Skip to content

Commit 3d0dd1a

Browse files
committed
[llvm-jitlink] Add Process and Platform JITDylibs, generalize alias option.
The Process JITDylib holds reflected process symbols. The Platform JITDylib holds ORC runtime symbols if the ORC runtime is loaded. The Platform and Process JITDylibs are appended to the link order of all other JITDylibs, including the main JITDylib, after any explicitly specified libraries. This scheme is similar to the one introduced in LLJIT in 371cb1a, and makes it easier to introduce aliases for process and platform symbols in a way that affects all JITDylibs uniformly. Since the Process and Platform JITDylibs are created implicitly the -alias option is generalized to allow source and destination JITDylibs to be explicitly specified, i.e. the -alias option now supports general re-exports. Testcases are updated to account for the change.
1 parent 989e8f9 commit 3d0dd1a

File tree

8 files changed

+172
-75
lines changed

8 files changed

+172
-75
lines changed

compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-data-reset.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
// RUN: %clang -c -o %t.main.o %p/Inputs/dlopen-dlclose-x2.S
44
// RUN: %clang -c -o %t.inits.o %s
55
// RUN: %llvm_jitlink \
6-
// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \
7-
// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \
6+
// RUN: -alias Platform:_dlopen=___orc_rt_macho_jit_dlopen \
7+
// RUN: -alias Platform:_dlclose=___orc_rt_macho_jit_dlclose \
88
// RUN: %t.main.o -jd inits %t.inits.o -lmain | FileCheck %s
99

1010
// CHECK: entering main

compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-trivial.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
// RUN: %clang -c -o %t.main.o %p/Inputs/dlopen-dlclose-x2.S
88
// RUN: %clang -c -o %t.inits.o %s
99
// RUN: %llvm_jitlink \
10-
// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \
11-
// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \
10+
// RUN: -alias Platform:_dlopen=___orc_rt_macho_jit_dlopen \
11+
// RUN: -alias Platform:_dlclose=___orc_rt_macho_jit_dlclose \
1212
// RUN: %t.main.o -jd inits %t.inits.o -lmain | FileCheck %s
1313

1414
// CHECK: entering main

compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen-nested.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
// RUN: %clang -c -o %t.inits.o %p/Inputs/standalone-ctor-and-cxa-atexit-dtor.S
66
// RUN: %clang -c -o %t.test.o %s
77
// RUN: %llvm_jitlink \
8-
// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \
9-
// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \
8+
// RUN: -alias Platform:_dlopen=___orc_rt_macho_jit_dlopen \
9+
// RUN: -alias Platform:_dlclose=___orc_rt_macho_jit_dlclose \
1010
// RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s
1111

1212
// CHECK: entering main

compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
// RUN: %clang -c -o %t.inits.o %p/Inputs/standalone-ctor-and-cxa-atexit-dtor.S
66
// RUN: %clang -c -o %t.test.o %s
77
// RUN: %llvm_jitlink \
8-
// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \
9-
// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \
8+
// RUN: -alias Platform:_dlopen=___orc_rt_macho_jit_dlopen \
9+
// RUN: -alias Platform:_dlclose=___orc_rt_macho_jit_dlclose \
1010
// RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s
1111

1212
// CHECK: entering main

compiler-rt/test/orc/TestCases/Windows/x86-64/trivial-jit-dlopen.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
// RUN: %clang_cl -MD -c -o %t.inits.o %p/Inputs/standalone-dylib.c
66
// RUN: %clang_cl -MD -c -o %t.test.o %s
77
// RUN: %llvm_jitlink \
8-
// RUN: -alias dlopen=__orc_rt_coff_jit_dlopen \
9-
// RUN: -alias dlclose=__orc_rt_coff_jit_dlclose \
8+
// RUN: -alias Platform:dlopen=__orc_rt_coff_jit_dlopen \
9+
// RUN: -alias Platform:dlclose=__orc_rt_coff_jit_dlclose \
1010
// RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s
1111

1212
// CHECK: entering main

llvm/test/ExecutionEngine/JITLink/AArch32/ELF_thumbv7_printf.s

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
// Check that main is a thumb symbol (with LSB set) and printf is arm (with LSB clear)
55
//
6-
// CHECK-LABEL: Symbol table:
6+
// CHECK-LABEL: JITDylib "main"
7+
// CHECK-NEXT: Link order: [ ("main", MatchAllSymbols), ("Process", MatchExportedSymbolsOnly) ]
8+
// CHECK-NEXT: Symbol table:
79
// CHECK-NEXT: "main": 0x{{[0-9a-f]+[13579bdf]}} [Callable] Ready
810
// CHECK-NEXT: "printf": 0x76bbe880 [Data] Ready
911

llvm/tools/llvm-jitlink/llvm-jitlink.cpp

Lines changed: 157 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -692,11 +692,12 @@ getTestObjectFileInterface(Session &S, MemoryBufferRef O) {
692692
}
693693

694694
static Error loadProcessSymbols(Session &S) {
695+
S.ProcessSymsJD = &S.ES.createBareJITDylib("Process");
695696
auto FilterMainEntryPoint =
696697
[EPName = S.ES.intern(EntryPointName)](SymbolStringPtr Name) {
697698
return Name != EPName;
698699
};
699-
S.MainJD->addGenerator(
700+
S.ProcessSymsJD->addGenerator(
700701
ExitOnErr(orc::EPCDynamicLibrarySearchGenerator::GetForTargetProcess(
701702
S.ES, std::move(FilterMainEntryPoint))));
702703

@@ -707,8 +708,9 @@ static Error loadDylibs(Session &S) {
707708
LLVM_DEBUG(dbgs() << "Loading dylibs...\n");
708709
for (const auto &Dylib : Dylibs) {
709710
LLVM_DEBUG(dbgs() << " " << Dylib << "\n");
710-
if (auto Err = S.loadAndLinkDynamicLibrary(*S.MainJD, Dylib))
711-
return Err;
711+
auto DL = S.getOrLoadDynamicLibrary(Dylib);
712+
if (!DL)
713+
return DL.takeError();
712714
}
713715

714716
return Error::success();
@@ -963,69 +965,79 @@ Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err)
963965

964966
ES.setErrorReporter(reportLLVMJITLinkError);
965967

966-
if (auto MainJDOrErr = ES.createJITDylib("main"))
967-
MainJD = &*MainJDOrErr;
968-
else {
969-
Err = MainJDOrErr.takeError();
970-
return;
971-
}
972-
973968
if (!NoProcessSymbols)
974969
ExitOnErr(loadProcessSymbols(*this));
975-
else {
976-
// This symbol is used in testcases.
977-
auto &TestResultJD = ES.createBareJITDylib("<TestResultJD>");
978-
ExitOnErr(TestResultJD.define(absoluteSymbols(
979-
{{ES.intern("llvm_jitlink_setTestResultOverride"),
980-
{ExecutorAddr::fromPtr(llvm_jitlink_setTestResultOverride),
981-
JITSymbolFlags::Exported}}})));
982-
MainJD->addToLinkOrder(TestResultJD);
983-
}
984970

985971
ExitOnErr(loadDylibs(*this));
986972

987973
auto &TT = ES.getTargetTriple();
988974

989-
if (DebuggerSupport && TT.isOSBinFormatMachO())
990-
ObjLayer.addPlugin(ExitOnErr(
991-
GDBJITDebugInfoRegistrationPlugin::Create(this->ES, *MainJD, TT)));
975+
if (DebuggerSupport && TT.isOSBinFormatMachO()) {
976+
if (!ProcessSymsJD) {
977+
Err = make_error<StringError>("MachO debugging requires process symbols",
978+
inconvertibleErrorCode());
979+
return;
980+
}
981+
ObjLayer.addPlugin(ExitOnErr(GDBJITDebugInfoRegistrationPlugin::Create(
982+
this->ES, *ProcessSymsJD, TT)));
983+
}
992984

993985
if (PerfSupport && TT.isOSBinFormatELF()) {
986+
if (!ProcessSymsJD) {
987+
Err = make_error<StringError>("MachO debugging requires process symbols",
988+
inconvertibleErrorCode());
989+
return;
990+
}
994991
ObjLayer.addPlugin(ExitOnErr(DebugInfoPreservationPlugin::Create()));
995992
ObjLayer.addPlugin(ExitOnErr(PerfSupportPlugin::Create(
996-
this->ES.getExecutorProcessControl(), *MainJD, true, true)));
993+
this->ES.getExecutorProcessControl(), *ProcessSymsJD, true, true)));
997994
}
998995

