xref: /netbsd-src/external/apache2/llvm/dist/llvm/tools/llvm-jitlink/llvm-jitlink.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
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