1 //===- llvm-jitlink.cpp -- Command line interface/tester for llvm-jitlink -===//
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 // This utility provides a simple command line interface to the llvm jitlink
10 // library, which makes relocatable object files executable in memory. Its
11 // primary function is as a testing utility for the jitlink library.
13 //===----------------------------------------------------------------------===//
15 #include "llvm-jitlink.h"
17 #include "llvm/BinaryFormat/Magic.h"
18 #include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
19 #include "llvm/ExecutionEngine/Orc/DebuggerSupportPlugin.h"
20 #include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
21 #include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
22 #include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
23 #include "llvm/ExecutionEngine/Orc/EPCEHFrameRegistrar.h"
24 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
25 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
26 #include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
27 #include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
28 #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
29 #include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
30 #include "llvm/MC/MCAsmInfo.h"
31 #include "llvm/MC/MCContext.h"
32 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
33 #include "llvm/MC/MCInstPrinter.h"
34 #include "llvm/MC/MCInstrAnalysis.h"
35 #include "llvm/MC/MCInstrInfo.h"
36 #include "llvm/MC/MCRegisterInfo.h"
37 #include "llvm/MC/MCSubtargetInfo.h"
38 #include "llvm/MC/MCTargetOptions.h"
39 #include "llvm/MC/TargetRegistry.h"
40 #include "llvm/Object/COFF.h"
41 #include "llvm/Object/MachO.h"
42 #include "llvm/Object/ObjectFile.h"
43 #include "llvm/Support/CommandLine.h"
44 #include "llvm/Support/Debug.h"
45 #include "llvm/Support/InitLLVM.h"
46 #include "llvm/Support/MemoryBuffer.h"
47 #include "llvm/Support/Path.h"
48 #include "llvm/Support/Process.h"
49 #include "llvm/Support/TargetSelect.h"
50 #include "llvm/Support/Timer.h"
58 #include <netinet/in.h>
59 #include <sys/socket.h>
61 #endif // LLVM_ON_UNIX
63 #define DEBUG_TYPE "llvm_jitlink"
66 using namespace llvm::jitlink
;
67 using namespace llvm::orc
;
69 static cl::OptionCategory
JITLinkCategory("JITLink Options");
71 static cl::list
<std::string
> InputFiles(cl::Positional
, cl::OneOrMore
,
72 cl::desc("input files"),
73 cl::cat(JITLinkCategory
));
75 static cl::list
<std::string
>
76 LibrarySearchPaths("L",
77 cl::desc("Add dir to the list of library search paths"),
78 cl::Prefix
, cl::cat(JITLinkCategory
));
80 static cl::list
<std::string
>
82 cl::desc("Link against library X in the library search paths"),
83 cl::Prefix
, cl::cat(JITLinkCategory
));
85 static cl::list
<std::string
>
86 LibrariesHidden("hidden-l",
87 cl::desc("Link against library X in the library search "
88 "paths with hidden visibility"),
89 cl::Prefix
, cl::cat(JITLinkCategory
));
91 static cl::list
<std::string
>
92 LoadHidden("load_hidden",
93 cl::desc("Link against library X with hidden visibility"),
94 cl::cat(JITLinkCategory
));
96 static cl::opt
<bool> NoExec("noexec", cl::desc("Do not execute loaded code"),
97 cl::init(false), cl::cat(JITLinkCategory
));
99 static cl::list
<std::string
>
100 CheckFiles("check", cl::desc("File containing verifier checks"),
101 cl::ZeroOrMore
, cl::cat(JITLinkCategory
));
103 static cl::opt
<std::string
>
104 CheckName("check-name", cl::desc("Name of checks to match against"),
105 cl::init("jitlink-check"), cl::cat(JITLinkCategory
));
107 static cl::opt
<std::string
>
108 EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
109 cl::init(""), cl::cat(JITLinkCategory
));
111 static cl::list
<std::string
> JITDylibs(
113 cl::desc("Specifies the JITDylib to be used for any subsequent "
114 "input file, -L<seacrh-path>, and -l<library> arguments"),
115 cl::cat(JITLinkCategory
));
117 static cl::list
<std::string
>
119 cl::desc("Pre-load dynamic libraries (e.g. language runtimes "
120 "required by the ORC runtime)"),
121 cl::ZeroOrMore
, cl::cat(JITLinkCategory
));
123 static cl::list
<std::string
> InputArgv("args", cl::Positional
,
124 cl::desc("<program arguments>..."),
125 cl::ZeroOrMore
, cl::PositionalEatsArgs
,
126 cl::cat(JITLinkCategory
));
129 DebuggerSupport("debugger-support",
130 cl::desc("Enable debugger suppport (default = !-noexec)"),
131 cl::init(true), cl::Hidden
, cl::cat(JITLinkCategory
));
134 NoProcessSymbols("no-process-syms",
135 cl::desc("Do not resolve to llvm-jitlink process symbols"),
136 cl::init(false), cl::cat(JITLinkCategory
));
138 static cl::list
<std::string
> AbsoluteDefs(
140 cl::desc("Inject absolute symbol definitions (syntax: <name>=<addr>)"),
141 cl::ZeroOrMore
, cl::cat(JITLinkCategory
));
143 static cl::list
<std::string
> TestHarnesses("harness", cl::Positional
,
144 cl::desc("Test harness files"),
146 cl::PositionalEatsArgs
,
147 cl::cat(JITLinkCategory
));
149 static cl::opt
<bool> ShowInitialExecutionSessionState(
151 cl::desc("Print ExecutionSession state before resolving entry point"),
152 cl::init(false), cl::cat(JITLinkCategory
));
154 static cl::opt
<bool> ShowEntryExecutionSessionState(
156 cl::desc("Print ExecutionSession state after resolving entry point"),
157 cl::init(false), cl::cat(JITLinkCategory
));
159 static cl::opt
<bool> ShowAddrs(
161 cl::desc("Print registered symbol, section, got and stub addresses"),
162 cl::init(false), cl::cat(JITLinkCategory
));
164 static cl::opt
<bool> ShowLinkGraph(
166 cl::desc("Print the link graph after fixups have been applied"),
167 cl::init(false), cl::cat(JITLinkCategory
));
169 static cl::opt
<bool> ShowSizes(
171 cl::desc("Show sizes pre- and post-dead stripping, and allocations"),
172 cl::init(false), cl::cat(JITLinkCategory
));
174 static cl::opt
<bool> ShowTimes("show-times",
175 cl::desc("Show times for llvm-jitlink phases"),
176 cl::init(false), cl::cat(JITLinkCategory
));
178 static cl::opt
<std::string
> SlabAllocateSizeString(
180 cl::desc("Allocate from a slab of the given size "
181 "(allowable suffixes: Kb, Mb, Gb. default = "
183 cl::init(""), cl::cat(JITLinkCategory
));
185 static cl::opt
<uint64_t> SlabAddress(
187 cl::desc("Set slab target address (requires -slab-allocate and -noexec)"),
188 cl::init(~0ULL), cl::cat(JITLinkCategory
));
190 static cl::opt
<uint64_t> SlabPageSize(
192 cl::desc("Set page size for slab (requires -slab-allocate and -noexec)"),
193 cl::init(0), cl::cat(JITLinkCategory
));
195 static cl::opt
<bool> ShowRelocatedSectionContents(
196 "show-relocated-section-contents",
197 cl::desc("show section contents after fixups have been applied"),
198 cl::init(false), cl::cat(JITLinkCategory
));
200 static cl::opt
<bool> PhonyExternals(
202 cl::desc("resolve all otherwise unresolved externals to null"),
203 cl::init(false), cl::cat(JITLinkCategory
));
205 static cl::opt
<std::string
> OutOfProcessExecutor(
206 "oop-executor", cl::desc("Launch an out-of-process executor to run code"),
207 cl::ValueOptional
, cl::cat(JITLinkCategory
));
209 static cl::opt
<std::string
> OutOfProcessExecutorConnect(
210 "oop-executor-connect",
211 cl::desc("Connect to an out-of-process executor via TCP"),
212 cl::cat(JITLinkCategory
));
214 static cl::opt
<std::string
>
215 OrcRuntime("orc-runtime", cl::desc("Use ORC runtime from given path"),
216 cl::init(""), cl::cat(JITLinkCategory
));
218 static cl::opt
<bool> AddSelfRelocations(
219 "add-self-relocations",
220 cl::desc("Add relocations to function pointers to the current function"),
221 cl::init(false), cl::cat(JITLinkCategory
));
223 ExitOnError ExitOnErr
;
225 LLVM_ATTRIBUTE_USED
void linkComponents() {
226 errs() << (void *)&llvm_orc_registerEHFrameSectionWrapper
227 << (void *)&llvm_orc_deregisterEHFrameSectionWrapper
228 << (void *)&llvm_orc_registerJITLoaderGDBWrapper
;
231 static bool UseTestResultOverride
= false;
232 static int64_t TestResultOverride
= 0;
234 extern "C" void llvm_jitlink_setTestResultOverride(int64_t Value
) {
235 TestResultOverride
= Value
;
236 UseTestResultOverride
= true;
239 static Error
addSelfRelocations(LinkGraph
&G
);
244 operator<<(raw_ostream
&OS
, const Session::MemoryRegionInfo
&MRI
) {
245 return OS
<< "target addr = "
246 << format("0x%016" PRIx64
, MRI
.getTargetAddress())
247 << ", content: " << (const void *)MRI
.getContent().data() << " -- "
248 << (const void *)(MRI
.getContent().data() + MRI
.getContent().size())
249 << " (" << MRI
.getContent().size() << " bytes)";
253 operator<<(raw_ostream
&OS
, const Session::SymbolInfoMap
&SIM
) {
255 for (auto &SKV
: SIM
)
256 OS
<< " \"" << SKV
.first() << "\" " << SKV
.second
<< "\n";
261 operator<<(raw_ostream
&OS
, const Session::FileInfo
&FI
) {
262 for (auto &SIKV
: FI
.SectionInfos
)
263 OS
<< " Section \"" << SIKV
.first() << "\": " << SIKV
.second
<< "\n";
264 for (auto &GOTKV
: FI
.GOTEntryInfos
)
265 OS
<< " GOT \"" << GOTKV
.first() << "\": " << GOTKV
.second
<< "\n";
266 for (auto &StubKV
: FI
.StubInfos
)
267 OS
<< " Stub \"" << StubKV
.first() << "\": " << StubKV
.second
<< "\n";
272 operator<<(raw_ostream
&OS
, const Session::FileInfoMap
&FIM
) {
273 for (auto &FIKV
: FIM
)
274 OS
<< "File \"" << FIKV
.first() << "\":\n" << FIKV
.second
;
278 static Error
applyHarnessPromotions(Session
&S
, LinkGraph
&G
) {
280 // If this graph is part of the test harness there's nothing to do.
281 if (S
.HarnessFiles
.empty() || S
.HarnessFiles
.count(G
.getName()))
282 return Error::success();
284 LLVM_DEBUG(dbgs() << "Applying promotions to graph " << G
.getName() << "\n");
286 // If this graph is part of the test then promote any symbols referenced by
287 // the harness to default scope, remove all symbols that clash with harness
289 std::vector
<Symbol
*> DefinitionsToRemove
;
290 for (auto *Sym
: G
.defined_symbols()) {
295 if (Sym
->getLinkage() == Linkage::Weak
) {
296 if (!S
.CanonicalWeakDefs
.count(Sym
->getName()) ||
297 S
.CanonicalWeakDefs
[Sym
->getName()] != G
.getName()) {
299 dbgs() << " Externalizing weak symbol " << Sym
->getName() << "\n";
301 DefinitionsToRemove
.push_back(Sym
);
304 dbgs() << " Making weak symbol " << Sym
->getName() << " strong\n";
306 if (S
.HarnessExternals
.count(Sym
->getName()))
307 Sym
->setScope(Scope::Default
);
309 Sym
->setScope(Scope::Hidden
);
310 Sym
->setLinkage(Linkage::Strong
);
312 } else if (S
.HarnessExternals
.count(Sym
->getName())) {
313 LLVM_DEBUG(dbgs() << " Promoting " << Sym
->getName() << "\n");
314 Sym
->setScope(Scope::Default
);
317 } else if (S
.HarnessDefinitions
.count(Sym
->getName())) {
318 LLVM_DEBUG(dbgs() << " Externalizing " << Sym
->getName() << "\n");
319 DefinitionsToRemove
.push_back(Sym
);
323 for (auto *Sym
: DefinitionsToRemove
)
324 G
.makeExternal(*Sym
);
326 return Error::success();
329 static uint64_t computeTotalBlockSizes(LinkGraph
&G
) {
330 uint64_t TotalSize
= 0;
331 for (auto *B
: G
.blocks())
332 TotalSize
+= B
->getSize();
336 static void dumpSectionContents(raw_ostream
&OS
, LinkGraph
&G
) {
337 constexpr orc::ExecutorAddrDiff DumpWidth
= 16;
338 static_assert(isPowerOf2_64(DumpWidth
), "DumpWidth must be a power of two");
340 // Put sections in address order.
341 std::vector
<Section
*> Sections
;
342 for (auto &S
: G
.sections())
343 Sections
.push_back(&S
);
345 llvm::sort(Sections
, [](const Section
*LHS
, const Section
*RHS
) {
346 if (llvm::empty(LHS
->symbols()) && llvm::empty(RHS
->symbols()))
348 if (llvm::empty(LHS
->symbols()))
350 if (llvm::empty(RHS
->symbols()))
352 SectionRange
LHSRange(*LHS
);
353 SectionRange
RHSRange(*RHS
);
354 return LHSRange
.getStart() < RHSRange
.getStart();
357 for (auto *S
: Sections
) {
358 OS
<< S
->getName() << " content:";
359 if (llvm::empty(S
->symbols())) {
360 OS
<< "\n section empty\n";
364 // Sort symbols into order, then render.
365 std::vector
<Symbol
*> Syms(S
->symbols().begin(), S
->symbols().end());
366 llvm::sort(Syms
, [](const Symbol
*LHS
, const Symbol
*RHS
) {
367 return LHS
->getAddress() < RHS
->getAddress();
370 orc::ExecutorAddr
NextAddr(Syms
.front()->getAddress().getValue() &
372 for (auto *Sym
: Syms
) {
373 bool IsZeroFill
= Sym
->getBlock().isZeroFill();
374 auto SymStart
= Sym
->getAddress();
375 auto SymSize
= Sym
->getSize();
376 auto SymEnd
= SymStart
+ SymSize
;
377 const uint8_t *SymData
= IsZeroFill
? nullptr
378 : reinterpret_cast<const uint8_t *>(
379 Sym
->getSymbolContent().data());
381 // Pad any space before the symbol starts.
382 while (NextAddr
!= SymStart
) {
383 if (NextAddr
% DumpWidth
== 0)
384 OS
<< formatv("\n{0:x16}:", NextAddr
);
389 // Render the symbol content.
390 while (NextAddr
!= SymEnd
) {
391 if (NextAddr
% DumpWidth
== 0)
392 OS
<< formatv("\n{0:x16}:", NextAddr
);
396 OS
<< formatv(" {0:x-2}", SymData
[NextAddr
- SymStart
]);
404 class JITLinkSlabAllocator final
: public JITLinkMemoryManager
{
406 struct FinalizedAllocInfo
{
407 FinalizedAllocInfo(sys::MemoryBlock Mem
,
408 std::vector
<shared::WrapperFunctionCall
> DeallocActions
)
409 : Mem(Mem
), DeallocActions(std::move(DeallocActions
)) {}
410 sys::MemoryBlock Mem
;
411 std::vector
<shared::WrapperFunctionCall
> DeallocActions
;
415 static Expected
<std::unique_ptr
<JITLinkSlabAllocator
>>
416 Create(uint64_t SlabSize
) {
417 Error Err
= Error::success();
418 std::unique_ptr
<JITLinkSlabAllocator
> Allocator(
419 new JITLinkSlabAllocator(SlabSize
, Err
));
421 return std::move(Err
);
422 return std::move(Allocator
);
425 void allocate(const JITLinkDylib
*JD
, LinkGraph
&G
,
426 OnAllocatedFunction OnAllocated
) override
{
428 // Local class for allocation.
429 class IPMMAlloc
: public InFlightAlloc
{
431 IPMMAlloc(JITLinkSlabAllocator
&Parent
, BasicLayout BL
,
432 sys::MemoryBlock StandardSegs
, sys::MemoryBlock FinalizeSegs
)
433 : Parent(Parent
), BL(std::move(BL
)),
434 StandardSegs(std::move(StandardSegs
)),
435 FinalizeSegs(std::move(FinalizeSegs
)) {}
437 void finalize(OnFinalizedFunction OnFinalized
) override
{
438 if (auto Err
= applyProtections()) {
439 OnFinalized(std::move(Err
));
443 auto DeallocActions
= runFinalizeActions(BL
.graphAllocActions());
444 if (!DeallocActions
) {
445 OnFinalized(DeallocActions
.takeError());
449 if (auto Err
= Parent
.freeBlock(FinalizeSegs
)) {
451 joinErrors(std::move(Err
), runDeallocActions(*DeallocActions
)));
455 OnFinalized(FinalizedAlloc(ExecutorAddr::fromPtr(
456 new FinalizedAllocInfo(StandardSegs
, std::move(*DeallocActions
)))));
459 void abandon(OnAbandonedFunction OnAbandoned
) override
{
460 OnAbandoned(joinErrors(Parent
.freeBlock(StandardSegs
),
461 Parent
.freeBlock(FinalizeSegs
)));
465 Error
applyProtections() {
466 for (auto &KV
: BL
.segments()) {
467 const auto &Group
= KV
.first
;
468 auto &Seg
= KV
.second
;
470 auto Prot
= toSysMemoryProtectionFlags(Group
.getMemProt());
473 alignTo(Seg
.ContentSize
+ Seg
.ZeroFillSize
, Parent
.PageSize
);
474 sys::MemoryBlock
MB(Seg
.WorkingMem
, SegSize
);
475 if (auto EC
= sys::Memory::protectMappedMemory(MB
, Prot
))
476 return errorCodeToError(EC
);
477 if (Prot
& sys::Memory::MF_EXEC
)
478 sys::Memory::InvalidateInstructionCache(MB
.base(),
481 return Error::success();
484 JITLinkSlabAllocator
&Parent
;
486 sys::MemoryBlock StandardSegs
;
487 sys::MemoryBlock FinalizeSegs
;
491 auto SegsSizes
= BL
.getContiguousPageBasedLayoutSizes(PageSize
);
494 OnAllocated(SegsSizes
.takeError());
498 char *AllocBase
= nullptr;
500 std::lock_guard
<std::mutex
> Lock(SlabMutex
);
502 if (SegsSizes
->total() > SlabRemaining
.allocatedSize()) {
503 OnAllocated(make_error
<StringError
>(
504 "Slab allocator out of memory: request for " +
505 formatv("{0:x}", SegsSizes
->total()) +
506 " bytes exceeds remaining capacity of " +
507 formatv("{0:x}", SlabRemaining
.allocatedSize()) + " bytes",
508 inconvertibleErrorCode()));
512 AllocBase
= reinterpret_cast<char *>(SlabRemaining
.base());
514 sys::MemoryBlock(AllocBase
+ SegsSizes
->total(),
515 SlabRemaining
.allocatedSize() - SegsSizes
->total());
518 sys::MemoryBlock
StandardSegs(AllocBase
, SegsSizes
->StandardSegs
);
519 sys::MemoryBlock
FinalizeSegs(AllocBase
+ SegsSizes
->StandardSegs
,
520 SegsSizes
->FinalizeSegs
);
522 auto NextStandardSegAddr
= ExecutorAddr::fromPtr(StandardSegs
.base());
523 auto NextFinalizeSegAddr
= ExecutorAddr::fromPtr(FinalizeSegs
.base());
526 dbgs() << "JITLinkSlabAllocator allocated:\n";
527 if (SegsSizes
->StandardSegs
)
528 dbgs() << formatv(" [ {0:x16} -- {1:x16} ]", NextStandardSegAddr
,
529 NextStandardSegAddr
+ StandardSegs
.allocatedSize())
530 << " to stardard segs\n";
532 dbgs() << " no standard segs\n";
533 if (SegsSizes
->FinalizeSegs
)
534 dbgs() << formatv(" [ {0:x16} -- {1:x16} ]", NextFinalizeSegAddr
,
535 NextFinalizeSegAddr
+ FinalizeSegs
.allocatedSize())
536 << " to finalize segs\n";
538 dbgs() << " no finalize segs\n";
541 for (auto &KV
: BL
.segments()) {
542 auto &Group
= KV
.first
;
543 auto &Seg
= KV
.second
;
546 (Group
.getMemDeallocPolicy() == MemDeallocPolicy::Standard
)
547 ? NextStandardSegAddr
548 : NextFinalizeSegAddr
;
551 dbgs() << " " << Group
<< " -> " << formatv("{0:x16}", SegAddr
)
554 Seg
.WorkingMem
= SegAddr
.toPtr
<char *>();
555 Seg
.Addr
= SegAddr
+ NextSlabDelta
;
557 SegAddr
+= alignTo(Seg
.ContentSize
+ Seg
.ZeroFillSize
, PageSize
);
559 // Zero out the zero-fill memory.
560 if (Seg
.ZeroFillSize
!= 0)
561 memset(Seg
.WorkingMem
+ Seg
.ContentSize
, 0, Seg
.ZeroFillSize
);
564 NextSlabDelta
+= SegsSizes
->total();
566 if (auto Err
= BL
.apply()) {
567 OnAllocated(std::move(Err
));
571 OnAllocated(std::unique_ptr
<InProcessMemoryManager::InFlightAlloc
>(
572 new IPMMAlloc(*this, std::move(BL
), std::move(StandardSegs
),
573 std::move(FinalizeSegs
))));
576 void deallocate(std::vector
<FinalizedAlloc
> FinalizedAllocs
,
577 OnDeallocatedFunction OnDeallocated
) override
{
578 Error Err
= Error::success();
579 for (auto &FA
: FinalizedAllocs
) {
580 std::unique_ptr
<FinalizedAllocInfo
> FAI(
581 FA
.release().toPtr
<FinalizedAllocInfo
*>());
583 // FIXME: Run dealloc actions.
585 Err
= joinErrors(std::move(Err
), freeBlock(FAI
->Mem
));
587 OnDeallocated(std::move(Err
));
591 JITLinkSlabAllocator(uint64_t SlabSize
, Error
&Err
) {
592 ErrorAsOutParameter
_(&Err
);
595 if (auto PageSizeOrErr
= sys::Process::getPageSize())
596 PageSize
= *PageSizeOrErr
;
598 Err
= PageSizeOrErr
.takeError();
603 Err
= make_error
<StringError
>("Page size is zero",
604 inconvertibleErrorCode());
608 PageSize
= SlabPageSize
;
610 if (!isPowerOf2_64(PageSize
)) {
611 Err
= make_error
<StringError
>("Page size is not a power of 2",
612 inconvertibleErrorCode());
616 // Round slab request up to page size.
617 SlabSize
= (SlabSize
+ PageSize
- 1) & ~(PageSize
- 1);
619 const sys::Memory::ProtectionFlags ReadWrite
=
620 static_cast<sys::Memory::ProtectionFlags
>(sys::Memory::MF_READ
|
621 sys::Memory::MF_WRITE
);
625 sys::Memory::allocateMappedMemory(SlabSize
, nullptr, ReadWrite
, EC
);
628 Err
= errorCodeToError(EC
);
632 // Calculate the target address delta to link as-if slab were at
634 if (SlabAddress
!= ~0ULL)
635 NextSlabDelta
= ExecutorAddr(SlabAddress
) -
636 ExecutorAddr::fromPtr(SlabRemaining
.base());
639 Error
freeBlock(sys::MemoryBlock MB
) {
640 // FIXME: Return memory to slab.
641 return Error::success();
644 std::mutex SlabMutex
;
645 sys::MemoryBlock SlabRemaining
;
646 uint64_t PageSize
= 0;
647 int64_t NextSlabDelta
= 0;
650 Expected
<uint64_t> getSlabAllocSize(StringRef SizeString
) {
651 SizeString
= SizeString
.trim();
653 uint64_t Units
= 1024;
655 if (SizeString
.endswith_insensitive("kb"))
656 SizeString
= SizeString
.drop_back(2).rtrim();
657 else if (SizeString
.endswith_insensitive("mb")) {
659 SizeString
= SizeString
.drop_back(2).rtrim();
660 } else if (SizeString
.endswith_insensitive("gb")) {
661 Units
= 1024 * 1024 * 1024;
662 SizeString
= SizeString
.drop_back(2).rtrim();
665 uint64_t SlabSize
= 0;
666 if (SizeString
.getAsInteger(10, SlabSize
))
667 return make_error
<StringError
>("Invalid numeric format for slab size",
668 inconvertibleErrorCode());
670 return SlabSize
* Units
;
673 static std::unique_ptr
<JITLinkMemoryManager
> createMemoryManager() {
674 if (!SlabAllocateSizeString
.empty()) {
675 auto SlabSize
= ExitOnErr(getSlabAllocSize(SlabAllocateSizeString
));
676 return ExitOnErr(JITLinkSlabAllocator::Create(SlabSize
));
678 return ExitOnErr(InProcessMemoryManager::Create());
681 static Expected
<MaterializationUnit::Interface
>
682 getTestObjectFileInterface(Session
&S
, MemoryBufferRef O
) {
684 // Get the standard interface for this object, but ignore the symbols field.
685 // We'll handle that manually to include promotion.
686 auto I
= getObjectFileInterface(S
.ES
, O
);
688 return I
.takeError();
689 I
->SymbolFlags
.clear();
691 // If creating an object file was going to fail it would have happened above,
692 // so we can 'cantFail' this.
693 auto Obj
= cantFail(object::ObjectFile::createObjectFile(O
));
695 // The init symbol must be included in the SymbolFlags map if present.
697 I
->SymbolFlags
[I
->InitSymbol
] =
698 JITSymbolFlags::MaterializationSideEffectsOnly
;
700 for (auto &Sym
: Obj
->symbols()) {
701 Expected
<uint32_t> SymFlagsOrErr
= Sym
.getFlags();
703 // TODO: Test this error.
704 return SymFlagsOrErr
.takeError();
706 // Skip symbols not defined in this object file.
707 if ((*SymFlagsOrErr
& object::BasicSymbolRef::SF_Undefined
))
710 auto Name
= Sym
.getName();
712 return Name
.takeError();
714 // Skip symbols that have type SF_File.
715 if (auto SymType
= Sym
.getType()) {
716 if (*SymType
== object::SymbolRef::ST_File
)
719 return SymType
.takeError();
721 auto SymFlags
= JITSymbolFlags::fromObjectSymbol(Sym
);
723 return SymFlags
.takeError();
725 if (SymFlags
->isWeak()) {
726 // If this is a weak symbol that's not defined in the harness then we
727 // need to either mark it as strong (if this is the first definition
728 // that we've seen) or discard it.
729 if (S
.HarnessDefinitions
.count(*Name
) || S
.CanonicalWeakDefs
.count(*Name
))
731 S
.CanonicalWeakDefs
[*Name
] = O
.getBufferIdentifier();
732 *SymFlags
&= ~JITSymbolFlags::Weak
;
733 if (!S
.HarnessExternals
.count(*Name
))
734 *SymFlags
&= ~JITSymbolFlags::Exported
;
735 } else if (S
.HarnessExternals
.count(*Name
)) {
736 *SymFlags
|= JITSymbolFlags::Exported
;
737 } else if (S
.HarnessDefinitions
.count(*Name
) ||
738 !(*SymFlagsOrErr
& object::BasicSymbolRef::SF_Global
))
741 auto InternedName
= S
.ES
.intern(*Name
);
742 I
->SymbolFlags
[InternedName
] = std::move(*SymFlags
);
748 static Error
loadProcessSymbols(Session
&S
) {
749 auto FilterMainEntryPoint
=
750 [EPName
= S
.ES
.intern(EntryPointName
)](SymbolStringPtr Name
) {
751 return Name
!= EPName
;
753 S
.MainJD
->addGenerator(
754 ExitOnErr(orc::EPCDynamicLibrarySearchGenerator::GetForTargetProcess(
755 S
.ES
, std::move(FilterMainEntryPoint
))));
757 return Error::success();
760 static Error
loadDylibs(Session
&S
) {
761 LLVM_DEBUG(dbgs() << "Loading dylibs...\n");
762 for (const auto &Dylib
: Dylibs
) {
763 LLVM_DEBUG(dbgs() << " " << Dylib
<< "\n");
764 auto G
= orc::EPCDynamicLibrarySearchGenerator::Load(S
.ES
, Dylib
.c_str());
766 return G
.takeError();
767 S
.MainJD
->addGenerator(std::move(*G
));
770 return Error::success();
773 static Expected
<std::unique_ptr
<ExecutorProcessControl
>> launchExecutor() {
775 // FIXME: Add support for Windows.
776 return make_error
<StringError
>("-" + OutOfProcessExecutor
.ArgStr
+
777 " not supported on non-unix platforms",
778 inconvertibleErrorCode());
779 #elif !LLVM_ENABLE_THREADS
780 // Out of process mode using SimpleRemoteEPC depends on threads.
781 return make_error
<StringError
>(
782 "-" + OutOfProcessExecutor
.ArgStr
+
783 " requires threads, but LLVM was built with "
784 "LLVM_ENABLE_THREADS=Off",
785 inconvertibleErrorCode());
788 constexpr int ReadEnd
= 0;
789 constexpr int WriteEnd
= 1;
797 // Create pipes to/from the executor..
798 if (pipe(ToExecutor
) != 0 || pipe(FromExecutor
) != 0)
799 return make_error
<StringError
>("Unable to create pipe for executor",
800 inconvertibleErrorCode());
807 // Close the parent ends of the pipes
808 close(ToExecutor
[WriteEnd
]);
809 close(FromExecutor
[ReadEnd
]);
811 // Execute the child process.
812 std::unique_ptr
<char[]> ExecutorPath
, FDSpecifier
;
814 ExecutorPath
= std::make_unique
<char[]>(OutOfProcessExecutor
.size() + 1);
815 strcpy(ExecutorPath
.get(), OutOfProcessExecutor
.data());
817 std::string
FDSpecifierStr("filedescs=");
818 FDSpecifierStr
+= utostr(ToExecutor
[ReadEnd
]);
819 FDSpecifierStr
+= ',';
820 FDSpecifierStr
+= utostr(FromExecutor
[WriteEnd
]);
821 FDSpecifier
= std::make_unique
<char[]>(FDSpecifierStr
.size() + 1);
822 strcpy(FDSpecifier
.get(), FDSpecifierStr
.c_str());
825 char *const Args
[] = {ExecutorPath
.get(), FDSpecifier
.get(), nullptr};
826 int RC
= execvp(ExecutorPath
.get(), Args
);
828 errs() << "unable to launch out-of-process executor \""
829 << ExecutorPath
.get() << "\"\n";
833 // else we're the parent...
835 // Close the child ends of the pipes
836 close(ToExecutor
[ReadEnd
]);
837 close(FromExecutor
[WriteEnd
]);
839 return SimpleRemoteEPC::Create
<FDSimpleRemoteEPCTransport
>(
840 std::make_unique
<DynamicThreadPoolTaskDispatcher
>(),
841 SimpleRemoteEPC::Setup(), FromExecutor
[ReadEnd
], ToExecutor
[WriteEnd
]);
845 #if LLVM_ON_UNIX && LLVM_ENABLE_THREADS
846 static Error
createTCPSocketError(Twine Details
) {
847 return make_error
<StringError
>(
848 formatv("Failed to connect TCP socket '{0}': {1}",
849 OutOfProcessExecutorConnect
, Details
),
850 inconvertibleErrorCode());
853 static Expected
<int> connectTCPSocket(std::string Host
, std::string PortStr
) {
856 Hints
.ai_family
= AF_INET
;
857 Hints
.ai_socktype
= SOCK_STREAM
;
858 Hints
.ai_flags
= AI_NUMERICSERV
;
860 if (int EC
= getaddrinfo(Host
.c_str(), PortStr
.c_str(), &Hints
, &AI
))
861 return createTCPSocketError("Address resolution failed (" +
862 StringRef(gai_strerror(EC
)) + ")");
864 // Cycle through the returned addrinfo structures and connect to the first
865 // reachable endpoint.
868 for (Server
= AI
; Server
!= nullptr; Server
= Server
->ai_next
) {
869 // socket might fail, e.g. if the address family is not supported. Skip to
870 // the next addrinfo structure in such a case.
871 if ((SockFD
= socket(AI
->ai_family
, AI
->ai_socktype
, AI
->ai_protocol
)) < 0)
874 // If connect returns null, we exit the loop with a working socket.
875 if (connect(SockFD
, Server
->ai_addr
, Server
->ai_addrlen
) == 0)
882 // If we reached the end of the loop without connecting to a valid endpoint,
883 // dump the last error that was logged in socket() or connect().
884 if (Server
== nullptr)
885 return createTCPSocketError(std::strerror(errno
));
891 static Expected
<std::unique_ptr
<ExecutorProcessControl
>> connectToExecutor() {
893 // FIXME: Add TCP support for Windows.
894 return make_error
<StringError
>("-" + OutOfProcessExecutorConnect
.ArgStr
+
895 " not supported on non-unix platforms",
896 inconvertibleErrorCode());
897 #elif !LLVM_ENABLE_THREADS
898 // Out of process mode using SimpleRemoteEPC depends on threads.
899 return make_error
<StringError
>(
900 "-" + OutOfProcessExecutorConnect
.ArgStr
+
901 " requires threads, but LLVM was built with "
902 "LLVM_ENABLE_THREADS=Off",
903 inconvertibleErrorCode());
906 StringRef Host
, PortStr
;
907 std::tie(Host
, PortStr
) = StringRef(OutOfProcessExecutorConnect
).split(':');
909 return createTCPSocketError("Host name for -" +
910 OutOfProcessExecutorConnect
.ArgStr
+
911 " can not be empty");
913 return createTCPSocketError("Port number in -" +
914 OutOfProcessExecutorConnect
.ArgStr
+
915 " can not be empty");
917 if (PortStr
.getAsInteger(10, Port
))
918 return createTCPSocketError("Port number '" + PortStr
+
919 "' is not a valid integer");
921 Expected
<int> SockFD
= connectTCPSocket(Host
.str(), PortStr
.str());
923 return SockFD
.takeError();
925 return SimpleRemoteEPC::Create
<FDSimpleRemoteEPCTransport
>(
926 std::make_unique
<DynamicThreadPoolTaskDispatcher
>(),
927 SimpleRemoteEPC::Setup(), *SockFD
, *SockFD
);
931 class PhonyExternalsGenerator
: public DefinitionGenerator
{
933 Error
tryToGenerate(LookupState
&LS
, LookupKind K
, JITDylib
&JD
,
934 JITDylibLookupFlags JDLookupFlags
,
935 const SymbolLookupSet
&LookupSet
) override
{
936 SymbolMap PhonySymbols
;
937 for (auto &KV
: LookupSet
)
938 PhonySymbols
[KV
.first
] = JITEvaluatedSymbol(0, JITSymbolFlags::Exported
);
939 return JD
.define(absoluteSymbols(std::move(PhonySymbols
)));
943 Expected
<std::unique_ptr
<Session
>> Session::Create(Triple TT
) {
945 std::unique_ptr
<ExecutorProcessControl
> EPC
;
946 if (OutOfProcessExecutor
.getNumOccurrences()) {
947 /// If -oop-executor is passed then launch the executor.
948 if (auto REPC
= launchExecutor())
949 EPC
= std::move(*REPC
);
951 return REPC
.takeError();
952 } else if (OutOfProcessExecutorConnect
.getNumOccurrences()) {
953 /// If -oop-executor-connect is passed then connect to the executor.
954 if (auto REPC
= connectToExecutor())
955 EPC
= std::move(*REPC
);
957 return REPC
.takeError();
959 /// Otherwise use SelfExecutorProcessControl to target the current process.
960 auto PageSize
= sys::Process::getPageSize();
962 return PageSize
.takeError();
963 EPC
= std::make_unique
<SelfExecutorProcessControl
>(
964 std::make_shared
<SymbolStringPool
>(),
965 std::make_unique
<InPlaceTaskDispatcher
>(), std::move(TT
), *PageSize
,
966 createMemoryManager());
969 Error Err
= Error::success();
970 std::unique_ptr
<Session
> S(new Session(std::move(EPC
), Err
));
972 return std::move(Err
);
976 Session::~Session() {
977 if (auto Err
= ES
.endSession())
978 ES
.reportError(std::move(Err
));
981 Session::Session(std::unique_ptr
<ExecutorProcessControl
> EPC
, Error
&Err
)
982 : ES(std::move(EPC
)),
983 ObjLayer(ES
, ES
.getExecutorProcessControl().getMemMgr()) {
985 /// Local ObjectLinkingLayer::Plugin class to forward modifyPassConfig to the
987 class JITLinkSessionPlugin
: public ObjectLinkingLayer::Plugin
{
989 JITLinkSessionPlugin(Session
&S
) : S(S
) {}
990 void modifyPassConfig(MaterializationResponsibility
&MR
, LinkGraph
&G
,
991 PassConfiguration
&PassConfig
) override
{
992 S
.modifyPassConfig(G
.getTargetTriple(), PassConfig
);
995 Error
notifyFailed(MaterializationResponsibility
&MR
) override
{
996 return Error::success();
998 Error
notifyRemovingResources(ResourceKey K
) override
{
999 return Error::success();
1001 void notifyTransferringResources(ResourceKey DstKey
,
1002 ResourceKey SrcKey
) override
{}
1008 ErrorAsOutParameter
_(&Err
);
1010 if (auto MainJDOrErr
= ES
.createJITDylib("main"))
1011 MainJD
= &*MainJDOrErr
;
1013 Err
= MainJDOrErr
.takeError();
1017 if (!NoProcessSymbols
)
1018 ExitOnErr(loadProcessSymbols(*this));
1019 ExitOnErr(loadDylibs(*this));
1021 auto &TT
= ES
.getExecutorProcessControl().getTargetTriple();
1023 if (DebuggerSupport
&& TT
.isOSBinFormatMachO())
1024 ObjLayer
.addPlugin(ExitOnErr(
1025 GDBJITDebugInfoRegistrationPlugin::Create(this->ES
, *MainJD
, TT
)));
1027 // Set up the platform.
1028 if (TT
.isOSBinFormatMachO() && !OrcRuntime
.empty()) {
1030 MachOPlatform::Create(ES
, ObjLayer
, *MainJD
, OrcRuntime
.c_str()))
1031 ES
.setPlatform(std::move(*P
));
1033 Err
= P
.takeError();
1036 } else if (TT
.isOSBinFormatELF() && !OrcRuntime
.empty()) {
1038 ELFNixPlatform::Create(ES
, ObjLayer
, *MainJD
, OrcRuntime
.c_str()))
1039 ES
.setPlatform(std::move(*P
));
1041 Err
= P
.takeError();
1044 } else if (!TT
.isOSWindows() && !TT
.isOSBinFormatMachO()) {
1046 ObjLayer
.addPlugin(std::make_unique
<EHFrameRegistrationPlugin
>(
1047 ES
, ExitOnErr(EPCEHFrameRegistrar::Create(this->ES
))));
1048 if (DebuggerSupport
)
1049 ObjLayer
.addPlugin(std::make_unique
<DebugObjectManagerPlugin
>(
1050 ES
, ExitOnErr(createJITLoaderGDBRegistrar(this->ES
))));
1053 ObjLayer
.addPlugin(std::make_unique
<JITLinkSessionPlugin
>(*this));
1055 // Process any harness files.
1056 for (auto &HarnessFile
: TestHarnesses
) {
1057 HarnessFiles
.insert(HarnessFile
);
1060 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(HarnessFile
)));
1063 ExitOnErr(getObjectFileInterface(ES
, ObjBuffer
->getMemBufferRef()));
1065 for (auto &KV
: ObjInterface
.SymbolFlags
)
1066 HarnessDefinitions
.insert(*KV
.first
);
1068 auto Obj
= ExitOnErr(
1069 object::ObjectFile::createObjectFile(ObjBuffer
->getMemBufferRef()));
1071 for (auto &Sym
: Obj
->symbols()) {
1072 uint32_t SymFlags
= ExitOnErr(Sym
.getFlags());
1073 auto Name
= ExitOnErr(Sym
.getName());
1078 if (SymFlags
& object::BasicSymbolRef::SF_Undefined
)
1079 HarnessExternals
.insert(Name
);
1083 // If a name is defined by some harness file then it's a definition, not an
1085 for (auto &DefName
: HarnessDefinitions
)
1086 HarnessExternals
.erase(DefName
.getKey());
1089 void Session::dumpSessionInfo(raw_ostream
&OS
) {
1090 OS
<< "Registered addresses:\n" << SymbolInfos
<< FileInfos
;
1093 void Session::modifyPassConfig(const Triple
&TT
,
1094 PassConfiguration
&PassConfig
) {
1095 if (!CheckFiles
.empty())
1096 PassConfig
.PostFixupPasses
.push_back([this](LinkGraph
&G
) {
1097 auto &EPC
= ES
.getExecutorProcessControl();
1098 if (EPC
.getTargetTriple().getObjectFormat() == Triple::ELF
)
1099 return registerELFGraphInfo(*this, G
);
1101 if (EPC
.getTargetTriple().getObjectFormat() == Triple::MachO
)
1102 return registerMachOGraphInfo(*this, G
);
1104 return make_error
<StringError
>("Unsupported object format for GOT/stub "
1106 inconvertibleErrorCode());
1110 PassConfig
.PostFixupPasses
.push_back([](LinkGraph
&G
) -> Error
{
1111 outs() << "Link graph \"" << G
.getName() << "\" post-fixup:\n";
1113 return Error::success();
1116 PassConfig
.PrePrunePasses
.push_back(
1117 [this](LinkGraph
&G
) { return applyHarnessPromotions(*this, G
); });
1120 PassConfig
.PrePrunePasses
.push_back([this](LinkGraph
&G
) -> Error
{
1121 SizeBeforePruning
+= computeTotalBlockSizes(G
);
1122 return Error::success();
1124 PassConfig
.PostFixupPasses
.push_back([this](LinkGraph
&G
) -> Error
{
1125 SizeAfterFixups
+= computeTotalBlockSizes(G
);
1126 return Error::success();
1130 if (ShowRelocatedSectionContents
)
1131 PassConfig
.PostFixupPasses
.push_back([](LinkGraph
&G
) -> Error
{
1132 outs() << "Relocated section contents for " << G
.getName() << ":\n";
1133 dumpSectionContents(outs(), G
);
1134 return Error::success();
1137 if (AddSelfRelocations
)
1138 PassConfig
.PostPrunePasses
.push_back(addSelfRelocations
);
1141 Expected
<Session::FileInfo
&> Session::findFileInfo(StringRef FileName
) {
1142 auto FileInfoItr
= FileInfos
.find(FileName
);
1143 if (FileInfoItr
== FileInfos
.end())
1144 return make_error
<StringError
>("file \"" + FileName
+ "\" not recognized",
1145 inconvertibleErrorCode());
1146 return FileInfoItr
->second
;
1149 Expected
<Session::MemoryRegionInfo
&>
1150 Session::findSectionInfo(StringRef FileName
, StringRef SectionName
) {
1151 auto FI
= findFileInfo(FileName
);
1153 return FI
.takeError();
1154 auto SecInfoItr
= FI
->SectionInfos
.find(SectionName
);
1155 if (SecInfoItr
== FI
->SectionInfos
.end())
1156 return make_error
<StringError
>("no section \"" + SectionName
+
1157 "\" registered for file \"" + FileName
+
1159 inconvertibleErrorCode());
1160 return SecInfoItr
->second
;
1163 Expected
<Session::MemoryRegionInfo
&>
1164 Session::findStubInfo(StringRef FileName
, StringRef TargetName
) {
1165 auto FI
= findFileInfo(FileName
);
1167 return FI
.takeError();
1168 auto StubInfoItr
= FI
->StubInfos
.find(TargetName
);
1169 if (StubInfoItr
== FI
->StubInfos
.end())
1170 return make_error
<StringError
>("no stub for \"" + TargetName
+
1171 "\" registered for file \"" + FileName
+
1173 inconvertibleErrorCode());
1174 return StubInfoItr
->second
;
1177 Expected
<Session::MemoryRegionInfo
&>
1178 Session::findGOTEntryInfo(StringRef FileName
, StringRef TargetName
) {
1179 auto FI
= findFileInfo(FileName
);
1181 return FI
.takeError();
1182 auto GOTInfoItr
= FI
->GOTEntryInfos
.find(TargetName
);
1183 if (GOTInfoItr
== FI
->GOTEntryInfos
.end())
1184 return make_error
<StringError
>("no GOT entry for \"" + TargetName
+
1185 "\" registered for file \"" + FileName
+
1187 inconvertibleErrorCode());
1188 return GOTInfoItr
->second
;
1191 bool Session::isSymbolRegistered(StringRef SymbolName
) {
1192 return SymbolInfos
.count(SymbolName
);
1195 Expected
<Session::MemoryRegionInfo
&>
1196 Session::findSymbolInfo(StringRef SymbolName
, Twine ErrorMsgStem
) {
1197 auto SymInfoItr
= SymbolInfos
.find(SymbolName
);
1198 if (SymInfoItr
== SymbolInfos
.end())
1199 return make_error
<StringError
>(ErrorMsgStem
+ ": symbol " + SymbolName
+
1201 inconvertibleErrorCode());
1202 return SymInfoItr
->second
;
1205 } // end namespace llvm
1207 static Triple
getFirstFileTriple() {
1208 static Triple FirstTT
= []() {
1209 assert(!InputFiles
.empty() && "InputFiles can not be empty");
1210 for (auto InputFile
: InputFiles
) {
1212 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(InputFile
)));
1213 switch (identify_magic(ObjBuffer
->getBuffer())) {
1214 case file_magic::elf_relocatable
:
1215 case file_magic::macho_object
:
1216 case file_magic::coff_object
: {
1217 auto Obj
= ExitOnErr(
1218 object::ObjectFile::createObjectFile(ObjBuffer
->getMemBufferRef()));
1219 return Obj
->makeTriple();
1231 static Error
sanitizeArguments(const Triple
&TT
, const char *ArgV0
) {
1233 // -noexec and --args should not be used together.
1234 if (NoExec
&& !InputArgv
.empty())
1235 errs() << "Warning: --args passed to -noexec run will be ignored.\n";
1237 // Set the entry point name if not specified.
1238 if (EntryPointName
.empty())
1239 EntryPointName
= TT
.getObjectFormat() == Triple::MachO
? "_main" : "main";
1241 // Disable debugger support by default in noexec tests.
1242 if (DebuggerSupport
.getNumOccurrences() == 0 && NoExec
)
1243 DebuggerSupport
= false;
1245 // If -slab-allocate is passed, check that we're not trying to use it in
1246 // -oop-executor or -oop-executor-connect mode.
1248 // FIXME: Remove once we enable remote slab allocation.
1249 if (SlabAllocateSizeString
!= "") {
1250 if (OutOfProcessExecutor
.getNumOccurrences() ||
1251 OutOfProcessExecutorConnect
.getNumOccurrences())
1252 return make_error
<StringError
>(
1253 "-slab-allocate cannot be used with -oop-executor or "
1254 "-oop-executor-connect",
1255 inconvertibleErrorCode());
1258 // If -slab-address is passed, require -slab-allocate and -noexec
1259 if (SlabAddress
!= ~0ULL) {
1260 if (SlabAllocateSizeString
== "" || !NoExec
)
1261 return make_error
<StringError
>(
1262 "-slab-address requires -slab-allocate and -noexec",
1263 inconvertibleErrorCode());
1265 if (SlabPageSize
== 0)
1266 errs() << "Warning: -slab-address used without -slab-page-size.\n";
1269 if (SlabPageSize
!= 0) {
1270 // -slab-page-size requires slab alloc.
1271 if (SlabAllocateSizeString
== "")
1272 return make_error
<StringError
>("-slab-page-size requires -slab-allocate",
1273 inconvertibleErrorCode());
1275 // Check -slab-page-size / -noexec interactions.
1277 if (auto RealPageSize
= sys::Process::getPageSize()) {
1278 if (SlabPageSize
% *RealPageSize
)
1279 return make_error
<StringError
>(
1280 "-slab-page-size must be a multiple of real page size for exec "
1281 "tests (did you mean to use -noexec ?)\n",
1282 inconvertibleErrorCode());
1284 errs() << "Could not retrieve process page size:\n";
1285 logAllUnhandledErrors(RealPageSize
.takeError(), errs(), "");
1286 errs() << "Executing with slab page size = "
1287 << formatv("{0:x}", SlabPageSize
) << ".\n"
1288 << "Tool may crash if " << formatv("{0:x}", SlabPageSize
)
1289 << " is not a multiple of the real process page size.\n"
1290 << "(did you mean to use -noexec ?)";
1295 // Only one of -oop-executor and -oop-executor-connect can be used.
1296 if (!!OutOfProcessExecutor
.getNumOccurrences() &&
1297 !!OutOfProcessExecutorConnect
.getNumOccurrences())
1298 return make_error
<StringError
>(
1299 "Only one of -" + OutOfProcessExecutor
.ArgStr
+ " and -" +
1300 OutOfProcessExecutorConnect
.ArgStr
+ " can be specified",
1301 inconvertibleErrorCode());
1303 // If -oop-executor was used but no value was specified then use a sensible
1305 if (!!OutOfProcessExecutor
.getNumOccurrences() &&
1306 OutOfProcessExecutor
.empty()) {
1307 SmallString
<256> OOPExecutorPath(sys::fs::getMainExecutable(
1308 ArgV0
, reinterpret_cast<void *>(&sanitizeArguments
)));
1309 sys::path::remove_filename(OOPExecutorPath
);
1310 sys::path::append(OOPExecutorPath
, "llvm-jitlink-executor");
1311 OutOfProcessExecutor
= OOPExecutorPath
.str().str();
1314 return Error::success();
1317 static void addPhonyExternalsGenerator(Session
&S
) {
1318 S
.MainJD
->addGenerator(std::make_unique
<PhonyExternalsGenerator
>());
1321 static Error
createJITDylibs(Session
&S
,
1322 std::map
<unsigned, JITDylib
*> &IdxToJD
) {
1323 // First, set up JITDylibs.
1324 LLVM_DEBUG(dbgs() << "Creating JITDylibs...\n");
1326 // Create a "main" JITLinkDylib.
1327 IdxToJD
[0] = S
.MainJD
;
1328 S
.JDSearchOrder
.push_back({S
.MainJD
, JITDylibLookupFlags::MatchAllSymbols
});
1329 LLVM_DEBUG(dbgs() << " 0: " << S
.MainJD
->getName() << "\n");
1331 // Add any extra JITDylibs from the command line.
1332 for (auto JDItr
= JITDylibs
.begin(), JDEnd
= JITDylibs
.end();
1333 JDItr
!= JDEnd
; ++JDItr
) {
1334 auto JD
= S
.ES
.createJITDylib(*JDItr
);
1336 return JD
.takeError();
1337 unsigned JDIdx
= JITDylibs
.getPosition(JDItr
- JITDylibs
.begin());
1338 IdxToJD
[JDIdx
] = &*JD
;
1339 S
.JDSearchOrder
.push_back({&*JD
, JITDylibLookupFlags::MatchAllSymbols
});
1340 LLVM_DEBUG(dbgs() << " " << JDIdx
<< ": " << JD
->getName() << "\n");
1345 dbgs() << "Dylib search order is [ ";
1346 for (auto &KV
: S
.JDSearchOrder
)
1347 dbgs() << KV
.first
->getName() << " ";
1351 return Error::success();
1354 static Error
addAbsoluteSymbols(Session
&S
,
1355 const std::map
<unsigned, JITDylib
*> &IdxToJD
) {
1356 // Define absolute symbols.
1357 LLVM_DEBUG(dbgs() << "Defining absolute symbols...\n");
1358 for (auto AbsDefItr
= AbsoluteDefs
.begin(), AbsDefEnd
= AbsoluteDefs
.end();
1359 AbsDefItr
!= AbsDefEnd
; ++AbsDefItr
) {
1360 unsigned AbsDefArgIdx
=
1361 AbsoluteDefs
.getPosition(AbsDefItr
- AbsoluteDefs
.begin());
1362 auto &JD
= *std::prev(IdxToJD
.lower_bound(AbsDefArgIdx
))->second
;
1364 StringRef AbsDefStmt
= *AbsDefItr
;
1365 size_t EqIdx
= AbsDefStmt
.find_first_of('=');
1366 if (EqIdx
== StringRef::npos
)
1367 return make_error
<StringError
>("Invalid absolute define \"" + AbsDefStmt
+
1368 "\". Syntax: <name>=<addr>",
1369 inconvertibleErrorCode());
1370 StringRef Name
= AbsDefStmt
.substr(0, EqIdx
).trim();
1371 StringRef AddrStr
= AbsDefStmt
.substr(EqIdx
+ 1).trim();
1374 if (AddrStr
.getAsInteger(0, Addr
))
1375 return make_error
<StringError
>("Invalid address expression \"" + AddrStr
+
1376 "\" in absolute define \"" + AbsDefStmt
+
1378 inconvertibleErrorCode());
1379 JITEvaluatedSymbol
AbsDef(Addr
, JITSymbolFlags::Exported
);
1380 if (auto Err
= JD
.define(absoluteSymbols({{S
.ES
.intern(Name
), AbsDef
}})))
1383 // Register the absolute symbol with the session symbol infos.
1384 S
.SymbolInfos
[Name
] = {ArrayRef
<char>(), Addr
};
1387 return Error::success();
1390 static Error
addTestHarnesses(Session
&S
) {
1391 LLVM_DEBUG(dbgs() << "Adding test harness objects...\n");
1392 for (auto HarnessFile
: TestHarnesses
) {
1393 LLVM_DEBUG(dbgs() << " " << HarnessFile
<< "\n");
1394 auto ObjBuffer
= errorOrToExpected(MemoryBuffer::getFile(HarnessFile
));
1396 return ObjBuffer
.takeError();
1397 if (auto Err
= S
.ObjLayer
.add(*S
.MainJD
, std::move(*ObjBuffer
)))
1400 return Error::success();
1403 static Error
addObjects(Session
&S
,
1404 const std::map
<unsigned, JITDylib
*> &IdxToJD
) {
1406 // Load each object into the corresponding JITDylib..
1407 LLVM_DEBUG(dbgs() << "Adding objects...\n");
1408 for (auto InputFileItr
= InputFiles
.begin(), InputFileEnd
= InputFiles
.end();
1409 InputFileItr
!= InputFileEnd
; ++InputFileItr
) {
1410 unsigned InputFileArgIdx
=
1411 InputFiles
.getPosition(InputFileItr
- InputFiles
.begin());
1412 const std::string
&InputFile
= *InputFileItr
;
1413 if (StringRef(InputFile
).endswith(".a"))
1415 auto &JD
= *std::prev(IdxToJD
.lower_bound(InputFileArgIdx
))->second
;
1416 LLVM_DEBUG(dbgs() << " " << InputFileArgIdx
<< ": \"" << InputFile
1417 << "\" to " << JD
.getName() << "\n";);
1418 auto ObjBuffer
= errorOrToExpected(MemoryBuffer::getFile(InputFile
));
1420 return ObjBuffer
.takeError();
1422 if (S
.HarnessFiles
.empty()) {
1423 if (auto Err
= S
.ObjLayer
.add(JD
, std::move(*ObjBuffer
)))
1426 // We're in -harness mode. Use a custom interface for this
1429 getTestObjectFileInterface(S
, (*ObjBuffer
)->getMemBufferRef());
1431 return ObjInterface
.takeError();
1432 if (auto Err
= S
.ObjLayer
.add(JD
, std::move(*ObjBuffer
),
1433 std::move(*ObjInterface
)))
1438 return Error::success();
1441 static Expected
<MaterializationUnit::Interface
>
1442 getObjectFileInterfaceHidden(ExecutionSession
&ES
, MemoryBufferRef ObjBuffer
) {
1443 auto I
= getObjectFileInterface(ES
, ObjBuffer
);
1445 for (auto &KV
: I
->SymbolFlags
)
1446 KV
.second
&= ~JITSymbolFlags::Exported
;
1451 static Error
addLibraries(Session
&S
,
1452 const std::map
<unsigned, JITDylib
*> &IdxToJD
) {
1454 // 1. Collect search paths for each JITDylib.
1455 DenseMap
<const JITDylib
*, SmallVector
<StringRef
, 2>> JDSearchPaths
;
1457 for (auto LSPItr
= LibrarySearchPaths
.begin(),
1458 LSPEnd
= LibrarySearchPaths
.end();
1459 LSPItr
!= LSPEnd
; ++LSPItr
) {
1460 unsigned LibrarySearchPathIdx
=
1461 LibrarySearchPaths
.getPosition(LSPItr
- LibrarySearchPaths
.begin());
1462 auto &JD
= *std::prev(IdxToJD
.lower_bound(LibrarySearchPathIdx
))->second
;
1464 StringRef LibrarySearchPath
= *LSPItr
;
1465 if (sys::fs::get_file_type(LibrarySearchPath
) !=
1466 sys::fs::file_type::directory_file
)
1467 return make_error
<StringError
>("While linking " + JD
.getName() + ", -L" +
1469 " does not point to a directory",
1470 inconvertibleErrorCode());
1472 JDSearchPaths
[&JD
].push_back(*LSPItr
);
1476 if (!JDSearchPaths
.empty())
1477 dbgs() << "Search paths:\n";
1478 for (auto &KV
: JDSearchPaths
) {
1479 dbgs() << " " << KV
.first
->getName() << ": [";
1480 for (auto &LibSearchPath
: KV
.second
)
1481 dbgs() << " \"" << LibSearchPath
<< "\"";
1486 // 2. Collect library loads
1487 struct LibraryLoad
{
1489 bool IsPath
= false;
1491 StringRef
*CandidateExtensions
;
1492 enum { Standard
, Hidden
} Modifier
;
1494 std::vector
<LibraryLoad
> LibraryLoads
;
1495 // Add archive files from the inputs to LibraryLoads.
1496 for (auto InputFileItr
= InputFiles
.begin(), InputFileEnd
= InputFiles
.end();
1497 InputFileItr
!= InputFileEnd
; ++InputFileItr
) {
1498 StringRef InputFile
= *InputFileItr
;
1499 if (!InputFile
.endswith(".a"))
1502 LL
.LibName
= InputFile
;
1504 LL
.Position
= InputFiles
.getPosition(InputFileItr
- InputFiles
.begin());
1505 LL
.CandidateExtensions
= nullptr;
1506 LL
.Modifier
= LibraryLoad::Standard
;
1507 LibraryLoads
.push_back(std::move(LL
));
1510 // Add -load_hidden arguments to LibraryLoads.
1511 for (auto LibItr
= LoadHidden
.begin(), LibEnd
= LoadHidden
.end();
1512 LibItr
!= LibEnd
; ++LibItr
) {
1514 LL
.LibName
= *LibItr
;
1516 LL
.Position
= LoadHidden
.getPosition(LibItr
- LoadHidden
.begin());
1517 LL
.CandidateExtensions
= nullptr;
1518 LL
.Modifier
= LibraryLoad::Hidden
;
1519 LibraryLoads
.push_back(std::move(LL
));
1521 StringRef StandardExtensions
[] = {".so", ".dylib", ".a"};
1522 StringRef ArchiveExtensionsOnly
[] = {".a"};
1524 // Add -lx arguments to LibraryLoads.
1525 for (auto LibItr
= Libraries
.begin(), LibEnd
= Libraries
.end();
1526 LibItr
!= LibEnd
; ++LibItr
) {
1528 LL
.LibName
= *LibItr
;
1529 LL
.Position
= Libraries
.getPosition(LibItr
- Libraries
.begin());
1530 LL
.CandidateExtensions
= StandardExtensions
;
1531 LL
.Modifier
= LibraryLoad::Standard
;
1532 LibraryLoads
.push_back(std::move(LL
));
1535 // Add -hidden-lx arguments to LibraryLoads.
1536 for (auto LibHiddenItr
= LibrariesHidden
.begin(),
1537 LibHiddenEnd
= LibrariesHidden
.end();
1538 LibHiddenItr
!= LibHiddenEnd
; ++LibHiddenItr
) {
1540 LL
.LibName
= *LibHiddenItr
;
1542 LibrariesHidden
.getPosition(LibHiddenItr
- LibrariesHidden
.begin());
1543 LL
.CandidateExtensions
= ArchiveExtensionsOnly
;
1544 LL
.Modifier
= LibraryLoad::Hidden
;
1545 LibraryLoads
.push_back(std::move(LL
));
1548 // If there are any load-<modified> options then turn on flag overrides
1549 // to avoid flag mismatch errors.
1550 if (!LibrariesHidden
.empty() || !LoadHidden
.empty())
1551 S
.ObjLayer
.setOverrideObjectFlagsWithResponsibilityFlags(true);
1553 // Sort library loads by position in the argument list.
1554 llvm::sort(LibraryLoads
, [](const LibraryLoad
&LHS
, const LibraryLoad
&RHS
) {
1555 return LHS
.Position
< RHS
.Position
;
1558 // 3. Process library loads.
1559 auto AddArchive
= [&](const char *Path
, const LibraryLoad
&LL
)
1560 -> Expected
<std::unique_ptr
<StaticLibraryDefinitionGenerator
>> {
1561 unique_function
<Expected
<MaterializationUnit::Interface
>(
1562 ExecutionSession
& ES
, MemoryBufferRef ObjBuffer
)>
1563 GetObjFileInterface
;
1564 switch (LL
.Modifier
) {
1565 case LibraryLoad::Standard
:
1566 GetObjFileInterface
= getObjectFileInterface
;
1568 case LibraryLoad::Hidden
:
1569 GetObjFileInterface
= getObjectFileInterfaceHidden
;
1572 return StaticLibraryDefinitionGenerator::Load(
1573 S
.ObjLayer
, Path
, S
.ES
.getExecutorProcessControl().getTargetTriple(),
1574 std::move(GetObjFileInterface
));
1577 for (auto &LL
: LibraryLoads
) {
1578 bool LibFound
= false;
1579 auto &JD
= *std::prev(IdxToJD
.lower_bound(LL
.Position
))->second
;
1581 // If this is the name of a JITDylib then link against that.
1582 if (auto *LJD
= S
.ES
.getJITDylibByName(LL
.LibName
)) {
1583 JD
.addToLinkOrder(*LJD
);
1588 auto G
= AddArchive(LL
.LibName
.str().c_str(), LL
);
1590 return createFileError(LL
.LibName
, G
.takeError());
1591 JD
.addGenerator(std::move(*G
));
1593 dbgs() << "Adding generator for static library " << LL
.LibName
<< " to "
1594 << JD
.getName() << "\n";
1599 // Otherwise look through the search paths.
1600 auto JDSearchPathsItr
= JDSearchPaths
.find(&JD
);
1601 if (JDSearchPathsItr
!= JDSearchPaths
.end()) {
1602 for (StringRef SearchPath
: JDSearchPathsItr
->second
) {
1603 for (const char *LibExt
: {".dylib", ".so", ".a"}) {
1604 SmallVector
<char, 256> LibPath
;
1605 LibPath
.reserve(SearchPath
.size() + strlen("lib") +
1606 LL
.LibName
.size() + strlen(LibExt
) +
1607 2); // +2 for pathsep, null term.
1608 llvm::copy(SearchPath
, std::back_inserter(LibPath
));
1609 sys::path::append(LibPath
, "lib" + LL
.LibName
+ LibExt
);
1610 LibPath
.push_back('\0');
1612 // Skip missing or non-regular paths.
1613 if (sys::fs::get_file_type(LibPath
.data()) !=
1614 sys::fs::file_type::regular_file
) {
1619 if (auto EC
= identify_magic(LibPath
, Magic
)) {
1620 // If there was an error loading the file then skip it.
1622 dbgs() << "Library search found \"" << LibPath
1623 << "\", but could not identify file type (" << EC
.message()
1624 << "). Skipping.\n";
1629 // We identified the magic. Assume that we can load it -- we'll reset
1630 // in the default case.
1633 case file_magic::elf_shared_object
:
1634 case file_magic::macho_dynamically_linked_shared_lib
: {
1635 // TODO: On first reference to LibPath this should create a JITDylib
1636 // with a generator and add it to JD's links-against list. Subsquent
1637 // references should use the JITDylib created on the first
1640 EPCDynamicLibrarySearchGenerator::Load(S
.ES
, LibPath
.data());
1642 return G
.takeError();
1644 dbgs() << "Adding generator for dynamic library "
1645 << LibPath
.data() << " to " << JD
.getName() << "\n";
1647 JD
.addGenerator(std::move(*G
));
1650 case file_magic::archive
:
1651 case file_magic::macho_universal_binary
: {
1652 auto G
= AddArchive(LibPath
.data(), LL
);
1654 return G
.takeError();
1655 JD
.addGenerator(std::move(*G
));
1657 dbgs() << "Adding generator for static library " << LibPath
.data()
1658 << " to " << JD
.getName() << "\n";
1663 // This file isn't a recognized library kind.
1665 dbgs() << "Library search found \"" << LibPath
1666 << "\", but file type is not supported. Skipping.\n";
1680 return make_error
<StringError
>("While linking " + JD
.getName() +
1681 ", could not find library for -l" +
1683 inconvertibleErrorCode());
1686 return Error::success();
1689 static Error
addProcessSymbols(Session
&S
,
1690 const std::map
<unsigned, JITDylib
*> &IdxToJD
) {
1692 if (NoProcessSymbols
)
1693 return Error::success();
1695 for (auto &KV
: IdxToJD
) {
1696 auto &JD
= *KV
.second
;
1697 JD
.addGenerator(ExitOnErr(
1698 orc::EPCDynamicLibrarySearchGenerator::GetForTargetProcess(S
.ES
)));
1701 return Error::success();
1704 static Error
addSessionInputs(Session
&S
) {
1705 std::map
<unsigned, JITDylib
*> IdxToJD
;
1707 if (auto Err
= createJITDylibs(S
, IdxToJD
))
1710 if (auto Err
= addAbsoluteSymbols(S
, IdxToJD
))
1713 if (!TestHarnesses
.empty())
1714 if (auto Err
= addTestHarnesses(S
))
1717 if (auto Err
= addObjects(S
, IdxToJD
))
1720 if (auto Err
= addLibraries(S
, IdxToJD
))
1723 if (auto Err
= addProcessSymbols(S
, IdxToJD
))
1726 return Error::success();
1731 const Target
*TheTarget
;
1732 std::unique_ptr
<MCSubtargetInfo
> STI
;
1733 std::unique_ptr
<MCRegisterInfo
> MRI
;
1734 std::unique_ptr
<MCAsmInfo
> MAI
;
1735 std::unique_ptr
<MCContext
> Ctx
;
1736 std::unique_ptr
<MCDisassembler
> Disassembler
;
1737 std::unique_ptr
<MCInstrInfo
> MII
;
1738 std::unique_ptr
<MCInstrAnalysis
> MIA
;
1739 std::unique_ptr
<MCInstPrinter
> InstPrinter
;
1741 } // anonymous namespace
1743 static TargetInfo
getTargetInfo(const Triple
&TT
) {
1744 auto TripleName
= TT
.str();
1745 std::string ErrorStr
;
1746 const Target
*TheTarget
= TargetRegistry::lookupTarget(TripleName
, ErrorStr
);
1748 ExitOnErr(make_error
<StringError
>("Error accessing target '" + TripleName
+
1750 inconvertibleErrorCode()));
1752 std::unique_ptr
<MCSubtargetInfo
> STI(
1753 TheTarget
->createMCSubtargetInfo(TripleName
, "", ""));
1756 make_error
<StringError
>("Unable to create subtarget for " + TripleName
,
1757 inconvertibleErrorCode()));
1759 std::unique_ptr
<MCRegisterInfo
> MRI(TheTarget
->createMCRegInfo(TripleName
));
1761 ExitOnErr(make_error
<StringError
>("Unable to create target register info "
1764 inconvertibleErrorCode()));
1766 MCTargetOptions MCOptions
;
1767 std::unique_ptr
<MCAsmInfo
> MAI(
1768 TheTarget
->createMCAsmInfo(*MRI
, TripleName
, MCOptions
));
1770 ExitOnErr(make_error
<StringError
>("Unable to create target asm info " +
1772 inconvertibleErrorCode()));
1774 auto Ctx
= std::make_unique
<MCContext
>(Triple(TripleName
), MAI
.get(),
1775 MRI
.get(), STI
.get());
1777 std::unique_ptr
<MCDisassembler
> Disassembler(
1778 TheTarget
->createMCDisassembler(*STI
, *Ctx
));
1780 ExitOnErr(make_error
<StringError
>("Unable to create disassembler for " +
1782 inconvertibleErrorCode()));
1784 std::unique_ptr
<MCInstrInfo
> MII(TheTarget
->createMCInstrInfo());
1786 ExitOnErr(make_error
<StringError
>("Unable to create instruction info for" +
1788 inconvertibleErrorCode()));
1790 std::unique_ptr
<MCInstrAnalysis
> MIA(
1791 TheTarget
->createMCInstrAnalysis(MII
.get()));
1793 ExitOnErr(make_error
<StringError
>(
1794 "Unable to create instruction analysis for" + TripleName
,
1795 inconvertibleErrorCode()));
1797 std::unique_ptr
<MCInstPrinter
> InstPrinter(
1798 TheTarget
->createMCInstPrinter(Triple(TripleName
), 0, *MAI
, *MII
, *MRI
));
1800 ExitOnErr(make_error
<StringError
>(
1801 "Unable to create instruction printer for" + TripleName
,
1802 inconvertibleErrorCode()));
1803 return {TheTarget
, std::move(STI
), std::move(MRI
),
1804 std::move(MAI
), std::move(Ctx
), std::move(Disassembler
),
1805 std::move(MII
), std::move(MIA
), std::move(InstPrinter
)};
1808 static Error
runChecks(Session
&S
) {
1809 const auto &TT
= S
.ES
.getExecutorProcessControl().getTargetTriple();
1811 if (CheckFiles
.empty())
1812 return Error::success();
1814 LLVM_DEBUG(dbgs() << "Running checks...\n");
1816 auto TI
= getTargetInfo(TT
);
1818 auto IsSymbolValid
= [&S
](StringRef Symbol
) {
1819 return S
.isSymbolRegistered(Symbol
);
1822 auto GetSymbolInfo
= [&S
](StringRef Symbol
) {
1823 return S
.findSymbolInfo(Symbol
, "Can not get symbol info");
1826 auto GetSectionInfo
= [&S
](StringRef FileName
, StringRef SectionName
) {
1827 return S
.findSectionInfo(FileName
, SectionName
);
1830 auto GetStubInfo
= [&S
](StringRef FileName
, StringRef SectionName
) {
1831 return S
.findStubInfo(FileName
, SectionName
);
1834 auto GetGOTInfo
= [&S
](StringRef FileName
, StringRef SectionName
) {
1835 return S
.findGOTEntryInfo(FileName
, SectionName
);
1838 RuntimeDyldChecker
Checker(
1839 IsSymbolValid
, GetSymbolInfo
, GetSectionInfo
, GetStubInfo
, GetGOTInfo
,
1840 TT
.isLittleEndian() ? support::little
: support::big
,
1841 TI
.Disassembler
.get(), TI
.InstPrinter
.get(), dbgs());
1843 std::string CheckLineStart
= "# " + CheckName
+ ":";
1844 for (auto &CheckFile
: CheckFiles
) {
1845 auto CheckerFileBuf
=
1846 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(CheckFile
)));
1847 if (!Checker
.checkAllRulesInBuffer(CheckLineStart
, &*CheckerFileBuf
))
1848 ExitOnErr(make_error
<StringError
>(
1849 "Some checks in " + CheckFile
+ " failed", inconvertibleErrorCode()));
1852 return Error::success();
1855 static Error
addSelfRelocations(LinkGraph
&G
) {
1856 auto TI
= getTargetInfo(G
.getTargetTriple());
1857 for (auto *Sym
: G
.defined_symbols())
1858 if (Sym
->isCallable())
1859 if (auto Err
= addFunctionPointerRelocationsToCurrentSymbol(
1860 *Sym
, G
, *TI
.Disassembler
, *TI
.MIA
))
1862 return Error::success();
1865 static void dumpSessionStats(Session
&S
) {
1868 if (!OrcRuntime
.empty())
1869 outs() << "Note: Session stats include runtime and entry point lookup, but "
1870 "not JITDylib initialization/deinitialization.\n";
1872 outs() << " Total size of all blocks before pruning: "
1873 << S
.SizeBeforePruning
1874 << "\n Total size of all blocks after fixups: " << S
.SizeAfterFixups
1878 static Expected
<JITEvaluatedSymbol
> getMainEntryPoint(Session
&S
) {
1879 return S
.ES
.lookup(S
.JDSearchOrder
, S
.ES
.intern(EntryPointName
));
1882 static Expected
<JITEvaluatedSymbol
> getOrcRuntimeEntryPoint(Session
&S
) {
1883 std::string RuntimeEntryPoint
= "__orc_rt_run_program_wrapper";
1884 const auto &TT
= S
.ES
.getExecutorProcessControl().getTargetTriple();
1885 if (TT
.getObjectFormat() == Triple::MachO
)
1886 RuntimeEntryPoint
= '_' + RuntimeEntryPoint
;
1887 return S
.ES
.lookup(S
.JDSearchOrder
, S
.ES
.intern(RuntimeEntryPoint
));
1890 static Expected
<int> runWithRuntime(Session
&S
, ExecutorAddr EntryPointAddr
) {
1891 StringRef DemangledEntryPoint
= EntryPointName
;
1892 const auto &TT
= S
.ES
.getExecutorProcessControl().getTargetTriple();
1893 if (TT
.getObjectFormat() == Triple::MachO
&&
1894 DemangledEntryPoint
.front() == '_')
1895 DemangledEntryPoint
= DemangledEntryPoint
.drop_front();
1896 using SPSRunProgramSig
=
1897 int64_t(SPSString
, SPSString
, SPSSequence
<SPSString
>);
1899 if (auto Err
= S
.ES
.callSPSWrapper
<SPSRunProgramSig
>(
1900 EntryPointAddr
, Result
, S
.MainJD
->getName(), DemangledEntryPoint
,
1901 static_cast<std::vector
<std::string
> &>(InputArgv
)))
1902 return std::move(Err
);
1906 static Expected
<int> runWithoutRuntime(Session
&S
,
1907 ExecutorAddr EntryPointAddr
) {
1908 return S
.ES
.getExecutorProcessControl().runAsMain(EntryPointAddr
, InputArgv
);
1912 struct JITLinkTimers
{
1913 TimerGroup JITLinkTG
{"llvm-jitlink timers", "timers for llvm-jitlink phases"};
1914 Timer LoadObjectsTimer
{"load", "time to load/add object files", JITLinkTG
};
1915 Timer LinkTimer
{"link", "time to link object files", JITLinkTG
};
1916 Timer RunTimer
{"run", "time to execute jitlink'd code", JITLinkTG
};
1920 int main(int argc
, char *argv
[]) {
1921 InitLLVM
X(argc
, argv
);
1923 InitializeAllTargetInfos();
1924 InitializeAllTargetMCs();
1925 InitializeAllDisassemblers();
1927 cl::HideUnrelatedOptions({&JITLinkCategory
, &getColorCategory()});
1928 cl::ParseCommandLineOptions(argc
, argv
, "llvm jitlink tool");
1929 ExitOnErr
.setBanner(std::string(argv
[0]) + ": ");
1931 /// If timers are enabled, create a JITLinkTimers instance.
1932 std::unique_ptr
<JITLinkTimers
> Timers
=
1933 ShowTimes
? std::make_unique
<JITLinkTimers
>() : nullptr;
1935 ExitOnErr(sanitizeArguments(getFirstFileTriple(), argv
[0]));
1937 auto S
= ExitOnErr(Session::Create(getFirstFileTriple()));
1940 TimeRegion
TR(Timers
? &Timers
->LoadObjectsTimer
: nullptr);
1941 ExitOnErr(addSessionInputs(*S
));
1945 addPhonyExternalsGenerator(*S
);
1947 if (ShowInitialExecutionSessionState
)
1950 JITEvaluatedSymbol EntryPoint
= nullptr;
1952 TimeRegion
TR(Timers
? &Timers
->LinkTimer
: nullptr);
1953 // Find the entry-point function unconditionally, since we want to force
1954 // it to be materialized to collect stats.
1955 EntryPoint
= ExitOnErr(getMainEntryPoint(*S
));
1957 dbgs() << "Using entry point \"" << EntryPointName
1958 << "\": " << formatv("{0:x16}", EntryPoint
.getAddress()) << "\n";
1961 // If we're running with the ORC runtime then replace the entry-point
1962 // with the __orc_rt_run_program symbol.
1963 if (!OrcRuntime
.empty()) {
1964 EntryPoint
= ExitOnErr(getOrcRuntimeEntryPoint(*S
));
1966 dbgs() << "(called via __orc_rt_run_program_wrapper at "
1967 << formatv("{0:x16}", EntryPoint
.getAddress()) << ")\n";
1972 if (ShowEntryExecutionSessionState
)
1976 S
->dumpSessionInfo(outs());
1978 ExitOnErr(runChecks(*S
));
1980 dumpSessionStats(*S
);
1987 LLVM_DEBUG(dbgs() << "Running \"" << EntryPointName
<< "\"...\n");
1988 TimeRegion
TR(Timers
? &Timers
->RunTimer
: nullptr);
1989 if (!OrcRuntime
.empty())
1991 ExitOnErr(runWithRuntime(*S
, ExecutorAddr(EntryPoint
.getAddress())));
1994 runWithoutRuntime(*S
, ExecutorAddr(EntryPoint
.getAddress())));
1997 // Destroy the session.
1998 ExitOnErr(S
->ES
.endSession());
2001 // If the executing code set a test result override then use that.
2002 if (UseTestResultOverride
)
2003 Result
= TestResultOverride
;