1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 04:02:42 +01:00

Reimplement ASMJIT runtime

Try to emplace generated code in lower address area.
Protect generated code from writing.
This commit is contained in:
Nekotekina 2020-10-17 19:28:21 +03:00
parent a0d95a823e
commit 3d980a9f66
2 changed files with 69 additions and 4 deletions

View File

@ -194,10 +194,75 @@ void jit_runtime::finalize() noexcept
std::memcpy(alloc(s_data_init.size(), 1, false), s_data_init.data(), s_data_init.size());
}
asmjit::JitRuntime& asmjit::get_global_runtime()
asmjit::Runtime& asmjit::get_global_runtime()
{
// 16 MiB for internal needs
static constexpr u64 size = 1024 * 1024 * 16;
struct custom_runtime final : asmjit::HostRuntime
{
custom_runtime() noexcept
{
// Search starting in first 2 GiB of memory
for (u64 addr = size;; addr += size)
{
if (auto ptr = utils::memory_reserve(size, reinterpret_cast<void*>(addr)))
{
m_pos.raw() = static_cast<std::byte*>(ptr);
break;
}
}
// Initialize "end" pointer
m_max = m_pos + size;
// Make memory writable + executable
utils::memory_commit(m_pos, size, utils::protection::wx);
}
asmjit::Error _add(void** dst, asmjit::CodeHolder* code) noexcept override
{
std::size_t codeSize = code->getCodeSize();
if (!codeSize) [[unlikely]]
{
*dst = nullptr;
return asmjit::kErrorNoCodeGenerated;
}
void* p = m_pos.fetch_add(::align(codeSize, 4096));
if (!p || m_pos > m_max) [[unlikely]]
{
*dst = nullptr;
return asmjit::kErrorNoVirtualMemory;
}
std::size_t relocSize = code->relocate(p);
if (!relocSize) [[unlikely]]
{
*dst = nullptr;
return asmjit::kErrorInvalidState;
}
utils::memory_protect(p, ::align(codeSize, 4096), utils::protection::rx);
flush(p, relocSize);
*dst = p;
return asmjit::kErrorOk;
}
asmjit::Error _release(void* ptr) noexcept override
{
return asmjit::kErrorOk;
}
private:
atomic_t<std::byte*> m_pos{};
std::byte* m_max{};
};
// Magic static
static asmjit::JitRuntime g_rt;
static custom_runtime g_rt;
return g_rt;
}

View File

@ -53,7 +53,7 @@ struct jit_runtime final : asmjit::HostRuntime
namespace asmjit
{
// Should only be used to build global functions
asmjit::JitRuntime& get_global_runtime();
asmjit::Runtime& get_global_runtime();
// Emit xbegin and adjacent loop, return label at xbegin
[[nodiscard]] asmjit::Label build_transaction_enter(X86Assembler& c, Label fallback, const X86Gp& ctr, uint less_than);
@ -64,7 +64,7 @@ namespace asmjit
// Build runtime function with asmjit::X86Assembler
template <typename FT, typename F>
FT build_function_asm(F&& builder)
inline FT build_function_asm(F&& builder)
{
using namespace asmjit;