Skip to content

Commit fda3a26

Browse files
authored
Fix some relocation type issues in windows (#574)
Implement Windows PE file relocation type IMAGE_REL_AMD64_ADDR64/ADDR32/REL32, implement relocation for symbol "__xmm@xxx"/"__plt@xxx"/".rdata", implement Windows invokeNative simd asm code and enable SIMD by default for windows platform. Also update wamrc tool. Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
1 parent afa1feb commit fda3a26

7 files changed

Lines changed: 385 additions & 30 deletions

File tree

core/iwasm/aot/aot_loader.c

Lines changed: 227 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "../interpreter/wasm_loader.h"
1616
#endif
1717

18+
#define XMM_PLT_PREFIX "__xmm@"
19+
#define REAL_PLT_PREFIX "__real@"
1820

1921
static void
2022
set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
@@ -1280,12 +1282,13 @@ get_data_section_addr(AOTModule *module, const char *section_name,
12801282
uint32 i;
12811283
AOTObjectDataSection *data_section = module->data_sections;
12821284

1283-
for (i = 0; i < module->data_section_count; i++, data_section++)
1285+
for (i = 0; i < module->data_section_count; i++, data_section++) {
12841286
if (!strcmp(data_section->name, section_name)) {
12851287
if (p_data_size)
12861288
*p_data_size = data_section->size;
12871289
return data_section->data;
12881290
}
1291+
}
12891292

12901293
return NULL;
12911294
}
@@ -1313,6 +1316,53 @@ is_literal_relocation(const char *reloc_sec_name)
13131316
return !strcmp(reloc_sec_name, ".rela.literal");
13141317
}
13151318

