mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-09 05:06:17 +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 (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.*")
|
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
|
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
# Add -fPIC flag if build as 64-bit
|
||||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||||
|
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
|
||||||
|
endif ()
|
||||||
else ()
|
else ()
|
||||||
add_definitions (-m32)
|
add_definitions (-m32)
|
||||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -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);
|
read_uint32(buf, buf_end, data_sections[i].size);
|
||||||
|
|
||||||
/* Allocate memory for data */
|
/* 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))) {
|
os_mmap(NULL, data_sections[i].size, map_prot, map_flags))) {
|
||||||
set_error_buf(error_buf, error_buf_size,
|
set_error_buf(error_buf, error_buf_size,
|
||||||
"allocate memory failed");
|
"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;
|
const uint8 *p = buf, *p_end = buf_end;
|
||||||
uint32 i;
|
uint32 i;
|
||||||
uint64 size, text_offset;
|
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;
|
size = sizeof(void*) * (uint64)module->func_count;
|
||||||
if (size > 0
|
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)
|
#if defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_THUMB_VFP)
|
||||||
/* bits[0] of thumb function address must be 1 */
|
/* bits[0] of thumb function address must be 1 */
|
||||||
module->func_ptrs[i] = (void*)((uintptr_t)module->func_ptrs[i] | 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
|
#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 */
|
/* Set start function when function pointers are resolved */
|
||||||
if (module->start_func_index != (uint32)-1) {
|
if (module->start_func_index != (uint32)-1) {
|
||||||
if (module->start_func_index >= module->import_func_count)
|
if (module->start_func_index >= module->import_func_count)
|
||||||
|
@ -2621,6 +2665,14 @@ aot_unload(AOTModule *module)
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
if (module->data_sections)
|
||||||
destroy_object_data_sections(module->data_sections,
|
destroy_object_data_sections(module->data_sections,
|
||||||
module->data_section_count);
|
module->data_section_count);
|
||||||
|
|
|
@ -339,6 +339,11 @@ memories_deinstantiate(AOTModuleInstance *module_inst)
|
||||||
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
#ifndef OS_ENABLE_HW_BOUND_CHECK
|
||||||
wasm_runtime_free(memory_inst->memory_data.ptr);
|
wasm_runtime_free(memory_inst->memory_data.ptr);
|
||||||
#else
|
#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,
|
os_munmap((uint8*)memory_inst->memory_data.ptr,
|
||||||
8 * (uint64)BH_GB);
|
8 * (uint64)BH_GB);
|
||||||
#endif
|
#endif
|
||||||
|
@ -499,8 +504,19 @@ memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
|
||||||
return NULL;
|
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) {
|
if (os_mprotect(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
|
||||||
set_error_buf(error_buf, error_buf_size, "mprotec memory failed");
|
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);
|
os_munmap(mapped_mem, map_size);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -583,6 +599,10 @@ fail1:
|
||||||
if (memory_inst->memory_data.ptr)
|
if (memory_inst->memory_data.ptr)
|
||||||
wasm_runtime_free(memory_inst->memory_data.ptr);
|
wasm_runtime_free(memory_inst->memory_data.ptr);
|
||||||
#else
|
#else
|
||||||
|
#ifdef BH_PLATFORM_WINDOWS
|
||||||
|
if (memory_inst->memory_data.ptr)
|
||||||
|
os_mem_decommit(p, total_size);
|
||||||
|
#endif
|
||||||
os_munmap(mapped_mem, map_size);
|
os_munmap(mapped_mem, map_size);
|
||||||
#endif
|
#endif
|
||||||
memory_inst->memory_data.ptr = NULL;
|
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;
|
static os_thread_local_attribute WASMExecEnv *aot_exec_env = NULL;
|
||||||
|
|
||||||
|
#ifndef BH_PLATFORM_WINDOWS
|
||||||
static void
|
static void
|
||||||
aot_signal_handler(void *sig_addr)
|
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;
|
AOTModuleInstance *module_inst;
|
||||||
AOTMemoryInstance *memory_inst;
|
AOTMemoryInstance *memory_inst;
|
||||||
|
@ -1140,11 +1168,18 @@ aot_signal_handler(void *sig_addr)
|
||||||
uint8 *stack_min_addr;
|
uint8 *stack_min_addr;
|
||||||
uint32 page_size;
|
uint32 page_size;
|
||||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
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 */
|
/* Check whether current thread is running aot function */
|
||||||
if (aot_exec_env
|
if (aot_exec_env
|
||||||
&& aot_exec_env->handle == os_self_thread()
|
&& 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 */
|
/* Get mapped mem info of current instance */
|
||||||
module_inst = (AOTModuleInstance *)aot_exec_env->module_inst;
|
module_inst = (AOTModuleInstance *)aot_exec_env->module_inst;
|
||||||
/* Get the default memory instance */
|
/* Get the default memory instance */
|
||||||
|
@ -1176,18 +1211,60 @@ aot_signal_handler(void *sig_addr)
|
||||||
os_longjmp(jmpbuf_node->jmpbuf, 1);
|
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
|
bool
|
||||||
aot_signal_init()
|
aot_signal_init()
|
||||||
{
|
{
|
||||||
|
#ifndef BH_PLATFORM_WINDOWS
|
||||||
return os_signal_init(aot_signal_handler) == 0 ? true : false;
|
return os_signal_init(aot_signal_handler) == 0 ? true : false;
|
||||||
|
#else
|
||||||
|
return AddVectoredExceptionHandler(1, stack_overflow_handler)
|
||||||
|
? true : false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
aot_signal_destroy()
|
aot_signal_destroy()
|
||||||
{
|
{
|
||||||
|
#ifndef BH_PLATFORM_WINDOWS
|
||||||
os_signal_destroy();
|
os_signal_destroy();
|
||||||
|
#else
|
||||||
|
RemoveVectoredExceptionHandler(stack_overflow_handler);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
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;
|
WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
|
||||||
uint32 page_size = os_getpagesize();
|
uint32 page_size = os_getpagesize();
|
||||||
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
|
||||||
|
#if BH_PLATFORM_WINDOWS
|
||||||
|
const char *exce;
|
||||||
|
int result;
|
||||||
|
#endif
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
/* Check native stack overflow firstly to ensure we have enough
|
/* 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,
|
ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
|
||||||
signature, attachment,
|
signature, attachment,
|
||||||
argv, argc, argv_ret);
|
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 {
|
else {
|
||||||
/* Exception has been set in signal handler before calling longjmp */
|
/* 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;
|
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,
|
if (os_mprotect(memory_inst->memory_data_end.ptr,
|
||||||
num_bytes_per_page * inc_page_count,
|
num_bytes_per_page * inc_page_count,
|
||||||
MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,28 @@ typedef struct AOTFunctionInstance {
|
||||||
} u;
|
} u;
|
||||||
} AOTFunctionInstance;
|
} 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 {
|
typedef struct AOTModule {
|
||||||
uint32 module_type;
|
uint32 module_type;
|
||||||
|
|
||||||
|
@ -173,6 +195,14 @@ typedef struct AOTModule {
|
||||||
uint32 float_plt_count;
|
uint32 float_plt_count;
|
||||||
#endif
|
#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
|
/* data sections in AOT object file, including .data, .rodata
|
||||||
* and .rodata.cstN. NULL for JIT mode. */
|
* and .rodata.cstN. NULL for JIT mode. */
|
||||||
AOTObjectDataSection *data_sections;
|
AOTObjectDataSection *data_sections;
|
||||||
|
@ -629,6 +659,14 @@ aot_signal_init();
|
||||||
|
|
||||||
void
|
void
|
||||||
aot_signal_destroy();
|
aot_signal_destroy();
|
||||||
|
|
||||||
|
#ifdef BH_PLATFORM_WINDOWS
|
||||||
|
EXCEPTION_DISPOSITION
|
||||||
|
aot_exception_handler(PEXCEPTION_RECORD ExceptionRecord,
|
||||||
|
ULONG64 EstablisherFrame,
|
||||||
|
PCONTEXT ContextRecord,
|
||||||
|
PDISPATCHER_CONTEXT DispatcherContext);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -61,15 +61,22 @@ get_plt_item_size()
|
||||||
uint32
|
uint32
|
||||||
get_plt_table_size()
|
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
|
void
|
||||||
init_plt_table(uint8 *plt)
|
init_plt_table(uint8 *plt)
|
||||||
{
|
{
|
||||||
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
|
uint32 i, num = sizeof(target_sym_map) / sizeof(SymbolMap);
|
||||||
|
uint8 *p;
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
uint8 *p = plt;
|
p = plt;
|
||||||
/* mov symbol_addr, rax */
|
/* mov symbol_addr, rax */
|
||||||
*p++ = 0x48;
|
*p++ = 0x48;
|
||||||
*p++ = 0xB8;
|
*p++ = 0xB8;
|
||||||
|
@ -80,6 +87,18 @@ init_plt_table(uint8 *plt)
|
||||||
*p++ = 0xE0;
|
*p++ = 0xE0;
|
||||||
plt += get_plt_item_size();
|
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
|
static bool
|
||||||
|
|
|
@ -2707,7 +2707,8 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
||||||
#if WASM_ENABLE_REF_TYPES != 0
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
case VALUE_TYPE_FUNCREF:
|
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;
|
argv1[p++] = NULL_REF;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2717,7 +2718,8 @@ wasm_application_execute_func(WASMModuleInstanceCommon *module_inst,
|
||||||
}
|
}
|
||||||
case VALUE_TYPE_EXTERNREF:
|
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;
|
argv1[p++] = NULL_REF;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -657,7 +657,11 @@ strcpy_wrapper(wasm_exec_env_t exec_env, char *dst, const char *src)
|
||||||
if (!validate_native_addr(dst, len))
|
if (!validate_native_addr(dst, len))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#ifndef BH_PLATFORM_WINDOWS
|
||||||
strncpy(dst, src, len);
|
strncpy(dst, src, len);
|
||||||
|
#else
|
||||||
|
strncpy_s(dst, len, src, len);
|
||||||
|
#endif
|
||||||
return addr_native_to_app(dst);
|
return addr_native_to_app(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,7 +675,11 @@ strncpy_wrapper(wasm_exec_env_t exec_env,
|
||||||
if (!validate_native_addr(dst, size))
|
if (!validate_native_addr(dst, size))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#ifndef BH_PLATFORM_WINDOWS
|
||||||
strncpy(dst, src, size);
|
strncpy(dst, src, size);
|
||||||
|
#else
|
||||||
|
strncpy_s(dst, size, src, size);
|
||||||
|
#endif
|
||||||
return addr_native_to_app(dst);
|
return addr_native_to_app(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,3 +43,16 @@ os_vprintf(const char *format, va_list ap)
|
||||||
#endif
|
#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/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <malloc.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -49,13 +50,34 @@ typedef struct {
|
||||||
unsigned int waiting_count;
|
unsigned int waiting_count;
|
||||||
} korp_cond;
|
} korp_cond;
|
||||||
|
|
||||||
static inline size_t
|
unsigned os_getpagesize();
|
||||||
getpagesize()
|
void *os_mem_commit(void *ptr, size_t size, int flags);
|
||||||
{
|
void os_mem_decommit(void *ptr, size_t size);
|
||||||
SYSTEM_INFO S;
|
|
||||||
GetNativeSystemInfo(&S);
|
#define os_thread_local_attribute __declspec(thread)
|
||||||
return S.dwPageSize;
|
|
||||||
}
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,81 +5,133 @@
|
||||||
|
|
||||||
#include "platform_api_vmcore.h"
|
#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 protect = PAGE_NOACCESS;
|
||||||
DWORD flProtect = 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;
|
size_t request_size, page_size;
|
||||||
void *addr;
|
void *addr;
|
||||||
|
|
||||||
page_size = getpagesize();
|
page_size = os_getpagesize();
|
||||||
request_size = (size + page_size - 1) & ~(page_size - 1);
|
request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||||
|
|
||||||
if (request_size < size)
|
if (request_size < size)
|
||||||
/* integer overflow */
|
/* integer overflow */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (request_size == 0)
|
protect = access_to_win32_flags(prot);
|
||||||
request_size = page_size;
|
if (protect != PAGE_NOACCESS) {
|
||||||
|
alloc_type |= MEM_COMMIT;
|
||||||
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;
|
|
||||||
|
|
||||||
|
addr = VirtualAlloc((LPVOID)hint, request_size, alloc_type, protect);
|
||||||
|
|
||||||
addr = VirtualAlloc((LPVOID)hint, request_size, AllocType,
|
#if TRACE_MEMMAP != 0
|
||||||
flProtect);
|
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;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
os_munmap(void *addr, size_t size)
|
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);
|
size_t request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||||
|
|
||||||
if (addr) {
|
if (addr) {
|
||||||
if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
|
if (!VirtualFree(addr, request_size, MEM_DECOMMIT)) {
|
||||||
if (VirtualFree(addr, size, MEM_DECOMMIT) == 0) {
|
printf("warning: os_munmap decommit pages failed, "
|
||||||
os_printf("os_munmap error addr:%p, size:0x%lx, errno:%d\n",
|
"addr: %p, request_size: %zu, errno: %d\n",
|
||||||
addr, request_size, errno);
|
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
|
int
|
||||||
os_mprotect(void *addr, size_t size, int prot)
|
os_mprotect(void *addr, size_t size, int prot)
|
||||||
{
|
{
|
||||||
DWORD AllocType = MEM_RESERVE | MEM_COMMIT;
|
DWORD protect;
|
||||||
DWORD flProtect = PAGE_NOACCESS;
|
size_t page_size = os_getpagesize();
|
||||||
|
size_t request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||||
|
|
||||||
if (!addr)
|
if (!addr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (prot & MMAP_PROT_EXEC) {
|
protect = access_to_win32_flags(prot);
|
||||||
if (prot & MMAP_PROT_WRITE)
|
#if TRACE_MEMMAP != 0
|
||||||
flProtect = PAGE_EXECUTE_READWRITE;
|
printf("Mprotect memory, addr: %p, request_size: %zu, protect: 0x%x\n",
|
||||||
else
|
addr, request_size, protect);
|
||||||
flProtect = PAGE_EXECUTE_READ;
|
#endif
|
||||||
}
|
return VirtualProtect((LPVOID)addr, request_size, protect, NULL);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
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 (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.*")
|
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
|
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
# Add -fPIC flag if build as 64-bit
|
||||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||||
|
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
|
||||||
|
endif ()
|
||||||
else ()
|
else ()
|
||||||
add_definitions (-m32)
|
add_definitions (-m32)
|
||||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
|
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user