MIPS: Truncate link address into 32bit for 32bit kernel
authorJiaxun Yang <jiaxun.yang@flygoat.com>
Wed, 6 May 2020 05:52:45 +0000 (13:52 +0800)
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>
Thu, 7 May 2020 08:31:01 +0000 (10:31 +0200)
LLD failed to link vmlinux with 64bit load address for 32bit ELF
while bfd will strip 64bit address into 32bit silently.
To fix LLD build, we should truncate load address provided by platform
into 32bit for 32bit kernel.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Link: https://github.com/ClangBuiltLinux/linux/issues/786
Link: https://sourceware.org/bugzilla/show_bug.cgi?id=25784
Reviewed-by: Fangrui Song <maskray@google.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
arch/mips/Makefile
arch/mips/boot/compressed/Makefile
arch/mips/kernel/vmlinux.lds.S

index e1c44aed815655b498ac701ad5b8f561dc624ff1..b6ee29e4565a3e80ce57d1f3db303398e0803a79 100644 (file)
@@ -288,12 +288,23 @@ ifdef CONFIG_64BIT
   endif
 endif
 
+# When linking a 32-bit executable the LLVM linker cannot cope with a
+# 32-bit load address that has been sign-extended to 64 bits.  Simply
+# remove the upper 32 bits then, as it is safe to do so with other
+# linkers.
+ifdef CONFIG_64BIT
+       load-ld                 = $(load-y)
+else
+       load-ld                 = $(subst 0xffffffff,0x,$(load-y))
+endif
+
 KBUILD_AFLAGS  += $(cflags-y)
 KBUILD_CFLAGS  += $(cflags-y)
-KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y)
+KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) -DLINKER_LOAD_ADDRESS=$(load-ld)
 KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0)
 
 bootvars-y     = VMLINUX_LOAD_ADDRESS=$(load-y) \
+                 LINKER_LOAD_ADDRESS=$(load-ld) \
                  VMLINUX_ENTRY_ADDRESS=$(entry-y) \
                  PLATFORM="$(platform-y)" \
                  ITS_INPUTS="$(its-y)"
index 0df0ee8a298dbf0c508390b918c8ac8fd70d2739..6e56caef69f063006c7ff1e7cc74007446e3d82f 100644 (file)
@@ -90,7 +90,7 @@ ifneq ($(zload-y),)
 VMLINUZ_LOAD_ADDRESS := $(zload-y)
 else
 VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
-               $(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
+               $(obj)/vmlinux.bin $(LINKER_LOAD_ADDRESS))
 endif
 UIMAGE_LOADADDR = $(VMLINUZ_LOAD_ADDRESS)
 
index a5f00ec73ea6e22c69b9d9039109d5d17927008c..f185a85a27c1a6c681b859abd8636864262cbb8c 100644 (file)
@@ -55,7 +55,7 @@ SECTIONS
        /* . = 0xa800000000300000; */
        . = 0xffffffff80300000;
 #endif
-       . = VMLINUX_LOAD_ADDRESS;
+       . = LINKER_LOAD_ADDRESS;
        /* read-only */
        _text = .;      /* Text and read-only data */
        .text : {