mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 07:21:54 +00:00
Implement Windows boundary check with hardware trap (#623)
This commit is contained in:
parent
eb29385963
commit
fa5f4fe940
|
@ -52,9 +52,11 @@ endif ()
|
|||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64" OR WAMR_BUILD_TARGET MATCHES "AARCH64.*" OR WAMR_BUILD_TARGET MATCHES "RISCV64.*")
|
||||
# Add -fPIC flag if build as 64-bit
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
|
||||
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
|
||||
# Add -fPIC flag if build as 64-bit
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
|
||||
endif ()
|
||||
else ()
|
||||
add_definitions (-m32)
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
|
||||
|
|
|
@ -1042,7 +1042,8 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end,
|
|||
read_uint32(buf, buf_end, data_sections[i].size);
|
||||
|
||||
/* Allocate memory for data */
|
||||
if (!(data_sections[i].data =
|
||||
if (data_sections[i].size > 0
|
||||
&& !(data_sections[i].data =
|
||||
os_mmap(NULL, data_sections[i].size, map_prot, map_flags))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"allocate memory failed");
|
||||
|
@ -1179,6 +1180,27 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
|||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 i;
|
||||
uint64 size, text_offset;
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
|
||||
RUNTIME_FUNCTION *rtl_func_table;
|
||||
AOTUnwindInfo *unwind_info;
|
||||
uint32 unwind_info_offset = module->code_size - sizeof(AOTUnwindInfo);
|
||||
uint32 unwind_code_offset = unwind_info_offset - PLT_ITEM_SIZE;
|
||||
#endif
|
||||
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
|
||||
unwind_info= (AOTUnwindInfo *)((uint8*)module->code + module->code_size
|
||||
- sizeof(AOTUnwindInfo));
|
||||
unwind_info->Version = 1;
|
||||
unwind_info->Flags = UNW_FLAG_EHANDLER;
|
||||
*(uint32*)&unwind_info->UnwindCode[0] = unwind_code_offset;
|
||||
|
||||
size = sizeof(RUNTIME_FUNCTION) * (uint64)module->func_count;
|
||||
if (size > 0
|
||||
&& !(rtl_func_table = module->rtl_func_table =
|
||||
loader_malloc(size, error_buf, error_buf_size))) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
size = sizeof(void*) * (uint64)module->func_count;
|
||||
if (size > 0
|
||||
|
@ -1205,9 +1227,31 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
|||
#if defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_THUMB_VFP)
|
||||
/* bits[0] of thumb function address must be 1 */
|
||||
module->func_ptrs[i] = (void*)((uintptr_t)module->func_ptrs[i] | 1);
|
||||
#endif
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
|
||||
rtl_func_table[i].BeginAddress = (DWORD)text_offset;
|
||||
if (i > 0) {
|
||||
rtl_func_table[i].EndAddress = rtl_func_table[i - 1].BeginAddress;
|
||||
}
|
||||
rtl_func_table[i].UnwindInfoAddress = (DWORD)unwind_info_offset;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
|
||||
if (module->func_count > 0) {
|
||||
rtl_func_table[module->func_count - 1].EndAddress =
|
||||
(DWORD)(module->code_size - get_plt_table_size());
|
||||
|
||||
if (!RtlAddFunctionTable(rtl_func_table, module->func_count,
|
||||
(DWORD64)(uintptr_t)module->code)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"add dynamic function table failed");
|
||||
return false;
|
||||
}
|
||||
module->rtl_func_table_registered = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set start function when function pointers are resolved */
|
||||
if (module->start_func_index != (uint32)-1) {
|
||||
if (module->start_func_index >= module->import_func_count)
|
||||
|
@ -2621,6 +2665,14 @@ aot_unload(AOTModule *module)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
|
||||
if (module->rtl_func_table) {
|
||||
if (module->rtl_func_table_registered)
|
||||
RtlDeleteFunctionTable(module->rtl_func_table);
|
||||
wasm_runtime_free(module->rtl_func_table);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (module->data_sections)
|
||||
destroy_object_data_sections(module->data_sections,
|
||||
module->data_section_count);
|
||||
|
|
|
@ -339,6 +339,11 @@ memories_deinstantiate(AOTModuleInstance *module_inst)
|
|||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||
wasm_runtime_free(memory_inst->memory_data.ptr);
|
||||
#else
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
os_mem_decommit(memory_inst->memory_data.ptr,
|
||||
memory_inst->num_bytes_per_page
|
||||
* memory_inst->cur_page_count);
|
||||
#endif
|
||||
os_munmap((uint8*)memory_inst->memory_data.ptr,
|
||||
8 * (uint64)BH_GB);
|
||||
#endif
|
||||
|
@ -499,8 +504,19 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
if (!os_mem_commit(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) {
|
||||
set_error_buf(error_buf, error_buf_size, "commit memory failed");
|
||||
os_munmap(mapped_mem, map_size);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (os_mprotect(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
|
||||
set_error_buf(error_buf, error_buf_size, "mprotec memory failed");
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
os_mem_decommit(p, total_size);
|
||||
#endif
|
||||
os_munmap(mapped_mem, map_size);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -583,6 +599,10 @@ fail1:
|
|||
if (memory_inst->memory_data.ptr)
|
||||
wasm_runtime_free(memory_inst->memory_data.ptr);
|
||||
#else
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
if (memory_inst->memory_data.ptr)
|
||||
os_mem_decommit(p, total_size);
|
||||
#endif
|
||||
os_munmap(mapped_mem, map_size);
|
||||
#endif
|
||||
memory_inst->memory_data.ptr = NULL;
|
||||
|
@ -1129,8 +1149,16 @@ aot_lookup_function(const AOTModuleInstance *module_inst,
|
|||
|
||||
static os_thread_local_attribute WASMExecEnv *aot_exec_env = NULL;
|
||||
|
||||
#ifndef BH_PLATFORM_WINDOWS
|
||||
static void
|
||||
aot_signal_handler(void *sig_addr)
|
||||
#else
|
||||
EXCEPTION_DISPOSITION
|
||||
aot_exception_handler(PEXCEPTION_RECORD ExceptionRecord,
|
||||
ULONG64 EstablisherFrame,
|
||||
PCONTEXT ContextRecord,
|
||||
PDISPATCHER_CONTEXT DispatcherContext)
|
||||
#endif
|
||||
{
|
||||
AOTModuleInstance *module_inst;
|
||||
AOTMemoryInstance *memory_inst;
|
||||
|
@ -1140,11 +1168,18 @@ aot_signal_handler(void *sig_addr)
|
|||
uint8 *stack_min_addr;
|
||||
uint32 page_size;
|
||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
uint8 *sig_addr = (uint8*)ExceptionRecord->ExceptionInformation[1];
|
||||
#endif
|
||||
|
||||
/* Check whether current thread is running aot function */
|
||||
if (aot_exec_env
|
||||
&& aot_exec_env->handle == os_self_thread()
|
||||
&& (jmpbuf_node = aot_exec_env->jmpbuf_stack_top)) {
|
||||
&& (jmpbuf_node = aot_exec_env->jmpbuf_stack_top)
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
&& ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION
|
||||
#endif
|
||||
) {
|
||||
/* Get mapped mem info of current instance */
|
||||
module_inst = (AOTModuleInstance *)aot_exec_env->module_inst;
|
||||
/* Get the default memory instance */
|
||||
|
@ -1176,18 +1211,60 @@ aot_signal_handler(void *sig_addr)
|
|||
os_longjmp(jmpbuf_node->jmpbuf, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
ContextRecord->Rip += 3;
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
(void)EstablisherFrame;
|
||||
(void)ContextRecord;
|
||||
(void)DispatcherContext;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
static LONG
|
||||
stack_overflow_handler(EXCEPTION_POINTERS *exce_info)
|
||||
{
|
||||
AOTModuleInstance* module_inst;
|
||||
WASMJmpBuf* jmpbuf_node;
|
||||
|
||||
/* Check whether it is stack overflow exception and
|
||||
current thread is running aot function */
|
||||
if (exce_info->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW
|
||||
&& aot_exec_env
|
||||
&& aot_exec_env->handle == os_self_thread()
|
||||
&& (jmpbuf_node = aot_exec_env->jmpbuf_stack_top)) {
|
||||
/* Set stack overflow exception and let the aot func continue
|
||||
to run, when the aot func returns, the caller will check
|
||||
whether the exception is thrown and return to runtime, and
|
||||
the damaged stack will be recovered by _resetstkoflw(). */
|
||||
module_inst = (AOTModuleInstance*)aot_exec_env->module_inst;
|
||||
aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
aot_signal_init()
|
||||
{
|
||||
#ifndef BH_PLATFORM_WINDOWS
|
||||
return os_signal_init(aot_signal_handler) == 0 ? true : false;
|
||||
#else
|
||||
return AddVectoredExceptionHandler(1, stack_overflow_handler)
|
||||
? true : false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
aot_signal_destroy()
|
||||
{
|
||||
#ifndef BH_PLATFORM_WINDOWS
|
||||
os_signal_destroy();
|
||||
#else
|
||||
RemoveVectoredExceptionHandler(stack_overflow_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1201,6 +1278,10 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
|||
WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
|
||||
uint32 page_size = os_getpagesize();
|
||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
||||
#if BH_PLATFORM_WINDOWS
|
||||
const char *exce;
|
||||
int result;
|
||||
#endif
|
||||
bool ret;
|
||||
|
||||
/* Check native stack overflow firstly to ensure we have enough
|
||||
|
@ -1226,6 +1307,15 @@ invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
|
|||
ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
|
||||
signature, attachment,
|
||||
argv, argc, argv_ret);
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
if ((exce = aot_get_exception(module_inst))
|
||||
&& strstr(exce, "native stack overflow")) {
|
||||
/* After a stack overflow, the stack was left
|
||||
in a damaged state, let the CRT repair it */
|
||||
result = _resetstkoflw();
|
||||
bh_assert(result != 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* Exception has been set in signal handler before calling longjmp */
|
||||
|
@ -1992,9 +2082,21 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
if (!os_mem_commit(memory_inst->memory_data_end.ptr,
|
||||
num_bytes_per_page * inc_page_count,
|
||||
MMAP_PROT_READ | MMAP_PROT_WRITE)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (os_mprotect(memory_inst->memory_data_end.ptr,
|
||||
num_bytes_per_page * inc_page_count,
|
||||
MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
os_mem_decommit(memory_inst->memory_data_end.ptr,
|
||||
num_bytes_per_page * inc_page_count);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,28 @@ typedef struct AOTFunctionInstance {
|
|||
} u;
|
||||
} AOTFunctionInstance;
|
||||
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
|
||||
typedef struct AOTUnwindInfo {
|
||||
uint8 Version : 3;
|
||||
uint8 Flags : 5;
|
||||
uint8 SizeOfProlog;
|
||||
uint8 CountOfCodes;
|
||||
uint8 FrameRegister : 4;
|
||||
uint8 FrameOffset : 4;
|
||||
struct {
|
||||
struct {
|
||||
uint8 CodeOffset;
|
||||
uint8 UnwindOp : 4;
|
||||
uint8 OpInfo : 4;
|
||||
};
|
||||
uint16 FrameOffset;
|
||||
} UnwindCode[1];
|
||||
} AOTUnwindInfo;
|
||||
|
||||
/* size of mov instruction and jmp instruction */
|
||||
#define PLT_ITEM_SIZE 12
|
||||
#endif
|
||||
|
||||
typedef struct AOTModule {
|
||||
uint32 module_type;
|
||||
|
||||
|
@ -173,6 +195,14 @@ typedef struct AOTModule {
|
|||
uint32 float_plt_count;
|
||||
#endif
|
||||
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
|
||||
/* dynamic function table to be added by RtlAddFunctionTable(),
|
||||
used to unwind the call stack and register exception handler
|
||||
for AOT functions */
|
||||
RUNTIME_FUNCTION *rtl_func_table;
|
||||
bool rtl_func_table_registered;
|
||||
#endif
|
||||
|
||||
/* data sections in AOT object file, including .data, .rodata
|
||||
* and .rodata.cstN. NULL for JIT mode. */
|
||||
AOTObjectDataSection *data_sections;
|
||||
|
@ -629,6 +659,14 @@ aot_signal_init();
|
|||
|
||||
void
|
||||
aot_signal_destroy();
|
||||
|
||||
#ifdef BH_PLATFORM_WINDOWS
|
||||
EXCEPTION_DISPOSITION
|
||||
aot_exception_handler(PEXCEPTION_RECORD ExceptionRecord,
|
||||
ULONG64 EstablisherFrame,
|
||||
PCONTEXT ContextRecord,
|
||||
PDISPATCHER_CONTEXT DispatcherContext);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void
|
||||
|
|
|
@ -61,15 +61,22 @@ get_plt_item_size()
|
|||
uint32
|
||||
get_plt_table_size()
|
||||
{
|
||||
return get_plt_item_size() * (sizeof(target_sym_map) / sizeof(SymbolMap));
|
||||
uint32 size = get_plt_item_size()
|
||||
* (sizeof(target_sym_map) / sizeof(SymbolMap));
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
|
||||
size += get_plt_item_size() + sizeof(AOTUnwindInfo);
|
||||
#endif
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
init_plt_table(uint8 *plt)
|
||||
{
|
||||
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
|
||||
uint8 *p;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
uint8 *p = plt;
|
||||
p = plt;
|
||||
/* mov symbol_addr, rax */
|
||||
*p++ = 0x48;
|
||||
*p++ = 0xB8;
|
||||
|
@ -80,6 +87,18 @@ init_plt_table(uint8 *plt)
|
|||
*p++ = 0xE0;
|
||||
plt += get_plt_item_size();
|
||||
}
|
||||
|
||||
#if defined(OS_ENABLE_HW_BOUND_CHECK) && defined(BH_PLATFORM_WINDOWS)
|
||||
p = plt;
|
||||
/* mov exception_handler, rax */
|
||||
*p++ = 0x48;
|
||||
*p++ = 0xB8;
|
||||
*(uint64*)p = (uint64)(uintptr_t)aot_exception_handler;
|
||||
p += sizeof(uint64);
|
||||
/* jmp rax */
|
||||
*p++ = 0xFF;
|
||||
*p++ = 0xE0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -2707,7 +2707,8 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
|||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
case VALUE_TYPE_FUNCREF:
|
||||
{
|
||||
if (strncasecmp(argv[i], "null", 4) == 0) {
|
||||
if (strncmp(argv[i], "null", 4) == 0
|
||||
|| strncmp(argv[i], "NULL", 4) == 0) {
|
||||
argv1[p++] = NULL_REF;
|
||||
}
|
||||
else {
|
||||
|
@ -2717,7 +2718,8 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
|||
}
|
||||
case VALUE_TYPE_EXTERNREF:
|
||||
{
|
||||
if (strncasecmp(argv[i], "null", 4) == 0) {
|
||||
if (strncmp(argv[i], "null", 4) == 0
|
||||
|| strncmp(argv[i], "NULL", 4) == 0) {
|
||||
argv1[p++] = NULL_REF;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -657,7 +657,11 @@ strcpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src)
|
|||
if (!validate_native_addr(dst, len))
|
||||
return 0;
|
||||
|
||||
#ifndef BH_PLATFORM_WINDOWS
|
||||
strncpy(dst, src, len);
|
||||
#else
|
||||
strncpy_s(dst, len, src, len);
|
||||
#endif
|
||||
return addr_native_to_app(dst);
|
||||
}
|
||||
|
||||
|
@ -671,7 +675,11 @@ strncpy_wrapper(wasm_exec_env_t exec_env,
|
|||
if (!validate_native_addr(dst, size))
|
||||
return 0;
|
||||
|
||||
#ifndef BH_PLATFORM_WINDOWS
|
||||
strncpy(dst, src, size);
|
||||
#else
|
||||
strncpy_s(dst, size, src, size);
|
||||
#endif
|
||||
return addr_native_to_app(dst);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,3 +43,16 @@ os_vprintf(const char *format, va_list ap)
|
|||
#endif
|
||||
}
|
||||
|
||||
unsigned
|
||||
os_getpagesize()
|
||||
{
|
||||
SYSTEM_INFO sys_info;
|
||||
GetNativeSystemInfo(&sys_info);
|
||||
return (unsigned)sys_info.dwPageSize;
|
||||
}
|
||||
|
||||
void
|
||||
os_dcache_flush(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include <Windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -49,13 +50,34 @@ typedef struct {
|
|||
unsigned int waiting_count;
|
||||
} korp_cond;
|
||||
|
||||
static inline size_t
|
||||
getpagesize()
|
||||
{
|
||||
SYSTEM_INFO S;
|
||||
GetNativeSystemInfo(&S);
|
||||
return S.dwPageSize;
|
||||
}
|
||||
unsigned os_getpagesize();
|
||||
void *os_mem_commit(void *ptr, size_t size, int flags);
|
||||
void os_mem_decommit(void *ptr, size_t size);
|
||||
|
||||
#define os_thread_local_attribute __declspec(thread)
|
||||
|
||||
#if WASM_DISABLE_HW_BOUND_CHECK == 0
|
||||
#if defined(BUILD_TARGET_X86_64) \
|
||||
|| defined(BUILD_TARGET_AMD_64)
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#define OS_ENABLE_HW_BOUND_CHECK
|
||||
|
||||
typedef jmp_buf korp_jmpbuf;
|
||||
|
||||
#define os_setjmp setjmp
|
||||
#define os_longjmp longjmp
|
||||
|
||||
bool os_thread_init_stack_guard_pages();
|
||||
|
||||
void os_thread_destroy_stack_guard_pages();
|
||||
|
||||
#define os_signal_unmask() (void)0
|
||||
#define os_sigreturn() (void)0
|
||||
|
||||
#endif /* end of BUILD_TARGET_X86_64/AMD_64 */
|
||||
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -5,81 +5,133 @@
|
|||
|
||||
#include "platform_api_vmcore.h"
|
||||
|
||||
void * os_mmap(void *hint, size_t size, int prot, int flags)
|
||||
#define TRACE_MEMMAP 0
|
||||
|
||||
static DWORD
|
||||
access_to_win32_flags(int prot)
|
||||
{
|
||||
DWORD AllocType = MEM_RESERVE | MEM_COMMIT;
|
||||
DWORD flProtect = PAGE_NOACCESS;
|
||||
DWORD protect = PAGE_NOACCESS;
|
||||
|
||||
if (prot & MMAP_PROT_EXEC) {
|
||||
if (prot & MMAP_PROT_WRITE)
|
||||
protect = PAGE_EXECUTE_READWRITE;
|
||||
else
|
||||
protect = PAGE_EXECUTE_READ;
|
||||
}
|
||||
else if (prot & MMAP_PROT_WRITE) {
|
||||
protect = PAGE_READWRITE;
|
||||
}
|
||||
else if (prot & MMAP_PROT_READ) {
|
||||
protect = PAGE_READONLY;
|
||||
}
|
||||
|
||||
return protect;
|
||||
}
|
||||
|
||||
void *
|
||||
os_mmap(void *hint, size_t size, int prot, int flags)
|
||||
{
|
||||
DWORD alloc_type = MEM_RESERVE;
|
||||
DWORD protect;
|
||||
size_t request_size, page_size;
|
||||
void *addr;
|
||||
|
||||
page_size = getpagesize();
|
||||
page_size = os_getpagesize();
|
||||
request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
if (request_size < size)
|
||||
/* integer overflow */
|
||||
return NULL;
|
||||
|
||||
if (request_size == 0)
|
||||
request_size = page_size;
|
||||
|
||||
if (prot & MMAP_PROT_EXEC) {
|
||||
if (prot & MMAP_PROT_WRITE)
|
||||
flProtect = PAGE_EXECUTE_READWRITE;
|
||||
else
|
||||
flProtect = PAGE_EXECUTE_READ;
|
||||
protect = access_to_win32_flags(prot);
|
||||
if (protect != PAGE_NOACCESS) {
|
||||
alloc_type |= MEM_COMMIT;
|
||||
}
|
||||
else if (prot & MMAP_PROT_WRITE)
|
||||
flProtect = PAGE_READWRITE;
|
||||
else if (prot & MMAP_PROT_READ)
|
||||
flProtect = PAGE_READONLY;
|
||||
|
||||
addr = VirtualAlloc((LPVOID)hint, request_size, alloc_type, protect);
|
||||
|
||||
addr = VirtualAlloc((LPVOID)hint, request_size, AllocType,
|
||||
flProtect);
|
||||
#if TRACE_MEMMAP != 0
|
||||
printf("Map memory, request_size: %zu, alloc_type: 0x%x, "
|
||||
"protect: 0x%x, ret: %p\n",
|
||||
request_size, alloc_type, protect, addr);
|
||||
#endif
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
os_munmap(void *addr, size_t size)
|
||||
{
|
||||
size_t page_size = getpagesize();
|
||||
size_t page_size = os_getpagesize();
|
||||
size_t request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
if (addr) {
|
||||
if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
|
||||
if (VirtualFree(addr, size, MEM_DECOMMIT) == 0) {
|
||||
os_printf("os_munmap error addr:%p, size:0x%lx, errno:%d\n",
|
||||
addr, request_size, errno);
|
||||
}
|
||||
if (!VirtualFree(addr, request_size, MEM_DECOMMIT)) {
|
||||
printf("warning: os_munmap decommit pages failed, "
|
||||
"addr: %p, request_size: %zu, errno: %d\n",
|
||||
addr, request_size, errno);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VirtualFree(addr, 0, MEM_RELEASE)) {
|
||||
printf("warning: os_munmap release pages failed, "
|
||||
"addr: %p, size: %zu, errno:%d\n",
|
||||
addr, request_size, errno);
|
||||
}
|
||||
}
|
||||
#if TRACE_MEMMAP != 0
|
||||
printf("Unmap memory, addr: %p, request_size: %zu\n",
|
||||
addr, request_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *
|
||||
os_mem_commit(void *addr, size_t size, int flags)
|
||||
{
|
||||
DWORD protect = access_to_win32_flags(flags);
|
||||
size_t page_size = os_getpagesize();
|
||||
size_t request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
if (!addr)
|
||||
return NULL;
|
||||
|
||||
#if TRACE_MEMMAP != 0
|
||||
printf("Commit memory, addr: %p, request_size: %zu, protect: 0x%x\n",
|
||||
addr, request_size, protect);
|
||||
#endif
|
||||
return VirtualAlloc((LPVOID)addr, request_size, MEM_COMMIT, protect);
|
||||
}
|
||||
|
||||
void
|
||||
os_mem_decommit(void *addr, size_t size)
|
||||
{
|
||||
size_t page_size = os_getpagesize();
|
||||
size_t request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
#if TRACE_MEMMAP != 0
|
||||
printf("Decommit memory, addr: %p, request_size: %zu\n",
|
||||
addr, request_size);
|
||||
#endif
|
||||
VirtualFree((LPVOID)addr, request_size, MEM_DECOMMIT);
|
||||
}
|
||||
|
||||
int
|
||||
os_mprotect(void *addr, size_t size, int prot)
|
||||
{
|
||||
DWORD AllocType = MEM_RESERVE | MEM_COMMIT;
|
||||
DWORD flProtect = PAGE_NOACCESS;
|
||||
DWORD protect;
|
||||
size_t page_size = os_getpagesize();
|
||||
size_t request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
if (prot & MMAP_PROT_EXEC) {
|
||||
if (prot & MMAP_PROT_WRITE)
|
||||
flProtect = PAGE_EXECUTE_READWRITE;
|
||||
else
|
||||
flProtect = PAGE_EXECUTE_READ;
|
||||
}
|
||||
else if (prot & MMAP_PROT_WRITE)
|
||||
flProtect = PAGE_READWRITE;
|
||||
else if (prot & MMAP_PROT_READ)
|
||||
flProtect = PAGE_READONLY;
|
||||
|
||||
return VirtualProtect((LPVOID)addr, size, flProtect, NULL);
|
||||
protect = access_to_win32_flags(prot);
|
||||
#if TRACE_MEMMAP != 0
|
||||
printf("Mprotect memory, addr: %p, request_size: %zu, protect: 0x%x\n",
|
||||
addr, request_size, protect);
|
||||
#endif
|
||||
return VirtualProtect((LPVOID)addr, request_size, protect, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
os_dcache_flush(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -149,7 +149,32 @@ void os_thread_exit(void *retval)
|
|||
{
|
||||
}
|
||||
|
||||
static os_thread_local_attribute uint8 *thread_stack_boundary = NULL;
|
||||
|
||||
uint8 *os_thread_get_stack_boundary()
|
||||
{
|
||||
return NULL;
|
||||
ULONG_PTR low_limit = 0, high_limit = 0;
|
||||
uint32 page_size;
|
||||
|
||||
if (thread_stack_boundary)
|
||||
return thread_stack_boundary;
|
||||
|
||||
page_size = os_getpagesize();
|
||||
GetCurrentThreadStackLimits(&low_limit, &high_limit);
|
||||
/* 4 pages are set unaccessible by system, we reserved
|
||||
one more page at least for safety */
|
||||
thread_stack_boundary = (uint8*)(uintptr_t)low_limit + page_size * 5;
|
||||
return thread_stack_boundary;
|
||||
}
|
||||
|
||||
bool
|
||||
os_thread_init_stack_guard_pages()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
os_thread_destroy_stack_guard_pages()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -76,9 +76,11 @@ message ("-- Build as target ${WAMR_BUILD_TARGET}")
|
|||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64" OR WAMR_BUILD_TARGET MATCHES "AARCH64.*")
|
||||
# Add -fPIC flag if build as 64-bit
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
|
||||
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
|
||||
# Add -fPIC flag if build as 64-bit
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
|
||||
endif ()
|
||||
else ()
|
||||
add_definitions (-m32)
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
|
||||
|
|
Loading…
Reference in New Issue
Block a user