1319+
#if defined(BH_PLATFORM_WINDOWS)
1320+
static bool
1321+
str2uint32(const char *buf, uint32 *p_res)
1322+
{
1323+
uint32 res = 0, val;
1324+
const char *buf_end = buf + 8;
1325+
char ch;
1326+
1327+
while (buf < buf_end) {
1328+
ch = *buf++;
1329+
if (ch >= '0' && ch <= '9')
1330+
val = ch - '0';
1331+
else if (ch >= 'a' && ch <= 'f')
1332+
val = ch - 'a' + 0xA;
1333+
else if (ch >= 'A' && ch <= 'F')
1334+
val = ch - 'A' + 0xA;
1335+
else
1336+
return false;
1337+
res = (res << 4) | val;
1338+
}
1339+
*p_res = res;
1340+
return true;
1341+
}
1342+
static bool
1343+
str2uint64(const char *buf, uint64 *p_res)
1344+
{
1345+
uint64 res = 0, val;
1346+
const char *buf_end = buf + 16;
1347+
char ch;
1348+
1349+
while (buf < buf_end) {
1350+
ch = *buf++;
1351+
if (ch >= '0' && ch <= '9')
1352+
val = ch - '0';
1353+
else if (ch >= 'a' && ch <= 'f')
1354+
val = ch - 'a' + 0xA;
1355+
else if (ch >= 'A' && ch <= 'F')
1356+
val = ch - 'A' + 0xA;
1357+
else
1358+
return false;
1359+
res = (res << 4) | val;
1360+
}
1361+
*p_res = res;
1362+
return true;
1363+
}
1364+
#endif
1365+
13161366
static bool
13171367
do_text_relocation(AOTModule *module,
13181368
AOTRelocationGroup *group,
@@ -1322,6 +1372,9 @@ do_text_relocation(AOTModule *module,
13221372
uint8 *aot_text = is_literal ? module->literal : module->code;
13231373
uint32 aot_text_size = is_literal ? module->literal_size : module->code_size;
13241374
uint32 i, func_index, symbol_len;
1375+
#if defined(BH_PLATFORM_WINDOWS)
1376+
uint32 xmm_plt_index = 0, real_plt_index = 0, float_plt_index = 0;
1377+
#endif
13251378
char symbol_buf[128] = { 0 }, *symbol, *p;
13261379
void *symbol_addr;
13271380
AOTRelocation *relocation = group->relocations;
@@ -1360,6 +1413,7 @@ do_text_relocation(AOTModule *module,
13601413
symbol_addr = module->code;
13611414
}
13621415
else if (!strcmp(symbol, ".data")
1416+
|| !strcmp(symbol, ".rdata")
13631417
|| !strcmp(symbol, ".rodata")
13641418
/* ".rodata.cst4/8/16/.." */
13651419
|| !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))) {
@@ -1373,9 +1427,66 @@ do_text_relocation(AOTModule *module,
13731427
else if (!strcmp(symbol, ".literal")) {
13741428
symbol_addr = module->literal;
13751429
}
1430+
#if defined(BH_PLATFORM_WINDOWS)
1431+
else if (!strcmp(group->section_name, ".text")
1432+
&& !strncmp(symbol, XMM_PLT_PREFIX, strlen(XMM_PLT_PREFIX))
1433+
&& strlen(symbol) == strlen(XMM_PLT_PREFIX) + 32) {
1434+
char xmm_buf[17] = { 0 };
1435+
1436+
symbol_addr = module->extra_plt_data + xmm_plt_index * 16;
1437+
bh_memcpy_s(xmm_buf, sizeof(xmm_buf),
1438+
symbol + strlen(XMM_PLT_PREFIX) + 16, 16);
1439+
if (!str2uint64(xmm_buf, (uint64*)symbol_addr)) {
1440+
set_error_buf(error_buf, error_buf,
1441+
"resolve symbol %s failed", symbol);
1442+
goto check_symbol_fail;
1443+
}
1444+
1445+
bh_memcpy_s(xmm_buf, sizeof(xmm_buf),
1446+
symbol + strlen(XMM_PLT_PREFIX), 16);
1447+
if (!str2uint64(xmm_buf, (uint64*)((uint8*)symbol_addr + 8))) {
1448+
set_error_buf(error_buf, error_buf,
1449+
"resolve symbol %s failed", symbol);
1450+
goto check_symbol_fail;
1451+
}
1452+
xmm_plt_index++;
1453+
}
1454+
else if (!strcmp(group->section_name, ".text")
1455+
&& !strncmp(symbol, REAL_PLT_PREFIX, strlen(REAL_PLT_PREFIX))
1456+
&& strlen(symbol) == strlen(REAL_PLT_PREFIX) + 16) {
1457+
char real_buf[17] = { 0 };
1458+
1459+
symbol_addr = module->extra_plt_data + module->xmm_plt_count * 16
1460+
+ real_plt_index * 8;
1461+
bh_memcpy_s(real_buf, sizeof(real_buf),
1462+
symbol + strlen(REAL_PLT_PREFIX), 16);
1463+
if (!str2uint64(real_buf, (uint64*)symbol_addr)) {
1464+
set_error_buf(error_buf, error_buf,
1465+
"resolve symbol %s failed", symbol);
1466+
goto check_symbol_fail;
1467+
}
1468+
real_plt_index++;
1469+
}
1470+
else if (!strcmp(group->section_name, ".text")
1471+
&& !strncmp(symbol, REAL_PLT_PREFIX, strlen(REAL_PLT_PREFIX))
1472+
&& strlen(symbol) == strlen(REAL_PLT_PREFIX) + 8) {
1473+
char float_buf[9] = { 0 };
1474+
1475+
symbol_addr = module->extra_plt_data + module->xmm_plt_count * 16
1476+
+ module->real_plt_count * 8 + float_plt_index * 4;
1477+
bh_memcpy_s(float_buf, sizeof(float_buf),
1478+
symbol + strlen(REAL_PLT_PREFIX), 8);
1479+
if (!str2uint32(float_buf, (uint32*)symbol_addr)) {
1480+
set_error_buf(error_buf, error_buf,
1481+
"resolve symbol %s failed", symbol);
1482+
goto check_symbol_fail;
1483+
}
1484+
float_plt_index++;
1485+
}
1486+
#endif /* end of defined(BH_PLATFORM_WINDOWS) */
13761487
else if (!(symbol_addr = resolve_target_sym(symbol, &symbol_index))) {
13771488
set_error_buf_v(error_buf, error_buf_size,
1378-
"resolve symbol %s failed", symbol);
1489+
"resolve symbol %s failed", symbol);
13791490
goto check_symbol_fail;
13801491
}
13811492

@@ -1418,6 +1529,9 @@ do_data_relocation(AOTModule *module,
14181529
else if (!strncmp(group->section_name, ".rel.", 5)) {
14191530
data_section_name = group->section_name + strlen(".rel");
14201531
}
1532+
else if (!strcmp(group->section_name, ".rdata")) {
1533+
data_section_name = group->section_name;
1534+
}
14211535
else {
14221536
set_error_buf(error_buf, error_buf_size,
14231537
"invalid data relocation section name");
@@ -1426,6 +1540,7 @@ do_data_relocation(AOTModule *module,
14261540

14271541
data_addr = get_data_section_addr(module, data_section_name,
14281542
&data_size);
1543+
14291544
if (group->relocation_count > 0 && !data_addr) {
14301545
set_error_buf(error_buf, error_buf_size,
14311546
"invalid data relocation count");
@@ -1514,6 +1629,106 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
15141629
goto fail;
15151630
}
15161631

1632+
#if defined(BH_PLATFORM_WINDOWS)
1633+
buf = symbol_buf_end;
1634+
read_uint32(buf, buf_end, group_count);
1635+
1636+
for (i = 0; i < group_count; i++) {
1637+
uint32 name_index, relocation_count;
1638+
uint16 group_name_len;
1639+
uint8 *group_name;
1640+
1641+
/* section name address is 4 bytes aligned. */
1642+
buf = (uint8*)align_ptr(buf, sizeof(uint32));
1643+
read_uint32(buf, buf_end, name_index);
1644+
1645+
if (name_index >= symbol_count) {
1646+
set_error_buf(error_buf, error_buf_size,
1647+
"symbol index out of range");
1648+
goto fail;
1649+
}
1650+
1651+
group_name = symbol_buf + symbol_offsets[name_index];
1652+
group_name_len = *(uint16 *)group_name;
1653+
group_name += sizeof(uint16);
1654+
1655+
read_uint32(buf, buf_end, relocation_count);
1656+
1657+
for (j = 0; j < relocation_count; j++) {
1658+
AOTRelocation relocation = { 0 };
1659+
uint32 symbol_index, offset32, addend32;
1660+
uint16 symbol_name_len;
1661+
uint8 *symbol_name;
1662+
1663+
if (sizeof(void *) == 8) {
1664+
read_uint64(buf, buf_end, relocation.relocation_offset);
1665+
read_uint64(buf, buf_end, relocation.relocation_addend);
1666+
}
1667+
else {
1668+
read_uint32(buf, buf_end, offset32);
1669+
relocation.relocation_offset = (uint64)offset32;
1670+
read_uint32(buf, buf_end, addend32);
1671+
relocation.relocation_addend = (uint64)addend32;
1672+
}
1673+
read_uint32(buf, buf_end, relocation.relocation_type);
1674+
read_uint32(buf, buf_end, symbol_index);
1675+
1676+
if (symbol_index >= symbol_count) {
1677+
set_error_buf(error_buf, error_buf_size,
1678+
"symbol index out of range");
1679+
goto fail;
1680+
}
1681+
1682+
symbol_name = symbol_buf + symbol_offsets[symbol_index];
1683+
symbol_name_len = *(uint16 *)symbol_name;
1684+
symbol_name += sizeof(uint16);
1685+
1686+
char group_name_buf[128] = { 0 };
1687+
char symbol_name_buf[128] = { 0 };
1688+
memcpy(group_name_buf, group_name, group_name_len);
1689+
memcpy(symbol_name_buf, symbol_name, symbol_name_len);
1690+
1691+
if (group_name_len == strlen(".text")
1692+
&& !strncmp(group_name, ".text", strlen(".text"))) {
1693+
if (symbol_name_len == strlen(XMM_PLT_PREFIX) + 32
1694+
&& !strncmp(symbol_name, XMM_PLT_PREFIX,
1695+
strlen(XMM_PLT_PREFIX))) {
1696+
module->xmm_plt_count++;
1697+
}
1698+
else if (symbol_name_len == strlen(REAL_PLT_PREFIX) + 16
1699+
&& !strncmp(symbol_name, REAL_PLT_PREFIX,
1700+
strlen(REAL_PLT_PREFIX))) {
1701+
module->real_plt_count++;
1702+
}
1703+
else if (symbol_name_len == strlen(REAL_PLT_PREFIX) + 8
1704+
&& !strncmp(symbol_name, REAL_PLT_PREFIX,
1705+
strlen(REAL_PLT_PREFIX))) {
1706+
module->float_plt_count++;
1707+
}
1708+
}
1709+
}
1710+
}
1711+
1712+
/* Allocate memory for extra plt data */
1713+
size = sizeof(uint64) * 2 * module->xmm_plt_count
1714+
+ sizeof(uint64) * module->real_plt_count
1715+
+ sizeof(uint32) * module->float_plt_count;
1716+
if (size > 0) {
1717+
int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
1718+
/* aot code and data in x86_64 must be in range 0 to 2G due to
1719+
relocation for R_X86_64_32/32S/PC32 */
1720+
int map_flags = MMAP_MAP_32BIT;
1721+
1722+
if (size > UINT32_MAX
1723+
|| !(module->extra_plt_data = os_mmap(NULL, (uint32)size,
1724+
map_prot, map_flags))) {
1725+
set_error_buf(error_buf, error_buf_size, "mmap memory failed");
1726+
goto fail;
1727+
}
1728+
module->extra_plt_data_size = (uint32)size;
1729+
}
1730+
#endif /* end of defined(BH_PLATFORM_WINDOWS) */
1731+
15171732
buf = symbol_buf_end;
15181733
read_uint32(buf, buf_end, group_count);
15191734

@@ -1614,6 +1829,8 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
16141829
}
16151830
}
16161831

1832+
/* TODO: set code and data read only */
1833+
16171834
ret = true;
16181835

16191836
fail:
@@ -2304,10 +2521,17 @@ aot_unload(AOTModule *module)
23042521

23052522
if (module->code) {
23062523
uint8 *mmap_addr = module->literal - sizeof(module->literal_size);
2307-
uint32 total_size = sizeof(module->literal_size) + module->literal_size + module->code_size;
2524+
uint32 total_size = sizeof(module->literal_size)
2525+
+ module->literal_size + module->code_size;
23082526
os_munmap(mmap_addr, total_size);
23092527
}
23102528

2529+
#if defined(BH_PLATFORM_WINDOWS)
2530+
if (module->extra_plt_data) {
2531+
os_munmap(module->extra_plt_data, module->extra_plt_data_size);
2532+
}
2533+
#endif
2534+
23112535
if (module->data_sections)
23122536
destroy_object_data_sections(module->data_sections,
23132537
module->data_section_count);

core/iwasm/aot/aot_runtime.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,17 @@ typedef struct AOTModule {
159159
uint8 *literal;
160160
uint32 literal_size;
161161

162+
#if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
163+
&& defined(BH_PLATFORM_WINDOWS)
164+
/* extra plt data area for __xmm and __real constants
165+
in Windows platform, NULL for JIT mode */
166+
uint8 *extra_plt_data;
167+
uint32 extra_plt_data_size;
168+
uint32 xmm_plt_count;
169+
uint32 real_plt_count;
170+
uint32 float_plt_count;
171+
#endif
172+
162173
/* data sections in AOT object file, including .data, .rodata
163174
* and .rodata.cstN. NULL for JIT mode. */
164175
AOTObjectDataSection *data_sections;

0 commit comments

Comments
 (0)