[DebugInfo] Avoid re-ordering assignments in LCSSA
[llvm-project.git] / llvm / tools / llvm-jitlink / llvm-jitlink.cpp
blob808a7db9c10191c511ff44a36ecf394fb4a528c0
1 //===- llvm-jitlink.cpp -- Command line interface/tester for llvm-jitlink -===//
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 // 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/ExecutionUtils.h"
19 #include "llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h"
20 #include "llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h"
21 #include "llvm/MC/MCAsmInfo.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
24 #include "llvm/MC/MCInstPrinter.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSubtargetInfo.h"
28 #include "llvm/MC/MCTargetOptions.h"
29 #include "llvm/Object/COFF.h"
30 #include "llvm/Object/MachO.h"
31 #include "llvm/Object/ObjectFile.h"
32 #include "llvm/Support/CommandLine.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/InitLLVM.h"
35 #include "llvm/Support/MemoryBuffer.h"
36 #include "llvm/Support/Process.h"
37 #include "llvm/Support/TargetRegistry.h"
38 #include "llvm/Support/TargetSelect.h"
39 #include "llvm/Support/Timer.h"
41 #include <list>
42 #include <string>
44 #ifdef LLVM_ON_UNIX
45 #include <netdb.h>
46 #include <netinet/in.h>
47 #include <sys/socket.h>
48 #include <unistd.h>
49 #endif // LLVM_ON_UNIX
51 #define DEBUG_TYPE "llvm_jitlink"
53 using namespace llvm;
54 using namespace llvm::jitlink;
55 using namespace llvm::orc;
57 static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,
58 cl::desc("input files"));
60 static cl::opt<bool> NoExec("noexec", cl::desc("Do not execute loaded code"),
61 cl::init(false));
63 static cl::list<std::string>
64 CheckFiles("check", cl::desc("File containing verifier checks"),
65 cl::ZeroOrMore);
67 static cl::opt<std::string>
68 CheckName("check-name", cl::desc("Name of checks to match against"),
69 cl::init("jitlink-check"));
71 static cl::opt<std::string>
72 EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
73 cl::init(""));
75 static cl::list<std::string> JITLinkDylibs(
76 "jld", cl::desc("Specifies the JITDylib to be used for any subsequent "
77 "input file arguments"));
79 static cl::list<std::string>
80 Dylibs("dlopen", cl::desc("Dynamic libraries to load before linking"),
81 cl::ZeroOrMore);
83 static cl::list<std::string> InputArgv("args", cl::Positional,
84 cl::desc("<program arguments>..."),
85 cl::ZeroOrMore, cl::PositionalEatsArgs);
87 static cl::opt<bool>
88 NoProcessSymbols("no-process-syms",
89 cl::desc("Do not resolve to llvm-jitlink process symbols"),
90 cl::init(false));
92 static cl::list<std::string> AbsoluteDefs(
93 "define-abs",
94 cl::desc("Inject absolute symbol definitions (syntax: <name>=<addr>)"),
95 cl::ZeroOrMore);
97 static cl::list<std::string> TestHarnesses("harness", cl::Positional,
98 cl::desc("Test harness files"),
99 cl::ZeroOrMore,
100 cl::PositionalEatsArgs);
102 static cl::opt<bool> ShowInitialExecutionSessionState(
103 "show-init-es",
104 cl::desc("Print ExecutionSession state before resolving entry point"),
105 cl::init(false));
107 static cl::opt<bool> ShowAddrs(
108 "show-addrs",
109 cl::desc("Print registered symbol, section, got and stub addresses"),
110 cl::init(false));
112 static cl::opt<bool> ShowLinkGraph(
113 "show-graph",
114 cl::desc("Print the link graph after fixups have been applied"),
115 cl::init(false));
117 static cl::opt<bool> ShowSizes(
118 "show-sizes",
119 cl::desc("Show sizes pre- and post-dead stripping, and allocations"),
120 cl::init(false));
122 static cl::opt<bool> ShowTimes("show-times",
123 cl::desc("Show times for llvm-jitlink phases"),
124 cl::init(false));
126 static cl::opt<std::string> SlabAllocateSizeString(
127 "slab-allocate",
128 cl::desc("Allocate from a slab of the given size "
129 "(allowable suffixes: Kb, Mb, Gb. default = "
130 "Kb)"),
131 cl::init(""));
133 static cl::opt<uint64_t> SlabAddress(
134 "slab-address",
135 cl::desc("Set slab target address (requires -slab-allocate and -noexec)"),
136 cl::init(~0ULL));
138 static cl::opt<bool> ShowRelocatedSectionContents(
139 "show-relocated-section-contents",
140 cl::desc("show section contents after fixups have been applied"),
141 cl::init(false));
143 static cl::opt<bool> PhonyExternals(
144 "phony-externals",
145 cl::desc("resolve all otherwise unresolved externals to null"),
146 cl::init(false));
148 static cl::opt<std::string> OutOfProcessExecutor(
149 "oop-executor", cl::desc("Launch an out-of-process executor to run code"),
150 cl::ValueOptional);
152 static cl::opt<std::string> OutOfProcessExecutorConnect(
153 "oop-executor-connect",
154 cl::desc("Connect to an out-of-process executor via TCP"));
156 ExitOnError ExitOnErr;
158 namespace llvm {
160 static raw_ostream &
161 operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) {
162 return OS << "target addr = "
163 << format("0x%016" PRIx64, MRI.getTargetAddress())
164 << ", content: " << (const void *)MRI.getContent().data() << " -- "
165 << (const void *)(MRI.getContent().data() + MRI.getContent().size())
166 << " (" << MRI.getContent().size() << " bytes)";
169 static raw_ostream &
170 operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) {
171 OS << "Symbols:\n";
172 for (auto &SKV : SIM)
173 OS << " \"" << SKV.first() << "\" " << SKV.second << "\n";
174 return OS;
177 static raw_ostream &
178 operator<<(raw_ostream &OS, const Session::FileInfo &FI) {
179 for (auto &SIKV : FI.SectionInfos)
180 OS << " Section \"" << SIKV.first() << "\": " << SIKV.second << "\n";
181 for (auto &GOTKV : FI.GOTEntryInfos)
182 OS << " GOT \"" << GOTKV.first() << "\": " << GOTKV.second << "\n";
183 for (auto &StubKV : FI.StubInfos)
184 OS << " Stub \"" << StubKV.first() << "\": " << StubKV.second << "\n";
185 return OS;
188 static raw_ostream &
189 operator<<(raw_ostream &OS, const Session::FileInfoMap &FIM) {
190 for (auto &FIKV : FIM)
191 OS << "File \"" << FIKV.first() << "\":\n" << FIKV.second;
192 return OS;
195 static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
197 // If this graph is part of the test harness there's nothing to do.
198 if (S.HarnessFiles.empty() || S.HarnessFiles.count(G.getName()))
199 return Error::success();
201 LLVM_DEBUG(dbgs() << "Appling promotions to graph " << G.getName() << "\n");
203 // If this graph is part of the test then promote any symbols referenced by
204 // the harness to default scope, remove all symbols that clash with harness
205 // definitions.
206 std::vector<Symbol *> DefinitionsToRemove;
207 for (auto *Sym : G.defined_symbols()) {
209 if (!Sym->hasName())
210 continue;
212 if (Sym->getLinkage() == Linkage::Weak) {
213 if (!S.CanonicalWeakDefs.count(Sym->getName()) ||
214 S.CanonicalWeakDefs[Sym->getName()] != G.getName()) {
215 LLVM_DEBUG({
216 dbgs() << " Externalizing weak symbol " << Sym->getName() << "\n";
218 DefinitionsToRemove.push_back(Sym);
219 } else {
220 LLVM_DEBUG({
221 dbgs() << " Making weak symbol " << Sym->getName() << " strong\n";
223 if (S.HarnessExternals.count(Sym->getName()))
224 Sym->setScope(Scope::Default);
225 else
226 Sym->setScope(Scope::Hidden);
227 Sym->setLinkage(Linkage::Strong);
229 } else if (S.HarnessExternals.count(Sym->getName())) {
230 LLVM_DEBUG(dbgs() << " Promoting " << Sym->getName() << "\n");
231 Sym->setScope(Scope::Default);
232 Sym->setLive(true);
233 continue;
234 } else if (S.HarnessDefinitions.count(Sym->getName())) {
235 LLVM_DEBUG(dbgs() << " Externalizing " << Sym->getName() << "\n");
236 DefinitionsToRemove.push_back(Sym);
240 for (auto *Sym : DefinitionsToRemove)
241 G.makeExternal(*Sym);
243 return Error::success();
246 static uint64_t computeTotalBlockSizes(LinkGraph &G) {
247 uint64_t TotalSize = 0;
248 for (auto *B : G.blocks())
249 TotalSize += B->getSize();
250 return TotalSize;
253 static void dumpSectionContents(raw_ostream &OS, LinkGraph &G) {
254 constexpr JITTargetAddress DumpWidth = 16;
255 static_assert(isPowerOf2_64(DumpWidth), "DumpWidth must be a power of two");
257 // Put sections in address order.
258 std::vector<Section *> Sections;
259 for (auto &S : G.sections())
260 Sections.push_back(&S);
262 std::sort(Sections.begin(), Sections.end(),
263 [](const Section *LHS, const Section *RHS) {
264 if (llvm::empty(LHS->symbols()) && llvm::empty(RHS->symbols()))
265 return false;
266 if (llvm::empty(LHS->symbols()))
267 return false;
268 if (llvm::empty(RHS->symbols()))
269 return true;
270 SectionRange LHSRange(*LHS);
271 SectionRange RHSRange(*RHS);
272 return LHSRange.getStart() < RHSRange.getStart();
275 for (auto *S : Sections) {
276 OS << S->getName() << " content:";
277 if (llvm::empty(S->symbols())) {
278 OS << "\n section empty\n";
279 continue;
282 // Sort symbols into order, then render.
283 std::vector<Symbol *> Syms(S->symbols().begin(), S->symbols().end());
284 llvm::sort(Syms, [](const Symbol *LHS, const Symbol *RHS) {
285 return LHS->getAddress() < RHS->getAddress();
288 JITTargetAddress NextAddr = Syms.front()->getAddress() & ~(DumpWidth - 1);
289 for (auto *Sym : Syms) {
290 bool IsZeroFill = Sym->getBlock().isZeroFill();
291 JITTargetAddress SymStart = Sym->getAddress();
292 JITTargetAddress SymSize = Sym->getSize();
293 JITTargetAddress SymEnd = SymStart + SymSize;
294 const uint8_t *SymData =
295 IsZeroFill ? nullptr : Sym->getSymbolContent().bytes_begin();
297 // Pad any space before the symbol starts.
298 while (NextAddr != SymStart) {
299 if (NextAddr % DumpWidth == 0)
300 OS << formatv("\n{0:x16}:", NextAddr);
301 OS << " ";
302 ++NextAddr;
305 // Render the symbol content.
306 while (NextAddr != SymEnd) {
307 if (NextAddr % DumpWidth == 0)
308 OS << formatv("\n{0:x16}:", NextAddr);
309 if (IsZeroFill)
310 OS << " 00";
311 else
312 OS << formatv(" {0:x-2}", SymData[NextAddr - SymStart]);
313 ++NextAddr;
316 OS << "\n";
320 class JITLinkSlabAllocator final : public JITLinkMemoryManager {
321 public:
322 static Expected<std::unique_ptr<JITLinkSlabAllocator>>
323 Create(uint64_t SlabSize) {
324 Error Err = Error::success();
325 std::unique_ptr<JITLinkSlabAllocator> Allocator(
326 new JITLinkSlabAllocator(SlabSize, Err));
327 if (Err)
328 return std::move(Err);
329 return std::move(Allocator);
332 Expected<std::unique_ptr<JITLinkMemoryManager::Allocation>>
333 allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) override {
335 using AllocationMap = DenseMap<unsigned, sys::MemoryBlock>;
337 // Local class for allocation.
338 class IPMMAlloc : public Allocation {
339 public:
340 IPMMAlloc(JITLinkSlabAllocator &Parent, AllocationMap SegBlocks)
341 : Parent(Parent), SegBlocks(std::move(SegBlocks)) {}
342 MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
343 assert(SegBlocks.count(Seg) && "No allocation for segment");
344 return {static_cast<char *>(SegBlocks[Seg].base()),
345 SegBlocks[Seg].allocatedSize()};
347 JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
348 assert(SegBlocks.count(Seg) && "No allocation for segment");
349 return pointerToJITTargetAddress(SegBlocks[Seg].base()) +
350 Parent.TargetDelta;
352 void finalizeAsync(FinalizeContinuation OnFinalize) override {
353 OnFinalize(applyProtections());
355 Error deallocate() override {
356 for (auto &KV : SegBlocks)
357 if (auto EC = sys::Memory::releaseMappedMemory(KV.second))
358 return errorCodeToError(EC);
359 return Error::success();
362 private:
363 Error applyProtections() {
364 for (auto &KV : SegBlocks) {
365 auto &Prot = KV.first;
366 auto &Block = KV.second;
367 if (auto EC = sys::Memory::protectMappedMemory(Block, Prot))
368 return errorCodeToError(EC);
369 if (Prot & sys::Memory::MF_EXEC)
370 sys::Memory::InvalidateInstructionCache(Block.base(),
371 Block.allocatedSize());
373 return Error::success();
376 JITLinkSlabAllocator &Parent;
377 AllocationMap SegBlocks;
380 AllocationMap Blocks;
382 for (auto &KV : Request) {
383 auto &Seg = KV.second;
385 if (Seg.getAlignment() > PageSize)
386 return make_error<StringError>("Cannot request higher than page "
387 "alignment",
388 inconvertibleErrorCode());
390 if (PageSize % Seg.getAlignment() != 0)
391 return make_error<StringError>("Page size is not a multiple of "
392 "alignment",
393 inconvertibleErrorCode());
395 uint64_t ZeroFillStart = Seg.getContentSize();
396 uint64_t SegmentSize = ZeroFillStart + Seg.getZeroFillSize();
398 // Round segment size up to page boundary.
399 SegmentSize = (SegmentSize + PageSize - 1) & ~(PageSize - 1);
401 // Take segment bytes from the front of the slab.
402 void *SlabBase = SlabRemaining.base();
403 uint64_t SlabRemainingSize = SlabRemaining.allocatedSize();
405 if (SegmentSize > SlabRemainingSize)
406 return make_error<StringError>("Slab allocator out of memory",
407 inconvertibleErrorCode());
409 sys::MemoryBlock SegMem(SlabBase, SegmentSize);
410 SlabRemaining =
411 sys::MemoryBlock(reinterpret_cast<char *>(SlabBase) + SegmentSize,
412 SlabRemainingSize - SegmentSize);
414 // Zero out the zero-fill memory.
415 memset(static_cast<char *>(SegMem.base()) + ZeroFillStart, 0,
416 Seg.getZeroFillSize());
418 // Record the block for this segment.
419 Blocks[KV.first] = std::move(SegMem);
421 return std::unique_ptr<InProcessMemoryManager::Allocation>(
422 new IPMMAlloc(*this, std::move(Blocks)));
425 private:
426 JITLinkSlabAllocator(uint64_t SlabSize, Error &Err) {
427 ErrorAsOutParameter _(&Err);
429 PageSize = sys::Process::getPageSizeEstimate();
431 if (!isPowerOf2_64(PageSize)) {
432 Err = make_error<StringError>("Page size is not a power of 2",
433 inconvertibleErrorCode());
434 return;
437 // Round slab request up to page size.
438 SlabSize = (SlabSize + PageSize - 1) & ~(PageSize - 1);
440 const sys::Memory::ProtectionFlags ReadWrite =
441 static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
442 sys::Memory::MF_WRITE);
444 std::error_code EC;
445 SlabRemaining =
446 sys::Memory::allocateMappedMemory(SlabSize, nullptr, ReadWrite, EC);
448 if (EC) {
449 Err = errorCodeToError(EC);
450 return;
453 // Calculate the target address delta to link as-if slab were at
454 // SlabAddress.
455 if (SlabAddress != ~0ULL)
456 TargetDelta =
457 SlabAddress - pointerToJITTargetAddress(SlabRemaining.base());
460 sys::MemoryBlock SlabRemaining;
461 uint64_t PageSize = 0;
462 int64_t TargetDelta = 0;
465 Expected<uint64_t> getSlabAllocSize(StringRef SizeString) {
466 SizeString = SizeString.trim();
468 uint64_t Units = 1024;
470 if (SizeString.endswith_lower("kb"))
471 SizeString = SizeString.drop_back(2).rtrim();
472 else if (SizeString.endswith_lower("mb")) {
473 Units = 1024 * 1024;
474 SizeString = SizeString.drop_back(2).rtrim();
475 } else if (SizeString.endswith_lower("gb")) {
476 Units = 1024 * 1024 * 1024;
477 SizeString = SizeString.drop_back(2).rtrim();
480 uint64_t SlabSize = 0;
481 if (SizeString.getAsInteger(10, SlabSize))
482 return make_error<StringError>("Invalid numeric format for slab size",
483 inconvertibleErrorCode());
485 return SlabSize * Units;
488 static std::unique_ptr<JITLinkMemoryManager> createMemoryManager() {
489 if (!SlabAllocateSizeString.empty()) {
490 auto SlabSize = ExitOnErr(getSlabAllocSize(SlabAllocateSizeString));
491 return ExitOnErr(JITLinkSlabAllocator::Create(SlabSize));
493 return std::make_unique<InProcessMemoryManager>();
496 LLVMJITLinkObjectLinkingLayer::LLVMJITLinkObjectLinkingLayer(
497 Session &S, JITLinkMemoryManager &MemMgr)
498 : ObjectLinkingLayer(S.ES, MemMgr), S(S) {}
500 Error LLVMJITLinkObjectLinkingLayer::add(ResourceTrackerSP RT,
501 std::unique_ptr<MemoryBuffer> O) {
503 if (S.HarnessFiles.empty() || S.HarnessFiles.count(O->getBufferIdentifier()))
504 return ObjectLinkingLayer::add(std::move(RT), std::move(O));
506 // Use getObjectSymbolInfo to compute the init symbol, but ignore
507 // the symbols field. We'll handle that manually to include promotion.
508 auto ObjSymInfo =
509 getObjectSymbolInfo(getExecutionSession(), O->getMemBufferRef());
511 if (!ObjSymInfo)
512 return ObjSymInfo.takeError();
514 auto &InitSymbol = ObjSymInfo->second;
516 // If creating an object file was going to fail it would have happened above,
517 // so we can 'cantFail' this.
518 auto Obj =
519 cantFail(object::ObjectFile::createObjectFile(O->getMemBufferRef()));
521 SymbolFlagsMap SymbolFlags;
523 // The init symbol must be included in the SymbolFlags map if present.
524 if (InitSymbol)
525 SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly;
527 for (auto &Sym : Obj->symbols()) {
528 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
529 if (!SymFlagsOrErr)
530 // TODO: Test this error.
531 return SymFlagsOrErr.takeError();
533 // Skip symbols not defined in this object file.
534 if ((*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined))
535 continue;
537 auto Name = Sym.getName();
538 if (!Name)
539 return Name.takeError();
541 // Skip symbols that have type SF_File.
542 if (auto SymType = Sym.getType()) {
543 if (*SymType == object::SymbolRef::ST_File)
544 continue;
545 } else
546 return SymType.takeError();
548 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
549 if (!SymFlags)
550 return SymFlags.takeError();
552 if (SymFlags->isWeak()) {
553 // If this is a weak symbol that's not defined in the harness then we
554 // need to either mark it as strong (if this is the first definition
555 // that we've seen) or discard it.
556 if (S.HarnessDefinitions.count(*Name) || S.CanonicalWeakDefs.count(*Name))
557 continue;
558 S.CanonicalWeakDefs[*Name] = O->getBufferIdentifier();
559 *SymFlags &= ~JITSymbolFlags::Weak;
560 if (!S.HarnessExternals.count(*Name))
561 *SymFlags &= ~JITSymbolFlags::Exported;
562 } else if (S.HarnessExternals.count(*Name)) {
563 *SymFlags |= JITSymbolFlags::Exported;
564 } else if (S.HarnessDefinitions.count(*Name) ||
565 !(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
566 continue;
568 auto InternedName = S.ES.intern(*Name);
569 SymbolFlags[InternedName] = std::move(*SymFlags);
572 auto MU = std::make_unique<BasicObjectLayerMaterializationUnit>(
573 *this, std::move(O), std::move(SymbolFlags), std::move(InitSymbol));
575 auto &JD = RT->getJITDylib();
576 return JD.define(std::move(MU), std::move(RT));
579 Expected<std::unique_ptr<TargetProcessControl>>
580 LLVMJITLinkRemoteTargetProcessControl::LaunchExecutor() {
581 #ifndef LLVM_ON_UNIX
582 // FIXME: Add support for Windows.
583 return make_error<StringError>("-" + OutOfProcessExecutor.ArgStr +
584 " not supported on non-unix platforms",
585 inconvertibleErrorCode());
586 #else
588 rpc::registerStringError<LLVMJITLinkChannel>();
590 constexpr int ReadEnd = 0;
591 constexpr int WriteEnd = 1;
593 // Pipe FDs.
594 int ToExecutor[2];
595 int FromExecutor[2];
597 pid_t ChildPID;
599 // Create pipes to/from the executor..
600 if (pipe(ToExecutor) != 0 || pipe(FromExecutor) != 0)
601 return make_error<StringError>("Unable to create pipe for executor",
602 inconvertibleErrorCode());
604 ChildPID = fork();
606 if (ChildPID == 0) {
607 // In the child...
609 // Close the parent ends of the pipes
610 close(ToExecutor[WriteEnd]);
611 close(FromExecutor[ReadEnd]);
613 // Execute the child process.
614 std::unique_ptr<char[]> ExecutorPath, FDSpecifier;
616 ExecutorPath = std::make_unique<char[]>(OutOfProcessExecutor.size() + 1);
617 strcpy(ExecutorPath.get(), OutOfProcessExecutor.data());
619 std::string FDSpecifierStr("filedescs=");
620 FDSpecifierStr += utostr(ToExecutor[ReadEnd]);
621 FDSpecifierStr += ',';
622 FDSpecifierStr += utostr(FromExecutor[WriteEnd]);
623 FDSpecifier = std::make_unique<char[]>(FDSpecifierStr.size() + 1);
624 strcpy(FDSpecifier.get(), FDSpecifierStr.c_str());
627 char *const Args[] = {ExecutorPath.get(), FDSpecifier.get(), nullptr};
628 int RC = execvp(ExecutorPath.get(), Args);
629 if (RC != 0) {
630 errs() << "unable to launch out-of-process executor \""
631 << ExecutorPath.get() << "\"\n";
632 exit(1);
635 // else we're the parent...
637 // Close the child ends of the pipes
638 close(ToExecutor[ReadEnd]);
639 close(FromExecutor[WriteEnd]);
641 // Return an RPC channel connected to our end of the pipes.
642 auto SSP = std::make_shared<SymbolStringPool>();
643 auto Channel = std::make_unique<rpc::FDRawByteChannel>(FromExecutor[ReadEnd],
644 ToExecutor[WriteEnd]);
645 auto Endpoint = std::make_unique<LLVMJITLinkRPCEndpoint>(*Channel, true);
647 auto ReportError = [](Error Err) {
648 logAllUnhandledErrors(std::move(Err), errs(), "");
651 Error Err = Error::success();
652 std::unique_ptr<LLVMJITLinkRemoteTargetProcessControl> RTPC(
653 new LLVMJITLinkRemoteTargetProcessControl(
654 std::move(SSP), std::move(Channel), std::move(Endpoint),
655 std::move(ReportError), Err));
656 if (Err)
657 return std::move(Err);
658 return std::move(RTPC);
659 #endif
662 Expected<std::unique_ptr<TargetProcessControl>>
663 LLVMJITLinkRemoteTargetProcessControl::ConnectToExecutor() {
664 #ifndef LLVM_ON_UNIX
665 // FIXME: Add TCP support for Windows.
666 return make_error<StringError>("-" + OutOfProcessExecutorConnect.ArgStr +
667 " not supported on non-unix platforms",
668 inconvertibleErrorCode());
669 #else
671 rpc::registerStringError<LLVMJITLinkChannel>();
673 StringRef HostNameStr, PortStr;
674 std::tie(HostNameStr, PortStr) =
675 StringRef(OutOfProcessExecutorConnect).split(':');
677 if (HostNameStr.empty())
678 return make_error<StringError>("host name for -" +
679 OutOfProcessExecutorConnect.ArgStr +
680 " can not be empty",
681 inconvertibleErrorCode());
682 if (PortStr.empty())
683 return make_error<StringError>(
684 "port for -" + OutOfProcessExecutorConnect.ArgStr + " can not be empty",
685 inconvertibleErrorCode());
687 std::string HostName = HostNameStr.str();
688 int Port = 0;
689 if (PortStr.getAsInteger(10, Port))
690 return make_error<StringError>("port number " + PortStr +
691 " is not a valid integer",
692 inconvertibleErrorCode());
694 int SockFD = socket(PF_INET, SOCK_STREAM, 0);
695 hostent *Server = gethostbyname(HostName.c_str());
696 sockaddr_in ServAddr;
697 memset(&ServAddr, 0, sizeof(ServAddr));
698 ServAddr.sin_family = PF_INET;
699 memmove(&Server->h_addr, &ServAddr.sin_addr.s_addr, Server->h_length);
700 ServAddr.sin_port = htons(Port);
701 if (connect(SockFD, reinterpret_cast<sockaddr *>(&ServAddr),
702 sizeof(ServAddr)) < 0)
703 return make_error<StringError>("Failed to connect to " + HostName + ":" +
704 Twine(Port),
705 inconvertibleErrorCode());
707 auto SSP = std::make_shared<SymbolStringPool>();
708 auto Channel = std::make_unique<rpc::FDRawByteChannel>(SockFD, SockFD);
709 auto Endpoint = std::make_unique<LLVMJITLinkRPCEndpoint>(*Channel, true);
711 auto ReportError = [](Error Err) {
712 logAllUnhandledErrors(std::move(Err), errs(), "");
715 Error Err = Error::success();
716 std::unique_ptr<LLVMJITLinkRemoteTargetProcessControl> RTPC(
717 new LLVMJITLinkRemoteTargetProcessControl(
718 std::move(SSP), std::move(Channel), std::move(Endpoint),
719 std::move(ReportError), Err));
720 if (Err)
721 return std::move(Err);
722 return std::move(RTPC);
723 #endif
726 Error LLVMJITLinkRemoteTargetProcessControl::disconnect() {
727 std::promise<MSVCPError> P;
728 auto F = P.get_future();
729 auto Err = closeConnection([&](Error Err) -> Error {
730 P.set_value(std::move(Err));
731 Finished = true;
732 return Error::success();
734 ListenerThread.join();
735 return joinErrors(std::move(Err), F.get());
738 class PhonyExternalsGenerator : public DefinitionGenerator {
739 public:
740 Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
741 JITDylibLookupFlags JDLookupFlags,
742 const SymbolLookupSet &LookupSet) override {
743 SymbolMap PhonySymbols;
744 for (auto &KV : LookupSet)
745 PhonySymbols[KV.first] = JITEvaluatedSymbol(0, JITSymbolFlags::Exported);
746 return JD.define(absoluteSymbols(std::move(PhonySymbols)));
750 Expected<std::unique_ptr<Session>> Session::Create(Triple TT) {
752 auto PageSize = sys::Process::getPageSize();
753 if (!PageSize)
754 return PageSize.takeError();
756 /// If -oop-executor is passed then launch the executor.
757 std::unique_ptr<TargetProcessControl> TPC;
758 if (OutOfProcessExecutor.getNumOccurrences()) {
759 if (auto RTPC = LLVMJITLinkRemoteTargetProcessControl::LaunchExecutor())
760 TPC = std::move(*RTPC);
761 else
762 return RTPC.takeError();
763 } else if (OutOfProcessExecutorConnect.getNumOccurrences()) {
764 if (auto RTPC = LLVMJITLinkRemoteTargetProcessControl::ConnectToExecutor())
765 TPC = std::move(*RTPC);
766 else
767 return RTPC.takeError();
768 } else
769 TPC = std::make_unique<SelfTargetProcessControl>(
770 std::make_shared<SymbolStringPool>(), std::move(TT), *PageSize,
771 createMemoryManager());
773 Error Err = Error::success();
774 std::unique_ptr<Session> S(new Session(std::move(TPC), Err));
775 if (Err)
776 return std::move(Err);
777 return std::move(S);
780 Session::~Session() {
781 if (auto Err = ES.endSession())
782 ES.reportError(std::move(Err));
785 // FIXME: Move to createJITDylib if/when we start using Platform support in
786 // llvm-jitlink.
787 Session::Session(std::unique_ptr<TargetProcessControl> TPC, Error &Err)
788 : TPC(std::move(TPC)), ObjLayer(*this, this->TPC->getMemMgr()) {
790 /// Local ObjectLinkingLayer::Plugin class to forward modifyPassConfig to the
791 /// Session.
792 class JITLinkSessionPlugin : public ObjectLinkingLayer::Plugin {
793 public:
794 JITLinkSessionPlugin(Session &S) : S(S) {}
795 void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
796 PassConfiguration &PassConfig) override {
797 S.modifyPassConfig(TT, PassConfig);
800 Error notifyFailed(MaterializationResponsibility &MR) override {
801 return Error::success();
803 Error notifyRemovingResources(ResourceKey K) override {
804 return Error::success();
806 void notifyTransferringResources(ResourceKey DstKey,
807 ResourceKey SrcKey) override {}
809 private:
810 Session &S;
813 ErrorAsOutParameter _(&Err);
815 if (auto MainJDOrErr = ES.createJITDylib("main"))
816 MainJD = &*MainJDOrErr;
817 else {
818 Err = MainJDOrErr.takeError();
819 return;
822 if (!NoExec && !this->TPC->getTargetTriple().isOSWindows())
823 ObjLayer.addPlugin(std::make_unique<EHFrameRegistrationPlugin>(
824 ES, ExitOnErr(TPCEHFrameRegistrar::Create(*this->TPC))));
826 ObjLayer.addPlugin(std::make_unique<JITLinkSessionPlugin>(*this));
828 // Process any harness files.
829 for (auto &HarnessFile : TestHarnesses) {
830 HarnessFiles.insert(HarnessFile);
832 auto ObjBuffer =
833 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(HarnessFile)));
835 auto ObjSymbolInfo =
836 ExitOnErr(getObjectSymbolInfo(ES, ObjBuffer->getMemBufferRef()));
838 for (auto &KV : ObjSymbolInfo.first)
839 HarnessDefinitions.insert(*KV.first);
841 auto Obj = ExitOnErr(
842 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()));
844 for (auto &Sym : Obj->symbols()) {
845 uint32_t SymFlags = ExitOnErr(Sym.getFlags());
846 auto Name = ExitOnErr(Sym.getName());
848 if (Name.empty())
849 continue;
851 if (SymFlags & object::BasicSymbolRef::SF_Undefined)
852 HarnessExternals.insert(Name);
856 // If a name is defined by some harness file then it's a definition, not an
857 // external.
858 for (auto &DefName : HarnessDefinitions)
859 HarnessExternals.erase(DefName.getKey());
862 void Session::dumpSessionInfo(raw_ostream &OS) {
863 OS << "Registered addresses:\n" << SymbolInfos << FileInfos;
866 void Session::modifyPassConfig(const Triple &TT,
867 PassConfiguration &PassConfig) {
868 if (!CheckFiles.empty())
869 PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) {
870 if (TPC->getTargetTriple().getObjectFormat() == Triple::ELF)
871 return registerELFGraphInfo(*this, G);
873 if (TPC->getTargetTriple().getObjectFormat() == Triple::MachO)
874 return registerMachOGraphInfo(*this, G);
876 return make_error<StringError>("Unsupported object format for GOT/stub "
877 "registration",
878 inconvertibleErrorCode());
881 if (ShowLinkGraph)
882 PassConfig.PostFixupPasses.push_back([](LinkGraph &G) -> Error {
883 outs() << "Link graph \"" << G.getName() << "\" post-fixup:\n";
884 G.dump(outs());
885 return Error::success();
888 PassConfig.PrePrunePasses.push_back(
889 [this](LinkGraph &G) { return applyHarnessPromotions(*this, G); });
891 if (ShowSizes) {
892 PassConfig.PrePrunePasses.push_back([this](LinkGraph &G) -> Error {
893 SizeBeforePruning += computeTotalBlockSizes(G);
894 return Error::success();
896 PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error {
897 SizeAfterFixups += computeTotalBlockSizes(G);
898 return Error::success();
902 if (ShowRelocatedSectionContents)
903 PassConfig.PostFixupPasses.push_back([](LinkGraph &G) -> Error {
904 outs() << "Relocated section contents for " << G.getName() << ":\n";
905 dumpSectionContents(outs(), G);
906 return Error::success();
910 Expected<Session::FileInfo &> Session::findFileInfo(StringRef FileName) {
911 auto FileInfoItr = FileInfos.find(FileName);
912 if (FileInfoItr == FileInfos.end())
913 return make_error<StringError>("file \"" + FileName + "\" not recognized",
914 inconvertibleErrorCode());
915 return FileInfoItr->second;
918 Expected<Session::MemoryRegionInfo &>
919 Session::findSectionInfo(StringRef FileName, StringRef SectionName) {
920 auto FI = findFileInfo(FileName);
921 if (!FI)
922 return FI.takeError();
923 auto SecInfoItr = FI->SectionInfos.find(SectionName);
924 if (SecInfoItr == FI->SectionInfos.end())
925 return make_error<StringError>("no section \"" + SectionName +
926 "\" registered for file \"" + FileName +
927 "\"",
928 inconvertibleErrorCode());
929 return SecInfoItr->second;
932 Expected<Session::MemoryRegionInfo &>
933 Session::findStubInfo(StringRef FileName, StringRef TargetName) {
934 auto FI = findFileInfo(FileName);
935 if (!FI)
936 return FI.takeError();
937 auto StubInfoItr = FI->StubInfos.find(TargetName);
938 if (StubInfoItr == FI->StubInfos.end())
939 return make_error<StringError>("no stub for \"" + TargetName +
940 "\" registered for file \"" + FileName +
941 "\"",
942 inconvertibleErrorCode());
943 return StubInfoItr->second;
946 Expected<Session::MemoryRegionInfo &>
947 Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) {
948 auto FI = findFileInfo(FileName);
949 if (!FI)
950 return FI.takeError();
951 auto GOTInfoItr = FI->GOTEntryInfos.find(TargetName);
952 if (GOTInfoItr == FI->GOTEntryInfos.end())
953 return make_error<StringError>("no GOT entry for \"" + TargetName +
954 "\" registered for file \"" + FileName +
955 "\"",
956 inconvertibleErrorCode());
957 return GOTInfoItr->second;
960 bool Session::isSymbolRegistered(StringRef SymbolName) {
961 return SymbolInfos.count(SymbolName);
964 Expected<Session::MemoryRegionInfo &>
965 Session::findSymbolInfo(StringRef SymbolName, Twine ErrorMsgStem) {
966 auto SymInfoItr = SymbolInfos.find(SymbolName);
967 if (SymInfoItr == SymbolInfos.end())
968 return make_error<StringError>(ErrorMsgStem + ": symbol " + SymbolName +
969 " not found",
970 inconvertibleErrorCode());
971 return SymInfoItr->second;
974 } // end namespace llvm
976 static Triple getFirstFileTriple() {
977 static Triple FirstTT = []() {
978 assert(!InputFiles.empty() && "InputFiles can not be empty");
979 auto ObjBuffer =
980 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(InputFiles.front())));
981 auto Obj = ExitOnErr(
982 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()));
983 return Obj->makeTriple();
984 }();
986 return FirstTT;
989 static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {
990 // Set the entry point name if not specified.
991 if (EntryPointName.empty()) {
992 if (TT.getObjectFormat() == Triple::MachO)
993 EntryPointName = "_main";
994 else
995 EntryPointName = "main";
998 // -noexec and --args should not be used together.
999 if (NoExec && !InputArgv.empty())
1000 outs() << "Warning: --args passed to -noexec run will be ignored.\n";
1002 // If -slab-address is passed, require -slab-allocate and -noexec
1003 if (SlabAddress != ~0ULL) {
1004 if (SlabAllocateSizeString == "" || !NoExec)
1005 return make_error<StringError>(
1006 "-slab-address requires -slab-allocate and -noexec",
1007 inconvertibleErrorCode());
1010 // Only one of -oop-executor and -oop-executor-connect can be used.
1011 if (!!OutOfProcessExecutor.getNumOccurrences() &&
1012 !!OutOfProcessExecutorConnect.getNumOccurrences())
1013 return make_error<StringError>(
1014 "Only one of -" + OutOfProcessExecutor.ArgStr + " and -" +
1015 OutOfProcessExecutorConnect.ArgStr + " can be specified",
1016 inconvertibleErrorCode());
1018 // If -oop-executor was used but no value was specified then use a sensible
1019 // default.
1020 if (!!OutOfProcessExecutor.getNumOccurrences() &&
1021 OutOfProcessExecutor.empty()) {
1022 SmallString<256> OOPExecutorPath(sys::fs::getMainExecutable(
1023 ArgV0, reinterpret_cast<void *>(&sanitizeArguments)));
1024 sys::path::remove_filename(OOPExecutorPath);
1025 if (OOPExecutorPath.back() != '/')
1026 OOPExecutorPath += '/';
1027 OOPExecutorPath += "llvm-jitlink-executor";
1028 OutOfProcessExecutor = OOPExecutorPath.str().str();
1031 return Error::success();
1034 static Error loadProcessSymbols(Session &S) {
1035 auto FilterMainEntryPoint =
1036 [EPName = S.ES.intern(EntryPointName)](SymbolStringPtr Name) {
1037 return Name != EPName;
1039 S.MainJD->addGenerator(
1040 ExitOnErr(orc::TPCDynamicLibrarySearchGenerator::GetForTargetProcess(
1041 *S.TPC, std::move(FilterMainEntryPoint))));
1043 return Error::success();
1046 static Error loadDylibs(Session &S) {
1047 for (const auto &Dylib : Dylibs) {
1048 auto G = orc::TPCDynamicLibrarySearchGenerator::Load(*S.TPC, Dylib.c_str());
1049 if (!G)
1050 return G.takeError();
1051 S.MainJD->addGenerator(std::move(*G));
1054 return Error::success();
1057 static void addPhonyExternalsGenerator(Session &S) {
1058 S.MainJD->addGenerator(std::make_unique<PhonyExternalsGenerator>());
1061 static Error loadObjects(Session &S) {
1062 std::map<unsigned, JITDylib *> IdxToJLD;
1064 // First, set up JITDylibs.
1065 LLVM_DEBUG(dbgs() << "Creating JITDylibs...\n");
1067 // Create a "main" JITLinkDylib.
1068 IdxToJLD[0] = S.MainJD;
1069 S.JDSearchOrder.push_back(S.MainJD);
1070 LLVM_DEBUG(dbgs() << " 0: " << S.MainJD->getName() << "\n");
1072 // Add any extra JITLinkDylibs from the command line.
1073 std::string JDNamePrefix("lib");
1074 for (auto JLDItr = JITLinkDylibs.begin(), JLDEnd = JITLinkDylibs.end();
1075 JLDItr != JLDEnd; ++JLDItr) {
1076 auto JD = S.ES.createJITDylib(JDNamePrefix + *JLDItr);
1077 if (!JD)
1078 return JD.takeError();
1079 unsigned JDIdx =
1080 JITLinkDylibs.getPosition(JLDItr - JITLinkDylibs.begin());
1081 IdxToJLD[JDIdx] = &*JD;
1082 S.JDSearchOrder.push_back(&*JD);
1083 LLVM_DEBUG(dbgs() << " " << JDIdx << ": " << JD->getName() << "\n");
1086 // Set every dylib to link against every other, in command line order.
1087 for (auto *JD : S.JDSearchOrder) {
1088 auto LookupFlags = JITDylibLookupFlags::MatchExportedSymbolsOnly;
1089 JITDylibSearchOrder LinkOrder;
1090 for (auto *JD2 : S.JDSearchOrder) {
1091 if (JD2 == JD)
1092 continue;
1093 LinkOrder.push_back(std::make_pair(JD2, LookupFlags));
1095 JD->setLinkOrder(std::move(LinkOrder));
1099 LLVM_DEBUG(dbgs() << "Adding test harness objects...\n");
1100 for (auto HarnessFile : TestHarnesses) {
1101 LLVM_DEBUG(dbgs() << " " << HarnessFile << "\n");
1102 auto ObjBuffer =
1103 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(HarnessFile)));
1104 ExitOnErr(S.ObjLayer.add(*S.MainJD, std::move(ObjBuffer)));
1107 // Load each object into the corresponding JITDylib..
1108 LLVM_DEBUG(dbgs() << "Adding objects...\n");
1109 for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();
1110 InputFileItr != InputFileEnd; ++InputFileItr) {
1111 unsigned InputFileArgIdx =
1112 InputFiles.getPosition(InputFileItr - InputFiles.begin());
1113 const std::string &InputFile = *InputFileItr;
1114 auto &JD = *std::prev(IdxToJLD.lower_bound(InputFileArgIdx))->second;
1115 LLVM_DEBUG(dbgs() << " " << InputFileArgIdx << ": \"" << InputFile
1116 << "\" to " << JD.getName() << "\n";);
1117 auto ObjBuffer =
1118 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(InputFile)));
1120 auto Magic = identify_magic(ObjBuffer->getBuffer());
1121 if (Magic == file_magic::archive ||
1122 Magic == file_magic::macho_universal_binary)
1123 JD.addGenerator(ExitOnErr(StaticLibraryDefinitionGenerator::Load(
1124 S.ObjLayer, InputFile.c_str(), S.TPC->getTargetTriple())));
1125 else
1126 ExitOnErr(S.ObjLayer.add(JD, std::move(ObjBuffer)));
1129 // Define absolute symbols.
1130 LLVM_DEBUG(dbgs() << "Defining absolute symbols...\n");
1131 for (auto AbsDefItr = AbsoluteDefs.begin(), AbsDefEnd = AbsoluteDefs.end();
1132 AbsDefItr != AbsDefEnd; ++AbsDefItr) {
1133 unsigned AbsDefArgIdx =
1134 AbsoluteDefs.getPosition(AbsDefItr - AbsoluteDefs.begin());
1135 auto &JD = *std::prev(IdxToJLD.lower_bound(AbsDefArgIdx))->second;
1137 StringRef AbsDefStmt = *AbsDefItr;
1138 size_t EqIdx = AbsDefStmt.find_first_of('=');
1139 if (EqIdx == StringRef::npos)
1140 return make_error<StringError>("Invalid absolute define \"" + AbsDefStmt +
1141 "\". Syntax: <name>=<addr>",
1142 inconvertibleErrorCode());
1143 StringRef Name = AbsDefStmt.substr(0, EqIdx).trim();
1144 StringRef AddrStr = AbsDefStmt.substr(EqIdx + 1).trim();
1146 uint64_t Addr;
1147 if (AddrStr.getAsInteger(0, Addr))
1148 return make_error<StringError>("Invalid address expression \"" + AddrStr +
1149 "\" in absolute define \"" + AbsDefStmt +
1150 "\"",
1151 inconvertibleErrorCode());
1152 JITEvaluatedSymbol AbsDef(Addr, JITSymbolFlags::Exported);
1153 if (auto Err = JD.define(absoluteSymbols({{S.ES.intern(Name), AbsDef}})))
1154 return Err;
1156 // Register the absolute symbol with the session symbol infos.
1157 S.SymbolInfos[Name] = { StringRef(), Addr };
1160 LLVM_DEBUG({
1161 dbgs() << "Dylib search order is [ ";
1162 for (auto *JD : S.JDSearchOrder)
1163 dbgs() << JD->getName() << " ";
1164 dbgs() << "]\n";
1167 return Error::success();
1170 static Error runChecks(Session &S) {
1172 auto TripleName = S.TPC->getTargetTriple().str();
1173 std::string ErrorStr;
1174 const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, ErrorStr);
1175 if (!TheTarget)
1176 ExitOnErr(make_error<StringError>("Error accessing target '" + TripleName +
1177 "': " + ErrorStr,
1178 inconvertibleErrorCode()));
1180 std::unique_ptr<MCSubtargetInfo> STI(
1181 TheTarget->createMCSubtargetInfo(TripleName, "", ""));
1182 if (!STI)
1183 ExitOnErr(
1184 make_error<StringError>("Unable to create subtarget for " + TripleName,
1185 inconvertibleErrorCode()));
1187 std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
1188 if (!MRI)
1189 ExitOnErr(make_error<StringError>("Unable to create target register info "
1190 "for " +
1191 TripleName,
1192 inconvertibleErrorCode()));
1194 MCTargetOptions MCOptions;
1195 std::unique_ptr<MCAsmInfo> MAI(
1196 TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
1197 if (!MAI)
1198 ExitOnErr(make_error<StringError>("Unable to create target asm info " +
1199 TripleName,
1200 inconvertibleErrorCode()));
1202 MCContext Ctx(MAI.get(), MRI.get(), nullptr);
1204 std::unique_ptr<MCDisassembler> Disassembler(
1205 TheTarget->createMCDisassembler(*STI, Ctx));
1206 if (!Disassembler)
1207 ExitOnErr(make_error<StringError>("Unable to create disassembler for " +
1208 TripleName,
1209 inconvertibleErrorCode()));
1211 std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
1213 std::unique_ptr<MCInstPrinter> InstPrinter(
1214 TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI));
1216 auto IsSymbolValid = [&S](StringRef Symbol) {
1217 return S.isSymbolRegistered(Symbol);
1220 auto GetSymbolInfo = [&S](StringRef Symbol) {
1221 return S.findSymbolInfo(Symbol, "Can not get symbol info");
1224 auto GetSectionInfo = [&S](StringRef FileName, StringRef SectionName) {
1225 return S.findSectionInfo(FileName, SectionName);
1228 auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName) {
1229 return S.findStubInfo(FileName, SectionName);
1232 auto GetGOTInfo = [&S](StringRef FileName, StringRef SectionName) {
1233 return S.findGOTEntryInfo(FileName, SectionName);
1236 RuntimeDyldChecker Checker(
1237 IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo,
1238 S.TPC->getTargetTriple().isLittleEndian() ? support::little
1239 : support::big,
1240 Disassembler.get(), InstPrinter.get(), dbgs());
1242 std::string CheckLineStart = "# " + CheckName + ":";
1243 for (auto &CheckFile : CheckFiles) {
1244 auto CheckerFileBuf =
1245 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(CheckFile)));
1246 if (!Checker.checkAllRulesInBuffer(CheckLineStart, &*CheckerFileBuf))
1247 ExitOnErr(make_error<StringError>(
1248 "Some checks in " + CheckFile + " failed", inconvertibleErrorCode()));
1251 return Error::success();
1254 static void dumpSessionStats(Session &S) {
1255 if (ShowSizes)
1256 outs() << "Total size of all blocks before pruning: " << S.SizeBeforePruning
1257 << "\nTotal size of all blocks after fixups: " << S.SizeAfterFixups
1258 << "\n";
1261 static Expected<JITEvaluatedSymbol> getMainEntryPoint(Session &S) {
1262 return S.ES.lookup(S.JDSearchOrder, EntryPointName);
1265 namespace {
1266 struct JITLinkTimers {
1267 TimerGroup JITLinkTG{"llvm-jitlink timers", "timers for llvm-jitlink phases"};
1268 Timer LoadObjectsTimer{"load", "time to load/add object files", JITLinkTG};
1269 Timer LinkTimer{"link", "time to link object files", JITLinkTG};
1270 Timer RunTimer{"run", "time to execute jitlink'd code", JITLinkTG};
1272 } // namespace
1274 int main(int argc, char *argv[]) {
1275 InitLLVM X(argc, argv);
1277 InitializeAllTargetInfos();
1278 InitializeAllTargetMCs();
1279 InitializeAllDisassemblers();
1281 cl::ParseCommandLineOptions(argc, argv, "llvm jitlink tool");
1282 ExitOnErr.setBanner(std::string(argv[0]) + ": ");
1284 /// If timers are enabled, create a JITLinkTimers instance.
1285 std::unique_ptr<JITLinkTimers> Timers =
1286 ShowTimes ? std::make_unique<JITLinkTimers>() : nullptr;
1288 ExitOnErr(sanitizeArguments(getFirstFileTriple(), argv[0]));
1290 auto S = ExitOnErr(Session::Create(getFirstFileTriple()));
1293 TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
1294 ExitOnErr(loadObjects(*S));
1297 if (!NoProcessSymbols)
1298 ExitOnErr(loadProcessSymbols(*S));
1299 ExitOnErr(loadDylibs(*S));
1301 if (PhonyExternals)
1302 addPhonyExternalsGenerator(*S);
1305 if (ShowInitialExecutionSessionState)
1306 S->ES.dump(outs());
1308 JITEvaluatedSymbol EntryPoint = 0;
1310 TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr);
1311 EntryPoint = ExitOnErr(getMainEntryPoint(*S));
1314 if (ShowAddrs)
1315 S->dumpSessionInfo(outs());
1317 ExitOnErr(runChecks(*S));
1319 dumpSessionStats(*S);
1321 if (NoExec)
1322 return 0;
1324 int Result = 0;
1326 TimeRegion TR(Timers ? &Timers->RunTimer : nullptr);
1327 Result = ExitOnErr(S->TPC->runAsMain(EntryPoint.getAddress(), InputArgv));
1330 ExitOnErr(S->ES.endSession());
1331 ExitOnErr(S->TPC->disconnect());
1333 return Result;