Unverified Commit df5f8c96 authored by Artur Wojcik's avatar Artur Wojcik Committed by GitHub
Browse files

port class 'dynamic_loader' to Windows (#2278)

parent a50cb302
......@@ -27,11 +27,20 @@
#include <migraphx/file_buffer.hpp>
#include <migraphx/tmp_dir.hpp>
#include <utility>
#ifdef _WIN32
// cppcheck-suppress definePrefix
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#else
#include <dlfcn.h>
#endif
namespace migraphx {
inline namespace MIGRAPHX_INLINE_NS {
#ifndef _WIN32
void check_load_error(bool flush = false)
{
char* error_msg = dlerror();
......@@ -81,6 +90,48 @@ fs::path dynamic_loader::path(void* address)
return p;
}
#else
struct dynamic_loader_impl
{
dynamic_loader_impl() = default;
dynamic_loader_impl(const fs::path& p, tmp_dir t = {})
: handle{LoadLibrary(p.string().c_str())}, temp{std::move(t)}
{
if(handle == nullptr)
{
MIGRAPHX_THROW("Error loading DLL: " + p.string() + " (" +
std::to_string(GetLastError()) + ")");
}
}
dynamic_loader_impl(const dynamic_loader_impl&) = delete;
dynamic_loader_impl& operator=(const dynamic_loader_impl&) = delete;
dynamic_loader_impl(dynamic_loader_impl&&) = default;
~dynamic_loader_impl()
{
if(handle != nullptr)
{
FreeLibrary(handle);
}
}
static std::shared_ptr<dynamic_loader_impl> from_buffer(const char* image, std::size_t size)
{
auto t = tmp_dir{"migx-dynload"};
auto f = t.path / "tmp.dll";
write_buffer(f.string(), image, size);
return std::make_shared<dynamic_loader_impl>(f, std::move(t));
}
HMODULE handle = nullptr;
tmp_dir temp;
};
#endif
optional<dynamic_loader> dynamic_loader::try_load(const fs::path& p)
{
try
......@@ -109,12 +160,19 @@ dynamic_loader::dynamic_loader(const std::vector<char>& buffer)
std::shared_ptr<void> dynamic_loader::get_symbol(const std::string& name) const
{
#ifndef _WIN32
// flush any previous error messages
check_load_error(true);
void* symbol = dlsym(impl->handle.get(), name.c_str());
if(symbol == nullptr)
check_load_error();
return {impl, symbol};
#else
FARPROC addr = GetProcAddress(impl->handle, name.c_str());
if(addr == nullptr)
MIGRAPHX_THROW("Symbol not found: " + name + " (" + std::to_string(GetLastError()) + ")");
return {impl, reinterpret_cast<void*>(addr)};
#endif
}
} // namespace MIGRAPHX_INLINE_NS
......
......@@ -38,12 +38,14 @@ struct dynamic_loader_impl;
struct MIGRAPHX_EXPORT dynamic_loader
{
#ifndef _WIN32
template <class T>
static fs::path path(T* address)
{
return path(reinterpret_cast<void*>(address));
}
static fs::path path(void* address);
#endif
static optional<dynamic_loader> try_load(const fs::path& p);
......
......@@ -57,7 +57,7 @@ struct instruction_ref : std::list<instruction>::iterator
std::is_same<U, instruction_ref>{})>
friend bool operator!=(const T& x, const U& y)
{
return !(x == y);
return not(x == y);
}
};
#else
......
......@@ -34,6 +34,7 @@ struct MIGRAPHX_EXPORT tmp_dir
{
fs::path path;
tmp_dir(const std::string& prefix = "");
tmp_dir(tmp_dir&&) = default;
void execute(const std::string& exe, const std::string& args) const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment