diff options
8 files changed, 172 insertions, 75 deletions
diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-data-reset.S b/compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-data-reset.S index 8582c9e..6b8e17d 100644 --- a/compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-data-reset.S +++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-data-reset.S @@ -3,8 +3,8 @@ // RUN: %clang -c -o %t.main.o %p/Inputs/dlopen-dlclose-x2.S // RUN: %clang -c -o %t.inits.o %s // RUN: %llvm_jitlink \ -// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \ -// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \ +// RUN: -alias Platform:_dlopen=___orc_rt_macho_jit_dlopen \ +// RUN: -alias Platform:_dlclose=___orc_rt_macho_jit_dlclose \ // RUN: %t.main.o -jd inits %t.inits.o -lmain | FileCheck %s // CHECK: entering main diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-trivial.S b/compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-trivial.S index e8f48ca..adc63f9 100644 --- a/compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-trivial.S +++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/jit-re-dlopen-trivial.S @@ -7,8 +7,8 @@ // RUN: %clang -c -o %t.main.o %p/Inputs/dlopen-dlclose-x2.S // RUN: %clang -c -o %t.inits.o %s // RUN: %llvm_jitlink \ -// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \ -// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \ +// RUN: -alias Platform:_dlopen=___orc_rt_macho_jit_dlopen \ +// RUN: -alias Platform:_dlclose=___orc_rt_macho_jit_dlclose \ // RUN: %t.main.o -jd inits %t.inits.o -lmain | FileCheck %s // CHECK: entering main diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen-nested.c b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen-nested.c index 49d9fb6..f4b49b2 100644 --- a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen-nested.c +++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen-nested.c @@ -5,8 +5,8 @@ // RUN: %clang -c -o %t.inits.o %p/Inputs/standalone-ctor-and-cxa-atexit-dtor.S // RUN: %clang -c -o %t.test.o %s // RUN: %llvm_jitlink \ -// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \ -// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \ +// RUN: -alias Platform:_dlopen=___orc_rt_macho_jit_dlopen \ +// RUN: -alias Platform:_dlclose=___orc_rt_macho_jit_dlclose \ // RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s // CHECK: entering main diff --git a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.c b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.c index ee9b989..a0007be9 100644 --- a/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.c +++ b/compiler-rt/test/orc/TestCases/Darwin/x86-64/trivial-jit-dlopen.c @@ -5,8 +5,8 @@ // RUN: %clang -c -o %t.inits.o %p/Inputs/standalone-ctor-and-cxa-atexit-dtor.S // RUN: %clang -c -o %t.test.o %s // RUN: %llvm_jitlink \ -// RUN: -alias _dlopen=___orc_rt_macho_jit_dlopen \ -// RUN: -alias _dlclose=___orc_rt_macho_jit_dlclose \ +// RUN: -alias Platform:_dlopen=___orc_rt_macho_jit_dlopen \ +// RUN: -alias Platform:_dlclose=___orc_rt_macho_jit_dlclose \ // RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s // CHECK: entering main diff --git a/compiler-rt/test/orc/TestCases/Windows/x86-64/trivial-jit-dlopen.c b/compiler-rt/test/orc/TestCases/Windows/x86-64/trivial-jit-dlopen.c index 6a9182b..fd17993 100644 --- a/compiler-rt/test/orc/TestCases/Windows/x86-64/trivial-jit-dlopen.c +++ b/compiler-rt/test/orc/TestCases/Windows/x86-64/trivial-jit-dlopen.c @@ -5,8 +5,8 @@ // RUN: %clang_cl -MD -c -o %t.inits.o %p/Inputs/standalone-dylib.c // RUN: %clang_cl -MD -c -o %t.test.o %s // RUN: %llvm_jitlink \ -// RUN: -alias dlopen=__orc_rt_coff_jit_dlopen \ -// RUN: -alias dlclose=__orc_rt_coff_jit_dlclose \ +// RUN: -alias Platform:dlopen=__orc_rt_coff_jit_dlopen \ +// RUN: -alias Platform:dlclose=__orc_rt_coff_jit_dlclose \ // RUN: %t.test.o -jd inits %t.inits.o -lmain | FileCheck %s // CHECK: entering main diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_thumbv7_printf.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_thumbv7_printf.s index 11a77c9..457ce6a 100644 --- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_thumbv7_printf.s +++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_thumbv7_printf.s @@ -3,7 +3,9 @@ // Check that main is a thumb symbol (with LSB set) and printf is arm (with LSB clear) // -// CHECK-LABEL: Symbol table: +// CHECK-LABEL: JITDylib "main" +// CHECK-NEXT: Link order: [ ("main", MatchAllSymbols), ("Process", MatchExportedSymbolsOnly) ] +// CHECK-NEXT: Symbol table: // CHECK-NEXT: "main": 0x{{[0-9a-f]+[13579bdf]}} [Callable] Ready // CHECK-NEXT: "printf": 0x76bbe880 [Data] Ready diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp index 17fb70f3..3d6247c 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -692,11 +692,12 @@ getTestObjectFileInterface(Session &S, MemoryBufferRef O) { } static Error loadProcessSymbols(Session &S) { + S.ProcessSymsJD = &S.ES.createBareJITDylib("Process"); auto FilterMainEntryPoint = [EPName = S.ES.intern(EntryPointName)](SymbolStringPtr Name) { return Name != EPName; }; - S.MainJD->addGenerator( + S.ProcessSymsJD->addGenerator( ExitOnErr(orc::EPCDynamicLibrarySearchGenerator::GetForTargetProcess( S.ES, std::move(FilterMainEntryPoint)))); @@ -707,8 +708,9 @@ static Error loadDylibs(Session &S) { LLVM_DEBUG(dbgs() << "Loading dylibs...\n"); for (const auto &Dylib : Dylibs) { LLVM_DEBUG(dbgs() << " " << Dylib << "\n"); - if (auto Err = S.loadAndLinkDynamicLibrary(*S.MainJD, Dylib)) - return Err; + auto DL = S.getOrLoadDynamicLibrary(Dylib); + if (!DL) + return DL.takeError(); } return Error::success(); @@ -963,69 +965,79 @@ Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err) ES.setErrorReporter(reportLLVMJITLinkError); - if (auto MainJDOrErr = ES.createJITDylib("main")) - MainJD = &*MainJDOrErr; - else { - Err = MainJDOrErr.takeError(); - return; - } - if (!NoProcessSymbols) ExitOnErr(loadProcessSymbols(*this)); - else { - // This symbol is used in testcases. - auto &TestResultJD = ES.createBareJITDylib("<TestResultJD>"); - ExitOnErr(TestResultJD.define(absoluteSymbols( - {{ES.intern("llvm_jitlink_setTestResultOverride"), - {ExecutorAddr::fromPtr(llvm_jitlink_setTestResultOverride), - JITSymbolFlags::Exported}}}))); - MainJD->addToLinkOrder(TestResultJD); - } ExitOnErr(loadDylibs(*this)); auto &TT = ES.getTargetTriple(); - if (DebuggerSupport && TT.isOSBinFormatMachO()) - ObjLayer.addPlugin(ExitOnErr( - GDBJITDebugInfoRegistrationPlugin::Create(this->ES, *MainJD, TT))); + if (DebuggerSupport && TT.isOSBinFormatMachO()) { + if (!ProcessSymsJD) { + Err = make_error<StringError>("MachO debugging requires process symbols", + inconvertibleErrorCode()); + return; + } + ObjLayer.addPlugin(ExitOnErr(GDBJITDebugInfoRegistrationPlugin::Create( + this->ES, *ProcessSymsJD, TT))); + } if (PerfSupport && TT.isOSBinFormatELF()) { + if (!ProcessSymsJD) { + Err = make_error<StringError>("MachO debugging requires process symbols", + inconvertibleErrorCode()); + return; + } ObjLayer.addPlugin(ExitOnErr(DebugInfoPreservationPlugin::Create())); ObjLayer.addPlugin(ExitOnErr(PerfSupportPlugin::Create( - this->ES.getExecutorProcessControl(), *MainJD, true, true))); + this->ES.getExecutorProcessControl(), *ProcessSymsJD, true, true))); } // Set up the platform. - if (TT.isOSBinFormatMachO() && !OrcRuntime.empty()) { - if (auto P = - MachOPlatform::Create(ES, ObjLayer, *MainJD, OrcRuntime.c_str())) - ES.setPlatform(std::move(*P)); - else { - Err = P.takeError(); - return; - } - } else if (TT.isOSBinFormatELF() && !OrcRuntime.empty()) { - if (auto P = - ELFNixPlatform::Create(ES, ObjLayer, *MainJD, OrcRuntime.c_str())) - ES.setPlatform(std::move(*P)); - else { - Err = P.takeError(); - return; - } - } else if (TT.isOSBinFormatCOFF() && !OrcRuntime.empty()) { - auto LoadDynLibrary = [&, this](JITDylib &JD, StringRef DLLName) -> Error { - if (!DLLName.ends_with_insensitive(".dll")) - return make_error<StringError>("DLLName not ending with .dll", - inconvertibleErrorCode()); - return loadAndLinkDynamicLibrary(JD, DLLName); - }; + if (!OrcRuntime.empty()) { + assert(ProcessSymsJD && "ProcessSymsJD should have been set"); + PlatformJD = &ES.createBareJITDylib("Platform"); + PlatformJD->addToLinkOrder(*ProcessSymsJD); + + if (TT.isOSBinFormatMachO()) { + if (auto P = MachOPlatform::Create(ES, ObjLayer, *PlatformJD, + OrcRuntime.c_str())) + ES.setPlatform(std::move(*P)); + else { + Err = P.takeError(); + return; + } + } else if (TT.isOSBinFormatELF()) { + if (auto P = ELFNixPlatform::Create(ES, ObjLayer, *PlatformJD, + OrcRuntime.c_str())) + ES.setPlatform(std::move(*P)); + else { + Err = P.takeError(); + return; + } + } else if (TT.isOSBinFormatCOFF()) { + auto LoadDynLibrary = [&, this](JITDylib &JD, + StringRef DLLName) -> Error { + if (!DLLName.ends_with_insensitive(".dll")) + return make_error<StringError>("DLLName not ending with .dll", + inconvertibleErrorCode()); + return loadAndLinkDynamicLibrary(JD, DLLName); + }; - if (auto P = COFFPlatform::Create(ES, ObjLayer, *MainJD, OrcRuntime.c_str(), - std::move(LoadDynLibrary))) - ES.setPlatform(std::move(*P)); - else { - Err = P.takeError(); + if (auto P = COFFPlatform::Create(ES, ObjLayer, *PlatformJD, + OrcRuntime.c_str(), + std::move(LoadDynLibrary))) + ES.setPlatform(std::move(*P)); + else { + Err = P.takeError(); + return; + } + } else { + Err = make_error<StringError>( + "-" + OrcRuntime.ArgStr + " specified, but format " + + Triple::getObjectFormatTypeName(TT.getObjectFormat()) + + " not supported", + inconvertibleErrorCode()); return; } } else if (TT.isOSBinFormatELF()) { @@ -1037,6 +1049,24 @@ Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err) ES, ExitOnErr(createJITLoaderGDBRegistrar(this->ES)), true, true)); } + if (auto MainJDOrErr = ES.createJITDylib("main")) + MainJD = &*MainJDOrErr; + else { + Err = MainJDOrErr.takeError(); + return; + } + + if (NoProcessSymbols) { + // This symbol is used in testcases, but we're not reflecting process + // symbols so we'll need to make it available some other way. + auto &TestResultJD = ES.createBareJITDylib("<TestResultJD>"); + ExitOnErr(TestResultJD.define(absoluteSymbols( + {{ES.intern("llvm_jitlink_setTestResultOverride"), + {ExecutorAddr::fromPtr(llvm_jitlink_setTestResultOverride), + JITSymbolFlags::Exported}}}))); + MainJD->addToLinkOrder(TestResultJD); + } + ObjLayer.addPlugin(std::make_unique<JITLinkSessionPlugin>(*this)); // Process any harness files. @@ -1266,6 +1296,10 @@ static Error sanitizeArguments(const Triple &TT, const char *ArgV0) { if (DebuggerSupport.getNumOccurrences() == 0 && NoExec) DebuggerSupport = false; + if (!OrcRuntime.empty() && NoProcessSymbols) + return make_error<StringError>("-orc-runtime requires process symbols", + inconvertibleErrorCode()); + // If -slab-allocate is passed, check that we're not trying to use it in // -oop-executor or -oop-executor-connect mode. // @@ -1365,6 +1399,13 @@ static Error createJITDylibs(Session &S, } } + if (S.PlatformJD) + S.JDSearchOrder.push_back( + {S.PlatformJD, JITDylibLookupFlags::MatchExportedSymbolsOnly}); + if (S.ProcessSymsJD) + S.JDSearchOrder.push_back( + {S.ProcessSymsJD, JITDylibLookupFlags::MatchExportedSymbolsOnly}); + LLVM_DEBUG({ dbgs() << "Dylib search order is [ "; for (auto &KV : S.JDSearchOrder) @@ -1416,23 +1457,67 @@ static Error addAliases(Session &S, const std::map<unsigned, JITDylib *> &IdxToJD) { // Define absolute symbols. LLVM_DEBUG(dbgs() << "Defining aliases...\n"); + + DenseMap<std::pair<JITDylib *, JITDylib *>, SymbolAliasMap> Reexports; for (auto AliasItr = Aliases.begin(), AliasEnd = Aliases.end(); AliasItr != AliasEnd; ++AliasItr) { - unsigned AliasArgIdx = Aliases.getPosition(AliasItr - Aliases.begin()); - auto &JD = *std::prev(IdxToJD.lower_bound(AliasArgIdx))->second; - StringRef AliasStmt = *AliasItr; - size_t EqIdx = AliasStmt.find_first_of('='); - if (EqIdx == StringRef::npos) - return make_error<StringError>("Invalid alias definition \"" + AliasStmt + - "\". Syntax: <name>=<addr>", - inconvertibleErrorCode()); - StringRef Alias = AliasStmt.substr(0, EqIdx).trim(); - StringRef Aliasee = AliasStmt.substr(EqIdx + 1).trim(); + auto BadExpr = [&]() { + return make_error<StringError>( + "Invalid alias definition \"" + *AliasItr + + "\". Syntax: [<dst-jd>:]<alias>=[<src-jd>:]<aliasee>", + inconvertibleErrorCode()); + }; + + auto GetJD = [&](StringRef JDName) -> Expected<JITDylib *> { + if (JDName.empty()) { + unsigned AliasArgIdx = Aliases.getPosition(AliasItr - Aliases.begin()); + return std::prev(IdxToJD.lower_bound(AliasArgIdx))->second; + } + + auto *JD = S.ES.getJITDylibByName(JDName); + if (!JD) + return make_error<StringError>(StringRef("In alias definition \"") + + *AliasItr + "\" no dylib named " + + JDName, + inconvertibleErrorCode()); - SymbolAliasMap SAM; - SAM[S.ES.intern(Alias)] = {S.ES.intern(Aliasee), JITSymbolFlags::Exported}; - if (auto Err = JD.define(symbolAliases(std::move(SAM)))) + return JD; + }; + + { + // First split on '=' to get alias and aliasee. + StringRef AliasStmt = *AliasItr; + auto [AliasExpr, AliaseeExpr] = AliasStmt.split('='); + if (AliaseeExpr.empty()) + return BadExpr(); + + auto [AliasJDName, Alias] = AliasExpr.split(':'); + if (Alias.empty()) + std::swap(AliasJDName, Alias); + + auto AliasJD = GetJD(AliasJDName); + if (!AliasJD) + return AliasJD.takeError(); + + auto [AliaseeJDName, Aliasee] = AliaseeExpr.split(':'); + if (Aliasee.empty()) + std::swap(AliaseeJDName, Aliasee); + + if (AliaseeJDName.empty() && !AliasJDName.empty()) + AliaseeJDName = AliasJDName; + auto AliaseeJD = GetJD(AliaseeJDName); + if (!AliaseeJD) + return AliaseeJD.takeError(); + + Reexports[{*AliasJD, *AliaseeJD}][S.ES.intern(Alias)] = { + S.ES.intern(Aliasee), JITSymbolFlags::Exported}; + } + } + + for (auto &[JDs, AliasMap] : Reexports) { + auto [DstJD, SrcJD] = JDs; + if (auto Err = DstJD->define(reexports(*SrcJD, std::move(AliasMap)))) return Err; } @@ -1766,6 +1851,14 @@ static Error addLibraries(Session &S, inconvertibleErrorCode()); } + // Add platform and process symbols if available. + for (auto &[Idx, JD] : IdxToJD) { + if (S.PlatformJD) + JD->addToLinkOrder(*S.PlatformJD); + if (S.ProcessSymsJD) + JD->addToLinkOrder(*S.ProcessSymsJD); + } + return Error::success(); } diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.h b/llvm/tools/llvm-jitlink/llvm-jitlink.h index 54a16ba..3ff406b 100644 --- a/llvm/tools/llvm-jitlink/llvm-jitlink.h +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.h @@ -31,6 +31,8 @@ struct Session { orc::ExecutionSession ES; orc::JITDylib *MainJD = nullptr; + orc::JITDylib *ProcessSymsJD = nullptr; + orc::JITDylib *PlatformJD = nullptr; orc::ObjectLinkingLayer ObjLayer; orc::JITDylibSearchOrder JDSearchOrder; SubtargetFeatures Features; |