LLVM: lib/ExecutionEngine/JITLink/ELF_systemz.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

16

21

22#define DEBUG_TYPE "jitlink"

23

24using namespace llvm;

26

27namespace {

28

29constexpr StringRef ELFGOTSymbolName = "_GLOBAL_OFFSET_TABLE_";

30

37}

38

39}

40

41namespace llvm {

45

46public:

48 std::unique_ptr G,

53 [this](LinkGraph &G) { return getOrCreateGOTSymbol(G); });

54 }

55

56private:

57 Symbol *GOTSymbol = nullptr;

58

61 }

62

64 auto DefineExternalGOTSymbolIfPresent =

67 if (Sym.getName() != nullptr &&

68 *Sym.getName() == ELFGOTSymbolName)

69 if (auto *GOTSection = G.findSectionByName(

71 GOTSymbol = &Sym;

72 return {*GOTSection, true};

73 }

74 return {};

75 });

76

77

78

79 if (auto Err = DefineExternalGOTSymbolIfPresent(G))

80 return Err;

81

82

83 if (GOTSymbol)

85

86

87

88

89 if (auto *GOTSection =

91

92

93 for (auto *Sym : GOTSection->symbols())

94 if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {

95 GOTSymbol = Sym;

97 }

98

99

100 SectionRange SR(*GOTSection);

101 if (SR.empty())

102 GOTSymbol =

103 &G.addAbsoluteSymbol(ELFGOTSymbolName, orc::ExecutorAddr(), 0,

105 else

106 GOTSymbol =

107 &G.addDefinedSymbol(*SR.getFirstBlock(), 0, ELFGOTSymbolName, 0,

109 }

110

111

112

113

114 if (!GOTSymbol) {

115 for (auto *Sym : G.external_symbols()) {

116 if (Sym->getName() != nullptr && *Sym->getName() == ELFGOTSymbolName) {

117 auto Blocks = G.blocks();

118 if (!Blocks.empty()) {

119 G.makeAbsolute(*Sym, (*Blocks.begin())->getAddress());

120 GOTSymbol = Sym;

121 break;

122 }

123 }

124 }

125 }

126

128 }

129};

130

133private:

136 using Base::G;

137

140

145

147 G->getTargetTriple().getArchName() +

148 " ELF object files",

150

152 &Self::addSingleRelocation))

153 return Err;

154 }

155

157 }

158

159 Error addSingleRelocation(const typename ELFT::Rela &Rel,

160 const typename ELFT::Shdr &FixupSect,

161 Block &BlockToFix) {

164 auto ELFReloc = Rel.getType(false);

165

166

169

170 uint32_t SymbolIndex = Rel.getSymbol(false);

172 if (!ObjSymbol)

173 return ObjSymbol.takeError();

174

176 if (!GraphSymbol)

178 formatv("Could not find symbol at given index, did you add it to "

179 "JITSymbolTable? index: {0}, shndx: {1} Size of table: {2}",

180 SymbolIndex, (*ObjSymbol)->st_shndx,

183

184

185 int64_t Addend = Rel.r_addend;

186 Edge::Kind Kind = Edge::Invalid;

187

188 switch (ELFReloc) {

189 case ELF::R_390_PC64: {

191 break;

192 }

193 case ELF::R_390_PC32: {

195 break;

196 }

197 case ELF::R_390_PC16: {

199 break;

200 }

201 case ELF::R_390_PC32DBL: {

203 break;

204 }

205 case ELF::R_390_PC24DBL: {

207 break;

208 }

209 case ELF::R_390_PC16DBL: {

211 break;

212 }

213 case ELF::R_390_PC12DBL: {

215 break;

216 }

217 case ELF::R_390_64: {

219 break;

220 }

221 case ELF::R_390_32: {

223 break;

224 }

225 case ELF::R_390_20: {

227 break;

228 }

229 case ELF::R_390_16: {

231 break;

232 }

233 case ELF::R_390_12: {

235 break;

236 }

237 case ELF::R_390_8: {

239 break;

240 }

241

242 case ELF::R_390_PLT64: {

244 break;

245 }

246 case ELF::R_390_PLT32: {

248 break;

249 }

250 case ELF::R_390_PLT32DBL: {

252 break;

253 }

254 case ELF::R_390_PLT24DBL: {

256 break;

257 }

258 case ELF::R_390_PLT16DBL: {

260 break;

261 }

262 case ELF::R_390_PLT12DBL: {

264 break;

265 }

266 case ELF::R_390_PLTOFF64: {

268 break;

269 }

270 case ELF::R_390_PLTOFF32: {

272 break;

273 }

274 case ELF::R_390_PLTOFF16: {

276 break;

277 }

278

279 case ELF::R_390_GOTOFF64: {

281 break;

282 }

283 case ELF::R_390_GOTOFF: {

285 break;

286 }

287 case ELF::R_390_GOTOFF16: {

289 break;

290 }

291

292 case ELF::R_390_GOT64:

293 case ELF::R_390_GOTPLT64: {

295 break;

296 }

297 case ELF::R_390_GOT32:

298 case ELF::R_390_GOTPLT32: {

300 break;

301 }

302 case ELF::R_390_GOT20:

303 case ELF::R_390_GOTPLT20: {

305 break;

306 }

307 case ELF::R_390_GOT16:

308 case ELF::R_390_GOTPLT16: {

310 break;

311 }

312 case ELF::R_390_GOT12:

313 case ELF::R_390_GOTPLT12: {

315 break;

316 }

317 case ELF::R_390_GOTENT:

318 case ELF::R_390_GOTPLTENT: {

320 break;

321 }

322

323

324 case ELF::R_390_GOTPC: {

326 break;

327 }

328 case ELF::R_390_GOTPCDBL: {

330 break;

331 }

332 default:

334 "In " + G->getName() + ": Unsupported systemz relocation type " +

336 }

337 auto FixupAddress = orc::ExecutorAddr(FixupSect.sh_addr) + Rel.r_offset;

338 Edge::OffsetT Offset = FixupAddress - BlockToFix.getAddress();

339 Edge GE(Kind, Offset, *GraphSymbol, Addend);

341 dbgs() << " ";

343 dbgs() << "\n";

344 });

