wamrc: Fix windows relocation to aot_func_internal#n (#2474)

AOT relocation to aot_func_internal#n is generated by wamrc --bounds-checks=1.
Resolve the issue by applying the relocation in the compilation stage by wamrc and
don't generate these relocations in the AOT file.

Fixes #2471.
This commit is contained in:
Wenyong Huang 2023-08-18 09:56:00 +08:00 committed by GitHub
parent 7baaed2fb8
commit 6716c23dd1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 142 additions and 7 deletions

View File

@ -164,6 +164,9 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
(uint32)((uintptr_t)symbol_addr + (intptr_t)reloc_addend
- (uintptr_t)(target_section_addr
+ (uint32)reloc_offset)
#if defined(BH_PLATFORM_WINDOWS)
- sizeof(int32)
#endif
+ value); /* S + A - P */
break;
}

View File

@ -242,7 +242,7 @@ apply_relocation(AOTModule *module, uint8 *target_section_addr,
- (uintptr_t)(target_section_addr + reloc_offset));
}
else {
target_addr = (intptr_t) /* L + A - P */
target_addr = (intptr_t) /* S + A - P */
((uintptr_t)symbol_addr + reloc_addend
- (uintptr_t)(target_section_addr + reloc_offset));
}

View File

@ -93,7 +93,10 @@ check_utf8_str(const uint8 *str, uint32 len)
/* Internal function in object file */
typedef struct AOTObjectFunc {
char *func_name;
/* text offset of aot_func#n */
uint64 text_offset;
/* text offset of aot_func_internal#n */
uint64 text_offset_of_aot_func_internal;
} AOTObjectFunc;
/* Symbol table list node */
@ -637,13 +640,33 @@ get_relocation_size(AOTRelocation *relocation, bool is_32bin)
}
static uint32
get_relocations_size(AOTRelocation *relocations, uint32 relocation_count,
get_relocations_size(AOTObjectData *obj_data,
AOTRelocationGroup *relocation_group,
AOTRelocation *relocations, uint32 relocation_count,
bool is_32bin)
{
AOTRelocation *relocation = relocations;
uint32 size = 0, i;
for (i = 0; i < relocation_count; i++, relocation++) {
/* ignore the relocations to aot_func_internal#n in text section
for windows platform since they will be applied in
aot_emit_text_section */
if (!strcmp(relocation_group->section_name, ".text")
&& !strncmp(relocation->symbol_name, AOT_FUNC_INTERNAL_PREFIX,
strlen(AOT_FUNC_INTERNAL_PREFIX))
&& ((!strncmp(obj_data->comp_ctx->target_arch, "x86_64", 6)
/* Windows AOT_COFF64_BIN_TYPE */
&& obj_data->target_info.bin_type == 6
/* IMAGE_REL_AMD64_REL32 in windows x86_64 */
&& relocation->relocation_type == 4)
|| (!strncmp(obj_data->comp_ctx->target_arch, "i386", 4)
/* Windows AOT_COFF32_BIN_TYPE */
&& obj_data->target_info.bin_type == 4
/* IMAGE_REL_I386_REL32 in windows x86_32 */
&& relocation->relocation_type == 20))) {
continue;
}
size = align_uint(size, 4);
size += get_relocation_size(relocation, is_32bin);
}
@ -651,19 +674,22 @@ get_relocations_size(AOTRelocation *relocations, uint32 relocation_count,
}
static uint32
get_relocation_group_size(AOTRelocationGroup *relocation_group, bool is_32bin)
get_relocation_group_size(AOTObjectData *obj_data,
AOTRelocationGroup *relocation_group, bool is_32bin)
{
uint32 size = 0;
/* section name index + relocation count + relocations */
size += (uint32)sizeof(uint32);
size += (uint32)sizeof(uint32);
size += get_relocations_size(relocation_group->relocations,
size += get_relocations_size(obj_data, relocation_group,
relocation_group->relocations,
relocation_group->relocation_count, is_32bin);
return size;
}
static uint32
get_relocation_groups_size(AOTRelocationGroup *relocation_groups,
get_relocation_groups_size(AOTObjectData *obj_data,
AOTRelocationGroup *relocation_groups,
uint32 relocation_group_count, bool is_32bin)
{
AOTRelocationGroup *relocation_group = relocation_groups;
@ -671,7 +697,7 @@ get_relocation_groups_size(AOTRelocationGroup *relocation_groups,
for (i = 0; i < relocation_group_count; i++, relocation_group++) {
size = align_uint(size, 4);
size += get_relocation_group_size(relocation_group, is_32bin);
size += get_relocation_group_size(obj_data, relocation_group, is_32bin);
}
return size;
}
@ -864,7 +890,7 @@ get_relocation_section_size(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
/* relocation group count + symbol_table + relocation groups */
return (uint32)sizeof(uint32) + symbol_table_size
+ get_relocation_groups_size(relocation_groups,
+ get_relocation_groups_size(obj_data, relocation_groups,
relocation_group_count,
is_32bit_binary(obj_data));
}
@ -1734,6 +1760,10 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
uint32 section_size = get_text_section_size(obj_data);
uint32 offset = *p_offset;
uint8 placeholder = 0;
AOTRelocationGroup *relocation_group;
AOTRelocation *relocation;
uint32 i, j, relocation_count;
uint8 *text;
*p_offset = offset = align_uint(offset, 4);
@ -1747,6 +1777,8 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
EMIT_BUF(&placeholder, 1);
}
text = buf + offset;
if (obj_data->text_size > 0) {
EMIT_BUF(obj_data->text, obj_data->text_size);
while (offset & 3)
@ -1768,6 +1800,67 @@ aot_emit_text_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset,
return false;
}
/* apply relocations to aot_func_internal#n in text section for
windows platform */
if ((!strncmp(obj_data->comp_ctx->target_arch, "x86_64", 6)
/* Windows AOT_COFF64_BIN_TYPE */
&& obj_data->target_info.bin_type == 6)
|| (!strncmp(obj_data->comp_ctx->target_arch, "i386", 4)
/* Windows AOT_COFF32_BIN_TYPE */
&& obj_data->target_info.bin_type == 4)) {
relocation_group = obj_data->relocation_groups;
for (i = 0; i < obj_data->relocation_group_count;
i++, relocation_group++) {
/* relocation in text section */
if (!strcmp(relocation_group->section_name, ".text")) {
relocation = relocation_group->relocations;
relocation_count = relocation_group->relocation_count;
for (j = 0; j < relocation_count; j++) {
/* relocation to aot_func_internal#n */
if (str_starts_with(relocation->symbol_name,
AOT_FUNC_INTERNAL_PREFIX)
&& ((obj_data->target_info.bin_type
== 6 /* AOT_COFF64_BIN_TYPE */
&& relocation->relocation_type
== 4 /* IMAGE_REL_AMD64_REL32 */)
|| (obj_data->target_info.bin_type
== 4 /* AOT_COFF32_BIN_TYPE */
&& obj_data->target_info.bin_type
== 20 /* IMAGE_REL_I386_REL32 */))) {
uint32 func_idx =
atoi(relocation->symbol_name
+ strlen(AOT_FUNC_INTERNAL_PREFIX));
uint64 text_offset, reloc_offset, reloc_addend;
bh_assert(func_idx < obj_data->func_count);
text_offset = obj_data->funcs[func_idx]
.text_offset_of_aot_func_internal;
reloc_offset = relocation->relocation_offset;
reloc_addend = relocation->relocation_addend;
/* S + A - P */
*(uint32 *)(text + reloc_offset) =
(uint32)(text_offset + reloc_addend - reloc_offset
- 4);
/* remove current relocation as it has been applied */
if (j < relocation_count - 1) {
uint32 move_size =
(uint32)(sizeof(AOTRelocation)
* (relocation_count - 1 - j));
bh_memmove_s(relocation, move_size, relocation + 1,
move_size);
}
relocation_group->relocation_count--;
}
else {
relocation++;
}
}
}
}
}
*p_offset = offset;
return true;
@ -2773,6 +2866,7 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
while (!LLVMObjectFileIsSymbolIteratorAtEnd(obj_data->binary, sym_itr)) {
if ((name = (char *)LLVMGetSymbolName(sym_itr))
&& str_starts_with(name, prefix)) {
/* symbol aot_func#n */
func_index = (uint32)atoi(name + strlen(prefix));
if (func_index < obj_data->func_count) {
LLVMSectionIteratorRef contain_section;
@ -2807,6 +2901,44 @@ aot_resolve_functions(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
}
}
}
else if ((name = (char *)LLVMGetSymbolName(sym_itr))
&& str_starts_with(name, AOT_FUNC_INTERNAL_PREFIX)) {
/* symbol aot_func_internal#n */
func_index = (uint32)atoi(name + strlen(AOT_FUNC_INTERNAL_PREFIX));
if (func_index < obj_data->func_count) {
LLVMSectionIteratorRef contain_section;
char *contain_section_name;
func = obj_data->funcs + func_index;
if (!(contain_section = LLVMObjectFileCopySectionIterator(
obj_data->binary))) {
aot_set_last_error("llvm get section iterator failed.");
LLVMDisposeSymbolIterator(sym_itr);
return false;
}
LLVMMoveToContainingSection(contain_section, sym_itr);
contain_section_name =
(char *)LLVMGetSectionName(contain_section);
LLVMDisposeSectionIterator(contain_section);
if (!strcmp(contain_section_name, ".text.unlikely.")) {
func->text_offset_of_aot_func_internal =
align_uint(obj_data->text_size, 4)
+ LLVMGetSymbolAddress(sym_itr);
}
else if (!strcmp(contain_section_name, ".text.hot.")) {
func->text_offset_of_aot_func_internal =
align_uint(obj_data->text_size, 4)
+ align_uint(obj_data->text_unlikely_size, 4)
+ LLVMGetSymbolAddress(sym_itr);
}
else {
func->text_offset_of_aot_func_internal =
LLVMGetSymbolAddress(sym_itr);
}
}
}
LLVMMoveToNextSymbol(sym_itr);
}
LLVMDisposeSymbolIterator(sym_itr);