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