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