Index: lld/ELF/Arch/SPARCV9.cpp =================================================================== --- lld/ELF/Arch/SPARCV9.cpp +++ lld/ELF/Arch/SPARCV9.cpp @@ -25,6 +25,7 @@ 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, @@ -45,6 +46,14 @@ 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, @@ -69,7 +78,7 @@ case R_SPARC_WDISP30: return R_PC; case R_SPARC_GOT10: - return R_GOT_OFF; + case R_SPARC_GOT13: case R_SPARC_GOT22: return R_GOT_OFF; case R_SPARC_WPLT30: @@ -127,6 +136,11 @@ checkInt(loc, val, 21, rel); write32be(loc, (read32be(loc) & ~0x0007ffff) | ((val >> 2) & 0x0007ffff)); break; + case R_SPARC_GOT13: + // V-simm13 + checkInt(loc, val, 13, rel); + write32be(loc, (read32be(loc) & ~0x00001fff) | (val & 0x000003ff)); + break; case R_SPARC_GOT10: case R_SPARC_PC10: // T-simm10 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-reloc-got.s =================================================================== --- /dev/null +++ lld/test/ELF/sparcv9-reloc-got.s @@ -0,0 +1,24 @@ +# REQUIRES: sparc +# RUN: llvm-mc -filetype=obj -triple=sparcv9 %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s +# RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOC %s + +# 13-bit PIC + +# CHECK: ldx [%l7+8], %o0 +ldx [%l7 + %got13(x)], %o0 + +# 32-bit PIC + +# CHECK-NEXT: sethi 0, %o1 +# CHECK-NEXT: add %o1, 16, %o1 +# CHECK-NEXT: ldx [%l7+%o1], %o0 +sethi %got22(y), %o1 +add %o1, %got10(y), %o1 +ldx [%l7 + %o1], %o0 + +# RELOC: .rela.dyn { +# RELOC-NEXT: R_SPARC_GLOB_DAT x 0x0 +# RELOC-NEXT: R_SPARC_GLOB_DAT y 0x0 +# RELOC-NEXT: }