pslang/libs/jit/source/host_executable.cpp

71 lines
2.1 KiB
C++

#include <pslang/jit/host_executable.hpp>
#include <pslang/jit/linker.hpp>
#include <pslang/jit/foreign.hpp>
#include <system_error>
#if defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h>
#include <unistd.h>
#endif
#include <stdexcept>
namespace pslang::jit
{
namespace
{
std::size_t native_page_size()
{
#if defined(__linux__) || defined(__APPLE__)
return getpagesize();
#else
throw std::runtime_error("Native page size is not supported for this platform");
#endif
}
}
host_executable_program make_host_executable(std::vector<compiled_module> const & modules)
{
#if defined(__linux__) || defined(__APPLE__)
auto const page_size = native_page_size();
auto const abi = host_abi();
for (auto const & module : modules)
if (module.abi != abi)
throw std::runtime_error("Internal error: wrong compiled module ABI for host-executable binary");
auto link_info = prepare_link(modules, {.section_alignment = page_size});
auto storage = (std::uint8_t *)mmap(nullptr, link_info.total_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (storage == MAP_FAILED)
throw std::system_error(errno, std::generic_category());
host_executable_program result;
result.mapping.reset(storage, [total_size = link_info.total_size](void * ptr){ munmap(ptr, total_size); });
link(modules, link_info, storage);
for (auto const & relocation : link_info.relocation_offset)
*(void **)(storage + relocation.second) = load_foreign(relocation.first);
if (mprotect(storage + link_info.code.begin, link_info.code.size, PROT_READ | PROT_EXEC) != 0)
throw std::system_error(errno, std::generic_category());
if (mprotect(storage + link_info.relocations.begin, link_info.relocations.size, PROT_READ) != 0)
throw std::system_error(errno, std::generic_category());
result.functions = std::move(link_info.functions);
result.globals = std::move(link_info.globals);
result.entry_points = std::move(link_info.entry_points);
return result;
#else
throw std::runtime_error("Host-executable modules are not supported for this platform");
#endif
}
}