[llvm-bugs] [Bug 30977] New: [ARM][AArch64] Add dynamic relocations for undefined weak GOT entries

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Nov 10 09:10:29 PST 2016


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: unassignedbugs at nondot.org
          Reporter: peter.smith at linaro.org
                CC: llvm-bugs at 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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20161110/9af91d93/attachment.html>


More information about the llvm-bugs mailing list