1515#include "../interpreter/wasm_loader.h"
1616#endif
1717
18+ #define XMM_PLT_PREFIX "__xmm@"
19+ #define REAL_PLT_PREFIX "__real@"
1820
1921static void
2022set_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+
13161366static bool
13171367do_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
16191836fail :
@@ -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 );
0 commit comments