2020-06-12 18:52:38 +03:00
|
|
|
//
|
2020-11-03 08:57:12 +03:00
|
|
|
// YaPB - Counter-Strike Bot based on PODBot by Markus Klinge.
|
|
|
|
|
// Copyright © 2004-2020 YaPB Project <yapb@jeefo.net>.
|
2020-06-12 18:52:38 +03:00
|
|
|
//
|
2020-11-03 08:57:12 +03:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-06-12 18:52:38 +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 {
|
|
|
|
|
public:
|
|
|
|
|
using Handle = void *;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
Handle handle_ = nullptr;
|
2020-11-23 00:06:18 +03:00
|
|
|
bool unloadable_ = true;
|
2020-06-12 18:52:38 +03:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit SharedLibrary () = default;
|
|
|
|
|
|
|
|
|
|
SharedLibrary (StringRef file) {
|
|
|
|
|
if (file.empty ()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
load (file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~SharedLibrary () {
|
|
|
|
|
unload ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
2020-11-23 00:06:18 +03:00
|
|
|
bool load (StringRef file, bool unloadable = true) noexcept {
|
2020-06-12 18:52:38 +03:00
|
|
|
if (*this) {
|
|
|
|
|
unload ();
|
|
|
|
|
}
|
2020-11-23 00:06:18 +03:00
|
|
|
unloadable_ = unloadable;
|
2020-06-12 18:52:38 +03:00
|
|
|
|
|
|
|
|
#if defined (CR_WINDOWS)
|
|
|
|
|
handle_ = LoadLibraryA (file.chars ());
|
|
|
|
|
#else
|
2020-11-23 00:06:18 +03:00
|
|
|
auto loadFlags = RTLD_NOW | RTLD_LOCAL;
|
|
|
|
|
|
|
|
|
|
#if defined (CR_LINUX) && !defined (__SANITIZE_ADDRESS__)
|
|
|
|
|
loadFlags |= RTLD_DEEPBIND;
|
|
|
|
|
#endif
|
|
|
|
|
handle_ = dlopen (file.chars (), loadFlags);
|
2020-06-12 18:52:38 +03:00
|
|
|
#endif
|
|
|
|
|
return handle_ != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool locate (Handle address) {
|
2020-11-23 00:06:18 +03:00
|
|
|
unloadable_ = false;
|
|
|
|
|
|
2020-06-12 18:52:38 +03:00
|
|
|
#if defined (CR_WINDOWS)
|
|
|
|
|
MEMORY_BASIC_INFORMATION mbi;
|
|
|
|
|
|
|
|
|
|
if (!VirtualQuery (address, &mbi, sizeof (mbi))) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mbi.State != MEM_COMMIT) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
handle_ = reinterpret_cast <Handle> (mbi.AllocationBase);
|
|
|
|
|
#else
|
|
|
|
|
Dl_info dli;
|
|
|
|
|
plat.bzero (&dli, sizeof (dli));
|
|
|
|
|
|
|
|
|
|
if (dladdr (address, &dli)) {
|
2020-11-23 00:06:18 +03:00
|
|
|
return load (dli.dli_fname, false);
|
2020-06-12 18:52:38 +03:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return handle_ != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void unload () noexcept {
|
2020-11-23 00:06:18 +03:00
|
|
|
if (!handle_ || !unloadable_) {
|
2020-06-12 18:52:38 +03:00
|
|
|
return;
|
|
|
|
|
}
|
2020-11-23 00:06:18 +03:00
|
|
|
|
2020-06-12 18:52:38 +03:00
|
|
|
#if defined (CR_WINDOWS)
|
|
|
|
|
FreeLibrary (static_cast <HMODULE> (handle_));
|
|
|
|
|
#else
|
|
|
|
|
dlclose (handle_);
|
|
|
|
|
#endif
|
|
|
|
|
handle_ = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename R> R resolve (const char *function) const {
|
|
|
|
|
if (!*this) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return SharedLibrary::getSymbol <R> (handle (), function);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Handle handle () const {
|
|
|
|
|
return handle_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
explicit operator bool () const {
|
|
|
|
|
return handle_ != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
2020-06-21 09:45:09 +03:00
|
|
|
template <typename R> static inline R CR_STDCALL getSymbol (Handle module, const char *function) {
|
2020-06-12 18:52:38 +03:00
|
|
|
return reinterpret_cast <R> (
|
|
|
|
|
#if defined (CR_WINDOWS)
|
|
|
|
|
GetProcAddress (static_cast <HMODULE> (module), function)
|
|
|
|
|
#else
|
|
|
|
|
dlsym (module, function)
|
|
|
|
|
#endif
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CR_NAMESPACE_END
|