Index: lld/ELF/Arch/SPARCV9.cpp =================================================================== --- lld/ELF/Arch/SPARCV9.cpp +++ lld/ELF/Arch/SPARCV9.cpp @@ -25,10 +25,13 @@ SPARCV9(); RelExpr getRelExpr(RelType type, const Symbol &s, const uint8_t *loc) const override; + void writeGotHeader(uint8_t *buf) const override; void writePlt(uint8_t *buf, const Symbol &sym, uint64_t pltEntryAddr) const override; void relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const override; + void relaxTlsIeToLe(uint8_t *loc, const Relocation &, + uint64_t val) const override; }; } // namespace @@ -42,9 +45,19 @@ pltEntrySize = 32; pltHeaderSize = 4 * pltEntrySize; + tlsGotRel = R_SPARC_TLS_TPOFF64; + defaultCommonPageSize = 8192; defaultMaxPageSize = 0x100000; defaultImageBase = 0x100000; + + // .got[0] = _DYNAMIC + gotBaseSymInGotPlt = false; + gotHeaderEntriesNum = 1; +} + +void SPARCV9::writeGotHeader(uint8_t *buf) const { + write32(buf, mainPart->dynamic->getVA()); } RelExpr SPARCV9::getRelExpr(RelType type, const Symbol &s, @@ -79,6 +92,11 @@ case R_SPARC_TLS_LE_HIX22: case R_SPARC_TLS_LE_LOX10: return R_TPREL; + case R_SPARC_TLS_IE_HI22: + case R_SPARC_TLS_IE_LO10: + case R_SPARC_TLS_IE_LDX: + case R_SPARC_TLS_IE_ADD: + return R_GOT_OFF; default: error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) + ") against symbol " + toString(s)); @@ -111,6 +129,7 @@ checkUInt(loc, val, 22, rel); write32be(loc, (read32be(loc) & ~0x003fffff) | (val & 0x003fffff)); break; + case R_SPARC_TLS_IE_HI22: case R_SPARC_GOT22: case R_SPARC_PC22: case R_SPARC_LM22: @@ -132,6 +151,7 @@ // T-simm10 write32be(loc, (read32be(loc) & ~0x000003ff) | (val & 0x000003ff)); break; + case R_SPARC_TLS_IE_LO10: case R_SPARC_LO10: // T-simm13 write32be(loc, (read32be(loc) & ~0x00001fff) | (val & 0x000003ff)); @@ -171,11 +191,36 @@ // T-simm13 write32be(loc, (read32be(loc) & ~0x00001fff) | (val & 0x000003ff) | 0x1C00); break; + case R_SPARC_TLS_IE_LDX: + case R_SPARC_TLS_IE_ADD: + break; default: llvm_unreachable("unknown relocation"); } } +void SPARCV9::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, + uint64_t val) const { + switch (rel.type) { + case R_SPARC_TLS_IE_ADD: + return; + case R_SPARC_TLS_IE_LDX: + // call ldx [%r1 + %r2], %r3 -> nop + write32(loc, 0x01000000); + return; + case R_SPARC_TLS_IE_HI22: + relocateNoSym(loc, R_SPARC_TLS_LE_HIX22, val); + return; + case R_SPARC_TLS_IE_LO10: + // or %r1, %tie_lo10(sym), %r2 -> xor %r1, %tle_lox10(sym), %r2 + write32be(loc, (read32be(loc) & ~0x01f80000) | 0x180000); + relocateNoSym(loc, R_SPARC_TLS_LE_LOX10, val); + return; + default: + llvm_unreachable("unsupported relocation for TLS IE to LE relaxation"); + } +} + void SPARCV9::writePlt(uint8_t *buf, const Symbol & /*sym*/, uint64_t pltEntryAddr) const { const uint8_t pltData[] = { Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -926,7 +926,7 @@ // Otherwise use the psABI defined relocation entry format. uint16_t m = config->emachine; return m == EM_AARCH64 || m == EM_AMDGPU || m == EM_HEXAGON || m == EM_PPC || - m == EM_PPC64 || m == EM_RISCV || m == EM_X86_64; + m == EM_PPC64 || m == EM_RISCV || m == EM_SPARCV9 || m == EM_X86_64; } static void parseClangOption(StringRef opt, const Twine &msg) { Index: lld/test/ELF/sparcv9-tls-ie.s =================================================================== --- /dev/null +++ lld/test/ELF/sparcv9-tls-ie.s @@ -0,0 +1,33 @@ +# REQUIRES: sparc +# RUN: llvm-mc -filetype=obj -triple=sparcv9 %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOC %s +# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=RELAX %s + +# CHECK: sethi 0, %o0 +# CHECK-NEXT: or %o0, 8, %o0 +# CHECK-NEXT: ldx [%l7+%o0], %o0 +# CHECK-NEXT: add %g7, %o0, %o0 + +# IE -> LE Relaxation + +# RELAX: sethi 1, %o0 +# RELAX-NEXT: xor %o0, -2, %o0 +# RELAX-NEXT: nop +# RELAX-NEXT: add %g7, %o0, %o0 +sethi %tie_hi22(a), %o0 +or %o0, %tie_lo10(a), %o0 +ldx [%l7 + %o0], %o0, %tie_ldx(a) +add %g7, %o0, %o0, %tie_add(a) + +.section .tbss +.globl a +a: +.zero 1024+2 +b: + +# RELOC: .rela.dyn { +# RELOC-NEXT: R_SPARC_TLS_TPOFF64 a 0x0 +# RELOC-NEXT: }