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

1

2

3

4

5

6

7

8

10

23

24using namespace llvm;

26

27#define DEBUG_TYPE "jitlink"

28

29namespace {

30

31enum JITLinkErrorCode { GenericJITLinkError = 1 };

32

33

34

35

36class JITLinkerErrorCategory : public std::error_category {

37public:

38 const char *name() const noexcept override { return "runtimedyld"; }

39

40 std::string message(int Condition) const override {

41 switch (static_cast<JITLinkErrorCode>(Condition)) {

42 case GenericJITLinkError:

43 return "Generic JITLink error";

44 }

46 }

47};

48

49}

50

51namespace llvm {

53

55

57

59 static JITLinkerErrorCategory TheJITLinkerErrorCategory;

60 return std::error_code(GenericJITLinkError, TheJITLinkerErrorCategory);

61}

62

64 switch (K) {

65 case Edge::Invalid:

66 return "INVALID RELOCATION";

67 case Edge::KeepAlive:

68 return "Keep-Alive";

69 default:

70 return "";

71 }

72}

73

75 switch (L) {

77 return "strong";

79 return "weak";

80 }

82}

83

85 switch (S) {

87 return "default";

89 return "hidden";

91 return "side-effects-only";

93 return "local";

94 }

96}

97

99 if (B.getSize() == 0)

100 return false;

101

102

103 if (B.isZeroFill())

104 return B.getSize() == 1;

105

106 for (size_t I = 0; I != B.getSize() - 1; ++I)

107 if (B.getContent()[I] == '\0')

108 return false;

109

110 return B.getContent()[B.getSize() - 1] == '\0';

111}

112

114 return OS << B.getAddress() << " -- " << (B.getAddress() + B.getSize())

115 << ": "

116 << "size = " << formatv("{0:x8}", B.getSize()) << ", "

117 << (B.isZeroFill() ? "zero-fill" : "content")

118 << ", align = " << B.getAlignment()

119 << ", align-ofs = " << B.getAlignmentOffset()

120 << ", section = " << B.getSection().getName();

121}

122

124 OS << Sym.getAddress() << " (" << (Sym.isDefined() ? "block" : "addressable")

129 << (Sym.isLive() ? "live" : "dead") << " - "

130 << (Sym.hasName() ? *Sym.getName() : "");

131 return OS;

132}

133

136 OS << "edge@" << B.getAddress() + E.getOffset() << ": " << B.getAddress()

137 << " + " << formatv("{0:x}", E.getOffset()) << " -- " << EdgeKindName

138 << " -> ";

139

140 auto &TargetSym = E.getTarget();

141 if (TargetSym.hasName())

142 OS << TargetSym.getName();

143 else {

144 auto &TargetBlock = TargetSym.getBlock();

145 auto &TargetSec = TargetBlock.getSection();

147 for (auto *B : TargetSec.blocks())

148 if (B->getAddress() < SecAddress)

149 SecAddress = B->getAddress();

150

152 OS << TargetSym.getAddress() << " (section " << TargetSec.getName();

153 if (SecDelta)

154 OS << " + " << formatv("{0:x}", SecDelta);

155 OS << " / block " << TargetBlock.getAddress();

156 if (TargetSym.getOffset())

157 OS << " + " << formatv("{0:x}", TargetSym.getOffset());

158 OS << ")";

159 }

160

161 if (E.getAddend() != 0)

162 OS << " + " << E.getAddend();

163}

164

166 for (auto *Sym : Symbols)

167 Sym->~Symbol();

168 for (auto *B : Blocks)

169 B->~Block();

170}

171

173 for (auto *Sym : AbsoluteSymbols) {

174 Sym->~Symbol();

175 }

177 Sym->~Symbol();

178 }

179 ExternalSymbols.clear();

180}

181

