Split compiled module code & data segments and use mprotect to make a module host-executable

This commit is contained in:
Nikita Lisitsa 2026-01-02 11:35:19 +03:00
parent da39ae1225
commit 98a5720141
4 changed files with 21 additions and 16 deletions

View file

@ -7,7 +7,7 @@ namespace pslang::jit
{
itanium,
msvc,
arm,
armv8,
};
}

View file

@ -10,10 +10,16 @@ namespace pslang::jit
{
struct compiled_module
{
struct segment
{
blob memory;
std::unordered_map<std::string, std::size_t> symbol_table;
std::size_t entry_point;
};
segment data;
segment code;
std::size_t entry_point; // in code segment
jit::abi abi;
};

View file

@ -6,24 +6,23 @@
#include <sys/mman.h>
#endif
#ifdef __APPLE__
#include <sys/mman.h>
#endif
namespace pslang::jit
{
compiled_module make_host_executable(compiled_module module)
{
#ifdef __linux__
if (module.abi != abi::itanium)
#if defined(__linux__) || defined(__APPLE__)
if (module.abi != abi::itanium && module.abi != abi::armv8)
throw std::runtime_error("Abi mismatch");
auto ptr = (std::uint8_t *)mmap(nullptr, module.memory.size, PROT_READ | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
auto shared_ptr = std::shared_ptr<std::uint8_t>(ptr, [size = module.memory.size](std::uint8_t * ptr){ munmap(ptr, size); });
// Assume the module code memory was obtained via mmap
mprotect(module.code.memory.data.get(), module.code.memory.size, PROT_READ | PROT_EXEC);
return compiled_module {
.memory = blob(shared_ptr, module.memory.size),
.symbol_table = std::move(module.symbol_table),
.entry_point = module.entry_point,
.abi = module.abi,
};
return module;
#else
throw std::runtime_error("Host-executable modules are not supported for this platform");
#endif

View file

@ -6,8 +6,8 @@ namespace pslang::jit
compiled_module compile(ast::statement_list_ptr const & /* statements */, jit::abi abi)
{
return {
.memory = {},
.symbol_table = {},
.data = {},
.code = {},
.entry_point = 0,
.abi = abi,
};