From ff296c1a623bb1a59b1e1bf1853aa52906c21da3 Mon Sep 17 00:00:00 2001 From: Wenyong Huang Date: Mon, 18 Mar 2024 09:51:38 +0800 Subject: [PATCH 1/5] Fix aot relocation symbols not found on windows 32-bit (#3231) The symbols in windows 32-bit may start with '_' and can not be found when resolving the relocations to them. This PR ignores the underscore when handling the relocation name of AOT_FUNC_INTERNAL_PREFIX, and redirect the relocation with name "_aot_stack_sizes" to the relocation with name ".aot_stack_sizes" (the name of the data section created). ps. https://github.com/bytecodealliance/wasm-micro-runtime/issues/3216 --- core/iwasm/aot/aot_loader.c | 11 +++++++++++ core/iwasm/compilation/aot_emit_aot_file.c | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 759954adb..3e832c27e 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -2917,6 +2917,17 @@ do_text_relocation(AOTModule *module, AOTRelocationGroup *group, } symbol_addr = module->func_ptrs[func_index]; } + else if (!strncmp(symbol, "_" AOT_FUNC_INTERNAL_PREFIX, + strlen("_" AOT_FUNC_INTERNAL_PREFIX))) { + p = symbol + strlen("_" AOT_FUNC_INTERNAL_PREFIX); + if (*p == '\0' + || (func_index = (uint32)atoi(p)) > module->func_count) { + set_error_buf_v(error_buf, error_buf_size, "invalid symbol %s", + symbol); + goto check_symbol_fail; + } + symbol_addr = module->func_ptrs[func_index]; + } #endif else if (is_text_section(symbol)) { symbol_addr = module->code; diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 758681d66..3bad41f30 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -3947,7 +3947,12 @@ aot_resolve_object_relocation_group(AOTObjectData *obj_data, * Note: aot_stack_sizes_section_name section only contains * stack_sizes table. */ - if (!strcmp(relocation->symbol_name, aot_stack_sizes_name)) { + if (!strcmp(relocation->symbol_name, aot_stack_sizes_name) + /* in windows 32, the symbol name may start with '_' */ + || (strlen(relocation->symbol_name) > 0 + && relocation->symbol_name[0] == '_' + && !strcmp(relocation->symbol_name + 1, + aot_stack_sizes_name))) { /* discard const */ relocation->symbol_name = (char *)aot_stack_sizes_section_name; } From 8c1269d44d1b3dadca0809ef9d605fdf5bc45000 Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Mon, 18 Mar 2024 10:32:55 +0800 Subject: [PATCH 2/5] trans_wasm_func_name.py: Correct function index during translation (#3232) Adding the N from "aot_func#N" with the import function count is the correct wasm function index. --- doc/perf_tune.md | 23 +++++++++++-------- .../trans_wasm_func_name.py | 13 +++++++---- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/doc/perf_tune.md b/doc/perf_tune.md index bb463d702..7858cc854 100644 --- a/doc/perf_tune.md +++ b/doc/perf_tune.md @@ -98,17 +98,22 @@ You should only use this method for well tested wasm applications and make sure Linux perf is a powerful tool to analyze the performance of a program, developer can use it to find the hot functions and optimize them. It is one profiler supported by WAMR. In order to use it, you need to add `--perf-profile` while running _iwasm_. By default, it is disabled. > [!CAUTION] -> For now, only llvm-jit mode supports linux-perf. +> For now, only llvm-jit mode and aot mode supports linux-perf. Here is a basic example, if there is a Wasm application _foo.wasm_, you'll execute. ``` -$ perf record --output=perf.data.raw -- iwasm --perf-profile foo.wasm +$ perf record --output=perf.data.raw -- iwasm --enable-linux-perf foo.wasm ``` -This will create a _perf.data_ and a _jit-xxx.dump_ under _~/.debug.jit/_ folder. This extra file is WAMR generated at runtime, and it contains the mapping between the JIT code and the original Wasm function names. +This will create a _perf.data_ and +- a _jit-xxx.dump_ under _~/.debug/jit/_ folder if running llvm-jit mode +- or _/tmp/perf-.map_ if running AOT mode -The next thing need to do is to merge _jit-xxx.dump_ file into the _perf.data_. + +This file is WAMR generated. It contains information which includes jitted(precompiled) code addresses in memory, names of jitted (precompiled) functions which are named as *aot_func#N* and so on. + +If running with llvm-jit mode, the next thing is to merge _jit-xxx.dump_ file into the _perf.data_. ``` $ perf inject --jit --input=perf.data.raw --output=perf.data @@ -141,28 +146,28 @@ $ perf report --input=perf.data [Flamegraph](https://www.brendangregg.com/flamegraphs.html) is a powerful tool to visualize stack traces of profiled software so that the most frequent code-paths can be identified quickly and accurately. In order to use it, you need to [capture graphs](https://github.com/brendangregg/FlameGraph#1-capture-stacks) when running `perf record` ``` -$ perf record -k mono --call-graph=fp --output=perf.data.raw -- iwasm --perf-profile foo.wasm +$ perf record -k mono --call-graph=fp --output=perf.data.raw -- iwasm --enable-linux-perf foo.wasm ``` -merge the _jit-xxx.dump_ file into the _perf.data.raw_. +If running with llvm-jit mode, merge the _jit-xxx.dump_ file into the _perf.data.raw_. ``` $ perf inject --jit --input=perf.data.raw --output=perf.data ``` -generate the stack trace file. +Generate the stack trace file. ``` $ perf script > out.perf ``` -[fold stacks](https://github.com/brendangregg/FlameGraph#2-fold-stacks). +[Fold stacks](https://github.com/brendangregg/FlameGraph#2-fold-stacks). ``` $ ./FlameGraph/stackcollapse-perf.pl out.perf > out.folded ``` -[render a flamegraph](https://github.com/brendangregg/FlameGraph#3-flamegraphpl) +[Render a flamegraph](https://github.com/brendangregg/FlameGraph#3-flamegraphpl) ``` $ ./FlameGraph/flamegraph.pl out.folded > perf.foo.wasm.svg diff --git a/test-tools/trans-jitted-func-name/trans_wasm_func_name.py b/test-tools/trans-jitted-func-name/trans_wasm_func_name.py index 1380cd52a..0206fc287 100644 --- a/test-tools/trans-jitted-func-name/trans_wasm_func_name.py +++ b/test-tools/trans-jitted-func-name/trans_wasm_func_name.py @@ -68,6 +68,7 @@ def collect_import_section_content(wasm_objdump_bin: Path, wasm_file: Path) -> d ) if p.stderr: + print("No content in import section") return {} import_section = {} @@ -77,17 +78,19 @@ def collect_import_section_content(wasm_objdump_bin: Path, wasm_file: Path) -> d if not line: continue - if line.startswith(" - func"): - import_section.update("function", import_section.get("function", 0) + 1) + if re.search(r"^-\s+func", line): + import_section.update(function=import_section.get("function", 0) + 1) else: pass + assert len(import_section) > 0, "failed to retrive content of import section" return import_section def collect_name_section_content(wasm_objdump_bin: Path, wasm_file: Path) -> dict: """ - execute "wasm_objdump_bin -j name -x wasm_file" and store the output in a list + execute "wasm_objdump_bin -j name -x wasm_file" and store the output in a dict + {1: xxxx, 2: yyyy, 3: zzzz} """ assert wasm_objdump_bin.exists() assert wasm_file.exists() @@ -117,7 +120,7 @@ def collect_name_section_content(wasm_objdump_bin: Path, wasm_file: Path) -> dic assert m func_index, func_name = m.groups() - name_section.update({func_index: func_name}) + name_section.update({int(func_index): func_name}) assert name_section return name_section @@ -162,7 +165,7 @@ def replace_function_name( new_line.append(sym) continue - func_idx = m.groups()[-1] + func_idx = int(m.groups()[-1]) + import_function_count if func_idx in name_section: wasm_func_name = f"[Wasm] {name_section[func_idx]}" else: From 7486056aeee723a523c7dd518b97b0cfad3213c6 Mon Sep 17 00:00:00 2001 From: TianlongLiang <111852609+TianlongLiang@users.noreply.github.com> Date: Mon, 18 Mar 2024 11:15:47 +0800 Subject: [PATCH 3/5] Fix nightly run tsan ASLR issue (#3233) The nightly run CI reported error: "FATAL: ThreadSanitizer: unexpected memory mapping 0x5be565bf3000-0x5be565bfb000" which is caused by the ASLR issue, we set `vm.mmap_rnd_bits` to 28 to resolve it, according to the post below: https://stackoverflow.com/questions/77850769/fatal-threadsanitizer-unexpected-memory-mapping-when-running-on-linux-kernels ps. https://github.com/bytecodealliance/wasm-micro-runtime/actions/runs/8319242277/job/22762363873#step:14:2008 --- .github/workflows/nightly_run.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nightly_run.yml b/.github/workflows/nightly_run.yml index cfc910ea2..b96072a0b 100644 --- a/.github/workflows/nightly_run.yml +++ b/.github/workflows/nightly_run.yml @@ -626,7 +626,9 @@ jobs: run: echo "TEST_ON_X86_32=true" >> $GITHUB_ENV - name: set additional tsan options - run: echo "TSAN_OPTIONS=suppressions=$PWD/tsan_suppressions.txt" >> $GITHUB_ENV + run: | + echo "TSAN_OPTIONS=suppressions=$PWD/tsan_suppressions.txt" >> $GITHUB_ENV + sudo sysctl vm.mmap_rnd_bits=28 working-directory: tests/wamr-test-suites #only download llvm libraries in jit and aot mode From b11a1d157d460719eea70ee6b366623e8b4a2ced Mon Sep 17 00:00:00 2001 From: Liangyu Zhang Date: Mon, 18 Mar 2024 16:26:30 +0800 Subject: [PATCH 4/5] GC: Add wasm_struct_obj_get_field_count API (#3236) --- core/iwasm/common/gc/gc_object.c | 10 ++++++++++ core/iwasm/common/gc/gc_object.h | 10 ++++++++++ core/iwasm/include/gc_export.h | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/core/iwasm/common/gc/gc_object.c b/core/iwasm/common/gc/gc_object.c index 57743a35d..333effcf6 100644 --- a/core/iwasm/common/gc/gc_object.c +++ b/core/iwasm/common/gc/gc_object.c @@ -189,6 +189,16 @@ wasm_struct_obj_get_field(const WASMStructObjectRef struct_obj, } } +uint32 +wasm_struct_obj_get_field_count(const WASMStructObjectRef struct_obj) +{ + WASMRttTypeRef rtt_type = + (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj); + WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type; + + return struct_type->field_count; +} + WASMArrayObjectRef wasm_array_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type, uint32 length, WASMValue *init_value) diff --git a/core/iwasm/common/gc/gc_object.h b/core/iwasm/common/gc/gc_object.h index 4c0cc4538..2d1336881 100644 --- a/core/iwasm/common/gc/gc_object.h +++ b/core/iwasm/common/gc/gc_object.h @@ -157,6 +157,16 @@ void wasm_struct_obj_get_field(const WASMStructObjectRef struct_obj, uint32 field_idx, bool sign_extend, WASMValue *value); +/** + * Return the field count of the WASM struct object. + * + * @param struct_obj the WASM struct object + * + * @return the field count of the WASM struct object + */ +uint32 +wasm_struct_obj_get_field_count(const WASMStructObjectRef struct_obj); + WASMArrayObjectRef wasm_array_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type, uint32 length, WASMValue *init_value); diff --git a/core/iwasm/include/gc_export.h b/core/iwasm/include/gc_export.h index 8a1003194..3eb88dbab 100644 --- a/core/iwasm/include/gc_export.h +++ b/core/iwasm/include/gc_export.h @@ -437,6 +437,16 @@ WASM_RUNTIME_API_EXTERN void wasm_struct_obj_get_field(const wasm_struct_obj_t obj, uint32_t field_idx, bool sign_extend, wasm_value_t *value); +/** + * Get the field count of the a struct object. + * + * @param obj the WASM struct object + * + * @return the field count of the a struct object + */ +WASM_RUNTIME_API_EXTERN uint32_t +wasm_struct_obj_get_field_count(const wasm_struct_obj_t obj); + /** * Create an array object with the index of defined type, the obj's length is * length, init value is init_value From 29d83224a899ba30673898d7afd0949c722468ac Mon Sep 17 00:00:00 2001 From: Tao Xiong <114033626+TAOFOR4@users.noreply.github.com> Date: Tue, 19 Mar 2024 01:15:46 +0100 Subject: [PATCH 5/5] Add esp32c6 support (#3234) This PR adds support for ESP32 C6, which has been mentioned in #3208. --- build-scripts/esp-idf/wamr/CMakeLists.txt | 2 +- product-mini/platforms/esp-idf/build_and_run.sh | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build-scripts/esp-idf/wamr/CMakeLists.txt b/build-scripts/esp-idf/wamr/CMakeLists.txt index 5ac04ddc9..47ccb055f 100644 --- a/build-scripts/esp-idf/wamr/CMakeLists.txt +++ b/build-scripts/esp-idf/wamr/CMakeLists.txt @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # Set WAMR's build options -if("${IDF_TARGET}" STREQUAL "esp32c3") +if("${IDF_TARGET}" STREQUAL "esp32c3" OR "${IDF_TARGET}" STREQUAL "esp32c6") set(WAMR_BUILD_TARGET "RISCV32") else() set(WAMR_BUILD_TARGET "XTENSA") diff --git a/product-mini/platforms/esp-idf/build_and_run.sh b/product-mini/platforms/esp-idf/build_and_run.sh index f764a3013..7ce1b57a5 100755 --- a/product-mini/platforms/esp-idf/build_and_run.sh +++ b/product-mini/platforms/esp-idf/build_and_run.sh @@ -6,6 +6,7 @@ ESP32_TARGET="esp32" ESP32C3_TARGET="esp32c3" ESP32S3_TARGET="esp32s3" +ESP32C6_TARGET="esp32c6" usage () { @@ -15,6 +16,7 @@ usage () echo " $0 $ESP32_TARGET" echo " $0 $ESP32C3_TARGET" echo " $0 $ESP32S3_TARGET" + echo " $0 $ESP32C6_TARGET" exit 1 }