parisc: Allow building 64-bit kernel without -mlong-calls compiler option
authorHelge Deller <deller@gmx.de>
Tue, 14 May 2019 19:40:53 +0000 (21:40 +0200)
committerHelge Deller <deller@gmx.de>
Mon, 20 May 2019 08:51:39 +0000 (10:51 +0200)
A 64-bit kernel built without CONFIG_MLONGCALLS (-mlong-calls compiler
option) usually fails to link because of unreachable functions.  Try to
work around that linking issue by moving the *.init and *.exit text
segments closer to the main text segment. With that change those
segments now don't get freed at runtime any longer, but since we in most
cases run with huge-page enabled, we ignore the lost memory in
preference of better performance.

This change will not guarantee that every kernel config will now
sucessfully build with short calls and without linking issues.

Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/Kconfig
arch/parisc/kernel/vmlinux.lds.S

index 13b9512527c7825333380fc70ce1a2169a385f67..4860efa91d7bbe7c61e535e7fd77e7dd677bcf62 100644 (file)
@@ -194,7 +194,8 @@ config PREFETCH
 
 config MLONGCALLS
        bool "Enable the -mlong-calls compiler option for big kernels"
-       default y
+       default y if !MODULES || UBSAN || FTRACE
+       default n
        depends on PA8X00
        help
          If you configure the kernel to include many drivers built-in instead
index c3b1b9c24ede70fd9957d646613413dea42398eb..cd33b4feacb162f49d4365f7e1908fcb86d0c817 100644 (file)
@@ -35,6 +35,15 @@ OUTPUT_FORMAT("elf64-hppa-linux")
 OUTPUT_ARCH(hppa:hppa2.0w)
 #endif
 
+#define EXIT_TEXT_SECTIONS()   .exit.text : { EXIT_TEXT }
+#if !defined(CONFIG_64BIT) || defined(CONFIG_MLONGCALLS)
+#define MLONGCALL_KEEP(x)
+#define MLONGCALL_DISCARD(x)   x
+#else
+#define MLONGCALL_KEEP(x)      x
+#define MLONGCALL_DISCARD(x)
+#endif
+
 ENTRY(parisc_kernel_start)
 #ifndef CONFIG_64BIT
 jiffies = jiffies_64 + 4;
@@ -47,15 +56,11 @@ SECTIONS
 
        __init_begin = .;
        HEAD_TEXT_SECTION
-       INIT_TEXT_SECTION(8)
+       MLONGCALL_DISCARD(INIT_TEXT_SECTION(8))
 
        . = ALIGN(PAGE_SIZE);
        INIT_DATA_SECTION(PAGE_SIZE)
-       /* we have to discard exit text and such at runtime, not link time */
-       .exit.text :
-       {
-               EXIT_TEXT
-       }
+       MLONGCALL_DISCARD(EXIT_TEXT_SECTIONS())
        .exit.data :
        {
                EXIT_DATA
@@ -73,11 +78,12 @@ SECTIONS
 
        _text = .;              /* Text and read-only data */
        _stext = .;
+       MLONGCALL_KEEP(INIT_TEXT_SECTION(8))
        .text ALIGN(PAGE_SIZE) : {
                TEXT_TEXT
+               LOCK_TEXT
                SCHED_TEXT
                CPUIDLE_TEXT
-               LOCK_TEXT
                KPROBES_TEXT
                IRQENTRY_TEXT
                SOFTIRQENTRY_TEXT
@@ -92,6 +98,7 @@ SECTIONS
                *(.lock.text)           /* out-of-line lock text */
                *(.gnu.warning)
        }
+       MLONGCALL_KEEP(EXIT_TEXT_SECTIONS())
        . = ALIGN(PAGE_SIZE);
        _etext = .;
        /* End of text section */