999996
// Set up the platform.
1000-
if (TT.isOSBinFormatMachO() && !OrcRuntime.empty()) {
1001-
if (auto P =
1002-
MachOPlatform::Create(ES, ObjLayer, *MainJD, OrcRuntime.c_str()))
1003-
ES.setPlatform(std::move(*P));
1004-
else {
1005-
Err = P.takeError();
1006-
return;
1007-
}
1008-
} else if (TT.isOSBinFormatELF() && !OrcRuntime.empty()) {
1009-
if (auto P =
1010-
ELFNixPlatform::Create(ES, ObjLayer, *MainJD, OrcRuntime.c_str()))
1011-
ES.setPlatform(std::move(*P));
1012-
else {
1013-
Err = P.takeError();
1014-
return;
1015-
}
1016-
} else if (TT.isOSBinFormatCOFF() && !OrcRuntime.empty()) {
1017-
auto LoadDynLibrary = [&, this](JITDylib &JD, StringRef DLLName) -> Error {
1018-
if (!DLLName.ends_with_insensitive(".dll"))
1019-
return make_error<StringError>("DLLName not ending with .dll",
1020-
inconvertibleErrorCode());
1021-
return loadAndLinkDynamicLibrary(JD, DLLName);
1022-
};
997+
if (!OrcRuntime.empty()) {
998+
assert(ProcessSymsJD && "ProcessSymsJD should have been set");
999+
PlatformJD = &ES.createBareJITDylib("Platform");
1000+
PlatformJD->addToLinkOrder(*ProcessSymsJD);
1001+
1002+
if (TT.isOSBinFormatMachO()) {
1003+
if (auto P = MachOPlatform::Create(ES, ObjLayer, *PlatformJD,
1004+
OrcRuntime.c_str()))
1005+
ES.setPlatform(std::move(*P));
1006+
else {
1007+
Err = P.takeError();
1008+
return;
1009+
}
1010+
} else if (TT.isOSBinFormatELF()) {
1011+
if (auto P = ELFNixPlatform::Create(ES, ObjLayer, *PlatformJD,
1012+
OrcRuntime.c_str()))
1013+
ES.setPlatform(std::move(*P));
1014+
else {
1015+
Err = P.takeError();
1016+
return;
1017+
}
1018+
} else if (TT.isOSBinFormatCOFF()) {
1019+
auto LoadDynLibrary = [&, this](JITDylib &JD,
1020+
StringRef DLLName) -> Error {
1021+
if (!DLLName.ends_with_insensitive(".dll"))
1022+
return make_error<StringError>("DLLName not ending with .dll",
1023+
inconvertibleErrorCode());
1024+
return loadAndLinkDynamicLibrary(JD, DLLName);
1025+
};
10231026

1024-
if (auto P = COFFPlatform::Create(ES, ObjLayer, *MainJD, OrcRuntime.c_str(),
1025-
std::move(LoadDynLibrary)))
1026-
ES.setPlatform(std::move(*P));
1027-
else {
1028-
Err = P.takeError();
1027+
if (auto P = COFFPlatform::Create(ES, ObjLayer, *PlatformJD,
1028+
OrcRuntime.c_str(),
1029+
std::move(LoadDynLibrary)))
1030+
ES.setPlatform(std::move(*P));
1031+
else {
1032+
Err = P.takeError();
1033+
return;
1034+
}
1035+
} else {
1036+
Err = make_error<StringError>(
1037+
"-" + OrcRuntime.ArgStr + " specified, but format " +
1038+
Triple::getObjectFormatTypeName(TT.getObjectFormat()) +
1039+
" not supported",
1040+
inconvertibleErrorCode());
10291041
return;
10301042
}
10311043
} else if (TT.isOSBinFormatELF()) {
@@ -1037,6 +1049,24 @@ Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err)
10371049
ES, ExitOnErr(createJITLoaderGDBRegistrar(this->ES)), true, true));
10381050
}
10391051

