Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output #811

Closed
ikitayama opened this issue Dec 13, 2019 · 42 comments
Assignees
Labels
[ARCH] powerpc This bug impacts ARCH=powerpc [BUG] linux A bug that should be fixed in the mainline kernel. [FIXED][LINUX] 5.15 This bug was fixed in Linux 5.15 [TOOL] lld The issue is relevant to LLD linker

Comments

@ikitayama
Copy link


[...]
  AR      init/built-in.a
  LD      vmlinux.o
  MODPOST vmlinux.o
WARNING: vmlinux.o(.text+0x31e4): Section mismatch in reference from the variable __boot_from_prom to the function .init.text:prom_init()
The function __boot_from_prom() references
the function __init prom_init().
This is often because __boot_from_prom lacks a __init
annotation or the annotation of prom_init is wrong.

WARNING: vmlinux.o(.text+0x33c8): Section mismatch in reference from the variable start_here_common to the function .init.text:start_kernel()
The function start_here_common() references
the function __init start_kernel().
This is often because start_here_common lacks a __init
annotation or the annotation of start_kernel is wrong.

WARNING: vmlinux.o(.text+0x7bd38): Section mismatch in reference from the function remove_pmd_table() to the function .meminit.text:split_kernel_mapping()
The function remove_pmd_table() references
the function __meminit split_kernel_mapping().
This is often because remove_pmd_table lacks a __meminit
annotation or the annotation of split_kernel_mapping is wrong.

  MODINFO modules.builtin.modinfo
  LD      .tmp_vmlinux1
ld.lld: warning: <internal>:(.bss.rel.ro) is being placed in '.bss.rel.ro'
ld.lld: warning: <internal>:(.gnu.hash) is being placed in '.gnu.hash'
ld.lld: warning: <internal>:(.symtab) is being placed in '.symtab'
ld.lld: warning: <internal>:(.symtab_shndx) is being placed in '.symtab_shndx'
ld.lld: warning: <internal>:(.shstrtab) is being placed in '.shstrtab'
ld.lld: warning: <internal>:(.strtab) is being placed in '.strtab'
ld.lld: error: unknown relocation (251) against symbol machine_check_early_common
ld.lld: error: unknown relocation (251) against symbol idle_return_gpr_loss
ld.lld: error: unknown relocation (251) against symbol machine_check_early_common
ld.lld: error: unknown relocation (251) against symbol hmi_exception_early_common
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv
ld.lld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
make[1]: *** [vmlinux] Error 1
make: *** [sub-make] Error 2
@nickdesaulniers nickdesaulniers added [ARCH] powerpc This bug impacts ARCH=powerpc [TOOL] lld The issue is relevant to LLD linker labels Dec 13, 2019
@nickdesaulniers
Copy link
Member

Thanks for the report (ignoring the section mismatches as we have bugs filed for some of them). What config and command did you use for us to reproduce?

@ikitayama
Copy link
Author

Nick,

The kernel is based on today's Torvalds's master branch and the build is executed:

$ make CC=clang LD=ld.lld defconfig

Note that I am on a Minskey node thus building the kernel natively with trunk Clang.

@ikitayama
Copy link
Author

Thanks for the report (ignoring the section mismatches as we have bugs filed for some of them). What config and command did you use for us to reproduce?

Is this specific to the architecture, or LLD's issue?

@nickdesaulniers
Copy link
Member

nickdesaulniers commented Dec 16, 2019

ld.lld: error: unknown relocation (251) against symbol kvmppc_interrupt_hv

That seems like an LLD issue. There are many different types of relocations which are architecture specific, as specified by their ABI. They have a number to identify the type, in this case 251, which is simply not implemented by LLD, though clang will create object files with those types of relocations.

I assume (or this implies) PPC contributors to LLVM are not testing w/ LLD.

@nickdesaulniers
Copy link
Member

nickdesaulniers commented Dec 16, 2019

I've filed https://llvm.org/pr44315 upstream.

@nickdesaulniers nickdesaulniers added the [BUG] llvm A bug that should be fixed in upstream LLVM label Dec 16, 2019
@ikitayama
Copy link
Author

ikitayama commented Dec 16, 2019 via email

@MaskRay
Copy link
Member

MaskRay commented Dec 20, 2019

Duplicate of #640

