From 6ae602bba7d33c900a117c9de0187ab5a28e14b8 Mon Sep 17 00:00:00 2001
From: Vassil Vassilev <v.g.vassilev@gmail.com>
Date: Mon, 21 Mar 2022 22:16:54 +0000
Subject: [PATCH] Make the dyld-based library search behavior default for
non-modules.
The dyld-based system was developed in the context on C++ modules but it turned
into a modules-agnostic feature. Instead of having to maintain more code, we
should rely on it even for non-modules build of ROOT.
---
core/metacling/src/TCling.cxx | 109 +++-------------------------------
1 file changed, 8 insertions(+), 101 deletions(-)
diff --git a/core/metacling/src/TCling.cxx b/core/metacling/src/TCling.cxx
index dec399cf2b..3eae1c8570 100644
--- a/core/metacling/src/TCling.cxx
+++ b/core/metacling/src/TCling.cxx
@@ -6501,14 +6501,18 @@ bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::stri
return false;
}
-static void* LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name,
- const cling::DynamicLibraryManager &DLM) {
+////////////////////////////////////////////////////////////////////////////////
+/// Autoload a library based on a missing symbol.
+
+void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
+
+ const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
R__LOCKGUARD(gInterpreterMutex);
auto LibLoader = [](const std::string& LibName) -> bool {
if (gSystem->Load(LibName.c_str(), "", false) < 0) {
- Error("TCling__LazyFunctionCreatorAutoloadForModule",
- "Failed to load library %s", LibName.c_str());
+ ::Error("TCling__LazyFunctionCreatorAutoloadForModule",
+ "Failed to load library %s", LibName.c_str());
return false;
}
return true; //success.
@@ -6536,103 +6540,6 @@ static void* LazyFunctionCreatorAutoloadForModule(const std::string &mangled_nam
return nullptr;
return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name);
-
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// Autoload a library based on a missing symbol.
-
-void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
- if (fCxxModulesEnabled)
- return LazyFunctionCreatorAutoloadForModule(mangled_name,
- *GetInterpreterImpl()->getDynamicLibraryManager());
-
- // First see whether the symbol is in the library that we are currently
- // loading. It will have access to the symbols of its dependent libraries,
- // thus checking "back()" is sufficient.
- if (!fRegisterModuleDyLibs.empty()) {
- if (void* addr = dlsym(fRegisterModuleDyLibs.back(),
- mangled_name.c_str())) {
- return addr;
- }
- }
-
- int err = 0;
- char* demangled_name_c = TClassEdit::DemangleName(mangled_name.c_str(), err);
- if (err) {
- return 0;
- }
-
- std::string name(demangled_name_c);
- free(demangled_name_c);
-
- //fprintf(stderr, "demangled name: '%s'\n", demangled_name);
- //
- // Separate out the class or namespace part of the
- // function name.
- //
-
- std::string::size_type pos = name.find("__thiscall ");
- if (pos != std::string::npos) {
- name.erase(0, pos + sizeof("__thiscall ")-1);
- }
- pos = name.find("__cdecl ");
- if (pos != std::string::npos) {
- name.erase(0, pos + sizeof("__cdecl ")-1);
- }
- if (!strncmp(name.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
- name.erase(0, sizeof("typeinfo for ")-1);
- } else if (!strncmp(name.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
- name.erase(0, sizeof("vtable for ")-1);
- } else if (!strncmp(name.c_str(), "operator", sizeof("operator")-1)
- && !isalnum(name[sizeof("operator")])) {
- // operator...(A, B) - let's try with A!
- name.erase(0, sizeof("operator")-1);
- pos = name.rfind('(');
- if (pos != std::string::npos) {
- name.erase(0, pos + 1);
- pos = name.find(",");
- if (pos != std::string::npos) {
- // remove next arg up to end, leaving only the first argument type.
- name.erase(pos);
- }
- pos = name.rfind(" const");
- if (pos != std::string::npos) {
- name.erase(pos, strlen(" const"));
- }
- while (!name.empty() && strchr("&*", name.back()))
- name.erase(name.length() - 1);
- }
- } else {
- TClassEdit::FunctionSplitInfo fsi;
- TClassEdit::SplitFunction(name, fsi);
- name = fsi.fScopeName;
- }
- //fprintf(stderr, "name: '%s'\n", name.c_str());
- // Now we have the class or namespace name, so do the lookup.
- TString libs = GetClassSharedLibs(name.c_str());
- if (libs.IsNull()) {
- // Not found in the map, all done.
- return 0;
- }
- //fprintf(stderr, "library: %s\n", iter->second.c_str());
- // Now we have the name of the libraries to load, so load them.
-
- TString lib;
- Ssiz_t posLib = 0;
- while (libs.Tokenize(lib, posLib)) {
- if (gSystem->Load(lib, "", kFALSE /*system*/) < 0) {
- // The library load failed, all done.
- //fprintf(stderr, "load failed: %s\n", errmsg.c_str());
- return 0;
- }
- }
-
- //fprintf(stderr, "load succeeded.\n");
- // Get the address of the function being called.
- void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
- //fprintf(stderr, "addr: %016lx\n", reinterpret_cast<unsigned long>(addr));
- return addr;
}
////////////////////////////////////////////////////////////////////////////////
--
2.35.1