Skip to content

Commit

Permalink
[ELF][MIPS] Support R_MIPS_COPY relocation
Browse files Browse the repository at this point in the history
Generate R_MIPS_COPY relocation for 'static' relocations against object
symbols defined in a shared libraries.

llvm-svn: 260083
  • Loading branch information
atanasyan committed Feb 8, 2016
1 parent ed203da commit e1bfc2e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
13 changes: 13 additions & 0 deletions lld/ELF/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ template <class ELFT> class MipsTargetInfo final : public TargetInfo {
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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1425,6 +1427,17 @@ void MipsTargetInfo<ELFT>::writeGotHeader(uint8_t *Buf) const {
P[1] = uintX_t(1) << (ELFT::Is64Bits ? 63 : 31);
}

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;
Expand Down
17 changes: 17 additions & 0 deletions lld/test/ELF/Inputs/mips-dynamic.s
Original file line number Diff line number Diff line change
@@ -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
42 changes: 42 additions & 0 deletions lld/test/ELF/mips-plt-copy.s
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit e1bfc2e

Please sign in to comment.