Fixed by https://reviews.llvm.org/rL369184 (I think this change is included in lld 9.0.0)

make ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu- CC=~/llvm/Release/bin/clang LD=~/llvm/Release/bin/ld.lld O=out/powerpc64le zImage.epapr modules -j 30 works correctly for me.
Please specify clang/lld versions and the build instruction next time :)

@MaskRay MaskRay closed this as completed Dec 20, 2019
@MaskRay
Copy link
Member

MaskRay commented Dec 20, 2019

powerpc is also good.

apt install u-boot-tools

make ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- CC=~/llvm/Release/bin/clang LD=~/llvm/Release/bin/ld.lld O=out/powerpc zImage -j 30

@ikitayama
Copy link
Author

ikitayama commented Dec 20, 2019 via email

@ikitayama
Copy link
Author


  AR      init/built-in.a
  LD      vmlinux.o
  MODPOST vmlinux.o
WARNING: vmlinux.o(.text+0x31e4): Section mismatch in reference from the variable __boot_from_prom to the function .init.text:prom_init()
The function __boot_from_prom() references
the function __init prom_init().
This is often because __boot_from_prom lacks a __init
annotation or the annotation of prom_init is wrong.

WARNING: vmlinux.o(.text+0x33c8): Section mismatch in reference from the variable start_here_common to the function .init.text:start_kernel()
The function start_here_common() references
the function __init start_kernel().
This is often because start_here_common lacks a __init
annotation or the annotation of start_kernel is wrong.

WARNING: vmlinux.o(.text+0x6af38): Section mismatch in reference from the function remove_pmd_table() to the function .meminit.text:split_kernel_mapping()
The function remove_pmd_table() references
the function __meminit split_kernel_mapping().
This is often because remove_pmd_table lacks a __meminit
annotation or the annotation of split_kernel_mapping is wrong.

  MODINFO modules.builtin.modinfo
  LD      .tmp_vmlinux1
