1 //===- SPARCV9.cpp --------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "InputFiles.h" 11 #include "Symbols.h" 12 #include "SyntheticSections.h" 13 #include "Target.h" 14 #include "lld/Common/ErrorHandler.h" 15 #include "llvm/Support/Endian.h" 16 17 using namespace llvm; 18 using namespace llvm::support::endian; 19 using namespace llvm::ELF; 20 using namespace lld; 21 using namespace lld::elf; 22 23 namespace { 24 class SPARCV9 final : public TargetInfo { 25 public: 26 SPARCV9(); 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; 32 }; 33 } // namespace 34 35 SPARCV9::SPARCV9() { 36 CopyRel = R_SPARC_COPY; 37 GotRel = R_SPARC_GLOB_DAT; 38 NoneRel = R_SPARC_NONE; 39 PltRel = R_SPARC_JMP_SLOT; 40 RelativeRel = R_SPARC_RELATIVE; 41 GotEntrySize = 8; 42 PltEntrySize = 32; 43 PltHeaderSize = 4 * PltEntrySize; 44 45 PageSize = 8192; 46 DefaultMaxPageSize = 0x100000; 47 DefaultImageBase = 0x100000; 48 } 49 50 RelExpr SPARCV9::getRelExpr(RelType Type, const Symbol &S, 51 const uint8_t *Loc) const { 52 switch (Type) { 53 case R_SPARC_32: 54 case R_SPARC_UA32: 55 case R_SPARC_64: 56 case R_SPARC_UA64: 57 return R_ABS; 58 case R_SPARC_PC10: 59 case R_SPARC_PC22: 60 case R_SPARC_DISP32: 61 case R_SPARC_WDISP30: 62 return R_PC; 63 case R_SPARC_GOT10: 64 return R_GOT_OFF; 65 case R_SPARC_GOT22: 66 return R_GOT_OFF; 67 case R_SPARC_WPLT30: 68 return R_PLT_PC; 69 case R_SPARC_NONE: 70 return R_NONE; 71 default: 72 return R_INVALID; 73 } 74 } 75 76 void SPARCV9::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { 77 switch (Type) { 78 case R_SPARC_32: 79 case R_SPARC_UA32: 80 // V-word32 81 checkUInt(Loc, Val, 32, Type); 82 write32be(Loc, Val); 83 break; 84 case R_SPARC_DISP32: 85 // V-disp32 86 checkInt(Loc, Val, 32, Type); 87 write32be(Loc, Val); 88 break; 89 case R_SPARC_WDISP30: 90 case R_SPARC_WPLT30: 91 // V-disp30 92 checkInt(Loc, Val, 32, Type); 93 write32be(Loc, (read32be(Loc) & ~0x3fffffff) | ((Val >> 2) & 0x3fffffff)); 94 break; 95 case R_SPARC_22: 96 // V-imm22 97 checkUInt(Loc, Val, 22, Type); 98 write32be(Loc, (read32be(Loc) & ~0x003fffff) | (Val & 0x003fffff)); 99 break; 100 case R_SPARC_GOT22: 101 case R_SPARC_PC22: 102 // T-imm22 103 write32be(Loc, (read32be(Loc) & ~0x003fffff) | ((Val >> 10) & 0x003fffff)); 104 break; 105 case R_SPARC_WDISP19: 106 // V-disp19 107 checkInt(Loc, Val, 21, Type); 108 write32be(Loc, (read32be(Loc) & ~0x0007ffff) | ((Val >> 2) & 0x0007ffff)); 109 break; 110 case R_SPARC_GOT10: 111 case R_SPARC_PC10: 112 // T-simm10 113 write32be(Loc, (read32be(Loc) & ~0x000003ff) | (Val & 0x000003ff)); 114 break; 115 case R_SPARC_64: 116 case R_SPARC_UA64: 117 case R_SPARC_GLOB_DAT: 118 // V-xword64 119 write64be(Loc, Val); 120 break; 121 default: 122 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); 123 } 124 } 125 126 void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr, 127 uint64_t PltEntryAddr, int32_t Index, 128 unsigned RelOff) const { 129 const uint8_t PltData[] = { 130 0x03, 0x00, 0x00, 0x00, // sethi (. - .PLT0), %g1 131 0x30, 0x68, 0x00, 0x00, // ba,a %xcc, .PLT1 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 137 0x01, 0x00, 0x00, 0x00 // nop 138 }; 139 memcpy(Buf, PltData, sizeof(PltData)); 140 141 uint64_t Off = getPltEntryOffset(Index); 142 relocateOne(Buf, R_SPARC_22, Off); 143 relocateOne(Buf + 4, R_SPARC_WDISP19, -(Off + 4 - PltEntrySize)); 144 } 145 146 TargetInfo *elf::getSPARCV9TargetInfo() { 147 static SPARCV9 Target; 148 return &Target; 149 } 150