Support emit specified custom sections into AoT file (#1207)

And add API to get the content of custom section with
section name for both wasm file and aot file.
This commit is contained in:
Xu Jun
2022-06-10 21:51:13 +08:00
committed by GitHub
parent d404107d85
commit 77595c9560
22 changed files with 420 additions and 31 deletions

View File

@ -168,6 +168,11 @@
#define WASM_ENABLE_DEBUG_AOT 0
#endif
/* Custom sections */
#ifndef WASM_ENABLE_LOAD_CUSTOM_SECTION
#define WASM_ENABLE_LOAD_CUSTOM_SECTION 0
#endif
/* WASM log system */
#ifndef WASM_ENABLE_LOG
#define WASM_ENABLE_LOG 1

View File

@ -12,8 +12,12 @@
#include "../compilation/aot.h"
#if WASM_ENABLE_JIT != 0
#include "../compilation/aot_llvm.h"
#endif
#if (WASM_ENABLE_JIT != 0) || (WASM_ENABLE_LOAD_CUSTOM_SECTION != 0)
#include "../interpreter/wasm_loader.h"
#endif
#if WASM_ENABLE_DEBUG_AOT != 0
#include "debug/elf_parser.h"
#include "debug/jit_debug.h"
@ -674,6 +678,36 @@ load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
error_buf, error_buf_size))
goto fail;
break;
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
case AOT_CUSTOM_SECTION_RAW:
{
const char *section_name;
WASMCustomSection *section;
if (p >= p_end) {
set_error_buf(error_buf, error_buf_size, "unexpected end");
goto fail;
}
read_string(p, p_end, section_name);
section = loader_malloc(sizeof(WASMCustomSection), error_buf,
error_buf_size);
if (!section) {
goto fail;
}
section->name_addr = (char *)section_name;
section->name_len = strlen(section_name);
section->content_addr = (uint8 *)p;
section->content_len = p_end - p;
section->next = module->custom_section_list;
module->custom_section_list = section;
LOG_VERBOSE("Load custom section [%s] success.", section_name);
break;
}
#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */
default:
break;
}
@ -3261,6 +3295,10 @@ aot_unload(AOTModule *module)
}
#endif
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
wasm_loader_destroy_custom_sections(module->custom_section_list);
#endif
wasm_runtime_free(module);
}
@ -3269,3 +3307,24 @@ aot_get_plt_table_size()
{
return get_plt_table_size();
}
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
const uint8 *
aot_get_custom_section(const AOTModule *module, const char *name, uint32 *len)
{
WASMCustomSection *section = module->custom_section_list;
while (section) {
if (strcmp(section->name_addr, name) == 0) {
if (len) {
*len = section->content_len;
}
return section->content_addr;
}
section = section->next;
}
return NULL;
}
#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION */

View File

@ -50,6 +50,7 @@ typedef enum AOTSectionType {
} AOTSectionType;
typedef enum AOTCustomSectionType {
AOT_CUSTOM_SECTION_RAW = 0,
AOT_CUSTOM_SECTION_NATIVE_SYMBOL = 1,
AOT_CUSTOM_SECTION_ACCESS_CONTROL = 2,
AOT_CUSTOM_SECTION_NAME = 3,
@ -268,6 +269,9 @@ typedef struct AOTModule {
uint32 *aux_func_indexes;
uint32 aux_func_name_count;
#endif
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
WASMCustomSection *custom_section_list;
#endif
} AOTModule;
typedef union {
@ -733,6 +737,9 @@ aot_dump_call_stack(WASMExecEnv *exec_env);
void
aot_dump_perf_profiling(const AOTModuleInstance *module_inst);
const uint8 *
aot_get_custom_section(const AOTModule *module, const char *name, uint32 *len);
#ifdef __cplusplus
} /* end of extern "C" */
#endif

View File

@ -2843,6 +2843,24 @@ wasm_exec_env_get_module(WASMExecEnv *exec_env)
return NULL;
}
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
const uint8 *
wasm_runtime_get_custom_section(WASMModuleCommon *const module_comm,
const char *name, uint32 *len)
{
#if WASM_ENABLE_INTERP != 0
if (module_comm->module_type == Wasm_Module_Bytecode)
return wasm_loader_get_custom_section((WASMModule *)module_comm, name,
len);
#endif
#if WASM_ENABLE_AOT != 0
if (module_comm->module_type == Wasm_Module_AoT)
return aot_get_custom_section((AOTModule *)module_comm, name, len);
#endif
return NULL;
}
#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */
static union {
int a;
char b;

View File

@ -658,6 +658,11 @@ wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst,
uint8 **p_native_start_addr,
uint8 **p_native_end_addr);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN const uint8 *
wasm_runtime_get_custom_section(WASMModuleCommon *const module_comm,
const char *name, uint32 *len);
uint32
wasm_runtime_get_temp_ret(WASMModuleInstanceCommon *module_inst);