ld.lld: warning: <internal>:(.bss.rel.ro) is being placed in '.bss.rel.ro'
ld.lld: warning: <internal>:(.gnu.hash) is being placed in '.gnu.hash'
ld.lld: warning: <internal>:(.symtab) is being placed in '.symtab'
ld.lld: warning: <internal>:(.symtab_shndx) is being placed in '.symtab_shndx'
ld.lld: warning: <internal>:(.shstrtab) is being placed in '.shstrtab'
ld.lld: warning: <internal>:(.strtab) is being placed in '.strtab'
ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against symbol: empty_zero_page in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/head_64.o
>>> referenced by arch/powerpc/kernel/head_64.o:(___ksymtab+empty_zero_page+0x0)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/head_64.o
>>> referenced by arch/powerpc/kernel/head_64.o:(___ksymtab+empty_zero_page+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/entry_64.o
>>> referenced by arch/powerpc/kernel/entry_64.o:(.text+0x3010)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/fpu.o
>>> referenced by arch/powerpc/kernel/fpu.o:(___ksymtab+load_fp_state+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/fpu.o
>>> referenced by arch/powerpc/kernel/fpu.o:(___ksymtab+store_fp_state+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/vector.o
>>> referenced by arch/powerpc/kernel/vector.o:(___ksymtab+load_vr_state+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/vector.o
>>> referenced by arch/powerpc/kernel/vector.o:(___ksymtab+store_vr_state+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(main.o)
>>> referenced by main.c
>>>               main.o:(__ksymtab_system_state) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(main.o)
>>> referenced by main.c
>>>               main.o:(__ksymtab_system_state) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(main.o)
>>> referenced by main.c
>>>               main.o:(__ksymtab_static_key_initialized) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(main.o)
>>> referenced by main.c
>>>               main.o:(__ksymtab_static_key_initialized) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(main.o)
>>> referenced by main.c
>>>               main.o:(__ksymtab_reset_devices) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(main.o)
>>> referenced by main.c
>>>               main.o:(__ksymtab_reset_devices) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(main.o)
>>> referenced by main.c
>>>               main.o:(__ksymtab_loops_per_jiffy) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(main.o)
>>> referenced by main.c
>>>               main.o:(__ksymtab_loops_per_jiffy) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(version.o)
>>> referenced by version.c
>>>               version.o:(__ksymtab_init_uts_ns) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(version.o)
>>> referenced by version.c
>>>               version.o:(__ksymtab_init_uts_ns) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts.o)
>>> referenced by do_mounts.c
>>>               do_mounts.o:(__ksymtab_name_to_dev_t) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts.o)
>>> referenced by do_mounts.c
>>>               do_mounts.o:(__ksymtab_name_to_dev_t) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(init_task.o)
>>> referenced by init_task.c
>>>               init_task.o:(__ksymtab_init_task) in archive init/built-in.a

ld.lld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
make[1]: *** [vmlinux] Error 1
make: *** [sub-make] Error 2

@ikitayama
Copy link
Author

@MaskRay could you repeat what you've done on Power?

@ikitayama ikitayama reopened this Dec 20, 2019
@ikitayama
Copy link
Author

I am happy to provide the .config I used, but don't know how I can upload it.

@tpimh
Copy link

tpimh commented Dec 21, 2019

I believe you can just drag-and-drop your config to github comment if you add .txt extension to your config filename.

@ikitayama
Copy link
Author

config-20191221.txt

@ikitayama
Copy link
Author

Can someone try to build the kernel with trunk Clang on POWER8 hardware, if the hardware matters?

@nathanchance
Copy link
Member

$ make -j$(nproc) -s ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu- CC=clang LD=ld.lld O=out.powerpc64le distclean ppc64le_defconfig zImage.epapr

reproduces the errors reported above.

@ikitayama
Copy link
Author

ikitayama commented Dec 22, 2019 via email

@MaskRay
Copy link
Member

MaskRay commented Dec 23, 2019

I am able to reproduce with make ARCH=powerpc CROSS_COMPILE=powerpc64le-linux-gnu- CC=clang LD=ld.lld O=out/powerpc64le distclean ppc64le_defconfig zImage.epapr -j30. There are two issues.

  1. I noticed an assertion error (-DLLVM_ENABLE_ASSERTIONS=On) due to /DISCARD/ : { *(.gnu_version*) } in arch/powerpc/kernel/vmlinux.lds.S.
    I don't think it was intentionally supported before. Created https://reviews.llvm.org/D71819 to make it work.

  2. The text relocations are real. lld can link .tmp_vmlinux1 smoothly if you pass -z notext. Though, it will still be insightful to investigate where these text relocations come from. I believe there are only 2 categories.

(a) For a CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y build (x86 and arm64 select the option by default), ___ksymtab+* sections (non-SHF_WRITE) contains entries relocated by PC relative relocations. These entries do not need dynamic relocations.

out/powerpc64le/.config generated by ppc64le_defconfig does not enable CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y.

% readelf -r out/x86_64/entry/entry_64.o
...
Relocation section '.rela___ksymtab+native_load_gs_index' at offset 0x6460 contains 2 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
0000000000000000  0000007a00000002 R_X86_64_PC32          0000000000000ea0 native_load_gs_index + 0
0000000000000004  0000001d00000002 R_X86_64_PC32          0000000000000000 __ksymtab_strings + 0

include/asm-generic/export.h

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl
,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts.o)
>>> referenced by do_mounts.c
>>>               do_mounts.o:(__ksymtab_name_to_dev_t) in archive init/built-in.a

(b) R_PPC64_ADDR64 in __mcount_loc sections.

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl
,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_rd.o)
>>> referenced by do_mounts_rd.c
>>>               do_mounts_rd.o:(__mcount_loc+0x0) in archive init/built-in.a

This section is generated by ./scripts/recordmcount "init/do_mounts_rd.o". The tool hard codes R_PPC64_ADDR64.

% grep PPC64 scripts/recordmcount.c
        case EM_PPC64:  reltype = R_PPC64_ADDR64; break;

Can anyone recommend some qemu-system-ppc64le command line?

This patch works for me.

--- i/arch/powerpc/Makefile
+++ w/arch/powerpc/Makefile
@@ -122,7 +122,7 @@ cflags-$(CONFIG_STACKPROTECTOR)     += -mstack-protector-guard-reg=r2
 endif
 
 LDFLAGS_vmlinux-y := -Bstatic
-LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie
+LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie -z notext
 LDFLAGS_vmlinux        := $(LDFLAGS_vmlinux-y)
 LDFLAGS_vmlinux += $(call ld-option,--orphan-handling=warn)

@nathanchance
Copy link
Member

Can anyone recommend some qemu-system-ppc64le command line?

Our CI has this one: https://travis-ci.com/ClangBuiltLinux/continuous-integration/jobs/267861149#L2761

Not sure if it will work because it is a generic ppc64le kernel, rather than powernv_defconfig.

@MaskRay
Copy link
Member

MaskRay commented Dec 26, 2019

D71819 was committed to address problem 1 as I described above. It looks like it is difficult to get rid of text relocations, I will figure out the if condition with the narrowest scope that arch/powerpc/Makefile needs.

@ikitayama
Copy link
Author

@MaskRay let us know when we can start testing the trunk on POWER8!

@nathanchance
Copy link
Member

@MaskRay doubling back to this because I am writing a mini test framework for us and I ran into this.

I tested your -z notext fix, which resolves the link failures. However, the resulting kernel does not boot in QEMU. It is not a result of that fix though as the kernel boots when linked with ld.bfd. I can't say what ld.lld is doing wrong though.

@ikitayama
Copy link
Author

I get as of today's linux master:


[kitayama1@juron1-adm linux]$ make LD=ld.lld -j129 CFLAGS=-Wl,-z,notext
  CALL    scripts/atomic/check-atomics.sh
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  GEN     .version
  CHK     include/generated/compile.h
  UPD     include/generated/compile.h
  CC      init/version.o
  AR      init/built-in.a
  LD      vmlinux.o
  MODPOST vmlinux.o
WARNING: modpost: vmlinux.o(.text.unlikely+0x2c4): Section mismatch in reference from the function early_init_mmu() to the function .init.text:radix__early_init_mmu()
The function early_init_mmu() references
the function __init radix__early_init_mmu().
This is often because early_init_mmu lacks a __init
annotation or the annotation of radix__early_init_mmu is wrong.

WARNING: modpost: vmlinux.o(.text.unlikely+0x2d0): Section mismatch in reference from the function early_init_mmu() to the function .init.text:hash__early_init_mmu()
The function early_init_mmu() references
the function __init hash__early_init_mmu().
This is often because early_init_mmu lacks a __init
annotation or the annotation of hash__early_init_mmu is wrong.

  MODINFO modules.builtin.modinfo
  GEN     modules.builtin
  LD      .tmp_vmlinux.kallsyms1
ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against symbol: empty_zero_page in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/head_64.o
>>> referenced by arch/powerpc/kernel/head_64.o:(___ksymtab+empty_zero_page+0x0)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/head_64.o
>>> referenced by arch/powerpc/kernel/head_64.o:(___ksymtab+empty_zero_page+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/entry_64.o
>>> referenced by arch/powerpc/kernel/entry_64.o:(.text+0x2C40)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/fpu.o
>>> referenced by arch/powerpc/kernel/fpu.o:(___ksymtab+load_fp_state+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/fpu.o
>>> referenced by arch/powerpc/kernel/fpu.o:(___ksymtab+store_fp_state+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/vector.o
>>> referenced by arch/powerpc/kernel/vector.o:(___ksymtab+load_vr_state+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in arch/powerpc/kernel/vector.o
>>> referenced by arch/powerpc/kernel/vector.o:(___ksymtab+store_vr_state+0x8)

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_rd.o)
>>> referenced by do_mounts_rd.c
>>>               do_mounts_rd.o:(__mcount_loc+0x0) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_rd.o)
>>> referenced by do_mounts_rd.c
>>>               do_mounts_rd.o:(__mcount_loc+0x8) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_rd.o)
>>> referenced by do_mounts_rd.c
>>>               do_mounts_rd.o:(__mcount_loc+0x10) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_rd.o)
>>> referenced by do_mounts_rd.c
>>>               do_mounts_rd.o:(__mcount_loc+0x18) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_rd.o)
>>> referenced by do_mounts_rd.c
>>>               do_mounts_rd.o:(__mcount_loc+0x20) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_rd.o)
>>> referenced by do_mounts_rd.c
>>>               do_mounts_rd.o:(__mcount_loc+0x28) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_rd.o)
>>> referenced by do_mounts_rd.c
>>>               do_mounts_rd.o:(__mcount_loc+0x30) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_initrd.o)
>>> referenced by do_mounts_initrd.c
>>>               do_mounts_initrd.o:(__mcount_loc+0x0) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_initrd.o)
>>> referenced by do_mounts_initrd.c
>>>               do_mounts_initrd.o:(__mcount_loc+0x8) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_initrd.o)
>>> referenced by do_mounts_initrd.c
>>>               do_mounts_initrd.o:(__mcount_loc+0x10) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_initrd.o)
>>> referenced by do_mounts_initrd.c
>>>               do_mounts_initrd.o:(__mcount_loc+0x18) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_md.o)
>>> referenced by do_mounts_md.c
>>>               do_mounts_md.o:(__mcount_loc+0x0) in archive init/built-in.a

ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output
>>> defined in init/built-in.a(do_mounts_md.o)
>>> referenced by do_mounts_md.c
>>>               do_mounts_md.o:(__mcount_loc+0x8) in archive init/built-in.a

