https://llvm.org/bugs/show_bug.cgi?id=30977
Bug ID: 30977 Summary: [ARM][AArch64] Add dynamic relocations for undefined weak GOT entries Product: lld Version: unspecified Hardware: PC OS: Linux Status: NEW Severity: normal Priority: P Component: ELF Assignee: unassignedb...@nondot.org Reporter: peter.sm...@linaro.org CC: llvm-bugs@lists.llvm.org Classification: Unclassified When a GOT slot generating relocation has an undefined weak reference as its target lld considers this non-preemptible and writes 0 into the GOT slot. This is in contrast to ld.bfd which puts a dynamic relocation so that the dynamic loader can find a definition in a shared library available at run-time but not available at static link time. Given how loosely weak references are defined in ELF, both lld and ld.bfd are within the specification. It remains to be seen if there is a legitimate way for a program to exploit the ld.bfd behaviour. Example from aarch64 which when compiled with clang --target=aarch64-none-linux will use a GOT generating relocation for WeakVar extern void WeakCall(int) __attribute__((weak)); extern int WeakVar __attribute__((weak)); int main(void) { int val = WeakVar; WeakCall(val); return WeakVar; } When linked with ld.bfd we get: Relocations [ Section (8) .rela.dyn { 0x410FD8 R_AARCH64_GLOB_DAT __gmon_start__ 0x0 0x410FE0 R_AARCH64_GLOB_DAT WeakVar 0x0 } Section (9) .rela.plt { 0x411000 R_AARCH64_JUMP_SLOT WeakCall 0x0 0x411008 R_AARCH64_JUMP_SLOT __libc_start_main 0x0 0x411010 R_AARCH64_JUMP_SLOT __gmon_start__ 0x0 0x411018 R_AARCH64_JUMP_SLOT abort 0x0 } ] When linked with ld.lld we get: Relocations [ Section (10) .rela.plt { 0x40028 R_AARCH64_JUMP_SLOT __libc_start_main 0x0 0x40030 R_AARCH64_JUMP_SLOT abort 0x0 } ] Note that the AARCH64 version of gcc uses a literal pool instead of the GOT generating relocation, so we don't get R_AARCH64_GLOB_DAT relocation Relocations [ Section (9) .rela.dyn { 0x4109F0 R_AARCH64_GLOB_DAT __gmon_start__ 0x0 } Section (10) .rela.plt { 0x410A10 R_AARCH64_JUMP_SLOT _Z8WeakCalli 0x0 0x410A18 R_AARCH64_JUMP_SLOT __libc_start_main 0x0 0x410A20 R_AARCH64_JUMP_SLOT __gmon_start__ 0x0 0x410A28 R_AARCH64_JUMP_SLOT abort 0x0 } ] There is a similar behaviour on ARM. However I note that the behaviour of ld.bfd on x86_64 is the same as lld so this behaviour may be target specific. At a rough guess ARM and AArch64 branch offsets are always relative, which may have influenced decisions made by the ld.bfd backend. Some further research is needed to work out: - Can any target other than ARM or AArch64 generate a dynamic relocation to an undefined weak reference? - Is there any reason that means that ARM and AArch64 must generate a dynamic relocation for correctness? Probably not worth doing anything unless we find something that depends on ld.bfds behaviour, and most likely making it target specific to ARM and AArch64. For the example I used clang 4.0 (trunk at time) with the only code generation option --target=aarch64-none-linux. I used the Linaro 2015-10 AArch64 Linux toolchain with GNU ld (GNU Binutils) 2.25.0 Linaro 2015_10 -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ llvm-bugs mailing list llvm-bugs@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs