diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index a17cce01..90a4f2e2 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -156,6 +156,7 @@ GET_U64_FROM_ADDR(uint32 *addr) #define BIN_TYPE_ELF32B 1 /* 32-bit big endian */ #define BIN_TYPE_ELF64L 2 /* 64-bit little endian */ #define BIN_TYPE_ELF64B 3 /* 64-bit big endian */ +#define BIN_TYPE_COFF64 6 /* 64-bit little endian */ /* Legal values for e_type (object file type). */ #define E_TYPE_NONE 0 /* No file type */ @@ -174,6 +175,7 @@ GET_U64_FROM_ADDR(uint32 *addr) #define E_MACHINE_MIPS_X 51 /* Stanford MIPS-X */ #define E_MACHINE_X86_64 62 /* AMD x86-64 architecture */ #define E_MACHINE_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define E_MACHINE_WIN_X86_64 0x8664 /* Windowx x86-64 architecture */ /* Legal values for e_version */ #define E_VERSION_CURRENT 1 /* Current version */ @@ -232,6 +234,7 @@ get_aot_file_target(AOTTargetInfo *target_info, char *machine_type = NULL; switch (target_info->e_machine) { case E_MACHINE_X86_64: + case E_MACHINE_WIN_X86_64: machine_type = "x86_64"; break; case E_MACHINE_386: @@ -973,7 +976,7 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end, return false; } #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) -#ifndef BH_PLATFORM_LINUX_SGX +#if !defined(BH_PLATFORM_LINUX_SGX) && !defined(BH_PLATFORM_WINDOWS) /* address must be in the first 2 Gigabytes of the process address space */ bh_assert((uintptr_t)data_sections[i].data < INT32_MAX); @@ -1564,7 +1567,11 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end, if (!strcmp(group->section_name, ".rel.text") || !strcmp(group->section_name, ".rela.text") - || !strcmp(group->section_name, ".rela.literal")) { + || !strcmp(group->section_name, ".rela.literal") +#ifdef BH_PLATFORM_WINDOWS + || !strcmp(group->section_name, ".text") +#endif + ) { if (!do_text_relocation(module, group, error_buf, error_buf_size)) return false; } @@ -1819,7 +1826,7 @@ create_sections(const uint8 *buf, uint32 size, goto fail; } #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) -#ifndef BH_PLATFORM_LINUX_SGX +#if !defined(BH_PLATFORM_LINUX_SGX) && !defined(BH_PLATFORM_WINDOWS) /* address must be in the first 2 Gigabytes of the process address space */ bh_assert((uintptr_t)aot_text < INT32_MAX); diff --git a/core/iwasm/aot/arch/aot_reloc_x86_64.c b/core/iwasm/aot/arch/aot_reloc_x86_64.c index a18b1c35..cd45e096 100644 --- a/core/iwasm/aot/arch/aot_reloc_x86_64.c +++ b/core/iwasm/aot/arch/aot_reloc_x86_64.c @@ -11,6 +11,8 @@ #define R_X86_64_32 10 /* Direct 32 bit zero extended */ #define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define IMAGE_REL_AMD64_REL32 4 /* The 32-bit relative address from the byte following the relocation. */ + void __divdi3(); void __udivdi3(); void __moddi3(); @@ -174,7 +176,9 @@ apply_relocation(AOTModule *module, "Try using wamrc with --size-level=1 option."); return false; } - +#ifdef BH_PLATFORM_WINDOWS + target_addr -= sizeof(int32); +#endif *(int32*)(target_section_addr + reloc_offset) = (int32)target_addr; break; } diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 1d27d4f3..e11efbb4 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -1399,6 +1399,27 @@ aot_emit_relocation_section(uint8 *buf, uint8 *buf_end, uint32 *p_offset, return true; } +typedef uint32 U32; +typedef int32 I32; +typedef uint16 U16; +typedef uint8 U8; + +struct coff_hdr { + U16 u16Machine; + U16 u16NumSections; + U32 u32DateTimeStamp; + U32 u32SymTblPtr; + U32 u32NumSymbols; + U16 u16PeHdrSize; + U16 u16Characs; +}; + +#define IMAGE_FILE_MACHINE_AMD64 0x8664 +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_IA64 0x0200 + +#define AOT_COFF_BIN_TYPE 6 + #define EI_NIDENT 16 typedef uint32 elf32_word; @@ -1487,7 +1508,8 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data) const uint8 *elf_buf = (uint8 *)LLVMGetBufferStart(obj_data->mem_buf); uint32 elf_size = (uint32)LLVMGetBufferSize(obj_data->mem_buf); - if (bin_type != LLVMBinaryTypeELF32L + if (bin_type != LLVMBinaryTypeCOFF + && bin_type != LLVMBinaryTypeELF32L && bin_type != LLVMBinaryTypeELF32B && bin_type != LLVMBinaryTypeELF64L && bin_type != LLVMBinaryTypeELF64B @@ -1501,7 +1523,23 @@ aot_resolve_target_info(AOTCompContext *comp_ctx, AOTObjectData *obj_data) obj_data->target_info.bin_type = bin_type - LLVMBinaryTypeELF32L; - if (bin_type == LLVMBinaryTypeELF32L + if (bin_type == LLVMBinaryTypeCOFF) { + struct coff_hdr * coff_header; + + if (!elf_buf || elf_size < sizeof(struct coff_hdr)) { + aot_set_last_error("invalid coff_hdr buffer."); + return false; + } + coff_header = (struct coff_hdr *)elf_buf; + obj_data->target_info.e_type = 1; + obj_data->target_info.e_machine = coff_header->u16Machine; + obj_data->target_info.e_version = 1; + obj_data->target_info.e_flags = 0; + + if (coff_header->u16Machine == IMAGE_FILE_MACHINE_AMD64) + obj_data->target_info.bin_type = AOT_COFF_BIN_TYPE; + } + else if (bin_type == LLVMBinaryTypeELF32L || bin_type == LLVMBinaryTypeELF32B) { struct elf32_ehdr *elf_header; bool is_little_bin = bin_type == LLVMBinaryTypeELF32L; @@ -1847,7 +1885,7 @@ fail: } static bool -is_relocation_section(char *section_name) +is_relocation_section_name(char *section_name) { return (!strcmp(section_name, ".rela.text") || !strcmp(section_name, ".rel.text") @@ -1864,20 +1902,33 @@ is_relocation_section(char *section_name) strlen(".rel.rodata.cst"))); } +static bool +is_relocation_section(LLVMSectionIteratorRef sec_itr) +{ + uint32 count = 0; + char *name = (char *)LLVMGetSectionName(sec_itr); + if (name) { + if (is_relocation_section_name(name)) + return true; + else if (!strncmp(name, ".text", strlen(".text")) + && get_relocations_count(sec_itr, &count) && count > 0) + return true; + } + return false; +} + static bool get_relocation_groups_count(AOTObjectData *obj_data, uint32 *p_count) { uint32 count = 0; LLVMSectionIteratorRef sec_itr; - char *name; if (!(sec_itr = LLVMObjectFileCopySectionIterator(obj_data->binary))) { aot_set_last_error("llvm get section iterator failed."); return false; } while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) { - if ((name = (char *)LLVMGetSectionName(sec_itr)) - && is_relocation_section(name)) { + if (is_relocation_section(sec_itr)) { count++; } LLVMMoveToNextSection(sec_itr); @@ -1918,8 +1969,8 @@ aot_resolve_object_relocation_groups(AOTObjectData *obj_data) return false; } while (!LLVMObjectFileIsSectionIteratorAtEnd(obj_data->binary, sec_itr)) { - if ((name = (char *)LLVMGetSectionName(sec_itr)) - && is_relocation_section(name)) { + if (is_relocation_section(sec_itr)) { + name = (char *)LLVMGetSectionName(sec_itr); relocation_group->section_name = name; if (!aot_resolve_object_relocation_group( obj_data, diff --git a/core/shared/platform/windows/win_memmap.c b/core/shared/platform/windows/win_memmap.c index 6bcf6b3e..1e7d7fd8 100644 --- a/core/shared/platform/windows/win_memmap.c +++ b/core/shared/platform/windows/win_memmap.c @@ -19,6 +19,9 @@ void * os_mmap(void *hint, size_t size, int prot, int flags) /* integer overflow */ return NULL; + if (request_size == 0) + request_size = page_size; + if (prot & MMAP_PROT_EXEC) { if (prot & MMAP_PROT_WRITE) flProtect = PAGE_EXECUTE_READWRITE;