1 //===- SPARCV9.cpp --------------------------------------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "InputFiles.h"
12 #include "SyntheticSections.h"
14 #include "lld/Common/ErrorHandler.h"
15 #include "llvm/Support/Endian.h"
18 using namespace llvm::support::endian;
19 using namespace llvm::ELF;
21 using namespace lld::elf;
24 class SPARCV9 final : public TargetInfo {
27 RelExpr getRelExpr(RelType Type, const Symbol &S,
28 const uint8_t *Loc) const override;
29 void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
30 int32_t Index, unsigned RelOff) const override;
31 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override;
36 CopyRel = R_SPARC_COPY;
37 GotRel = R_SPARC_GLOB_DAT;
38 PltRel = R_SPARC_JMP_SLOT;
39 RelativeRel = R_SPARC_RELATIVE;
42 PltHeaderSize = 4 * PltEntrySize;
45 DefaultMaxPageSize = 0x100000;
46 DefaultImageBase = 0x100000;
49 RelExpr SPARCV9::getRelExpr(RelType Type, const Symbol &S,
50 const uint8_t *Loc) const {
75 void SPARCV9::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const {
80 checkUInt<32>(Loc, Val, Type);
85 checkInt<32>(Loc, Val, Type);
91 checkInt<32>(Loc, Val, Type);
92 write32be(Loc, (read32be(Loc) & ~0x3fffffff) | ((Val >> 2) & 0x3fffffff));
96 checkUInt<22>(Loc, Val, Type);
97 write32be(Loc, (read32be(Loc) & ~0x003fffff) | (Val & 0x003fffff));
102 write32be(Loc, (read32be(Loc) & ~0x003fffff) | ((Val >> 10) & 0x003fffff));
104 case R_SPARC_WDISP19:
106 checkInt<21>(Loc, Val, Type);
107 write32be(Loc, (read32be(Loc) & ~0x0007ffff) | ((Val >> 2) & 0x0007ffff));
112 write32be(Loc, (read32be(Loc) & ~0x000003ff) | (Val & 0x000003ff));
116 case R_SPARC_GLOB_DAT:
121 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
125 void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
126 uint64_t PltEntryAddr, int32_t Index,
127 unsigned RelOff) const {
128 const uint8_t PltData[] = {
129 0x03, 0x00, 0x00, 0x00, // sethi (. - .PLT0), %g1
130 0x30, 0x68, 0x00, 0x00, // ba,a %xcc, .PLT1
131 0x01, 0x00, 0x00, 0x00, // nop
132 0x01, 0x00, 0x00, 0x00, // nop
133 0x01, 0x00, 0x00, 0x00, // nop
134 0x01, 0x00, 0x00, 0x00, // nop
135 0x01, 0x00, 0x00, 0x00, // nop
136 0x01, 0x00, 0x00, 0x00 // nop
138 memcpy(Buf, PltData, sizeof(PltData));
140 uint64_t Off = PltHeaderSize + Index * PltEntrySize;
141 relocateOne(Buf, R_SPARC_22, Off);
142 relocateOne(Buf + 4, R_SPARC_WDISP19, -(Off + 4 - PltEntrySize));
145 TargetInfo *elf::getSPARCV9TargetInfo() {
146 static SPARCV9 Target;