LLVM: lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

21#include

22#include

23

24using namespace llvm;

25

26namespace {

27enum X86_32RelType { RT32_NONE, RT32_32, RT32_16, RT32_8 };

28enum X86_64RelType { RT64_NONE, RT64_64, RT64_32, RT64_32S, RT64_16, RT64_8 };

29

31public:

32 X86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine);

33 ~X86ELFObjectWriter() override = default;

34

35protected:

36 unsigned getRelocType(const MCFixup &, const MCValue &,

37 bool IsPCRel) const override;

38 bool needsRelocateWithSymbol(const MCValue &, unsigned Type) const override;

39

40 void checkIs32(SMLoc Loc, X86_64RelType Type) const;

41 void checkIs64(SMLoc Loc, X86_64RelType Type) const;

42 unsigned getRelocType32(SMLoc Loc, X86::Specifier Specifier,

43 X86_32RelType Type, bool IsPCRel,

45 unsigned getRelocType64(SMLoc Loc, X86::Specifier Specifier,

46 X86_64RelType Type, bool IsPCRel,

48};

49

50}

51

52X86ELFObjectWriter::X86ELFObjectWriter(bool IsELF64, uint8_t OSABI,

55

56

59

61 bool &IsPCRel) {

62 switch (unsigned(Kind)) {

63 default:

66 return RT64_NONE;

68 return RT64_64;

72 return RT64_32S;

73 return RT64_32;

76 IsPCRel = true;

77 return RT64_32;

86 return RT64_32;

89 return RT64_32;

91 return RT64_16;

93 return RT64_8;

94 }

95}

96

97void X86ELFObjectWriter::checkIs32(SMLoc Loc, X86_64RelType Type) const {

98 if (Type != RT64_32)

99 reportError(Loc, "32 bit reloc applied to a field with a different size");

100}

101

102void X86ELFObjectWriter::checkIs64(SMLoc Loc, X86_64RelType Type) const {

103 if (Type != RT64_64)

104 reportError(Loc, "64 bit reloc applied to a field with a different size");

105}

106

107unsigned X86ELFObjectWriter::getRelocType64(SMLoc Loc, X86::Specifier Specifier,

108 X86_64RelType Type, bool IsPCRel,

110 switch (Specifier) {

111 default:

115 switch (Type) {

116 case RT64_NONE:

118 return ELF::R_X86_64_NONE;

120 case RT64_64:

121 return IsPCRel ? ELF::R_X86_64_PC64 : ELF::R_X86_64_64;

122 case RT64_32:

123 return IsPCRel ? ELF::R_X86_64_PC32 : ELF::R_X86_64_32;

124 case RT64_32S:

125 return ELF::R_X86_64_32S;

126 case RT64_16:

127 return IsPCRel ? ELF::R_X86_64_PC16 : ELF::R_X86_64_16;

128 case RT64_8:

129 return IsPCRel ? ELF::R_X86_64_PC8 : ELF::R_X86_64_8;

130 }

133 switch (Type) {

134 case RT64_64:

135 return IsPCRel ? ELF::R_X86_64_GOTPC64 : ELF::R_X86_64_GOT64;

136 case RT64_32:

137 return IsPCRel ? ELF::R_X86_64_GOTPC32 : ELF::R_X86_64_GOT32;

138 case RT64_32S:

139 case RT64_16:

140 case RT64_8:

141 case RT64_NONE:

143 }

147 if (Type != RT64_64)

148 reportError(Loc, "unsupported relocation type");

149 return ELF::R_X86_64_GOTOFF64;

152 switch (Type) {

153 case RT64_64:

154 return ELF::R_X86_64_TPOFF64;

155 case RT64_32:

156 return ELF::R_X86_64_TPOFF32;

157 case RT64_32S:

158 case RT64_16:

159 case RT64_8:

160 case RT64_NONE:

162 }

166 switch (Type) {

167 case RT64_64:

168 return ELF::R_X86_64_DTPOFF64;

169 case RT64_32:

170 return ELF::R_X86_64_DTPOFF32;

171 case RT64_32S:

172 case RT64_16:

173 case RT64_8:

174 case RT64_NONE:

176 }

180 switch (Type) {

181 case RT64_64:

182 return ELF::R_X86_64_SIZE64;

183 case RT64_32:

184 return ELF::R_X86_64_SIZE32;

185 case RT64_32S:

186 case RT64_16:

187 case RT64_8:

188 case RT64_NONE:

190 }

193 return ELF::R_X86_64_TLSDESC_CALL;

196 ? ELF::R_X86_64_CODE_4_GOTPC32_TLSDESC

197 : ELF::R_X86_64_GOTPC32_TLSDESC;

199 checkIs32(Loc, Type);

200 return ELF::R_X86_64_TLSGD;

202 checkIs32(Loc, Type);

205 return ELF::R_X86_64_CODE_4_GOTTPOFF;

207 return ELF::R_X86_64_CODE_6_GOTTPOFF;

208 return ELF::R_X86_64_GOTTPOFF;

210 checkIs32(Loc, Type);

211 return ELF::R_X86_64_TLSLD;

213 checkIs32(Loc, Type);

214 return ELF::R_X86_64_PLT32;

216 checkIs32(Loc, Type);

217

218

219

220 if (getContext().getTargetOptions()->X86RelaxRelocations)

221 return ELF::R_X86_64_GOTPCREL;

222 switch (unsigned(Kind)) {

223 default:

224 return ELF::R_X86_64_GOTPCREL;

226 return ELF::R_X86_64_GOTPCRELX;

229 return ELF::R_X86_64_REX_GOTPCRELX;

232 return ELF::R_X86_64_CODE_4_GOTPCRELX;

233 }

236 checkIs32(Loc, Type);

237 return ELF::R_X86_64_GOTPCREL;

239 checkIs64(Loc, Type);

240 return ELF::R_X86_64_PLTOFF64;

241 }

242}

