From 912072e60cd4fc5d2e8353b1a8d3823c5205e356 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 10 Aug 2016 13:09:11 +0300 Subject: [PATCH] LLVM: minor fixes (JIT.cpp) --- Utilities/JIT.cpp | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/Utilities/JIT.cpp b/Utilities/JIT.cpp index 6d928c2502..9d7fec31bb 100644 --- a/Utilities/JIT.cpp +++ b/Utilities/JIT.cpp @@ -46,7 +46,7 @@ static const u64 s_memory_size = 0x20000000; static void* const s_memory = []() -> void* { #ifdef _WIN32 - for (u64 addr = 0x1000000; addr <= 0x60000000; addr += 0x1000000) + for (u64 addr = 0x10000000; addr <= 0x60000000; addr += 0x1000000) { if (VirtualAlloc((void*)addr, s_memory_size, MEM_RESERVE, PAGE_NOACCESS)) { @@ -60,6 +60,10 @@ static void* const s_memory = []() -> void* #endif }(); +// Code section +static u8* s_code_addr; +static u64 s_code_size; + // EH frames static u8* s_unwind_info; static u64 s_unwind_size; @@ -125,6 +129,9 @@ struct MemoryManager final : llvm::RTDyldMemoryManager return nullptr; } + s_code_addr = (u8*)m_next; + s_code_size = size; + LOG_SUCCESS(GENERAL, "LLVM: Code section %u '%s' allocated -> 0x%p (size=0x%llx, aligned 0x%x)", sec_id, sec_name.data(), m_next, size, align); return (u8*)std::exchange(m_next, (void*)next); } @@ -140,6 +147,11 @@ struct MemoryManager final : llvm::RTDyldMemoryManager return nullptr; } + if (!is_ro) + { + LOG_ERROR(GENERAL, "LLVM: Writeable data section not supported!"); + } + #ifdef _WIN32 if (!VirtualAlloc(m_next, size, MEM_COMMIT, PAGE_READWRITE)) #else @@ -156,7 +168,15 @@ struct MemoryManager final : llvm::RTDyldMemoryManager virtual bool finalizeMemory(std::string* = nullptr) override { - // TODO: make sections read-only when necessary + // TODO: make only read-only sections read-only +#ifdef _WIN32 + DWORD op; + VirtualProtect(s_memory, (u64)m_next - (u64)s_memory, PAGE_READONLY, &op); + VirtualProtect(s_code_addr, s_code_size, PAGE_EXECUTE_READ, &op); +#else + ::mprotect(s_memory, (u64)m_next - (u64)s_memory, PROT_READ); + ::mprotect(s_code_addr, s_code_size, PROT_READ | PROT_EXEC); +#endif return false; } @@ -267,19 +287,17 @@ jit_compiler::jit_compiler(std::unique_ptr&& _module, std::unorder func_set.emplace(pair.second); } - // Hack (cannot obtain last function size) - func_set.emplace(::align(*--func_set.end() + 4096, 4096)); - const u64 base = (u64)s_memory; const u8* bits = s_unwind_info; s_unwind.clear(); s_unwind.reserve(m_map.size()); - for (auto it = func_set.begin(), end = --func_set.end(); it != end; it++) + for (const u64 addr : func_set) { - const u64 addr = *it; - const u64 next = *func_set.upper_bound(addr); + // Find next function address + const auto _next = func_set.upper_bound(addr); + const u64 next = _next != func_set.end() ? *_next : (u64)s_code_addr + s_code_size; // Generate RUNTIME_FUNCTION record RUNTIME_FUNCTION uw; @@ -297,6 +315,7 @@ jit_compiler::jit_compiler(std::unique_ptr&& _module, std::unorder if (flags != 1) { + // Can't happen for trivial code LOG_ERROR(GENERAL, "LLVM: unsupported UNWIND_INFO version/flags (0x%02x)", flags); break; } @@ -306,11 +325,11 @@ jit_compiler::jit_compiler(std::unique_ptr&& _module, std::unorder if (s_unwind_info + s_unwind_size != bits) { - LOG_FATAL(GENERAL, "LLVM: .xdata analysis failed! (0x%p != 0x%p)", s_unwind_info + s_unwind_size, bits); + LOG_ERROR(GENERAL, "LLVM: .xdata analysis failed! (0x%p != 0x%p)", s_unwind_info + s_unwind_size, bits); } else if (!RtlAddFunctionTable(s_unwind.data(), (DWORD)s_unwind.size(), base)) { - LOG_FATAL(GENERAL, "RtlAddFunctionTable(addr=0x%p) failed! Error %u", s_unwind_info, GetLastError()); + LOG_ERROR(GENERAL, "RtlAddFunctionTable(addr=0x%p) failed! Error %u", s_unwind_info, GetLastError()); } else {