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