182std::vector<Block *> LinkGraph::splitBlockImpl(std::vector<Block *> Blocks,

183 SplitBlockCache *Cache) {

184 assert(!Blocks.empty() && "Blocks must at least contain the original block");

185

186

187 ArrayRef Content = Blocks.front()->getContent();

188 for (size_t I = 0; I != Blocks.size() - 1; ++I) {

189 Blocks[I]->setContent(

190 Content.slice(Blocks[I]->getAddress() - Blocks[0]->getAddress(),

191 Blocks[I + 1]->getAddress() - Blocks[I]->getAddress()));

192 }

193 Blocks.back()->setContent(

194 Content.slice(Blocks.back()->getAddress() - Blocks[0]->getAddress()));

195 bool IsMutable = Blocks[0]->ContentMutable;

196 for (auto *B : Blocks)

197 B->ContentMutable = IsMutable;

198

199

200 {

202 if (!Cache)

203 Cache = &LocalBlockSymbolsCache;

204

205

206 if (*Cache == std::nullopt) {

207 *Cache = SplitBlockCache::value_type();

208

209 for (auto *Sym : Blocks[0]->getSection().symbols())

210 if (&Sym->getBlock() == Blocks[0])

211 (*Cache)->push_back(Sym);

212 llvm::sort(**Cache, [](const Symbol *LHS, const Symbol *RHS) {

213 return LHS->getAddress() > RHS->getAddress();

214 });

215 }

216

217 auto TransferSymbol = [](Symbol &Sym, Block &B) {

218 Sym.setOffset(Sym.getAddress() - B.getAddress());

219 Sym.setBlock(B);

220 if (Sym.getSize() > B.getSize())

221 Sym.setSize(B.getSize() - Sym.getOffset());

222 };

223

224

225 for (size_t I = 0; I != Blocks.size() - 1; ++I) {

226 if ((*Cache)->empty())

227 break;

228 while (!(*Cache)->empty() &&

229 (*Cache)->back()->getAddress() < Blocks[I + 1]->getAddress()) {

230 TransferSymbol(*(*Cache)->back(), *Blocks[I]);

231 (*Cache)->pop_back();

232 }

233 }

234

235 while (!(*Cache)->empty()) {

236 auto &Sym = *(*Cache)->back();

237 (*Cache)->pop_back();

238 assert(Sym.getAddress() >= Blocks.back()->getAddress() &&

239 "Symbol address preceeds block");

240 assert(Sym.getAddress() <= Blocks.back()->getRange().End &&

241 "Symbol address starts past end of block");

242 TransferSymbol(Sym, *Blocks.back());

243 }

244 }

245

246

247 auto &Edges = Blocks[0]->Edges;

249 return LHS.getOffset() < RHS.getOffset();

250 });

251

252 for (size_t I = Blocks.size() - 1; I != 0; --I) {

253

254

255 if (Edges.empty())

256 break;

257

258 Edge::OffsetT Delta = Blocks[I]->getAddress() - Blocks[0]->getAddress();

259

260

261 if (Edges.back().getOffset() < Delta)

262 continue;

263

264 size_t EI = Edges.size() - 1;

265 while (EI != 0 && Edges[EI - 1].getOffset() >= Delta)

266 --EI;

267

268 for (size_t J = EI; J != Edges.size(); ++J) {

269 Blocks[I]->Edges.push_back(std::move(Edges[J]));

270 Blocks[I]->Edges.back().setOffset(Blocks[I]->Edges.back().getOffset() -

271 Delta);

272 }

273

274 while (Edges.size() > EI)

275 Edges.pop_back();

276 }

277

278 return Blocks;

279}

280

283

284 OS << "LinkGraph \"" << getName()

286

287

289 BlockSymbols[&Sym->getBlock()].push_back(Sym);

290

291

292

293 for (auto &KV : BlockSymbols)

295 if (LHS->getOffset() != RHS->getOffset())

296 return LHS->getOffset() < RHS->getOffset();

297 if (LHS->getLinkage() != RHS->getLinkage())

298 return LHS->getLinkage() < RHS->getLinkage();

299 if (LHS->getScope() != RHS->getScope())

300 return LHS->getScope() < RHS->getScope();

301 if (LHS->hasName()) {

302 if (!RHS->hasName())

303 return true;

304 return LHS->getName() < RHS->getName();

305 }

306 return false;

307 });

308

309 std::vector<Section *> SortedSections;

311 SortedSections.push_back(&Sec);

313 return LHS->getName() < RHS->getName();

314 });

315

316 for (auto *Sec : SortedSections) {

317 OS << "section " << Sec->getName() << ":\n\n";

318

319 std::vector<Block *> SortedBlocks;

322 return LHS->getAddress() < RHS->getAddress();

323 });

324

