Linux: can't create dynamic relocation R_386_32 with LLD

Created on 28 Jun 2019  路  9Comments  路  Source: ClangBuiltLinux/linux

ld.lld: error: can't create dynamic relocation R_386_32 against symbol: _bss in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in 
>>> referenced by arch/x86/boot/compressed/head_32.o:(.text+0x4)

This is specific to i386 and LLD. Not yet submitted to LLVM bugzilla.

[ARCH] x86 [BUG] linux [FIXED][LINUX] 5.10 [TOOL] lld

All 9 comments

arch/x86/boot/compressed/Makefile resets KBUILD_CFLAGS and KBUILD_LDFLAGS. Can you try:

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 6b84afdd7538..90d59a064136 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -43,7 +43,7 @@ KBUILD_AFLAGS  := $(KBUILD_CFLAGS) -D__ASSEMBLY__
 GCOV_PROFILE := n
 UBSAN_SANITIZE :=n

-KBUILD_LDFLAGS := -m elf_$(UTS_MACHINE)
+KBUILD_LDFLAGS := -m elf_$(UTS_MACHINE) -z notext
 # Compressed kernel should be built as PIE since it may be loaded at any
 # address by the bootloader.
 ifeq ($(CONFIG_X86_32),y)

We do that in arch/arm64/Makefile if CONFIG_RELOCATABLE is set. So I'm guessing this issue might go away if KASLR (CONFIG_RANDOMIZE_BASE and CONFIG_RELOCATABLE) is used. If that's the case, then my diff above should probably similarly be guarded like in arch/arm64/Makefile by CONFIG_RELOCATABLE.

Builds fine with -z notext, confirmed.

I have tested with both CONFIG_RELOCATABLE set and unset and can confirm that the guess was right. I updated the patch:


--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -55,6 +55,12 @@ else
 KBUILD_LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \
    && echo "-z noreloc-overflow -pie --no-dynamic-linker")
 endif
+ifeq ($(CONFIG_RELOCATABLE), y)
+# LLD by default disallows relocations in read-only segments. For a relocatable
+# kernel, we pass -z notext to the linker to explicitly allow relocations. This
+# behavior is default for BFD.
+KBUILD_LDFLAGS += -z notext
+endif
 LDFLAGS_vmlinux := -T

I like the check for CONFIG_RELOCATABLE. @tpimh did you test that LLD can link the image both w/ and w/o that config enabled? The comment can go in the commit message, rather than in source I think.

Tested with both CONFIG_RELOCATABLE set and unset. Links and boots fine in both cases.

Cool, send it.

With this series applied: https://lore.kernel.org/lkml/[email protected]/T/#u

I was able to link and boot an i386_defconfig with LLD. (Also https://lore.kernel.org/linux-next/[email protected]/, and a series I recently sent to Linus most of patches from Brian Gerst plus one). So this is close to working.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nathanchance picture nathanchance  路  4Comments

nickdesaulniers picture nickdesaulniers  路  5Comments

tpgxyz picture tpgxyz  路  4Comments

tpimh picture tpimh  路  5Comments

nathanchance picture nathanchance  路  3Comments