summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2016-02-04 11:51:39 +0000
committerSimon Atanasyan <simon@atanasyan.com>2016-02-04 11:51:39 +0000
commit170356ba325cd48d894014475a2a75190c333e0b (patch)
tree9b55fd72bb71a3f837905e74eee8f30c2e452e5f
parent1dafd45e6f15e1a738f5c6859cc2e3f6049d38e3 (diff)
downloadbcm5719-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.cpp6
-rw-r--r--lld/test/ELF/mips-got-extsym.s59
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
OpenPOWER on IntegriCloud