diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 72544103db6d..adf5949f20f6 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -1235,7 +1235,10 @@ template MipsTargetInfo::MipsTargetInfo() { UseLazyBinding = true; CopyRel = R_MIPS_COPY; PltRel = R_MIPS_JUMP_SLOT; - RelativeRel = R_MIPS_REL32; + if (ELFT::Is64Bits) + RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32; + else + RelativeRel = R_MIPS_REL32; } template @@ -1286,7 +1289,7 @@ RelExpr MipsTargetInfo::getRelExpr(uint32_t Type, template uint32_t MipsTargetInfo::getDynRel(uint32_t Type) const { if (Type == R_MIPS_32 || Type == R_MIPS_64) - return R_MIPS_REL32; + return RelativeRel; StringRef S = getELFRelocationTypeName(EM_MIPS, Type); error("relocation " + S + " cannot be used when making a shared object; " "recompile with -fPIC."); @@ -1452,6 +1455,9 @@ void MipsTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type, case R_MIPS_32: write32(Loc, Val); break; + case R_MIPS_64: + write64(Loc, Val); + break; case R_MIPS_26: { uint32_t Instr = read32(Loc); write32(Loc, (Instr & ~0x3ffffff) | (Val >> 2)); diff --git a/lld/test/ELF/mips-64.s b/lld/test/ELF/mips-64.s new file mode 100644 index 000000000000..d4a8df31eb27 --- /dev/null +++ b/lld/test/ELF/mips-64.s @@ -0,0 +1,67 @@ +# Check R_MIPS_64 relocation calculation. + +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-objdump -t -s %t.so | FileCheck -check-prefix=SYM %s +# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t.so | FileCheck %s + +# REQUIRES: mips + + .global __start +__start: + nop + + .data + .type v1,@object + .size v1,4 +v1: + .quad 0 + + .globl v2 + .type v2,@object + .size v2,8 +v2: + .quad v2+8 # R_MIPS_64 target v2 addend 8 + .quad v1 # R_MIPS_64 target v1 addend 0 + +# SYM: Contents of section .data: +# SYM-NEXT: 30000 00000000 00000000 00000000 00000000 +# ^-- v2 +# SYM-NEXT: 30010 00000000 00030000 +# ^-- v1 + +# SYM: SYMBOL TABLE: +# SYM: 00030000 l .data 00000004 v1 +# SYM: 00030008 g .data 00000008 v2 + +# CHECK: Relocations [ +# CHECK-NEXT: Section (7) .rela.dyn { +# CHECK-NEXT: 0x30008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE v2 0x8 +# CHECK-NEXT: 0x30010 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE - 0x30000 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +# CHECK: DynamicSection [ +# CHECK: Tag Type Name/Value +# CHECK: 0x0000000000000008 RELASZ 48 (bytes) +# CHECK: 0x0000000000000009 RELAENT 24 (bytes) + +# CHECK: Primary GOT { +# CHECK-NEXT: Canonical gp value: +# CHECK-NEXT: Reserved entries [ +# CHECK: ] +# CHECK-NEXT: Local entries [ +# CHECK-NEXT: ] +# CHECK-NEXT: Global entries [ +# CHECK-NEXT: Entry { +# CHECK-NEXT: Address: +# CHECK-NEXT: Access: +# CHECK-NEXT: Initial: 0x30008 +# CHECK-NEXT: Value: 0x30008 +# CHECK-NEXT: Type: Object +# CHECK-NEXT: Section: .data +# CHECK-NEXT: Name: v2 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Number of TLS and multi-GOT entries: 0 +# CHECK-NEXT: }