aot_resolve_target_info: Avoid in-place modification of e_type (#3564)

* I believe that LLVM MemoryBuffer interface is supposed to be read-only
  and it's allowed to use eg. read-only mmap of the underlying file.
  It isn't appropriate to modify the view at all.

* in case of WASM_ENABLE_DEBUG_AOT, the whole buffer is written as the text
  section of the aot file. the modified e_type would confuse dwarf consumers.
  note that, even when we are using XIP, the debug info usually contains
  relocations. for example, llvm-dwarfdump doesn't seem to perform relocations
  on .debug_info section for ET_CORE (== 4 == our E_TYPE_XIP) objects.
This commit is contained in:
YAMAMOTO Takashi 2024-06-25 11:47:23 +09:00 committed by GitHub
parent f7d2826772
commit e66b41427f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -3038,15 +3038,18 @@ typedef struct elf64_rela {
elf64_sxword r_addend;
} elf64_rela;
#define SET_TARGET_INFO(f, v, type, little) \
do { \
type tmp = elf_header->v; \
if ((little && !is_little_endian()) \
|| (!little && is_little_endian())) \
exchange_##type((uint8 *)&tmp); \
obj_data->target_info.f = tmp; \
#define SET_TARGET_INFO_VALUE(f, val, type, little) \
do { \
type tmp = val; \
if ((little && !is_little_endian()) \
|| (!little && is_little_endian())) \
exchange_##type((uint8 *)&tmp); \
obj_data->target_info.f = tmp; \
} while (0)
#define SET_TARGET_INFO_FIELD(f, v, type, little) \
SET_TARGET_INFO_VALUE(f, elf_header->v, type, little)
static bool
aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
{
@ -3096,6 +3099,7 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
|| bin_type == LLVMBinaryTypeELF32B) {
struct elf32_ehdr *elf_header;
bool is_little_bin = bin_type == LLVMBinaryTypeELF32L;
uint16 e_type;
if (!elf_buf || elf_size < sizeof(struct elf32_ehdr)) {
aot_set_last_error("invalid elf32 buffer.");
@ -3103,20 +3107,22 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
}
elf_header = (struct elf32_ehdr *)elf_buf;
e_type = elf_header->e_type;
/* Emit eXecute In Place file type while in indirect mode */
if (comp_ctx->is_indirect_mode)
elf_header->e_type = E_TYPE_XIP;
e_type = E_TYPE_XIP;
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_version, e_version, uint32, is_little_bin);
SET_TARGET_INFO(e_flags, e_flags, uint32, is_little_bin);
SET_TARGET_INFO_VALUE(e_type, e_type, uint16, is_little_bin);
SET_TARGET_INFO_FIELD(e_machine, e_machine, uint16, is_little_bin);
SET_TARGET_INFO_FIELD(e_version, e_version, uint32, is_little_bin);
SET_TARGET_INFO_FIELD(e_flags, e_flags, uint32, is_little_bin);
}
else if (bin_type == LLVMBinaryTypeELF64L
|| bin_type == LLVMBinaryTypeELF64B) {
struct elf64_ehdr *elf_header;
bool is_little_bin = bin_type == LLVMBinaryTypeELF64L;
uint16 e_type;
if (!elf_buf || elf_size < sizeof(struct elf64_ehdr)) {
aot_set_last_error("invalid elf64 buffer.");
@ -3124,15 +3130,16 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
}
elf_header = (struct elf64_ehdr *)elf_buf;
e_type = elf_header->e_type;
/* Emit eXecute In Place file type while in indirect mode */
if (comp_ctx->is_indirect_mode)
elf_header->e_type = E_TYPE_XIP;
e_type = E_TYPE_XIP;
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_version, e_version, uint32, is_little_bin);
SET_TARGET_INFO(e_flags, e_flags, uint32, is_little_bin);
SET_TARGET_INFO_VALUE(e_type, e_type, uint16, is_little_bin);
SET_TARGET_INFO_FIELD(e_machine, e_machine, uint16, is_little_bin);
SET_TARGET_INFO_FIELD(e_version, e_version, uint32, is_little_bin);
SET_TARGET_INFO_FIELD(e_flags, e_flags, uint32, is_little_bin);
}
else if (bin_type == LLVMBinaryTypeMachO32L
|| bin_type == LLVMBinaryTypeMachO32B) {