1 //===------------- JITLink.cpp - Core Run-time JIT linker APIs ------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
10
11 #include "llvm/BinaryFormat/Magic.h"
12 #include "llvm/ExecutionEngine/JITLink/COFF.h"
13 #include "llvm/ExecutionEngine/JITLink/ELF.h"
14 #include "llvm/ExecutionEngine/JITLink/MachO.h"
15 #include "llvm/Support/Format.h"
16 #include "llvm/Support/MemoryBuffer.h"
17 #include "llvm/Support/raw_ostream.h"
18
19 using namespace llvm;
20 using namespace llvm::object;
21
22 #define DEBUG_TYPE "jitlink"
23
24 namespace {
25
26 enum JITLinkErrorCode { GenericJITLinkError = 1 };
27
28 // FIXME: This class is only here to support the transition to llvm::Error. It
29 // will be removed once this transition is complete. Clients should prefer to
30 // deal with the Error value directly, rather than converting to error_code.
31 class JITLinkerErrorCategory : public std::error_category {
32 public:
name() const33 const char *name() const noexcept override { return "runtimedyld"; }
34
message(int Condition) const35 std::string message(int Condition) const override {
36 switch (static_cast<JITLinkErrorCode>(Condition)) {
37 case GenericJITLinkError:
38 return "Generic JITLink error";
39 }
40 llvm_unreachable("Unrecognized JITLinkErrorCode");
41 }
42 };
43
44 } // namespace
45
46 namespace llvm {
47 namespace jitlink {
48
49 char JITLinkError::ID = 0;
50
log(raw_ostream & OS) const51 void JITLinkError::log(raw_ostream &OS) const { OS << ErrMsg; }
52
convertToErrorCode() const53 std::error_code JITLinkError::convertToErrorCode() const {
54 static JITLinkerErrorCategory TheJITLinkerErrorCategory;
55 return std::error_code(GenericJITLinkError, TheJITLinkerErrorCategory);
56 }
57
getGenericEdgeKindName(Edge::Kind K)58 const char *getGenericEdgeKindName(Edge::Kind K) {
59 switch (K) {
60 case Edge::Invalid:
61 return "INVALID RELOCATION";
62 case Edge::KeepAlive:
63 return "Keep-Alive";
64 default:
65 return "<Unrecognized edge kind>";
66 }
67 }
68
getLinkageName(Linkage L)69 const char *getLinkageName(Linkage L) {
70 switch (L) {
71 case Linkage::Strong:
72 return "strong";
73 case Linkage::Weak:
74 return "weak";
75 }
76 llvm_unreachable("Unrecognized llvm.jitlink.Linkage enum");
77 }
78
getScopeName(Scope S)79 const char *getScopeName(Scope S) {
80 switch (S) {
81 case Scope::Default:
82 return "default";
83 case Scope::Hidden:
84 return "hidden";
85 case Scope::Local:
86 return "local";
87 }
88 llvm_unreachable("Unrecognized llvm.jitlink.Scope enum");
89 }
90
operator <<(raw_ostream & OS,const Block & B)91 raw_ostream &operator<<(raw_ostream &OS, const Block &B) {
92 return OS << B.getAddress() << " -- " << (B.getAddress() + B.getSize())
93 << ": "
94 << "size = " << formatv("{0:x8}", B.getSize()) << ", "
95 << (B.isZeroFill() ? "zero-fill" : "content")
96 << ", align = " << B.getAlignment()
97 << ", align-ofs = " << B.getAlignmentOffset()
98 << ", section = " << B.getSection().getName();
99 }
100
operator <<(raw_ostream & OS,const Symbol & Sym)101 raw_ostream &operator<<(raw_ostream &OS, const Symbol &Sym) {
102 OS << Sym.getAddress() << " (" << (Sym.isDefined() ? "block" : "addressable")
103 << " + " << formatv("{0:x8}", Sym.getOffset())
104 << "): size: " << formatv("{0:x8}", Sym.getSize())
105 << ", linkage: " << formatv("{0:6}", getLinkageName(Sym.getLinkage()))
106 << ", scope: " << formatv("{0:8}", getScopeName(Sym.getScope())) << ", "
107 << (Sym.isLive() ? "live" : "dead") << " - "
108 << (Sym.hasName() ? Sym.getName() : "<anonymous symbol>");
109 return OS;
110 }
111
printEdge(raw_ostream & OS,const Block & B,const Edge & E,StringRef EdgeKindName)112 void printEdge(raw_ostream &OS, const Block &B, const Edge &E,
113 StringRef EdgeKindName) {
114 OS << "edge@" << B.getAddress() + E.getOffset() << ": " << B.getAddress()
115 << " + " << formatv("{0:x}", E.getOffset()) << " -- " << EdgeKindName
116 << " -> ";
117
118 auto &TargetSym = E.getTarget();
119 if (TargetSym.hasName())
120 OS << TargetSym.getName();
121 else {
122 auto &TargetBlock = TargetSym.getBlock();
123 auto &TargetSec = TargetBlock.getSection();
124 orc::ExecutorAddr SecAddress(~uint64_t(0));
125 for (auto *B : TargetSec.blocks())
126 if (B->getAddress() < SecAddress)
127 SecAddress = B->getAddress();
128
129 orc::ExecutorAddrDiff SecDelta = TargetSym.getAddress() - SecAddress;
130 OS << TargetSym.getAddress() << " (section " << TargetSec.getName();
131 if (SecDelta)
132 OS << " + " << formatv("{0:x}", SecDelta);
133 OS << " / block " << TargetBlock.getAddress();
134 if (TargetSym.getOffset())
135 OS << " + " << formatv("{0:x}", TargetSym.getOffset());
136 OS << ")";
137 }
138
139 if (E.getAddend() != 0)
140 OS << " + " << E.getAddend();
141 }
142
~Section()143 Section::~Section() {
144 for (auto *Sym : Symbols)
145 Sym->~Symbol();
146 for (auto *B : Blocks)
147 B->~Block();
148 }
149
splitBlock(Block & B,size_t SplitIndex,SplitBlockCache * Cache)150 Block &LinkGraph::splitBlock(Block &B, size_t SplitIndex,
151 SplitBlockCache *Cache) {
152
153 assert(SplitIndex > 0 && "splitBlock can not be called with SplitIndex == 0");
154
155 // If the split point covers all of B then just return B.
156 if (SplitIndex == B.getSize())
157 return B;
158
159 assert(SplitIndex < B.getSize() && "SplitIndex out of range");
160
161 // Create the new block covering [ 0, SplitIndex ).
162 auto &NewBlock =
163 B.isZeroFill()
164 ? createZeroFillBlock(B.getSection(), SplitIndex, B.getAddress(),
165 B.getAlignment(), B.getAlignmentOffset())
166 : createContentBlock(
167 B.getSection(), B.getContent().slice(0, SplitIndex),
168 B.getAddress(), B.getAlignment(), B.getAlignmentOffset());
169
170 // Modify B to cover [ SplitIndex, B.size() ).
171 B.setAddress(B.getAddress() + SplitIndex);
172 B.setContent(B.getContent().slice(SplitIndex));
173 B.setAlignmentOffset((B.getAlignmentOffset() + SplitIndex) %
174 B.getAlignment());
175
176 // Handle edge transfer/update.
177 {
178 // Copy edges to NewBlock (recording their iterators so that we can remove
179 // them from B), and update of Edges remaining on B.
180 std::vector<Block::edge_iterator> EdgesToRemove;
181 for (auto I = B.edges().begin(); I != B.edges().end();) {
182 if (I->getOffset() < SplitIndex) {
183 NewBlock.addEdge(*I);
184 I = B.removeEdge(I);
185 } else {
186 I->setOffset(I->getOffset() - SplitIndex);
187 ++I;
188 }
189 }
190 }
191
192 // Handle symbol transfer/update.
193 {
194 // Initialize the symbols cache if necessary.
195 SplitBlockCache LocalBlockSymbolsCache;
196 if (!Cache)
197 Cache = &LocalBlockSymbolsCache;
198 if (*Cache == std::nullopt) {
199 *Cache = SplitBlockCache::value_type();
200 for (auto *Sym : B.getSection().symbols())
201 if (&Sym->getBlock() == &B)
202 (*Cache)->push_back(Sym);
203
204 llvm::sort(**Cache, [](const Symbol *LHS, const Symbol *RHS) {
205 return LHS->getOffset() > RHS->getOffset();
206 });
207 }
208 auto &BlockSymbols = **Cache;
209
210 // Transfer all symbols with offset less than SplitIndex to NewBlock.
211 while (!BlockSymbols.empty() &&
212 BlockSymbols.back()->getOffset() < SplitIndex) {
213 auto *Sym = BlockSymbols.back();
214 // If the symbol extends beyond the split, update the size to be within
215 // the new block.
216 if (Sym->getOffset() + Sym->getSize() > SplitIndex)
217 Sym->setSize(SplitIndex - Sym->getOffset());
218 Sym->setBlock(NewBlock);
219 BlockSymbols.pop_back();
220 }
221
222 // Update offsets for all remaining symbols in B.
223 for (auto *Sym : BlockSymbols)
224 Sym->setOffset(Sym->getOffset() - SplitIndex);
225 }
226
227 return NewBlock;
228 }
229
dump(raw_ostream & OS)230 void LinkGraph::dump(raw_ostream &OS) {
231 DenseMap<Block *, std::vector<Symbol *>> BlockSymbols;
232
233 // Map from blocks to the symbols pointing at them.
234 for (auto *Sym : defined_symbols())
235 BlockSymbols[&Sym->getBlock()].push_back(Sym);
236
237 // For each block, sort its symbols by something approximating
238 // relevance.
239 for (auto &KV : BlockSymbols)
240 llvm::sort(KV.second, [](const Symbol *LHS, const Symbol *RHS) {
241 if (LHS->getOffset() != RHS->getOffset())
242 return LHS->getOffset() < RHS->getOffset();
243 if (LHS->getLinkage() != RHS->getLinkage())
244 return LHS->getLinkage() < RHS->getLinkage();
245 if (LHS->getScope() != RHS->getScope())
246 return LHS->getScope() < RHS->getScope();
247 if (LHS->hasName()) {
248 if (!RHS->hasName())
249 return true;
250 return LHS->getName() < RHS->getName();
251 }
252 return false;
253 });
254
255 for (auto &Sec : sections()) {
256 OS << "section " << Sec.getName() << ":\n\n";
257
258 std::vector<Block *> SortedBlocks;
259 llvm::copy(Sec.blocks(), std::back_inserter(SortedBlocks));
260 llvm::sort(SortedBlocks, [](const Block *LHS, const Block *RHS) {
261 return LHS->getAddress() < RHS->getAddress();
262 });
263
264 for (auto *B : SortedBlocks) {
265 OS << " block " << B->getAddress()
266 << " size = " << formatv("{0:x8}", B->getSize())
267 << ", align = " << B->getAlignment()
268 << ", alignment-offset = " << B->getAlignmentOffset();
269 if (B->isZeroFill())
270 OS << ", zero-fill";
271 OS << "\n";
272
273 auto BlockSymsI = BlockSymbols.find(B);
274 if (BlockSymsI != BlockSymbols.end()) {
275 OS << " symbols:\n";
276 auto &Syms = BlockSymsI->second;
277 for (auto *Sym : Syms)
278 OS << " " << *Sym << "\n";
279 } else
280 OS << " no symbols\n";
281
282 if (!B->edges_empty()) {
283 OS << " edges:\n";
284 std::vector<Edge> SortedEdges;
285 llvm::copy(B->edges(), std::back_inserter(SortedEdges));
286 llvm::sort(SortedEdges, [](const Edge &LHS, const Edge &RHS) {
287 return LHS.getOffset() < RHS.getOffset();
288 });
289 for (auto &E : SortedEdges) {
290 OS << " " << B->getFixupAddress(E) << " (block + "
291 << formatv("{0:x8}", E.getOffset()) << "), addend = ";
292 if (E.getAddend() >= 0)
293 OS << formatv("+{0:x8}", E.getAddend());
294 else
295 OS << formatv("-{0:x8}", -E.getAddend());
296 OS << ", kind = " << getEdgeKindName(E.getKind()) << ", target = ";
297 if (E.getTarget().hasName())
298 OS << E.getTarget().getName();
299 else
300 OS << "addressable@"
301 << formatv("{0:x16}", E.getTarget().getAddress()) << "+"
302 << formatv("{0:x8}", E.getTarget().getOffset());
303 OS << "\n";
304 }
305 } else
306 OS << " no edges\n";
307 OS << "\n";
308 }
309 }
310
311 OS << "Absolute symbols:\n";
312 if (!absolute_symbols().empty()) {
313 for (auto *Sym : absolute_symbols())
314 OS << " " << Sym->getAddress() << ": " << *Sym << "\n";
315 } else
316 OS << " none\n";
317
318 OS << "\nExternal symbols:\n";
319 if (!external_symbols().empty()) {
320 for (auto *Sym : external_symbols())
321 OS << " " << Sym->getAddress() << ": " << *Sym << "\n";
322 } else
323 OS << " none\n";
324 }
325
operator <<(raw_ostream & OS,const SymbolLookupFlags & LF)326 raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LF) {
327 switch (LF) {
328 case SymbolLookupFlags::RequiredSymbol:
329 return OS << "RequiredSymbol";
330 case SymbolLookupFlags::WeaklyReferencedSymbol:
331 return OS << "WeaklyReferencedSymbol";
332 }
333 llvm_unreachable("Unrecognized lookup flags");
334 }
335
anchor()336 void JITLinkAsyncLookupContinuation::anchor() {}
337
338 JITLinkContext::~JITLinkContext() = default;
339
shouldAddDefaultTargetPasses(const Triple & TT) const340 bool JITLinkContext::shouldAddDefaultTargetPasses(const Triple &TT) const {
341 return true;
342 }
343
getMarkLivePass(const Triple & TT) const344 LinkGraphPassFunction JITLinkContext::getMarkLivePass(const Triple &TT) const {
345 return LinkGraphPassFunction();
346 }
347
modifyPassConfig(LinkGraph & G,PassConfiguration & Config)348 Error JITLinkContext::modifyPassConfig(LinkGraph &G,
349 PassConfiguration &Config) {
350 return Error::success();
351 }
352
markAllSymbolsLive(LinkGraph & G)353 Error markAllSymbolsLive(LinkGraph &G) {
354 for (auto *Sym : G.defined_symbols())
355 Sym->setLive(true);
356 return Error::success();
357 }
358
makeTargetOutOfRangeError(const LinkGraph & G,const Block & B,const Edge & E)359 Error makeTargetOutOfRangeError(const LinkGraph &G, const Block &B,
360 const Edge &E) {
361 std::string ErrMsg;
362 {
363 raw_string_ostream ErrStream(ErrMsg);
364 Section &Sec = B.getSection();
365 ErrStream << "In graph " << G.getName() << ", section " << Sec.getName()
366 << ": relocation target ";
367 if (E.getTarget().hasName()) {
368 ErrStream << "\"" << E.getTarget().getName() << "\"";
369 } else
370 ErrStream << E.getTarget().getBlock().getSection().getName() << " + "
371 << formatv("{0:x}", E.getOffset());
372 ErrStream << " at address " << formatv("{0:x}", E.getTarget().getAddress())
373 << " is out of range of " << G.getEdgeKindName(E.getKind())
374 << " fixup at " << formatv("{0:x}", B.getFixupAddress(E)) << " (";
375
376 Symbol *BestSymbolForBlock = nullptr;
377 for (auto *Sym : Sec.symbols())
378 if (&Sym->getBlock() == &B && Sym->hasName() && Sym->getOffset() == 0 &&
379 (!BestSymbolForBlock ||
380 Sym->getScope() < BestSymbolForBlock->getScope() ||
381 Sym->getLinkage() < BestSymbolForBlock->getLinkage()))
382 BestSymbolForBlock = Sym;
383
384 if (BestSymbolForBlock)
385 ErrStream << BestSymbolForBlock->getName() << ", ";
386 else
387 ErrStream << "<anonymous block> @ ";
388
389 ErrStream << formatv("{0:x}", B.getAddress()) << " + "
390 << formatv("{0:x}", E.getOffset()) << ")";
391 }
392 return make_error<JITLinkError>(std::move(ErrMsg));
393 }
394
makeAlignmentError(llvm::orc::ExecutorAddr Loc,uint64_t Value,int N,const Edge & E)395 Error makeAlignmentError(llvm::orc::ExecutorAddr Loc, uint64_t Value, int N,
396 const Edge &E) {
397 return make_error<JITLinkError>("0x" + llvm::utohexstr(Loc.getValue()) +
398 " improper alignment for relocation " +
399 formatv("{0:d}", E.getKind()) + ": 0x" +
400 llvm::utohexstr(Value) +
401 " is not aligned to " + Twine(N) + " bytes");
402 }
403
404 Expected<std::unique_ptr<LinkGraph>>
createLinkGraphFromObject(MemoryBufferRef ObjectBuffer)405 createLinkGraphFromObject(MemoryBufferRef ObjectBuffer) {
406 auto Magic = identify_magic(ObjectBuffer.getBuffer());
407 switch (Magic) {
408 case file_magic::macho_object:
409 return createLinkGraphFromMachOObject(ObjectBuffer);
410 case file_magic::elf_relocatable:
411 return createLinkGraphFromELFObject(ObjectBuffer);
412 case file_magic::coff_object:
413 return createLinkGraphFromCOFFObject(ObjectBuffer);
414 default:
415 return make_error<JITLinkError>("Unsupported file format");
416 };
417 }
418
link(std::unique_ptr<LinkGraph> G,std::unique_ptr<JITLinkContext> Ctx)419 void link(std::unique_ptr<LinkGraph> G, std::unique_ptr<JITLinkContext> Ctx) {
420 switch (G->getTargetTriple().getObjectFormat()) {
421 case Triple::MachO:
422 return link_MachO(std::move(G), std::move(Ctx));
423 case Triple::ELF:
424 return link_ELF(std::move(G), std::move(Ctx));
425 case Triple::COFF:
426 return link_COFF(std::move(G), std::move(Ctx));
427 default:
428 Ctx->notifyFailed(make_error<JITLinkError>("Unsupported object format"));
429 };
430 }
431
432 } // end namespace jitlink
433 } // end namespace llvm
434