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