View File

@ -877,11 +877,15 @@ get_native_symbol_list_size(AOTCompContext *comp_ctx)
static uint32
get_name_section_size(AOTCompData *comp_data);
static uint32
get_custom_sections_size(AOTCompContext *comp_ctx, AOTCompData *comp_data);
static uint32
get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
AOTObjectData *obj_data)
{
uint32 size = 0;
uint32 size_custom_section = 0;
/* aot file header */
size += get_file_header_size();
@ -939,6 +943,12 @@ get_aot_file_size(AOTCompContext *comp_ctx, AOTCompData *comp_data,
get_name_section_size(comp_data));
}
size_custom_section = get_custom_sections_size(comp_ctx, comp_data);
if (size_custom_section > 0) {
size = align_uint(size, 4);
size += size_custom_section;
}
return size;
}
@ -1274,6 +1284,36 @@ fail:
return 0;
}
static uint32
get_custom_sections_size(AOTCompContext *comp_ctx, AOTCompData *comp_data)
{
uint32 size = 0, i;
for (i = 0; i < comp_ctx->custom_sections_count; i++) {
const char *section_name = comp_ctx->custom_sections_wp[i];
const uint8 *content = NULL;
uint32 length = 0;
content = wasm_loader_get_custom_section(comp_data->wasm_module,
section_name, &length);
if (!content) {
LOG_WARNING("Can't find custom section [%s], ignore it",
section_name);
continue;
}
size = align_uint(size, 4);
/* section id + section size + sub section id */
size += (uint32)sizeof(uint32) * 3;
/* section name and len */
size += get_string_size(comp_ctx, section_name);
/* section content */
size += length;
}
return size;
}
static bool
aot_emit_file_header(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
AOTCompData *comp_data, AOTObjectData *obj_data)
@ -1897,6 +1937,41 @@ aot_emit_name_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
return true;
}
static bool
aot_emit_custom_sections(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
AOTCompData *comp_data, AOTCompContext *comp_ctx)
{
uint32 offset = *p_offset, i;
for (i = 0; i < comp_ctx->custom_sections_count; i++) {
const char *section_name = comp_ctx->custom_sections_wp[i];
const uint8 *content = NULL;
uint32 length = 0;
content = wasm_loader_get_custom_section(comp_data->wasm_module,
section_name, &length);
if (!content) {
/* Warning has been reported during calculating size */
continue;
}
offset = align_uint(offset, 4);
EMIT_U32(AOT_SECTION_TYPE_CUSTOM);
/* sub section id + content */
EMIT_U32(sizeof(uint32) * 1 + get_string_size(comp_ctx, section_name)
+ length);
EMIT_U32(AOT_CUSTOM_SECTION_RAW);
EMIT_STR(section_name);
bh_memcpy_s((uint8 *)(buf + offset), (uint32)(buf_end - buf), content,
length);
offset += length;
}
*p_offset = offset;
return true;
}
typedef uint32 U32;
typedef int32 I32;
typedef uint16 U16;
@ -2751,7 +2826,9 @@ aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
|| !aot_emit_relocation_section(buf, buf_end, &offset, comp_ctx,
comp_data, obj_data)
|| !aot_emit_native_symbol(buf, buf_end, &offset, comp_ctx)
|| !aot_emit_name_section(buf, buf_end, &offset, comp_data, comp_ctx))
|| !aot_emit_name_section(buf, buf_end, &offset, comp_data, comp_ctx)
|| !aot_emit_custom_sections(buf, buf_end, &offset, comp_data,
comp_ctx))
goto fail2;
#if 0

View File