325 for (auto *B : SortedBlocks) {

326 OS << " block " << B->getAddress()

327 << " size = " << formatv("{0:x8}", B->getSize())

328 << ", align = " << B->getAlignment()

329 << ", alignment-offset = " << B->getAlignmentOffset();

330 if (B->isZeroFill())

331 OS << ", zero-fill";

332 OS << "\n";

333

334 auto BlockSymsI = BlockSymbols.find(B);

335 if (BlockSymsI != BlockSymbols.end()) {

336 OS << " symbols:\n";

337 auto &Syms = BlockSymsI->second;

338 for (auto *Sym : Syms)

339 OS << " " << *Sym << "\n";

340 } else

341 OS << " no symbols\n";

342

343 if (B->edges_empty()) {

344 OS << " edges:\n";

345 std::vector SortedEdges;

348 return LHS.getOffset() < RHS.getOffset();

349 });

350 for (auto &E : SortedEdges) {

351 OS << " " << B->getFixupAddress(E) << " (block + "

352 << formatv("{0:x8}", E.getOffset()) << "), addend = ";

353 if (E.getAddend() >= 0)

354 OS << formatv("+{0:x8}", E.getAddend());

355 else

356 OS << formatv("-{0:x8}", -E.getAddend());

357 OS << ", kind = " << getEdgeKindName(E.getKind()) << ", target = ";

358 if (E.getTarget().hasName())

359 OS << E.getTarget().getName();

360 else

361 OS << "addressable@"

362 << formatv("{0:x16}", E.getTarget().getAddress()) << "+"

363 << formatv("{0:x8}", E.getTarget().getOffset());

364 OS << "\n";

365 }

366 } else

367 OS << " no edges\n";

368 OS << "\n";

369 }

370 }

371

372 OS << "Absolute symbols:\n";

373 if (!absolute_symbols().empty()) {

374 for (auto *Sym : absolute_symbols())

375 OS << " " << Sym->getAddress() << ": " << *Sym << "\n";

376 } else

377 OS << " none\n";

378

379 OS << "\nExternal symbols:\n";

380 if (!external_symbols().empty()) {

381 for (auto *Sym : external_symbols())

382 OS << " " << Sym->getAddress() << ": " << *Sym

383 << (Sym->isWeaklyReferenced() ? " (weakly referenced)" : "") << "\n";

384 } else

385 OS << " none\n";

386}

387

389 switch (LF) {

391 return OS << "RequiredSymbol";

393 return OS << "WeaklyReferencedSymbol";

394 }

396}

397

398void JITLinkAsyncLookupContinuation::anchor() {}

399

400JITLinkContext::~JITLinkContext() = default;

401

405

409

414

416 for (auto *Sym : G.defined_symbols())

417 Sym->setLive(true);

419}

420

422 const Edge &E) {

423 std::string ErrMsg;

424 {

426 Section &Sec = B.getSection();

427 ErrStream << "In graph " << G.getName() << ", section " << Sec.getName()

428 << ": relocation target "

429 << formatv("{0:x}", E.getTarget().getAddress() + E.getAddend())

430 << " (";

431 if (E.getTarget().hasName())

432 ErrStream << E.getTarget().getName();

433 else

434 ErrStream << "";

435 if (E.getAddend()) {

436

437 ErrStream << formatv(":{0:x}", E.getTarget().getAddress()) << " + "

438 << formatv("{0:x}", E.getAddend());

439 }

440 ErrStream << ") is out of range of " << G.getEdgeKindName(E.getKind())

441 << " fixup at address "

442 << formatv("{0:x}", E.getTarget().getAddress()) << " (";

443

444 Symbol *BestSymbolForBlock = nullptr;

445 for (auto *Sym : Sec.symbols())

446 if (&Sym->getBlock() == &B && Sym->hasName() && Sym->getOffset() == 0 &&

447 (!BestSymbolForBlock ||

448 Sym->getScope() < BestSymbolForBlock->getScope() ||

449 Sym->getLinkage() < BestSymbolForBlock->getLinkage()))

450 BestSymbolForBlock = Sym;

451

452 if (BestSymbolForBlock)

453 ErrStream << BestSymbolForBlock->getName() << ", ";

454 else

455 ErrStream << " @ ";

456

457 ErrStream << formatv("{0:x}", B.getAddress()) << " + "

458 << formatv("{0:x}", E.getOffset()) << ")";

459 }

461}

