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