Use indirect call in pre-checker function to avoid relocation in XIP mode (#3142)

The stack profiler `aot_func#xxx` calls the wrapped function of `aot_func_internal#xxx`
by using symbol reference,  but in some platform like xtensa, it’s translated into a native
long call, which needs to resolve the indirect address by relocation and breaks the XIP
feature which requires the eliminating of relocation.

The solution is to change the symbol reference into an indirect call through the lookup
table, the code will be like this:
```llvm
call_wrapped_func:                                ; preds = %stack_bound_check_block
  %func_addr1 = getelementptr inbounds ptr, ptr %func_ptrs_ptr, i32 75
  %func_tmp2 = load ptr, ptr %func_addr1, align 4
  tail call void %func_tmp2(ptr %exec_env)
  ret void
```
This commit is contained in:
dongsheng28849455
2024-02-27 11:17:57 +08:00
committed by GitHub
parent 2349df1271
commit 4f6d70bc52
4 changed files with 132 additions and 17 deletions

View File

@ -2500,15 +2500,26 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
const uint8 *p = buf, *p_end = buf_end;
uint32 i;
uint64 size, text_offset;
uint32 func_count = module->func_count;
size = sizeof(void *) * (uint64)module->func_count;
#if defined(BUILD_TARGET_XTENSA)
/*
* For Xtensa XIP, real func_count is doubled, including aot_func and
* aot_func_internal, so need to multipy func_count by 2 here.
*/
if (module->is_indirect_mode) {
func_count *= 2;
}
#endif
size = sizeof(void *) * (uint64)func_count;
if (size > 0
&& !(module->func_ptrs =
loader_malloc(size, error_buf, error_buf_size))) {
return false;
}
for (i = 0; i < module->func_count; i++) {
for (i = 0; i < func_count; i++) {
if (sizeof(void *) == 8) {
read_uint64(p, p_end, text_offset);
}
@ -2543,14 +2554,14 @@ load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
module->start_function = NULL;
}
size = sizeof(uint32) * (uint64)module->func_count;
size = sizeof(uint32) * (uint64)func_count;
if (size > 0
&& !(module->func_type_indexes =
loader_malloc(size, error_buf, error_buf_size))) {
return false;
}
for (i = 0; i < module->func_count; i++) {
for (i = 0; i < func_count; i++) {
read_uint32(p, p_end, module->func_type_indexes[i]);
if (module->func_type_indexes[i] >= module->type_count) {
set_error_buf(error_buf, error_buf_size, "unknown type");

View File

@ -1108,10 +1108,21 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
{
uint32 i;
void **func_ptrs;
uint64 total_size = ((uint64)module->import_func_count + module->func_count)
* sizeof(void *);
uint32 func_count = module->func_count;
#if defined(BUILD_TARGET_XTENSA)
/*
* For Xtensa XIP, real func_count is doubled, including aot_func and
* aot_func_internal, so need to multipy func_count by 2 here.
*/
if (module->is_indirect_mode) {
func_count *= 2;
}
#endif
if (module->import_func_count + module->func_count == 0)
uint64 total_size =
((uint64)module->import_func_count + func_count) * sizeof(void *);
if (module->import_func_count + func_count == 0)
return true;
/* Allocate memory */
@ -1133,8 +1144,8 @@ init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
}
/* Set defined function pointers */
bh_memcpy_s(func_ptrs, sizeof(void *) * module->func_count,
module->func_ptrs, sizeof(void *) * module->func_count);
bh_memcpy_s(func_ptrs, sizeof(void *) * func_count, module->func_ptrs,
sizeof(void *) * func_count);
return true;
}
@ -1144,10 +1155,21 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
{
uint32 i;
uint32 *func_type_index;
uint64 total_size = ((uint64)module->import_func_count + module->func_count)
* sizeof(uint32);
uint32 func_count = module->func_count;
#if defined(BUILD_TARGET_XTENSA)
/*
* For Xtensa XIP, real func_count is doubled, including aot_func and
* aot_func_internal, so need to multipy func_count by 2 here.
*/
if (module->is_indirect_mode) {
func_count *= 2;
}
#endif
if (module->import_func_count + module->func_count == 0)
uint64 total_size =
((uint64)module->import_func_count + func_count) * sizeof(uint32);
if (module->import_func_count + func_count == 0)
return true;
/* Allocate memory */
@ -1161,8 +1183,8 @@ init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
for (i = 0; i < module->import_func_count; i++, func_type_index++)
*func_type_index = module->import_funcs[i].func_type_index;
bh_memcpy_s(func_type_index, sizeof(uint32) * module->func_count,
module->func_type_indexes, sizeof(uint32) * module->func_count);
bh_memcpy_s(func_type_index, sizeof(uint32) * func_count,
module->func_type_indexes, sizeof(uint32) * func_count);
return true;
}