462

464 const Edge &E) {

466 " improper alignment for relocation " +

467 formatv("{0:d}", E.getKind()) + ": 0x" +

469 " is not aligned to " + Twine(N) + " bytes");

470}

471

473 switch (TT.getArch()) {

485 default:

486 return nullptr;

487 }

488}

489

491 switch (TT.getArch()) {

503 default:

504 return nullptr;

505 }

506}

507

510 std::shared_ptrorc::SymbolStringPool SSP) {

512 switch (Magic) {

521 default:

523 };

524}

525

526std::unique_ptr

529 static std::atomic<uint64_t> Counter = {0};

530 auto Index = Counter.fetch_add(1, std::memory_order_relaxed);

531 auto G = std::make_unique(

532 "<Absolute Symbols " + std::to_string(Index) + ">", std::move(SSP),

534 for (auto &[Name, Def] : Symbols) {

535 auto &Sym =

536 G->addAbsoluteSymbol(*Name, Def.getAddress(), 0,

538 Sym.setCallable(Def.getFlags().isCallable());

539 }

540

541 return G;

542}

543

544void link(std::unique_ptr G, std::unique_ptr Ctx) {

545 switch (G->getTargetTriple().getObjectFormat()) {

547 return link_MachO(std::move(G), std::move(Ctx));

549 return link_ELF(std::move(G), std::move(Ctx));

551 return link_COFF(std::move(G), std::move(Ctx));

553 return link_XCOFF(std::move(G), std::move(Ctx));

554 default:

556 };

557}

558

559}

560}

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

bbsections Prepares for basic block sections

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

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

std::pair< BasicBlock *, BasicBlock * > Edge

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

ArrayRef< T > slice(size_t N, size_t M) const

slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.

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 getBuffer() 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.

const std::string & str() const

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

An Addressable with content and edges.

Represents fixups and constraints in the LinkGraph.

virtual Error modifyPassConfig(LinkGraph &G, PassConfiguration &Config)

Called by JITLink to modify the pass pipeline prior to linking.

Definition JITLink.cpp:410

virtual bool shouldAddDefaultTargetPasses(const Triple &TT) const

Called by JITLink prior to linking to determine whether default passes for the target should be added...

Definition JITLink.cpp:402

virtual LinkGraphPassFunction getMarkLivePass(const Triple &TT) const

Returns the mark-live pass to be used for this link.

Definition JITLink.cpp:406

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

Definition JITLink.cpp:58

void log(raw_ostream &OS) const override

Print an error message to an output stream.

Definition JITLink.cpp:56

const std::string & getName() const

Returns the name of this graph (usually the name of the original underlying MemoryBuffer).

LLVM_ABI ~LinkGraph()

Definition JITLink.cpp:172

LLVM_ABI void dump(raw_ostream &OS)

Dump the graph.

Definition JITLink.cpp:281

iterator_range< external_symbol_iterator > external_symbols()

const Triple & getTargetTriple() const

Returns the target triple for this Graph.

iterator_range< defined_symbol_iterator > defined_symbols()

std::optional< SmallVector< Symbol *, 8 > > SplitBlockCache

Cache type for the splitBlock function.

Represents an object file section.

iterator_range< symbol_iterator > symbols()

Returns an iterator over the symbols defined in this section.

StringRef getName() const

Returns the name of this section.

LLVM_ABI ~Section()

Definition JITLink.cpp:165

bool isLive() const

Returns true if this symbol is live (i.e.

const orc::SymbolStringPtr & getName() const

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

bool isDefined() const

Returns true if this Symbol has content (potentially) defined within this object file (i....

Scope getScope() const

Get the visibility for this Symbol.

Linkage getLinkage() const

Get the linkage for this Symbol.

orc::ExecutorAddr getAddress() const

Returns the address of this symbol.

orc::ExecutorAddrDiff getSize() const

Returns the size of this symbol.

orc::ExecutorAddrDiff getOffset() const

Returns the offset for this symbol within the underlying addressable.

bool hasName() const

Returns true if this symbol has a name.

Represents an address in the executor process.

This class implements an extremely fast bulk output stream that can only output to a stream.

A raw_ostream that writes to an std::string.

#define llvm_unreachable(msg)

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

LLVM_ABI const char * getEdgeKindName(Edge::Kind K)

Get a human-readable name for the given AArch32 edge kind.

Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, uint64_t InitialAddend=0)

Creates a new pointer block in the given section and returns an Anonymous symbol pointing to it.

Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)

Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...

Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)

Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...

Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, uint64_t InitialAddend=0)

