2019-07-27 17:36:24 +03:00
|
|
|
//
|
|
|
|
|
// Yet Another POD-Bot, based on PODBot by Markus Klinge ("CountFloyd").
|
2019-09-21 23:20:33 +03:00
|
|
|
// Copyright (c) Yet Another POD-Bot Contributors <yapb@entix.io>.
|
2019-07-27 17:36:24 +03:00
|
|
|
//
|
2019-09-21 23:20:33 +03:00
|
|
|
// This software is licensed under the MIT license.
|
|
|
|
|
// Additional exceptions apply. For full license details, see LICENSE.txt
|
2019-07-27 17:36:24 +03:00
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <crlib/cr-basic.h>
|
|
|
|
|
#include <crlib/cr-string.h>
|
|
|
|
|
|
|
|
|
|
#if defined (CR_LINUX) || defined (CR_OSX)
|
|
|
|
|
# include <dlfcn.h>
|
|
|
|
|
# include <errno.h>
|
|
|
|
|
# include <fcntl.h>
|
|
|
|
|
# include <sys/stat.h>
|
|
|
|
|
# include <unistd.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
CR_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
|
|
// handling dynamic library loading
|
|
|
|
|
class SharedLibrary final : public DenyCopying {
|
|
|
|
|
private:
|
|
|
|
|
void *m_handle = nullptr;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit SharedLibrary () = default;
|
|
|
|
|
|
|
|
|
|
SharedLibrary (const String &file) {
|
|
|
|
|
if (file.empty ()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
load (file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~SharedLibrary () {
|
|
|
|
|
unload ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
2019-07-31 14:05:36 +03:00
|
|
|
bool load (const String &file) noexcept {
|
2019-09-14 23:13:55 +03:00
|
|
|
if (*this) {
|
|
|
|
|
unload ();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-31 14:05:36 +03:00
|
|
|
#if defined (CR_WINDOWS)
|
2019-07-27 17:36:24 +03:00
|
|
|
m_handle = LoadLibraryA (file.chars ());
|
|
|
|
|
#else
|
|
|
|
|
m_handle = dlopen (file.chars (), RTLD_NOW);
|
|
|
|
|
#endif
|
|
|
|
|
return m_handle != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-31 14:05:36 +03:00
|
|
|
bool locate (void *address) {
|
|
|
|
|
#if defined (CR_WINDOWS)
|
|
|
|
|
MEMORY_BASIC_INFORMATION mbi;
|
|
|
|
|
|
|
|
|
|
if (!VirtualQuery (address, &mbi, sizeof (mbi))) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mbi.State != MEM_COMMIT) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
m_handle = reinterpret_cast <void *> (mbi.AllocationBase);
|
|
|
|
|
#else
|
|
|
|
|
Dl_info dli;
|
2019-09-21 23:20:33 +03:00
|
|
|
plat.bzero (&dli, sizeof (dli));
|
2019-07-31 14:05:36 +03:00
|
|
|
|
|
|
|
|
if (dladdr (address, &dli)) {
|
|
|
|
|
return load (dli.dli_fname);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return m_handle != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-27 17:36:24 +03:00
|
|
|
void unload () noexcept {
|
|
|
|
|
if (!*this) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-07-31 14:05:36 +03:00
|
|
|
#if defined (CR_WINDOWS)
|
2019-07-27 17:36:24 +03:00
|
|
|
FreeLibrary (static_cast <HMODULE> (m_handle));
|
|
|
|
|
#else
|
|
|
|
|
dlclose (m_handle);
|
|
|
|
|
#endif
|
2019-07-31 14:05:36 +03:00
|
|
|
m_handle = nullptr;
|
2019-07-27 17:36:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename R> R resolve (const char *function) const {
|
|
|
|
|
if (!*this) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return reinterpret_cast <R> (
|
2019-07-31 14:05:36 +03:00
|
|
|
#if defined (CR_WINDOWS)
|
2019-07-27 17:36:24 +03:00
|
|
|
GetProcAddress (static_cast <HMODULE> (m_handle), function)
|
|
|
|
|
#else
|
|
|
|
|
dlsym (m_handle, function)
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-31 14:05:36 +03:00
|
|
|
void *handle () const {
|
|
|
|
|
return m_handle;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-27 17:36:24 +03:00
|
|
|
public:
|
|
|
|
|
explicit operator bool () const {
|
|
|
|
|
return m_handle != nullptr;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CR_NAMESPACE_END
|