Add new E_TYPE_XIP to indicate XIP mode (#874)

Emit e_type = E_TYPE_XIP in target info section to indicate that it is
an XIP file, and replace related checks in aot loader.
This commit is contained in:
Huang Qi 2021-12-08 18:43:08 +08:00 committed by GitHub
parent 5fbf03fa6e
commit 208cafc776
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 34 deletions

View File

@ -53,6 +53,8 @@ static const aot_intrinsic g_intrinsic_mapping[] = {
{ "f64_convert_i64_u", "aot_intrinsic_u64_to_f64", AOT_INTRINSIC_FLAG_U64_TO_F64 }, { "f64_convert_i64_u", "aot_intrinsic_u64_to_f64", AOT_INTRINSIC_FLAG_U64_TO_F64 },
{ "f32_convert_i64_s", "aot_intrinsic_i64_to_f32", AOT_INTRINSIC_FLAG_I64_TO_F32 }, { "f32_convert_i64_s", "aot_intrinsic_i64_to_f32", AOT_INTRINSIC_FLAG_I64_TO_F32 },
{ "f32_convert_i64_u", "aot_intrinsic_u64_to_f32", AOT_INTRINSIC_FLAG_U64_TO_F32 }, { "f32_convert_i64_u", "aot_intrinsic_u64_to_f32", AOT_INTRINSIC_FLAG_U64_TO_F32 },
{ "i32_trunc_f32_u", "aot_intrinsic_f32_to_u32", AOT_INTRINSIC_FLAG_F32_TO_U32 },
{ "i32_trunc_f32_s", "aot_intrinsic_f32_to_i32", AOT_INTRINSIC_FLAG_F32_TO_I32 },
{ "i32_trunc_f64_u", "aot_intrinsic_f64_to_u32", AOT_INTRINSIC_FLAG_F64_TO_U32 }, { "i32_trunc_f64_u", "aot_intrinsic_f64_to_u32", AOT_INTRINSIC_FLAG_F64_TO_U32 },
{ "i32_trunc_f64_s", "aot_intrinsic_f64_to_i32", AOT_INTRINSIC_FLAG_F64_TO_I32 }, { "i32_trunc_f64_s", "aot_intrinsic_f64_to_i32", AOT_INTRINSIC_FLAG_F64_TO_I32 },
{ "f32_demote_f64", "aot_intrinsic_f64_to_f32", AOT_INTRINSIC_FLAG_F64_TO_F32 }, { "f32_demote_f64", "aot_intrinsic_f64_to_f32", AOT_INTRINSIC_FLAG_F64_TO_F32 },
@ -423,6 +425,9 @@ int32
aot_intrinsic_f32_cmp(AOTFloatCond cond, float32 lhs, float32 rhs) aot_intrinsic_f32_cmp(AOTFloatCond cond, float32 lhs, float32 rhs)
{ {
switch (cond) { switch (cond) {
case FLOAT_EQ:
return (float32)fabs(lhs - rhs) <= WA_FLT_EPSILON ? 1 : 0;
case FLOAT_LT: case FLOAT_LT:
return lhs < rhs ? 1 : 0; return lhs < rhs ? 1 : 0;
@ -451,6 +456,9 @@ int32
aot_intrinsic_f64_cmp(AOTFloatCond cond, float64 lhs, float64 rhs) aot_intrinsic_f64_cmp(AOTFloatCond cond, float64 lhs, float64 rhs)
{ {
switch (cond) { switch (cond) {
case FLOAT_EQ:
return fabs(lhs - rhs) <= WA_DBL_EPSILON ? 1 : 0;
case FLOAT_LT: case FLOAT_LT:
return lhs < rhs ? 1 : 0; return lhs < rhs ? 1 : 0;

View File

@ -174,6 +174,7 @@ GET_U64_FROM_ADDR(uint32 *addr)
#define E_TYPE_REL 1 /* Relocatable file */ #define E_TYPE_REL 1 /* Relocatable file */
#define E_TYPE_EXEC 2 /* Executable file */ #define E_TYPE_EXEC 2 /* Executable file */
#define E_TYPE_DYN 3 /* Shared object file */ #define E_TYPE_DYN 3 /* Shared object file */
#define E_TYPE_XIP 4 /* eXecute In Place file */
/* Legal values for e_machine (architecture). */ /* Legal values for e_machine (architecture). */
#define E_MACHINE_386 3 /* Intel 80386 */ #define E_MACHINE_386 3 /* Intel 80386 */
@ -422,10 +423,10 @@ load_target_info_section(const uint8 *buf, const uint8 *buf_end,
} }
/* Check target elf file type */ /* Check target elf file type */
if (target_info.e_type != E_TYPE_REL) { if (target_info.e_type != E_TYPE_REL && target_info.e_type != E_TYPE_XIP) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"invalid object file type, " "invalid object file type, "
"expected relocatable file type but got others"); "expected relocatable or XIP file type but got others");
return false; return false;
} }
@ -476,8 +477,6 @@ load_native_symbol_section(const uint8 *buf, const uint8 *buf_end,
read_uint32(p, p_end, cnt); read_uint32(p, p_end, cnt);
module->native_symbol_count = cnt;
if (cnt > 0) { if (cnt > 0) {
module->native_symbol_list = wasm_runtime_malloc(cnt * sizeof(void *)); module->native_symbol_list = wasm_runtime_malloc(cnt * sizeof(void *));
if (module->native_symbol_list == NULL) { if (module->native_symbol_list == NULL) {
@ -1467,7 +1466,7 @@ load_text_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
} }
#endif #endif
if ((module->code_size > 0) && (module->native_symbol_count == 0)) { if ((module->code_size > 0) && !module->is_indirect_mode) {
plt_base = (uint8 *)buf_end - get_plt_table_size(); plt_base = (uint8 *)buf_end - get_plt_table_size();
init_plt_table(plt_base); init_plt_table(plt_base);
} }
@ -2192,7 +2191,7 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
) { ) {
#if !defined(BH_PLATFORM_LINUX) && !defined(BH_PLATFORM_LINUX_SGX) \ #if !defined(BH_PLATFORM_LINUX) && !defined(BH_PLATFORM_LINUX_SGX) \
&& !defined(BH_PLATFORM_DARWIN) && !defined(BH_PLATFORM_DARWIN)
if (module->native_symbol_count > 0) { if (module->is_indirect_mode) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"cannot apply relocation to text section " "cannot apply relocation to text section "
"for aot file generated with " "for aot file generated with "
@ -2492,33 +2491,36 @@ destroy_sections(AOTSection *section_list, bool destroy_aot_text)
} }
static bool static bool
resolve_native_symbols(const uint8 *buf, uint32 size, uint32 *p_count, resolve_execute_mode(const uint8 *buf, uint32 size, bool *p_mode,
char *error_buf, uint32 error_buf_size) char *error_buf, uint32 error_buf_size)
{ {
const uint8 *p = buf, *p_end = buf + size; const uint8 *p = buf, *p_end = buf + size;
uint32 section_type; uint32 section_type;
uint32 section_size = 0; uint32 section_size = 0;
uint16 e_type = 0;
p += 8; p += 8;
while (p < p_end) { while (p < p_end) {
read_uint32(p, p_end, section_type); read_uint32(p, p_end, section_type);
if (section_type <= AOT_SECTION_TYPE_SIGANATURE if (section_type <= AOT_SECTION_TYPE_SIGANATURE
|| section_type == AOT_SECTION_TYPE_CUSTOM) { || section_type == AOT_SECTION_TYPE_TARGET_INFO) {
read_uint32(p, p_end, section_size); read_uint32(p, p_end, section_size);
CHECK_BUF(p, p_end, section_size); CHECK_BUF(p, p_end, section_size);
if (section_type == AOT_SECTION_TYPE_CUSTOM) { if (section_type == AOT_SECTION_TYPE_TARGET_INFO) {
read_uint32(p, p_end, section_type); p += 4;
if (section_type == AOT_CUSTOM_SECTION_NATIVE_SYMBOL) { read_uint16(p, p_end, e_type);
/* Read the count of native symbol */ if (e_type == E_TYPE_XIP) {
read_uint32(p, p_end, *p_count); *p_mode = true;
return true;
} }
p -= sizeof(uint32); else {
*p_mode = false;
}
break;
} }
} }
else if (section_type > AOT_SECTION_TYPE_SIGANATURE) { else if (section_type > AOT_SECTION_TYPE_SIGANATURE) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"resolve native symbol failed"); "resolve execute mode failed");
break; break;
} }
p += section_size; p += section_size;
@ -2536,18 +2538,18 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
AOTSection *section_list = NULL, *section_list_end = NULL, *section; AOTSection *section_list = NULL, *section_list_end = NULL, *section;
const uint8 *p = buf, *p_end = buf + size; const uint8 *p = buf, *p_end = buf + size;
bool destroy_aot_text = false; bool destroy_aot_text = false;
uint32 native_symbol_count = 0; bool is_indirect_mode = false;
uint32 section_type; uint32 section_type;
uint32 section_size; uint32 section_size;
uint64 total_size; uint64 total_size;
uint8 *aot_text; uint8 *aot_text;
if (!resolve_native_symbols(buf, size, &native_symbol_count, error_buf, if (!resolve_execute_mode(buf, size, &is_indirect_mode, error_buf,
error_buf_size)) { error_buf_size)) {
goto fail; goto fail;
} }
module->native_symbol_count = native_symbol_count; module->is_indirect_mode = is_indirect_mode;
p += 8; p += 8;
while (p < p_end) { while (p < p_end) {
@ -2568,7 +2570,7 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
section->section_body_size = section_size; section->section_body_size = section_size;
if (section_type == AOT_SECTION_TYPE_TEXT) { if (section_type == AOT_SECTION_TYPE_TEXT) {
if ((section_size > 0) && (native_symbol_count == 0)) { if ((section_size > 0) && !module->is_indirect_mode) {
int map_prot = int map_prot =
MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC; MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \ #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
@ -2671,8 +2673,7 @@ load(const uint8 *buf, uint32 size, AOTModule *module, char *error_buf,
if (!ret) { if (!ret) {
/* If load_from_sections() fails, then aot text is destroyed /* If load_from_sections() fails, then aot text is destroyed
in destroy_sections() */ in destroy_sections() */
destroy_sections(section_list, destroy_sections(section_list, module->is_indirect_mode ? false : true);
module->native_symbol_count == 0 ? true : false);
/* aot_unload() won't destroy aot text again */ /* aot_unload() won't destroy aot text again */
module->code = NULL; module->code = NULL;
} }
@ -3039,7 +3040,7 @@ aot_unload(AOTModule *module)
if (module->const_str_set) if (module->const_str_set)
bh_hash_map_destroy(module->const_str_set); bh_hash_map_destroy(module->const_str_set);
if (module->code && (module->native_symbol_count == 0)) { if (module->code && !module->is_indirect_mode) {
/* The layout is: literal size + literal + code (with plt table) */ /* The layout is: literal size + literal + code (with plt table) */
uint8 *mmap_addr = module->literal - sizeof(uint32); uint8 *mmap_addr = module->literal - sizeof(uint32);
uint32 total_size = uint32 total_size =

View File

@ -99,6 +99,8 @@ typedef struct {
REG_SYM(aot_intrinsic_i64_to_f64), \ REG_SYM(aot_intrinsic_i64_to_f64), \
REG_SYM(aot_intrinsic_u64_to_f64), \ REG_SYM(aot_intrinsic_u64_to_f64), \
REG_SYM(aot_intrinsic_f64_to_f32), \ REG_SYM(aot_intrinsic_f64_to_f32), \
REG_SYM(aot_intrinsic_f32_to_i32), \
REG_SYM(aot_intrinsic_f32_to_u32), \
REG_SYM(aot_intrinsic_f64_to_i32), \ REG_SYM(aot_intrinsic_f64_to_i32), \
REG_SYM(aot_intrinsic_f64_to_u32), \ REG_SYM(aot_intrinsic_f64_to_u32), \
REG_SYM(aot_intrinsic_f32_to_f64), \ REG_SYM(aot_intrinsic_f32_to_f64), \

View File

@ -135,7 +135,6 @@ typedef struct AOTModule {
AOTMemInitData **mem_init_data_list; AOTMemInitData **mem_init_data_list;
/* native symbol */ /* native symbol */
uint32 native_symbol_count;
void **native_symbol_list; void **native_symbol_list;
/* import tables */ /* import tables */
@ -246,6 +245,9 @@ typedef struct AOTModule {
/* is jit mode or not */ /* is jit mode or not */
bool is_jit_mode; bool is_jit_mode;
/* is indirect mode or not */
bool is_indirect_mode;
#if WASM_ENABLE_JIT != 0 #if WASM_ENABLE_JIT != 0
WASMModule *wasm_module; WASMModule *wasm_module;
AOTCompContext *comp_ctx; AOTCompContext *comp_ctx;

View File

@ -56,6 +56,8 @@ static void
wasm_runtime_destroy_registered_module_list(); wasm_runtime_destroy_registered_module_list();
#endif /* WASM_ENABLE_MULTI_MODULE */ #endif /* WASM_ENABLE_MULTI_MODULE */
#define E_TYPE_XIP 4
#if WASM_ENABLE_REF_TYPES != 0 #if WASM_ENABLE_REF_TYPES != 0
/* Initialize externref hashmap */ /* Initialize externref hashmap */
static bool static bool
@ -309,6 +311,14 @@ align_ptr(const uint8 *p, uint32 b)
return false; \ return false; \
} while (0) } while (0)
#define read_uint16(p, p_end, res) \
do { \
p = (uint8 *)align_ptr(p, sizeof(uint16)); \
CHECK_BUF(p, p_end, sizeof(uint16)); \
res = *(uint16 *)p; \
p += sizeof(uint16); \
} while (0)
#define read_uint32(p, p_end, res) \ #define read_uint32(p, p_end, res) \
do { \ do { \
p = (uint8 *)align_ptr(p, sizeof(uint32)); \ p = (uint8 *)align_ptr(p, sizeof(uint32)); \
@ -321,7 +331,8 @@ bool
wasm_runtime_is_xip_file(const uint8 *buf, uint32 size) wasm_runtime_is_xip_file(const uint8 *buf, uint32 size)
{ {
const uint8 *p = buf, *p_end = buf + size; const uint8 *p = buf, *p_end = buf + size;
uint32 section_type, sub_section_type, section_size; uint32 section_type, section_size;
uint16 e_type;
if (get_package_type(buf, size) != Wasm_Module_AoT) if (get_package_type(buf, size) != Wasm_Module_AoT)
return false; return false;
@ -333,14 +344,12 @@ wasm_runtime_is_xip_file(const uint8 *buf, uint32 size)
read_uint32(p, p_end, section_size); read_uint32(p, p_end, section_size);
CHECK_BUF(p, p_end, section_size); CHECK_BUF(p, p_end, section_size);
if (section_type == AOT_SECTION_TYPE_CUSTOM) { if (section_type == AOT_SECTION_TYPE_TARGET_INFO) {
read_uint32(p, p_end, sub_section_type); p += 4;
if (sub_section_type == AOT_CUSTOM_SECTION_NATIVE_SYMBOL) { read_uint16(p, p_end, e_type);
if (e_type == E_TYPE_XIP) {
return true; return true;
} }
else {
p -= sizeof(uint32);
}
} }
else if (section_type >= AOT_SECTION_TYPE_SIGANATURE) { else if (section_type >= AOT_SECTION_TYPE_SIGANATURE) {
return false; return false;

View File

@ -1909,6 +1909,9 @@ struct coff_hdr {
U16 u16Characs; U16 u16Characs;
}; };
#define E_TYPE_REL 1
#define E_TYPE_XIP 4
#define IMAGE_FILE_MACHINE_AMD64 0x8664 #define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_I386 0x014c #define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_IA64 0x0200 #define IMAGE_FILE_MACHINE_IA64 0x0200
@ -2025,7 +2028,13 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
return false; return false;
} }
coff_header = (struct coff_hdr *)elf_buf; coff_header = (struct coff_hdr *)elf_buf;
obj_data->target_info.e_type = 1;
/* Emit eXecute In Place file type while in indirect mode */
if (comp_ctx->is_indirect_mode)
obj_data->target_info.e_type = E_TYPE_XIP;
else
obj_data->target_info.e_type = E_TYPE_REL;
obj_data->target_info.e_machine = coff_header->u16Machine; obj_data->target_info.e_machine = coff_header->u16Machine;
obj_data->target_info.e_version = 1; obj_data->target_info.e_version = 1;
obj_data->target_info.e_flags = 0; obj_data->target_info.e_flags = 0;
@ -2047,6 +2056,11 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
} }
elf_header = (struct elf32_ehdr *)elf_buf; elf_header = (struct elf32_ehdr *)elf_buf;
/* Emit eXecute In Place file type while in indirect mode */
if (comp_ctx->is_indirect_mode)
elf_header->e_type = E_TYPE_XIP;
SET_TARGET_INFO(e_type, e_type, uint16, is_little_bin); SET_TARGET_INFO(e_type, e_type, uint16, is_little_bin);
SET_TARGET_INFO(e_machine, e_machine, uint16, is_little_bin); SET_TARGET_INFO(e_machine, e_machine, uint16, is_little_bin);
SET_TARGET_INFO(e_version, e_version, uint32, is_little_bin); SET_TARGET_INFO(e_version, e_version, uint32, is_little_bin);
@ -2063,6 +2077,11 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
} }
elf_header = (struct elf64_ehdr *)elf_buf; elf_header = (struct elf64_ehdr *)elf_buf;
/* Emit eXecute In Place file type while in indirect mode */
if (comp_ctx->is_indirect_mode)
elf_header->e_type = E_TYPE_XIP;
SET_TARGET_INFO(e_type, e_type, uint16, is_little_bin); SET_TARGET_INFO(e_type, e_type, uint16, is_little_bin);
SET_TARGET_INFO(e_machine, e_machine, uint16, is_little_bin); SET_TARGET_INFO(e_machine, e_machine, uint16, is_little_bin);
SET_TARGET_INFO(e_version, e_version, uint32, is_little_bin); SET_TARGET_INFO(e_version, e_version, uint32, is_little_bin);

View File

@ -35,4 +35,9 @@
#define WA_FREE wasm_runtime_free #define WA_FREE wasm_runtime_free
#endif #endif
/* The epsilon value is from https://www.cplusplus.com/reference/cfloat/ */
#define WA_FLT_EPSILON 1e-5f
#define WA_DBL_EPSILON 1e-9
#endif /* #ifndef _BH_PLATFORM_H */ #endif /* #ifndef _BH_PLATFORM_H */