30#include <unordered_map>
73 LibRef(
const std::string& name) noexcept
74 : m_name(name), m_count(1) {}
78 LibRef& operator=(
const LibRef&)
noexcept =
default;
79 LibRef& operator=(LibRef&&)
noexcept =
default;
81 ssize_t incrRefCount() {
return ++m_count; }
82 ssize_t decrRefCount() {
return --m_count; }
83 ssize_t count() {
return m_count; }
85 const std::string& name() {
return m_name; }
87 std::string toString() {
return "LibRef["+m_name+
", count "+
std::to_string(m_count)+
"]"; }
89 typedef std::shared_ptr<LibRef> LibRef_ref;
91 typedef std::unordered_map<libhandle_t, LibRef_ref> LibRefMap_t;
92 typedef typename LibRefMap_t::iterator LibRefIter_t;
94 std::mutex m_mtx_libref;
95 LibRefMap_t m_handleToNameMap;
103 std::unique_lock<std::mutex> lock(m_mtx_libref);
104 LibRef_ref libRef =
nullptr;
105 LibRefIter_t iter = m_handleToNameMap.find(handle);
106 if( m_handleToNameMap.end() == iter ) {
107 std::pair<LibRefIter_t,bool> res = m_handleToNameMap.insert( { handle, std::make_shared<LibRef>(libName) } );
108 libRef = res.first->second;
110 libRef->incrRefCount();
113 libRef = iter->second;
114 libRef->incrRefCount();
116 DBG_PRINT(
"DynamicLinkerImpl.incrLibRefCount %s -> %s, libs loaded %zu",
117 jau::to_hexstring(handle).c_str(), libRef->toString().c_str(), m_handleToNameMap.size());
122 std::unique_lock<std::mutex> lock(m_mtx_libref);
123 LibRef_ref libRef =
nullptr;
124 LibRefIter_t iter = m_handleToNameMap.find(handle);
125 if( m_handleToNameMap.end() != iter ) {
126 libRef = iter->second;
127 if( 0 == libRef->decrRefCount() ) {
128 m_handleToNameMap.erase(iter);
130 DBG_PRINT(
"DynamicLinkerImpl.decrLibRefCount %s -> %s, libs loaded %zu",
131 jau::to_hexstring(handle).c_str(), libRef->toString().c_str(), m_handleToNameMap.size());
133 DBG_PRINT(
"DynamicLinkerImpl.decrLibRefCount %s -> null, libs loaded %zu",
145 return "DYLD_LIBRARY_PATH";
149 return "LD_LIBRARY_PATH";
221 static
std::
string getBaseName(const
std::
string& filename, const
bool isBasename=false, const
bool caseInsensitive=
jau::os::
is_windows()) noexcept;
230 bool searchSystemPath=false,
231 bool searchSystemPathFirst=false) noexcept;
258 if(
nullptr != handle ) {
260 DBG_PRINT(
"DynamicLinkerImpl.openLibraryGlobal \"%s\": %s -> %s",
261 pathname.c_str(),
jau::to_hexstring(handle).c_str(), libRef->toString().c_str());
263 DBG_PRINT(
"DynamicLinkerImpl.openLibraryGlobal \"%s\" failed, error %s",
277 if(
nullptr != handle ) {
279 DBG_PRINT(
"DynamicLinkerImpl.openLibraryLocal \"%s\": %s -> %s",
280 pathname.c_str(),
jau::to_hexstring(handle).c_str(), libRef->toString().c_str());
282 DBG_PRINT(
"DynamicLinkerImpl.openLibraryLocal \"%s\" failed, error %s",
296 jau::INFO_PRINT(
"DynamicLinkerImpl.lookupLibraryPathname(%s, %s) -> '%s'",
297 jau::to_hexstring(handle).c_str(), symbolName.c_str(),
nullptr != fname ? fname :
"null");
338 if(
nullptr != libRef ) {
339 DBG_PRINT(
"DynamicLinkerImpl.closeLibrary(%s -> %s)",
344 if(
nullptr != handle ) {
static std::string getProperty(const std::string &name) noexcept
Returns the value of the environment's variable 'name'.
Low level secure dynamic linker access.
static std::string getBaseName(const std::string &filename, const bool isBasename=false, const bool caseInsensitive=jau::os::is_windows()) noexcept
Returns the library basename, i.e.
static constexpr const bool DEBUG_LOOKUP
virtual const char * lookupLibraryPathnameImpl(libhandle_t libraryHandle, const std::string &symbolName) noexcept=0
virtual libhandle_t openLibraryLocalImpl(const std::string &pathname) noexcept=0
virtual libhandle_t openLibraryGlobalImpl(const std::string &pathname) noexcept=0
static DynamicLinker & get() noexcept
Returns static singleton instance of DynamicLinker.
symhandle_t lookupSymbolGlobal(const std::string &symbolName) noexcept
virtual symhandle_t lookupSymbolLocalImpl(libhandle_t handle, const std::string &symbolName) noexcept=0
static std::vector< std::string > enumerateLibraryPaths(const std::string &libName, bool searchSystemPath=false, bool searchSystemPathFirst=false) noexcept
Returns list of potential absolute library filenames.
LibRef_ref decrLibRefCount(const libhandle_t handle) noexcept
symhandle_t lookupSymbol(libhandle_t handle, const std::string &symbolName) noexcept
virtual std::string getLastErrorImpl() noexcept=0
void * symhandle_t
symbol handle within a library
static constexpr_cxx20 std::string getDefaultPrefix() noexcept
Returns the native library prefix, e.g.
static constexpr_cxx20 std::string getDefaultSuffix() noexcept
Returns the native library suffix including the dot, e.g.
LibRef_ref incrLibRefCount(const libhandle_t handle, const std::string &libName) noexcept
libhandle_t openLibraryGlobal(const std::string &pathname) noexcept
Opens the named library, allowing system wide access for other users.
DynamicLinker() noexcept=default
static constexpr_cxx20 std::string getEnvLibPathVarName() noexcept
Returns the environment library path variable name, e.g.
void * libhandle_t
library handle
const char * lookupLibraryPathname(libhandle_t handle, const std::string &symbolName) noexcept
virtual ~DynamicLinker() noexcept=default
std::string getLastError() noexcept
Returns a string containing the last error.
static constexpr_cxx20 std::string getCanonicalName(const std::string &basename, const bool checkIsCanonical=true) noexcept
Returns canonical library name for this system from given library-basename, e.g.
libhandle_t openLibraryLocal(const std::string &pathname) noexcept
Opens the named library, restricting access to this process.
void closeLibrary(libhandle_t handle) noexcept
Security checks are implicit by previous call of openLibraryLocal(const std::string_view&,...
static bool isCanonicalName(const std::string &filename, const bool isBasename=false, const bool caseInsensitive=jau::os::is_windows()) noexcept
Returns true if the given filename contains the canonical prefix and suffix, otherwise returns false.
static std::vector< std::string > getSystemEnvLibraryPaths()
Returns a list of system paths, from the getSystemEnvLibraryPathVarname() variable.
virtual void closeLibraryImpl(libhandle_t handle) noexcept=0
virtual symhandle_t lookupSymbolGlobalImpl(const std::string &symbolName) noexcept=0
#define DBG_PRINT(...)
Use for environment-variable environment::DEBUG conditional debug messages, prefix '[elapsed_time] De...
std::string to_string(const alphabet &v) noexcept
#define constexpr_cxx20
constexpr qualifier replacement for C++20 constexpr.
std::string basename(const std::string_view &path) noexcept
Return stripped leading directory components from given path separated by /.
constexpr bool is_darwin() noexcept
Evaluates true if platform os_type::native contains os_type::Darwin.
constexpr_cxx20 std::string path_separator() noexcept
Returns the OS's path separator as a string, e.g.
constexpr bool is_windows() noexcept
Evaluates true if platform os_type::native contains os_type::Windows.
std::vector< std::string > split_string(const std::string &str, const std::string &separator) noexcept
Split given string str at separator into the resulting std::vector excluding the separator sequence .
std::string to_hexstring(value_type const &v) noexcept
Produce a lower-case hexadecimal string representation of the given pointer.
Author: Sven Gothel sgothel@jausoft.com Copyright (c) 2024 Gothel Software e.K.
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
void INFO_PRINT(const char *format,...) noexcept
Use for unconditional informal messages, prefix '[elapsed_time] Info: '.