[ELF][MIPS] Always create global GOT entry for symbols defined in DSO
authorSimon Atanasyan <simon@atanasyan.com>
Thu, 4 Feb 2016 11:51:39 +0000 (11:51 +0000)
committerSimon Atanasyan <simon@atanasyan.com>
Thu, 4 Feb 2016 11:51:39 +0000 (11:51 +0000)
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
lld/test/ELF/mips-got-extsym.s [new file with mode: 0644]

index 1e94b03..58299b1 100644 (file)
@@ -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 (file)
index 0000000..1cf99ae
--- /dev/null
@@ -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