summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Writer.cpp17
-rw-r--r--lld/test/ELF/mips-32.s26
2 files changed, 41 insertions, 2 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 8fb71c53d6d..e0ed5264afe 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -608,6 +608,23 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
// We don't know anything about the finaly symbol. Just ask the dynamic
// linker to handle the relocation for us.
AddDyn({Target->getDynRel(Type), C.OutSec, Offset, false, &Body, Addend});
+ // MIPS ABI turns using of GOT and dynamic relocations inside out.
+ // While regular ABI uses dynamic relocations to fill up GOT entries
+ // MIPS ABI requires dynamic linker to fills up GOT entries using
+ // specially sorted dynamic symbol table. This affects even dynamic
+ // relocations against symbols which do not require GOT entries
+ // creation explicitly, i.e. do not have any GOT-relocations. So if
+ // a preemptible symbol has a dynamic relocation we anyway have
+ // to create a GOT entry for it.
+ // If a non-preemptible symbol has a dynamic relocation against it,
+ // dynamic linker takes it st_value, adds offset and writes down
+ // result of the dynamic relocation. In case of preemptible symbol
+ // dynamic linker performs symbol resolution, writes the symbol value
+ // to the GOT entry and reads the GOT entry when it needs to perform
+ // a dynamic relocation.
+ // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
+ if (Config->EMachine == EM_MIPS && !Body.isInGot())
+ Out<ELFT>::Got->addEntry(Body);
continue;
}
diff --git a/lld/test/ELF/mips-32.s b/lld/test/ELF/mips-32.s
index 5cfd556f928..6622aeaa278 100644
--- a/lld/test/ELF/mips-32.s
+++ b/lld/test/ELF/mips-32.s
@@ -4,13 +4,15 @@
# RUN: ld.lld -shared %t-be.o -o %t-be.so
# RUN: llvm-objdump -t -s %t-be.so \
# RUN: | FileCheck -check-prefix=SYM -check-prefix=BE %s
-# RUN: llvm-readobj -r -dynamic-table %t-be.so | FileCheck -check-prefix=REL %s
+# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-be.so \
+# RUN: | FileCheck -check-prefix=REL %s
# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
# RUN: ld.lld -shared %t-el.o -o %t-el.so
# RUN: llvm-objdump -t -s %t-el.so \
# RUN: | FileCheck -check-prefix=SYM -check-prefix=EL %s
-# RUN: llvm-readobj -r -dynamic-table %t-el.so | FileCheck -check-prefix=REL %s
+# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-el.so \
+# RUN: | FileCheck -check-prefix=REL %s
# REQUIRES: mips
@@ -54,3 +56,23 @@ v2:
# REL: Tag Type Name/Value
# REL: 0x00000012 RELSZ 16 (bytes)
# REL: 0x00000013 RELENT 8 (bytes)
+
+# REL: Primary GOT {
+# REL-NEXT: Canonical gp value:
+# REL-NEXT: Reserved entries [
+# REL: ]
+# REL-NEXT: Local entries [
+# REL-NEXT: ]
+# REL-NEXT: Global entries [
+# REL-NEXT: Entry {
+# REL-NEXT: Address:
+# REL-NEXT: Access:
+# REL-NEXT: Initial: 0x30004
+# REL-NEXT: Value: 0x30004
+# REL-NEXT: Type: Object
+# REL-NEXT: Section: .data
+# REL-NEXT: Name: v2
+# REL-NEXT: }
+# REL-NEXT: ]
+# REL-NEXT: Number of TLS and multi-GOT entries: 0
+# REL-NEXT: }
OpenPOWER on IntegriCloud