@ -1587,6 +1587,9 @@ aot_create_comp_context(AOTCompData *comp_data, aot_comp_option_t option)
comp_ctx->opt_level = option->opt_level;
comp_ctx->size_level = option->size_level;
comp_ctx->custom_sections_wp = option->custom_sections;
comp_ctx->custom_sections_count = option->custom_sections_count;
if (option->is_jit_mode) {
char *triple_jit = NULL;

View File

@ -348,6 +348,8 @@ typedef struct AOTCompContext {
/* Function contexts */
AOTFuncContext **func_ctxes;
uint32 func_ctx_count;
char **custom_sections_wp;
uint32 custom_sections_count;
} AOTCompContext;
enum {
@ -378,6 +380,8 @@ typedef struct AOTCompOption {
uint32 size_level;
uint32 output_format;
uint32 bounds_checks;
char **custom_sections;
uint32 custom_sections_count;
} AOTCompOption, *aot_comp_option_t;
AOTCompContext *

View File

@ -59,6 +59,8 @@ typedef struct AOTCompOption {
uint32_t size_level;
uint32_t output_format;
uint32_t bounds_checks;
char **custom_sections;
uint32_t custom_sections_count;
} AOTCompOption, *aot_comp_option_t;
aot_comp_context_t

View File

@ -1053,6 +1053,20 @@ wasm_externref_retain(uint32_t externref_idx);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_dump_call_stack(wasm_exec_env_t exec_env);
/**
* Get a custom section by name
*
* @param module_comm the module to find
* @param name name of the custom section
* @param len return the length of the content if found
*
* @return Custom section content (not including the name length
* and name string) if found, NULL otherwise
*/
WASM_RUNTIME_API_EXTERN const uint8_t *
wasm_runtime_get_custom_section(wasm_module_t const module_comm,
const char *name, uint32_t *len);
/* clang-format on */
#ifdef __cplusplus

View File

@ -335,6 +335,19 @@ typedef struct WASMFastOPCodeNode {
} WASMFastOPCodeNode;
#endif
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
typedef struct WASMCustomSection {
struct WASMCustomSection *next;
/* Start address of the section name */
char *name_addr;
/* Length of the section name decoded from leb */
uint32 name_len;
/* Start address of the content (name len and name skipped) */
uint8 *content_addr;
uint32 content_len;
} WASMCustomSection;
#endif
struct WASMModule {
/* Module type, for module loaded from WASM bytecode binary,
this field is Wasm_Module_Bytecode;
@ -453,6 +466,10 @@ struct WASMModule {
const uint8 *name_section_buf;
const uint8 *name_section_buf_end;
#endif
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
WASMCustomSection *custom_section_list;
#endif
};
typedef struct BlockType {

View File

@ -2811,7 +2811,8 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
uint32 error_buf_size)
{
const uint8 *p = buf, *p_end = buf_end;
uint32 name_len;
char section_name[32];
uint32 name_len, buffer_len;
if (p >= p_end) {
set_error_buf(error_buf, error_buf_size, "unexpected end");
@ -2830,6 +2831,16 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
return false;
}
buffer_len = sizeof(section_name);
memset(section_name, 0, buffer_len);
if (name_len < buffer_len) {
bh_memcpy_s(section_name, buffer_len, p, name_len);
}
else {
bh_memcpy_s(section_name, buffer_len, p, buffer_len - 4);
memset(section_name + buffer_len - 4, '.', 3);
}
#if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
if (memcmp(p, "name", 4) == 0) {
module->name_section_buf = buf;
@ -2837,9 +2848,34 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
p += name_len;
handle_name_section(p, p_end, module, is_load_from_file_buf, error_buf,
error_buf_size);
LOG_VERBOSE("Load custom name section success.");
return true;
}
#endif
LOG_VERBOSE("Load custom section success.\n");
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
{
WASMCustomSection *section =
loader_malloc(sizeof(WASMCustomSection), error_buf, error_buf_size);
if (!section) {
return false;
}
section->name_addr = (char *)p;
section->name_len = name_len;
section->content_addr = (uint8 *)(p + name_len);
section->content_len = p_end - p - name_len;
section->next = module->custom_section_list;
module->custom_section_list = section;
LOG_VERBOSE("Load custom section [%s] success.", section_name);
return true;
}
#endif
LOG_VERBOSE("Ignore custom section [%s].", section_name);
return true;
fail:
return false;
@ -3739,6 +3775,7 @@ wasm_loader_unload(WASMModule *module)
}
}
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
WASMFastOPCodeNode *fast_opcode =
bh_list_first_elem(&module->fast_opcode_list);
@ -3749,6 +3786,11 @@ wasm_loader_unload(WASMModule *module)
}
os_mutex_destroy(&module->ref_count_lock);
#endif
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
wasm_loader_destroy_custom_sections(module->custom_section_list);
#endif
wasm_runtime_free(module);
}
@ -6440,6 +6482,40 @@ get_table_seg_elem_type(const WASMModule *module, uint32 table_seg_idx,
}
#endif
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
const uint8 *
wasm_loader_get_custom_section(WASMModule *module, const char *name,
uint32 *len)
{
WASMCustomSection *section = module->custom_section_list;
while (section) {
if ((section->name_len == strlen(name))
&& (memcmp(section->name_addr, name, section->name_len) == 0)) {
if (len) {
*len = section->content_len;
}
return section->content_addr;
}
section = section->next;
}
return false;
}
void
wasm_loader_destroy_custom_sections(WASMCustomSection *section_list)
{
WASMCustomSection *section = section_list, *next;
while (section) {
next = section->next;
wasm_runtime_free(section);
section = next;
}
}
#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION */
static bool
wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
uint32 cur_func_idx, char *error_buf,

View File

@ -73,6 +73,11 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache,
uint8 block_type, uint8 **p_else_addr,
uint8 **p_end_addr);
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
void
wasm_loader_destroy_custom_sections(WASMCustomSection *section_list);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -436,6 +436,10 @@ void
wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env);
#endif
const uint8 *
wasm_loader_get_custom_section(WASMModule *module, const char *name,
uint32 *len);
#ifdef __cplusplus
}
#endif