1052+
if (auto MainJDOrErr = ES.createJITDylib("main"))
1053+
MainJD = &*MainJDOrErr;
1054+
else {
1055+
Err = MainJDOrErr.takeError();
1056+
return;
1057+
}
1058+
1059+
if (NoProcessSymbols) {
1060+
// This symbol is used in testcases, but we're not reflecting process
1061+
// symbols so we'll need to make it available some other way.
1062+
auto &TestResultJD = ES.createBareJITDylib("<TestResultJD>");
1063+
ExitOnErr(TestResultJD.define(absoluteSymbols(
1064+
{{ES.intern("llvm_jitlink_setTestResultOverride"),
1065+
{ExecutorAddr::fromPtr(llvm_jitlink_setTestResultOverride),
1066+
JITSymbolFlags::Exported}}})));
1067+
MainJD->addToLinkOrder(TestResultJD);
1068+
}
1069+
10401070
ObjLayer.addPlugin(std::make_unique<JITLinkSessionPlugin>(*this));
10411071

10421072
// Process any harness files.
@@ -1266,6 +1296,10 @@ static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {
12661296
if (DebuggerSupport.getNumOccurrences() == 0 && NoExec)
12671297
DebuggerSupport = false;
12681298

1299+
if (!OrcRuntime.empty() && NoProcessSymbols)
1300+
return make_error<StringError>("-orc-runtime requires process symbols",
1301+
inconvertibleErrorCode());
1302+
12691303
// If -slab-allocate is passed, check that we're not trying to use it in
12701304
// -oop-executor or -oop-executor-connect mode.
12711305
//
@@ -1365,6 +1399,13 @@ static Error createJITDylibs(Session &S,
13651399
}
13661400
}
13671401

