From 170356ba325cd48d894014475a2a75190c333e0b Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Thu, 4 Feb 2016 11:51:39 +0000 Subject: [PATCH] [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 --- lld/ELF/Writer.cpp | 6 ++--- lld/test/ELF/mips-got-extsym.s | 59 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 lld/test/ELF/mips-got-extsym.s diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 1e94b03..58299b1 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -294,8 +294,6 @@ void Writer::scanRelocs( if (Config->EMachine == EM_MIPS && needsMipsLocalGot(Type, Body)) { // FIXME (simon): Do not add so many redundant entries. Out::Got->addMipsLocalEntry(); - if (Body) - Body->setUsedInDynamicReloc(); continue; } @@ -358,13 +356,15 @@ void Writer::scanRelocs( continue; Out::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 0000000..1cf99ae --- /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 -- 2.7.4