345

346 BlockToFix.addEdge(std::move(GE));

347

349 }

350

351public:

354 std::shared_ptrorc::SymbolStringPool SSP,

357 std::move(Features), FileName,

358 systemz::getEdgeKindName) {}

359};

360

362 MemoryBufferRef ObjectBuffer, std::shared_ptrorc::SymbolStringPool SSP) {

364 dbgs() << "Building jitlink graph for new input "

366 });

367

369 if (!ELFObj)

370 return ELFObj.takeError();

371

372 auto Features = (*ELFObj)->getFeatures();

373 if (!Features)

374 return Features.takeError();

375

377 "Only SystemZ is supported");

378

381 (*ELFObj)->getFileName(), ELFObjFile.getELFFile(), std::move(SSP),

382 (*ELFObj)->makeTriple(), std::move(*Features))

384}

385

387 std::unique_ptr Ctx) {

389 const Triple &TT = G->getTargetTriple();

390 if (Ctx->shouldAddDefaultTargetPasses(TT)) {

391

398

399

400 if (auto MarkLive = Ctx->getMarkLivePass(TT))

401 Config.PrePrunePasses.push_back(std::move(MarkLive));

402 else

404

405

406 Config.PostPrunePasses.push_back(buildTables_ELF_systemz);

407

408

412

413

414

415 }

416

417 if (auto Err = Ctx->modifyPassConfig(*G, Config))

418 return Ctx->notifyFailed(std::move(Err));

419

421}

422

423}

424}

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

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define LLVM_UNLIKELY(EXPR)

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

StringRef getBufferIdentifier() const

StringRef - Represent a constant reference to a string, i.e.

Manages the enabling and disabling of subtarget specific features.

Triple - Helper class for working with autoconf configuration names.

orc::ExecutorAddr getAddress() const

An Addressable with content and edges.

void addEdge(Edge::Kind K, Edge::OffsetT Offset, Symbol &Target, Edge::AddendT Addend)

Add an edge to this block.

A LinkGraph pass that splits blocks in a section that follows the DWARF Record format into sub-blocks...

A LinkGraph pass that adds missing FDE-to-CIE, FDE-to-PC and FDE-to-LSDA edges.

ELFJITLinker_systemz(std::unique_ptr< JITLinkContext > Ctx, std::unique_ptr< LinkGraph > G, PassConfiguration PassConfig)

Definition ELF_systemz.cpp:47

std::unique_ptr< LinkGraph > G

Definition ELF_systemz.cpp:132

ELFLinkGraphBuilder_systemz(StringRef FileName, const object::ELFFile< ELFT > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features)

Definition ELF_systemz.cpp:352

const ELFFile::Elf_Shdr * SymTabSec

virtual Error addRelocations()=0

ELFLinkGraphBuilder(const object::ELFFile< object::ELF64BE > &Obj, std::shared_ptr< orc::SymbolStringPool > SSP, Triple TT, SubtargetFeatures Features, StringRef FileName, LinkGraph::GetEdgeKindNameFunction GetEdgeKindName)

Expected< std::unique_ptr< LinkGraph > > buildGraph()

Attempt to construct and return the LinkGraph.

DenseMap< ELFSymbolIndex, Symbol * > GraphSymbols

ELFFile::Elf_Shdr_Range Sections

Error forEachRelaRelocation(const typename ELFT::Shdr &RelSect, RelocHandlerMethod &&Func)

Traverse all matching ELFT::Rela relocation records in the given section.

Symbol * getGraphSymbol(ELFSymbolIndex SymIndex)

Represents fixups and constraints in the LinkGraph.

PassConfiguration & getPassConfig()

bool shouldAddDefaultTargetPasses(const Triple &TT)

static void link(ArgTs &&... Args)

const orc::SymbolStringPtr & getName() const

Returns the name of this symbol (empty if the symbol is anonymous).

Global Offset Table Builder.

static StringRef getSectionName()

Procedure Linkage Table Builder.

static Expected< std::unique_ptr< ObjectFile > > createELFObjectFile(MemoryBufferRef Object, bool InitContent=true)

