diff options
-rw-r--r-- | lld/ELF/Target.cpp | 13 | ||||
-rw-r--r-- | lld/test/ELF/Inputs/mips-dynamic.s | 17 | ||||
-rw-r--r-- | lld/test/ELF/mips-plt-copy.s | 42 |
3 files changed, 72 insertions, 0 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 2b1e9f7308d..70edfd30342 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -196,6 +196,7 @@ public: MipsTargetInfo(); unsigned getDynRel(unsigned Type) const override; void writeGotHeader(uint8_t *Buf) const override; + bool needsCopyRel(uint32_t Type, const SymbolBody &S) const override; bool needsGot(uint32_t Type, const SymbolBody &S) const override; bool needsPlt(uint32_t Type, const SymbolBody &S) const override; void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, @@ -1386,6 +1387,7 @@ void AMDGPUTargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, } template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() { + CopyRel = R_MIPS_COPY; PageSize = 65536; GotHeaderEntriesNum = 2; RelativeRel = R_MIPS_REL32; @@ -1426,6 +1428,17 @@ void MipsTargetInfo<ELFT>::writeGotHeader(uint8_t *Buf) const { } template <class ELFT> +bool MipsTargetInfo<ELFT>::needsCopyRel(uint32_t Type, + const SymbolBody &S) const { + if (Config->Shared) + return false; + if (Type == R_MIPS_HI16 || Type == R_MIPS_LO16 || isRelRelative(Type)) + if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(&S)) + return SS->Sym.getType() == STT_OBJECT; + return false; +} + +template <class ELFT> bool MipsTargetInfo<ELFT>::needsGot(uint32_t Type, const SymbolBody &S) const { return Type == R_MIPS_GOT16 || Type == R_MIPS_CALL16; } diff --git a/lld/test/ELF/Inputs/mips-dynamic.s b/lld/test/ELF/Inputs/mips-dynamic.s index eba5b7f327b..baf07c1daad 100644 --- a/lld/test/ELF/Inputs/mips-dynamic.s +++ b/lld/test/ELF/Inputs/mips-dynamic.s @@ -1,4 +1,21 @@ + .option pic2 .text .globl _foo _foo: nop + + .globl foo + .type foo, @function +foo: + nop + + .data + .globl data0 + .type data0, @object +data0: + .word 0 + + .globl data1 + .type data1, @object +data1: + .word 0 diff --git a/lld/test/ELF/mips-plt-copy.s b/lld/test/ELF/mips-plt-copy.s new file mode 100644 index 00000000000..6ef05ab9dcc --- /dev/null +++ b/lld/test/ELF/mips-plt-copy.s @@ -0,0 +1,42 @@ +# Check creating of R_MIPS_COPY dynamic relocation. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \ +# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o +# RUN: ld.lld %t.so.o -shared -o %t.so +# RUN: ld.lld %t.o %t.so -o %t.exe +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# CHECK: Relocations [ +# CHECK-NEXT: Section (7) .rel.dyn { +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0 +# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data1 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +# CHECK: Primary GOT { +# CHECK: Local entries [ +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: ] +# CHECK-NEXT: Number of TLS and multi-GOT entries: 0 +# CHECK-NEXT: } + + .text + .globl __start +__start: + lui $t0,%hi(data0) # R_MIPS_HI16 requires COPY rel for DSO defined data. + addi $t0,$t0,%lo(data0) + lui $t0,%hi(gd) # Does not require COPY rel for locally defined data. + addi $t0,$t0,%lo(gd) + lui $t0,%hi(ld) # Does not require COPY rel for local data. + addi $t0,$t0,%lo(ld) + + .data + .globl gd +gd: + .word 0 +ld: + .word data1+8-. # R_MIPS_PC32 requires COPY rel for DSO defined data. |