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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Jun 2020 08:25:11 +0000 (10:25 +0200)
[ Upstream commit ff487d41036035376e47972c7c522490b839ab37 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/mips/Makefile
arch/mips/boot/compressed/Makefile
arch/mips/kernel/vmlinux.lds.S

index 5977884b008e6d798755dbf98ae5d29fda1b015c..a4a06d173858808755b45a85093e62f8e1cb60eb 100644 (file)
@@ -279,12 +279,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 baa34e4deb78014394aa7edab2952ccc00e7d428..516e593a8ee9d64bcbf13914a5eb5b8004f78344 100644 (file)
@@ -87,7 +87,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 36f2e860ba3eade90e3c1f535c18713d257ebaff..be63fff95b2abb64c8e766807927d823b3bee940 100644 (file)
@@ -50,7 +50,7 @@ SECTIONS
        /* . = 0xa800000000300000; */
        . = 0xffffffff80300000;
 #endif
-       . = VMLINUX_LOAD_ADDRESS;
+       . = LINKER_LOAD_ADDRESS;
        /* read-only */
        _text = .;      /* Text and read-only data */
        .text : {