diff options
| author | Simon Atanasyan <simon@atanasyan.com> | 2016-02-04 11:51:39 +0000 |
|---|---|---|
| committer | Simon Atanasyan <simon@atanasyan.com> | 2016-02-04 11:51:39 +0000 |
| commit | 170356ba325cd48d894014475a2a75190c333e0b (patch) | |
| tree | 9b55fd72bb71a3f837905e74eee8f30c2e452e5f | |
| parent | 1dafd45e6f15e1a738f5c6859cc2e3f6049d38e3 (diff) | |
| download | bcm5719-llvm-170356ba325cd48d894014475a2a75190c333e0b.tar.gz bcm5719-llvm-170356ba325cd48d894014475a2a75190c333e0b.zip | |
[ELF][MIPS] Always create global GOT entry for symbols defined in DSO
If relocation against symbol requires GOT entry creation and this symbol
is defined in DSO, the GOT entry should be created in the 'global' part
of the GOT even if we link executable file. Also we do not need to create
a dynamic symbol table entry for global symbol corresponding to the
local GOT entry.
llvm-svn: 259778
| -rw-r--r-- | lld/ELF/Writer.cpp | 6 | ||||
| -rw-r--r-- | lld/test/ELF/mips-got-extsym.s | 59 |
2 files changed, 62 insertions, 3 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 1e94b03b69d..58299b130c3 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -294,8 +294,6 @@ void Writer<ELFT>::scanRelocs( if (Config->EMachine == EM_MIPS && needsMipsLocalGot(Type, Body)) { // FIXME (simon): Do not add so many redundant entries. Out<ELFT>::Got->addMipsLocalEntry(); - if (Body) - Body->setUsedInDynamicReloc(); continue; } @@ -358,13 +356,15 @@ void Writer<ELFT>::scanRelocs( continue; Out<ELFT>::Got->addEntry(Body); - if (Config->EMachine == EM_MIPS) + if (Config->EMachine == EM_MIPS) { // MIPS ABI has special rules to process GOT entries // and doesn't require relocation entries for them. // See "Global Offset Table" in Chapter 5 in the following document // for detailed description: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf + Body->setUsedInDynamicReloc(); continue; + } bool CBP = canBePreempted(Body, /*NeedsGot=*/true); bool Dynrel = Config->Shared && !Target->isRelRelative(Type) && diff --git a/lld/test/ELF/mips-got-extsym.s b/lld/test/ELF/mips-got-extsym.s new file mode 100644 index 00000000000..1cf99aeed49 --- /dev/null +++ b/lld/test/ELF/mips-got-extsym.s @@ -0,0 +1,59 @@ +# Check creation of GOT entries for global symbols in case of executable +# file linking. Symbols defined in DSO should get entries in the global part +# of the GOT. Symbols defined in the executable itself should get local GOT +# entries and does not need a row in .dynsym table. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o +# RUN: ld.lld -shared %t.so.o -o %t.so +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-readobj -dt -t -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Symbols [ +# CHECK: Symbol { +# CHECK: Name: _foo +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global + +# CHECK: Symbol { +# CHECK: Name: bar +# CHECK-NEXT: Value: 0x20008 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global + +# CHECK: DynamicSymbols [ +# CHECK-NOT: Name: bar + +# CHECK: Local entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x30008 +# CHECK-NEXT: Access: -32744 +# CHECK-NEXT: Initial: 0x20008 +# ^-- bar +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: 0x3000C +# CHECK-NEXT: Access: -32740 +# CHECK-NEXT: Initial: 0x0 +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Type: None +# CHECK-NEXT: Section: Undefined +# CHECK-NEXT: Name: _foo@ +# CHECK-NEXT: } +# CHECK-NEXT: ] + + .text + .globl __start +__start: + lw $t0,%got(bar)($gp) + lw $t0,%got(_foo)($gp) + +.global bar +bar: + .word 0 |

