LLVM: lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

11

12#define DEBUG_TYPE "dyld"

13

28

37 }

39}

40

41void RuntimeDyldELFMips::applyRelocation(const RelocationEntry &RE,

47 return;

48 }

50}

51

52int64_t

53RuntimeDyldELFMips::evaluateMIPS32Relocation(const SectionEntry &Section,

55 uint32_t Type) {

56

57 LLVM_DEBUG(dbgs() << "evaluateMIPS32Relocation, LocalAddress: 0x"

59 << " FinalAddress: 0x"

61 << " Value: 0x" << format("%llx", Value) << " Type: 0x"

63

64 switch (Type) {

65 default:

68 case ELF::R_MIPS_32:

70 case ELF::R_MIPS_26:

71 return Value >> 2;

72 case ELF::R_MIPS_HI16:

73

74 return (Value + 0x8000) >> 16;

75 case ELF::R_MIPS_LO16:

77 case ELF::R_MIPS_PC32: {

78 uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

79 return Value - FinalAddress;

80 }

81 case ELF::R_MIPS_PC16: {

82 uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

83 return (Value - FinalAddress) >> 2;

84 }

85 case ELF::R_MIPS_PC19_S2: {

86 uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

87 return (Value - (FinalAddress & ~0x3)) >> 2;

88 }

89 case ELF::R_MIPS_PC21_S2: {

90 uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

91 return (Value - FinalAddress) >> 2;

92 }

93 case ELF::R_MIPS_PC26_S2: {

94 uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

95 return (Value - FinalAddress) >> 2;

96 }

97 case ELF::R_MIPS_PCHI16: {

98 uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

99 return (Value - FinalAddress + 0x8000) >> 16;

100 }

101 case ELF::R_MIPS_PCLO16: {

102 uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

103 return Value - FinalAddress;

104 }

105 }

106}

107

108int64_t RuntimeDyldELFMips::evaluateMIPS64Relocation(

110 int64_t Addend, uint64_t SymOffset, SID SectionID) {

111

112 LLVM_DEBUG(dbgs() << "evaluateMIPS64Relocation, LocalAddress: 0x"

114 << " FinalAddress: 0x"

116 << " Value: 0x" << format("%llx", Value) << " Type: 0x"

117 << format("%x", Type) << " Addend: 0x"

118 << format("%llx", Addend)

119 << " Offset: " << format("%llx" PRIx64, Offset)

120 << " SID: " << format("%d", SectionID)

121 << " SymOffset: " << format("%x", SymOffset) << "\n");

122

123 switch (Type) {

124 default:

126 break;

127 case ELF::R_MIPS_JALR:

128 case ELF::R_MIPS_NONE:

129 break;

130 case ELF::R_MIPS_32:

131 case ELF::R_MIPS_64:

132 return Value + Addend;

133 case ELF::R_MIPS_26:

134 return ((Value + Addend) >> 2) & 0x3ffffff;

135 case ELF::R_MIPS_GPREL16: {

137 return Value + Addend - (GOTAddr + 0x7ff0);

138 }

139 case ELF::R_MIPS_SUB:

140 return Value - Addend;

141 case ELF::R_MIPS_HI16:

142

143 return ((Value + Addend + 0x8000) >> 16) & 0xffff;

144 case ELF::R_MIPS_LO16:

145 return (Value + Addend) & 0xffff;

146 case ELF::R_MIPS_HIGHER:

147 return ((Value + Addend + 0x80008000) >> 32) & 0xffff;

148 case ELF::R_MIPS_HIGHEST:

149 return ((Value + Addend + 0x800080008000) >> 48) & 0xffff;

150 case ELF::R_MIPS_CALL16:

151 case ELF::R_MIPS_GOT_DISP:

152 case ELF::R_MIPS_GOT_PAGE: {

153 uint8_t *LocalGOTAddr =

156

158 if (Type == ELF::R_MIPS_GOT_PAGE)

160

161 if (GOTEntry)

163 "GOT entry has two different addresses.");

164 else

166

167 return (SymOffset - 0x7ff0) & 0xffff;

168 }

169 case ELF::R_MIPS_GOT_OFST: {

170 int64_t page = (Value + Addend + 0x8000) & ~0xffff;

171 return (Value + Addend - page) & 0xffff;

172 }

173 case ELF::R_MIPS_GPREL32: {

175 return Value + Addend - (GOTAddr + 0x7ff0);

176 }

177 case ELF::R_MIPS_PC16: {

178 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

179 return ((Value + Addend - FinalAddress) >> 2) & 0xffff;

180 }

181 case ELF::R_MIPS_PC32: {

182 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

183 return Value + Addend - FinalAddress;

184 }

185 case ELF::R_MIPS_PC18_S3: {

186 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

187 return ((Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff;

188 }

189 case ELF::R_MIPS_PC19_S2: {

190 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

191 return ((Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;

192 }

193 case ELF::R_MIPS_PC21_S2: {

194 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

195 return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff;

196 }

197 case ELF::R_MIPS_PC26_S2: {

198 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

199 return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff;

200 }

201 case ELF::R_MIPS_PCHI16: {

202 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

203 return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff;

204 }

205 case ELF::R_MIPS_PCLO16: {

206 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

207 return (Value + Addend - FinalAddress) & 0xffff;

208 }

209 }

210 return 0;

211}

212

213void RuntimeDyldELFMips::applyMIPSRelocation(uint8_t *TargetPtr, int64_t Value,

214 uint32_t Type) {

216

217 switch (Type) {

218 default:

220 break;

221 case ELF::R_MIPS_GPREL16:

222 case ELF::R_MIPS_HI16:

223 case ELF::R_MIPS_LO16:

224 case ELF::R_MIPS_HIGHER:

225 case ELF::R_MIPS_HIGHEST:

226 case ELF::R_MIPS_PC16:

227 case ELF::R_MIPS_PCHI16:

228 case ELF::R_MIPS_PCLO16:

229 case ELF::R_MIPS_CALL16:

230 case ELF::R_MIPS_GOT_DISP:

231 case ELF::R_MIPS_GOT_PAGE:

232 case ELF::R_MIPS_GOT_OFST:

233 Insn = (Insn & 0xffff0000) | (Value & 0x0000ffff);

235 break;

236 case ELF::R_MIPS_PC18_S3:

237 Insn = (Insn & 0xfffc0000) | (Value & 0x0003ffff);

239 break;

240 case ELF::R_MIPS_PC19_S2:

241 Insn = (Insn & 0xfff80000) | (Value & 0x0007ffff);

243 break;

244 case ELF::R_MIPS_PC21_S2:

245 Insn = (Insn & 0xffe00000) | (Value & 0x001fffff);

247 break;

248 case ELF::R_MIPS_26:

249 case ELF::R_MIPS_PC26_S2:

250 Insn = (Insn & 0xfc000000) | (Value & 0x03ffffff);

252 break;

253 case ELF::R_MIPS_32:

254 case ELF::R_MIPS_GPREL32:

255 case ELF::R_MIPS_PC32:

257 break;

258 case ELF::R_MIPS_64:

259 case ELF::R_MIPS_SUB:

261 break;

262 }

263}

264

267 int64_t Addend, uint64_t SymOffset, SID SectionID) {

268 int64_t CalculatedValue = evaluateMIPS64Relocation(

269 Section, Offset, Value, Type, Addend, SymOffset, SectionID);

270 applyMIPSRelocation(Section.getAddressWithOffset(Offset), CalculatedValue,

272}

273

276 int64_t Addend, uint64_t SymOffset, SID SectionID) {

280

281

282

284 int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value,

285 RelType, Addend,

286 SymOffset, SectionID);

287 if (r_type2 != ELF::R_MIPS_NONE) {

288 RelType = r_type2;

289 CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,

290 CalculatedValue, SymOffset,

291 SectionID);

292 }

293 if (r_type3 != ELF::R_MIPS_NONE) {

294 RelType = r_type3;

295 CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType,

296 CalculatedValue, SymOffset,

297 SectionID);

298 }

299 applyMIPSRelocation(Section.getAddressWithOffset(Offset), CalculatedValue,

300 RelType);

301}