ld.lld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
make[1]: *** [vmlinux] Error 1
make: *** [sub-make] Error 2

@bwendling
Copy link

Are there any updates on this bug? The -z notext changes helps one of our cases.

@nickdesaulniers nickdesaulniers changed the title Building the kernel with ld.lld ends up an error on POWER8 can't create dynamic relocation R_PPC64_ADDR64 against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output Jul 28, 2020
@nickdesaulniers
Copy link
Member

However, the resulting kernel does not boot in QEMU

@nathanchance can you attach GDB and see where the kernel is?

@nathanchance
Copy link
Member

Yeah I can try to double back around to that on Thursday or Friday (my two days off this week).

@nathanchance
Copy link
Member

nathanchance commented Jan 6, 2021

Yeah I can try to double back around to that on Thursday or Friday

Well that was a lie... but hey, better late than never :)

  • ppc64le_defconfig or powernv_defconfig + CONFIG_RELOCATABLE=y is still enough to reproduce this issue with latest LLVM.
  • @MaskRay 's diff above continues to build and link the kernel just fine.
  • Booting fails prior to llvm/llvm-project@2fc704a. In other words, ToT LLVM boots these two configuration combinations just fine now. Prior to that commit, the boot just hangs.

Seems like we should send along @MaskRay 's patch and maybe mark CONFIG_RELOCATABLE as depends on !LD_IS_LLD || LLD_VERSION >= 120000

