@@ -294,6 +294,39 @@ loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
294294 return mem ;
295295}
296296
297+ static void *
298+ loader_mmap (uint32 size , bool prot_exec , char * error_buf , uint32 error_buf_size )
299+ {
300+ int map_prot =
301+ MMAP_PROT_READ | MMAP_PROT_WRITE | (prot_exec ? MMAP_PROT_EXEC : 0 );
302+ int map_flags ;
303+ void * mem ;
304+
305+ #if UINTPTR_MAX == UINT64_MAX
306+ /* The mmapped AOT data and code in 64-bit targets had better be in
307+ range 0 to 2G, or aot loader may fail to apply some relocations,
308+ e.g., R_X86_64_32/R_X86_64_32S/R_X86_64_PC32/R_RISCV_32.
309+ We try to mmap with MMAP_MAP_32BIT flag first, and if fails, mmap
310+ again without the flag. */
311+ map_flags = MMAP_MAP_32BIT ;
312+ if ((mem = os_mmap (NULL , size , map_prot , map_flags ,
313+ os_get_invalid_handle ()))) {
314+ /* The mmapped memory must be in the first 2 Gigabytes of the
315+ process address space */
316+ bh_assert ((uintptr_t )mem < INT32_MAX );
317+ return mem ;
318+ }
319+ #endif
320+
321+ map_flags = MMAP_MAP_NONE ;
322+ if (!(mem = os_mmap (NULL , size , map_prot , map_flags ,
323+ os_get_invalid_handle ()))) {
324+ set_error_buf (error_buf , error_buf_size , "allocate memory failed" );
325+ return NULL ;
326+ }
327+ return mem ;
328+ }
329+
297330static char *
298331load_string (uint8 * * p_buf , const uint8 * buf_end , AOTModule * module ,
299332 bool is_load_from_file_buf ,
@@ -2407,7 +2440,8 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end,
24072440 read_string (buf , buf_end , data_sections [i ].name );
24082441 read_uint32 (buf , buf_end , data_sections [i ].size );
24092442 CHECK_BUF (buf , buf_end , data_sections [i ].size );
2410- /* temporary record data ptr for merge, will be replaced after mmaped */
2443+ /* Temporary record data ptr for merge, will be replaced after the
2444+ merged_data_sections is mmapped */
24112445 if (data_sections [i ].size > 0 )
24122446 data_sections [i ].data = (uint8 * )buf ;
24132447 buf += data_sections [i ].size ;
@@ -2418,33 +2452,13 @@ load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end,
24182452 return false;
24192453 }
24202454 if (total_size > 0 ) {
2421- int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE ;
2422- #if defined(BUILD_TARGET_X86_64 ) || defined(BUILD_TARGET_AMD_64 ) \
2423- || defined(BUILD_TARGET_RISCV64_LP64D ) \
2424- || defined(BUILD_TARGET_RISCV64_LP64 )
2425- /* aot code and data in x86_64 must be in range 0 to 2G due to
2426- relocation for R_X86_64_32/32S/PC32 */
2427- int map_flags = MMAP_MAP_32BIT ;
2428- #else
2429- int map_flags = MMAP_MAP_NONE ;
2430- #endif
24312455 /* Allocate memory for data */
24322456 merged_sections = module -> merged_data_sections =
2433- os_mmap (NULL , (uint32 )total_size , map_prot , map_flags ,
2434- os_get_invalid_handle ());
2457+ loader_mmap ((uint32 )total_size , false, error_buf , error_buf_size );
24352458 if (!merged_sections ) {
2436- set_error_buf (error_buf , error_buf_size , "allocate memory failed" );
24372459 return false;
24382460 }
24392461 module -> merged_data_sections_size = (uint32 )total_size ;
2440- #if defined(BUILD_TARGET_X86_64 ) || defined(BUILD_TARGET_AMD_64 )
2441- #if !defined(BH_PLATFORM_LINUX_SGX ) && !defined(BH_PLATFORM_WINDOWS ) \
2442- && !defined(BH_PLATFORM_DARWIN )
2443- /* address must be in the first 2 Gigabytes of
2444- the process address space */
2445- bh_assert ((uintptr_t )merged_sections < INT32_MAX );
2446- #endif
2447- #endif
24482462 }
24492463
24502464 /* Second iteration: Create each data section */
@@ -2570,71 +2584,63 @@ try_merge_data_and_text(const uint8 **buf, const uint8 **buf_end,
25702584 return true;
25712585 }
25722586
2573- /* calc total memory needed */
2587+ /* calculate the total memory needed */
25742588 total_size += align_uint64 ((uint64 )code_size , page_size );
25752589 for (i = 0 ; i < module -> data_section_count ; ++ i ) {
25762590 total_size +=
25772591 align_uint64 ((uint64 )module -> data_sections [i ].size , page_size );
25782592 }
2579- /* distance between .data and .text should not greater than 4GB for some
2580- * targets (eg . arm64 reloc need < 4G distance) */
2593+ /* distance between .data and .text should not be greater than 4GB
2594+ for some targets (e.g . arm64 reloc need < 4G distance) */
25812595 if (total_size > UINT32_MAX ) {
25822596 return false;
25832597 }
2598+ /* code_size was checked and must be larger than 0 here */
2599+ bh_assert (total_size > 0 );
25842600
2585- if (total_size != 0 ) {
2586- int map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE ;
2601+ sections = loader_mmap ((uint32 )total_size , false, NULL , 0 );
2602+ if (!sections ) {
2603+ /* merge failed but may be not critical for some targets */
2604+ return false;
2605+ }
2606+ /* change the code part to be executable */
2607+ if (os_mprotect (sections , code_size ,
2608+ MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC )
2609+ != 0 ) {
2610+ os_munmap (sections , (uint32 )total_size );
2611+ return false;
2612+ }
25872613
2588- #if defined(BUILD_TARGET_X86_64 ) || defined(BUILD_TARGET_AMD_64 ) \
2589- || defined(BUILD_TARGET_RISCV64_LP64D ) \
2590- || defined(BUILD_TARGET_RISCV64_LP64 )
2591- /* aot code and data in x86_64 must be in range 0 to 2G due
2592- to relocation for R_X86_64_32/32S/PC32 */
2593- int map_flags = MMAP_MAP_32BIT ;
2594- #else
2595- int map_flags = MMAP_MAP_NONE ;
2596- #endif
2614+ module -> merged_data_text_sections = sections ;
2615+ module -> merged_data_text_sections_size = (uint32 )total_size ;
25972616
2598- sections = os_mmap (NULL , (uint32 )total_size , map_prot , map_flags ,
2599- os_get_invalid_handle ());
2600- if (!sections ) {
2601- /* merge failed but maybe not critical for some targes */
2602- return false;
2603- }
2604- if (os_mprotect (sections , code_size , map_prot | MMAP_PROT_EXEC ) != 0 ) {
2605- os_munmap (sections , (uint32 )total_size );
2606- return false;
2607- }
2617+ /* order not essential just as compiler does: .text section first */
2618+ * buf = sections ;
2619+ * buf_end = sections + code_size ;
2620+ bh_memcpy_s (sections , code_size , old_buf , code_size );
2621+ os_munmap (old_buf , code_size );
2622+ sections += align_uint ((uint32 )code_size , page_size );
26082623
2609- module -> merged_data_text_sections = sections ;
2610- module -> merged_data_text_sections_size = (uint32 )total_size ;
2611-
2612- /* order not essential just as compilers do: .text section first */
2613- * buf = sections ;
2614- * buf_end = sections + code_size ;
2615- bh_memcpy_s (sections , code_size , old_buf , code_size );
2616- os_munmap (old_buf , code_size );
2617- sections += align_uint ((uint32 )code_size , page_size );
2618-
2619- /* then .data sections */
2620- for (i = 0 ; i < module -> data_section_count ; ++ i ) {
2621- AOTObjectDataSection * data_section = module -> data_sections + i ;
2622- uint8 * old_data = data_section -> data ;
2623- data_section -> data = sections ;
2624- bh_memcpy_s (data_section -> data , data_section -> size , old_data ,
2625- data_section -> size );
2626- sections += align_uint (data_section -> size , page_size );
2627- }
2628- if (module -> merged_data_sections ) {
2629- os_munmap (module -> merged_data_sections ,
2630- module -> merged_data_sections_size );
2631- module -> merged_data_sections = NULL ;
2632- module -> merged_data_sections_size = 0 ;
2633- }
2624+ /* then migrate .data sections */
2625+ for (i = 0 ; i < module -> data_section_count ; ++ i ) {
2626+ AOTObjectDataSection * data_section = module -> data_sections + i ;
2627+ uint8 * old_data = data_section -> data ;
2628+ data_section -> data = sections ;
2629+ bh_memcpy_s (data_section -> data , data_section -> size , old_data ,
2630+ data_section -> size );
2631+ sections += align_uint (data_section -> size , page_size );
2632+ }
2633+ /* free the original data sections */
2634+ if (module -> merged_data_sections ) {
2635+ os_munmap (module -> merged_data_sections ,
2636+ module -> merged_data_sections_size );
2637+ module -> merged_data_sections = NULL ;
2638+ module -> merged_data_sections_size = 0 ;
26342639 }
2640+
26352641 return true;
26362642}
2637- #endif // ! defined(BH_PLATFORM_NUTTX) && !defined(BH_PLATFORM_ESP_IDF)
2643+ #endif /* ! defined(BH_PLATFORM_NUTTX) && !defined(BH_PLATFORM_ESP_IDF) */
26382644
26392645static bool
26402646load_text_section (const uint8 * buf , const uint8 * buf_end , AOTModule * module ,
@@ -3495,16 +3501,9 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
34953501 + sizeof (uint64 ) * module -> real_plt_count
34963502 + sizeof (uint32 ) * module -> float_plt_count ;
34973503 if (size > 0 ) {
3498- map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC ;
3499- /* aot code and data in x86_64 must be in range 0 to 2G due to
3500- relocation for R_X86_64_32/32S/PC32 */
3501- map_flags = MMAP_MAP_32BIT ;
3502-
35033504 if (size > UINT32_MAX
3504- || !(module -> extra_plt_data =
3505- os_mmap (NULL , (uint32 )size , map_prot , map_flags ,
3506- os_get_invalid_handle ()))) {
3507- set_error_buf (error_buf , error_buf_size , "mmap memory failed" );
3505+ || !(module -> extra_plt_data = loader_mmap (
3506+ (uint32 )size , true, error_buf , error_buf_size ))) {
35083507 goto fail ;
35093508 }
35103509 module -> extra_plt_data_size = (uint32 )size ;
@@ -3616,19 +3615,12 @@ load_relocation_section(const uint8 *buf, const uint8 *buf_end,
36163615 GOTItem * got_item = module -> got_item_list ;
36173616 uint32 got_item_idx = 0 ;
36183617
3619- map_prot = MMAP_PROT_READ | MMAP_PROT_WRITE ;
3620- /* aot code and data in x86_64 must be in range 0 to 2G due to
3621- relocation for R_X86_64_32/32S/PC32 */
3622- map_flags = MMAP_MAP_32BIT ;
3623-
36243618 /* Create the GOT for func_ptrs, note that it is different from
36253619 the .got section of a dynamic object file */
36263620 size = (uint64 )sizeof (void * ) * got_item_count ;
36273621 if (size > UINT32_MAX
3628- || !(module -> got_func_ptrs =
3629- os_mmap (NULL , (uint32 )size , map_prot , map_flags ,
3630- os_get_invalid_handle ()))) {
3631- set_error_buf (error_buf , error_buf_size , "mmap memory failed" );
3622+ || !(module -> got_func_ptrs = loader_mmap (
3623+ (uint32 )size , false, error_buf , error_buf_size ))) {
36323624 goto fail ;
36333625 }
36343626
@@ -3863,7 +3855,7 @@ load_from_sections(AOTModule *module, AOTSection *sections,
38633855 if (!try_merge_data_and_text (& buf , & buf_end , module ,
38643856 error_buf , error_buf_size ))
38653857 LOG_WARNING ("merge .data and .text sections failed" );
3866- #endif // ! defined(BH_PLATFORM_NUTTX) && !defined(BH_PLATFORM_ESP_IDF)
3858+ #endif /* ! defined(BH_PLATFORM_NUTTX) && !defined(BH_PLATFORM_ESP_IDF) */
38673859 if (!load_text_section (buf , buf_end , module , error_buf ,
38683860 error_buf_size ))
38693861 return false;
@@ -4180,37 +4172,16 @@ create_sections(AOTModule *module, const uint8 *buf, uint32 size,
41804172
41814173 if (section_type == AOT_SECTION_TYPE_TEXT ) {
41824174 if ((section_size > 0 ) && !module -> is_indirect_mode ) {
4183- int map_prot =
4184- MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC ;
4185- #if defined(BUILD_TARGET_X86_64 ) || defined(BUILD_TARGET_AMD_64 ) \
4186- || defined(BUILD_TARGET_RISCV64_LP64D ) \
4187- || defined(BUILD_TARGET_RISCV64_LP64 )
4188- /* aot code and data in x86_64 must be in range 0 to 2G due
4189- to relocation for R_X86_64_32/32S/PC32 */
4190- int map_flags = MMAP_MAP_32BIT ;
4191- #else
4192- int map_flags = MMAP_MAP_NONE ;
4193- #endif
41944175 total_size =
41954176 (uint64 )section_size + aot_get_plt_table_size ();
41964177 total_size = (total_size + 3 ) & ~((uint64 )3 );
41974178 if (total_size >= UINT32_MAX
41984179 || !(aot_text =
4199- os_mmap ( NULL , (uint32 )total_size , map_prot ,
4200- map_flags , os_get_invalid_handle () ))) {
4180+ loader_mmap ( (uint32 )total_size , true ,
4181+ error_buf , error_buf_size ))) {
42014182 wasm_runtime_free (section );
4202- set_error_buf (error_buf , error_buf_size ,
4203- "mmap memory failed" );
42044183 goto fail ;
42054184 }
4206- #if defined(BUILD_TARGET_X86_64 ) || defined(BUILD_TARGET_AMD_64 )
4207- #if !defined(BH_PLATFORM_LINUX_SGX ) && !defined(BH_PLATFORM_WINDOWS ) \
4208- && !defined(BH_PLATFORM_DARWIN )
4209- /* address must be in the first 2 Gigabytes of
4210- the process address space */
4211- bh_assert ((uintptr_t )aot_text < INT32_MAX );
4212- #endif
4213- #endif
42144185
42154186#if (WASM_MEM_DUAL_BUS_MIRROR != 0 )
42164187 mirrored_text = os_get_dbus_mirror (aot_text );
0 commit comments