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