@MaskRay
Copy link
Member

MaskRay commented Jan 7, 2021

From scripts/recordmcount.c case EM_PPC64: reltype = R_PPC64_ADDR64; break;, I don't understand why the text relocation is only a problem for ppc64. If other architectures can have such absolute relocations in non-SHF_WRITE sections, they should have text relocations as well.

@nickdesaulniers
Copy link
Member

@paulmenzel
Copy link

Do you know if there is a patch to fix this? Are the PPC folks aware of this?

@nathanchance
Copy link
Member

@paulmenzel Fangrui's diff above along with a recent version of clang should work. I do not think we have followed up with any of the PowerPC folks but it is probably worth involving them at this point.

@nickdesaulniers
Copy link
Member

@MaskRay can you please send your above diff to LKML for review?

Will we need to gate something on llvm/llvm-project@2fc704a? (ie. lld-12)

@paulmenzel
Copy link

@paulmenzel Fangrui's diff above along with a recent version of clang should work.

Thank you. With that Makefile change, make -j100 LLVM=1 bindeb-pkg succeeded on Ubuntu 21.04 with llvm/clang 12.0-52~exp1.

I do not think we have followed up with any of the PowerPC folks but it is probably worth involving them at this point.

Let’s see, if @MaskRay responds and is able to send the patch.

@paulmenzel
Copy link

Linux’ PPC maintainer Michael Ellerman replied to my message asking if the proposed fix was acceptable:

Sorry but I have no idea if it's the right fix. What I need is the
author (or someone else) to send a patch with a change log explaining
the change, what it does, why it's right for llvm, and why it's right
for binutils.

@MaskRay, could you do that? (Or write a summary, and I contact them with you in cc.)

@bwendling
Copy link

Here's what I applied to our local branch:

