#include #include #include using namespace std; namespace lth_locale = leatherman::locale; namespace leatherman { namespace dynamic_library { dynamic_library dynamic_library::find_by_pattern(std::string const& pattern) { // POSIX doesn't have this capability return dynamic_library(); } dynamic_library dynamic_library::find_by_symbol(std::string const& symbol) { dynamic_library library; // Load the "null" library; this will cause dlsym to search for the symbol void* handle = dlopen(nullptr, RTLD_GLOBAL | RTLD_LAZY); if (!handle) { return library; } // Check to see if a search for the symbol succeeds if (!dlsym(handle, symbol.c_str())) { dlclose(handle); return library; } // At least one loaded module will resolve the given symbol // Return this handle to allow the caller to search for other symbols library._handle = handle; library._first_load = false; return library; } bool dynamic_library::load(string const& name, bool global) { close(); auto load_mode = (global ? RTLD_GLOBAL : RTLD_LOCAL) | RTLD_LAZY; _handle = dlopen(name.c_str(), load_mode); if (!_handle) { LOG_DEBUG("library {1} not found {2} ({3}).", name.c_str(), strerror(errno), errno); return false; } _first_load = true; _name = name; return true; } void dynamic_library::close() { if (_handle) { dlclose(_handle); _handle = nullptr; } _name.clear(); _first_load = false; } void* dynamic_library::find_symbol(string const& name, bool throw_if_missing, string const& alias) const { if (!_handle) { if (throw_if_missing) { throw missing_import_exception("library is not loaded."); } else { LOG_DEBUG("library {1} is not loaded when attempting to load symbol {2}.", _name.c_str(), name.c_str()); } return nullptr; } void* symbol = dlsym(_handle, name.c_str()); if (!symbol && !alias.empty()) { LOG_DEBUG("symbol {1} not found in library {2}, trying alias {3}.", name.c_str(), _name.c_str(), alias.c_str()); symbol = dlsym(_handle, alias.c_str()); } if (!symbol) { if (throw_if_missing) { throw missing_import_exception(lth_locale::format("symbol {1} was not found in {2}.", name, _name)); } else { LOG_DEBUG("symbol {1} not found in library {2}.", name.c_str(), _name.c_str()); } } return symbol; } }} // namespace leatherman::dynamic_library