Implement Windows boundary check with hardware trap (#623)

This commit is contained in:
Wenyong Huang 2021-04-27 17:18:27 +08:00 committed by GitHub
parent eb29385963
commit fa5f4fe940
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 400 additions and 63 deletions

View File

@ -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")

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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);
}

View File

@ -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)
{
}

View File

@ -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
}

View File

@ -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)
{
}

View File

@ -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()
{
}

View File

@ -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")