1402+
if (S.PlatformJD)
1403+
S.JDSearchOrder.push_back(
1404+
{S.PlatformJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});
1405+
if (S.ProcessSymsJD)
1406+
S.JDSearchOrder.push_back(
1407+
{S.ProcessSymsJD, JITDylibLookupFlags::MatchExportedSymbolsOnly});
1408+
13681409
LLVM_DEBUG({
13691410
dbgs() << "Dylib search order is [ ";
13701411
for (auto &KV : S.JDSearchOrder)
@@ -1416,23 +1457,67 @@ static Error addAliases(Session &S,
14161457
const std::map<unsigned, JITDylib *> &IdxToJD) {
14171458
// Define absolute symbols.
14181459
LLVM_DEBUG(dbgs() << "Defining aliases...\n");
1460+
1461+
DenseMap<std::pair<JITDylib *, JITDylib *>, SymbolAliasMap> Reexports;
14191462
for (auto AliasItr = Aliases.begin(), AliasEnd = Aliases.end();
14201463
AliasItr != AliasEnd; ++AliasItr) {
1421-
unsigned AliasArgIdx = Aliases.getPosition(AliasItr - Aliases.begin());
1422-
auto &JD = *std::prev(IdxToJD.lower_bound(AliasArgIdx))->second;
14231464

1424-
StringRef AliasStmt = *AliasItr;
1425-
size_t EqIdx = AliasStmt.find_first_of('=');
1426-
if (EqIdx == StringRef::npos)
1427-
return make_error<StringError>("Invalid alias definition \"" + AliasStmt +
1428-
"\". Syntax: <name>=<addr>",
1429-
inconvertibleErrorCode());
1430-
StringRef Alias = AliasStmt.substr(0, EqIdx).trim();
1431-
StringRef Aliasee = AliasStmt.substr(EqIdx + 1).trim();
1465+
auto BadExpr = [&]() {
1466+
return make_error<StringError>(
1467+
"Invalid alias definition \"" + *AliasItr +
1468+
"\". Syntax: [<dst-jd>:]<alias>=[<src-jd>:]<aliasee>",
1469+
inconvertibleErrorCode());
1470+
};
1471+
1472+
auto GetJD = [&](StringRef JDName) -> Expected<JITDylib *> {
1473+
if (JDName.empty()) {
1474+
unsigned AliasArgIdx = Aliases.getPosition(AliasItr - Aliases.begin());
1475+
return std::prev(IdxToJD.lower_bound(AliasArgIdx))->second;
1476+
}
1477+
1478+
auto *JD = S.ES.getJITDylibByName(JDName);
1479+
if (!JD)
1480+
return make_error<StringError>(StringRef("In alias definition \"") +
1481+
*AliasItr + "\" no dylib named " +
1482+
JDName,
1483+
inconvertibleErrorCode());
14321484

1433-
SymbolAliasMap SAM;
1434-
SAM[S.ES.intern(Alias)] = {S.ES.intern(Aliasee), JITSymbolFlags::Exported};
1435-
if (auto Err = JD.define(symbolAliases(std::move(SAM))))
1485+
return JD;
1486+
};
1487+
1488+
{
1489+
// First split on '=' to get alias and aliasee.
1490+
StringRef AliasStmt = *AliasItr;
1491+
auto [AliasExpr, AliaseeExpr] = AliasStmt.split('=');
1492+
if (AliaseeExpr.empty())
1493+
return BadExpr();
1494+
1495+
auto [AliasJDName, Alias] = AliasExpr.split(':');
1496+
if (Alias.empty())
1497+
std::swap(AliasJDName, Alias);
1498+
1499+
auto AliasJD = GetJD(AliasJDName);
1500+
if (!AliasJD)
1501+
return AliasJD.takeError();
1502+
1503+
auto [AliaseeJDName, Aliasee] = AliaseeExpr.split(':');
1504+
if (Aliasee.empty())
1505+
std::swap(AliaseeJDName, Aliasee);
1506+
1507+
if (AliaseeJDName.empty() && !AliasJDName.empty())
1508+
AliaseeJDName = AliasJDName;
1509+
auto AliaseeJD = GetJD(AliaseeJDName);
1510+
if (!AliaseeJD)
1511+
return AliaseeJD.takeError();
1512+
1513+
Reexports[{*AliasJD, *AliaseeJD}][S.ES.intern(Alias)] = {
1514+
S.ES.intern(Aliasee), JITSymbolFlags::Exported};
1515+
}
1516+
}
1517+
1518+
for (auto &[JDs, AliasMap] : Reexports) {
1519+
auto [DstJD, SrcJD] = JDs;
1520+
if (auto Err = DstJD->define(reexports(*SrcJD, std::move(AliasMap))))
14361521
return Err;
14371522
}
14381523

@@ -1766,6 +1851,14 @@ static Error addLibraries(Session &S,
17661851
inconvertibleErrorCode());
17671852
}
17681853

1854+
// Add platform and process symbols if available.
1855+
for (auto &[Idx, JD] : IdxToJD) {
1856+
if (S.PlatformJD)
1857+
JD->addToLinkOrder(*S.PlatformJD);
1858+
if (S.ProcessSymsJD)
1859+
JD->addToLinkOrder(*S.ProcessSymsJD);
1860+
}
1861+
17691862
return Error::success();
17701863
}
17711864

llvm/tools/llvm-jitlink/llvm-jitlink.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ struct Session {
3131

3232
orc::ExecutionSession ES;
3333
orc::JITDylib *MainJD = nullptr;
34+
orc::JITDylib *ProcessSymsJD = nullptr;
35+
orc::JITDylib *PlatformJD = nullptr;
3436
orc::ObjectLinkingLayer ObjLayer;
3537
orc::JITDylibSearchOrder JDSearchOrder;
3638
SubtargetFeatures Features;

0 commit comments

Comments
 (0)