From 9e7a1062327621f551bb897f680da92c2bb9209a Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Thu, 19 Jan 2023 12:49:02 +0900 Subject: [PATCH] dlmalloc: require __heap_end This commit effectively drops the support of older wasm-ld. (LLVM <15.0.7) We have two relevant use cases: * `memory.grow` use outside of malloc (eg. used by polyfill preview1 binaries) * `--init-memory` to somehow preallocate heap (eg. avoid dynamic allocations, especially on small environments) While https://github.com/WebAssembly/wasi-libc/pull/377 fixed the former, it broke the latter if you are using an older LLVM, which doesn't provide the `__heap_end` symbol, to link your module. As we couldn't come up with a solution which satisfies all parties, this commit simply makes it require new enough LLVM which provides `__heap_end`. After all, a link-time failure is more friendly to users than failing later in a subtle way. --- dlmalloc/src/malloc.c | 25 ++++++------------- .../wasm32-wasi-threads/undefined-symbols.txt | 1 + expected/wasm32-wasi/undefined-symbols.txt | 1 + 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/dlmalloc/src/malloc.c b/dlmalloc/src/malloc.c index 6e7a15c03..c6afd938c 100644 --- a/dlmalloc/src/malloc.c +++ b/dlmalloc/src/malloc.c @@ -5215,7 +5215,7 @@ static void internal_inspect_all(mstate m, /* Symbol marking the end of data, bss and explicit stack, provided by wasm-ld. */ extern char __heap_base; -extern char __heap_end __attribute__((__weak__)); +extern char __heap_end; /* Initialize the initial state of dlmalloc to be able to use free memory between __heap_base and initial. */ static void try_init_allocator(void) { @@ -5227,23 +5227,14 @@ static void try_init_allocator(void) { char *base = &__heap_base; // Try to use the linker pseudo-symbol `__heap_end` for the initial size of - // the heap, but if that's not defined due to LLVM being too old perhaps then - // round up `base` to the nearest `PAGESIZE`. The initial size of linear - // memory will be at least the heap base to this page boundary, and it's then - // assumed that the initial linear memory image was truncated at that point. - // While this reflects the default behavior of `wasm-ld` it is also possible - // for users to craft larger linear memories by passing options to extend - // beyond this threshold. In this situation the memory will not be used for - // dlmalloc. - // - // Note that `sbrk(0)`, or in dlmalloc-ese `CALL_MORECORE(0)`, is specifically - // not used here. That captures the current size of the heap but is only - // correct if the we're the first to try to grow the heap. If the heap has - // grown elsewhere, such as a different allocator in place, then this would - // incorrectly claim such memroy as our own. + // the heap. char *end = &__heap_end; - if (end == NULL) - end = (char*) page_align((size_t) base); + if (end == NULL) { + // This can happen when 1. you are using an old wasm-ld which doesn't + // provide `__heap_end` and 2. something (other libraries or maybe + // your app?) provide a weak reference to `__heap_end`. + return; + } size_t initial_heap_size = end - base; /* Check that initial heap is long enough to serve a minimal allocation request. */ diff --git a/expected/wasm32-wasi-threads/undefined-symbols.txt b/expected/wasm32-wasi-threads/undefined-symbols.txt index a68515194..c04b5f703 100644 --- a/expected/wasm32-wasi-threads/undefined-symbols.txt +++ b/expected/wasm32-wasi-threads/undefined-symbols.txt @@ -13,6 +13,7 @@ __getf2 __global_base __gttf2 __heap_base +__heap_end __imported_wasi_snapshot_preview1_args_get __imported_wasi_snapshot_preview1_args_sizes_get __imported_wasi_snapshot_preview1_clock_res_get diff --git a/expected/wasm32-wasi/undefined-symbols.txt b/expected/wasm32-wasi/undefined-symbols.txt index b9cdb3432..6d3b2b7d6 100644 --- a/expected/wasm32-wasi/undefined-symbols.txt +++ b/expected/wasm32-wasi/undefined-symbols.txt @@ -11,6 +11,7 @@ __floatunsitf __getf2 __gttf2 __heap_base +__heap_end __imported_wasi_snapshot_preview1_args_get __imported_wasi_snapshot_preview1_args_sizes_get __imported_wasi_snapshot_preview1_clock_res_get