diff options
-rw-r--r-- | lld/ELF/Target.cpp | 20 | ||||
-rw-r--r-- | lld/test/ELF/mips-tls-hilo.s | 39 |
2 files changed, 59 insertions, 0 deletions
diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index e76e0a9e61d..fda8975c95f 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -1677,6 +1677,10 @@ void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P, uint64_t S, uint64_t ZA, uint8_t *PairedLoc) const { const endianness E = ELFT::TargetEndianness; + // Thread pointer and DRP offsets from the start of TLS data area. + // https://www.linux-mips.org/wiki/NPTL + const uint32_t TPOffset = 0x7000; + const uint32_t DTPOffset = 0x8000; switch (Type) { case R_MIPS_32: add32<E>(Loc, S); @@ -1747,6 +1751,18 @@ void MipsTargetInfo<ELFT>::relocateOne(uint8_t *Loc, uint8_t *BufEnd, case R_MIPS_PCLO16: writeMipsLo16<E>(Loc, S + readSignedLo16<E>(Loc) - P); break; + case R_MIPS_TLS_DTPREL_HI16: + writeMipsHi16<E>(Loc, S - DTPOffset + readSignedLo16<E>(Loc)); + break; + case R_MIPS_TLS_DTPREL_LO16: + writeMipsLo16<E>(Loc, S - DTPOffset + readSignedLo16<E>(Loc)); + break; + case R_MIPS_TLS_TPREL_HI16: + writeMipsHi16<E>(Loc, S - TPOffset + readSignedLo16<E>(Loc)); + break; + case R_MIPS_TLS_TPREL_LO16: + writeMipsLo16<E>(Loc, S - TPOffset + readSignedLo16<E>(Loc)); + break; default: fatal("unrecognized reloc " + Twine(Type)); } @@ -1767,6 +1783,10 @@ bool MipsTargetInfo<ELFT>::isRelRelative(uint32_t Type) const { case R_MIPS_64: case R_MIPS_HI16: case R_MIPS_LO16: + case R_MIPS_TLS_DTPREL_HI16: + case R_MIPS_TLS_DTPREL_LO16: + case R_MIPS_TLS_TPREL_HI16: + case R_MIPS_TLS_TPREL_LO16: return false; } } diff --git a/lld/test/ELF/mips-tls-hilo.s b/lld/test/ELF/mips-tls-hilo.s new file mode 100644 index 00000000000..31d3d59e28c --- /dev/null +++ b/lld/test/ELF/mips-tls-hilo.s @@ -0,0 +1,39 @@ +# Check MIPS R_MIPS_TLS_DTPREL_HI16/LO16 and R_MIPS_TLS_TPREL_HI16/LO16 +# relocations handling. + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t.exe +# RUN: llvm-objdump -d -t %t.exe | FileCheck -check-prefix=DIS %s +# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s + +# REQUIRES: mips + +# DIS: __start: +# DIS-NEXT: 20000: 24 62 00 00 addiu $2, $3, 0 +# %hi(loc0 - .tdata - 0x8000) --^ +# DIS-NEXT: 20004: 24 62 80 00 addiu $2, $3, -32768 +# %lo(loc0 - .tdata - 0x8000) --^ +# DIS-NEXT: 20008: 24 62 00 00 addiu $2, $3, 0 +# %hi(loc0 - .tdata - 0x7000) --^ +# DIS-NEXT: 2000c: 24 62 90 00 addiu $2, $3, -28672 +# %lo(loc0 - .tdata - 0x7000) --^ + +# DIS: 00030000 l .tdata 00000000 .tdata +# DIS: 00030000 l .tdata 00000000 loc0 + +# CHECK: Relocations [ +# CHECK-NEXT: ] +# CHECK-NOT: Primary GOT + + .text + .globl __start + .type __start,@function +__start: + addiu $2, $3, %dtprel_hi(loc0) # R_MIPS_TLS_DTPREL_HI16 + addiu $2, $3, %dtprel_lo(loc0) # R_MIPS_TLS_DTPREL_LO16 + addiu $2, $3, %tprel_hi(loc0) # R_MIPS_TLS_TPREL_HI16 + addiu $2, $3, %tprel_lo(loc0) # R_MIPS_TLS_TPREL_LO16 + + .section .tdata,"awT",%progbits +loc0: + .word 0 |