commit 8c3901a857cd00d3fe0009ff4771890f530fb7c3
Author: Bill Wendling <morbo@google.com>
Date:   Mon Jul 20 00:39:43 2020 -0700

    ppc: add "-z notext" flag to disable diagnostic

    The "-z notext" flag disables reporting an error if DT_TEXTREL is set on
    PPC with CONFIG=kdump:

      ld.lld: error: can't create dynamic relocation R_PPC64_ADDR64 against
        local symbol in readonly segment; recompile object files with -fPIC
        or pass '-Wl,-z,notext' to allow text relocations in the output
      >>> defined in built-in.a(arch/powerpc/kernel/misc.o)
      >>> referenced by arch/powerpc/kernel/misc.o:(.text+0x20) in archive
          built-in.a

    The BFD linker disables this by default (though it's configurable in
    current versions). LLD enables this by default. So we add the flag to
    keep LLD from emitting the error.

    Tested: Built with clang and gcc. The flag has no effect on code
            generation.

    Effort: core/clang
    Google-Bug-Id: 161394878
    Change-Id: Ia02eff4ec9712f9ae045ebd833b7aed4b6205d65

diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index 7ceffa26ca5c..1209df105ca3 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -110,6 +110,7 @@ endif

 LDFLAGS_vmlinux-y := -Bstatic
 LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie
+LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) += -z notext
 LDFLAGS_vmlinux        := $(LDFLAGS_vmlinux-y)
 LDFLAGS_vmlinux += $(call ld-option,--orphan-handling=warn)

Basically, it's making explicit what binutils does implicitly.

@nickdesaulniers
Copy link
Member

Didn't @mpe already accept
commit 4c078c8 ("powerpc/boot/wrapper: Add "-z notext" flag to disable diagnostic")
which already explains these differences in default behavior between linkers? This is the same as
commit commit 3bbd3db ("arm64: relocatable: fix inconsistencies in linker script and options")

@nickdesaulniers
Copy link
Member

Also @gwelymernans please strip off the google specific commit message tags, and send that upstream and cc @paulmenzel (you can run git log --author "Paul Menzel" to find @paulmenzel 's email address).

In future, @paulmenzel please please please cc clang-built-linux@googlegroups.com on questions related to LLVM. It's in the MAINTAINERS file and clangbuiltlinux.github.io if you forget.

@MaskRay
Copy link
Member

MaskRay commented Aug 12, 2021

The BFD linker disables this by default (though it's configurable in current versions). LLD enables this by default. So we add the flag to keep LLD from emitting the error.

If binutils is configured with --enable-textrel-check={warning,error,yes}, the dynamic relocation R_PPC64_ADDR64 in readonly sections may cause a warning/error in the absence of -z notext. Someone may want to confirm this.

@bwendling
Copy link

bwendling commented Aug 12, 2021

Also @gwelymernans please strip off the google specific commit message tags, and send that upstream and cc @paulmenzel (you can run git log --author "Paul Menzel" to find @paulmenzel 's email address).

Done.

@nickdesaulniers nickdesaulniers added [BUG] linux A bug that should be fixed in the mainline kernel. [PATCH] Submitted A patch has been submitted for review and removed [BUG] llvm A bug that should be fixed in upstream LLVM labels Aug 12, 2021
@paulmenzel
Copy link

@gwelymernans, thank you for sending the patch for review. (I am not part of cc:, but it’s fine, as besides Tested-by: I am not able to contribute anything useful to the discussion. (You could refer to the arm64 commit https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3bbd3db86470c701091fb1d67f1fab6621debf50 in the commit message. But it’s also documented in the discussion here.)

@nickdesaulniers
Copy link
Member

accepted: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id=0355785313e2191be4e1108cdbda94ddb0238c48

@nickdesaulniers nickdesaulniers added [PATCH] Accepted A submitted patch has been accepted upstream and removed [PATCH] Submitted A patch has been submitted for review labels Aug 27, 2021
@nickdesaulniers
Copy link
Member

0355785

@nickdesaulniers nickdesaulniers added [FIXED][LINUX] 5.15 This bug was fixed in Linux 5.15 and removed [PATCH] Accepted A submitted patch has been accepted upstream labels Sep 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[ARCH] powerpc This bug impacts ARCH=powerpc [BUG] linux A bug that should be fixed in the mainline kernel. [FIXED][LINUX] 5.15 This bug was fixed in Linux 5.15 [TOOL] lld The issue is relevant to LLD linker
Projects
None yet
Development

No branches or pull requests

7 participants