Creates a new pointer block in the given section and returns an Anonymous symbol pointing to it.

Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)

Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...

Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, uint64_t InitialAddend=0)

Creates a new pointer block in the given section and returns an Anonymous symbol pointing to it.

Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, uint64_t InitialAddend=0)

Creates a new pointer block in the given section and returns an anonymous symbol pointing to it.

Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)

Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...

Symbol & createAnonymousPointerJumpStub(LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)

Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...

Symbol & createAnonymousPointer(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget=nullptr, uint64_t InitialAddend=0)

Creates a new pointer block in the given section and returns an anonymous symbol pointing to it.

unique_function< Error(LinkGraph &)> LinkGraphPassFunction

A function for mutating LinkGraphs.

LLVM_ABI Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B, const Edge &E)

Create an out of range error for the given edge in the given block.

Definition JITLink.cpp:421

LLVM_ABI const char * getGenericEdgeKindName(Edge::Kind K)

Returns the string name of the given generic edge kind, or "unknown" otherwise.

Definition JITLink.cpp:63

LLVM_ABI const char * getLinkageName(Linkage L)

For errors and debugging output.

Definition JITLink.cpp:74

SymbolLookupFlags

Flags for symbol lookup.

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

Create a LinkGraph from an COFF relocatable object.

LLVM_ABI std::unique_ptr< LinkGraph > absoluteSymbolsLinkGraph(Triple TT, std::shared_ptr< orc::SymbolStringPool > SSP, orc::SymbolMap Symbols)

Create a LinkGraph defining the given absolute symbols.

Definition JITLink.cpp:527

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

Create a LinkGraph from an ELF relocatable object.

LLVM_ABI Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N, const Edge &E)

Definition JITLink.cpp:463

LLVM_ABI raw_ostream & operator<<(raw_ostream &OS, const Block &B)

Definition JITLink.cpp:113

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

Create a LinkGraph from an XCOFF relocatable object.

LLVM_ABI PointerJumpStubCreator getPointerJumpStubCreator(const Triple &TT)

Get target-specific PointerJumpStubCreator.

Definition JITLink.cpp:490

unique_function< Symbol &( LinkGraph &G, Section &StubSection, Symbol &PointerSymbol)> PointerJumpStubCreator

Create a jump stub that jumps via the pointer at the given symbol and an anonymous symbol pointing to...

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

Link the given graph.

Definition JITLink.cpp:544

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

Create a LinkGraph from a MachO relocatable object.

LLVM_ABI Error markAllSymbolsLive(LinkGraph &G)

Marks all symbols in a graph live.

Definition JITLink.cpp:415

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

Link the given graph.

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

Link the given graph.

LLVM_ABI const char * getScopeName(Scope S)

For debugging output.

Definition JITLink.cpp:84

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

Create a LinkGraph from the given object buffer.

Definition JITLink.cpp:509

Linkage

Describes symbol linkage. This can be used to resolve definition clashes.

unique_function< Symbol &(LinkGraph &G, Section &PointerSection, Symbol *InitialTarget, uint64_t InitialAddend)> AnonymousPointerCreator

Creates a new pointer block in the given section and returns an Anonymous symbol pointing to it.

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

Definition JITLink.cpp:134

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

Link the given graph.

Scope

Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...

LLVM_ABI bool isCStringBlock(Block &B)

Definition JITLink.cpp:98

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

jit-link the given ObjBuffer, which must be a MachO object file.

LLVM_ABI AnonymousPointerCreator getAnonymousPointerCreator(const Triple &TT)

Get target-specific AnonymousPointerCreator.

Definition JITLink.cpp:472

Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)

uint64_t ExecutorAddrDiff

DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap

A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI file_magic identify_magic(StringRef magic)

Identify the type of a binary file based on how magical it is.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)

static Error getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)

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

void sort(IteratorTy Start, IteratorTy End)

Error make_error(ArgTs &&... Args)

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

raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)

@ elf_relocatable

ELF Relocatable object file.

@ xcoff_object_64

64-bit XCOFF object file

@ macho_object

Mach-O Object file.

@ coff_object

COFF object file.

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