From 6ae602bba7d33c900a117c9de0187ab5a28e14b8 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev 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(addr)); - return addr; } //////////////////////////////////////////////////////////////////////////////// -- 2.35.1