[llvm] 5255ca9 - [llvm-jitlink] Update handling of library options.
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 14 18:50:00 PST 2021
Author: Lang Hames
Date: 2021-12-15T13:49:30+11:00
New Revision: 5255ca9726e9734eae5115488517175f9c94c9de
URL: https://github.com/llvm/llvm-project/commit/5255ca9726e9734eae5115488517175f9c94c9de
DIFF: https://github.com/llvm/llvm-project/commit/5255ca9726e9734eae5115488517175f9c94c9de.diff
LOG: [llvm-jitlink] Update handling of library options.
Adds -L<search-path> and -l<library> options that are analogous to ld's
versions.
Each instance of -L<search-path> or -l<library> will apply to the most recent
-jd option on the command line (-jd <name> creates a JITDylib with the given
name). Library names will match against JITDylibs first, then llvm-jitlink will
look through the search paths for files named <search-path>/lib<library>.dylib
or <search-path>/lib<library>.a.
The default "main" JITDylib will link against all JITDylibs created by -jd
options, and all JITDylibs will link against the process symbols (unless
-no-process-symbols is specified).
The -dlopen option is renamed -preload, and will load dylibs into the JITDylib
for the ORC runtime only.
The effect of these changes is to make it easier to describe a non-trivial
program layout to llvm-jitlink for testing purposes. E.g. the following
invocation describes a program consisting of three JITDylibs: "main" (created
implicitly) containing main.o, "Foo" containing foo1.o and foo2.o, and linking
against library "bar" (not a JITDylib, so it must be a .dylib or .a on disk)
and "Baz" (which is a JITDylib), and "Baz" containing baz.o.
llvm-jitlink \
main.o \
-jd Foo foo1.o foo2.o -L${HOME}/lib -lbar -lBaz
-jd Baz baz.o
Added:
llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_extra_def_strong.s
llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_extra_def_weak.s
llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s
Modified:
compiler-rt/test/orc/TestCases/Darwin/arm64/trivial-objc-methods.S
compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-objc-methods.S
compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S
llvm/test/ExecutionEngine/JITLink/X86/MachO_gdb_jit_nonzero_alignment_offsets.s
llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_definitions.s
llvm/tools/llvm-jitlink/llvm-jitlink.cpp
llvm/tools/llvm-jitlink/llvm-jitlink.h
Removed:
llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_strong_def_extra.s
llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_weak_defs_extra.s
################################################################################
diff --git a/compiler-rt/test/orc/TestCases/Darwin/arm64/trivial-objc-methods.S b/compiler-rt/test/orc/TestCases/Darwin/arm64/trivial-objc-methods.S
index 6c681efc6d803..1a0718c0b822c 100644
--- a/compiler-rt/test/orc/TestCases/Darwin/arm64/trivial-objc-methods.S
+++ b/compiler-rt/test/orc/TestCases/Darwin/arm64/trivial-objc-methods.S
@@ -1,5 +1,5 @@
// RUN: %clang -c -o %t %s
-// RUN: %llvm_jitlink -dlopen libobjc.A.dylib %t
+// RUN: %llvm_jitlink -preload libobjc.A.dylib %t
//
// Test that Objective-C class and instance methods work.
diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-objc-methods.S b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-objc-methods.S
index 5934630aeccf2..8e5f95cd27e56 100644
--- a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-objc-methods.S
+++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-objc-methods.S
@@ -1,5 +1,5 @@
// RUN: %clang -c -o %t %s
-// RUN: %llvm_jitlink -dlopen libobjc.A.dylib %t
+// RUN: %llvm_jitlink -preload libobjc.A.dylib %t
//
// Test that Objective-C class and instance methods work.
diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S
index 106bb5e9b8ed2..f6bb257bb46bf 100644
--- a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S
+++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-swift-types-section.S
@@ -1,5 +1,5 @@
# RUN: %clang -c -o %t %s
-# RUN: %llvm_jitlink -dlopen /usr/lib/swift/libswiftCore.dylib %t
+# RUN: %llvm_jitlink -preload /usr/lib/swift/libswiftCore.dylib %t
# REQUIRES: osx-swift-runtime
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_strong_def_extra.s b/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_extra_def_strong.s
similarity index 70%
rename from llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_strong_def_extra.s
rename to llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_extra_def_strong.s
index 15785ed0f69c7..260ffee4c5add 100644
--- a/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_strong_def_extra.s
+++ b/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_extra_def_strong.s
@@ -1,11 +1,11 @@
-# Supplies a strong definition of WeakDef.
+# Supplies a strong definition of ExtraDef.
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 14 sdk_version 10, 14
.section __DATA,__data
- .globl WeakDef
+ .globl ExtraDef
.p2align 2
-WeakDef:
+ExtraDef:
.long 3
.subsections_via_symbols
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_extra_def_weak.s b/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_extra_def_weak.s
new file mode 100644
index 0000000000000..200faed3fec57
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_extra_def_weak.s
@@ -0,0 +1,19 @@
+# Supplies a weak def of ExtraDef, and a pointer holding its address,
+# ExtraDefInExtraFile.
+
+ .section __TEXT,__text,regular,pure_instructions
+ .build_version macos, 10, 14 sdk_version 10, 14
+ .section __DATA,__data
+ .globl ExtraDef
+ .weak_definition ExtraDef
+ .p2align 2
+ExtraDef:
+ .long 2
+
+ .globl ExtraDefAddrInExtraFile
+ .p2align 3
+ExtraDefAddrInExtraFile:
+ .quad ExtraDef
+
+
+.subsections_via_symbols
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_weak_defs_extra.s b/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_weak_defs_extra.s
deleted file mode 100644
index b25bb8a3079ba..0000000000000
--- a/llvm/test/ExecutionEngine/JITLink/X86/Inputs/MachO_weak_defs_extra.s
+++ /dev/null
@@ -1,19 +0,0 @@
-# Supplies a weak def, WeakDef, and a pointer holding its address,
-# WeakDefAddrInExtraFile.
-
- .section __TEXT,__text,regular,pure_instructions
- .build_version macos, 10, 14 sdk_version 10, 14
- .section __DATA,__data
- .globl WeakDef
- .weak_definition WeakDef
- .p2align 2
-WeakDef:
- .long 2
-
- .globl WeakDefAddrInExtraFile
- .p2align 3
-WeakDefAddrInExtraFile:
- .quad WeakDef
-
-
-.subsections_via_symbols
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s
new file mode 100644
index 0000000000000..e3fea53e397b9
--- /dev/null
+++ b/llvm/test/ExecutionEngine/JITLink/X86/MachO_archive_support.s
@@ -0,0 +1,22 @@
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
+# RUN: -o %t/MachO_extra_def_strong.o %S/Inputs/MachO_extra_def_strong.s
+# RUN: llvm-ar crs %t/libExtraDef.a %t/MachO_extra_def_strong.o
+# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
+# RUN: -o %t/MachO_archive_support.o %s
+# RUN: llvm-jitlink -noexec %t/MachO_archive_support.o -lFoo -jd Foo -L%t -lExtraDef
+#
+# Test that archives can be loaded and referenced from other JITDylibs.
+
+ .section __TEXT,__text,regular,pure_instructions
+
+ .globl _main
+ .p2align 4, 0x90
+_main:
+ retq
+
+ .section __DATA,__data
+ .globl ExtraDefRef
+ .p2align 3
+ExtraDefRef:
+ .quad ExtraDef
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_gdb_jit_nonzero_alignment_offsets.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_gdb_jit_nonzero_alignment_offsets.s
index e8618e0868bb1..7f313b42f1bf3 100644
--- a/llvm/test/ExecutionEngine/JITLink/X86/MachO_gdb_jit_nonzero_alignment_offsets.s
+++ b/llvm/test/ExecutionEngine/JITLink/X86/MachO_gdb_jit_nonzero_alignment_offsets.s
@@ -1,18 +1,18 @@
# REQUIRES: system-darwin && asserts
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
-# RUN: -o %t/MachO_strong_def_extra.o %S/Inputs/MachO_strong_def_extra.s
+# RUN: -o %t/MachO_extra_def_strong.o %S/Inputs/MachO_extra_def_strong.s
# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
# RUN: -o %t/MachO_gdb_jit_nonzero_alignment_offsets.o %s
# RUN: llvm-jitlink -noexec -debugger-support \
# RUN: %t/MachO_gdb_jit_nonzero_alignment_offsets.o \
-# RUN: %t/MachO_strong_def_extra.o
+# RUN: %t/MachO_extra_def_strong.o
#
# Check that blocks with non-zero alignment offsets don't break debugging
# support.
#
-# In this test case the WeakDef symbol below will be overridden by a strong def
-# in MachO_strong_defs_extra.s. This will leave main (with alignment 16,
+# In this test case the ExtraDef symbol below will be overridden by a strong
+# def in MachO_strong_defs_extra.s. This will leave main (with alignment 16,
# alignment offset 4) as the only block in __TEXT,__text. The testcase ensures
# that the debugging support plugin doesn't crash or throw an error in this
# case.
@@ -20,10 +20,10 @@
.section __TEXT,__text,regular,pure_instructions
.p2align 4, 0x90
- .globl WeakDef
- .weak_definition WeakDef
+ .globl ExtraDef
+ .weak_definition ExtraDef
.p2align 2
-WeakDef:
+ExtraDef:
.long 42
.globl _main
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_definitions.s b/llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_definitions.s
index e6440130e1388..4a69ec06e57ae 100644
--- a/llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_definitions.s
+++ b/llvm/test/ExecutionEngine/JITLink/X86/MachO_weak_definitions.s
@@ -1,14 +1,14 @@
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
-# RUN: -o %t/MachO_weak_defs_extra.o %S/Inputs/MachO_weak_defs_extra.s
+# RUN: -o %t/MachO_extra_def_weak.o %S/Inputs/MachO_extra_def_weak.s
# RUN: llvm-mc -triple x86_64-apple-macosx10.9 -filetype=obj \
# RUN: -o %t/MachO_weak_definitions.o %s
# RUN: llvm-jitlink -noexec -check=%s %t/MachO_weak_definitions.o \
-# RUN: %t/MachO_weak_defs_extra.o
+# RUN: %t/MachO_extra_def_weak.o
#
# Check that objects linked separately agree on the address of weak symbols.
#
-# jitlink-check: *{8}WeakDefAddrInThisFile = *{8}WeakDefAddrInExtraFile
+# jitlink-check: *{8}ExtraDefAddrInThisFile = *{8}ExtraDefAddrInExtraFile
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 14 sdk_version 10, 14
@@ -18,22 +18,22 @@ _main:
retq
.section __DATA,__data
- .globl WeakDef
- .weak_definition WeakDef
+ .globl ExtraDef
+ .weak_definition ExtraDef
.p2align 2
-WeakDef:
+ExtraDef:
.long 1
- .globl WeakDefAddrInThisFile
+ .globl ExtraDefAddrInThisFile
.p2align 3
-WeakDefAddrInThisFile:
- .quad WeakDef
+ExtraDefAddrInThisFile:
+ .quad ExtraDef
-# Take the address of WeakDefAddrInExtraFile to force its materialization
+# Take the address of ExtraDefAddrInExtraFile to force its materialization
.globl extra_file_anchor
.p2align 3
extra_file_anchor:
- .quad WeakDefAddrInExtraFile
+ .quad ExtraDefAddrInExtraFile
.subsections_via_symbols
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 306fac9f77e7e..366944b506756 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -72,6 +72,16 @@ static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,
cl::desc("input files"),
cl::cat(JITLinkCategory));
+static cl::list<std::string>
+ LibrarySearchPaths("L",
+ cl::desc("Add dir to the list of library search paths"),
+ cl::Prefix, cl::cat(JITLinkCategory));
+
+static cl::list<std::string>
+ Libraries("l",
+ cl::desc("Link against library X in the library search paths"),
+ cl::Prefix, cl::cat(JITLinkCategory));
+
static cl::opt<bool> NoExec("noexec", cl::desc("Do not execute loaded code"),
cl::init(false), cl::cat(JITLinkCategory));
@@ -87,14 +97,16 @@ static cl::opt<std::string>
EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
cl::init(""), cl::cat(JITLinkCategory));
-static cl::list<std::string> JITLinkDylibs(
- "jld",
+static cl::list<std::string> JITDylibs(
+ "jd",
cl::desc("Specifies the JITDylib to be used for any subsequent "
- "input file arguments"),
+ "input file, -L<seacrh-path>, and -l<library> arguments"),
cl::cat(JITLinkCategory));
static cl::list<std::string>
- Dylibs("dlopen", cl::desc("Dynamic libraries to load before linking"),
+ Dylibs("preload",
+ cl::desc("Pre-load dynamic libraries (e.g. language runtimes "
+ "required by the ORC runtime)"),
cl::ZeroOrMore, cl::cat(JITLinkCategory));
static cl::list<std::string> InputArgv("args", cl::Positional,
@@ -128,6 +140,11 @@ static cl::opt<bool> ShowInitialExecutionSessionState(
cl::desc("Print ExecutionSession state before resolving entry point"),
cl::init(false), cl::cat(JITLinkCategory));
+static cl::opt<bool> ShowEntryExecutionSessionState(
+ "show-entry-es",
+ cl::desc("Print ExecutionSession state after resolving entry point"),
+ cl::init(false), cl::cat(JITLinkCategory));
+
static cl::opt<bool> ShowAddrs(
"show-addrs",
cl::desc("Print registered symbol, section, got and stub addresses"),
@@ -1278,95 +1295,48 @@ static void addPhonyExternalsGenerator(Session &S) {
S.MainJD->addGenerator(std::make_unique<PhonyExternalsGenerator>());
}
-static Error loadObjects(Session &S) {
- std::map<unsigned, JITDylib *> IdxToJLD;
-
+static Error createJITDylibs(Session &S,
+ std::map<unsigned, JITDylib *> &IdxToJD) {
// First, set up JITDylibs.
LLVM_DEBUG(dbgs() << "Creating JITDylibs...\n");
{
// Create a "main" JITLinkDylib.
- IdxToJLD[0] = S.MainJD;
+ IdxToJD[0] = S.MainJD;
S.JDSearchOrder.push_back({S.MainJD, JITDylibLookupFlags::MatchAllSymbols});
LLVM_DEBUG(dbgs() << " 0: " << S.MainJD->getName() << "\n");
- // Add any extra JITLinkDylibs from the command line.
- std::string JDNamePrefix("lib");
- for (auto JLDItr = JITLinkDylibs.begin(), JLDEnd = JITLinkDylibs.end();
- JLDItr != JLDEnd; ++JLDItr) {
- auto JD = S.ES.createJITDylib(JDNamePrefix + *JLDItr);
+ // Add any extra JITDylibs from the command line.
+ for (auto JDItr = JITDylibs.begin(), JDEnd = JITDylibs.end();
+ JDItr != JDEnd; ++JDItr) {
+ auto JD = S.ES.createJITDylib(*JDItr);
if (!JD)
return JD.takeError();
- unsigned JDIdx =
- JITLinkDylibs.getPosition(JLDItr - JITLinkDylibs.begin());
- IdxToJLD[JDIdx] = &*JD;
+ unsigned JDIdx = JITDylibs.getPosition(JDItr - JITDylibs.begin());
+ IdxToJD[JDIdx] = &*JD;
S.JDSearchOrder.push_back({&*JD, JITDylibLookupFlags::MatchAllSymbols});
LLVM_DEBUG(dbgs() << " " << JDIdx << ": " << JD->getName() << "\n");
}
-
- // Set every dylib to link against every other, in command line order,
- // using exported symbols only.
- for (auto &KV : S.JDSearchOrder) {
- auto *JD = KV.first;
- auto LookupFlags = JITDylibLookupFlags::MatchExportedSymbolsOnly;
- JITDylibSearchOrder LinkOrder;
- for (auto &KV2 : S.JDSearchOrder) {
- auto *JD2 = KV2.first;
- if (JD2 == JD)
- continue;
- LinkOrder.push_back(std::make_pair(JD2, LookupFlags));
- }
- JD->setLinkOrder(std::move(LinkOrder));
- }
}
- LLVM_DEBUG(dbgs() << "Adding test harness objects...\n");
- for (auto HarnessFile : TestHarnesses) {
- LLVM_DEBUG(dbgs() << " " << HarnessFile << "\n");
- auto ObjBuffer =
- ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(HarnessFile)));
- ExitOnErr(S.ObjLayer.add(*S.MainJD, std::move(ObjBuffer)));
- }
+ LLVM_DEBUG({
+ dbgs() << "Dylib search order is [ ";
+ for (auto &KV : S.JDSearchOrder)
+ dbgs() << KV.first->getName() << " ";
+ dbgs() << "]\n";
+ });
- // Load each object into the corresponding JITDylib..
- LLVM_DEBUG(dbgs() << "Adding objects...\n");
- for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();
- InputFileItr != InputFileEnd; ++InputFileItr) {
- unsigned InputFileArgIdx =
- InputFiles.getPosition(InputFileItr - InputFiles.begin());
- const std::string &InputFile = *InputFileItr;
- auto &JD = *std::prev(IdxToJLD.lower_bound(InputFileArgIdx))->second;
- LLVM_DEBUG(dbgs() << " " << InputFileArgIdx << ": \"" << InputFile
- << "\" to " << JD.getName() << "\n";);
- auto ObjBuffer =
- ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(InputFile)));
-
- auto Magic = identify_magic(ObjBuffer->getBuffer());
- if (Magic == file_magic::archive ||
- Magic == file_magic::macho_universal_binary)
- JD.addGenerator(ExitOnErr(StaticLibraryDefinitionGenerator::Load(
- S.ObjLayer, InputFile.c_str(),
- S.ES.getExecutorProcessControl().getTargetTriple())));
- else {
- if (S.HarnessFiles.empty())
- ExitOnErr(S.ObjLayer.add(JD, std::move(ObjBuffer)));
- else {
- // We're in -harness mode. Use a custom interface for this
- // test object.
- auto ObjInterface = ExitOnErr(
- getTestObjectFileInterface(S, ObjBuffer->getMemBufferRef()));
- ExitOnErr(
- S.ObjLayer.add(JD, std::move(ObjBuffer), std::move(ObjInterface)));
- }
- }
- }
+ return Error::success();
+}
+static Error addAbsoluteSymbols(Session &S,
+ const std::map<unsigned, JITDylib *> &IdxToJD) {
// Define absolute symbols.
LLVM_DEBUG(dbgs() << "Defining absolute symbols...\n");
for (auto AbsDefItr = AbsoluteDefs.begin(), AbsDefEnd = AbsoluteDefs.end();
AbsDefItr != AbsDefEnd; ++AbsDefItr) {
unsigned AbsDefArgIdx =
AbsoluteDefs.getPosition(AbsDefItr - AbsoluteDefs.begin());
- auto &JD = *std::prev(IdxToJLD.lower_bound(AbsDefArgIdx))->second;
+ auto &JD = *std::prev(IdxToJD.lower_bound(AbsDefArgIdx))->second;
StringRef AbsDefStmt = *AbsDefItr;
size_t EqIdx = AbsDefStmt.find_first_of('=');
@@ -1391,13 +1361,234 @@ static Error loadObjects(Session &S) {
S.SymbolInfos[Name] = {ArrayRef<char>(), Addr};
}
+ return Error::success();
+}
+
+static Error addTestHarnesses(Session &S) {
+ LLVM_DEBUG(dbgs() << "Adding test harness objects...\n");
+ for (auto HarnessFile : TestHarnesses) {
+ LLVM_DEBUG(dbgs() << " " << HarnessFile << "\n");
+ auto ObjBuffer = errorOrToExpected(MemoryBuffer::getFile(HarnessFile));
+ if (!ObjBuffer)
+ return ObjBuffer.takeError();
+ if (auto Err = S.ObjLayer.add(*S.MainJD, std::move(*ObjBuffer)))
+ return Err;
+ }
+ return Error::success();
+}
+
+static Error addObjects(Session &S,
+ const std::map<unsigned, JITDylib *> &IdxToJD) {
+
+ // Load each object into the corresponding JITDylib..
+ LLVM_DEBUG(dbgs() << "Adding objects...\n");
+ for (auto InputFileItr = InputFiles.begin(), InputFileEnd = InputFiles.end();
+ InputFileItr != InputFileEnd; ++InputFileItr) {
+ unsigned InputFileArgIdx =
+ InputFiles.getPosition(InputFileItr - InputFiles.begin());
+ const std::string &InputFile = *InputFileItr;
+ auto &JD = *std::prev(IdxToJD.lower_bound(InputFileArgIdx))->second;
+ LLVM_DEBUG(dbgs() << " " << InputFileArgIdx << ": \"" << InputFile
+ << "\" to " << JD.getName() << "\n";);
+ auto ObjBuffer = errorOrToExpected(MemoryBuffer::getFile(InputFile));
+ if (!ObjBuffer)
+ return ObjBuffer.takeError();
+
+ if (S.HarnessFiles.empty()) {
+ if (auto Err = S.ObjLayer.add(JD, std::move(*ObjBuffer)))
+ return Err;
+ } else {
+ // We're in -harness mode. Use a custom interface for this
+ // test object.
+ auto ObjInterface =
+ getTestObjectFileInterface(S, (*ObjBuffer)->getMemBufferRef());
+ if (!ObjInterface)
+ return ObjInterface.takeError();
+ if (auto Err = S.ObjLayer.add(JD, std::move(*ObjBuffer),
+ std::move(*ObjInterface)))
+ return Err;
+ }
+ }
+
+ return Error::success();
+}
+
+static Error addLibraries(Session &S,
+ const std::map<unsigned, JITDylib *> &IdxToJD) {
+
+ DenseMap<const JITDylib *, SmallVector<StringRef, 2>> JDSearchPaths;
+
+ for (auto LSPItr = LibrarySearchPaths.begin(),
+ LSPEnd = LibrarySearchPaths.end();
+ LSPItr != LSPEnd; ++LSPItr) {
+ unsigned LibrarySearchPathIdx =
+ LibrarySearchPaths.getPosition(LSPItr - LibrarySearchPaths.begin());
+ auto &JD = *std::prev(IdxToJD.lower_bound(LibrarySearchPathIdx))->second;
+
+ StringRef LibrarySearchPath = *LSPItr;
+ if (sys::fs::get_file_type(LibrarySearchPath) !=
+ sys::fs::file_type::directory_file)
+ return make_error<StringError>("While linking " + JD.getName() + ", -L" +
+ LibrarySearchPath +
+ " does not point to a directory",
+ inconvertibleErrorCode());
+
+ JDSearchPaths[&JD].push_back(*LSPItr);
+ }
+
LLVM_DEBUG({
- dbgs() << "Dylib search order is [ ";
- for (auto &KV : S.JDSearchOrder)
- dbgs() << KV.first->getName() << " ";
- dbgs() << "]\n";
+ if (!JDSearchPaths.empty())
+ dbgs() << "Search paths:\n";
+ for (auto &KV : JDSearchPaths) {
+ dbgs() << " " << KV.first->getName() << ": [";
+ for (auto &LibSearchPath : KV.second)
+ dbgs() << " \"" << LibSearchPath << "\"";
+ dbgs() << " ]\n";
+ }
});
+ for (auto LibItr = Libraries.begin(), LibEnd = Libraries.end();
+ LibItr != LibEnd; ++LibItr) {
+
+ bool LibFound = false;
+ StringRef LibName(*LibItr);
+ unsigned LibIdx = Libraries.getPosition(LibItr - Libraries.begin());
+ auto &JD = *std::prev(IdxToJD.lower_bound(LibIdx))->second;
+
+ // If this is the name of a JITDylib then link against that.
+ if (auto *LJD = S.ES.getJITDylibByName(LibName)) {
+ JD.addToLinkOrder(*LJD);
+ continue;
+ }
+
+ // Otherwise look through the search paths.
+ auto JDSearchPathsItr = JDSearchPaths.find(&JD);
+ if (JDSearchPathsItr != JDSearchPaths.end()) {
+ for (StringRef SearchPath : JDSearchPathsItr->second) {
+ for (const char *LibExt : {".dylib", ".so", ".a"}) {
+ SmallVector<char, 256> LibPath;
+ LibPath.reserve(SearchPath.size() + strlen("lib") + LibName.size() +
+ strlen(LibExt) + 2); // +2 for pathsep, null term.
+ llvm::copy(SearchPath, std::back_inserter(LibPath));
+ sys::path::append(LibPath, "lib" + LibName + LibExt);
+ LibPath.push_back('\0');
+
+ // Skip missing or non-regular paths.
+ if (sys::fs::get_file_type(LibPath.data()) !=
+ sys::fs::file_type::regular_file) {
+ continue;
+ }
+
+ file_magic Magic;
+ if (auto EC = identify_magic(LibPath, Magic)) {
+ // If there was an error loading the file then skip it.
+ LLVM_DEBUG({
+ dbgs() << "Library search found \"" << LibPath
+ << "\", but could not identify file type (" << EC.message()
+ << "). Skipping.\n";
+ });
+ continue;
+ }
+
+ // We identified the magic. Assume that we can load it -- we'll reset
+ // in the default case.
+ LibFound = true;
+ switch (Magic) {
+ case file_magic::elf_shared_object:
+ case file_magic::macho_dynamically_linked_shared_lib: {
+ // TODO: On first reference to LibPath this should create a JITDylib
+ // with a generator and add it to JD's links-against list. Subsquent
+ // references should use the JITDylib created on the first
+ // reference.
+ auto G =
+ EPCDynamicLibrarySearchGenerator::Load(S.ES, LibPath.data());
+ if (!G)
+ return G.takeError();
+ LLVM_DEBUG({
+ dbgs() << "Adding generator for dynamic library "
+ << LibPath.data() << " to " << JD.getName() << "\n";
+ });
+ JD.addGenerator(std::move(*G));
+ break;
+ }
+ case file_magic::archive:
+ case file_magic::macho_universal_binary: {
+ auto G = StaticLibraryDefinitionGenerator::Load(
+ S.ObjLayer, LibPath.data(),
+ S.ES.getExecutorProcessControl().getTargetTriple());
+ if (!G)
+ return G.takeError();
+ JD.addGenerator(std::move(*G));
+ LLVM_DEBUG({
+ dbgs() << "Adding generator for static library " << LibPath.data()
+ << " to " << JD.getName() << "\n";
+ });
+ break;
+ }
+ default:
+ // This file isn't a recognized library kind.
+ LLVM_DEBUG({
+ dbgs() << "Library search found \"" << LibPath
+ << "\", but file type is not supported. Skipping.\n";
+ });
+ LibFound = false;
+ break;
+ }
+ if (LibFound)
+ break;
+ }
+ if (LibFound)
+ break;
+ }
+ }
+
+ if (!LibFound)
+ return make_error<StringError>("While linking " + JD.getName() +
+ ", could not find library for -l" +
+ LibName,
+ inconvertibleErrorCode());
+ }
+
+ return Error::success();
+}
+
+static Error addProcessSymbols(Session &S,
+ const std::map<unsigned, JITDylib *> &IdxToJD) {
+
+ if (NoProcessSymbols)
+ return Error::success();
+
+ for (auto &KV : IdxToJD) {
+ auto &JD = *KV.second;
+ JD.addGenerator(ExitOnErr(
+ orc::EPCDynamicLibrarySearchGenerator::GetForTargetProcess(S.ES)));
+ }
+
+ return Error::success();
+}
+
+static Error addSessionInputs(Session &S) {
+ std::map<unsigned, JITDylib *> IdxToJD;
+
+ if (auto Err = createJITDylibs(S, IdxToJD))
+ return Err;
+
+ if (auto Err = addAbsoluteSymbols(S, IdxToJD))
+ return Err;
+
+ if (!TestHarnesses.empty())
+ if (auto Err = addTestHarnesses(S))
+ return Err;
+
+ if (auto Err = addObjects(S, IdxToJD))
+ return Err;
+
+ if (auto Err = addLibraries(S, IdxToJD))
+ return Err;
+
+ if (auto Err = addProcessSymbols(S, IdxToJD))
+ return Err;
+
return Error::success();
}
@@ -1613,7 +1804,7 @@ int main(int argc, char *argv[]) {
{
TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
- ExitOnErr(loadObjects(*S));
+ ExitOnErr(addSessionInputs(*S));
}
if (PhonyExternals)
@@ -1644,6 +1835,9 @@ int main(int argc, char *argv[]) {
}
}
+ if (ShowEntryExecutionSessionState)
+ S->ES.dump(outs());
+
if (ShowAddrs)
S->dumpSessionInfo(outs());
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.h b/llvm/tools/llvm-jitlink/llvm-jitlink.h
index 7873bcaa13d4c..15c62327c8280 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.h
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.h
@@ -36,6 +36,7 @@ struct Session {
orc::JITDylib *MainJD = nullptr;
orc::ObjectLinkingLayer ObjLayer;
orc::JITDylibSearchOrder JDSearchOrder;
+ std::vector<std::string> LibrarySearchPaths;
~Session();
More information about the llvm-commits
mailing list