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.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm-jitlink.h"
16
17 #include "llvm/BinaryFormat/Magic.h"
18 #include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
19 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
20 #include "llvm/ExecutionEngine/Orc/TPCDebugObjectRegistrar.h"
21 #include "llvm/ExecutionEngine/Orc/TPCDynamicLibrarySearchGenerator.h"
22 #include "llvm/ExecutionEngine/Orc/TPCEHFrameRegistrar.h"
23 #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
24 #include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
28 #include "llvm/MC/MCInstPrinter.h"
29 #include "llvm/MC/MCInstrInfo.h"
30 #include "llvm/MC/MCRegisterInfo.h"
31 #include "llvm/MC/MCSubtargetInfo.h"
32 #include "llvm/MC/MCTargetOptions.h"
33 #include "llvm/Object/COFF.h"
34 #include "llvm/Object/MachO.h"
35 #include "llvm/Object/ObjectFile.h"
36 #include "llvm/Support/CommandLine.h"
37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/InitLLVM.h"
39 #include "llvm/Support/MemoryBuffer.h"
40 #include "llvm/Support/Path.h"
41 #include "llvm/Support/Process.h"
42 #include "llvm/Support/TargetRegistry.h"
43 #include "llvm/Support/TargetSelect.h"
44 #include "llvm/Support/Timer.h"
45
46 #include <cstring>
47 #include <list>
48 #include <string>
49
50 #ifdef LLVM_ON_UNIX
51 #include <netdb.h>
52 #include <netinet/in.h>
53 #include <sys/socket.h>
54 #include <unistd.h>
55 #endif // LLVM_ON_UNIX
56
57 #define DEBUG_TYPE "llvm_jitlink"
58
59 using namespace llvm;
60 using namespace llvm::jitlink;
61 using namespace llvm::orc;
62
63 static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,
64 cl::desc("input files"));
65
66 static cl::opt<bool> NoExec("noexec", cl::desc("Do not execute loaded code"),
67 cl::init(false));
68
69 static cl::list<std::string>
70 CheckFiles("check", cl::desc("File containing verifier checks"),
71 cl::ZeroOrMore);
72
73 static cl::opt<std::string>
74 CheckName("check-name", cl::desc("Name of checks to match against"),
75 cl::init("jitlink-check"));
76
77 static cl::opt<std::string>
78 EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
79 cl::init(""));
80
81 static cl::list<std::string> JITLinkDylibs(
82 "jld", cl::desc("Specifies the JITDylib to be used for any subsequent "
83 "input file arguments"));
84
85 static cl::list<std::string>
86 Dylibs("dlopen", cl::desc("Dynamic libraries to load before linking"),
87 cl::ZeroOrMore);
88
89 static cl::list<std::string> InputArgv("args", cl::Positional,
90 cl::desc("<program arguments>..."),
91 cl::ZeroOrMore, cl::PositionalEatsArgs);
92
93 static cl::opt<bool>
94 NoProcessSymbols("no-process-syms",
95 cl::desc("Do not resolve to llvm-jitlink process symbols"),
96 cl::init(false));
97
98 static cl::list<std::string> AbsoluteDefs(
99 "define-abs",
100 cl::desc("Inject absolute symbol definitions (syntax: <name>=<addr>)"),
101 cl::ZeroOrMore);
102
103 static cl::list<std::string> TestHarnesses("harness", cl::Positional,
104 cl::desc("Test harness files"),
105 cl::ZeroOrMore,
106 cl::PositionalEatsArgs);
107
108 static cl::opt<bool> ShowInitialExecutionSessionState(
109 "show-init-es",
110 cl::desc("Print ExecutionSession state before resolving entry point"),
111 cl::init(false));
112
113 static cl::opt<bool> ShowAddrs(
114 "show-addrs",
115 cl::desc("Print registered symbol, section, got and stub addresses"),
116 cl::init(false));
117
118 static cl::opt<bool> ShowLinkGraph(
119 "show-graph",
120 cl::desc("Print the link graph after fixups have been applied"),
121 cl::init(false));
122
123 static cl::opt<bool> ShowSizes(
124 "show-sizes",
125 cl::desc("Show sizes pre- and post-dead stripping, and allocations"),
126 cl::init(false));
127
128 static cl::opt<bool> ShowTimes("show-times",
129 cl::desc("Show times for llvm-jitlink phases"),
130 cl::init(false));
131
132 static cl::opt<std::string> SlabAllocateSizeString(
133 "slab-allocate",
134 cl::desc("Allocate from a slab of the given size "
135 "(allowable suffixes: Kb, Mb, Gb. default = "
136 "Kb)"),
137 cl::init(""));
138
139 static cl::opt<uint64_t> SlabAddress(
140 "slab-address",
141 cl::desc("Set slab target address (requires -slab-allocate and -noexec)"),
142 cl::init(~0ULL));
143
144 static cl::opt<bool> ShowRelocatedSectionContents(
145 "show-relocated-section-contents",
146 cl::desc("show section contents after fixups have been applied"),
147 cl::init(false));
148
149 static cl::opt<bool> PhonyExternals(
150 "phony-externals",
151 cl::desc("resolve all otherwise unresolved externals to null"),
152 cl::init(false));
153
154 static cl::opt<std::string> OutOfProcessExecutor(
155 "oop-executor", cl::desc("Launch an out-of-process executor to run code"),
156 cl::ValueOptional);
157
158 static cl::opt<std::string> OutOfProcessExecutorConnect(
159 "oop-executor-connect",
160 cl::desc("Connect to an out-of-process executor via TCP"));
161
162 ExitOnError ExitOnErr;
163
linkComponents()164 LLVM_ATTRIBUTE_USED void linkComponents() {
165 errs() << (void *)&llvm_orc_registerEHFrameSectionWrapper
166 << (void *)&llvm_orc_deregisterEHFrameSectionWrapper
167 << (void *)&llvm_orc_registerJITLoaderGDBWrapper;
168 }
169
170 namespace llvm {
171
172 static raw_ostream &
operator <<(raw_ostream & OS,const Session::MemoryRegionInfo & MRI)173 operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) {
174 return OS << "target addr = "
175 << format("0x%016" PRIx64, MRI.getTargetAddress())
176 << ", content: " << (const void *)MRI.getContent().data() << " -- "
177 << (const void *)(MRI.getContent().data() + MRI.getContent().size())
178 << " (" << MRI.getContent().size() << " bytes)";
179 }
180
181 static raw_ostream &
operator <<(raw_ostream & OS,const Session::SymbolInfoMap & SIM)182 operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) {
183 OS << "Symbols:\n";
184 for (auto &SKV : SIM)
185 OS << " \"" << SKV.first() << "\" " << SKV.second << "\n";
186 return OS;
187 }
188
189 static raw_ostream &
operator <<(raw_ostream & OS,const Session::FileInfo & FI)190 operator<<(raw_ostream &OS, const Session::FileInfo &FI) {
191 for (auto &SIKV : FI.SectionInfos)
192 OS << " Section \"" << SIKV.first() << "\": " << SIKV.second << "\n";
193 for (auto &GOTKV : FI.GOTEntryInfos)
194 OS << " GOT \"" << GOTKV.first() << "\": " << GOTKV.second << "\n";
195 for (auto &StubKV : FI.StubInfos)
196 OS << " Stub \"" << StubKV.first() << "\": " << StubKV.second << "\n";
197 return OS;
198 }
199
200 static raw_ostream &
operator <<(raw_ostream & OS,const Session::FileInfoMap & FIM)201 operator<<(raw_ostream &OS, const Session::FileInfoMap &FIM) {
202 for (auto &FIKV : FIM)
203 OS << "File \"" << FIKV.first() << "\":\n" << FIKV.second;
204 return OS;
205 }
206
applyHarnessPromotions(Session & S,LinkGraph & G)207 static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
208
209 // If this graph is part of the test harness there's nothing to do.
210 if (S.HarnessFiles.empty() || S.HarnessFiles.count(G.getName()))
211 return Error::success();
212
213 LLVM_DEBUG(dbgs() << "Appling promotions to graph " << G.getName() << "\n");
214
215 // If this graph is part of the test then promote any symbols referenced by
216 // the harness to default scope, remove all symbols that clash with harness
217 // definitions.
218 std::vector<Symbol *> DefinitionsToRemove;
219 for (auto *Sym : G.defined_symbols()) {
220
221 if (!Sym->hasName())
222 continue;
223
224 if (Sym->getLinkage() == Linkage::Weak) {
225 if (!S.CanonicalWeakDefs.count(Sym->getName()) ||
226 S.CanonicalWeakDefs[Sym->getName()] != G.getName()) {
227 LLVM_DEBUG({
228 dbgs() << " Externalizing weak symbol " << Sym->getName() << "\n";
229 });
230 DefinitionsToRemove.push_back(Sym);
231 } else {
232 LLVM_DEBUG({
233 dbgs() << " Making weak symbol " << Sym->getName() << " strong\n";
234 });
235 if (S.HarnessExternals.count(Sym->getName()))
236 Sym->setScope(Scope::Default);
237 else
238 Sym->setScope(Scope::Hidden);
239 Sym->setLinkage(Linkage::Strong);
240 }
241 } else if (S.HarnessExternals.count(Sym->getName())) {
242 LLVM_DEBUG(dbgs() << " Promoting " << Sym->getName() << "\n");
243 Sym->setScope(Scope::Default);
244 Sym->setLive(true);
245 continue;
246 } else if (S.HarnessDefinitions.count(Sym->getName())) {
247 LLVM_DEBUG(dbgs() << " Externalizing " << Sym->getName() << "\n");
248 DefinitionsToRemove.push_back(Sym);
249 }
250 }
251
252 for (auto *Sym : DefinitionsToRemove)
253 G.makeExternal(*Sym);
254
255 return Error::success();
256 }
257
computeTotalBlockSizes(LinkGraph & G)258 static uint64_t computeTotalBlockSizes(LinkGraph &G) {
259 uint64_t TotalSize = 0;
260 for (auto *B : G.blocks())
261 TotalSize += B->getSize();
262 return TotalSize;
263 }
264
dumpSectionContents(raw_ostream & OS,LinkGraph & G)265 static void dumpSectionContents(raw_ostream &OS, LinkGraph &G) {
266 constexpr JITTargetAddress DumpWidth = 16;
267 static_assert(isPowerOf2_64(DumpWidth), "DumpWidth must be a power of two");
268
269 // Put sections in address order.
270 std::vector<Section *> Sections;
271 for (auto &S : G.sections())
272 Sections.push_back(&S);
273
274 llvm::sort(Sections, [](const Section *LHS, const Section *RHS) {
275 if (llvm::empty(LHS->symbols()) && llvm::empty(RHS->symbols()))
276 return false;
277 if (llvm::empty(LHS->symbols()))
278 return false;
279 if (llvm::empty(RHS->symbols()))
280 return true;
281 SectionRange LHSRange(*LHS);
282 SectionRange RHSRange(*RHS);
283 return LHSRange.getStart() < RHSRange.getStart();
284 });
285
286 for (auto *S : Sections) {
287 OS << S->getName() << " content:";
288 if (llvm::empty(S->symbols())) {
289 OS << "\n section empty\n";
290 continue;
291 }
292
293 // Sort symbols into order, then render.
294 std::vector<Symbol *> Syms(S->symbols().begin(), S->symbols().end());
295 llvm::sort(Syms, [](const Symbol *LHS, const Symbol *RHS) {
296 return LHS->getAddress() < RHS->getAddress();
297 });
298
299 JITTargetAddress NextAddr = Syms.front()->getAddress() & ~(DumpWidth - 1);
300 for (auto *Sym : Syms) {
301 bool IsZeroFill = Sym->getBlock().isZeroFill();
302 JITTargetAddress SymStart = Sym->getAddress();
303 JITTargetAddress SymSize = Sym->getSize();
304 JITTargetAddress SymEnd = SymStart + SymSize;
305 const uint8_t *SymData = IsZeroFill ? nullptr
306 : reinterpret_cast<const uint8_t *>(
307 Sym->getSymbolContent().data());
308
309 // Pad any space before the symbol starts.
310 while (NextAddr != SymStart) {
311 if (NextAddr % DumpWidth == 0)
312 OS << formatv("\n{0:x16}:", NextAddr);
313 OS << " ";
314 ++NextAddr;
315 }
316
317 // Render the symbol content.
318 while (NextAddr != SymEnd) {
319 if (NextAddr % DumpWidth == 0)
320 OS << formatv("\n{0:x16}:", NextAddr);
321 if (IsZeroFill)
322 OS << " 00";
323 else
324 OS << formatv(" {0:x-2}", SymData[NextAddr - SymStart]);
325 ++NextAddr;
326 }
327 }
328 OS << "\n";
329 }
330 }
331
332 class JITLinkSlabAllocator final : public JITLinkMemoryManager {
333 public:
334 static Expected<std::unique_ptr<JITLinkSlabAllocator>>
Create(uint64_t SlabSize)335 Create(uint64_t SlabSize) {
336 Error Err = Error::success();
337 std::unique_ptr<JITLinkSlabAllocator> Allocator(
338 new JITLinkSlabAllocator(SlabSize, Err));
339 if (Err)
340 return std::move(Err);
341 return std::move(Allocator);
342 }
343
344 Expected<std::unique_ptr<JITLinkMemoryManager::Allocation>>
allocate(const JITLinkDylib * JD,const SegmentsRequestMap & Request)345 allocate(const JITLinkDylib *JD, const SegmentsRequestMap &Request) override {
346
347 using AllocationMap = DenseMap<unsigned, sys::MemoryBlock>;
348
349 // Local class for allocation.
350 class IPMMAlloc : public Allocation {
351 public:
352 IPMMAlloc(JITLinkSlabAllocator &Parent, AllocationMap SegBlocks)
353 : Parent(Parent), SegBlocks(std::move(SegBlocks)) {}
354 MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
355 assert(SegBlocks.count(Seg) && "No allocation for segment");
356 return {static_cast<char *>(SegBlocks[Seg].base()),
357 SegBlocks[Seg].allocatedSize()};
358 }
359 JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
360 assert(SegBlocks.count(Seg) && "No allocation for segment");
361 return pointerToJITTargetAddress(SegBlocks[Seg].base()) +
362 Parent.TargetDelta;
363 }
364 void finalizeAsync(FinalizeContinuation OnFinalize) override {
365 OnFinalize(applyProtections());
366 }
367 Error deallocate() override {
368 for (auto &KV : SegBlocks)
369 if (auto EC = sys::Memory::releaseMappedMemory(KV.second))
370 return errorCodeToError(EC);
371 return Error::success();
372 }
373
374 private:
375 Error applyProtections() {
376 for (auto &KV : SegBlocks) {
377 auto &Prot = KV.first;
378 auto &Block = KV.second;
379 if (auto EC = sys::Memory::protectMappedMemory(Block, Prot))
380 return errorCodeToError(EC);
381 if (Prot & sys::Memory::MF_EXEC)
382 sys::Memory::InvalidateInstructionCache(Block.base(),
383 Block.allocatedSize());
384 }
385 return Error::success();
386 }
387
388 JITLinkSlabAllocator &Parent;
389 AllocationMap SegBlocks;
390 };
391
392 AllocationMap Blocks;
393
394 for (auto &KV : Request) {
395 auto &Seg = KV.second;
396
397 if (Seg.getAlignment() > PageSize)
398 return make_error<StringError>("Cannot request higher than page "
399 "alignment",
400 inconvertibleErrorCode());
401
402 if (PageSize % Seg.getAlignment() != 0)
403 return make_error<StringError>("Page size is not a multiple of "
404 "alignment",
405 inconvertibleErrorCode());
406
407 uint64_t ZeroFillStart = Seg.getContentSize();
408 uint64_t SegmentSize = ZeroFillStart + Seg.getZeroFillSize();
409
410 // Round segment size up to page boundary.
411 SegmentSize = (SegmentSize + PageSize - 1) & ~(PageSize - 1);
412
413 // Take segment bytes from the front of the slab.
414 void *SlabBase = SlabRemaining.base();
415 uint64_t SlabRemainingSize = SlabRemaining.allocatedSize();
416
417 if (SegmentSize > SlabRemainingSize)
418 return make_error<StringError>("Slab allocator out of memory",
419 inconvertibleErrorCode());
420
421 sys::MemoryBlock SegMem(SlabBase, SegmentSize);
422 SlabRemaining =
423 sys::MemoryBlock(reinterpret_cast<char *>(SlabBase) + SegmentSize,
424 SlabRemainingSize - SegmentSize);
425
426 // Zero out the zero-fill memory.
427 memset(static_cast<char *>(SegMem.base()) + ZeroFillStart, 0,
428 Seg.getZeroFillSize());
429
430 // Record the block for this segment.
431 Blocks[KV.first] = std::move(SegMem);
432 }
433 return std::unique_ptr<InProcessMemoryManager::Allocation>(
434 new IPMMAlloc(*this, std::move(Blocks)));
435 }
436
437 private:
JITLinkSlabAllocator(uint64_t SlabSize,Error & Err)438 JITLinkSlabAllocator(uint64_t SlabSize, Error &Err) {
439 ErrorAsOutParameter _(&Err);
440
441 PageSize = sys::Process::getPageSizeEstimate();
442
443 if (!isPowerOf2_64(PageSize)) {
444 Err = make_error<StringError>("Page size is not a power of 2",
445 inconvertibleErrorCode());
446 return;
447 }
448
449 // Round slab request up to page size.
450 SlabSize = (SlabSize + PageSize - 1) & ~(PageSize - 1);
451
452 const sys::Memory::ProtectionFlags ReadWrite =
453 static_cast<sys::Memory::ProtectionFlags>(sys::Memory::MF_READ |
454 sys::Memory::MF_WRITE);
455
456 std::error_code EC;
457 SlabRemaining =
458 sys::Memory::allocateMappedMemory(SlabSize, nullptr, ReadWrite, EC);
459
460 if (EC) {
461 Err = errorCodeToError(EC);
462 return;
463 }
464
465 // Calculate the target address delta to link as-if slab were at
466 // SlabAddress.
467 if (SlabAddress != ~0ULL)
468 TargetDelta =
469 SlabAddress - pointerToJITTargetAddress(SlabRemaining.base());
470 }
471
472 sys::MemoryBlock SlabRemaining;
473 uint64_t PageSize = 0;
474 int64_t TargetDelta = 0;
475 };
476
getSlabAllocSize(StringRef SizeString)477 Expected<uint64_t> getSlabAllocSize(StringRef SizeString) {
478 SizeString = SizeString.trim();
479
480 uint64_t Units = 1024;
481
482 if (SizeString.endswith_lower("kb"))
483 SizeString = SizeString.drop_back(2).rtrim();
484 else if (SizeString.endswith_lower("mb")) {
485 Units = 1024 * 1024;
486 SizeString = SizeString.drop_back(2).rtrim();
487 } else if (SizeString.endswith_lower("gb")) {
488 Units = 1024 * 1024 * 1024;
489 SizeString = SizeString.drop_back(2).rtrim();
490 }
491
492 uint64_t SlabSize = 0;
493 if (SizeString.getAsInteger(10, SlabSize))
494 return make_error<StringError>("Invalid numeric format for slab size",
495 inconvertibleErrorCode());
496
497 return SlabSize * Units;
498 }
499
createMemoryManager()500 static std::unique_ptr<JITLinkMemoryManager> createMemoryManager() {
501 if (!SlabAllocateSizeString.empty()) {
502 auto SlabSize = ExitOnErr(getSlabAllocSize(SlabAllocateSizeString));
503 return ExitOnErr(JITLinkSlabAllocator::Create(SlabSize));
504 }
505 return std::make_unique<InProcessMemoryManager>();
506 }
507
LLVMJITLinkObjectLinkingLayer(Session & S,JITLinkMemoryManager & MemMgr)508 LLVMJITLinkObjectLinkingLayer::LLVMJITLinkObjectLinkingLayer(
509 Session &S, JITLinkMemoryManager &MemMgr)
510 : ObjectLinkingLayer(S.ES, MemMgr), S(S) {}
511
add(ResourceTrackerSP RT,std::unique_ptr<MemoryBuffer> O)512 Error LLVMJITLinkObjectLinkingLayer::add(ResourceTrackerSP RT,
513 std::unique_ptr<MemoryBuffer> O) {
514
515 if (S.HarnessFiles.empty() || S.HarnessFiles.count(O->getBufferIdentifier()))
516 return ObjectLinkingLayer::add(std::move(RT), std::move(O));
517
518 // Use getObjectSymbolInfo to compute the init symbol, but ignore
519 // the symbols field. We'll handle that manually to include promotion.
520 auto ObjSymInfo =
521 getObjectSymbolInfo(getExecutionSession(), O->getMemBufferRef());
522
523 if (!ObjSymInfo)
524 return ObjSymInfo.takeError();
525
526 auto &InitSymbol = ObjSymInfo->second;
527
528 // If creating an object file was going to fail it would have happened above,
529 // so we can 'cantFail' this.
530 auto Obj =
531 cantFail(object::ObjectFile::createObjectFile(O->getMemBufferRef()));
532
533 SymbolFlagsMap SymbolFlags;
534
535 // The init symbol must be included in the SymbolFlags map if present.
536 if (InitSymbol)
537 SymbolFlags[InitSymbol] = JITSymbolFlags::MaterializationSideEffectsOnly;
538
539 for (auto &Sym : Obj->symbols()) {
540 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
541 if (!SymFlagsOrErr)
542 // TODO: Test this error.
543 return SymFlagsOrErr.takeError();
544
545 // Skip symbols not defined in this object file.
546 if ((*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined))
547 continue;
548
549 auto Name = Sym.getName();
550 if (!Name)
551 return Name.takeError();
552
553 // Skip symbols that have type SF_File.
554 if (auto SymType = Sym.getType()) {
555 if (*SymType == object::SymbolRef::ST_File)
556 continue;
557 } else
558 return SymType.takeError();
559
560 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
561 if (!SymFlags)
562 return SymFlags.takeError();
563
564 if (SymFlags->isWeak()) {
565 // If this is a weak symbol that's not defined in the harness then we
566 // need to either mark it as strong (if this is the first definition
567 // that we've seen) or discard it.
568 if (S.HarnessDefinitions.count(*Name) || S.CanonicalWeakDefs.count(*Name))
569 continue;
570 S.CanonicalWeakDefs[*Name] = O->getBufferIdentifier();
571 *SymFlags &= ~JITSymbolFlags::Weak;
572 if (!S.HarnessExternals.count(*Name))
573 *SymFlags &= ~JITSymbolFlags::Exported;
574 } else if (S.HarnessExternals.count(*Name)) {
575 *SymFlags |= JITSymbolFlags::Exported;
576 } else if (S.HarnessDefinitions.count(*Name) ||
577 !(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
578 continue;
579
580 auto InternedName = S.ES.intern(*Name);
581 SymbolFlags[InternedName] = std::move(*SymFlags);
582 }
583
584 auto MU = std::make_unique<BasicObjectLayerMaterializationUnit>(
585 *this, std::move(O), std::move(SymbolFlags), std::move(InitSymbol));
586
587 auto &JD = RT->getJITDylib();
588 return JD.define(std::move(MU), std::move(RT));
589 }
590
591 Expected<std::unique_ptr<TargetProcessControl>>
LaunchExecutor()592 LLVMJITLinkRemoteTargetProcessControl::LaunchExecutor() {
593 #ifndef LLVM_ON_UNIX
594 // FIXME: Add support for Windows.
595 return make_error<StringError>("-" + OutOfProcessExecutor.ArgStr +
596 " not supported on non-unix platforms",
597 inconvertibleErrorCode());
598 #else
599
600 shared::registerStringError<LLVMJITLinkChannel>();
601
602 constexpr int ReadEnd = 0;
603 constexpr int WriteEnd = 1;
604
605 // Pipe FDs.
606 int ToExecutor[2];
607 int FromExecutor[2];
608
609 pid_t ChildPID;
610
611 // Create pipes to/from the executor..
612 if (pipe(ToExecutor) != 0 || pipe(FromExecutor) != 0)
613 return make_error<StringError>("Unable to create pipe for executor",
614 inconvertibleErrorCode());
615
616 ChildPID = fork();
617
618 if (ChildPID == 0) {
619 // In the child...
620
621 // Close the parent ends of the pipes
622 close(ToExecutor[WriteEnd]);
623 close(FromExecutor[ReadEnd]);
624
625 // Execute the child process.
626 std::unique_ptr<char[]> ExecutorPath, FDSpecifier;
627 {
628 ExecutorPath = std::make_unique<char[]>(OutOfProcessExecutor.size() + 1);
629 strcpy(ExecutorPath.get(), OutOfProcessExecutor.data());
630
631 std::string FDSpecifierStr("filedescs=");
632 FDSpecifierStr += utostr(ToExecutor[ReadEnd]);
633 FDSpecifierStr += ',';
634 FDSpecifierStr += utostr(FromExecutor[WriteEnd]);
635 FDSpecifier = std::make_unique<char[]>(FDSpecifierStr.size() + 1);
636 strcpy(FDSpecifier.get(), FDSpecifierStr.c_str());
637 }
638
639 char *const Args[] = {ExecutorPath.get(), FDSpecifier.get(), nullptr};
640 int RC = execvp(ExecutorPath.get(), Args);
641 if (RC != 0) {
642 errs() << "unable to launch out-of-process executor \""
643 << ExecutorPath.get() << "\"\n";
644 exit(1);
645 }
646 }
647 // else we're the parent...
648
649 // Close the child ends of the pipes
650 close(ToExecutor[ReadEnd]);
651 close(FromExecutor[WriteEnd]);
652
653 // Return an RPC channel connected to our end of the pipes.
654 auto SSP = std::make_shared<SymbolStringPool>();
655 auto Channel = std::make_unique<shared::FDRawByteChannel>(
656 FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
657 auto Endpoint = std::make_unique<LLVMJITLinkRPCEndpoint>(*Channel, true);
658
659 auto ReportError = [](Error Err) {
660 logAllUnhandledErrors(std::move(Err), errs(), "");
661 };
662
663 Error Err = Error::success();
664 std::unique_ptr<LLVMJITLinkRemoteTargetProcessControl> RTPC(
665 new LLVMJITLinkRemoteTargetProcessControl(
666 std::move(SSP), std::move(Channel), std::move(Endpoint),
667 std::move(ReportError), Err));
668 if (Err)
669 return std::move(Err);
670 return std::move(RTPC);
671 #endif
672 }
673
674 #ifdef LLVM_ON_UNIX
createTCPSocketError(Twine Details)675 static Error createTCPSocketError(Twine Details) {
676 return make_error<StringError>(
677 formatv("Failed to connect TCP socket '{0}': {1}",
678 OutOfProcessExecutorConnect, Details),
679 inconvertibleErrorCode());
680 }
681
connectTCPSocket(std::string Host,std::string PortStr)682 static Expected<int> connectTCPSocket(std::string Host, std::string PortStr) {
683 addrinfo *AI;
684 addrinfo Hints{};
685 Hints.ai_family = AF_INET;
686 Hints.ai_socktype = SOCK_STREAM;
687 Hints.ai_flags = AI_NUMERICSERV;
688
689 if (int EC = getaddrinfo(Host.c_str(), PortStr.c_str(), &Hints, &AI))
690 return createTCPSocketError("Address resolution failed (" +
691 StringRef(gai_strerror(EC)) + ")");
692
693 // Cycle through the returned addrinfo structures and connect to the first
694 // reachable endpoint.
695 int SockFD;
696 addrinfo *Server;
697 for (Server = AI; Server != nullptr; Server = Server->ai_next) {
698 // socket might fail, e.g. if the address family is not supported. Skip to
699 // the next addrinfo structure in such a case.
700 if ((SockFD = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0)
701 continue;
702
703 // If connect returns null, we exit the loop with a working socket.
704 if (connect(SockFD, Server->ai_addr, Server->ai_addrlen) == 0)
705 break;
706
707 close(SockFD);
708 }
709 freeaddrinfo(AI);
710
711 // If we reached the end of the loop without connecting to a valid endpoint,
712 // dump the last error that was logged in socket() or connect().
713 if (Server == nullptr)
714 return createTCPSocketError(std::strerror(errno));
715
716 return SockFD;
717 }
718 #endif
719
720 Expected<std::unique_ptr<TargetProcessControl>>
ConnectToExecutor()721 LLVMJITLinkRemoteTargetProcessControl::ConnectToExecutor() {
722 #ifndef LLVM_ON_UNIX
723 // FIXME: Add TCP support for Windows.
724 return make_error<StringError>("-" + OutOfProcessExecutorConnect.ArgStr +
725 " not supported on non-unix platforms",
726 inconvertibleErrorCode());
727 #else
728
729 shared::registerStringError<LLVMJITLinkChannel>();
730
731 StringRef Host, PortStr;
732 std::tie(Host, PortStr) = StringRef(OutOfProcessExecutorConnect).split(':');
733 if (Host.empty())
734 return createTCPSocketError("Host name for -" +
735 OutOfProcessExecutorConnect.ArgStr +
736 " can not be empty");
737 if (PortStr.empty())
738 return createTCPSocketError("Port number in -" +
739 OutOfProcessExecutorConnect.ArgStr +
740 " can not be empty");
741 int Port = 0;
742 if (PortStr.getAsInteger(10, Port))
743 return createTCPSocketError("Port number '" + PortStr +
744 "' is not a valid integer");
745
746 Expected<int> SockFD = connectTCPSocket(Host.str(), PortStr.str());
747 if (!SockFD)
748 return SockFD.takeError();
749
750 auto SSP = std::make_shared<SymbolStringPool>();
751 auto Channel = std::make_unique<shared::FDRawByteChannel>(*SockFD, *SockFD);
752 auto Endpoint = std::make_unique<LLVMJITLinkRPCEndpoint>(*Channel, true);
753
754 auto ReportError = [](Error Err) {
755 logAllUnhandledErrors(std::move(Err), errs(), "");
756 };
757
758 Error Err = Error::success();
759 std::unique_ptr<LLVMJITLinkRemoteTargetProcessControl> RTPC(
760 new LLVMJITLinkRemoteTargetProcessControl(
761 std::move(SSP), std::move(Channel), std::move(Endpoint),
762 std::move(ReportError), Err));
763 if (Err)
764 return std::move(Err);
765 return std::move(RTPC);
766 #endif
767 }
768
disconnect()769 Error LLVMJITLinkRemoteTargetProcessControl::disconnect() {
770 std::promise<MSVCPError> P;
771 auto F = P.get_future();
772 auto Err = closeConnection([&](Error Err) -> Error {
773 P.set_value(std::move(Err));
774 Finished = true;
775 return Error::success();
776 });
777 ListenerThread.join();
778 return joinErrors(std::move(Err), F.get());
779 }
780
781 class PhonyExternalsGenerator : public DefinitionGenerator {
782 public:
tryToGenerate(LookupState & LS,LookupKind K,JITDylib & JD,JITDylibLookupFlags JDLookupFlags,const SymbolLookupSet & LookupSet)783 Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
784 JITDylibLookupFlags JDLookupFlags,
785 const SymbolLookupSet &LookupSet) override {
786 SymbolMap PhonySymbols;
787 for (auto &KV : LookupSet)
788 PhonySymbols[KV.first] = JITEvaluatedSymbol(0, JITSymbolFlags::Exported);
789 return JD.define(absoluteSymbols(std::move(PhonySymbols)));
790 }
791 };
792
Create(Triple TT)793 Expected<std::unique_ptr<Session>> Session::Create(Triple TT) {
794
795 auto PageSize = sys::Process::getPageSize();
796 if (!PageSize)
797 return PageSize.takeError();
798
799 /// If -oop-executor is passed then launch the executor.
800 std::unique_ptr<TargetProcessControl> TPC;
801 if (OutOfProcessExecutor.getNumOccurrences()) {
802 if (auto RTPC = LLVMJITLinkRemoteTargetProcessControl::LaunchExecutor())
803 TPC = std::move(*RTPC);
804 else
805 return RTPC.takeError();
806 } else if (OutOfProcessExecutorConnect.getNumOccurrences()) {
807 if (auto RTPC = LLVMJITLinkRemoteTargetProcessControl::ConnectToExecutor())
808 TPC = std::move(*RTPC);
809 else
810 return RTPC.takeError();
811 } else
812 TPC = std::make_unique<SelfTargetProcessControl>(
813 std::make_shared<SymbolStringPool>(), std::move(TT), *PageSize,
814 createMemoryManager());
815
816 Error Err = Error::success();
817 std::unique_ptr<Session> S(new Session(std::move(TPC), Err));
818 if (Err)
819 return std::move(Err);
820 return std::move(S);
821 }
822
~Session()823 Session::~Session() {
824 if (auto Err = ES.endSession())
825 ES.reportError(std::move(Err));
826 }
827
828 // FIXME: Move to createJITDylib if/when we start using Platform support in
829 // llvm-jitlink.
Session(std::unique_ptr<TargetProcessControl> TPC,Error & Err)830 Session::Session(std::unique_ptr<TargetProcessControl> TPC, Error &Err)
831 : TPC(std::move(TPC)), ObjLayer(*this, this->TPC->getMemMgr()) {
832
833 /// Local ObjectLinkingLayer::Plugin class to forward modifyPassConfig to the
834 /// Session.
835 class JITLinkSessionPlugin : public ObjectLinkingLayer::Plugin {
836 public:
837 JITLinkSessionPlugin(Session &S) : S(S) {}
838 void modifyPassConfig(MaterializationResponsibility &MR, LinkGraph &G,
839 PassConfiguration &PassConfig) override {
840 S.modifyPassConfig(G.getTargetTriple(), PassConfig);
841 }
842
843 Error notifyFailed(MaterializationResponsibility &MR) override {
844 return Error::success();
845 }
846 Error notifyRemovingResources(ResourceKey K) override {
847 return Error::success();
848 }
849 void notifyTransferringResources(ResourceKey DstKey,
850 ResourceKey SrcKey) override {}
851
852 private:
853 Session &S;
854 };
855
856 ErrorAsOutParameter _(&Err);
857
858 if (auto MainJDOrErr = ES.createJITDylib("main"))
859 MainJD = &*MainJDOrErr;
860 else {
861 Err = MainJDOrErr.takeError();
862 return;
863 }
864
865 if (!NoExec && !this->TPC->getTargetTriple().isOSWindows()) {
866 ObjLayer.addPlugin(std::make_unique<EHFrameRegistrationPlugin>(
867 ES, ExitOnErr(TPCEHFrameRegistrar::Create(*this->TPC))));
868 ObjLayer.addPlugin(std::make_unique<DebugObjectManagerPlugin>(
869 ES, ExitOnErr(createJITLoaderGDBRegistrar(*this->TPC))));
870 }
871
872 ObjLayer.addPlugin(std::make_unique<JITLinkSessionPlugin>(*this));
873
874 // Process any harness files.
875 for (auto &HarnessFile : TestHarnesses) {
876 HarnessFiles.insert(HarnessFile);
877
878 auto ObjBuffer =
879 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(HarnessFile)));
880
881 auto ObjSymbolInfo =
882 ExitOnErr(getObjectSymbolInfo(ES, ObjBuffer->getMemBufferRef()));
883
884 for (auto &KV : ObjSymbolInfo.first)
885 HarnessDefinitions.insert(*KV.first);
886
887 auto Obj = ExitOnErr(
888 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()));
889
890 for (auto &Sym : Obj->symbols()) {
891 uint32_t SymFlags = ExitOnErr(Sym.getFlags());
892 auto Name = ExitOnErr(Sym.getName());
893
894 if (Name.empty())
895 continue;
896
897 if (SymFlags & object::BasicSymbolRef::SF_Undefined)
898 HarnessExternals.insert(Name);
899 }
900 }
901
902 // If a name is defined by some harness file then it's a definition, not an
903 // external.
904 for (auto &DefName : HarnessDefinitions)
905 HarnessExternals.erase(DefName.getKey());
906 }
907
dumpSessionInfo(raw_ostream & OS)908 void Session::dumpSessionInfo(raw_ostream &OS) {
909 OS << "Registered addresses:\n" << SymbolInfos << FileInfos;
910 }
911
modifyPassConfig(const Triple & TT,PassConfiguration & PassConfig)912 void Session::modifyPassConfig(const Triple &TT,
913 PassConfiguration &PassConfig) {
914 if (!CheckFiles.empty())
915 PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) {
916 if (TPC->getTargetTriple().getObjectFormat() == Triple::ELF)
917 return registerELFGraphInfo(*this, G);
918
919 if (TPC->getTargetTriple().getObjectFormat() == Triple::MachO)
920 return registerMachOGraphInfo(*this, G);
921
922 return make_error<StringError>("Unsupported object format for GOT/stub "
923 "registration",
924 inconvertibleErrorCode());
925 });
926
927 if (ShowLinkGraph)
928 PassConfig.PostFixupPasses.push_back([](LinkGraph &G) -> Error {
929 outs() << "Link graph \"" << G.getName() << "\" post-fixup:\n";
930 G.dump(outs());
931 return Error::success();
932 });
933
934 PassConfig.PrePrunePasses.push_back(
935 [this](LinkGraph &G) { return applyHarnessPromotions(*this, G); });
936
937 if (ShowSizes) {
938 PassConfig.PrePrunePasses.push_back([this](LinkGraph &G) -> Error {
939 SizeBeforePruning += computeTotalBlockSizes(G);
940 return Error::success();
941 });
942 PassConfig.PostFixupPasses.push_back([this](LinkGraph &G) -> Error {
943 SizeAfterFixups += computeTotalBlockSizes(G);
944 return Error::success();
945 });
946 }
947
948 if (ShowRelocatedSectionContents)
949 PassConfig.PostFixupPasses.push_back([](LinkGraph &G) -> Error {
950 outs() << "Relocated section contents for " << G.getName() << ":\n";
951 dumpSectionContents(outs(), G);
952 return Error::success();
953 });
954 }
955
findFileInfo(StringRef FileName)956 Expected<Session::FileInfo &> Session::findFileInfo(StringRef FileName) {
957 auto FileInfoItr = FileInfos.find(FileName);
958 if (FileInfoItr == FileInfos.end())
959 return make_error<StringError>("file \"" + FileName + "\" not recognized",
960 inconvertibleErrorCode());
961 return FileInfoItr->second;
962 }
963
964 Expected<Session::MemoryRegionInfo &>
findSectionInfo(StringRef FileName,StringRef SectionName)965 Session::findSectionInfo(StringRef FileName, StringRef SectionName) {
966 auto FI = findFileInfo(FileName);
967 if (!FI)
968 return FI.takeError();
969 auto SecInfoItr = FI->SectionInfos.find(SectionName);
970 if (SecInfoItr == FI->SectionInfos.end())
971 return make_error<StringError>("no section \"" + SectionName +
972 "\" registered for file \"" + FileName +
973 "\"",
974 inconvertibleErrorCode());
975 return SecInfoItr->second;
976 }
977
978 Expected<Session::MemoryRegionInfo &>
findStubInfo(StringRef FileName,StringRef TargetName)979 Session::findStubInfo(StringRef FileName, StringRef TargetName) {
980 auto FI = findFileInfo(FileName);
981 if (!FI)
982 return FI.takeError();
983 auto StubInfoItr = FI->StubInfos.find(TargetName);
984 if (StubInfoItr == FI->StubInfos.end())
985 return make_error<StringError>("no stub for \"" + TargetName +
986 "\" registered for file \"" + FileName +
987 "\"",
988 inconvertibleErrorCode());
989 return StubInfoItr->second;
990 }
991
992 Expected<Session::MemoryRegionInfo &>
findGOTEntryInfo(StringRef FileName,StringRef TargetName)993 Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) {
994 auto FI = findFileInfo(FileName);
995 if (!FI)
996 return FI.takeError();
997 auto GOTInfoItr = FI->GOTEntryInfos.find(TargetName);
998 if (GOTInfoItr == FI->GOTEntryInfos.end())
999 return make_error<StringError>("no GOT entry for \"" + TargetName +
1000 "\" registered for file \"" + FileName +
1001 "\"",
1002 inconvertibleErrorCode());
1003 return GOTInfoItr->second;
1004 }
1005
isSymbolRegistered(StringRef SymbolName)1006 bool Session::isSymbolRegistered(StringRef SymbolName) {
1007 return SymbolInfos.count(SymbolName);
1008 }
1009
1010 Expected<Session::MemoryRegionInfo &>
findSymbolInfo(StringRef SymbolName,Twine ErrorMsgStem)1011 Session::findSymbolInfo(StringRef SymbolName, Twine ErrorMsgStem) {
1012 auto SymInfoItr = SymbolInfos.find(SymbolName);
1013 if (SymInfoItr == SymbolInfos.end())
1014 return make_error<StringError>(ErrorMsgStem + ": symbol " + SymbolName +
1015 " not found",
1016 inconvertibleErrorCode());
1017 return SymInfoItr->second;
1018 }
1019
1020 } // end namespace llvm
1021
getFirstFileTriple()1022 static Triple getFirstFileTriple() {
1023 static Triple FirstTT = []() {
1024 assert(!InputFiles.empty() && "InputFiles can not be empty");
1025 for (auto InputFile : InputFiles) {
1026 auto ObjBuffer =
1027 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(InputFile)));
1028 switch (identify_magic(ObjBuffer->getBuffer())) {
1029 case file_magic::elf_relocatable:
1030 case file_magic::macho_object:
1031 case file_magic::coff_object: {
1032 auto Obj = ExitOnErr(
1033 object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef()));
1034 return Obj->makeTriple();
1035 }
1036 default:
1037 break;
1038 }
1039 }
1040 return Triple();
1041 }();
1042
1043 return FirstTT;
1044 }
1045
sanitizeArguments(const Triple & TT,const char * ArgV0)1046 static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {
1047 // Set the entry point name if not specified.
1048 if (EntryPointName.empty()) {
1049 if (TT.getObjectFormat() == Triple::MachO)
1050 EntryPointName = "_main";
1051 else
1052 EntryPointName = "main";
1053 }
1054
1055 // -noexec and --args should not be used together.
1056 if (NoExec && !InputArgv.empty())
1057 outs() << "Warning: --args passed to -noexec run will be ignored.\n";
1058
1059 // If -slab-address is passed, require -slab-allocate and -noexec
1060 if (SlabAddress != ~0ULL) {
1061 if (SlabAllocateSizeString == "" || !NoExec)
1062 return make_error<StringError>(
1063 "-slab-address requires -slab-allocate and -noexec",
1064 inconvertibleErrorCode());
1065 }
1066
1067 // Only one of -oop-executor and -oop-executor-connect can be used.
1068 if (!!OutOfProcessExecutor.getNumOccurrences() &&
1069 !!OutOfProcessExecutorConnect.getNumOccurrences())
1070 return make_error<StringError>(
1071 "Only one of -" + OutOfProcessExecutor.ArgStr + " and -" +
1072 OutOfProcessExecutorConnect.ArgStr + " can be specified",
1073 inconvertibleErrorCode());
1074
1075 // If -oop-executor was used but no value was specified then use a sensible
1076 // default.
1077 if (!!OutOfProcessExecutor.getNumOccurrences() &&
1078 OutOfProcessExecutor.empty()) {
1079 SmallString<256> OOPExecutorPath(sys::fs::getMainExecutable(
1080 ArgV0, reinterpret_cast<void *>(&sanitizeArguments)));
1081 sys::path::remove_filename(OOPExecutorPath);
1082 if (OOPExecutorPath.back() != '/')
1083 OOPExecutorPath += '/';
1084 OOPExecutorPath += "llvm-jitlink-executor";
1085 OutOfProcessExecutor = OOPExecutorPath.str().str();
1086 }
1087
1088 return Error::success();
1089 }
1090
loadProcessSymbols(Session & S)1091 static Error loadProcessSymbols(Session &S) {
1092 auto FilterMainEntryPoint =
1093 [EPName = S.ES.intern(EntryPointName)](SymbolStringPtr Name) {
1094 return Name != EPName;
1095 };
1096 S.MainJD->addGenerator(
1097 ExitOnErr(orc::TPCDynamicLibrarySearchGenerator::GetForTargetProcess(
1098 *S.TPC, std::move(FilterMainEntryPoint))));
1099
1100 return Error::success();
1101 }
1102
loadDylibs(Session & S)1103 static Error loadDylibs(Session &S) {
1104 for (const auto &Dylib : Dylibs) {
1105 auto G = orc::TPCDynamicLibrarySearchGenerator::Load(*S.TPC, Dylib.c_str());
1106 if (!G)
1107 return G.takeError();
1108 S.MainJD->addGenerator(std::move(*G));
1109 }
1110
1111 return Error::success();
1112 }
1113
addPhonyExternalsGenerator(Session & S)1114 static void addPhonyExternalsGenerator(Session &S) {
1115 S.MainJD->addGenerator(std::make_unique<PhonyExternalsGenerator>());
1116 }
1117
loadObjects(Session & S)1118 static Error loadObjects(Session &S) {
1119 std::map<unsigned, JITDylib *> IdxToJLD;
1120
1121 // First, set up JITDylibs.
1122 LLVM_DEBUG(dbgs() << "Creating JITDylibs...\n");
1123 {
1124 // Create a "main" JITLinkDylib.
1125 IdxToJLD[0] = S.MainJD;
1126 S.JDSearchOrder.push_back(S.MainJD);
1127 LLVM_DEBUG(dbgs() << " 0: " << S.MainJD->getName() << "\n");
1128
1129 // Add any extra JITLinkDylibs from the command line.
1130 std::string JDNamePrefix("lib");
1131 for (auto JLDItr = JITLinkDylibs.begin(), JLDEnd = JITLinkDylibs.end();
1132 JLDItr != JLDEnd; ++JLDItr) {
1133 auto JD = S.ES.createJITDylib(JDNamePrefix + *JLDItr);
1134 if (!JD)
1135 return JD.takeError();
1136 unsigned JDIdx =
1137 JITLinkDylibs.getPosition(JLDItr - JITLinkDylibs.begin());
1138 IdxToJLD[JDIdx] = &*JD;
1139 S.JDSearchOrder.push_back(&*JD);
1140 LLVM_DEBUG(dbgs() << " " << JDIdx << ": " << JD->getName() << "\n");
1141 }
1142
1143 // Set every dylib to link against every other, in command line order.
1144 for (auto *JD : S.JDSearchOrder) {
1145 auto LookupFlags = JITDylibLookupFlags::MatchExportedSymbolsOnly;
1146 JITDylibSearchOrder LinkOrder;
1147 for (auto *JD2 : S.JDSearchOrder) {
1148 if (JD2 == JD)
1149 continue;
1150 LinkOrder.push_back(std::make_pair(JD2, LookupFlags));
1151 }
1152 JD->setLinkOrder(std::move(LinkOrder));
1153 }
1154 }
1155
1156 LLVM_DEBUG(dbgs() << "Adding test harness objects...\n");
1157 for (auto HarnessFile : TestHarnesses) {
1158 LLVM_DEBUG(dbgs() << " " << HarnessFile << "\n");
1159 auto ObjBuffer =
1160 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(HarnessFile)));
1161 ExitOnErr(S.ObjLayer.add(*S.MainJD, std::move(ObjBuffer)));
1162 }
1163
1164 // Load each object into the corresponding JITDylib..
1165 LLVM_DEBUG(dbgs() << "Adding objects...\n");
1166 for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();
1167 InputFileItr != InputFileEnd; ++InputFileItr) {
1168 unsigned InputFileArgIdx =
1169 InputFiles.getPosition(InputFileItr - InputFiles.begin());
1170 const std::string &InputFile = *InputFileItr;
1171 auto &JD = *std::prev(IdxToJLD.lower_bound(InputFileArgIdx))->second;
1172 LLVM_DEBUG(dbgs() << " " << InputFileArgIdx << ": \"" << InputFile
1173 << "\" to " << JD.getName() << "\n";);
1174 auto ObjBuffer =
1175 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(InputFile)));
1176
1177 auto Magic = identify_magic(ObjBuffer->getBuffer());
1178 if (Magic == file_magic::archive ||
1179 Magic == file_magic::macho_universal_binary)
1180 JD.addGenerator(ExitOnErr(StaticLibraryDefinitionGenerator::Load(
1181 S.ObjLayer, InputFile.c_str(), S.TPC->getTargetTriple())));
1182 else
1183 ExitOnErr(S.ObjLayer.add(JD, std::move(ObjBuffer)));
1184 }
1185
1186 // Define absolute symbols.
1187 LLVM_DEBUG(dbgs() << "Defining absolute symbols...\n");
1188 for (auto AbsDefItr = AbsoluteDefs.begin(), AbsDefEnd = AbsoluteDefs.end();
1189 AbsDefItr != AbsDefEnd; ++AbsDefItr) {
1190 unsigned AbsDefArgIdx =
1191 AbsoluteDefs.getPosition(AbsDefItr - AbsoluteDefs.begin());
1192 auto &JD = *std::prev(IdxToJLD.lower_bound(AbsDefArgIdx))->second;
1193
1194 StringRef AbsDefStmt = *AbsDefItr;
1195 size_t EqIdx = AbsDefStmt.find_first_of('=');
1196 if (EqIdx == StringRef::npos)
1197 return make_error<StringError>("Invalid absolute define \"" + AbsDefStmt +
1198 "\". Syntax: <name>=<addr>",
1199 inconvertibleErrorCode());
1200 StringRef Name = AbsDefStmt.substr(0, EqIdx).trim();
1201 StringRef AddrStr = AbsDefStmt.substr(EqIdx + 1).trim();
1202
1203 uint64_t Addr;
1204 if (AddrStr.getAsInteger(0, Addr))
1205 return make_error<StringError>("Invalid address expression \"" + AddrStr +
1206 "\" in absolute define \"" + AbsDefStmt +
1207 "\"",
1208 inconvertibleErrorCode());
1209 JITEvaluatedSymbol AbsDef(Addr, JITSymbolFlags::Exported);
1210 if (auto Err = JD.define(absoluteSymbols({{S.ES.intern(Name), AbsDef}})))
1211 return Err;
1212
1213 // Register the absolute symbol with the session symbol infos.
1214 S.SymbolInfos[Name] = {ArrayRef<char>(), Addr};
1215 }
1216
1217 LLVM_DEBUG({
1218 dbgs() << "Dylib search order is [ ";
1219 for (auto *JD : S.JDSearchOrder)
1220 dbgs() << JD->getName() << " ";
1221 dbgs() << "]\n";
1222 });
1223
1224 return Error::success();
1225 }
1226
runChecks(Session & S)1227 static Error runChecks(Session &S) {
1228
1229 auto TripleName = S.TPC->getTargetTriple().str();
1230 std::string ErrorStr;
1231 const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, ErrorStr);
1232 if (!TheTarget)
1233 ExitOnErr(make_error<StringError>("Error accessing target '" + TripleName +
1234 "': " + ErrorStr,
1235 inconvertibleErrorCode()));
1236
1237 std::unique_ptr<MCSubtargetInfo> STI(
1238 TheTarget->createMCSubtargetInfo(TripleName, "", ""));
1239 if (!STI)
1240 ExitOnErr(
1241 make_error<StringError>("Unable to create subtarget for " + TripleName,
1242 inconvertibleErrorCode()));
1243
1244 std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
1245 if (!MRI)
1246 ExitOnErr(make_error<StringError>("Unable to create target register info "
1247 "for " +
1248 TripleName,
1249 inconvertibleErrorCode()));
1250
1251 MCTargetOptions MCOptions;
1252 std::unique_ptr<MCAsmInfo> MAI(
1253 TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
1254 if (!MAI)
1255 ExitOnErr(make_error<StringError>("Unable to create target asm info " +
1256 TripleName,
1257 inconvertibleErrorCode()));
1258
1259 MCContext Ctx(Triple(TripleName), MAI.get(), MRI.get(), STI.get());
1260
1261 std::unique_ptr<MCDisassembler> Disassembler(
1262 TheTarget->createMCDisassembler(*STI, Ctx));
1263 if (!Disassembler)
1264 ExitOnErr(make_error<StringError>("Unable to create disassembler for " +
1265 TripleName,
1266 inconvertibleErrorCode()));
1267
1268 std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
1269
1270 std::unique_ptr<MCInstPrinter> InstPrinter(
1271 TheTarget->createMCInstPrinter(Triple(TripleName), 0, *MAI, *MII, *MRI));
1272
1273 auto IsSymbolValid = [&S](StringRef Symbol) {
1274 return S.isSymbolRegistered(Symbol);
1275 };
1276
1277 auto GetSymbolInfo = [&S](StringRef Symbol) {
1278 return S.findSymbolInfo(Symbol, "Can not get symbol info");
1279 };
1280
1281 auto GetSectionInfo = [&S](StringRef FileName, StringRef SectionName) {
1282 return S.findSectionInfo(FileName, SectionName);
1283 };
1284
1285 auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName) {
1286 return S.findStubInfo(FileName, SectionName);
1287 };
1288
1289 auto GetGOTInfo = [&S](StringRef FileName, StringRef SectionName) {
1290 return S.findGOTEntryInfo(FileName, SectionName);
1291 };
1292
1293 RuntimeDyldChecker Checker(
1294 IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo,
1295 S.TPC->getTargetTriple().isLittleEndian() ? support::little
1296 : support::big,
1297 Disassembler.get(), InstPrinter.get(), dbgs());
1298
1299 std::string CheckLineStart = "# " + CheckName + ":";
1300 for (auto &CheckFile : CheckFiles) {
1301 auto CheckerFileBuf =
1302 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(CheckFile)));
1303 if (!Checker.checkAllRulesInBuffer(CheckLineStart, &*CheckerFileBuf))
1304 ExitOnErr(make_error<StringError>(
1305 "Some checks in " + CheckFile + " failed", inconvertibleErrorCode()));
1306 }
1307
1308 return Error::success();
1309 }
1310
dumpSessionStats(Session & S)1311 static void dumpSessionStats(Session &S) {
1312 if (ShowSizes)
1313 outs() << "Total size of all blocks before pruning: " << S.SizeBeforePruning
1314 << "\nTotal size of all blocks after fixups: " << S.SizeAfterFixups
1315 << "\n";
1316 }
1317
getMainEntryPoint(Session & S)1318 static Expected<JITEvaluatedSymbol> getMainEntryPoint(Session &S) {
1319 return S.ES.lookup(S.JDSearchOrder, EntryPointName);
1320 }
1321
1322 namespace {
1323 struct JITLinkTimers {
1324 TimerGroup JITLinkTG{"llvm-jitlink timers", "timers for llvm-jitlink phases"};
1325 Timer LoadObjectsTimer{"load", "time to load/add object files", JITLinkTG};
1326 Timer LinkTimer{"link", "time to link object files", JITLinkTG};
1327 Timer RunTimer{"run", "time to execute jitlink'd code", JITLinkTG};
1328 };
1329 } // namespace
1330
main(int argc,char * argv[])1331 int main(int argc, char *argv[]) {
1332 InitLLVM X(argc, argv);
1333
1334 InitializeAllTargetInfos();
1335 InitializeAllTargetMCs();
1336 InitializeAllDisassemblers();
1337
1338 cl::ParseCommandLineOptions(argc, argv, "llvm jitlink tool");
1339 ExitOnErr.setBanner(std::string(argv[0]) + ": ");
1340
1341 /// If timers are enabled, create a JITLinkTimers instance.
1342 std::unique_ptr<JITLinkTimers> Timers =
1343 ShowTimes ? std::make_unique<JITLinkTimers>() : nullptr;
1344
1345 ExitOnErr(sanitizeArguments(getFirstFileTriple(), argv[0]));
1346
1347 auto S = ExitOnErr(Session::Create(getFirstFileTriple()));
1348
1349 {
1350 TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
1351 ExitOnErr(loadObjects(*S));
1352 }
1353
1354 if (!NoProcessSymbols)
1355 ExitOnErr(loadProcessSymbols(*S));
1356 ExitOnErr(loadDylibs(*S));
1357
1358 if (PhonyExternals)
1359 addPhonyExternalsGenerator(*S);
1360
1361
1362 if (ShowInitialExecutionSessionState)
1363 S->ES.dump(outs());
1364
1365 JITEvaluatedSymbol EntryPoint = 0;
1366 {
1367 TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr);
1368 EntryPoint = ExitOnErr(getMainEntryPoint(*S));
1369 }
1370
1371 if (ShowAddrs)
1372 S->dumpSessionInfo(outs());
1373
1374 ExitOnErr(runChecks(*S));
1375
1376 dumpSessionStats(*S);
1377
1378 if (NoExec)
1379 return 0;
1380
1381 int Result = 0;
1382 {
1383 TimeRegion TR(Timers ? &Timers->RunTimer : nullptr);
1384 Result = ExitOnErr(S->TPC->runAsMain(EntryPoint.getAddress(), InputArgv));
1385 }
1386
1387 ExitOnErr(S->ES.endSession());
1388 ExitOnErr(S->TPC->disconnect());
1389
1390 return Result;
1391 }
1392