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#include "llvm/BinaryFormat/Magic.h"
17#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX, LLVM_ENABLE_THREADS
18#include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"
19#include "llvm/ExecutionEngine/Orc/BacktraceTools.h"
20#include "llvm/ExecutionEngine/Orc/COFFPlatform.h"
21#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"
22#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.h"
23#include "llvm/ExecutionEngine/Orc/Debugging/ELFDebugObjectPlugin.h"
24#include "llvm/ExecutionEngine/Orc/Debugging/PerfSupportPlugin.h"
25#include "llvm/ExecutionEngine/Orc/Debugging/VTuneSupportPlugin.h"
26#include "llvm/ExecutionEngine/Orc/EHFrameRegistrationPlugin.h"
27#include "llvm/ExecutionEngine/Orc/ELFNixPlatform.h"
28#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
29#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
30#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
31#include "llvm/ExecutionEngine/Orc/JITLinkRedirectableSymbolManager.h"
32#include "llvm/ExecutionEngine/Orc/JITLinkReentryTrampolines.h"
33#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
34#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h"
35#include "llvm/ExecutionEngine/Orc/MachO.h"
36#include "llvm/ExecutionEngine/Orc/MachOPlatform.h"
37#include "llvm/ExecutionEngine/Orc/MapperJITLinkMemoryManager.h"
38#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
39#include "llvm/ExecutionEngine/Orc/SectCreate.h"
40#include "llvm/ExecutionEngine/Orc/SelfExecutorProcessControl.h"
41#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
42#include "llvm/ExecutionEngine/Orc/SimpleRemoteMemoryMapper.h"
43#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
44#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderPerf.h"
45#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderVTune.h"
46#include "llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h"
47#include "llvm/ExecutionEngine/Orc/UnwindInfoRegistrationPlugin.h"
48#include "llvm/MC/MCAsmInfo.h"
49#include "llvm/MC/MCContext.h"
50#include "llvm/MC/MCDisassembler/MCDisassembler.h"
51#include "llvm/MC/MCInstPrinter.h"
52#include "llvm/MC/MCInstrAnalysis.h"
53#include "llvm/MC/MCInstrInfo.h"
54#include "llvm/MC/MCRegisterInfo.h"
55#include "llvm/MC/MCSubtargetInfo.h"
56#include "llvm/MC/MCTargetOptions.h"
57#include "llvm/MC/TargetRegistry.h"
58#include "llvm/Object/COFF.h"
59#include "llvm/Object/MachO.h"
60#include "llvm/Object/ObjectFile.h"
61#include "llvm/Object/TapiUniversal.h"
62#include "llvm/Support/CommandLine.h"
63#include "llvm/Support/Debug.h"
64#include "llvm/Support/InitLLVM.h"
65#include "llvm/Support/MemoryBuffer.h"
66#include "llvm/Support/Path.h"
67#include "llvm/Support/Process.h"
68#include "llvm/Support/TargetSelect.h"
69#include "llvm/Support/Timer.h"
70#include <chrono>
71#include <cstring>
72#include <deque>
73#include <string>
74
75#ifdef LLVM_ON_UNIX
76#include <netdb.h>
77#include <netinet/in.h>
78#include <sys/socket.h>
79#include <unistd.h>
80#endif // LLVM_ON_UNIX
81
82#define DEBUG_TYPE "llvm_jitlink"
83
84using namespace llvm;
85using namespace llvm::jitlink;
86using namespace llvm::orc;
87
88static cl::OptionCategory JITLinkCategory("JITLink Options");
89
90static cl::list<std::string> InputFiles(cl::Positional, cl::desc("input files"),
91 cl::cat(JITLinkCategory));
92
93static cl::list<bool> LazyLink("lazy",
94 cl::desc("Link the following file lazily"),
95 cl::cat(JITLinkCategory));
96
97enum class SpeculateKind { None, Simple };
98
99static cl::opt<SpeculateKind> Speculate(
100 "speculate", cl::desc("Choose speculation scheme"),
101 cl::init(Val: SpeculateKind::None),
102 cl::values(clEnumValN(SpeculateKind::None, "none", "No speculation"),
103 clEnumValN(SpeculateKind::Simple, "simple",
104 "Simple speculation")),
105 cl::cat(JITLinkCategory));
106
107static cl::opt<std::string> SpeculateOrder(
108 "speculate-order",
109 cl::desc("A CSV file containing (JITDylib, Function) pairs to"
110 "speculatively look up"),
111 cl::cat(JITLinkCategory));
112
113static cl::opt<std::string> RecordLazyExecs(
114 "record-lazy-execs",
115 cl::desc("Write lazy-function executions to a CSV file as (JITDylib, "
116 "function) pairs"),
117 cl::cat(JITLinkCategory));
118
119static cl::opt<size_t> MaterializationThreads(
120 "num-threads", cl::desc("Number of materialization threads to use"),
121 cl::init(Val: std::numeric_limits<size_t>::max()), cl::cat(JITLinkCategory));
122
123static cl::list<std::string>
124 LibrarySearchPaths("L",
125 cl::desc("Add dir to the list of library search paths"),
126 cl::Prefix, cl::cat(JITLinkCategory));
127
128static cl::list<std::string>
129 Libraries("l",
130 cl::desc("Link against library X in the library search paths"),
131 cl::Prefix, cl::cat(JITLinkCategory));
132
133static cl::list<std::string>
134 LibrariesHidden("hidden-l",
135 cl::desc("Link against library X in the library search "
136 "paths with hidden visibility"),
137 cl::Prefix, cl::cat(JITLinkCategory));
138
139static cl::list<std::string>
140 LoadHidden("load_hidden",
141 cl::desc("Link against library X with hidden visibility"),
142 cl::cat(JITLinkCategory));
143
144static cl::opt<std::string>
145 WriteSymbolTableTo("write-symtab",
146 cl::desc("Write the symbol table for the JIT'd program "
147 "to the specified file"),
148 cl::cat(JITLinkCategory));
149
150static cl::opt<std::string> SymbolicateWith(
151 "symbolicate-with",
152 cl::desc("Given a path to a symbol table file, symbolicate the given "
153 "backtrace(s)"),
154 cl::cat(JITLinkCategory));
155
156static cl::list<std::string>
157 LibrariesWeak("weak-l",
158 cl::desc("Emulate weak link against library X. Must resolve "
159 "to a TextAPI file, and all symbols in the "
160 "interface will resolve to null."),
161 cl::Prefix, cl::cat(JITLinkCategory));
162
163static cl::list<std::string> WeakLibraries(
164 "weak_library",
165 cl::desc("Emulate weak link against library X. X must point to a "
166 "TextAPI file, and all symbols in the interface will "
167 "resolve to null"),
168 cl::cat(JITLinkCategory));
169
170static cl::opt<bool> SearchSystemLibrary(
171 "search-sys-lib",
172 cl::desc("Add system library paths to library search paths"),
173 cl::init(Val: false), cl::cat(JITLinkCategory));
174
175static cl::opt<bool> NoExec("noexec", cl::desc("Do not execute loaded code"),
176 cl::init(Val: false), cl::cat(JITLinkCategory));
177
178static cl::list<std::string>
179 CheckFiles("check", cl::desc("File containing verifier checks"),
180 cl::cat(JITLinkCategory));
181
182static cl::opt<std::string>
183 CheckName("check-name", cl::desc("Name of checks to match against"),
184 cl::init(Val: "jitlink-check"), cl::cat(JITLinkCategory));
185
186static cl::opt<std::string>
187 EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
188 cl::init(Val: ""), cl::cat(JITLinkCategory));
189
190static cl::list<std::string> JITDylibs(
191 "jd",
192 cl::desc("Specifies the JITDylib to be used for any subsequent "
193 "input file, -L<seacrh-path>, and -l<library> arguments"),
194 cl::cat(JITLinkCategory));
195
196static cl::list<std::string>
197 Dylibs("preload",
198 cl::desc("Pre-load dynamic libraries (e.g. language runtimes "
199 "required by the ORC runtime)"),
200 cl::cat(JITLinkCategory));
201
202static cl::list<std::string> InputArgv("args", cl::Positional,
203 cl::desc("<program arguments>..."),
204 cl::PositionalEatsArgs,
205 cl::cat(JITLinkCategory));
206
207static cl::opt<bool>
208 DebuggerSupport("debugger-support",
209 cl::desc("Enable debugger suppport (default = !-noexec)"),
210 cl::init(Val: true), cl::Hidden, cl::cat(JITLinkCategory));
211
212static cl::opt<bool> PerfSupport("perf-support",
213 cl::desc("Enable perf profiling support"),
214 cl::init(Val: false), cl::Hidden,
215 cl::cat(JITLinkCategory));
216
217static cl::opt<bool> VTuneSupport("vtune-support",
218 cl::desc("Enable vtune profiling support"),
219 cl::init(Val: false), cl::Hidden,
220 cl::cat(JITLinkCategory));
221static cl::opt<bool>
222 NoProcessSymbols("no-process-syms",
223 cl::desc("Do not resolve to llvm-jitlink process symbols"),
224 cl::init(Val: false), cl::cat(JITLinkCategory));
225
226static cl::list<std::string> AbsoluteDefs(
227 "abs",
228 cl::desc("Inject absolute symbol definitions (syntax: <name>=<addr>)"),
229 cl::cat(JITLinkCategory));
230
231static cl::list<std::string>
232 Aliases("alias",
233 cl::desc("Inject symbol aliases (syntax: <alias-name>=<aliasee>)"),
234 cl::cat(JITLinkCategory));
235
236static cl::list<std::string>
237 SectCreate("sectcreate",
238 cl::desc("given <sectname>,<filename>[@<sym>=<offset>,...] "
239 "add the content of <filename> to <sectname>"),
240 cl::cat(JITLinkCategory));
241
242static cl::list<std::string> TestHarnesses("harness", cl::Positional,
243 cl::desc("Test harness files"),
244 cl::PositionalEatsArgs,
245 cl::cat(JITLinkCategory));
246
247static cl::opt<bool>
248 ShowLinkedFiles("show-linked-files",
249 cl::desc("List each file/graph name if/when it is linked"),
250 cl::init(Val: false), cl::cat(JITLinkCategory));
251
252static cl::opt<bool> ShowInitialExecutionSessionState(
253 "show-init-es",
254 cl::desc("Print ExecutionSession state before resolving entry point"),
255 cl::init(Val: false), cl::cat(JITLinkCategory));
256
257static cl::opt<bool> ShowEntryExecutionSessionState(
258 "show-entry-es",
259 cl::desc("Print ExecutionSession state after resolving entry point"),
260 cl::init(Val: false), cl::cat(JITLinkCategory));
261
262static cl::opt<bool> ShowAddrs(
263 "show-addrs",
264 cl::desc("Print registered symbol, section, got and stub addresses"),
265 cl::init(Val: false), cl::cat(JITLinkCategory));
266
267static cl::opt<std::string> ShowLinkGraphs(
268 "show-graphs",
269 cl::desc("Takes a posix regex and prints the link graphs of all files "
270 "matching that regex after fixups have been applied"),
271 cl::Optional, cl::cat(JITLinkCategory));
272
273static cl::opt<bool> ShowTimes("show-times",
274 cl::desc("Show times for llvm-jitlink phases"),
275 cl::init(Val: false), cl::cat(JITLinkCategory));
276
277static cl::opt<std::string> SlabAllocateSizeString(
278 "slab-allocate",
279 cl::desc("Allocate from a slab of the given size "
280 "(allowable suffixes: Kb, Mb, Gb. default = "
281 "Kb)"),
282 cl::init(Val: ""), cl::cat(JITLinkCategory));
283
284static cl::opt<uint64_t> SlabAddress(
285 "slab-address",
286 cl::desc("Set slab target address (requires -slab-allocate and -noexec)"),
287 cl::init(Val: ~0ULL), cl::cat(JITLinkCategory));
288
289static cl::opt<uint64_t> SlabPageSize(
290 "slab-page-size",
291 cl::desc("Set page size for slab (requires -slab-allocate and -noexec)"),
292 cl::init(Val: 0), cl::cat(JITLinkCategory));
293
294static cl::opt<bool> ShowRelocatedSectionContents(
295 "show-relocated-section-contents",
296 cl::desc("show section contents after fixups have been applied"),
297 cl::init(Val: false), cl::cat(JITLinkCategory));
298
299static cl::opt<bool> PhonyExternals(
300 "phony-externals",
301 cl::desc("resolve all otherwise unresolved externals to null"),
302 cl::init(Val: false), cl::cat(JITLinkCategory));
303
304static cl::opt<std::string> OutOfProcessExecutor(
305 "oop-executor", cl::desc("Launch an out-of-process executor to run code"),
306 cl::ValueOptional, cl::cat(JITLinkCategory));
307
308static cl::opt<std::string> OutOfProcessExecutorConnect(
309 "oop-executor-connect",
310 cl::desc("Connect to an out-of-process executor via TCP"),
311 cl::cat(JITLinkCategory));
312
313static cl::opt<std::string>
314 OrcRuntime("orc-runtime", cl::desc("Use ORC runtime from given path"),
315 cl::init(Val: ""), cl::cat(JITLinkCategory));
316
317static cl::opt<bool> AddSelfRelocations(
318 "add-self-relocations",
319 cl::desc("Add relocations to function pointers to the current function"),
320 cl::init(Val: false), cl::cat(JITLinkCategory));
321
322static cl::opt<bool>
323 ShowErrFailedToMaterialize("show-err-failed-to-materialize",
324 cl::desc("Show FailedToMaterialize errors"),
325 cl::init(Val: false), cl::cat(JITLinkCategory));
326
327enum class MemMgr { Default, Generic, SimpleRemote, Shared };
328
329static cl::opt<MemMgr> UseMemMgr(
330 "use-memmgr", cl::desc("Choose memory manager"), cl::init(Val: MemMgr::Generic),
331 cl::values(clEnumValN(MemMgr::Default, "default",
332 "Use setup default (InProcess or EPCGeneric)"),
333 clEnumValN(MemMgr::Generic, "generic",
334 "Generic remote memory manager"),
335 clEnumValN(MemMgr::SimpleRemote, "simple-remote",
336 "Mapper memory manager with simple-remote backend"),
337 clEnumValN(MemMgr::Shared, "shared",
338 "Mapper memory manager with shared-memory manager")),
339 cl::cat(JITLinkCategory));
340
341static cl::opt<std::string>
342 OverrideTriple("triple", cl::desc("Override target triple detection"),
343 cl::init(Val: ""), cl::cat(JITLinkCategory));
344
345static cl::opt<bool> AllLoad("all_load",
346 cl::desc("Load all members of static archives"),
347 cl::init(Val: false), cl::cat(JITLinkCategory));
348
349static cl::opt<bool> ForceLoadObjC(
350 "ObjC",
351 cl::desc("Load all members of static archives that implement "
352 "Objective-C classes or categories, or Swift structs, "
353 "classes or extensions"),
354 cl::init(Val: false), cl::cat(JITLinkCategory));
355
356static cl::opt<std::string> WaitingOnGraphCapture(
357 "waiting-on-graph-capture",
358 cl::desc("Record WaitingOnGraph operations to the given file"),
359 cl::init(Val: ""), cl::cat(JITLinkCategory));
360
361static cl::opt<std::string> WaitingOnGraphReplay(
362 "waiting-on-graph-replay",
363 cl::desc("Replay WaitingOnGraph operations from the given file"),
364 cl::init(Val: ""), cl::cat(JITLinkCategory));
365
366static ExitOnError ExitOnErr;
367
368static LLVM_ATTRIBUTE_USED void linkComponents() {
369 errs() << "Linking in runtime functions\n"
370 << (void *)&llvm_orc_registerEHFrameSectionAllocAction << '\n'
371 << (void *)&llvm_orc_deregisterEHFrameSectionAllocAction << '\n'
372 << (void *)&llvm_orc_registerJITLoaderGDBAllocAction << '\n'
373 << (void *)&llvm_orc_registerJITLoaderPerfStart << '\n'
374 << (void *)&llvm_orc_registerJITLoaderPerfEnd << '\n'
375 << (void *)&llvm_orc_registerJITLoaderPerfImpl << '\n'
376 << (void *)&llvm_orc_registerVTuneImpl << '\n'
377 << (void *)&llvm_orc_unregisterVTuneImpl << '\n'
378 << (void *)&llvm_orc_test_registerVTuneImpl << '\n';
379}
380
381static bool UseTestResultOverride = false;
382static int64_t TestResultOverride = 0;
383
384extern "C" LLVM_ATTRIBUTE_USED void
385llvm_jitlink_setTestResultOverride(int64_t Value) {
386 TestResultOverride = Value;
387 UseTestResultOverride = true;
388}
389
390static Error addSelfRelocations(LinkGraph &G);
391
392namespace {
393
394template <typename ErrT>
395
396class ConditionalPrintErr {
397public:
398 ConditionalPrintErr(bool C) : C(C) {}
399 void operator()(ErrT &EI) {
400 if (C) {
401 errs() << "llvm-jitlink error: ";
402 EI.log(errs());
403 errs() << "\n";
404 }
405 }
406
407private:
408 bool C;
409};
410
411Expected<std::unique_ptr<MemoryBuffer>> getFile(const Twine &FileName) {
412 if (auto F = MemoryBuffer::getFile(Filename: FileName))
413 return std::move(*F);
414 else
415 return createFileError(F: FileName, EC: F.getError());
416}
417
418void reportLLVMJITLinkError(Error Err) {
419 handleAllErrors(
420 E: std::move(Err),
421 Handlers: ConditionalPrintErr<orc::FailedToMaterialize>(ShowErrFailedToMaterialize),
422 Handlers: ConditionalPrintErr<ErrorInfoBase>(true));
423}
424
425} // end anonymous namespace
426
427namespace llvm {
428
429static raw_ostream &
430operator<<(raw_ostream &OS, const Session::MemoryRegionInfo &MRI) {
431 OS << "target addr = " << format(Fmt: "0x%016" PRIx64, Vals: MRI.getTargetAddress());
432
433 if (MRI.isZeroFill())
434 OS << ", zero-fill: " << MRI.getZeroFillLength() << " bytes";
435 else
436 OS << ", content: " << (const void *)MRI.getContent().data() << " -- "
437 << (const void *)(MRI.getContent().data() + MRI.getContent().size())
438 << " (" << MRI.getContent().size() << " bytes)";
439
440 return OS;
441}
442
443static raw_ostream &
444operator<<(raw_ostream &OS, const Session::SymbolInfoMap &SIM) {
445 OS << "Symbols:\n";
446 for (auto &SKV : SIM)
447 OS << " \"" << SKV.first << "\" " << SKV.second << "\n";
448 return OS;
449}
450
451static raw_ostream &
452operator<<(raw_ostream &OS, const Session::FileInfo &FI) {
453 for (auto &SIKV : FI.SectionInfos)
454 OS << " Section \"" << SIKV.first() << "\": " << SIKV.second << "\n";
455 for (auto &GOTKV : FI.GOTEntryInfos)
456 OS << " GOT \"" << GOTKV.first() << "\": " << GOTKV.second << "\n";
457 for (auto &StubKVs : FI.StubInfos) {
458 OS << " Stubs \"" << StubKVs.first() << "\":";
459 for (auto MemRegion : StubKVs.second)
460 OS << " " << MemRegion;
461 OS << "\n";
462 }
463 return OS;
464}
465
466static raw_ostream &
467operator<<(raw_ostream &OS, const Session::FileInfoMap &FIM) {
468 for (auto &FIKV : FIM)
469 OS << "File \"" << FIKV.first() << "\":\n" << FIKV.second;
470 return OS;
471}
472
473bool lazyLinkingRequested() {
474 for (auto LL : LazyLink)
475 if (LL)
476 return true;
477 return false;
478}
479
480static Error applyLibraryLinkModifiers(Session &S, LinkGraph &G) {
481 // If there are hidden archives and this graph is an archive
482 // member then apply hidden modifier.
483 if (!S.HiddenArchives.empty()) {
484 StringRef ObjName(G.getName());
485 if (ObjName.ends_with(Suffix: ')')) {
486 auto LibName = ObjName.split(Separator: '[').first;
487 if (S.HiddenArchives.count(Key: LibName)) {
488 for (auto *Sym : G.defined_symbols())
489 Sym->setScope(std::max(a: Sym->getScope(), b: Scope::Hidden));
490 }
491 }
492 }
493
494 return Error::success();
495}
496
497static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
498 std::lock_guard<std::mutex> Lock(S.M);
499
500 // If this graph is part of the test harness there's nothing to do.
501 if (S.HarnessFiles.empty() || S.HarnessFiles.count(Key: G.getName()))
502 return Error::success();
503
504 LLVM_DEBUG(dbgs() << "Applying promotions to graph " << G.getName() << "\n");
505
506 // If this graph is part of the test then promote any symbols referenced by
507 // the harness to default scope, remove all symbols that clash with harness
508 // definitions.
509 std::vector<Symbol *> DefinitionsToRemove;
510 for (auto *Sym : G.defined_symbols()) {
511
512 if (!Sym->hasName())
513 continue;
514
515 if (Sym->getLinkage() == Linkage::Weak) {
516 auto It = S.CanonicalWeakDefs.find(Val: *Sym->getName());
517 if (It == S.CanonicalWeakDefs.end() || It->second != G.getName()) {
518 LLVM_DEBUG({
519 dbgs() << " Externalizing weak symbol " << Sym->getName() << "\n";
520 });
521 DefinitionsToRemove.push_back(x: Sym);
522 } else {
523 LLVM_DEBUG({
524 dbgs() << " Making weak symbol " << Sym->getName() << " strong\n";
525 });
526 if (S.HarnessExternals.count(Key: *Sym->getName()))
527 Sym->setScope(Scope::Default);
528 else
529 Sym->setScope(Scope::Hidden);
530 Sym->setLinkage(Linkage::Strong);
531 }
532 } else if (S.HarnessExternals.count(Key: *Sym->getName())) {
533 LLVM_DEBUG(dbgs() << " Promoting " << Sym->getName() << "\n");
534 Sym->setScope(Scope::Default);
535 Sym->setLive(true);
536 continue;
537 } else if (S.HarnessDefinitions.count(Key: *Sym->getName())) {
538 LLVM_DEBUG(dbgs() << " Externalizing " << Sym->getName() << "\n");
539 DefinitionsToRemove.push_back(x: Sym);
540 }
541 }
542
543 for (auto *Sym : DefinitionsToRemove)
544 G.makeExternal(Sym&: *Sym);
545
546 return Error::success();
547}
548
549static void dumpSectionContents(raw_ostream &OS, Session &S, LinkGraph &G) {
550 std::lock_guard<std::mutex> Lock(S.M);
551
552 outs() << "Relocated section contents for " << G.getName() << ":\n";
553
554 constexpr orc::ExecutorAddrDiff DumpWidth = 16;
555 static_assert(isPowerOf2_64(Value: DumpWidth), "DumpWidth must be a power of two");
556
557 // Put sections in address order.
558 std::vector<Section *> Sections;
559 for (auto &S : G.sections())
560 Sections.push_back(x: &S);
561
562 llvm::sort(C&: Sections, Comp: [](const Section *LHS, const Section *RHS) {
563 if (LHS->symbols().empty() && RHS->symbols().empty())
564 return false;
565 if (LHS->symbols().empty())
566 return false;
567 if (RHS->symbols().empty())
568 return true;
569 SectionRange LHSRange(*LHS);
570 SectionRange RHSRange(*RHS);
571 return LHSRange.getStart() < RHSRange.getStart();
572 });
573
574 for (auto *S : Sections) {
575 OS << S->getName() << " content:";
576 if (S->symbols().empty()) {
577 OS << "\n section empty\n";
578 continue;
579 }
580
581 // Sort symbols into order, then render.
582 std::vector<Symbol *> Syms(S->symbols().begin(), S->symbols().end());
583 llvm::sort(C&: Syms, Comp: [](const Symbol *LHS, const Symbol *RHS) {
584 return LHS->getAddress() < RHS->getAddress();
585 });
586
587 orc::ExecutorAddr NextAddr(Syms.front()->getAddress().getValue() &
588 ~(DumpWidth - 1));
589 for (auto *Sym : Syms) {
590 bool IsZeroFill = Sym->getBlock().isZeroFill();
591 auto SymStart = Sym->getAddress();
592 auto SymSize = Sym->getSize();
593 auto SymEnd = SymStart + SymSize;
594 const uint8_t *SymData = IsZeroFill ? nullptr
595 : reinterpret_cast<const uint8_t *>(
596 Sym->getSymbolContent().data());
597
598 // Pad any space before the symbol starts.
599 while (NextAddr != SymStart) {
600 if (NextAddr % DumpWidth == 0)
601 OS << formatv(Fmt: "\n{0:x16}:", Vals&: NextAddr);
602 OS << " ";
603 ++NextAddr;
604 }
605
606 // Render the symbol content.
607 while (NextAddr != SymEnd) {
608 if (NextAddr % DumpWidth == 0)
609 OS << formatv(Fmt: "\n{0:x16}:", Vals&: NextAddr);
610 if (IsZeroFill)
611 OS << " 00";
612 else
613 OS << formatv(Fmt: " {0:x-2}", Vals: SymData[NextAddr - SymStart]);
614 ++NextAddr;
615 }
616 }
617 OS << "\n";
618 }
619}
620
621// A memory mapper with a fake offset applied only used for -noexec testing
622class InProcessDeltaMapper final : public InProcessMemoryMapper {
623public:
624 InProcessDeltaMapper(size_t PageSize, uint64_t TargetAddr)
625 : InProcessMemoryMapper(PageSize), TargetMapAddr(TargetAddr),
626 DeltaAddr(0) {}
627
628 static Expected<std::unique_ptr<InProcessDeltaMapper>> Create() {
629 size_t PageSize = SlabPageSize;
630 if (!PageSize) {
631 if (auto PageSizeOrErr = sys::Process::getPageSize())
632 PageSize = *PageSizeOrErr;
633 else
634 return PageSizeOrErr.takeError();
635 }
636
637 if (PageSize == 0)
638 return make_error<StringError>(Args: "Page size is zero",
639 Args: inconvertibleErrorCode());
640
641 return std::make_unique<InProcessDeltaMapper>(args&: PageSize, args&: SlabAddress);
642 }
643
644 void reserve(size_t NumBytes, OnReservedFunction OnReserved) override {
645 InProcessMemoryMapper::reserve(
646 NumBytes, OnReserved: [this, OnReserved = std::move(OnReserved)](
647 Expected<ExecutorAddrRange> Result) mutable {
648 if (!Result)
649 return OnReserved(Result.takeError());
650
651 assert(DeltaAddr == 0 && "Overwriting previous offset");
652 if (TargetMapAddr != ~0ULL)
653 DeltaAddr = TargetMapAddr - Result->Start.getValue();
654 auto OffsetRange = ExecutorAddrRange(Result->Start + DeltaAddr,
655 Result->End + DeltaAddr);
656
657 OnReserved(OffsetRange);
658 });
659 }
660
661 char *prepare(jitlink::LinkGraph &G, ExecutorAddr Addr,
662 size_t ContentSize) override {
663 return InProcessMemoryMapper::prepare(G, Addr: Addr - DeltaAddr, ContentSize);
664 }
665
666 void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override {
667 // Slide mapping based on delta, make all segments read-writable, and
668 // discard allocation actions.
669 auto FixedAI = std::move(AI);
670 FixedAI.MappingBase -= DeltaAddr;
671 for (auto &Seg : FixedAI.Segments)
672 Seg.AG = {MemProt::Read | MemProt::Write, Seg.AG.getMemLifetime()};
673 FixedAI.Actions.clear();
674 InProcessMemoryMapper::initialize(
675 AI&: FixedAI, OnInitialized: [this, OnInitialized = std::move(OnInitialized)](
676 Expected<ExecutorAddr> Result) mutable {
677 if (!Result)
678 return OnInitialized(Result.takeError());
679
680 OnInitialized(ExecutorAddr(Result->getValue() + DeltaAddr));
681 });
682 }
683
684 void deinitialize(ArrayRef<ExecutorAddr> Allocations,
685 OnDeinitializedFunction OnDeInitialized) override {
686 std::vector<ExecutorAddr> Addrs(Allocations.size());
687 for (const auto Base : Allocations) {
688 Addrs.push_back(x: Base - DeltaAddr);
689 }
690
691 InProcessMemoryMapper::deinitialize(Allocations: Addrs, OnDeInitialized: std::move(OnDeInitialized));
692 }
693
694 void release(ArrayRef<ExecutorAddr> Reservations,
695 OnReleasedFunction OnRelease) override {
696 std::vector<ExecutorAddr> Addrs(Reservations.size());
697 for (const auto Base : Reservations) {
698 Addrs.push_back(x: Base - DeltaAddr);
699 }
700 InProcessMemoryMapper::release(Reservations: Addrs, OnRelease: std::move(OnRelease));
701 }
702
703private:
704 uint64_t TargetMapAddr;
705 uint64_t DeltaAddr;
706};
707
708Expected<uint64_t> getSlabAllocSize(StringRef SizeString) {
709 SizeString = SizeString.trim();
710
711 uint64_t Units = 1024;
712
713 if (SizeString.ends_with_insensitive(Suffix: "kb"))
714 SizeString = SizeString.drop_back(N: 2).rtrim();
715 else if (SizeString.ends_with_insensitive(Suffix: "mb")) {
716 Units = 1024 * 1024;
717 SizeString = SizeString.drop_back(N: 2).rtrim();
718 } else if (SizeString.ends_with_insensitive(Suffix: "gb")) {
719 Units = 1024 * 1024 * 1024;
720 SizeString = SizeString.drop_back(N: 2).rtrim();
721 }
722
723 uint64_t SlabSize = 0;
724 if (SizeString.getAsInteger(Radix: 10, Result&: SlabSize))
725 return make_error<StringError>(Args: "Invalid numeric format for slab size",
726 Args: inconvertibleErrorCode());
727
728 return SlabSize * Units;
729}
730
731static std::unique_ptr<JITLinkMemoryManager> createInProcessMemoryManager() {
732 uint64_t SlabSize;
733#ifdef _WIN32
734 SlabSize = 1024 * 1024;
735#else
736 SlabSize = 1024 * 1024 * 1024;
737#endif
738
739 if (!SlabAllocateSizeString.empty())
740 SlabSize = ExitOnErr(getSlabAllocSize(SizeString: SlabAllocateSizeString));
741
742 // If this is a -no-exec case and we're tweaking the slab address or size then
743 // use the delta mapper.
744 if (NoExec && (SlabAddress || SlabPageSize))
745 return ExitOnErr(
746 MapperJITLinkMemoryManager::CreateWithMapper<InProcessDeltaMapper>(
747 ReservationGranularity: SlabSize));
748
749 // Otherwise use the standard in-process mapper.
750 return ExitOnErr(
751 MapperJITLinkMemoryManager::CreateWithMapper<InProcessMemoryMapper>(
752 ReservationGranularity: SlabSize));
753}
754
755Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
756createSimpleRemoteMemoryManager(ExecutorProcessControl &EPC) {
757 SimpleRemoteMemoryMapper::SymbolAddrs SAs;
758 if (auto Err = EPC.getBootstrapSymbols(
759 Pairs: {{SAs.Instance, rt::SimpleExecutorMemoryManagerInstanceName},
760 {SAs.Reserve, rt::SimpleExecutorMemoryManagerReserveWrapperName},
761 {SAs.Initialize,
762 rt::SimpleExecutorMemoryManagerInitializeWrapperName},
763 {SAs.Deinitialize,
764 rt::SimpleExecutorMemoryManagerDeinitializeWrapperName},
765 {SAs.Release, rt::SimpleExecutorMemoryManagerReleaseWrapperName}}))
766 return std::move(Err);
767#ifdef _WIN32
768 size_t SlabSize = 1024 * 1024;
769#else
770 size_t SlabSize = 1024 * 1024 * 1024;
771#endif
772 return MapperJITLinkMemoryManager::CreateWithMapper<SimpleRemoteMemoryMapper>(
773 ReservationGranularity: SlabSize, A&: EPC, A&: SAs);
774}
775
776Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
777createSharedMemoryManager(ExecutorProcessControl &EPC) {
778 SharedMemoryMapper::SymbolAddrs SAs;
779 if (auto Err = EPC.getBootstrapSymbols(
780 Pairs: {{SAs.Instance, rt::ExecutorSharedMemoryMapperServiceInstanceName},
781 {SAs.Reserve,
782 rt::ExecutorSharedMemoryMapperServiceReserveWrapperName},
783 {SAs.Initialize,
784 rt::ExecutorSharedMemoryMapperServiceInitializeWrapperName},
785 {SAs.Deinitialize,
786 rt::ExecutorSharedMemoryMapperServiceDeinitializeWrapperName},
787 {SAs.Release,
788 rt::ExecutorSharedMemoryMapperServiceReleaseWrapperName}}))
789 return std::move(Err);
790
791#ifdef _WIN32
792 size_t SlabSize = 1024 * 1024;
793#else
794 size_t SlabSize = 1024 * 1024 * 1024;
795#endif
796
797 if (!SlabAllocateSizeString.empty())
798 SlabSize = ExitOnErr(getSlabAllocSize(SizeString: SlabAllocateSizeString));
799
800 return MapperJITLinkMemoryManager::CreateWithMapper<SharedMemoryMapper>(
801 ReservationGranularity: SlabSize, A&: EPC, A&: SAs);
802}
803
804static Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
805createMemoryManager(ExecutorProcessControl &EPC) {
806 if (OutOfProcessExecutor.getNumOccurrences() ||
807 OutOfProcessExecutorConnect.getNumOccurrences()) {
808
809 switch (UseMemMgr) {
810 case MemMgr::Default:
811 case MemMgr::Generic:
812 return EPC.createDefaultMemoryManager();
813 case MemMgr::SimpleRemote:
814 return createSimpleRemoteMemoryManager(EPC);
815 case MemMgr::Shared:
816 return createSharedMemoryManager(EPC);
817 }
818 }
819
820 return createInProcessMemoryManager();
821}
822
823static Expected<MaterializationUnit::Interface>
824getTestObjectFileInterface(Session &S, MemoryBufferRef O) {
825
826 // Get the standard interface for this object, but ignore the symbols field.
827 // We'll handle that manually to include promotion.
828 auto I = getObjectFileInterface(ES&: S.ES, ObjBuffer: O);
829 if (!I)
830 return I.takeError();
831 I->SymbolFlags.clear();
832
833 // If creating an object file was going to fail it would have happened above,
834 // so we can 'cantFail' this.
835 auto Obj = cantFail(ValOrErr: object::ObjectFile::createObjectFile(Object: O));
836
837 // The init symbol must be included in the SymbolFlags map if present.
838 if (I->InitSymbol)
839 I->SymbolFlags[I->InitSymbol] =
840 JITSymbolFlags::MaterializationSideEffectsOnly;
841
842 for (auto &Sym : Obj->symbols()) {
843 Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
844 if (!SymFlagsOrErr)
845 // TODO: Test this error.
846 return SymFlagsOrErr.takeError();
847
848 // Skip symbols not defined in this object file.
849 if ((*SymFlagsOrErr & object::BasicSymbolRef::SF_Undefined))
850 continue;
851
852 auto Name = Sym.getName();
853 if (!Name)
854 return Name.takeError();
855
856 // Skip symbols that have type SF_File.
857 if (auto SymType = Sym.getType()) {
858 if (*SymType == object::SymbolRef::ST_File)
859 continue;
860 } else
861 return SymType.takeError();
862
863 auto SymFlags = JITSymbolFlags::fromObjectSymbol(Symbol: Sym);
864 if (!SymFlags)
865 return SymFlags.takeError();
866
867 if (SymFlags->isWeak()) {
868 // If this is a weak symbol that's not defined in the harness then we
869 // need to either mark it as strong (if this is the first definition
870 // that we've seen) or discard it.
871 if (S.HarnessDefinitions.count(Key: *Name) || S.CanonicalWeakDefs.count(Val: *Name))
872 continue;
873 S.CanonicalWeakDefs[*Name] = O.getBufferIdentifier();
874 *SymFlags &= ~JITSymbolFlags::Weak;
875 if (!S.HarnessExternals.count(Key: *Name))
876 *SymFlags &= ~JITSymbolFlags::Exported;
877 } else if (S.HarnessExternals.count(Key: *Name)) {
878 *SymFlags |= JITSymbolFlags::Exported;
879 } else if (S.HarnessDefinitions.count(Key: *Name) ||
880 !(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global))
881 continue;
882
883 I->SymbolFlags[S.ES.intern(SymName: *Name)] = std::move(*SymFlags);
884 }
885
886 return I;
887}
888
889static Error loadProcessSymbols(Session &S) {
890 S.ProcessSymsJD = &S.ES.createBareJITDylib(Name: "Process");
891 auto FilterMainEntryPoint =
892 [EPName = S.ES.intern(SymName: EntryPointName)](SymbolStringPtr Name) {
893 return Name != EPName;
894 };
895 S.ProcessSymsJD->addGenerator(
896 DefGenerator: ExitOnErr(orc::EPCDynamicLibrarySearchGenerator::GetForTargetProcess(
897 ES&: S.ES, DylibMgr&: *S.DylibMgr, Allow: std::move(FilterMainEntryPoint))));
898
899 return Error::success();
900}
901
902static Error loadDylibs(Session &S) {
903 LLVM_DEBUG(dbgs() << "Loading dylibs...\n");
904 for (const auto &Dylib : Dylibs) {
905 LLVM_DEBUG(dbgs() << " " << Dylib << "\n");
906 auto DL = S.getOrLoadDynamicLibrary(LibPath: Dylib);
907 if (!DL)
908 return DL.takeError();
909 }
910
911 return Error::success();
912}
913
914static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
915#ifndef LLVM_ON_UNIX
916 // FIXME: Add support for Windows.
917 return make_error<StringError>("-" + OutOfProcessExecutor.ArgStr +
918 " not supported on non-unix platforms",
919 inconvertibleErrorCode());
920#elif !LLVM_ENABLE_THREADS
921 // Out of process mode using SimpleRemoteEPC depends on threads.
922 return make_error<StringError>(
923 "-" + OutOfProcessExecutor.ArgStr +
924 " requires threads, but LLVM was built with "
925 "LLVM_ENABLE_THREADS=Off",
926 inconvertibleErrorCode());
927#else
928
929 constexpr int ReadEnd = 0;
930 constexpr int WriteEnd = 1;
931
932 // Pipe FDs.
933 int ToExecutor[2];
934 int FromExecutor[2];
935
936 pid_t ChildPID;
937
938 // Create pipes to/from the executor..
939 if (pipe(pipedes: ToExecutor) != 0 || pipe(pipedes: FromExecutor) != 0)
940 return make_error<StringError>(Args: "Unable to create pipe for executor",
941 Args: inconvertibleErrorCode());
942
943 ChildPID = fork();
944
945 if (ChildPID == 0) {
946 // In the child...
947
948 // Close the parent ends of the pipes
949 close(fd: ToExecutor[WriteEnd]);
950 close(fd: FromExecutor[ReadEnd]);
951
952 // Execute the child process.
953 std::unique_ptr<char[]> ExecutorPath, FDSpecifier;
954 {
955 ExecutorPath = std::make_unique<char[]>(num: OutOfProcessExecutor.size() + 1);
956 strcpy(dest: ExecutorPath.get(), src: OutOfProcessExecutor.data());
957
958 std::string FDSpecifierStr("filedescs=");
959 FDSpecifierStr += utostr(X: ToExecutor[ReadEnd]);
960 FDSpecifierStr += ',';
961 FDSpecifierStr += utostr(X: FromExecutor[WriteEnd]);
962 FDSpecifier = std::make_unique<char[]>(num: FDSpecifierStr.size() + 1);
963 strcpy(dest: FDSpecifier.get(), src: FDSpecifierStr.c_str());
964 }
965
966 char *const Args[] = {ExecutorPath.get(), FDSpecifier.get(), nullptr};
967 int RC = execvp(file: ExecutorPath.get(), argv: Args);
968 if (RC != 0) {
969 errs() << "unable to launch out-of-process executor \""
970 << ExecutorPath.get() << "\"\n";
971 exit(status: 1);
972 }
973 }
974 // else we're the parent...
975
976 // Close the child ends of the pipes
977 close(fd: ToExecutor[ReadEnd]);
978 close(fd: FromExecutor[WriteEnd]);
979
980 return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
981 D: std::make_unique<DynamicThreadPoolTaskDispatcher>(args&: MaterializationThreads),
982 TransportTCtorArgs&: FromExecutor[ReadEnd], TransportTCtorArgs&: ToExecutor[WriteEnd]);
983#endif
984}
985
986#if LLVM_ON_UNIX && LLVM_ENABLE_THREADS
987static Error createTCPSocketError(Twine Details) {
988 return make_error<StringError>(
989 Args: formatv(Fmt: "Failed to connect TCP socket '{0}': {1}",
990 Vals&: OutOfProcessExecutorConnect, Vals&: Details),
991 Args: inconvertibleErrorCode());
992}
993
994static Expected<int> connectTCPSocket(std::string Host, std::string PortStr) {
995 addrinfo *AI;
996 addrinfo Hints{};
997 Hints.ai_family = AF_INET;
998 Hints.ai_socktype = SOCK_STREAM;
999 Hints.ai_flags = AI_NUMERICSERV;
1000
1001 if (int EC = getaddrinfo(name: Host.c_str(), service: PortStr.c_str(), req: &Hints, pai: &AI))
1002 return createTCPSocketError(Details: "Address resolution failed (" +
1003 StringRef(gai_strerror(ecode: EC)) + ")");
1004
1005 // Cycle through the returned addrinfo structures and connect to the first
1006 // reachable endpoint.
1007 int SockFD;
1008 addrinfo *Server;
1009 for (Server = AI; Server != nullptr; Server = Server->ai_next) {
1010 // socket might fail, e.g. if the address family is not supported. Skip to
1011 // the next addrinfo structure in such a case.
1012 if ((SockFD = socket(domain: AI->ai_family, type: AI->ai_socktype, protocol: AI->ai_protocol)) < 0)
1013 continue;
1014
1015 // If connect returns null, we exit the loop with a working socket.
1016 if (connect(fd: SockFD, addr: Server->ai_addr, len: Server->ai_addrlen) == 0)
1017 break;
1018
1019 close(fd: SockFD);
1020 }
1021 freeaddrinfo(ai: AI);
1022
1023 // If we reached the end of the loop without connecting to a valid endpoint,
1024 // dump the last error that was logged in socket() or connect().
1025 if (Server == nullptr)
1026 return createTCPSocketError(Details: std::strerror(errno));
1027
1028 return SockFD;
1029}
1030#endif
1031
1032static Expected<std::unique_ptr<ExecutorProcessControl>> connectToExecutor() {
1033#ifndef LLVM_ON_UNIX
1034 // FIXME: Add TCP support for Windows.
1035 return make_error<StringError>("-" + OutOfProcessExecutorConnect.ArgStr +
1036 " not supported on non-unix platforms",
1037 inconvertibleErrorCode());
1038#elif !LLVM_ENABLE_THREADS
1039 // Out of process mode using SimpleRemoteEPC depends on threads.
1040 return make_error<StringError>(
1041 "-" + OutOfProcessExecutorConnect.ArgStr +
1042 " requires threads, but LLVM was built with "
1043 "LLVM_ENABLE_THREADS=Off",
1044 inconvertibleErrorCode());
1045#else
1046
1047 StringRef Host, PortStr;
1048 std::tie(args&: Host, args&: PortStr) = StringRef(OutOfProcessExecutorConnect).split(Separator: ':');
1049 if (Host.empty())
1050 return createTCPSocketError(Details: "Host name for -" +
1051 OutOfProcessExecutorConnect.ArgStr +
1052 " can not be empty");
1053 if (PortStr.empty())
1054 return createTCPSocketError(Details: "Port number in -" +
1055 OutOfProcessExecutorConnect.ArgStr +
1056 " can not be empty");
1057 int Port = 0;
1058 if (PortStr.getAsInteger(Radix: 10, Result&: Port))
1059 return createTCPSocketError(Details: "Port number '" + PortStr +
1060 "' is not a valid integer");
1061
1062 Expected<int> SockFD = connectTCPSocket(Host: Host.str(), PortStr: PortStr.str());
1063 if (!SockFD)
1064 return SockFD.takeError();
1065
1066 return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
1067 D: std::make_unique<DynamicThreadPoolTaskDispatcher>(args: std::nullopt), TransportTCtorArgs&: *SockFD,
1068 TransportTCtorArgs&: *SockFD);
1069#endif
1070}
1071
1072class PhonyExternalsGenerator : public DefinitionGenerator {
1073public:
1074 Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD,
1075 JITDylibLookupFlags JDLookupFlags,
1076 const SymbolLookupSet &LookupSet) override {
1077 SymbolMap PhonySymbols;
1078 for (auto &KV : LookupSet)
1079 PhonySymbols[KV.first] = {ExecutorAddr(), JITSymbolFlags::Exported};
1080 return JD.define(MU: absoluteSymbols(Symbols: std::move(PhonySymbols)));
1081 }
1082};
1083
1084Expected<std::unique_ptr<Session::LazyLinkingSupport>>
1085createLazyLinkingSupport(Session &S) {
1086 auto MemAccess = S.ES.getExecutorProcessControl().createDefaultMemoryAccess();
1087 if (!MemAccess)
1088 return MemAccess.takeError();
1089
1090 auto RSMgr =
1091 JITLinkRedirectableSymbolManager::Create(ObjLinkingLayer&: *S.ObjLayer, MemAccess&: **MemAccess);
1092 if (!RSMgr)
1093 return RSMgr.takeError();
1094
1095 std::shared_ptr<SimpleLazyReexportsSpeculator> Speculator;
1096 switch (Speculate) {
1097 case SpeculateKind::None:
1098 break;
1099 case SpeculateKind::Simple:
1100 SimpleLazyReexportsSpeculator::RecordExecutionFunction RecordExecs;
1101
1102 if (!RecordLazyExecs.empty())
1103 RecordExecs = [&S](const LazyReexportsManager::CallThroughInfo &CTI) {
1104 S.LazyFnExecOrder.push_back(x: {CTI.JD->getName(), CTI.BodyName});
1105 };
1106
1107 Speculator =
1108 SimpleLazyReexportsSpeculator::Create(ES&: S.ES, RecordExec: std::move(RecordExecs));
1109 break;
1110 }
1111
1112 auto LRMgr = createJITLinkLazyReexportsManager(
1113 ObjLinkingLayer&: *S.ObjLayer, RSMgr&: **RSMgr, PlatformJD&: *S.PlatformJD, L: Speculator.get());
1114 if (!LRMgr)
1115 return LRMgr.takeError();
1116
1117 return std::make_unique<Session::LazyLinkingSupport>(
1118 args: std::move(*MemAccess), args: std::move(*RSMgr), args: std::move(Speculator),
1119 args: std::move(*LRMgr), args&: *S.ObjLayer);
1120}
1121
1122static Error writeLazyExecOrder(Session &S) {
1123 if (RecordLazyExecs.empty())
1124 return Error::success();
1125
1126 std::error_code EC;
1127 raw_fd_ostream ExecOrderOut(RecordLazyExecs, EC);
1128 if (EC)
1129 return createFileError(F: RecordLazyExecs, EC);
1130
1131 for (auto &[JDName, FunctionName] : S.LazyFnExecOrder)
1132 ExecOrderOut << JDName << ", " << FunctionName << "\n";
1133
1134 return Error::success();
1135}
1136
1137Expected<std::unique_ptr<Session>> Session::Create(Triple TT,
1138 SubtargetFeatures Features) {
1139
1140 std::unique_ptr<ExecutorProcessControl> EPC;
1141 if (OutOfProcessExecutor.getNumOccurrences()) {
1142 /// If -oop-executor is passed then launch the executor.
1143 if (auto REPC = launchExecutor())
1144 EPC = std::move(*REPC);
1145 else
1146 return REPC.takeError();
1147 } else if (OutOfProcessExecutorConnect.getNumOccurrences()) {
1148 /// If -oop-executor-connect is passed then connect to the executor.
1149 if (auto REPC = connectToExecutor())
1150 EPC = std::move(*REPC);
1151 else
1152 return REPC.takeError();
1153 } else {
1154 /// Otherwise use SelfExecutorProcessControl to target the current process.
1155 auto PageSize = sys::Process::getPageSize();
1156 if (!PageSize)
1157 return PageSize.takeError();
1158 std::unique_ptr<TaskDispatcher> Dispatcher;
1159 if (MaterializationThreads == 0)
1160 Dispatcher = std::make_unique<InPlaceTaskDispatcher>();
1161 else {
1162#if LLVM_ENABLE_THREADS
1163 Dispatcher = std::make_unique<DynamicThreadPoolTaskDispatcher>(
1164 args&: MaterializationThreads);
1165#else
1166 llvm_unreachable("MaterializationThreads should be 0");
1167#endif
1168 }
1169
1170 EPC = std::make_unique<SelfExecutorProcessControl>(
1171 args: std::make_shared<SymbolStringPool>(), args: std::move(Dispatcher),
1172 args: std::move(TT), args&: *PageSize);
1173 }
1174
1175 Error Err = Error::success();
1176 std::unique_ptr<Session> S(new Session(std::move(EPC), Err));
1177 if (Err)
1178 return std::move(Err);
1179 S->Features = std::move(Features);
1180
1181 if (lazyLinkingRequested()) {
1182 if (auto LazyLinking = createLazyLinkingSupport(S&: *S))
1183 S->LazyLinking = std::move(*LazyLinking);
1184 else
1185 return LazyLinking.takeError();
1186 }
1187
1188 return std::move(S);
1189}
1190
1191Session::~Session() {
1192 if (auto Err = writeLazyExecOrder(S&: *this))
1193 ES.reportError(Err: std::move(Err));
1194
1195 if (auto Err = ES.endSession())
1196 ES.reportError(Err: std::move(Err));
1197}
1198
1199Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err)
1200 : ES(std::move(EPC)) {
1201
1202 /// Local ObjectLinkingLayer::Plugin class to forward modifyPassConfig to the
1203 /// Session.
1204 class JITLinkSessionPlugin : public ObjectLinkingLayer::Plugin {
1205 public:
1206 JITLinkSessionPlugin(Session &S) : S(S) {}
1207 void modifyPassConfig(MaterializationResponsibility &MR, LinkGraph &G,
1208 PassConfiguration &PassConfig) override {
1209 S.modifyPassConfig(G, PassConfig);
1210 }
1211
1212 Error notifyFailed(MaterializationResponsibility &MR) override {
1213 return Error::success();
1214 }
1215 Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
1216 return Error::success();
1217 }
1218 void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
1219 ResourceKey SrcKey) override {}
1220
1221 private:
1222 Session &S;
1223 };
1224
1225 ErrorAsOutParameter _(&Err);
1226
1227 if (auto MM = createMemoryManager(EPC&: ES.getExecutorProcessControl())) {
1228 MemoryMgr = std::move(*MM);
1229 ObjLayer = std::make_unique<orc::ObjectLinkingLayer>(args&: ES, args&: *MemoryMgr);
1230 } else {
1231 Err = MM.takeError();
1232 return;
1233 }
1234
1235 if (auto DM = ES.getExecutorProcessControl().createDefaultDylibMgr())
1236 DylibMgr = std::move(*DM);
1237 else {
1238 Err = DM.takeError();
1239 return;
1240 }
1241
1242 ES.setErrorReporter(reportLLVMJITLinkError);
1243
1244 // Attach WaitingOnGraph recorder if requested.
1245 if (!WaitingOnGraphCapture.empty()) {
1246 if (auto GRecorderOrErr =
1247 WaitingOnGraphOpRecorder::Create(Path: WaitingOnGraphCapture)) {
1248 GOpRecorder = std::move(*GRecorderOrErr);
1249 ES.setWaitingOnGraphOpRecorder(*GOpRecorder);
1250 } else {
1251 Err = GRecorderOrErr.takeError();
1252 return;
1253 }
1254 }
1255
1256 if (!NoProcessSymbols)
1257 ExitOnErr(loadProcessSymbols(S&: *this));
1258
1259 ExitOnErr(loadDylibs(S&: *this));
1260
1261 auto &TT = ES.getTargetTriple();
1262
1263 if (!WriteSymbolTableTo.empty()) {
1264 if (auto STDump = SymbolTableDumpPlugin::Create(Path: WriteSymbolTableTo))
1265 ObjLayer->addPlugin(P: std::move(*STDump));
1266 else {
1267 Err = STDump.takeError();
1268 return;
1269 }
1270 }
1271
1272 if (DebuggerSupport && TT.isOSBinFormatMachO()) {
1273 if (!ProcessSymsJD) {
1274 Err = make_error<StringError>(Args: "MachO debugging requires process symbols",
1275 Args: inconvertibleErrorCode());
1276 return;
1277 }
1278 ObjLayer->addPlugin(P: ExitOnErr(GDBJITDebugInfoRegistrationPlugin::Create(
1279 ES&: this->ES, ProcessJD&: *ProcessSymsJD, TT)));
1280 }
1281
1282 if (PerfSupport && TT.isOSBinFormatELF()) {
1283 if (!ProcessSymsJD) {
1284 Err = make_error<StringError>(Args: "MachO debugging requires process symbols",
1285 Args: inconvertibleErrorCode());
1286 return;
1287 }
1288 ObjLayer->addPlugin(P: ExitOnErr(DebugInfoPreservationPlugin::Create()));
1289 ObjLayer->addPlugin(P: ExitOnErr(PerfSupportPlugin::Create(
1290 EPC&: this->ES.getExecutorProcessControl(), JD&: *ProcessSymsJD, EmitDebugInfo: true, EmitUnwindInfo: true)));
1291 }
1292
1293 if (VTuneSupport && TT.isOSBinFormatELF()) {
1294 ObjLayer->addPlugin(P: ExitOnErr(DebugInfoPreservationPlugin::Create()));
1295 ObjLayer->addPlugin(P: ExitOnErr(
1296 VTuneSupportPlugin::Create(EPC&: this->ES.getExecutorProcessControl(),
1297 JD&: *ProcessSymsJD, /*EmitDebugInfo=*/true,
1298 /*TestMode=*/true)));
1299 }
1300
1301 // Set up the platform.
1302 if (!OrcRuntime.empty()) {
1303 assert(ProcessSymsJD && "ProcessSymsJD should have been set");
1304 PlatformJD = &ES.createBareJITDylib(Name: "Platform");
1305 PlatformJD->addToLinkOrder(JD&: *ProcessSymsJD);
1306
1307 if (TT.isOSBinFormatMachO()) {
1308 if (auto P =
1309 MachOPlatform::Create(ObjLinkingLayer&: *ObjLayer, PlatformJD&: *PlatformJD, OrcRuntimePath: OrcRuntime.c_str()))
1310 ES.setPlatform(std::move(*P));
1311 else {
1312 Err = P.takeError();
1313 return;
1314 }
1315 } else if (TT.isOSBinFormatELF()) {
1316 if (auto P = ELFNixPlatform::Create(ObjLinkingLayer&: *ObjLayer, PlatformJD&: *PlatformJD,
1317 OrcRuntimePath: OrcRuntime.c_str()))
1318 ES.setPlatform(std::move(*P));
1319 else {
1320 Err = P.takeError();
1321 return;
1322 }
1323 } else if (TT.isOSBinFormatCOFF()) {
1324 auto LoadDynLibrary = [&, this](JITDylib &JD,
1325 StringRef DLLName) -> Error {
1326 if (!DLLName.ends_with_insensitive(Suffix: ".dll"))
1327 return make_error<StringError>(Args: "DLLName not ending with .dll",
1328 Args: inconvertibleErrorCode());
1329 return loadAndLinkDynamicLibrary(JD, LibPath: DLLName);
1330 };
1331
1332 if (auto P =
1333 COFFPlatform::Create(ObjLinkingLayer&: *ObjLayer, PlatformJD&: *PlatformJD, OrcRuntimePath: OrcRuntime.c_str(),
1334 LoadDynLibrary: std::move(LoadDynLibrary)))
1335 ES.setPlatform(std::move(*P));
1336 else {
1337 Err = P.takeError();
1338 return;
1339 }
1340 } else {
1341 Err = make_error<StringError>(
1342 Args: "-" + OrcRuntime.ArgStr + " specified, but format " +
1343 Triple::getObjectFormatTypeName(ObjectFormat: TT.getObjectFormat()) +
1344 " not supported",
1345 Args: inconvertibleErrorCode());
1346 return;
1347 }
1348 } else if (TT.isOSBinFormatMachO()) {
1349 if (!NoExec) {
1350 std::optional<bool> ForceEHFrames;
1351 if ((Err = ES.getBootstrapMapValue<bool, bool>(Key: "darwin-use-ehframes-only",
1352 Val&: ForceEHFrames)))
1353 return;
1354 bool UseEHFrames = ForceEHFrames.value_or(u: false);
1355 if (!UseEHFrames)
1356 ObjLayer->addPlugin(
1357 P: ExitOnErr(UnwindInfoRegistrationPlugin::Create(ES)));
1358 else
1359 ObjLayer->addPlugin(P: ExitOnErr(EHFrameRegistrationPlugin::Create(ES)));
1360 }
1361 } else if (TT.isOSBinFormatELF()) {
1362 if (!NoExec)
1363 ObjLayer->addPlugin(P: ExitOnErr(EHFrameRegistrationPlugin::Create(ES)));
1364 if (DebuggerSupport) {
1365 Error TargetSymErr = Error::success();
1366 auto Plugin =
1367 std::make_unique<ELFDebugObjectPlugin>(args&: ES, args: true, args: true, args&: TargetSymErr);
1368 if (!TargetSymErr)
1369 ObjLayer->addPlugin(P: std::move(Plugin));
1370 else
1371 logAllUnhandledErrors(E: std::move(TargetSymErr), OS&: errs(),
1372 ErrorBanner: "Debugger support not available: ");
1373 }
1374 }
1375
1376 if (auto MainJDOrErr = ES.createJITDylib(Name: "main"))
1377 MainJD = &*MainJDOrErr;
1378 else {
1379 Err = MainJDOrErr.takeError();
1380 return;
1381 }
1382
1383 if (NoProcessSymbols) {
1384 // This symbol is used in testcases, but we're not reflecting process
1385 // symbols so we'll need to make it available some other way.
1386 auto &TestResultJD = ES.createBareJITDylib(Name: "<TestResultJD>");
1387 ExitOnErr(TestResultJD.define(MU: absoluteSymbols(
1388 Symbols: {{ES.intern(SymName: "llvm_jitlink_setTestResultOverride"),
1389 {ExecutorAddr::fromPtr(Ptr: llvm_jitlink_setTestResultOverride),
1390 JITSymbolFlags::Exported}}})));
1391 MainJD->addToLinkOrder(JD&: TestResultJD);
1392 }
1393
1394 ObjLayer->addPlugin(P: std::make_unique<JITLinkSessionPlugin>(args&: *this));
1395
1396 // Process any harness files.
1397 for (auto &HarnessFile : TestHarnesses) {
1398 HarnessFiles.insert(key: HarnessFile);
1399
1400 auto ObjBuffer =
1401 ExitOnErr(loadLinkableFile(Path: HarnessFile, TT: ES.getTargetTriple(),
1402 LA: LoadArchives::Never))
1403 .first;
1404
1405 auto ObjInterface =
1406 ExitOnErr(getObjectFileInterface(ES, ObjBuffer: ObjBuffer->getMemBufferRef()));
1407
1408 for (auto &KV : ObjInterface.SymbolFlags)
1409 HarnessDefinitions.insert(key: *KV.first);
1410
1411 auto Obj = ExitOnErr(
1412 object::ObjectFile::createObjectFile(Object: ObjBuffer->getMemBufferRef()));
1413
1414 for (auto &Sym : Obj->symbols()) {
1415 uint32_t SymFlags = ExitOnErr(Sym.getFlags());
1416 auto Name = ExitOnErr(Sym.getName());
1417
1418 if (Name.empty())
1419 continue;
1420
1421 if (SymFlags & object::BasicSymbolRef::SF_Undefined)
1422 HarnessExternals.insert(key: Name);
1423 }
1424 }
1425
1426 // If a name is defined by some harness file then it's a definition, not an
1427 // external.
1428 for (auto &DefName : HarnessDefinitions)
1429 HarnessExternals.erase(Key: DefName.getKey());
1430
1431 if (!ShowLinkGraphs.empty())
1432 ShowGraphsRegex = Regex(ShowLinkGraphs);
1433}
1434
1435void Session::dumpSessionInfo(raw_ostream &OS) {
1436 OS << "Registered addresses:\n" << SymbolInfos << FileInfos;
1437}
1438
1439void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) {
1440
1441 if (ShowLinkedFiles)
1442 outs() << "Linking " << G.getName() << "\n";
1443
1444 if (!CheckFiles.empty() || ShowAddrs)
1445 PassConfig.PostFixupPasses.push_back(x: [this](LinkGraph &G) {
1446 if (ES.getTargetTriple().getObjectFormat() == Triple::ELF)
1447 return registerELFGraphInfo(S&: *this, G);
1448
1449 if (ES.getTargetTriple().getObjectFormat() == Triple::MachO)
1450 return registerMachOGraphInfo(S&: *this, G);
1451
1452 if (ES.getTargetTriple().getObjectFormat() == Triple::COFF)
1453 return registerCOFFGraphInfo(S&: *this, G);
1454
1455 return make_error<StringError>(Args: "Unsupported object format for GOT/stub "
1456 "registration",
1457 Args: inconvertibleErrorCode());
1458 });
1459
1460 if (ShowGraphsRegex)
1461 PassConfig.PostFixupPasses.push_back(x: [this](LinkGraph &G) -> Error {
1462 std::lock_guard<std::mutex> Lock(M);
1463 // Print graph if ShowLinkGraphs is specified-but-empty, or if
1464 // it contains the given graph.
1465 if (ShowGraphsRegex->match(String: G.getName())) {
1466 outs() << "Link graph \"" << G.getName() << "\" post-fixup:\n";
1467 G.dump(OS&: outs());
1468 }
1469 return Error::success();
1470 });
1471
1472 PassConfig.PrePrunePasses.push_back(x: [this](LinkGraph &G) {
1473 std::lock_guard<std::mutex> Lock(M);
1474 ++ActiveLinks;
1475 return Error::success();
1476 });
1477 PassConfig.PrePrunePasses.push_back(
1478 x: [this](LinkGraph &G) { return applyLibraryLinkModifiers(S&: *this, G); });
1479 PassConfig.PrePrunePasses.push_back(
1480 x: [this](LinkGraph &G) { return applyHarnessPromotions(S&: *this, G); });
1481
1482 if (ShowRelocatedSectionContents)
1483 PassConfig.PostFixupPasses.push_back(x: [this](LinkGraph &G) -> Error {
1484 dumpSectionContents(OS&: outs(), S&: *this, G);
1485 return Error::success();
1486 });
1487
1488 if (AddSelfRelocations)
1489 PassConfig.PostPrunePasses.push_back(x: addSelfRelocations);
1490
1491 PassConfig.PostFixupPasses.push_back(x: [this](LinkGraph &G) {
1492 std::lock_guard<std::mutex> Lock(M);
1493 if (--ActiveLinks == 0)
1494 ActiveLinksCV.notify_all();
1495 return Error::success();
1496 });
1497}
1498
1499Expected<JITDylib *> Session::getOrLoadDynamicLibrary(StringRef LibPath) {
1500 auto It = DynLibJDs.find(x: LibPath);
1501 if (It != DynLibJDs.end()) {
1502 return It->second;
1503 }
1504 auto G =
1505 EPCDynamicLibrarySearchGenerator::Load(ES, DylibMgr&: *DylibMgr, LibraryPath: LibPath.data());
1506 if (!G)
1507 return G.takeError();
1508 auto JD = &ES.createBareJITDylib(Name: LibPath.str());
1509
1510 JD->addGenerator(DefGenerator: std::move(*G));
1511 DynLibJDs.emplace(args: LibPath.str(), args&: JD);
1512 LLVM_DEBUG({
1513 dbgs() << "Loaded dynamic library " << LibPath.data() << " for " << LibPath
1514 << "\n";
1515 });
1516 return JD;
1517}
1518
1519Error Session::loadAndLinkDynamicLibrary(JITDylib &JD, StringRef LibPath) {
1520 auto DL = getOrLoadDynamicLibrary(LibPath);
1521 if (!DL)
1522 return DL.takeError();
1523 JD.addToLinkOrder(JD&: **DL);
1524 LLVM_DEBUG({
1525 dbgs() << "Linking dynamic library " << LibPath << " to " << JD.getName()
1526 << "\n";
1527 });
1528 return Error::success();
1529}
1530
1531Error Session::FileInfo::registerGOTEntry(
1532 LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {
1533 if (Sym.isSymbolZeroFill())
1534 return make_error<StringError>(Args: "Unexpected zero-fill symbol in section " +
1535 Sym.getBlock().getSection().getName(),
1536 Args: inconvertibleErrorCode());
1537 auto TS = GetSymbolTarget(G, Sym.getBlock());
1538 if (!TS)
1539 return TS.takeError();
1540 GOTEntryInfos[*TS->getName()] = {Sym.getSymbolContent(),
1541 Sym.getAddress().getValue(),
1542 Sym.getTargetFlags()};
1543 return Error::success();
1544}
1545
1546Error Session::FileInfo::registerStubEntry(
1547 LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {
1548 if (Sym.isSymbolZeroFill())
1549 return make_error<StringError>(Args: "Unexpected zero-fill symbol in section " +
1550 Sym.getBlock().getSection().getName(),
1551 Args: inconvertibleErrorCode());
1552 auto TS = GetSymbolTarget(G, Sym.getBlock());
1553 if (!TS)
1554 return TS.takeError();
1555
1556 SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*TS->getName()];
1557 Entry.insert(I: Entry.begin(),
1558 Elt: {Sym.getSymbolContent(), Sym.getAddress().getValue(),
1559 Sym.getTargetFlags()});
1560 return Error::success();
1561}
1562
1563Error Session::FileInfo::registerMultiStubEntry(
1564 LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {
1565 if (Sym.isSymbolZeroFill())
1566 return make_error<StringError>(Args: "Unexpected zero-fill symbol in section " +
1567 Sym.getBlock().getSection().getName(),
1568 Args: inconvertibleErrorCode());
1569
1570 auto Target = GetSymbolTarget(G, Sym.getBlock());
1571 if (!Target)
1572 return Target.takeError();
1573
1574 SmallVectorImpl<MemoryRegionInfo> &Entry = StubInfos[*Target->getName()];
1575 Entry.emplace_back(Args: Sym.getSymbolContent(), Args: Sym.getAddress().getValue(),
1576 Args: Sym.getTargetFlags());
1577
1578 // Let's keep stubs ordered by ascending address.
1579 std::sort(first: Entry.begin(), last: Entry.end(),
1580 comp: [](const MemoryRegionInfo &L, const MemoryRegionInfo &R) {
1581 return L.getTargetAddress() < R.getTargetAddress();
1582 });
1583
1584 return Error::success();
1585}
1586
1587Expected<Session::FileInfo &> Session::findFileInfo(StringRef FileName) {
1588 auto FileInfoItr = FileInfos.find(Key: FileName);
1589 if (FileInfoItr == FileInfos.end())
1590 return make_error<StringError>(Args: "file \"" + FileName + "\" not recognized",
1591 Args: inconvertibleErrorCode());
1592 return FileInfoItr->second;
1593}
1594
1595Expected<Session::MemoryRegionInfo &>
1596Session::findSectionInfo(StringRef FileName, StringRef SectionName) {
1597 auto FI = findFileInfo(FileName);
1598 if (!FI)
1599 return FI.takeError();
1600 auto SecInfoItr = FI->SectionInfos.find(Key: SectionName);
1601 if (SecInfoItr == FI->SectionInfos.end())
1602 return make_error<StringError>(Args: "no section \"" + SectionName +
1603 "\" registered for file \"" + FileName +
1604 "\"",
1605 Args: inconvertibleErrorCode());
1606 return SecInfoItr->second;
1607}
1608
1609class MemoryMatcher {
1610public:
1611 MemoryMatcher(ArrayRef<char> Content)
1612 : Pos(Content.data()), End(Pos + Content.size()) {}
1613
1614 template <typename MaskType> bool matchMask(MaskType Mask) {
1615 if (Mask == (Mask & *reinterpret_cast<const MaskType *>(Pos))) {
1616 Pos += sizeof(MaskType);
1617 return true;
1618 }
1619 return false;
1620 }
1621
1622 template <typename ValueType> bool matchEqual(ValueType Value) {
1623 if (Value == *reinterpret_cast<const ValueType *>(Pos)) {
1624 Pos += sizeof(ValueType);
1625 return true;
1626 }
1627 return false;
1628 }
1629
1630 bool done() const { return Pos == End; }
1631
1632private:
1633 const char *Pos;
1634 const char *End;
1635};
1636
1637static StringRef detectStubKind(const Session::MemoryRegionInfo &Stub) {
1638 using namespace support::endian;
1639 auto Armv7MovWTle = byte_swap<uint32_t>(value: 0xe300c000, endian: endianness::little);
1640 auto Armv7BxR12le = byte_swap<uint32_t>(value: 0xe12fff1c, endian: endianness::little);
1641 auto Thumbv7MovWTle = byte_swap<uint32_t>(value: 0x0c00f240, endian: endianness::little);
1642 auto Thumbv7BxR12le = byte_swap<uint16_t>(value: 0x4760, endian: endianness::little);
1643
1644 MemoryMatcher M(Stub.getContent());
1645 if (M.matchMask(Mask: Thumbv7MovWTle)) {
1646 if (M.matchMask(Mask: Thumbv7MovWTle))
1647 if (M.matchEqual(Value: Thumbv7BxR12le))
1648 if (M.done())
1649 return "thumbv7_abs_le";
1650 } else if (M.matchMask(Mask: Armv7MovWTle)) {
1651 if (M.matchMask(Mask: Armv7MovWTle))
1652 if (M.matchEqual(Value: Armv7BxR12le))
1653 if (M.done())
1654 return "armv7_abs_le";
1655 }
1656 return "";
1657}
1658
1659Expected<Session::MemoryRegionInfo &>
1660Session::findStubInfo(StringRef FileName, StringRef TargetName,
1661 StringRef KindNameFilter) {
1662 auto FI = findFileInfo(FileName);
1663 if (!FI)
1664 return FI.takeError();
1665 auto StubInfoItr = FI->StubInfos.find(Key: TargetName);
1666 if (StubInfoItr == FI->StubInfos.end())
1667 return make_error<StringError>(Args: "no stub for \"" + TargetName +
1668 "\" registered for file \"" + FileName +
1669 "\"",
1670 Args: inconvertibleErrorCode());
1671 auto &StubsForTarget = StubInfoItr->second;
1672 assert(!StubsForTarget.empty() && "At least 1 stub in each entry");
1673 if (KindNameFilter.empty() && StubsForTarget.size() == 1)
1674 return StubsForTarget[0]; // Regular single-stub match
1675
1676 std::string KindsStr;
1677 SmallVector<MemoryRegionInfo *, 1> Matches;
1678 Regex KindNameMatcher(KindNameFilter.empty() ? ".*" : KindNameFilter);
1679 for (MemoryRegionInfo &Stub : StubsForTarget) {
1680 StringRef Kind = detectStubKind(Stub);
1681 if (KindNameMatcher.match(String: Kind))
1682 Matches.push_back(Elt: &Stub);
1683 KindsStr += "\"" + (Kind.empty() ? "<unknown>" : Kind.str()) + "\", ";
1684 }
1685 if (Matches.empty())
1686 return make_error<StringError>(
1687 Args: "\"" + TargetName + "\" has " + Twine(StubsForTarget.size()) +
1688 " stubs in file \"" + FileName +
1689 "\", but none of them matches the stub-kind filter \"" +
1690 KindNameFilter + "\" (all encountered kinds are " +
1691 StringRef(KindsStr.data(), KindsStr.size() - 2) + ").",
1692 Args: inconvertibleErrorCode());
1693 if (Matches.size() > 1)
1694 return make_error<StringError>(
1695 Args: "\"" + TargetName + "\" has " + Twine(Matches.size()) +
1696 " candidate stubs in file \"" + FileName +
1697 "\". Please refine stub-kind filter \"" + KindNameFilter +
1698 "\" for disambiguation (encountered kinds are " +
1699 StringRef(KindsStr.data(), KindsStr.size() - 2) + ").",
1700 Args: inconvertibleErrorCode());
1701
1702 return *Matches[0];
1703}
1704
1705Expected<Session::MemoryRegionInfo &>
1706Session::findGOTEntryInfo(StringRef FileName, StringRef TargetName) {
1707 auto FI = findFileInfo(FileName);
1708 if (!FI)
1709 return FI.takeError();
1710 auto GOTInfoItr = FI->GOTEntryInfos.find(Key: TargetName);
1711 if (GOTInfoItr == FI->GOTEntryInfos.end())
1712 return make_error<StringError>(Args: "no GOT entry for \"" + TargetName +
1713 "\" registered for file \"" + FileName +
1714 "\"",
1715 Args: inconvertibleErrorCode());
1716 return GOTInfoItr->second;
1717}
1718
1719bool Session::isSymbolRegistered(const orc::SymbolStringPtr &SymbolName) {
1720 return SymbolInfos.count(Val: SymbolName);
1721}
1722
1723Expected<Session::MemoryRegionInfo &>
1724Session::findSymbolInfo(const orc::SymbolStringPtr &SymbolName,
1725 Twine ErrorMsgStem) {
1726 auto SymInfoItr = SymbolInfos.find(Val: SymbolName);
1727 if (SymInfoItr == SymbolInfos.end())
1728 return make_error<StringError>(Args: ErrorMsgStem + ": symbol " + *SymbolName +
1729 " not found",
1730 Args: inconvertibleErrorCode());
1731 return SymInfoItr->second;
1732}
1733
1734} // end namespace llvm
1735
1736static std::pair<Triple, SubtargetFeatures> getFirstFileTripleAndFeatures() {
1737
1738 // If we're running in symbolicate mode then just use the process triple.
1739 if (!SymbolicateWith.empty())
1740 return std::make_pair(x: Triple(sys::getProcessTriple()), y: SubtargetFeatures());
1741
1742 // Otherwise we need to inspect the input files.
1743 static std::pair<Triple, SubtargetFeatures> FirstTTAndFeatures = []() {
1744 assert(!InputFiles.empty() && "InputFiles can not be empty");
1745
1746 if (!OverrideTriple.empty()) {
1747 LLVM_DEBUG({
1748 dbgs() << "Triple from -triple override: " << OverrideTriple << "\n";
1749 });
1750 return std::make_pair(x: Triple(OverrideTriple), y: SubtargetFeatures());
1751 }
1752
1753 for (auto InputFile : InputFiles) {
1754 auto ObjBuffer = ExitOnErr(getFile(FileName: InputFile));
1755 file_magic Magic = identify_magic(magic: ObjBuffer->getBuffer());
1756 switch (Magic) {
1757 case file_magic::coff_object:
1758 case file_magic::elf_relocatable:
1759 case file_magic::macho_object: {
1760 auto Obj = ExitOnErr(
1761 object::ObjectFile::createObjectFile(Object: ObjBuffer->getMemBufferRef()));
1762 Triple TT;
1763 if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(Val: Obj.get()))
1764 TT = MachOObj->getArchTriple();
1765 else
1766 TT = Obj->makeTriple();
1767 if (Magic == file_magic::coff_object) {
1768 // TODO: Move this to makeTriple() if possible.
1769 TT.setObjectFormat(Triple::COFF);
1770 TT.setOS(Triple::OSType::Win32);
1771 }
1772 SubtargetFeatures Features;
1773 if (auto ObjFeatures = Obj->getFeatures())
1774 Features = std::move(*ObjFeatures);
1775
1776 LLVM_DEBUG({
1777 dbgs() << "Triple from " << InputFile << ": " << TT.str() << "\n";
1778 });
1779 return std::make_pair(x&: TT, y&: Features);
1780 }
1781 default:
1782 break;
1783 }
1784 }
1785
1786 // If no plain object file inputs exist to pin down the triple then detect
1787 // the host triple and default to that.
1788 auto JTMB = ExitOnErr(JITTargetMachineBuilder::detectHost());
1789 LLVM_DEBUG({
1790 dbgs() << "Triple from host-detection: " << JTMB.getTargetTriple().str()
1791 << "\n";
1792 });
1793 return std::make_pair(x&: JTMB.getTargetTriple(), y&: JTMB.getFeatures());
1794 }();
1795
1796 return FirstTTAndFeatures;
1797}
1798
1799static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {
1800
1801 if (InputFiles.empty())
1802 return make_error<StringError>(
1803 Args: "Not enough positional command line arguments specified! (see "
1804 "llvm-jitlink --help)",
1805 Args: inconvertibleErrorCode());
1806
1807 // If we're in replay mode we should never get here.
1808 assert(WaitingOnGraphReplay.empty());
1809
1810 // -noexec and --args should not be used together.
1811 if (NoExec && !InputArgv.empty())
1812 errs() << "Warning: --args passed to -noexec run will be ignored.\n";
1813
1814 // Set the entry point name if not specified.
1815 if (EntryPointName.empty())
1816 EntryPointName = TT.getObjectFormat() == Triple::MachO ? "_main" : "main";
1817
1818 // Disable debugger support by default in noexec tests.
1819 if (DebuggerSupport.getNumOccurrences() == 0 && NoExec)
1820 DebuggerSupport = false;
1821
1822 if (!OrcRuntime.empty() && NoProcessSymbols)
1823 return make_error<StringError>(Args: "-orc-runtime requires process symbols",
1824 Args: inconvertibleErrorCode());
1825
1826 // If -slab-allocate is passed, check that we're not trying to use it in
1827 // -oop-executor or -oop-executor-connect mode.
1828 //
1829 // FIXME: Remove once we enable remote slab allocation.
1830 if (SlabAllocateSizeString != "") {
1831 if (OutOfProcessExecutor.getNumOccurrences() ||
1832 OutOfProcessExecutorConnect.getNumOccurrences())
1833 return make_error<StringError>(
1834 Args: "-slab-allocate cannot be used with -oop-executor or "
1835 "-oop-executor-connect",
1836 Args: inconvertibleErrorCode());
1837 }
1838
1839 // If -slab-address is passed, require -slab-allocate and -noexec
1840 if (SlabAddress != ~0ULL) {
1841 if (SlabAllocateSizeString == "" || !NoExec)
1842 return make_error<StringError>(
1843 Args: "-slab-address requires -slab-allocate and -noexec",
1844 Args: inconvertibleErrorCode());
1845
1846 if (SlabPageSize == 0)
1847 errs() << "Warning: -slab-address used without -slab-page-size.\n";
1848 }
1849
1850 if (SlabPageSize != 0) {
1851 // -slab-page-size requires slab alloc.
1852 if (SlabAllocateSizeString == "")
1853 return make_error<StringError>(Args: "-slab-page-size requires -slab-allocate",
1854 Args: inconvertibleErrorCode());
1855
1856 // Check -slab-page-size / -noexec interactions.
1857 if (!NoExec) {
1858 if (auto RealPageSize = sys::Process::getPageSize()) {
1859 if (SlabPageSize % *RealPageSize)
1860 return make_error<StringError>(
1861 Args: "-slab-page-size must be a multiple of real page size for exec "
1862 "tests (did you mean to use -noexec ?)\n",
1863 Args: inconvertibleErrorCode());
1864 } else {
1865 errs() << "Could not retrieve process page size:\n";
1866 logAllUnhandledErrors(E: RealPageSize.takeError(), OS&: errs(), ErrorBanner: "");
1867 errs() << "Executing with slab page size = "
1868 << formatv(Fmt: "{0:x}", Vals&: SlabPageSize) << ".\n"
1869 << "Tool may crash if " << formatv(Fmt: "{0:x}", Vals&: SlabPageSize)
1870 << " is not a multiple of the real process page size.\n"
1871 << "(did you mean to use -noexec ?)";
1872 }
1873 }
1874 }
1875
1876#if LLVM_ENABLE_THREADS
1877 if (MaterializationThreads == std::numeric_limits<size_t>::max()) {
1878 if (auto HC = std::thread::hardware_concurrency())
1879 MaterializationThreads = HC;
1880 else {
1881 errs() << "Warning: std::thread::hardware_concurrency() returned 0, "
1882 "defaulting to -num-threads=1.\n";
1883 MaterializationThreads = 1;
1884 }
1885 }
1886#else
1887 if (MaterializationThreads.getNumOccurrences() &&
1888 MaterializationThreads != 0) {
1889 errs() << "Warning: -num-threads was set, but LLVM was built with threads "
1890 "disabled. Resetting to -num-threads=0\n";
1891 }
1892 MaterializationThreads = 0;
1893#endif
1894
1895 if (!!OutOfProcessExecutor.getNumOccurrences() ||
1896 !!OutOfProcessExecutorConnect.getNumOccurrences()) {
1897 if (NoExec)
1898 return make_error<StringError>(Args: "-noexec cannot be used with " +
1899 OutOfProcessExecutor.ArgStr + " or " +
1900 OutOfProcessExecutorConnect.ArgStr,
1901 Args: inconvertibleErrorCode());
1902
1903 if (MaterializationThreads == 0)
1904 return make_error<StringError>(Args: "-threads=0 cannot be used with " +
1905 OutOfProcessExecutor.ArgStr + " or " +
1906 OutOfProcessExecutorConnect.ArgStr,
1907 Args: inconvertibleErrorCode());
1908 }
1909
1910#ifndef NDEBUG
1911 if (DebugFlag && MaterializationThreads != 0)
1912 errs() << "Warning: debugging output is not thread safe. "
1913 "Use -num-threads=0 to stabilize output.\n";
1914#endif // NDEBUG
1915
1916 // Only one of -oop-executor and -oop-executor-connect can be used.
1917 if (!!OutOfProcessExecutor.getNumOccurrences() &&
1918 !!OutOfProcessExecutorConnect.getNumOccurrences())
1919 return make_error<StringError>(
1920 Args: "Only one of -" + OutOfProcessExecutor.ArgStr + " and -" +
1921 OutOfProcessExecutorConnect.ArgStr + " can be specified",
1922 Args: inconvertibleErrorCode());
1923
1924 // If -oop-executor was used but no value was specified then use a sensible
1925 // default.
1926 if (!!OutOfProcessExecutor.getNumOccurrences() &&
1927 OutOfProcessExecutor.empty()) {
1928 SmallString<256> OOPExecutorPath(sys::fs::getMainExecutable(
1929 argv0: ArgV0, MainExecAddr: reinterpret_cast<void *>(&sanitizeArguments)));
1930 sys::path::remove_filename(path&: OOPExecutorPath);
1931 sys::path::append(path&: OOPExecutorPath, a: "llvm-jitlink-executor");
1932 OutOfProcessExecutor = OOPExecutorPath.str().str();
1933 }
1934
1935 // If lazy linking is requested then check compatibility with other options.
1936 if (lazyLinkingRequested()) {
1937 if (OrcRuntime.empty())
1938 return make_error<StringError>(Args: "Lazy linking requries the ORC runtime",
1939 Args: inconvertibleErrorCode());
1940
1941 if (!TestHarnesses.empty())
1942 return make_error<StringError>(
1943 Args: "Lazy linking cannot be used with -harness mode",
1944 Args: inconvertibleErrorCode());
1945 } else if (Speculate != SpeculateKind::None) {
1946 errs() << "Warning: -speculate ignored as there are no -lazy inputs\n";
1947 Speculate = SpeculateKind::None;
1948 }
1949
1950 if (Speculate == SpeculateKind::None) {
1951 if (!SpeculateOrder.empty()) {
1952 errs() << "Warning: -speculate-order ignored because speculation is "
1953 "disabled\n";
1954 SpeculateOrder = "";
1955 }
1956
1957 if (!RecordLazyExecs.empty()) {
1958 errs() << "Warning: -record-lazy-execs ignored because speculation is "
1959 "disabled\n";
1960 RecordLazyExecs = "";
1961 }
1962 }
1963
1964 if (!SymbolicateWith.empty()) {
1965 if (!WriteSymbolTableTo.empty())
1966 errs() << WriteSymbolTableTo.ArgStr << " specified with "
1967 << SymbolicateWith.ArgStr << ", ignoring.";
1968 if (InputFiles.empty())
1969 InputFiles.push_back(value: "-");
1970 }
1971
1972 return Error::success();
1973}
1974
1975static void addPhonyExternalsGenerator(Session &S) {
1976 S.MainJD->addGenerator(DefGenerator: std::make_unique<PhonyExternalsGenerator>());
1977}
1978
1979static Error createJITDylibs(Session &S,
1980 std::map<unsigned, JITDylib *> &IdxToJD) {
1981 // First, set up JITDylibs.
1982 LLVM_DEBUG(dbgs() << "Creating JITDylibs...\n");
1983 {
1984 // Create a "main" JITLinkDylib.
1985 IdxToJD[0] = S.MainJD;
1986 S.JDSearchOrder.push_back(x: {S.MainJD, JITDylibLookupFlags::MatchAllSymbols});
1987 LLVM_DEBUG(dbgs() << " 0: " << S.MainJD->getName() << "\n");
1988
1989 // Add any extra JITDylibs from the command line.
1990 for (auto JDItr = JITDylibs.begin(), JDEnd = JITDylibs.end();
1991 JDItr != JDEnd; ++JDItr) {
1992 auto JD = S.ES.createJITDylib(Name: *JDItr);
1993 if (!JD)
1994 return JD.takeError();
1995 unsigned JDIdx = JITDylibs.getPosition(optnum: JDItr - JITDylibs.begin());
1996 IdxToJD[JDIdx] = &*JD;
1997 S.JDSearchOrder.push_back(x: {&*JD, JITDylibLookupFlags::MatchAllSymbols});
1998 LLVM_DEBUG(dbgs() << " " << JDIdx << ": " << JD->getName() << "\n");
1999 }
2000 }
2001
2002 if (S.PlatformJD)
2003 S.JDSearchOrder.push_back(
2004 x: {S.PlatformJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});
2005 if (S.ProcessSymsJD)
2006 S.JDSearchOrder.push_back(
2007 x: {S.ProcessSymsJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});
2008
2009 LLVM_DEBUG({
2010 dbgs() << "Dylib search order is [ ";
2011 for (auto &KV : S.JDSearchOrder)
2012 dbgs() << KV.first->getName() << " ";
2013 dbgs() << "]\n";
2014 });
2015
2016 return Error::success();
2017}
2018
2019static Error addAbsoluteSymbols(Session &S,
2020 const std::map<unsigned, JITDylib *> &IdxToJD) {
2021 // Define absolute symbols.
2022 LLVM_DEBUG(dbgs() << "Defining absolute symbols...\n");
2023 for (auto AbsDefItr = AbsoluteDefs.begin(), AbsDefEnd = AbsoluteDefs.end();
2024 AbsDefItr != AbsDefEnd; ++AbsDefItr) {
2025 unsigned AbsDefArgIdx =
2026 AbsoluteDefs.getPosition(optnum: AbsDefItr - AbsoluteDefs.begin());
2027 auto &JD = *std::prev(x: IdxToJD.lower_bound(x: AbsDefArgIdx))->second;
2028
2029 StringRef AbsDefStmt = *AbsDefItr;
2030 size_t EqIdx = AbsDefStmt.find_first_of(C: '=');
2031 if (EqIdx == StringRef::npos)
2032 return make_error<StringError>(Args: "Invalid absolute define \"" + AbsDefStmt +
2033 "\". Syntax: <name>=<addr>",
2034 Args: inconvertibleErrorCode());
2035 StringRef Name = AbsDefStmt.substr(Start: 0, N: EqIdx).trim();
2036 StringRef AddrStr = AbsDefStmt.substr(Start: EqIdx + 1).trim();
2037
2038 uint64_t Addr;
2039 if (AddrStr.getAsInteger(Radix: 0, Result&: Addr))
2040 return make_error<StringError>(Args: "Invalid address expression \"" + AddrStr +
2041 "\" in absolute symbol definition \"" +
2042 AbsDefStmt + "\"",
2043 Args: inconvertibleErrorCode());
2044 ExecutorSymbolDef AbsDef(ExecutorAddr(Addr), JITSymbolFlags::Exported);
2045 auto InternedName = S.ES.intern(SymName: Name);
2046 if (auto Err = JD.define(MU: absoluteSymbols(Symbols: {{InternedName, AbsDef}})))
2047 return Err;
2048
2049 // Register the absolute symbol with the session symbol infos.
2050 S.SymbolInfos[std::move(InternedName)] =
2051 {ArrayRef<char>(), Addr, AbsDef.getFlags().getTargetFlags()};
2052 }
2053
2054 return Error::success();
2055}
2056
2057static Error addAliases(Session &S,
2058 const std::map<unsigned, JITDylib *> &IdxToJD) {
2059 // Define absolute symbols.
2060 LLVM_DEBUG(dbgs() << "Defining aliases...\n");
2061
2062 DenseMap<std::pair<JITDylib *, JITDylib *>, SymbolAliasMap> Reexports;
2063 for (auto AliasItr = Aliases.begin(), AliasEnd = Aliases.end();
2064 AliasItr != AliasEnd; ++AliasItr) {
2065
2066 auto BadExpr = [&]() {
2067 return make_error<StringError>(
2068 Args: "Invalid alias definition \"" + *AliasItr +
2069 "\". Syntax: [<dst-jd>:]<alias>=[<src-jd>:]<aliasee>",
2070 Args: inconvertibleErrorCode());
2071 };
2072
2073 auto GetJD = [&](StringRef JDName) -> Expected<JITDylib *> {
2074 if (JDName.empty()) {
2075 unsigned AliasArgIdx = Aliases.getPosition(optnum: AliasItr - Aliases.begin());
2076 return std::prev(x: IdxToJD.lower_bound(x: AliasArgIdx))->second;
2077 }
2078
2079 auto *JD = S.ES.getJITDylibByName(Name: JDName);
2080 if (!JD)
2081 return make_error<StringError>(Args: StringRef("In alias definition \"") +
2082 *AliasItr + "\" no dylib named " +
2083 JDName,
2084 Args: inconvertibleErrorCode());
2085
2086 return JD;
2087 };
2088
2089 {
2090 // First split on '=' to get alias and aliasee.
2091 StringRef AliasStmt = *AliasItr;
2092 auto [AliasExpr, AliaseeExpr] = AliasStmt.split(Separator: '=');
2093 if (AliaseeExpr.empty())
2094 return BadExpr();
2095
2096 auto [AliasJDName, Alias] = AliasExpr.split(Separator: ':');
2097 if (Alias.empty())
2098 std::swap(a&: AliasJDName, b&: Alias);
2099
2100 auto AliasJD = GetJD(AliasJDName);
2101 if (!AliasJD)
2102 return AliasJD.takeError();
2103
2104 auto [AliaseeJDName, Aliasee] = AliaseeExpr.split(Separator: ':');
2105 if (Aliasee.empty())
2106 std::swap(a&: AliaseeJDName, b&: Aliasee);
2107
2108 if (AliaseeJDName.empty() && !AliasJDName.empty())
2109 AliaseeJDName = AliasJDName;
2110 auto AliaseeJD = GetJD(AliaseeJDName);
2111 if (!AliaseeJD)
2112 return AliaseeJD.takeError();
2113
2114 Reexports[{*AliasJD, *AliaseeJD}][S.ES.intern(SymName: Alias)] = {
2115 S.ES.intern(SymName: Aliasee), JITSymbolFlags::Exported};
2116 }
2117 }
2118
2119 for (auto &[JDs, AliasMap] : Reexports) {
2120 auto [DstJD, SrcJD] = JDs;
2121 if (auto Err = DstJD->define(MU: reexports(SourceJD&: *SrcJD, Aliases: std::move(AliasMap))))
2122 return Err;
2123 }
2124
2125 return Error::success();
2126}
2127
2128static Error addSectCreates(Session &S,
2129 const std::map<unsigned, JITDylib *> &IdxToJD) {
2130 for (auto SCItr = SectCreate.begin(), SCEnd = SectCreate.end();
2131 SCItr != SCEnd; ++SCItr) {
2132
2133 unsigned SCArgIdx = SectCreate.getPosition(optnum: SCItr - SectCreate.begin());
2134 auto &JD = *std::prev(x: IdxToJD.lower_bound(x: SCArgIdx))->second;
2135
2136 StringRef SCArg(*SCItr);
2137
2138 auto [SectAndFileName, ExtraSymbolsString] = SCArg.rsplit(Separator: '@');
2139 auto [SectName, FileName] = SectAndFileName.rsplit(Separator: ',');
2140 if (SectName.empty())
2141 return make_error<StringError>(Args: "In -sectcreate=" + SCArg +
2142 ", filename component cannot be empty",
2143 Args: inconvertibleErrorCode());
2144 if (FileName.empty())
2145 return make_error<StringError>(Args: "In -sectcreate=" + SCArg +
2146 ", filename component cannot be empty",
2147 Args: inconvertibleErrorCode());
2148
2149 auto Content = getFile(FileName);
2150 if (!Content)
2151 return Content.takeError();
2152
2153 SectCreateMaterializationUnit::ExtraSymbolsMap ExtraSymbols;
2154 while (!ExtraSymbolsString.empty()) {
2155 StringRef NextSymPair;
2156 std::tie(args&: NextSymPair, args&: ExtraSymbolsString) = ExtraSymbolsString.split(Separator: ',');
2157
2158 auto [Sym, OffsetString] = NextSymPair.split(Separator: '=');
2159 size_t Offset;
2160
2161 if (OffsetString.getAsInteger(Radix: 0, Result&: Offset))
2162 return make_error<StringError>(Args: "In -sectcreate=" + SCArg + ", " +
2163 OffsetString +
2164 " is not a valid integer",
2165 Args: inconvertibleErrorCode());
2166
2167 ExtraSymbols[S.ES.intern(SymName: Sym)] = {.Flags: JITSymbolFlags::Exported, .Offset: Offset};
2168 }
2169
2170 if (auto Err = JD.define(MU: std::make_unique<SectCreateMaterializationUnit>(
2171 args&: *S.ObjLayer, args: SectName.str(), args: MemProt::Read, args: 16, args: std::move(*Content),
2172 args: std::move(ExtraSymbols))))
2173 return Err;
2174 }
2175
2176 return Error::success();
2177}
2178
2179static Error addTestHarnesses(Session &S) {
2180 LLVM_DEBUG(dbgs() << "Adding test harness objects...\n");
2181 for (auto HarnessFile : TestHarnesses) {
2182 LLVM_DEBUG(dbgs() << " " << HarnessFile << "\n");
2183 auto Linkable = loadLinkableFile(Path: HarnessFile, TT: S.ES.getTargetTriple(),
2184 LA: LoadArchives::Never);
2185 if (!Linkable)
2186 return Linkable.takeError();
2187 if (auto Err = S.ObjLayer->add(JD&: *S.MainJD, O: std::move(Linkable->first)))
2188 return Err;
2189 }
2190 return Error::success();
2191}
2192
2193static Error addObjects(Session &S,
2194 const std::map<unsigned, JITDylib *> &IdxToJD,
2195 const DenseSet<unsigned> &LazyLinkIdxs) {
2196
2197 // Load each object into the corresponding JITDylib..
2198 LLVM_DEBUG(dbgs() << "Adding objects...\n");
2199 for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();
2200 InputFileItr != InputFileEnd; ++InputFileItr) {
2201 unsigned InputFileArgIdx =
2202 InputFiles.getPosition(optnum: InputFileItr - InputFiles.begin());
2203 const std::string &InputFile = *InputFileItr;
2204 if (StringRef(InputFile).ends_with(Suffix: ".a") ||
2205 StringRef(InputFile).ends_with(Suffix: ".lib"))
2206 continue;
2207 auto &JD = *std::prev(x: IdxToJD.lower_bound(x: InputFileArgIdx))->second;
2208 bool AddLazy = LazyLinkIdxs.count(V: InputFileArgIdx);
2209 LLVM_DEBUG(dbgs() << " " << InputFileArgIdx << ": \"" << InputFile << "\" "
2210 << (AddLazy ? " (lazy-linked)" : "") << " to "
2211 << JD.getName() << "\n";);
2212 auto ObjBuffer = loadLinkableFile(Path: InputFile, TT: S.ES.getTargetTriple(),
2213 LA: LoadArchives::Never);
2214 if (!ObjBuffer)
2215 return ObjBuffer.takeError();
2216
2217 if (S.HarnessFiles.empty()) {
2218 if (auto Err =
2219 S.getLinkLayer(Lazy: AddLazy).add(JD, O: std::move(ObjBuffer->first)))
2220 return Err;
2221 } else {
2222 // We're in -harness mode. Use a custom interface for this
2223 // test object.
2224 auto ObjInterface =
2225 getTestObjectFileInterface(S, O: ObjBuffer->first->getMemBufferRef());
2226 if (!ObjInterface)
2227 return ObjInterface.takeError();
2228
2229 if (auto Err = S.ObjLayer->add(JD, O: std::move(ObjBuffer->first),
2230 I: std::move(*ObjInterface)))
2231 return Err;
2232 }
2233 }
2234
2235 return Error::success();
2236}
2237
2238static Expected<MaterializationUnit::Interface>
2239getObjectFileInterfaceHidden(ExecutionSession &ES, MemoryBufferRef ObjBuffer) {
2240 auto I = getObjectFileInterface(ES, ObjBuffer);
2241 if (I) {
2242 for (auto &KV : I->SymbolFlags)
2243 KV.second &= ~JITSymbolFlags::Exported;
2244 }
2245 return I;
2246}
2247
2248static SmallVector<StringRef, 5> getSearchPathsFromEnvVar(Session &S) {
2249 // FIXME: Handle EPC environment.
2250 SmallVector<StringRef, 5> PathVec;
2251 auto TT = S.ES.getTargetTriple();
2252 if (TT.isOSBinFormatCOFF())
2253 StringRef(getenv(name: "PATH")).split(A&: PathVec, Separator: ";");
2254 else if (TT.isOSBinFormatELF())
2255 StringRef(getenv(name: "LD_LIBRARY_PATH")).split(A&: PathVec, Separator: ":");
2256
2257 return PathVec;
2258}
2259
2260static Expected<std::unique_ptr<DefinitionGenerator>>
2261LoadLibraryWeak(Session &S, StringRef Path) {
2262 auto Symbols = getDylibInterface(ES&: S.ES, Path);
2263 if (!Symbols)
2264 return Symbols.takeError();
2265
2266 return std::make_unique<EPCDynamicLibrarySearchGenerator>(
2267 args&: S.ES, args&: *S.DylibMgr,
2268 args: [Symbols = std::move(*Symbols)](const SymbolStringPtr &Sym) {
2269 return Symbols.count(V: Sym);
2270 });
2271}
2272
2273static Error addLibraries(Session &S,
2274 const std::map<unsigned, JITDylib *> &IdxToJD,
2275 const DenseSet<unsigned> &LazyLinkIdxs) {
2276
2277 // 1. Collect search paths for each JITDylib.
2278 DenseMap<const JITDylib *, SmallVector<StringRef, 2>> JDSearchPaths;
2279
2280 for (auto LSPItr = LibrarySearchPaths.begin(),
2281 LSPEnd = LibrarySearchPaths.end();
2282 LSPItr != LSPEnd; ++LSPItr) {
2283 unsigned LibrarySearchPathIdx =
2284 LibrarySearchPaths.getPosition(optnum: LSPItr - LibrarySearchPaths.begin());
2285 auto &JD = *std::prev(x: IdxToJD.lower_bound(x: LibrarySearchPathIdx))->second;
2286
2287 StringRef LibrarySearchPath = *LSPItr;
2288 if (sys::fs::get_file_type(Path: LibrarySearchPath) !=
2289 sys::fs::file_type::directory_file)
2290 return make_error<StringError>(Args: "While linking " + JD.getName() + ", -L" +
2291 LibrarySearchPath +
2292 " does not point to a directory",
2293 Args: inconvertibleErrorCode());
2294
2295 JDSearchPaths[&JD].push_back(Elt: *LSPItr);
2296 }
2297
2298 LLVM_DEBUG({
2299 if (!JDSearchPaths.empty())
2300 dbgs() << "Search paths:\n";
2301 for (auto &KV : JDSearchPaths) {
2302 dbgs() << " " << KV.first->getName() << ": [";
2303 for (auto &LibSearchPath : KV.second)
2304 dbgs() << " \"" << LibSearchPath << "\"";
2305 dbgs() << " ]\n";
2306 }
2307 });
2308
2309 // 2. Collect library loads
2310 struct LibraryLoad {
2311 std::string LibName;
2312 bool IsPath = false;
2313 unsigned Position;
2314 ArrayRef<StringRef> CandidateExtensions;
2315 enum { Standard, Hidden, Weak } Modifier;
2316 };
2317
2318 // Queue to load library as in the order as it appears in the argument list.
2319 std::deque<LibraryLoad> LibraryLoadQueue;
2320
2321 // Add archive files from the inputs to LibraryLoads.
2322 for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();
2323 InputFileItr != InputFileEnd; ++InputFileItr) {
2324 StringRef InputFile = *InputFileItr;
2325 if (!InputFile.ends_with(Suffix: ".a") && !InputFile.ends_with(Suffix: ".lib"))
2326 continue;
2327 LibraryLoad LL;
2328 LL.LibName = InputFile.str();
2329 LL.IsPath = true;
2330 LL.Position = InputFiles.getPosition(optnum: InputFileItr - InputFiles.begin());
2331 LL.CandidateExtensions = {};
2332 LL.Modifier = LibraryLoad::Standard;
2333 LibraryLoadQueue.push_back(x: std::move(LL));
2334 }
2335
2336 // Add -load_hidden arguments to LibraryLoads.
2337 for (auto LibItr = LoadHidden.begin(), LibEnd = LoadHidden.end();
2338 LibItr != LibEnd; ++LibItr) {
2339 LibraryLoad LL;
2340 LL.LibName = *LibItr;
2341 LL.IsPath = true;
2342 LL.Position = LoadHidden.getPosition(optnum: LibItr - LoadHidden.begin());
2343 LL.CandidateExtensions = {};
2344 LL.Modifier = LibraryLoad::Hidden;
2345 LibraryLoadQueue.push_back(x: std::move(LL));
2346 }
2347
2348 // Add -weak_library arguments to LibraryLoads.
2349 for (auto LibItr = WeakLibraries.begin(), LibEnd = WeakLibraries.end();
2350 LibItr != LibEnd; ++LibItr) {
2351 LibraryLoad LL;
2352 LL.LibName = *LibItr;
2353 LL.IsPath = true;
2354 LL.Position = WeakLibraries.getPosition(optnum: LibItr - WeakLibraries.begin());
2355 LL.CandidateExtensions = {};
2356 LL.Modifier = LibraryLoad::Weak;
2357 LibraryLoadQueue.push_back(x: std::move(LL));
2358 }
2359
2360 StringRef StandardExtensions[] = {".so", ".dylib", ".dll", ".a", ".lib"};
2361 StringRef DynLibExtensionsOnly[] = {".so", ".dylib", ".dll"};
2362 StringRef ArchiveExtensionsOnly[] = {".a", ".lib"};
2363 StringRef WeakLinkExtensionsOnly[] = {".dylib", ".tbd"};
2364
2365 // Add -lx arguments to LibraryLoads.
2366 for (auto LibItr = Libraries.begin(), LibEnd = Libraries.end();
2367 LibItr != LibEnd; ++LibItr) {
2368 LibraryLoad LL;
2369 LL.LibName = *LibItr;
2370 LL.Position = Libraries.getPosition(optnum: LibItr - Libraries.begin());
2371 LL.CandidateExtensions = StandardExtensions;
2372 LL.Modifier = LibraryLoad::Standard;
2373 LibraryLoadQueue.push_back(x: std::move(LL));
2374 }
2375
2376 // Add -hidden-lx arguments to LibraryLoads.
2377 for (auto LibHiddenItr = LibrariesHidden.begin(),
2378 LibHiddenEnd = LibrariesHidden.end();
2379 LibHiddenItr != LibHiddenEnd; ++LibHiddenItr) {
2380 LibraryLoad LL;
2381 LL.LibName = *LibHiddenItr;
2382 LL.Position =
2383 LibrariesHidden.getPosition(optnum: LibHiddenItr - LibrariesHidden.begin());
2384 LL.CandidateExtensions = ArchiveExtensionsOnly;
2385 LL.Modifier = LibraryLoad::Hidden;
2386 LibraryLoadQueue.push_back(x: std::move(LL));
2387 }
2388
2389 // Add -weak-lx arguments to LibraryLoads.
2390 for (auto LibWeakItr = LibrariesWeak.begin(),
2391 LibWeakEnd = LibrariesWeak.end();
2392 LibWeakItr != LibWeakEnd; ++LibWeakItr) {
2393 LibraryLoad LL;
2394 LL.LibName = *LibWeakItr;
2395 LL.Position = LibrariesWeak.getPosition(optnum: LibWeakItr - LibrariesWeak.begin());
2396 LL.CandidateExtensions = WeakLinkExtensionsOnly;
2397 LL.Modifier = LibraryLoad::Weak;
2398 LibraryLoadQueue.push_back(x: std::move(LL));
2399 }
2400
2401 // Sort library loads by position in the argument list.
2402 llvm::sort(C&: LibraryLoadQueue,
2403 Comp: [](const LibraryLoad &LHS, const LibraryLoad &RHS) {
2404 return LHS.Position < RHS.Position;
2405 });
2406
2407 // 3. Process library loads.
2408 auto AddArchive = [&](JITDylib &JD, const char *Path, const LibraryLoad &LL)
2409 -> Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>> {
2410 StaticLibraryDefinitionGenerator::GetObjectFileInterface
2411 GetObjFileInterface;
2412 switch (LL.Modifier) {
2413 case LibraryLoad::Standard:
2414 GetObjFileInterface = getObjectFileInterface;
2415 break;
2416 case LibraryLoad::Hidden:
2417 GetObjFileInterface = getObjectFileInterfaceHidden;
2418 S.HiddenArchives.insert(key: Path);
2419 break;
2420 case LibraryLoad::Weak:
2421 llvm_unreachable("Unsupported");
2422 break;
2423 }
2424
2425 auto &LinkLayer = S.getLinkLayer(Lazy: LazyLinkIdxs.count(V: LL.Position));
2426
2427 std::set<std::string> ImportedDynamicLibraries;
2428 StaticLibraryDefinitionGenerator::VisitMembersFunction VisitMembers;
2429
2430 // COFF gets special handling due to import libraries.
2431 if (S.ES.getTargetTriple().isOSBinFormatCOFF()) {
2432 if (AllLoad) {
2433 VisitMembers =
2434 [ImportScanner = COFFImportFileScanner(ImportedDynamicLibraries),
2435 LoadAll =
2436 StaticLibraryDefinitionGenerator::loadAllObjectFileMembers(
2437 L&: LinkLayer, JD)](object::Archive &A,
2438 MemoryBufferRef MemberBuf,
2439 size_t Index) mutable -> Expected<bool> {
2440 if (!ImportScanner(A, MemberBuf, Index))
2441 return false;
2442 return LoadAll(A, MemberBuf, Index);
2443 };
2444 } else
2445 VisitMembers = COFFImportFileScanner(ImportedDynamicLibraries);
2446 } else if (AllLoad)
2447 VisitMembers = StaticLibraryDefinitionGenerator::loadAllObjectFileMembers(
2448 L&: LinkLayer, JD);
2449 else if (S.ES.getTargetTriple().isOSBinFormatMachO() && ForceLoadObjC)
2450 VisitMembers = ForceLoadMachOArchiveMembers(LinkLayer, JD, true);
2451
2452 auto G = StaticLibraryDefinitionGenerator::Load(
2453 L&: LinkLayer, FileName: Path, VisitMembers: std::move(VisitMembers),
2454 GetObjFileInterface: std::move(GetObjFileInterface));
2455 if (!G)
2456 return G.takeError();
2457
2458 // Push additional dynamic libraries to search.
2459 // Note that this mechanism only happens in COFF.
2460 for (auto FileName : ImportedDynamicLibraries) {
2461 LibraryLoad NewLL;
2462 auto FileNameRef = StringRef(FileName);
2463 if (!FileNameRef.ends_with_insensitive(Suffix: ".dll"))
2464 return make_error<StringError>(
2465 Args: "COFF Imported library not ending with dll extension?",
2466 Args: inconvertibleErrorCode());
2467 NewLL.LibName = FileNameRef.drop_back(N: strlen(s: ".dll")).str();
2468 NewLL.Position = LL.Position;
2469 NewLL.CandidateExtensions = DynLibExtensionsOnly;
2470 NewLL.Modifier = LibraryLoad::Standard;
2471 LibraryLoadQueue.push_front(x: std::move(NewLL));
2472 }
2473 return G;
2474 };
2475
2476 SmallVector<StringRef, 5> SystemSearchPaths;
2477 if (SearchSystemLibrary.getValue())
2478 SystemSearchPaths = getSearchPathsFromEnvVar(S);
2479 while (!LibraryLoadQueue.empty()) {
2480 bool LibFound = false;
2481 auto LL = LibraryLoadQueue.front();
2482 LibraryLoadQueue.pop_front();
2483 auto &JD = *std::prev(x: IdxToJD.lower_bound(x: LL.Position))->second;
2484
2485 // If this is the name of a JITDylib then link against that.
2486 if (auto *LJD = S.ES.getJITDylibByName(Name: LL.LibName)) {
2487 if (LL.Modifier == LibraryLoad::Weak)
2488 return make_error<StringError>(
2489 Args: "Can't use -weak-lx or -weak_library to load JITDylib " +
2490 LL.LibName,
2491 Args: inconvertibleErrorCode());
2492 JD.addToLinkOrder(JD&: *LJD);
2493 continue;
2494 }
2495
2496 if (LL.IsPath) {
2497 // Must be -weak_library.
2498 if (LL.Modifier == LibraryLoad::Weak) {
2499 if (auto G = LoadLibraryWeak(S, Path: LL.LibName)) {
2500 JD.addGenerator(DefGenerator: std::move(*G));
2501 continue;
2502 } else
2503 return G.takeError();
2504 }
2505
2506 // Otherwise handle archive.
2507 auto G = AddArchive(JD, LL.LibName.c_str(), LL);
2508 if (!G)
2509 return createFileError(F: LL.LibName, E: G.takeError());
2510 JD.addGenerator(DefGenerator: std::move(*G));
2511 LLVM_DEBUG({
2512 dbgs() << "Adding generator for static library " << LL.LibName << " to "
2513 << JD.getName() << "\n";
2514 });
2515 continue;
2516 }
2517
2518 // Otherwise look through the search paths.
2519 auto CurJDSearchPaths = JDSearchPaths[&JD];
2520 for (StringRef SearchPath :
2521 concat<StringRef>(Ranges&: CurJDSearchPaths, Ranges&: SystemSearchPaths)) {
2522 for (auto LibExt : LL.CandidateExtensions) {
2523 SmallVector<char, 256> LibPath;
2524 LibPath.reserve(N: SearchPath.size() + strlen(s: "lib") + LL.LibName.size() +
2525 LibExt.size() + 2); // +2 for pathsep, null term.
2526 llvm::append_range(C&: LibPath, R&: SearchPath);
2527 if (LibExt != ".lib" && LibExt != ".dll")
2528 sys::path::append(path&: LibPath, a: "lib" + LL.LibName + LibExt);
2529 else
2530 sys::path::append(path&: LibPath, a: LL.LibName + LibExt);
2531 LibPath.push_back(Elt: '\0');
2532
2533 // Skip missing or non-regular paths.
2534 if (sys::fs::get_file_type(Path: LibPath.data()) !=
2535 sys::fs::file_type::regular_file) {
2536 continue;
2537 }
2538
2539 file_magic Magic;
2540 if (auto EC = identify_magic(path: LibPath, result&: Magic)) {
2541 // If there was an error loading the file then skip it.
2542 LLVM_DEBUG({
2543 dbgs() << "Library search found \"" << LibPath
2544 << "\", but could not identify file type (" << EC.message()
2545 << "). Skipping.\n";
2546 });
2547 continue;
2548 }
2549
2550 // We identified the magic. Assume that we can load it -- we'll reset
2551 // in the default case.
2552 LibFound = true;
2553 switch (Magic) {
2554 case file_magic::pecoff_executable:
2555 case file_magic::elf_shared_object:
2556 case file_magic::macho_dynamically_linked_shared_lib: {
2557 if (LL.Modifier == LibraryLoad::Weak) {
2558 if (auto G = LoadLibraryWeak(S, Path: LibPath.data()))
2559 JD.addGenerator(DefGenerator: std::move(*G));
2560 else
2561 return G.takeError();
2562 } else {
2563 if (auto Err = S.loadAndLinkDynamicLibrary(JD, LibPath: LibPath.data()))
2564 return Err;
2565 }
2566 break;
2567 }
2568 case file_magic::archive:
2569 case file_magic::macho_universal_binary: {
2570 auto G = AddArchive(JD, LibPath.data(), LL);
2571 if (!G)
2572 return G.takeError();
2573 JD.addGenerator(DefGenerator: std::move(*G));
2574 LLVM_DEBUG({
2575 dbgs() << "Adding generator for static library " << LibPath.data()
2576 << " to " << JD.getName() << "\n";
2577 });
2578 break;
2579 }
2580 case file_magic::tapi_file:
2581 assert(LL.Modifier == LibraryLoad::Weak &&
2582 "TextAPI file not being loaded as weak?");
2583 if (auto G = LoadLibraryWeak(S, Path: LibPath.data()))
2584 JD.addGenerator(DefGenerator: std::move(*G));
2585 else
2586 return G.takeError();
2587 break;
2588 default:
2589 // This file isn't a recognized library kind.
2590 LLVM_DEBUG({
2591 dbgs() << "Library search found \"" << LibPath
2592 << "\", but file type is not supported. Skipping.\n";
2593 });
2594 LibFound = false;
2595 break;
2596 }
2597 if (LibFound)
2598 break;
2599 }
2600 if (LibFound)
2601 break;
2602 }
2603
2604 if (!LibFound)
2605 return make_error<StringError>(Args: "While linking " + JD.getName() +
2606 ", could not find library for -l" +
2607 LL.LibName,
2608 Args: inconvertibleErrorCode());
2609 }
2610
2611 // Add platform and process symbols if available.
2612 for (auto &[Idx, JD] : IdxToJD) {
2613 if (S.PlatformJD)
2614 JD->addToLinkOrder(JD&: *S.PlatformJD);
2615 if (S.ProcessSymsJD)
2616 JD->addToLinkOrder(JD&: *S.ProcessSymsJD);
2617 }
2618
2619 return Error::success();
2620}
2621
2622static Error addSpeculationOrder(Session &S) {
2623
2624 if (SpeculateOrder.empty())
2625 return Error::success();
2626
2627 assert(S.LazyLinking && "SpeculateOrder set, but lazy linking not enabled");
2628 assert(S.LazyLinking->Speculator && "SpeculatoOrder set, but no speculator");
2629
2630 auto SpecOrderBuffer = getFile(FileName: SpeculateOrder);
2631 if (!SpecOrderBuffer)
2632 return SpecOrderBuffer.takeError();
2633
2634 StringRef LineStream((*SpecOrderBuffer)->getBuffer());
2635 std::vector<std::pair<std::string, SymbolStringPtr>> SpecOrder;
2636
2637 size_t LineNumber = 0;
2638 while (!LineStream.empty()) {
2639 ++LineNumber;
2640
2641 auto MakeSpecOrderErr = [&](StringRef Reason) {
2642 return make_error<StringError>(Args: "Error in speculation order file \"" +
2643 SpeculateOrder + "\" on line " +
2644 Twine(LineNumber) + ": " + Reason,
2645 Args: inconvertibleErrorCode());
2646 };
2647
2648 StringRef CurLine;
2649 std::tie(args&: CurLine, args&: LineStream) = LineStream.split(Separator: '\n');
2650 CurLine = CurLine.trim();
2651 if (CurLine.empty())
2652 continue;
2653
2654 auto [JDName, FuncName] = CurLine.split(Separator: ',');
2655
2656 if (FuncName.empty())
2657 return MakeSpecOrderErr("missing ',' separator");
2658
2659 JDName = JDName.trim();
2660 if (JDName.empty())
2661 return MakeSpecOrderErr("no value for column 1 (JIT Dylib name)");
2662
2663 FuncName = FuncName.trim();
2664 if (FuncName.empty())
2665 return MakeSpecOrderErr("no value for column 2 (function name)");
2666
2667 SpecOrder.push_back(x: {JDName.str(), S.ES.intern(SymName: FuncName)});
2668 }
2669
2670 S.LazyLinking->Speculator->addSpeculationSuggestions(NewSuggestions: std::move(SpecOrder));
2671
2672 return Error::success();
2673}
2674
2675static Error addSessionInputs(Session &S) {
2676 std::map<unsigned, JITDylib *> IdxToJD;
2677 DenseSet<unsigned> LazyLinkIdxs;
2678
2679 for (auto LLItr = LazyLink.begin(), LLEnd = LazyLink.end(); LLItr != LLEnd;
2680 ++LLItr) {
2681 if (*LLItr)
2682 LazyLinkIdxs.insert(V: LazyLink.getPosition(optnum: LLItr - LazyLink.begin()) + 1);
2683 }
2684
2685 if (auto Err = createJITDylibs(S, IdxToJD))
2686 return Err;
2687
2688 if (auto Err = addAbsoluteSymbols(S, IdxToJD))
2689 return Err;
2690
2691 if (auto Err = addAliases(S, IdxToJD))
2692 return Err;
2693
2694 if (auto Err = addSectCreates(S, IdxToJD))
2695 return Err;
2696
2697 if (!TestHarnesses.empty())
2698 if (auto Err = addTestHarnesses(S))
2699 return Err;
2700
2701 if (auto Err = addObjects(S, IdxToJD, LazyLinkIdxs))
2702 return Err;
2703
2704 if (auto Err = addLibraries(S, IdxToJD, LazyLinkIdxs))
2705 return Err;
2706
2707 if (auto Err = addSpeculationOrder(S))
2708 return Err;
2709
2710 return Error::success();
2711}
2712
2713namespace {
2714struct TargetInfo {
2715 const Target *TheTarget;
2716 std::unique_ptr<MCSubtargetInfo> STI;
2717 std::unique_ptr<MCRegisterInfo> MRI;
2718 std::unique_ptr<MCAsmInfo> MAI;
2719 std::unique_ptr<MCContext> Ctx;
2720 std::unique_ptr<MCDisassembler> Disassembler;
2721 std::unique_ptr<MCInstrInfo> MII;
2722 std::unique_ptr<MCInstrAnalysis> MIA;
2723 std::unique_ptr<MCInstPrinter> InstPrinter;
2724};
2725} // anonymous namespace
2726
2727static TargetInfo
2728getTargetInfo(const Triple &TT,
2729 const SubtargetFeatures &TF = SubtargetFeatures()) {
2730 std::string ErrorStr;
2731 const Target *TheTarget = TargetRegistry::lookupTarget(TheTriple: TT, Error&: ErrorStr);
2732 if (!TheTarget)
2733 ExitOnErr(make_error<StringError>(Args: "Error accessing target '" + TT.str() +
2734 "': " + ErrorStr,
2735 Args: inconvertibleErrorCode()));
2736
2737 std::unique_ptr<MCSubtargetInfo> STI(
2738 TheTarget->createMCSubtargetInfo(TheTriple: TT, CPU: "", Features: TF.getString()));
2739 if (!STI)
2740 ExitOnErr(
2741 make_error<StringError>(Args: "Unable to create subtarget for " + TT.str(),
2742 Args: inconvertibleErrorCode()));
2743
2744 std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
2745 if (!MRI)
2746 ExitOnErr(make_error<StringError>(Args: "Unable to create target register info "
2747 "for " +
2748 TT.str(),
2749 Args: inconvertibleErrorCode()));
2750
2751 MCTargetOptions MCOptions;
2752 std::unique_ptr<MCAsmInfo> MAI(
2753 TheTarget->createMCAsmInfo(MRI: *MRI, TheTriple: TT, Options: MCOptions));
2754 if (!MAI)
2755 ExitOnErr(
2756 make_error<StringError>(Args: "Unable to create target asm info " + TT.str(),
2757 Args: inconvertibleErrorCode()));
2758
2759 auto Ctx = std::make_unique<MCContext>(args: Triple(TT.str()), args&: *MAI, args&: *MRI, args&: *STI);
2760
2761 std::unique_ptr<MCDisassembler> Disassembler(
2762 TheTarget->createMCDisassembler(STI: *STI, Ctx&: *Ctx));
2763 if (!Disassembler)
2764 ExitOnErr(
2765 make_error<StringError>(Args: "Unable to create disassembler for " + TT.str(),
2766 Args: inconvertibleErrorCode()));
2767
2768 std::unique_ptr<MCInstrInfo> MII(TheTarget->createMCInstrInfo());
2769 if (!MII)
2770 ExitOnErr(make_error<StringError>(Args: "Unable to create instruction info for" +
2771 TT.str(),
2772 Args: inconvertibleErrorCode()));
2773
2774 std::unique_ptr<MCInstrAnalysis> MIA(
2775 TheTarget->createMCInstrAnalysis(Info: MII.get()));
2776 if (!MIA)
2777 ExitOnErr(make_error<StringError>(
2778 Args: "Unable to create instruction analysis for" + TT.str(),
2779 Args: inconvertibleErrorCode()));
2780
2781 std::unique_ptr<MCInstPrinter> InstPrinter(
2782 TheTarget->createMCInstPrinter(T: Triple(TT.str()), SyntaxVariant: 0, MAI: *MAI, MII: *MII, MRI: *MRI));
2783 if (!InstPrinter)
2784 ExitOnErr(make_error<StringError>(
2785 Args: "Unable to create instruction printer for" + TT.str(),
2786 Args: inconvertibleErrorCode()));
2787 return {.TheTarget: TheTarget, .STI: std::move(STI), .MRI: std::move(MRI),
2788 .MAI: std::move(MAI), .Ctx: std::move(Ctx), .Disassembler: std::move(Disassembler),
2789 .MII: std::move(MII), .MIA: std::move(MIA), .InstPrinter: std::move(InstPrinter)};
2790}
2791static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
2792 if (CheckFiles.empty())
2793 return Error::success();
2794
2795 S.waitForFilesLinkedFromEntryPointFile();
2796
2797 LLVM_DEBUG(dbgs() << "Running checks...\n");
2798
2799 auto IsSymbolValid = [&S](StringRef Symbol) {
2800 auto InternedSymbol = S.ES.intern(SymName: Symbol);
2801 return S.isSymbolRegistered(SymbolName: InternedSymbol);
2802 };
2803
2804 auto GetSymbolInfo = [&S](StringRef Symbol) {
2805 auto InternedSymbol = S.ES.intern(SymName: Symbol);
2806 return S.findSymbolInfo(SymbolName: InternedSymbol, ErrorMsgStem: "Can not get symbol info");
2807 };
2808
2809 auto GetSectionInfo = [&S](StringRef FileName, StringRef SectionName) {
2810 return S.findSectionInfo(FileName, SectionName);
2811 };
2812
2813 auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName,
2814 StringRef KindNameFilter) {
2815 return S.findStubInfo(FileName, TargetName: SectionName, KindNameFilter);
2816 };
2817
2818 auto GetGOTInfo = [&S](StringRef FileName, StringRef SectionName) {
2819 return S.findGOTEntryInfo(FileName, TargetName: SectionName);
2820 };
2821
2822 RuntimeDyldChecker Checker(
2823 IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo,
2824 S.ES.getTargetTriple().isLittleEndian() ? llvm::endianness::little
2825 : llvm::endianness::big,
2826 TT, StringRef(), Features, dbgs());
2827
2828 std::string CheckLineStart = "# " + CheckName + ":";
2829 for (auto &CheckFile : CheckFiles) {
2830 auto CheckerFileBuf = ExitOnErr(getFile(FileName: CheckFile));
2831 if (!Checker.checkAllRulesInBuffer(RulePrefix: CheckLineStart, MemBuf: &*CheckerFileBuf))
2832 ExitOnErr(make_error<StringError>(
2833 Args: "Some checks in " + CheckFile + " failed", Args: inconvertibleErrorCode()));
2834 }
2835
2836 return Error::success();
2837}
2838
2839static Error addSelfRelocations(LinkGraph &G) {
2840 auto TI = getTargetInfo(TT: G.getTargetTriple());
2841 for (auto *Sym : G.defined_symbols())
2842 if (Sym->isCallable())
2843 if (auto Err = addFunctionPointerRelocationsToCurrentSymbol(
2844 Sym&: *Sym, G, Disassembler&: *TI.Disassembler, MIA&: *TI.MIA))
2845 return Err;
2846 return Error::success();
2847}
2848
2849static Expected<ExecutorSymbolDef> getMainEntryPoint(Session &S) {
2850 return S.ES.lookup(SearchOrder: S.JDSearchOrder, Symbol: S.ES.intern(SymName: EntryPointName));
2851}
2852
2853static Expected<ExecutorSymbolDef> getOrcRuntimeEntryPoint(Session &S) {
2854 std::string RuntimeEntryPoint = "__orc_rt_run_program_wrapper";
2855 if (S.ES.getTargetTriple().getObjectFormat() == Triple::MachO)
2856 RuntimeEntryPoint = '_' + RuntimeEntryPoint;
2857 return S.ES.lookup(SearchOrder: S.JDSearchOrder, Symbol: S.ES.intern(SymName: RuntimeEntryPoint));
2858}
2859
2860static Expected<ExecutorSymbolDef> getEntryPoint(Session &S) {
2861 ExecutorSymbolDef EntryPoint;
2862
2863 // Find the entry-point function unconditionally, since we want to force
2864 // it to be materialized to collect stats.
2865 if (auto EP = getMainEntryPoint(S))
2866 EntryPoint = *EP;
2867 else
2868 return EP.takeError();
2869 LLVM_DEBUG({
2870 dbgs() << "Using entry point \"" << EntryPointName
2871 << "\": " << formatv("{0:x16}", EntryPoint.getAddress()) << "\n";
2872 });
2873
2874 // If we're running with the ORC runtime then replace the entry-point
2875 // with the __orc_rt_run_program symbol.
2876 if (!OrcRuntime.empty()) {
2877 if (auto EP = getOrcRuntimeEntryPoint(S))
2878 EntryPoint = *EP;
2879 else
2880 return EP.takeError();
2881 LLVM_DEBUG({
2882 dbgs() << "(called via __orc_rt_run_program_wrapper at "
2883 << formatv("{0:x16}", EntryPoint.getAddress()) << ")\n";
2884 });
2885 }
2886
2887 return EntryPoint;
2888}
2889
2890static Expected<int> runWithRuntime(Session &S, ExecutorAddr EntryPointAddr) {
2891 StringRef DemangledEntryPoint = EntryPointName;
2892 if (S.ES.getTargetTriple().getObjectFormat() == Triple::MachO &&
2893 DemangledEntryPoint.front() == '_')
2894 DemangledEntryPoint = DemangledEntryPoint.drop_front();
2895 using llvm::orc::shared::SPSString;
2896 using SPSRunProgramSig =
2897 int64_t(SPSString, SPSString, shared::SPSSequence<SPSString>);
2898 int64_t Result;
2899 if (auto Err = S.ES.callSPSWrapper<SPSRunProgramSig>(
2900 WrapperFnAddr: EntryPointAddr, WrapperCallArgs&: Result, WrapperCallArgs: S.MainJD->getName(), WrapperCallArgs&: DemangledEntryPoint,
2901 WrapperCallArgs&: static_cast<std::vector<std::string> &>(InputArgv)))
2902 return std::move(Err);
2903 return Result;
2904}
2905
2906static Expected<int> runWithoutRuntime(Session &S,
2907 ExecutorAddr EntryPointAddr) {
2908 return S.ES.getExecutorProcessControl().runAsMain(MainFnAddr: EntryPointAddr, Args: InputArgv);
2909}
2910
2911static Error symbolicateBacktraces() {
2912 auto Symtab = DumpedSymbolTable::Create(Path: SymbolicateWith);
2913 if (!Symtab)
2914 return Symtab.takeError();
2915
2916 for (auto InputFile : InputFiles) {
2917 auto BacktraceBuffer = MemoryBuffer::getFileOrSTDIN(Filename: InputFile);
2918 if (!BacktraceBuffer)
2919 return createFileError(F: InputFile, EC: BacktraceBuffer.getError());
2920
2921 outs() << Symtab->symbolicate(Backtrace: (*BacktraceBuffer)->getBuffer());
2922 }
2923
2924 return Error::success();
2925}
2926
2927static Error waitingOnGraphReplay() {
2928 // Warn about ignored options.
2929 {
2930 bool PrintedHeader = false;
2931 for (auto &[OptName, Opt] : cl::getRegisteredOptions()) {
2932 if (Opt == &WaitingOnGraphReplay)
2933 continue;
2934 if (Opt->getNumOccurrences()) {
2935 if (!PrintedHeader) {
2936 errs() << "Warning: Running in -waiting-on-graph-replay mode. "
2937 "The following options will be ignored:\n";
2938 PrintedHeader = true;
2939 }
2940 errs() << " " << OptName << "\n";
2941 }
2942 }
2943 }
2944
2945 // Read the replay buffer file.
2946 auto GraphOpsBuffer = getFile(FileName: WaitingOnGraphReplay);
2947 if (!GraphOpsBuffer)
2948 return GraphOpsBuffer.takeError();
2949
2950 using Replay = orc::detail::WaitingOnGraphOpReplay<uintptr_t, uintptr_t>;
2951 using Graph = typename Replay::Graph;
2952 using Replayer = typename Replay::Replayer;
2953
2954 std::vector<typename Replay::Op> RecordedOps;
2955
2956 // First read the buffer to build the Ops vector. Doing this up-front allows
2957 // us to avoid polluting the timings below with the cost of parsing.
2958 Error Err = Error::success();
2959 for (auto &Op :
2960 orc::detail::readWaitingOnGraphOpsFromBuffer<uintptr_t, uintptr_t>(
2961 InputBuffer: (*GraphOpsBuffer)->getBuffer(), Err))
2962 RecordedOps.push_back(x: std::move(Op));
2963 if (Err)
2964 return Err;
2965
2966 // Now replay the Ops:
2967 Graph G;
2968 Replayer R(G);
2969
2970 outs() << "Replaying WaitingOnGraph operations from " << WaitingOnGraphReplay
2971 << "...\n";
2972 auto ReplayStart = std::chrono::high_resolution_clock::now();
2973 for (auto &Op : RecordedOps)
2974 R.replay(O: std::move(Op));
2975 auto ReplayEnd = std::chrono::high_resolution_clock::now();
2976 std::chrono::duration<double> ReplayDiff = ReplayEnd - ReplayStart;
2977 outs() << ReplayDiff.count() << "s to replay " << RecordedOps.size()
2978 << " ops (wall-clock time)\n";
2979 return Error::success();
2980}
2981
2982namespace {
2983struct JITLinkTimers {
2984 TimerGroup JITLinkTG{"llvm-jitlink timers", "timers for llvm-jitlink phases"};
2985 Timer LoadObjectsTimer{"load", "time to load/add object files", JITLinkTG};
2986 Timer LinkTimer{"link", "time to link object files", JITLinkTG};
2987 Timer RunTimer{"run", "time to execute jitlink'd code", JITLinkTG};
2988};
2989} // namespace
2990
2991int main(int argc, char *argv[]) {
2992 InitLLVM X(argc, argv);
2993
2994 InitializeAllTargetInfos();
2995 InitializeAllTargetMCs();
2996 InitializeAllDisassemblers();
2997
2998 cl::HideUnrelatedOptions(Categories: {&JITLinkCategory, &getColorCategory()});
2999 cl::ParseCommandLineOptions(argc, argv, Overview: "llvm jitlink tool");
3000 ExitOnErr.setBanner(std::string(argv[0]) + ": ");
3001
3002 // Check for WaitingOnGraph replay mode.
3003 if (!WaitingOnGraphReplay.empty()) {
3004 ExitOnErr(waitingOnGraphReplay());
3005 return 0;
3006 }
3007
3008 /// If timers are enabled, create a JITLinkTimers instance.
3009 std::unique_ptr<JITLinkTimers> Timers =
3010 ShowTimes ? std::make_unique<JITLinkTimers>() : nullptr;
3011
3012 auto [TT, Features] = getFirstFileTripleAndFeatures();
3013 ExitOnErr(sanitizeArguments(TT, ArgV0: argv[0]));
3014
3015 if (!SymbolicateWith.empty()) {
3016 ExitOnErr(symbolicateBacktraces());
3017 return 0;
3018 }
3019
3020 auto S = ExitOnErr(Session::Create(TT, Features));
3021
3022 enableStatistics(S&: *S, UsingOrcRuntime: !OrcRuntime.empty());
3023
3024 {
3025 TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
3026 ExitOnErr(addSessionInputs(S&: *S));
3027 }
3028
3029 if (PhonyExternals)
3030 addPhonyExternalsGenerator(S&: *S);
3031
3032 if (ShowInitialExecutionSessionState)
3033 S->ES.dump(OS&: outs());
3034
3035 Expected<ExecutorSymbolDef> EntryPoint((ExecutorSymbolDef()));
3036 {
3037 ExpectedAsOutParameter<ExecutorSymbolDef> _(&EntryPoint);
3038 TimeRegion TR(Timers ? &Timers->LinkTimer : nullptr);
3039 EntryPoint = getEntryPoint(S&: *S);
3040 }
3041
3042 // Print any reports regardless of whether we succeeded or failed.
3043 if (ShowEntryExecutionSessionState)
3044 S->ES.dump(OS&: outs());
3045
3046 if (ShowAddrs)
3047 S->dumpSessionInfo(OS&: outs());
3048
3049 if (!EntryPoint) {
3050 if (Timers)
3051 Timers->JITLinkTG.printAll(OS&: errs());
3052 reportLLVMJITLinkError(Err: EntryPoint.takeError());
3053 ExitOnErr(S->ES.endSession());
3054 exit(status: 1);
3055 }
3056
3057 ExitOnErr(runChecks(S&: *S, TT: std::move(TT), Features: std::move(Features)));
3058
3059 int Result = 0;
3060 if (!NoExec) {
3061 LLVM_DEBUG(dbgs() << "Running \"" << EntryPointName << "\"...\n");
3062 TimeRegion TR(Timers ? &Timers->RunTimer : nullptr);
3063 if (!OrcRuntime.empty())
3064 Result = ExitOnErr(runWithRuntime(S&: *S, EntryPointAddr: EntryPoint->getAddress()));
3065 else
3066 Result = ExitOnErr(runWithoutRuntime(S&: *S, EntryPointAddr: EntryPoint->getAddress()));
3067 }
3068
3069 // Destroy the session.
3070 ExitOnErr(S->ES.endSession());
3071 S.reset();
3072
3073 if (Timers)
3074 Timers->JITLinkTG.printAll(OS&: errs());
3075
3076 // If the executing code set a test result override then use that.
3077 if (UseTestResultOverride)
3078 Result = TestResultOverride;
3079
3080 return Result;
3081}
3082