Represents an address in the executor process.

Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const Symbol *GOTSymbol)

Apply fixup expression for edge to block content.

@ DeltaPLT32

A 32-bit Delta.

@ Delta64PLTFromGOT

A 64-bit offset from GOT to PLT.

@ Pointer16

A plain 16-bit pointer value relocation.

@ RequestGOTAndTransformToDelta32FromGOT

A GOT entry getter/constructor, transformed to Delta32FromGOT pointing at the GOT entry for the origi...

@ RequestGOTAndTransformToDelta32dbl

A GOT entry getter/constructor, transformed to Delta32dbl pointing at the GOT entry for the original ...

@ Pointer64

A plain 64-bit pointer value relocation.

@ Pointer20

A plain 20-bit pointer value relocation.

@ RequestGOTAndTransformToDelta16FromGOT

A GOT entry getter/constructor, transformed to Delta16FromGOT pointing at the GOT entry for the origi...

@ RequestGOTAndTransformToDelta12FromGOT

A GOT entry getter/constructor, transformed to Delta12FromGOT pointing at the GOT entry for the origi...

@ RequestGOTAndTransformToDelta64FromGOT

A GOT entry getter/constructor, transformed to Delta64FromGOT pointing at the GOT entry for the origi...

@ DeltaPLT16dbl

A 16-bit Delta shifted by 1.

@ Delta16FromGOT

A 16-bit offset from GOT.

@ Pointer8

A plain 8-bit pointer value relocation.

@ Delta16PLTFromGOT

A 16-bit offset from GOT to PLT.

@ Delta32PLTFromGOT

A 32-bit offset from GOT to PLT.

@ Delta32dblGOTBase

A 32-bit Delta to GOT base shifted by 1.

@ Delta32FromGOT

A 32-bit offset from GOT.

@ Delta32GOTBase

A 32-bit Delta to GOT base.

@ DeltaPLT12dbl

A 12-bit Delta shifted by 1.

@ RequestGOTAndTransformToDelta20FromGOT

A GOT entry getter/constructor, transformed to Delta20FromGOT pointing at the GOT entry for the origi...

@ Delta16dbl

A 16-bit delta shifted by 1.

@ DeltaPLT32dbl

A 32-bit Delta shifted by 1.

@ NegDelta32

A 32-bit negative delta.

@ Delta24dbl

A 24-bit delta shifted by 1.

@ DeltaPLT64

A 64-bit Delta.

@ DeltaPLT24dbl

A 24-bit Delta shifted by 1.

@ Pointer12

A plain 12-bit pointer value relocation.

@ Delta12dbl

A 12-bit delta shifted by 1.

@ Pointer32

A plain 32-bit pointer value relocation.

@ Delta32dbl

A 32-bit delta shifted by 1.

@ Delta64FromGOT

A 64-bit offset from GOT.

const char * getEdgeKindName(Edge::Kind K)

Returns a string name for the given systemz edge.

void visitExistingEdges(LinkGraph &G, VisitorTs &&...Vs)

For each edge in the given graph, apply a list of visitors to the edge, stopping when the first visit...

void link_ELF_systemz(std::unique_ptr< LinkGraph > G, std::unique_ptr< JITLinkContext > Ctx)

jit-link the given object buffer, which must be a ELF systemz relocatable object file.

Definition ELF_systemz.cpp:386

LLVM_ABI Error markAllSymbolsLive(LinkGraph &G)

Marks all symbols in a graph live.

LLVM_ABI void printEdge(raw_ostream &OS, const Block &B, const Edge &E, StringRef EdgeKindName)

SectionRangeSymbolDesc identifyELFSectionStartAndEndSymbols(LinkGraph &G, Symbol &Sym)

ELF section start/end symbol detection.

DefineExternalSectionStartAndEndSymbols< SymbolIdentifierFunction > createDefineExternalSectionStartAndEndSymbolsPass(SymbolIdentifierFunction &&F)

Returns a JITLink pass (as a function class) that uses the given symbol identification function to id...

Expected< std::unique_ptr< LinkGraph > > createLinkGraphFromELFObject_systemz(MemoryBufferRef ObjectBuffer, std::shared_ptr< orc::SymbolStringPool > SSP)

Create a LinkGraph from an ELF/systemz relocatable object.

Definition ELF_systemz.cpp:361

LLVM_ABI StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type)

ELFType< llvm::endianness::big, true > ELF64BE

detail::packed_endian_specific_integral< int32_t, llvm::endianness::big, unaligned > big32_t

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

LLVM_ABI raw_ostream & dbgs()

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

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

Implement std::hash so that hash_code can be used in STL containers.

An LinkGraph pass configuration, consisting of a list of pre-prune, post-prune, and post-fixup passes...

LinkGraphPassList PostAllocationPasses

Post-allocation passes.

LinkGraphPassList PostPrunePasses

Post-prune passes.

LinkGraphPassList PrePrunePasses

Pre-prune passes.

Elf_Rel_Impl< ELFType< E, Is64 >, true > Rela

Elf_Shdr_Impl< ELFType< E, Is64 > > Shdr