243

244unsigned X86ELFObjectWriter::getRelocType32(SMLoc Loc, X86::Specifier Specifier,

245 X86_32RelType Type, bool IsPCRel,

247 switch (Specifier) {

248 default:

252 switch (Type) {

253 case RT32_NONE:

255 return ELF::R_386_NONE;

257 case RT32_32:

258 return IsPCRel ? ELF::R_386_PC32 : ELF::R_386_32;

259 case RT32_16:

260 return IsPCRel ? ELF::R_386_PC16 : ELF::R_386_16;

261 case RT32_8:

262 return IsPCRel ? ELF::R_386_PC8 : ELF::R_386_8;

263 }

266 if (Type != RT32_32)

267 break;

268 if (IsPCRel)

269 return ELF::R_386_GOTPC;

270

271

272 if (getContext().getTargetOptions()->X86RelaxRelocations)

273 return ELF::R_386_GOT32;

274

276 : ELF::R_386_GOT32;

279 if (Type != RT32_32)

280 break;

281 return ELF::R_386_GOTOFF;

283 return ELF::R_386_TLS_DESC_CALL;

285 return ELF::R_386_TLS_GOTDESC;

287 if (Type != RT32_32)

288 break;

290 return ELF::R_386_TLS_LE_32;

292 if (Type != RT32_32)

293 break;

295 return ELF::R_386_TLS_LDO_32;

297 if (Type != RT32_32)

298 break;

300 return ELF::R_386_TLS_GD;

302 if (Type != RT32_32)

303 break;

305 return ELF::R_386_TLS_IE_32;

307 if (Type != RT32_32)

308 break;

309 return ELF::R_386_PLT32;

311 if (Type != RT32_32)

312 break;

314 return ELF::R_386_TLS_IE;

316 if (Type != RT32_32)

317 break;

319 return ELF::R_386_TLS_LE;

321 if (Type != RT32_32)

322 break;

324 return ELF::R_386_TLS_GOTIE;

326 if (Type != RT32_32)

327 break;

329 return ELF::R_386_TLS_LDM;

330 }

331 reportError(Loc, "unsupported relocation type");

332 return ELF::R_386_NONE;

333}

334

335unsigned X86ELFObjectWriter::getRelocType(const MCFixup &Fixup,

336 const MCValue &Target,

337 bool IsPCRel) const {

340 switch (Specifier) {

352 if (auto *S = const_cast<MCSymbol *>(Target.getAddSym()))

353 static_cast<MCSymbolELF *>(S)->setType(ELF::STT_TLS);

354 break;

355 default:

356 break;

357 }

358

359 X86_64RelType Type = getType64(Kind, Specifier, IsPCRel);

361 return getRelocType64(Fixup.getLoc(), Specifier, Type, IsPCRel, Kind);

362

364 "Unsupported ELF machine type.");

365

366 X86_32RelType RelType = RT32_NONE;

367 switch (Type) {

368 case RT64_NONE:

369 break;

370 case RT64_64:

372 return ELF::R_386_NONE;

373 case RT64_32:

374 case RT64_32S:

375 RelType = RT32_32;

376 break;

377 case RT64_16:

378 RelType = RT32_16;

379 break;

380 case RT64_8:

381 RelType = RT32_8;

382 break;

383 }

384 return getRelocType32(Fixup.getLoc(), Specifier, RelType, IsPCRel, Kind);

385}

386

387bool X86ELFObjectWriter::needsRelocateWithSymbol(const MCValue &V,

388 unsigned Type) const {

389 switch (V.getSpecifier()) {

394 return true;

395 default:

396 return false;

397 }

398}

399

400std::unique_ptr

402 return std::make_unique(IsELF64, OSABI, EMachine);

403}

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

static Error reportError(StringRef Message)

PowerPC TLS Dynamic Call Fixup

static X86_64RelType getType64(MCFixupKind Kind, X86::Specifier &Specifier, bool &IsPCRel)

Definition X86ELFObjectWriter.cpp:60

Represents a location in source code.

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

#define llvm_unreachable(msg)

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

@ reloc_riprel_4byte_movq_load_rex2

@ reloc_signed_4byte_relax

@ reloc_branch_4byte_pcrel

@ reloc_riprel_4byte_relax

@ reloc_riprel_4byte_relax_evex

@ reloc_riprel_4byte_relax_rex

@ reloc_global_offset_table

@ reloc_riprel_4byte_movq_load

@ reloc_riprel_4byte_relax_rex2

Context & getContext() const

This is an optimization pass for GlobalISel generic memory operations.

uint16_t MCFixupKind

Extensible enumeration to represent the type of a fixup.

@ FK_Data_8

A eight-byte fixup.

@ FK_Data_1

A one-byte fixup.

@ FK_Data_4

A four-byte fixup.

@ FK_Data_2

A two-byte fixup.

std::unique_ptr< MCObjectTargetWriter > createX86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine)

Construct an X86 ELF object writer.

Definition X86ELFObjectWriter.cpp:401