Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,28 @@ WAMR supports building the iwasm VM core only (no app framework) to the mini pro

### Build wamrc AoT compiler

Both wasm binary file and AoT file are supported by iwasm. The wamrc AoT compiler is to compile wasm binary file to AoT file which can also be run by iwasm. Execute following commands to build **wamrc** compiler:
Both wasm binary file and AoT file are supported by iwasm. The wamrc AoT compiler is to compile wasm binary file to AoT file which can also be run by iwasm. Execute following commands to build **wamrc** compiler for Linux:

```shell
cd wamr-compiler
./build_llvm.sh (use build_llvm_xtensa.sh instead to support xtensa target; use build_llvm.py for windows)
./build_llvm.sh (or "./build_llvm_xtensa.sh" to support xtensa target)
mkdir build && cd build
cmake ..
cmake .. (or "cmake .. -DWAMR_BUILD_TARGET=darwin" for MacOS)
make
ln -s {current path}/wamrc /usr/bin/wamrc
# wamrc is generated under current directory
```
For MacOS, you should replace `cmake ..` with `cmake -DWAMR_BUILD_PLATFORM=darwin ..`.

For Windows you should replace `cmake ..` with `cmake -D WAMR_BUILD_PLATFORM=windows -A Win32 ..`.
For **Windows**:
```shell
cd wamr-compiler
python build_llvm.py
open LLVM.sln in wasm-micro-runtime\core\deps\llvm\win32build with Visual Studio
build LLVM.sln Release
mkdir build && cd build
cmake ..
cmake --build . --config Release
# wamrc.exe is generated under .\Release directory
```

Application framework
===================================
Expand Down
230 changes: 227 additions & 3 deletions core/iwasm/aot/aot_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include "../interpreter/wasm_loader.h"
#endif

#define XMM_PLT_PREFIX "__xmm@"
#define REAL_PLT_PREFIX "__real@"

static void
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
Expand Down Expand Up @@ -1280,12 +1282,13 @@ get_data_section_addr(AOTModule *module, const char *section_name,
uint32 i;
AOTObjectDataSection *data_section = module->data_sections;

for (i = 0; i < module->data_section_count; i++, data_section++)
for (i = 0; i < module->data_section_count; i++, data_section++) {
if (!strcmp(data_section->name, section_name)) {
if (p_data_size)
*p_data_size = data_section->size;
return data_section->data;
}
}

return NULL;
}
Expand Down Expand Up @@ -1313,6 +1316,53 @@ is_literal_relocation(const char *reloc_sec_name)
return !strcmp(reloc_sec_name, ".rela.literal");
}

#if defined(BH_PLATFORM_WINDOWS)
static bool
str2uint32(const char *buf, uint32 *p_res)
{
uint32 res = 0, val;
const char *buf_end = buf + 8;
char ch;

while (buf < buf_end) {
ch = *buf++;
if (ch >= '0' && ch <= '9')
val = ch - '0';
else if (ch >= 'a' && ch <= 'f')
val = ch - 'a' + 0xA;
else if (ch >= 'A' && ch <= 'F')
val = ch - 'A' + 0xA;
else
return false;
res = (res << 4) | val;
}
*p_res = res;
return true;
}
static bool
str2uint64(const char *buf, uint64 *p_res)
{
uint64 res = 0, val;
const char *buf_end = buf + 16;
char ch;

while (buf < buf_end) {
ch = *buf++;
if (ch >= '0' && ch <= '9')
val = ch - '0';
else if (ch >= 'a' && ch <= 'f')
val = ch - 'a' + 0xA;
else if (ch >= 'A' && ch <= 'F')
val = ch - 'A' + 0xA;
else
return false;
res = (res << 4) | val;
}
*p_res = res;
return true;
}
#endif

static bool
do_text_relocation(AOTModule *module,
AOTRelocationGroup *group,
Expand All @@ -1322,6 +1372,9 @@ do_text_relocation(AOTModule *module,
uint8 *aot_text = is_literal ? module->literal : module->code;
uint32 aot_text_size = is_literal ? module->literal_size : module->code_size;
uint32 i, func_index, symbol_len;
#if defined(BH_PLATFORM_WINDOWS)
uint32 xmm_plt_index = 0, real_plt_index = 0, float_plt_index = 0;
#endif
char symbol_buf[128] = { 0 }, *symbol, *p;
void *symbol_addr;
AOTRelocation *relocation = group->relocations;
Expand Down Expand Up @@ -1360,6 +1413,7 @@ do_text_relocation(AOTModule *module,
symbol_addr = module->code;
}
else if (!strcmp(symbol, ".data")
|| !strcmp(symbol, ".rdata")
|| !strcmp(symbol, ".rodata")
/* ".rodata.cst4/8/16/.." */
|| !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))) {
Expand All @@ -1373,9 +1427,66 @@ do_text_relocation(AOTModule *module,
else if (!strcmp(symbol, ".literal")) {
symbol_addr = module->literal;
}
#if defined(BH_PLATFORM_WINDOWS)
else if (!strcmp(group->section_name, ".text")
&& !strncmp(symbol, XMM_PLT_PREFIX, strlen(XMM_PLT_PREFIX))
&& strlen(symbol) == strlen(XMM_PLT_PREFIX) + 32) {
char xmm_buf[17] = { 0 };

symbol_addr = module->extra_plt_data + xmm_plt_index * 16;
bh_memcpy_s(xmm_buf, sizeof(xmm_buf),
symbol + strlen(XMM_PLT_PREFIX) + 16, 16);
if (!str2uint64(xmm_buf, (uint64*)symbol_addr)) {
set_error_buf(error_buf, error_buf,
"resolve symbol %s failed", symbol);
goto check_symbol_fail;
}

bh_memcpy_s(xmm_buf, sizeof(xmm_buf),
symbol + strlen(XMM_PLT_PREFIX), 16);
if (!str2uint64(xmm_buf, (uint64*)((uint8*)symbol_addr + 8))) {
set_error_buf(error_buf, error_buf,
"resolve symbol %s failed", symbol);
goto check_symbol_fail;
}
xmm_plt_index++;
}
else if (!strcmp(group->section_name, ".text")
&& !strncmp(symbol, REAL_PLT_PREFIX, strlen(REAL_PLT_PREFIX))
&& strlen(symbol) == strlen(REAL_PLT_PREFIX) + 16) {
char real_buf[17] = { 0 };

symbol_addr = module->extra_plt_data + module->xmm_plt_count * 16
+ real_plt_index * 8;
bh_memcpy_s(real_buf, sizeof(real_buf),
symbol + strlen(REAL_PLT_PREFIX), 16);
if (!str2uint64(real_buf, (uint64*)symbol_addr)) {
set_error_buf(error_buf, error_buf,
"resolve symbol %s failed", symbol);
goto check_symbol_fail;
}
real_plt_index++;
}
else if (!strcmp(group->section_name, ".text")
&& !strncmp(symbol, REAL_PLT_PREFIX, strlen(REAL_PLT_PREFIX))
&& strlen(symbol) == strlen(REAL_PLT_PREFIX) + 8) {
char float_buf[9] = { 0 };

symbol_addr = module->extra_plt_data + module->xmm_plt_count * 16
+ module->real_plt_count * 8 + float_plt_index * 4;
bh_memcpy_s(float_buf, sizeof(float_buf),
symbol + strlen(REAL_PLT_PREFIX), 8);
if (!str2uint32(float_buf, (uint32*)symbol_addr)) {
set_error_buf(error_buf, error_buf,
"resolve symbol %s failed", symbol);
goto check_symbol_fail;
}
float_plt_index++;
}
#endif /* end of defined(BH_PLATFORM_WINDOWS) */
else if (!(symbol_addr = resolve_target_sym(symbol, &symbol_index))) {
set_error_buf_v(error_buf, error_buf_size,
"resolve symbol %s failed", symbol);
"resolve symbol %s failed", symbol);
goto check_symbol_fail;
}

Expand Down Expand Up @@ -1418,6 +1529,9 @@ do_data_relocation(AOTModule *module,
else if (!strncmp(group->section_name, ".rel.", 5)) {
data_section_name = group->section_name + strlen(".rel");
}
else if (!strcmp(group->section_name, ".rdata")) {
data_section_name = group->section_name;
}
else {
set_error_buf(error_buf, error_buf_size,
"invalid data relocation section name");
Expand All @@ -1426,6 +1540,7 @@ do_data_relocation(AOTModule *module,

data_addr = get_data_section_addr(module, data_section_name,
&data_size);

if (group->relocation_count > 0 && !data_addr) {
set_error_buf(error_buf, error_buf_size,
"invalid data relocation count");
Expand Down Expand Up @@ -1514,6 +1629,106 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
goto fail;
}

#if defined(BH_PLATFORM_WINDOWS)
buf = symbol_buf_end;
read_uint32(buf, buf_end, group_count);

for (i = 0; i < group_count; i++) {
uint32 name_index, relocation_count;
uint16 group_name_len;
uint8 *group_name;

/* section name address is 4 bytes aligned. */
buf = (uint8*)align_ptr(buf, sizeof(uint32));
read_uint32(buf, buf_end, name_index);

if (name_index >= symbol_count) {
set_error_buf(error_buf, error_buf_size,
"symbol index out of range");
goto fail;
}

group_name = symbol_buf + symbol_offsets[name_index];
group_name_len = *(uint16 *)group_name;
group_name += sizeof(uint16);

read_uint32(buf, buf_end, relocation_count);

for (j = 0; j < relocation_count; j++) {
AOTRelocation relocation = { 0 };
uint32 symbol_index, offset32, addend32;
uint16 symbol_name_len;
uint8 *symbol_name;

if (sizeof(void *) == 8) {
read_uint64(buf, buf_end, relocation.relocation_offset);
read_uint64(buf, buf_end, relocation.relocation_addend);
}
else {
read_uint32(buf, buf_end, offset32);
relocation.relocation_offset = (uint64)offset32;
read_uint32(buf, buf_end, addend32);
relocation.relocation_addend = (uint64)addend32;
}
read_uint32(buf, buf_end, relocation.relocation_type);
read_uint32(buf, buf_end, symbol_index);

if (symbol_index >= symbol_count) {
set_error_buf(error_buf, error_buf_size,
"symbol index out of range");
goto fail;
}

symbol_name = symbol_buf + symbol_offsets[symbol_index];
symbol_name_len = *(uint16 *)symbol_name;
symbol_name += sizeof(uint16);

char group_name_buf[128] = { 0 };
char symbol_name_buf[128] = { 0 };
memcpy(group_name_buf, group_name, group_name_len);
memcpy(symbol_name_buf, symbol_name, symbol_name_len);

if (group_name_len == strlen(".text")
&& !strncmp(group_name, ".text", strlen(".text"))) {
if (symbol_name_len == strlen(XMM_PLT_PREFIX) + 32
&& !strncmp(symbol_name, XMM_PLT_PREFIX,
strlen(XMM_PLT_PREFIX))) {
module->xmm_plt_count++;
}
else if (symbol_name_len == strlen(REAL_PLT_PREFIX) + 16
&& !strncmp(symbol_name, REAL_PLT_PREFIX,
strlen(REAL_PLT_PREFIX))) {
module->real_plt_count++;
}
else if (symbol_name_len == strlen(REAL_PLT_PREFIX) + 8
&& !strncmp(symbol_name, REAL_PLT_PREFIX,
strlen(REAL_PLT_PREFIX))) {
module->float_plt_count++;
}
}
}
}

/* Allocate memory for extra plt data */
size = sizeof(uint64) * 2 * module->xmm_plt_count
+ sizeof(uint64) * module->real_plt_count
+ sizeof(uint32) * module->float_plt_count;
if (size > 0) {
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
/* aot code and data in x86_64 must be in range 0 to 2G due to
relocation for R_X86_64_32/32S/PC32 */
int map_flags = MMAP_MAP_32BIT;

if (size > UINT32_MAX
|| !(module->extra_plt_data = os_mmap(NULL, (uint32)size,
map_prot, map_flags))) {
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
goto fail;
}
module->extra_plt_data_size = (uint32)size;
}
#endif /* end of defined(BH_PLATFORM_WINDOWS) */

buf = symbol_buf_end;
read_uint32(buf, buf_end, group_count);

Expand Down Expand Up @@ -1614,6 +1829,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
}
}

/* TODO: set code and data read only */

ret = true;

fail:
Expand Down Expand Up @@ -2304,10 +2521,17 @@ aot_unload(AOTModule *module)

if (module->code) {
uint8 *mmap_addr = module->literal - sizeof(module->literal_size);
uint32 total_size = sizeof(module->literal_size) + module->literal_size + module->code_size;
uint32 total_size = sizeof(module->literal_size)
+ module->literal_size + module->code_size;
os_munmap(mmap_addr, total_size);
}

#if defined(BH_PLATFORM_WINDOWS)
if (module->extra_plt_data) {
os_munmap(module->extra_plt_data, module->extra_plt_data_size);
}
#endif

if (module->data_sections)
destroy_object_data_sections(module->data_sections,
module->data_section_count);
Expand Down
11 changes: 11 additions & 0 deletions core/iwasm/aot/aot_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,17 @@ typedef struct AOTModule {
uint8 *literal;
uint32 literal_size;

#if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
&& defined(BH_PLATFORM_WINDOWS)
/* extra plt data area for __xmm and __real constants
in Windows platform, NULL for JIT mode */
uint8 *extra_plt_data;
uint32 extra_plt_data_size;
uint32 xmm_plt_count;
uint32 real_plt_count;
uint32 float_plt_count;
#endif

/* data sections in AOT object file, including .data, .rodata
* and .rodata.cstN. NULL for JIT mode. */
AOTObjectDataSection *data_sections;
Expand Down
Loading