Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -608,6 +608,23 @@ // 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::Got->addEntry(Body); continue; } Index: lld/trunk/test/ELF/mips-32.s =================================================================== --- lld/trunk/test/ELF/mips-32.s +++ lld/trunk/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 @@ # 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: }