1 //===------------- JITLink.cpp - Core Run-time JIT linker APIs ------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
11 #include "llvm/BinaryFormat/Magic.h"
12 #include "llvm/ExecutionEngine/JITLink/ELF.h"
13 #include "llvm/ExecutionEngine/JITLink/MachO.h"
14 #include "llvm/Support/Format.h"
15 #include "llvm/Support/ManagedStatic.h"
16 #include "llvm/Support/MemoryBuffer.h"
17 #include "llvm/Support/raw_ostream.h"
20 using namespace llvm::object
;
22 #define DEBUG_TYPE "jitlink"
26 enum JITLinkErrorCode
{ GenericJITLinkError
= 1 };
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
{
33 const char *name() const noexcept override
{ return "runtimedyld"; }
35 std::string
message(int Condition
) const override
{
36 switch (static_cast<JITLinkErrorCode
>(Condition
)) {
37 case GenericJITLinkError
:
38 return "Generic JITLink error";
40 llvm_unreachable("Unrecognized JITLinkErrorCode");
44 static ManagedStatic
<JITLinkerErrorCategory
> JITLinkerErrorCategory
;
51 char JITLinkError::ID
= 0;
53 void JITLinkError::log(raw_ostream
&OS
) const { OS
<< ErrMsg
; }
55 std::error_code
JITLinkError::convertToErrorCode() const {
56 return std::error_code(GenericJITLinkError
, *JITLinkerErrorCategory
);
59 const char *getGenericEdgeKindName(Edge::Kind K
) {
62 return "INVALID RELOCATION";
66 return "<Unrecognized edge kind>";
70 const char *getLinkageName(Linkage L
) {
77 llvm_unreachable("Unrecognized llvm.jitlink.Linkage enum");
80 const char *getScopeName(Scope S
) {
89 llvm_unreachable("Unrecognized llvm.jitlink.Scope enum");
92 raw_ostream
&operator<<(raw_ostream
&OS
, const Block
&B
) {
93 return OS
<< B
.getAddress() << " -- " << (B
.getAddress() + B
.getSize())
95 << "size = " << formatv("{0:x8}", B
.getSize()) << ", "
96 << (B
.isZeroFill() ? "zero-fill" : "content")
97 << ", align = " << B
.getAlignment()
98 << ", align-ofs = " << B
.getAlignmentOffset()
99 << ", section = " << B
.getSection().getName();
102 raw_ostream
&operator<<(raw_ostream
&OS
, const Symbol
&Sym
) {
103 OS
<< Sym
.getAddress() << " (" << (Sym
.isDefined() ? "block" : "addressable")
104 << " + " << formatv("{0:x8}", Sym
.getOffset())
105 << "): size: " << formatv("{0:x8}", Sym
.getSize())
106 << ", linkage: " << formatv("{0:6}", getLinkageName(Sym
.getLinkage()))
107 << ", scope: " << formatv("{0:8}", getScopeName(Sym
.getScope())) << ", "
108 << (Sym
.isLive() ? "live" : "dead") << " - "
109 << (Sym
.hasName() ? Sym
.getName() : "<anonymous symbol>");
113 void printEdge(raw_ostream
&OS
, const Block
&B
, const Edge
&E
,
114 StringRef EdgeKindName
) {
115 OS
<< "edge@" << B
.getAddress() + E
.getOffset() << ": " << B
.getAddress()
116 << " + " << formatv("{0:x}", E
.getOffset()) << " -- " << EdgeKindName
119 auto &TargetSym
= E
.getTarget();
120 if (TargetSym
.hasName())
121 OS
<< TargetSym
.getName();
123 auto &TargetBlock
= TargetSym
.getBlock();
124 auto &TargetSec
= TargetBlock
.getSection();
125 orc::ExecutorAddr
SecAddress(~uint64_t(0));
126 for (auto *B
: TargetSec
.blocks())
127 if (B
->getAddress() < SecAddress
)
128 SecAddress
= B
->getAddress();
130 orc::ExecutorAddrDiff SecDelta
= TargetSym
.getAddress() - SecAddress
;
131 OS
<< TargetSym
.getAddress() << " (section " << TargetSec
.getName();
133 OS
<< " + " << formatv("{0:x}", SecDelta
);
134 OS
<< " / block " << TargetBlock
.getAddress();
135 if (TargetSym
.getOffset())
136 OS
<< " + " << formatv("{0:x}", TargetSym
.getOffset());
140 if (E
.getAddend() != 0)
141 OS
<< " + " << E
.getAddend();
144 Section::~Section() {
145 for (auto *Sym
: Symbols
)
147 for (auto *B
: Blocks
)
151 Block
&LinkGraph::splitBlock(Block
&B
, size_t SplitIndex
,
152 SplitBlockCache
*Cache
) {
154 assert(SplitIndex
> 0 && "splitBlock can not be called with SplitIndex == 0");
156 // If the split point covers all of B then just return B.
157 if (SplitIndex
== B
.getSize())
160 assert(SplitIndex
< B
.getSize() && "SplitIndex out of range");
162 // Create the new block covering [ 0, SplitIndex ).
165 ? createZeroFillBlock(B
.getSection(), SplitIndex
, B
.getAddress(),
166 B
.getAlignment(), B
.getAlignmentOffset())
167 : createContentBlock(
168 B
.getSection(), B
.getContent().slice(0, SplitIndex
),
169 B
.getAddress(), B
.getAlignment(), B
.getAlignmentOffset());
171 // Modify B to cover [ SplitIndex, B.size() ).
172 B
.setAddress(B
.getAddress() + SplitIndex
);
173 B
.setContent(B
.getContent().slice(SplitIndex
));
174 B
.setAlignmentOffset((B
.getAlignmentOffset() + SplitIndex
) %
177 // Handle edge transfer/update.
179 // Copy edges to NewBlock (recording their iterators so that we can remove
180 // them from B), and update of Edges remaining on B.
181 std::vector
<Block::edge_iterator
> EdgesToRemove
;
182 for (auto I
= B
.edges().begin(); I
!= B
.edges().end();) {
183 if (I
->getOffset() < SplitIndex
) {
184 NewBlock
.addEdge(*I
);
187 I
->setOffset(I
->getOffset() - SplitIndex
);
193 // Handle symbol transfer/update.
195 // Initialize the symbols cache if necessary.
196 SplitBlockCache LocalBlockSymbolsCache
;
198 Cache
= &LocalBlockSymbolsCache
;
199 if (*Cache
== None
) {
200 *Cache
= SplitBlockCache::value_type();
201 for (auto *Sym
: B
.getSection().symbols())
202 if (&Sym
->getBlock() == &B
)
203 (*Cache
)->push_back(Sym
);
205 llvm::sort(**Cache
, [](const Symbol
*LHS
, const Symbol
*RHS
) {
206 return LHS
->getOffset() > RHS
->getOffset();
209 auto &BlockSymbols
= **Cache
;
211 // Transfer all symbols with offset less than SplitIndex to NewBlock.
212 while (!BlockSymbols
.empty() &&
213 BlockSymbols
.back()->getOffset() < SplitIndex
) {
214 auto *Sym
= BlockSymbols
.back();
215 // If the symbol extends beyond the split, update the size to be within
217 if (Sym
->getOffset() + Sym
->getSize() > SplitIndex
)
218 Sym
->setSize(SplitIndex
- Sym
->getOffset());
219 Sym
->setBlock(NewBlock
);
220 BlockSymbols
.pop_back();
223 // Update offsets for all remaining symbols in B.
224 for (auto *Sym
: BlockSymbols
)
225 Sym
->setOffset(Sym
->getOffset() - SplitIndex
);
231 void LinkGraph::dump(raw_ostream
&OS
) {
232 DenseMap
<Block
*, std::vector
<Symbol
*>> BlockSymbols
;
234 // Map from blocks to the symbols pointing at them.
235 for (auto *Sym
: defined_symbols())
236 BlockSymbols
[&Sym
->getBlock()].push_back(Sym
);
238 // For each block, sort its symbols by something approximating
240 for (auto &KV
: BlockSymbols
)
241 llvm::sort(KV
.second
, [](const Symbol
*LHS
, const Symbol
*RHS
) {
242 if (LHS
->getOffset() != RHS
->getOffset())
243 return LHS
->getOffset() < RHS
->getOffset();
244 if (LHS
->getLinkage() != RHS
->getLinkage())
245 return LHS
->getLinkage() < RHS
->getLinkage();
246 if (LHS
->getScope() != RHS
->getScope())
247 return LHS
->getScope() < RHS
->getScope();
248 if (LHS
->hasName()) {
251 return LHS
->getName() < RHS
->getName();
256 for (auto &Sec
: sections()) {
257 OS
<< "section " << Sec
.getName() << ":\n\n";
259 std::vector
<Block
*> SortedBlocks
;
260 llvm::copy(Sec
.blocks(), std::back_inserter(SortedBlocks
));
261 llvm::sort(SortedBlocks
, [](const Block
*LHS
, const Block
*RHS
) {
262 return LHS
->getAddress() < RHS
->getAddress();
265 for (auto *B
: SortedBlocks
) {
266 OS
<< " block " << B
->getAddress()
267 << " size = " << formatv("{0:x8}", B
->getSize())
268 << ", align = " << B
->getAlignment()
269 << ", alignment-offset = " << B
->getAlignmentOffset();
274 auto BlockSymsI
= BlockSymbols
.find(B
);
275 if (BlockSymsI
!= BlockSymbols
.end()) {
277 auto &Syms
= BlockSymsI
->second
;
278 for (auto *Sym
: Syms
)
279 OS
<< " " << *Sym
<< "\n";
281 OS
<< " no symbols\n";
283 if (!B
->edges_empty()) {
285 std::vector
<Edge
> SortedEdges
;
286 llvm::copy(B
->edges(), std::back_inserter(SortedEdges
));
287 llvm::sort(SortedEdges
, [](const Edge
&LHS
, const Edge
&RHS
) {
288 return LHS
.getOffset() < RHS
.getOffset();
290 for (auto &E
: SortedEdges
) {
291 OS
<< " " << B
->getFixupAddress(E
) << " (block + "
292 << formatv("{0:x8}", E
.getOffset()) << "), addend = ";
293 if (E
.getAddend() >= 0)
294 OS
<< formatv("+{0:x8}", E
.getAddend());
296 OS
<< formatv("-{0:x8}", -E
.getAddend());
297 OS
<< ", kind = " << getEdgeKindName(E
.getKind()) << ", target = ";
298 if (E
.getTarget().hasName())
299 OS
<< E
.getTarget().getName();
302 << formatv("{0:x16}", E
.getTarget().getAddress()) << "+"
303 << formatv("{0:x8}", E
.getTarget().getOffset());
312 OS
<< "Absolute symbols:\n";
313 if (!llvm::empty(absolute_symbols())) {
314 for (auto *Sym
: absolute_symbols())
315 OS
<< " " << Sym
->getAddress() << ": " << *Sym
<< "\n";
319 OS
<< "\nExternal symbols:\n";
320 if (!llvm::empty(external_symbols())) {
321 for (auto *Sym
: external_symbols())
322 OS
<< " " << Sym
->getAddress() << ": " << *Sym
<< "\n";
327 raw_ostream
&operator<<(raw_ostream
&OS
, const SymbolLookupFlags
&LF
) {
329 case SymbolLookupFlags::RequiredSymbol
:
330 return OS
<< "RequiredSymbol";
331 case SymbolLookupFlags::WeaklyReferencedSymbol
:
332 return OS
<< "WeaklyReferencedSymbol";
334 llvm_unreachable("Unrecognized lookup flags");
337 void JITLinkAsyncLookupContinuation::anchor() {}
339 JITLinkContext::~JITLinkContext() {}
341 bool JITLinkContext::shouldAddDefaultTargetPasses(const Triple
&TT
) const {
345 LinkGraphPassFunction
JITLinkContext::getMarkLivePass(const Triple
&TT
) const {
346 return LinkGraphPassFunction();
349 Error
JITLinkContext::modifyPassConfig(LinkGraph
&G
,
350 PassConfiguration
&Config
) {
351 return Error::success();
354 Error
markAllSymbolsLive(LinkGraph
&G
) {
355 for (auto *Sym
: G
.defined_symbols())
357 return Error::success();
360 Error
makeTargetOutOfRangeError(const LinkGraph
&G
, const Block
&B
,
364 raw_string_ostream
ErrStream(ErrMsg
);
365 Section
&Sec
= B
.getSection();
366 ErrStream
<< "In graph " << G
.getName() << ", section " << Sec
.getName()
367 << ": relocation target ";
368 if (E
.getTarget().hasName()) {
369 ErrStream
<< "\"" << E
.getTarget().getName() << "\"";
371 ErrStream
<< E
.getTarget().getBlock().getSection().getName() << " + "
372 << formatv("{0:x}", E
.getOffset());
373 ErrStream
<< " at address " << formatv("{0:x}", E
.getTarget().getAddress())
374 << " is out of range of " << G
.getEdgeKindName(E
.getKind())
375 << " fixup at " << formatv("{0:x}", B
.getFixupAddress(E
)) << " (";
377 Symbol
*BestSymbolForBlock
= nullptr;
378 for (auto *Sym
: Sec
.symbols())
379 if (&Sym
->getBlock() == &B
&& Sym
->hasName() && Sym
->getOffset() == 0 &&
380 (!BestSymbolForBlock
||
381 Sym
->getScope() < BestSymbolForBlock
->getScope() ||
382 Sym
->getLinkage() < BestSymbolForBlock
->getLinkage()))
383 BestSymbolForBlock
= Sym
;
385 if (BestSymbolForBlock
)
386 ErrStream
<< BestSymbolForBlock
->getName() << ", ";
388 ErrStream
<< "<anonymous block> @ ";
390 ErrStream
<< formatv("{0:x}", B
.getAddress()) << " + "
391 << formatv("{0:x}", E
.getOffset()) << ")";
393 return make_error
<JITLinkError
>(std::move(ErrMsg
));
396 Expected
<std::unique_ptr
<LinkGraph
>>
397 createLinkGraphFromObject(MemoryBufferRef ObjectBuffer
) {
398 auto Magic
= identify_magic(ObjectBuffer
.getBuffer());
400 case file_magic::macho_object
:
401 return createLinkGraphFromMachOObject(ObjectBuffer
);
402 case file_magic::elf_relocatable
:
403 return createLinkGraphFromELFObject(ObjectBuffer
);
405 return make_error
<JITLinkError
>("Unsupported file format");
409 void link(std::unique_ptr
<LinkGraph
> G
, std::unique_ptr
<JITLinkContext
> Ctx
) {
410 switch (G
->getTargetTriple().getObjectFormat()) {
412 return link_MachO(std::move(G
), std::move(Ctx
));
414 return link_ELF(std::move(G
), std::move(Ctx
));
416 Ctx
->notifyFailed(make_error
<JITLinkError
>("Unsupported object format"));
420 } // end namespace jitlink
421 } // end namespace llvm