302

306 int32_t Addend) {

307 uint8_t *TargetPtr = Section.getAddressWithOffset(Offset);

309

310 LLVM_DEBUG(dbgs() << "resolveMIPSO32Relocation, LocalAddress: "

311 << Section.getAddressWithOffset(Offset) << " FinalAddress: "

312 << format("%p", Section.getLoadAddressWithOffset(Offset))

313 << " Value: " << format("%x", Value) << " Type: "

315 << " SymOffset: " << format("%x", Offset) << "\n");

316

318

319 applyMIPSRelocation(TargetPtr, Value, Type);

320}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

RelocationEntry - used to represent relocations internally in the dynamic linker.

uint32_t RelType

RelType - relocation type.

uint64_t Offset

Offset - offset into the section.

int64_t Addend

Addend - the relocation addend encoded in the instruction itself.

unsigned SectionID

SectionID - the section this relocation points to.

void resolveMIPSN32Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, uint64_t SymOffset, SID SectionID)

Definition RuntimeDyldELFMips.cpp:265

void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override

A object file specific relocation resolver.

Definition RuntimeDyldELFMips.cpp:14

void resolveMIPSN64Relocation(const SectionEntry &Section, uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend, uint64_t SymOffset, SID SectionID)

Definition RuntimeDyldELFMips.cpp:274

void resolveMIPSO32Relocation(const SectionEntry &Section, uint64_t Offset, uint32_t Value, uint32_t Type, int32_t Addend)

Definition RuntimeDyldELFMips.cpp:303

size_t getGOTEntrySize() override

DenseMap< SID, SID > SectionToGOTMap

void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const

Endian-aware write.

uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const

Endian-aware read Read the least significant Size bytes from Src.

uint64_t getSectionLoadAddress(unsigned SectionID) const

uint8_t * getSectionAddress(unsigned SectionID) const

SectionEntry - represents a section emitted into memory by the dynamic linker.

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

FunctionAddr VTableAddr Value

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.