Skip to content

Commit 5f517e4

Browse files
authored
aot loader: Refine os_mmap related code (#3711)
1 parent 55cb9c5 commit 5f517e4

1 file changed

Lines changed: 85 additions & 114 deletions

File tree

core/iwasm/aot/aot_loader.c

Lines changed: 85 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
297330
static char *
298331
load_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

26392645
static bool
26402646
load_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

Comments
 (0)