Merge main into dev/socket

This commit is contained in:
Wenyong Huang 2022-09-30 08:32:59 +08:00
commit 301672d8b6
89 changed files with 2877 additions and 423 deletions

View File

@ -9,29 +9,37 @@ FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT}
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asian/Shanghai ENV TZ=Asian/Shanghai
RUN apt update \ # hadolint ignore=DL3008
&& apt install -y apt-transport-https apt-utils build-essential \ RUN apt-get update \
&& apt-get install -y apt-transport-https apt-utils build-essential \
ca-certificates curl g++-multilib git gnupg \ ca-certificates curl g++-multilib git gnupg \
libgcc-9-dev lib32gcc-9-dev lsb-release \ libgcc-9-dev lib32gcc-9-dev lsb-release \
ninja-build ocaml ocamlbuild python2.7 \ ninja-build ocaml ocamlbuild python2.7 \
software-properties-common tree tzdata \ software-properties-common tree tzdata \
unzip valgrind vim wget zip unzip valgrind vim wget zip --no-install-recommends \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
# #
# CMAKE (https://apt.kitware.com/) # CMAKE (https://apt.kitware.com/)
RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null \ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# hadolint ignore=DL3008
RUN wget --progress=dot:giga -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null \
&& echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ bionic main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null \ && echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ bionic main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null \
&& apt update \ && apt-get update \
&& rm /usr/share/keyrings/kitware-archive-keyring.gpg \ && rm /usr/share/keyrings/kitware-archive-keyring.gpg \
&& apt install -y kitware-archive-keyring \ && apt-get install -y kitware-archive-keyring --no-install-recommends \
&& apt install -y cmake && apt-get install -y cmake --no-install-recommends \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
# #
# install emsdk # install emsdk
RUN cd /opt \ WORKDIR /opt
&& git clone https://github.com/emscripten-core/emsdk.git RUN git clone https://github.com/emscripten-core/emsdk.git
RUN cd /opt/emsdk \
&& git pull \ WORKDIR /opt/emsdk
RUN git pull \
&& ./emsdk install 2.0.26 \ && ./emsdk install 2.0.26 \
&& ./emsdk activate 2.0.26 \ && ./emsdk activate 2.0.26 \
&& echo "source /opt/emsdk/emsdk_env.sh" >> /root/.bashrc && echo "source /opt/emsdk/emsdk_env.sh" >> /root/.bashrc
@ -39,60 +47,66 @@ RUN cd /opt/emsdk \
# #
# install wasi-sdk # install wasi-sdk
ARG WASI_SDK_VER=16 ARG WASI_SDK_VER=16
RUN wget -c https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VER}/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -P /opt RUN wget -c --progress=dot:giga https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VER}/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -P /opt \
RUN tar xf /opt/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -C /opt \ && tar xf /opt/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -C /opt \
&& ln -fs /opt/wasi-sdk-${WASI_SDK_VER}.0 /opt/wasi-sdk && ln -fs /opt/wasi-sdk-${WASI_SDK_VER}.0 /opt/wasi-sdk \
RUN rm /opt/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz && rm /opt/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz
# #
#install wabt #install wabt
ARG WABT_VER=1.0.29 ARG WABT_VER=1.0.29
RUN wget -c https://github.com/WebAssembly/wabt/releases/download/${WABT_VER}/wabt-${WABT_VER}-ubuntu.tar.gz -P /opt RUN wget -c --progress=dot:giga https://github.com/WebAssembly/wabt/releases/download/${WABT_VER}/wabt-${WABT_VER}-ubuntu.tar.gz -P /opt \
RUN tar xf /opt/wabt-${WABT_VER}-ubuntu.tar.gz -C /opt \ && tar xf /opt/wabt-${WABT_VER}-ubuntu.tar.gz -C /opt \
&& ln -fs /opt/wabt-${WABT_VER} /opt/wabt && ln -fs /opt/wabt-${WABT_VER} /opt/wabt \
RUN rm /opt/wabt-${WABT_VER}-ubuntu.tar.gz && rm /opt/wabt-${WABT_VER}-ubuntu.tar.gz
# #
# install bazelisk # install bazelisk
ARG BAZELISK_VER=1.12.0 ARG BAZELISK_VER=1.12.0
RUN mkdir /opt/bazelisk RUN mkdir /opt/bazelisk \
RUN wget -c https://github.com/bazelbuild/bazelisk/releases/download/v${BAZELISK_VER}/bazelisk-linux-amd64 -P /opt/bazelisk && wget -c --progress=dot:giga https://github.com/bazelbuild/bazelisk/releases/download/v${BAZELISK_VER}/bazelisk-linux-amd64 -P /opt/bazelisk \
RUN chmod a+x /opt/bazelisk/bazelisk-linux-amd64 \ && chmod a+x /opt/bazelisk/bazelisk-linux-amd64 \
&& ln -fs /opt/bazelisk/bazelisk-linux-amd64 /opt/bazelisk/bazel && ln -fs /opt/bazelisk/bazelisk-linux-amd64 /opt/bazelisk/bazel
# #
# install clang+llvm # install clang+llvm
RUN cd /etc/apt/apt.conf.d \ WORKDIR /etc/apt/apt.conf.d
&& touch 99verfiy-peer.conf \ RUN touch 99verfiy-peer.conf \
&& echo "Acquire { https::Verify-Peer false }" > 99verfiy-peer.conf && echo "Acquire { https::Verify-Peer false }" > 99verfiy-peer.conf
RUN cd /tmp \
&& wget https://apt.llvm.org/llvm.sh \ WORKDIR /tmp
&& chmod a+x ./llvm.sh RUN wget --progress=dot:giga https://apt.llvm.org/llvm.sh \
RUN /tmp/llvm.sh 12 all && chmod a+x ./llvm.sh \
RUN ln -sf /usr/bin/clang-format-12 /usr/bin/clang-format && /tmp/llvm.sh 12 all \
&& ln -sf /usr/bin/clang-format-12 /usr/bin/clang-format \
&& rm -rf /tmp/*
# #
# [Optional] # [Optional]
# #
# Install pip # Install pip
RUN apt update && apt install -y --reinstall python3-venv python3-pip # hadolint ignore=DL3008
RUN python3 -m pip install --upgrade pip RUN apt-get update \
&& apt-get install -y --reinstall python3-venv python3-pip --no-install-recommends \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
# #
# Install required python packages # Install required python packages
RUN pip3 install --user black nose pycparser pylint # hadolint ignore=DL3013
RUN python3 -m pip install --no-cache-dir --upgrade pip \
&& pip3 install --no-cache-dir --user black nose pycparser pylint
# set path # set path, PS and clean up
ENV PATH "/opt/bazelisk:/opt/clang-llvm/bin:${PATH}" ENV PATH "/opt/bazelisk:/opt/clang-llvm/bin:${PATH}"
RUN echo "export PATH=/opt/bazelisk:/opt/clang-llvm/bin:${PATH}" >> /root/.bashrc RUN echo "export PATH=/opt/bazelisk:/opt/clang-llvm/bin:${PATH}" >> /root/.bashrc \
&& printf "%s\n" "PS1='\n[ \u@wamr-dev-docker \W ]\n$ '" >> /root/.bashrc \
# && apt-get autoremove -y \
# PS
RUN echo "PS1='\n[ \u@wamr-dev-docker \W ]\n$ '" >> /root/.bashrc
# Clean up
RUN apt-get autoremove -y \
&& apt-get clean -y \ && apt-get clean -y \
&& rm -rf /var/lib/apt/lists/* \ && rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/* && rm -rf /tmp/*
# set workdir when container run
VOLUME /workspace
WORKDIR /workspace

View File

@ -413,6 +413,15 @@ jobs:
./build.sh ./build.sh
./run.sh ./run.sh
- name: Build Sample [file]
if: ${{ matrix.light == 'green' }}
run: |
cd samples/file
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./src/iwasm -f wasm-app/file.wasm -d .
- name: Build Sample [multi-thread] - name: Build Sample [multi-thread]
if: ${{ matrix.light == 'green' }} if: ${{ matrix.light == 'green' }}
run: | run: |

View File

@ -356,6 +356,15 @@ jobs:
./build.sh ./build.sh
./run.sh ./run.sh
- name: Build Sample [file]
if: ${{ matrix.light == 'green' }}
run: |
cd samples/file
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./src/iwasm -f wasm-app/file.wasm -d .
- name: Build Sample [multi-thread] - name: Build Sample [multi-thread]
if: ${{ matrix.light == 'green' }} if: ${{ matrix.light == 'green' }}
run: | run: |

View File

@ -72,7 +72,10 @@ jobs:
steps: steps:
- name: Install Utilities - name: Install Utilities
run: sudo apt install -y kconfig-frontends-nox genromfs run: |
sudo apt install -y kconfig-frontends-nox genromfs
pip3 install pyelftools
pip3 install cxxfilt
- name: Install ARM Compilers - name: Install ARM Compilers
if: ${{ contains(matrix.nuttx_board_config, 'arm') }} if: ${{ contains(matrix.nuttx_board_config, 'arm') }}

View File

@ -140,6 +140,7 @@ jobs:
# "-DWAMR_BUILD_SIMD=1", # "-DWAMR_BUILD_SIMD=1",
"-DWAMR_BUILD_TAIL_CALL=1", "-DWAMR_BUILD_TAIL_CALL=1",
"-DWAMR_DISABLE_HW_BOUND_CHECK=1", "-DWAMR_DISABLE_HW_BOUND_CHECK=1",
"-DWAMR_BUILD_SGX_IPFS=1",
] ]
os: [ubuntu-20.04] os: [ubuntu-20.04]
platform: [linux-sgx] platform: [linux-sgx]
@ -363,6 +364,15 @@ jobs:
./build.sh ./build.sh
./run.sh ./run.sh
- name: Build Sample [file]
if: ${{ matrix.light == 'green' }}
run: |
cd samples/file
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./src/iwasm -f wasm-app/file.wasm -d .
- name: Build Sample [multi-thread] - name: Build Sample [multi-thread]
if: ${{ matrix.light == 'green' }} if: ${{ matrix.light == 'green' }}
run: | run: |

View File

@ -15,6 +15,7 @@ WAMR project reused some components from other open source project:
- **uvwasi**: for the WASI Libc with uvwasi implementation - **uvwasi**: for the WASI Libc with uvwasi implementation
- **asmjit**: for the Fast JIT x86-64 codegen implementation - **asmjit**: for the Fast JIT x86-64 codegen implementation
- **zydis**: for the Fast JIT x86-64 codegen implementation - **zydis**: for the Fast JIT x86-64 codegen implementation
- **NuttX ELF headers**: used in core/iwasm/aot/debug/elf_parser.c
The WAMR fast interpreter is a clean room development. We would acknowledge the inspirations by [WASM3](https://github.com/wasm3/wasm3) open source project for the approach of pre-calculated oprand stack location. The WAMR fast interpreter is a clean room development. We would acknowledge the inspirations by [WASM3](https://github.com/wasm3/wasm3) open source project for the approach of pre-calculated oprand stack location.
@ -33,6 +34,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
| uvwasi | unspecified | v0.0.12 | https://github.com/nodejs/uvwasi | | | uvwasi | unspecified | v0.0.12 | https://github.com/nodejs/uvwasi | |
| asmjit | unspecified | unspecified | https://github.com/asmjit/asmjit | | | asmjit | unspecified | unspecified | https://github.com/asmjit/asmjit | |
| zydis | unspecified | e14a07895136182a5b53e181eec3b1c6e0b434de | https://github.com/zyantific/zydis | | | zydis | unspecified | e14a07895136182a5b53e181eec3b1c6e0b434de | https://github.com/zyantific/zydis | |
| NuttX ELF headers | 72313301e23f9c2de969fb64b9a0f67bb4c284df | 10.3.0 | https://github.com/apache/incubator-nuttx | |
## Licenses ## Licenses
@ -89,3 +91,9 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
### zydis ### zydis
[LICENSE](./core/iwasm/fast-jit/cg/LICENSE_ZYDIS) [LICENSE](./core/iwasm/fast-jit/cg/LICENSE_ZYDIS)
### NuttX ELF headers
[LICENSE](./core/iwasm/aot/debug/LICENSE_NUTTX)
[NOTICE](./core/iwasm/aot/debug/NOTICE_NUTTX)

View File

@ -25,6 +25,7 @@ Getting started
- [Build WASM applications](./doc/build_wasm_app.md) - [Build WASM applications](./doc/build_wasm_app.md)
- [Port WAMR to a new platform](./doc/port_wamr.md) - [Port WAMR to a new platform](./doc/port_wamr.md)
- [Benchmarks](./tests/benchmarks) and [Samples](./samples) - [Benchmarks](./tests/benchmarks) and [Samples](./samples)
- [VS Code development container](./doc/devcontainer.md)
iwasm VM core iwasm VM core
========================= =========================
@ -150,6 +151,7 @@ The WAMR [samples](./samples) integrate the iwasm VM core, application manager a
- [**basic**](./samples/basic): Demonstrating how to use runtime exposed API's to call WASM functions, how to register native functions and call them, and how to call WASM function from native function. - [**basic**](./samples/basic): Demonstrating how to use runtime exposed API's to call WASM functions, how to register native functions and call them, and how to call WASM function from native function.
- **[simple](./samples/simple/README.md)**: The runtime is integrated with most of the WAMR APP libraries, and a few WASM applications are provided for testing the WAMR APP API set. It uses **built-in libc** and executes apps in **interpreter** mode by default. - **[simple](./samples/simple/README.md)**: The runtime is integrated with most of the WAMR APP libraries, and a few WASM applications are provided for testing the WAMR APP API set. It uses **built-in libc** and executes apps in **interpreter** mode by default.
- **[file](./samples/file/README.md)**: Demonstrating the supported file interaction API of WASI. This sample can also demonstrate the SGX IPFS (Intel Protected File System), enabling an enclave to seal and unseal data at rest.
- **[littlevgl](./samples/littlevgl/README.md)**: Demonstrating the graphic user interface application usage on WAMR. The whole [LVGL](https://github.com/lvgl/lvgl) 2D user graphic library and the UI application are built into WASM application. It uses **WASI libc** and executes apps in **AOT mode** by default. - **[littlevgl](./samples/littlevgl/README.md)**: Demonstrating the graphic user interface application usage on WAMR. The whole [LVGL](https://github.com/lvgl/lvgl) 2D user graphic library and the UI application are built into WASM application. It uses **WASI libc** and executes apps in **AOT mode** by default.
- **[gui](./samples/gui/README.md)**: Move the [LVGL](https://github.com/lvgl/lvgl) library into the runtime and define a WASM application interface by wrapping the littlevgl API. It uses **WASI libc** and executes apps in **interpreter** mode by default. - **[gui](./samples/gui/README.md)**: Move the [LVGL](https://github.com/lvgl/lvgl) library into the runtime and define a WASM application interface by wrapping the littlevgl API. It uses **WASI libc** and executes apps in **interpreter** mode by default.
- **[multi-thread](./samples/multi-thread/)**: Demonstrating how to run wasm application which creates multiple threads to execute wasm functions concurrently, and uses mutex/cond by calling pthread related API's. - **[multi-thread](./samples/multi-thread/)**: Demonstrating how to run wasm application which creates multiple threads to execute wasm functions concurrently, and uses mutex/cond by calling pthread related API's.

View File

@ -287,3 +287,7 @@ if (WAMR_BUILD_STACK_GUARD_SIZE GREATER 0)
add_definitions (-DWASM_STACK_GUARD_SIZE=${WAMR_BUILD_STACK_GUARD_SIZE}) add_definitions (-DWASM_STACK_GUARD_SIZE=${WAMR_BUILD_STACK_GUARD_SIZE})
message (" Custom stack guard size: " ${WAMR_BUILD_STACK_GUARD_SIZE}) message (" Custom stack guard size: " ${WAMR_BUILD_STACK_GUARD_SIZE})
endif () endif ()
if (WAMR_BUILD_SGX_IPFS EQUAL 1)
add_definitions (-DWASM_ENABLE_SGX_IPFS=1)
message (" SGX IPFS enabled")
endif ()

View File

@ -52,7 +52,7 @@ endif ()
################ optional according to settings ################ ################ optional according to settings ################
if (WAMR_BUILD_INTERP EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1 if (WAMR_BUILD_INTERP EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1
OR WAMR_BUILD_FAST_JIT EQUAL 1) OR WAMR_BUILD_FAST_JIT EQUAL 1)
if (WAMR_BUILD_FAST_JIT EQUAL 1) if (WAMR_BUILD_FAST_JIT EQUAL 1 OR WAMR_BUILD_JIT EQUAL 1)
set (WAMR_BUILD_FAST_INTERP 0) set (WAMR_BUILD_FAST_INTERP 0)
endif () endif ()
include (${IWASM_DIR}/interpreter/iwasm_interp.cmake) include (${IWASM_DIR}/interpreter/iwasm_interp.cmake)

View File

@ -1,92 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
# tie the ${VARIANT} and a llvm binary release together
# please find a matched version on https://github.com/llvm/llvm-project/releases
ARG VARIANT=focal
FROM ubuntu:${VARIANT}
ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Asian/Shanghai
RUN apt update \
&& apt install -y apt-transport-https apt-utils build-essential \
ca-certificates curl g++-multilib git gnupg \
libgcc-9-dev lib32gcc-9-dev lsb-release \
ninja-build ocaml ocamlbuild python2.7 \
software-properties-common tree tzdata \
unzip valgrind vim wget zip
#
# CMAKE (https://apt.kitware.com/)
RUN wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /usr/share/keyrings/kitware-archive-keyring.gpg > /dev/null \
&& echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ bionic main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null \
&& apt update \
&& rm /usr/share/keyrings/kitware-archive-keyring.gpg \
&& apt install -y kitware-archive-keyring \
&& apt install -y cmake
#
# install emsdk (may not necessary ?)
RUN cd /opt \
&& git clone https://github.com/emscripten-core/emsdk.git
RUN cd /opt/emsdk \
&& git pull \
&& ./emsdk install 2.0.26 \
&& ./emsdk activate 2.0.26 \
&& echo "source /opt/emsdk/emsdk_env.sh" >> /root/.bashrc
#
# install clang and llvm release
ARG CLANG_VER=13.0.0
RUN wget https://github.com/llvm/llvm-project/releases/download/llvmorg-${CLANG_VER}/clang+llvm-${CLANG_VER}-x86_64-linux-gnu-ubuntu-20.04.tar.xz -P /opt
RUN cd /opt \
&& tar xf clang+llvm-${CLANG_VER}-x86_64-linux-gnu-ubuntu-20.04.tar.xz \
&& ln -sf clang+llvm-${CLANG_VER}-x86_64-linux-gnu-ubuntu-20.04 clang-llvm
RUN rm /opt/clang+llvm-${CLANG_VER}-x86_64-linux-gnu-ubuntu-20.04.tar.xz
#
# install wasi-sdk
ARG WASI_SDK_VER=14
RUN wget -c https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VER}/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -P /opt
RUN tar xf /opt/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz -C /opt \
&& ln -fs /opt/wasi-sdk-${WASI_SDK_VER}.0 /opt/wasi-sdk
RUN rm /opt/wasi-sdk-${WASI_SDK_VER}.0-linux.tar.gz
#
#install wabt
ARG WABT_VER=1.0.24
RUN wget -c https://github.com/WebAssembly/wabt/releases/download/${WABT_VER}/wabt-${WABT_VER}-ubuntu.tar.gz -P /opt
RUN tar xf /opt/wabt-${WABT_VER}-ubuntu.tar.gz -C /opt \
&& ln -fs /opt/wabt-${WABT_VER} /opt/wabt
RUN rm /opt/wabt-${WABT_VER}-ubuntu.tar.gz
#
# install bazelisk
ARG BAZELISK_VER=1.10.1
RUN mkdir /opt/bazelisk
RUN wget -c https://github.com/bazelbuild/bazelisk/releases/download/v${BAZELISK_VER}/bazelisk-linux-amd64 -P /opt/bazelisk
RUN chmod a+x /opt/bazelisk/bazelisk-linux-amd64 \
&& ln -fs /opt/bazelisk/bazelisk-linux-amd64 /opt/bazelisk/bazel
#
# install
RUN apt update && apt install -y clang-format
# set path
ENV PATH "$PATH:/opt/wasi-sdk/bin:/opt/wabt/bin:/opt/binaryen/bin:/opt/bazelisk:/opt/clang-llvm/bin"
RUN echo "export PATH=/opt/wasi-sdk/bin:/opt/wabt/bin:/opt/binaryen/bin:/opt/bazelisk:/opt/clang-llvm/bin:${PATH}" >> /root/.bashrc
#
# PS
RUN echo "PS1='\n[ \u@wamr-dev-docker \W ]\n$ '" >> /root/.bashrc
# Clean up
RUN apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/*
VOLUME /workspace
WORKDIR /workspace

View File

@ -9,7 +9,7 @@ readonly VARIANT=$(lsb_release -c | awk '{print $2}')
docker build \ docker build \
--memory=4G --cpu-quota=50000 \ --memory=4G --cpu-quota=50000 \
-t wamr_dev_${VARIANT}:0.1 -f "${CURRENT_PATH}"/Dockerfile "${CURRENT_PATH}" \ -t wamr_dev_${VARIANT}:0.1 -f "${ROOT}"/.devcontainer/Dockerfile "${ROOT}"/.devcontainer \
&& docker run --rm -it \ && docker run --rm -it \
--cap-add=SYS_PTRACE \ --cap-add=SYS_PTRACE \
--cpus=".5" \ --cpus=".5" \

View File

@ -407,4 +407,8 @@
#define WASM_ENABLE_REF_TYPES 0 #define WASM_ENABLE_REF_TYPES 0
#endif #endif
#ifndef WASM_ENABLE_SGX_IPFS
#define WASM_ENABLE_SGX_IPFS 0
#endif
#endif /* end of _CONFIG_H_ */ #endif /* end of _CONFIG_H_ */

View File

@ -696,9 +696,9 @@ load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
} }
section->name_addr = (char *)section_name; section->name_addr = (char *)section_name;
section->name_len = strlen(section_name); section->name_len = (uint32)strlen(section_name);
section->content_addr = (uint8 *)p; section->content_addr = (uint8 *)p;
section->content_len = p_end - p; section->content_len = (uint32)(p_end - p);
section->next = module->custom_section_list; section->next = module->custom_section_list;
module->custom_section_list = section; module->custom_section_list = section;

View File

@ -244,14 +244,18 @@ table_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
tbl_inst = aot_get_table_inst(module_inst, table_seg->table_index); tbl_inst = aot_get_table_inst(module_inst, table_seg->table_index);
bh_assert(tbl_inst); bh_assert(tbl_inst);
#if WASM_ENABLE_REF_TYPES != 0
bh_assert( bh_assert(
table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
|| table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
#if WASM_ENABLE_REF_TYPES != 0
|| table_seg->offset.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST
|| table_seg->offset.init_expr_type == INIT_EXPR_TYPE_REFNULL_CONST || table_seg->offset.init_expr_type
== INIT_EXPR_TYPE_REFNULL_CONST);
#else
bh_assert(table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
|| table_seg->offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL);
#endif #endif
);
/* Resolve table data base offset */ /* Resolve table data base offset */
if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) { if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
@ -2093,10 +2097,12 @@ aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
if (memory->is_shared) { if (memory->is_shared) {
memory->num_bytes_per_page = UINT32_MAX; memory->num_bytes_per_page = num_bytes_per_page;
memory->cur_page_count = total_page_count; memory->cur_page_count = total_page_count;
memory->max_page_count = max_page_count; memory->max_page_count = max_page_count;
memory->memory_data_size = (uint32)total_size_new; /* No need to update memory->memory_data_size as it is
initialized with the maximum memory data size for
shared memory */
return true; return true;
} }
#endif #endif
@ -2918,6 +2924,9 @@ lookup_func_name(const char **func_names, uint32 *func_indexes,
int64 low = 0, mid; int64 low = 0, mid;
int64 high = func_index_count - 1; int64 high = func_index_count - 1;
if (!func_names || !func_indexes || func_index_count == 0)
return NULL;
while (low <= high) { while (low <= high) {
mid = (low + high) / 2; mid = (low + high) / 2;
if (func_index == func_indexes[mid]) { if (func_index == func_indexes[mid]) {
@ -3078,7 +3087,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
return 0; return 0;
} }
total_frames = bh_vector_size(module_inst->frames.ptr); total_frames = (uint32)bh_vector_size(module_inst->frames.ptr);
if (total_frames == 0) { if (total_frames == 0) {
return 0; return 0;
} }

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,5 @@
Apache NuttX
Copyright 2020 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

368
core/iwasm/aot/debug/elf.h Normal file
View File

@ -0,0 +1,368 @@
/****************************************************************************
* include/elf.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __INCLUDE_ELF_H
#define __INCLUDE_ELF_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
#define EI_NIDENT 16 /* Size of e_ident[] */
/* NOTE: elf64.h and elf32.h refer EI_NIDENT defined above */
#include "elf64.h"
#include "elf32.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Values for Elf_Ehdr::e_type */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* Relocatable file */
#define ET_EXEC 2 /* Executable file */
#define ET_DYN 3 /* Shared object file */
#define ET_CORE 4 /* Core file */
#define ET_LOPROC 0xff00 /* Processor-specific */
#define ET_HIPROC 0xffff /* Processor-specific */
/* Values for Elf_Ehdr::e_machine (most of this were not included in the
* original SCO document but have been gleaned from elsewhere).
*/
#define EM_NONE 0 /* No machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola 68000 */
#define EM_88K 5 /* Motorola 88000 */
#define EM_486 6 /* Intel 486+ */
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#define EM_PARISC 15 /* HPPA */
#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* PowerPC64 */
#define EM_ARM 40 /* ARM */
#define EM_SH 42 /* SuperH */
#define EM_SPARCV9 43 /* SPARC v9 64-bit */
#define EM_H8_300 46
#define EM_IA_64 50 /* HP/Intel IA-64 */
#define EM_X86_64 62 /* AMD x86-64 */
#define EM_S390 22 /* IBM S/390 */
#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Renesas M32R */
#define EM_XTENSA 94 /* Tensilica Xtensa */
#define EM_RISCV 243 /* RISC-V */
#define EM_ALPHA 0x9026
#define EM_CYGNUS_V850 0x9080
#define EM_CYGNUS_M32R 0x9041
#define EM_S390_OLD 0xa390
#define EM_FRV 0x5441
/* Values for Elf_Ehdr::e_version */
#define EV_NONE 0 /* Invalid version */
#define EV_CURRENT 1 /* The current version */
/* Table 2. Ehe ELF identifier */
#define EI_MAG0 0 /* File identification */
#define EI_MAG1 1
#define EI_MAG2 2
#define EI_MAG3 3
#define EI_CLASS 4 /* File class */
#define EI_DATA 5 /* Data encoding */
#define EI_VERSION 6 /* File version */
#define EI_OSABI 7 /* OS ABI */
#define EI_PAD 8 /* Start of padding bytes */
/* EI_NIDENT is defined in "Included Files" section */
#define EI_MAGIC_SIZE 4
#define EI_MAGIC \
{ \
0x7f, 'E', 'L', 'F' \
}
#define ELFMAG0 0x7f /* EI_MAG */
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF"
/* Table 3. Values for EI_CLASS */
#define ELFCLASSNONE 0 /* Invalid class */
#define ELFCLASS32 1 /* 32-bit objects */
#define ELFCLASS64 2 /* 64-bit objects */
/* Table 4. Values for EI_DATA */
#define ELFDATANONE 0 /* Invalid data encoding */
#define ELFDATA2LSB \
1 /* Least significant byte occupying the lowest address \
*/
#define ELFDATA2MSB 2 /* Most significant byte occupying the lowest address */
/* Table 6. Values for EI_OSABI */
#define ELFOSABI_NONE 0 /* UNIX System V ABI */
#define ELFOSABI_SYSV 0 /* Alias. */
#define ELFOSABI_HPUX 1 /* HP-UX */
#define ELFOSABI_NETBSD 2 /* NetBSD. */
#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
#define ELFOSABI_LINUX ELFOSABI_GNU
/* Compatibility alias. */
#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
#define ELFOSABI_AIX 7 /* IBM AIX. */
#define ELFOSABI_IRIX 8 /* SGI Irix. */
#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
#define ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
#ifndef ELF_OSABI
#define ELF_OSABI ELFOSABI_NONE
#endif
/* Table 7: Special Section Indexes */
#define SHN_UNDEF 0
#define SHN_LOPROC 0xff00
#define SHN_HIPROC 0xff1f
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
/* Figure 4-9: Section Types, sh_type */
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
/* Figure 4-11: Section Attribute Flags, sh_flags */
#define SHF_WRITE 1
#define SHF_ALLOC 2
#define SHF_EXECINSTR 4
#define SHF_MASKPROC 0xf0000000
/* Figure 4-16: Symbol Binding, ELF_ST_BIND */
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
#define STB_LOPROC 13
#define STB_HIPROC 15
/* Figure 4-17: Symbol Types, ELF_ST_TYPE */
#define STT_NOTYPE 0
#define STT_OBJECT 1
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_LOPROC 13
#define STT_HIPROC 15
/* Figure 5-2: Segment Types, p_type */
#define PT_NULL 0
#define PT_LOAD 1
#define PT_DYNAMIC 2
#define PT_INTERP 3
#define PT_NOTE 4
#define PT_SHLIB 5
#define PT_PHDR 6
#define PT_LOPROC 0x70000000
#define PT_HIPROC 0x7fffffff
/* Figure 5-3: Segment Flag Bits, p_flags */
#define PF_X 1 /* Execute */
#define PF_W 2 /* Write */
#define PF_R 4 /* Read */
#define PF_MASKPROC 0xf0000000 /* Unspecified */
/* Figure 5-10: Dynamic Array Tags, d_tag */
#define DT_NULL 0 /* d_un=ignored */
#define DT_NEEDED 1 /* d_un=d_val */
#define DT_PLTRELSZ 2 /* d_un=d_val */
#define DT_PLTGOT 3 /* d_un=d_ptr */
#define DT_HASH 4 /* d_un=d_ptr */
#define DT_STRTAB 5 /* d_un=d_ptr */
#define DT_SYMTAB 6 /* d_un=d_ptr */
#define DT_RELA 7 /* d_un=d_ptr */
#define DT_RELASZ 8 /* d_un=d_val */
#define DT_RELAENT 9 /* d_un=d_val */
#define DT_STRSZ 10 /* d_un=d_val */
#define DT_SYMENT 11 /* d_un=d_val */
#define DT_INIT 12 /* d_un=d_ptr */
#define DT_FINI 13 /* d_un=d_ptr */
#define DT_SONAME 14 /* d_un=d_val */
#define DT_RPATH 15 /* d_un=d_val */
#define DT_SYMBOLIC 16 /* d_un=ignored */
#define DT_REL 17 /* d_un=d_ptr */
#define DT_RELSZ 18 /* d_un=d_val */
#define DT_RELENT 19 /* d_un=d_val */
#define DT_PLTREL 20 /* d_un=d_val */
#define DT_DEBUG 21 /* d_un=d_ptr */
#define DT_TEXTREL 22 /* d_un=ignored */
#define DT_JMPREL 23 /* d_un=d_ptr */
#define DT_BINDNOW 24 /* d_un=ignored */
#define DT_LOPROC 0x70000000 /* d_un=unspecified */
#define DT_HIPROC 0x7fffffff /* d_un= unspecified */
/* Legal values for note segment descriptor types for core files. */
#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
#define NT_PRFPREG 2 /* Contains copy of fpregset struct. */
#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
#define NT_PRXREG 4 /* Contains copy of prxregset struct */
#define NT_TASKSTRUCT 4 /* Contains copy of task structure */
#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */
#define NT_AUXV 6 /* Contains copy of auxv array */
#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */
#define NT_ASRS 8 /* Contains copy of asrset struct */
#define NT_PSTATUS 10 /* Contains copy of pstatus struct */
#define NT_PSINFO 13 /* Contains copy of psinfo struct */
#define NT_PRCRED 14 /* Contains copy of prcred struct */
#define NT_UTSNAME 15 /* Contains copy of utsname struct */
#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */
#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */
#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
#define NT_SIGINFO 0x53494749
/* Contains copy of siginfo_t,
* size might increase
*/
#define NT_FILE 0x46494c45
/* Contains information about mapped
* files
*/
#define NT_PRXFPREG 0x46e62b7f
/* Contains copy of user_fxsr_struct */
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
#define NT_PPC_TAR 0x103 /* Target Address Register */
#define NT_PPC_PPR 0x104 /* Program Priority Register */
#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */
#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */
#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */
#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */
#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */
#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */
#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */
#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */
#define NT_PPC_TM_CTAR \
0x10d /* TM checkpointed Target Address \
* Register \
*/
#define NT_PPC_TM_CPPR \
0x10e /* TM checkpointed Program Priority \
* Register \
*/
#define NT_PPC_TM_CDSCR \
0x10f /* TM checkpointed Data Stream Control \
* Register \
*/
#define NT_PPC_PKEY \
0x110 /* Memory Protection Keys \
* registers. \
*/
#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
#define NT_S390_TIMER 0x301 /* s390 timer register */
#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */
#define NT_S390_CTRS 0x304 /* s390 control registers */
#define NT_S390_PREFIX 0x305 /* s390 prefix register */
#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */
#define NT_S390_VXRS_LOW \
0x309 /* s390 vector registers 0-15 \
* upper half. \
*/
#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31. */
#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers. */
#define NT_S390_GS_BC \
0x30c /* s390 guarded storage \
* broadcast control block. \
*/
#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation. */
#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
#define NT_ARM_TLS 0x401 /* ARM TLS register */
#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */
#define NT_ARM_SVE \
0x405 /* ARM Scalable Vector Extension \
* registers \
*/
#define NT_ARM_PAC_MASK \
0x406 /* ARM pointer authentication \
* code masks. \
*/
#define NT_ARM_PACA_KEYS \
0x407 /* ARM pointer authentication \
* address keys. \
*/
#define NT_ARM_PACG_KEYS \
0x408 /* ARM pointer authentication \
* generic key. \
*/
#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note. */
#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers. */
#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode. */
#define NT_MIPS_MSA 0x802 /* MIPS SIMD registers. */
/* Legal values for the note segment descriptor types for object files. */
#define NT_VERSION 1 /* Contains a version string. */
#endif /* __INCLUDE_ELF_H */

View File

@ -0,0 +1,161 @@
/****************************************************************************
* include/elf32.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __INCLUDE_ELF32_H
#define __INCLUDE_ELF32_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define ELF32_ST_BIND(i) ((i) >> 4)
#define ELF32_ST_TYPE(i) ((i)&0xf)
#define ELF32_ST_INFO(b, t) (((b) << 4) | ((t)&0xf))
/* Definitions for Elf32_Rel*::r_info */
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((i)&0xff)
#define ELF32_R_INFO(s, t) (((s) << 8) | ((t)&0xff))
#if 0
#define ELF_R_SYM(i) ELF32_R_SYM(i)
#endif
/****************************************************************************
* Public Type Definitions
****************************************************************************/
/* Figure 4.2: 32-Bit Data Types */
typedef uint32_t Elf32_Addr; /* Unsigned program address */
typedef uint16_t Elf32_Half; /* Unsigned medium integer */
typedef uint32_t Elf32_Off; /* Unsigned file offset */
typedef int32_t Elf32_Sword; /* Signed large integer */
typedef uint32_t Elf32_Word; /* Unsigned large integer */
/* Figure 4-3: ELF Header */
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shstrndx;
} Elf32_Ehdr;
/* Figure 4-8: Section Header */
typedef struct {
Elf32_Word sh_name;
Elf32_Word sh_type;
Elf32_Word sh_flags;
Elf32_Addr sh_addr;
Elf32_Off sh_offset;
Elf32_Word sh_size;
Elf32_Word sh_link;
Elf32_Word sh_info;
Elf32_Word sh_addralign;
Elf32_Word sh_entsize;
} Elf32_Shdr;
/* Figure 4-15: Symbol Table Entry */
typedef struct {
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf32_Half st_shndx;
} Elf32_Sym;
/* Figure 4-19: Relocation Entries */
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
} Elf32_Rel;
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Sword r_addend;
} Elf32_Rela;
/* Figure 5-1: Program Header */
typedef struct {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
/* Figure 5-7: Note Information */
typedef struct {
Elf32_Word n_namesz; /* Length of the note's name. */
Elf32_Word n_descsz; /* Length of the note's descriptor. */
Elf32_Word n_type; /* Type of the note. */
} Elf32_Nhdr;
/* Figure 5-9: Dynamic Structure */
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
#if 0
typedef Elf32_Addr Elf_Addr;
typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Rel Elf_Rel;
typedef Elf32_Rela Elf_Rela;
typedef Elf32_Nhdr Elf_Nhdr;
typedef Elf32_Phdr Elf_Phdr;
typedef Elf32_Sym Elf_Sym;
typedef Elf32_Shdr Elf_Shdr;
typedef Elf32_Word Elf_Word;
#endif
#endif /* __INCLUDE_ELF32_H */

View File

@ -0,0 +1,161 @@
/****************************************************************************
* include/elf64.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __INCLUDE_ELF64_H
#define __INCLUDE_ELF64_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* See ELF-64 Object File Format: Version 1.5 Draft 2 */
/* Definitions for Elf64_Rel*::r_info */
#define ELF64_R_SYM(i) ((i) >> 32)
#define ELF64_R_TYPE(i) ((i)&0xffffffffL)
#define ELF64_R_INFO(s, t) (((s) << 32) + ((t)&0xffffffffL))
#if 0
#define ELF_R_SYM(i) ELF64_R_SYM(i)
#endif
/****************************************************************************
* Public Type Definitions
****************************************************************************/
/* Table 1: ELF-64 Data Types */
typedef uint64_t Elf64_Addr; /* Unsigned program address */
typedef uint64_t Elf64_Off; /* Unsigned file offset */
typedef uint16_t Elf64_Half; /* Unsigned medium integer */
typedef uint32_t Elf64_Word; /* Unsigned long integer */
typedef int32_t Elf64_Sword; /* Signed integer */
typedef uint64_t Elf64_Xword; /* Unsigned long integer */
typedef int64_t Elf64_Sxword; /* Signed large integer */
/* Figure 2: ELF-64 Header */
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* ELF identification */
Elf64_Half e_type; /* Object file type */
Elf64_Half e_machine; /* Machine type */
Elf64_Word e_version; /* Object file version */
Elf64_Addr e_entry; /* Entry point address */
Elf64_Off e_phoff; /* Program header offset */
Elf64_Off e_shoff; /* Section header offset */
Elf64_Word e_flags; /* Processor-specific flags */
Elf64_Half e_ehsize; /* ELF header size */
Elf64_Half e_phentsize; /* Size of program header entry */
Elf64_Half e_phnum; /* Number of program header entry */
Elf64_Half e_shentsize; /* Size of section header entry */
Elf64_Half e_shnum; /* Number of section header entries */
Elf64_Half e_shstrndx; /* Section name string table index */
} Elf64_Ehdr;
/* Figure 3: ELF-64 Section Header */
typedef struct {
Elf64_Word sh_name; /* Section name */
Elf64_Word sh_type; /* Section type */
Elf64_Xword sh_flags; /* Section attributes */
Elf64_Addr sh_addr; /* Virtual address in memory */
Elf64_Off sh_offset; /* Offset in file */
Elf64_Xword sh_size; /* Size of section */
Elf64_Word sh_link; /* Link to other section */
Elf64_Word sh_info; /* Miscellaneous information */
Elf64_Xword sh_addralign; /* Address alignment boundary */
Elf64_Xword sh_entsize; /* Size of entries, if section has table */
} Elf64_Shdr;
/* Figure 4: ELF-64 Symbol Table Entry */
typedef struct {
Elf64_Word st_name; /* Symbol name */
unsigned char st_info; /* Type and Binding attributes */
unsigned char st_other; /* Reserved */
Elf64_Half st_shndx; /* Section table index */
Elf64_Addr st_value; /* Symbol value */
Elf64_Xword st_size; /* Size of object (e.g., common) */
} Elf64_Sym;
/* Figure 5: ELF-64 Relocation Entries */
typedef struct {
Elf64_Addr r_offset; /* Address of reference */
Elf64_Xword r_info; /* Symbol index and type of relocation */
} Elf64_Rel;
typedef struct {
Elf64_Addr r_offset; /* Address of reference */
Elf64_Xword r_info; /* Symbol index and type of relocation */
Elf64_Sxword r_addend; /* Constant part of expression */
} Elf64_Rela;
/* Figure 6: ELF-64 Program Header Table Entry */
typedef struct {
Elf64_Word p_type; /* Type of segment */
Elf64_Word p_flags; /* Segment attributes */
Elf64_Off p_offset; /* Offset in file */
Elf64_Addr p_vaddr; /* Virtual address in memory */
Elf64_Addr p_paddr; /* Reserved */
Elf64_Word p_filesz; /* Size of segment in file */
Elf64_Word p_memsz; /* Size of segment in memory */
Elf64_Word p_align; /* Alignment of segment */
} Elf64_Phdr;
/* Figure 7. Format of a Note Section */
typedef struct {
Elf64_Word n_namesz; /* Length of the note's name. */
Elf64_Word n_descsz; /* Length of the note's descriptor. */
Elf64_Word n_type; /* Type of the note. */
} Elf64_Nhdr;
/* Figure 8: Dynamic Table Structure */
typedef struct {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
#if 0
typedef Elf64_Addr Elf_Addr;
typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Rel Elf_Rel;
typedef Elf64_Rela Elf_Rela;
typedef Elf64_Nhdr Elf_Nhdr;
typedef Elf64_Phdr Elf_Phdr;
typedef Elf64_Sym Elf_Sym;
typedef Elf64_Shdr Elf_Shdr;
typedef Elf64_Word Elf_Word;
#endif
#endif /* __INCLUDE_ELF64_H */

View File

@ -12,7 +12,7 @@
#include <errno.h> #include <errno.h>
#include <stdbool.h> #include <stdbool.h>
#include <elf.h> #include "elf.h"
#include "aot_runtime.h" #include "aot_runtime.h"
#include "bh_log.h" #include "bh_log.h"

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/ */
#ifndef _ELF_PARSERE_H_ #ifndef _ELF_PARSER_H_
#define _ELF_PARSER_H_ #define _ELF_PARSER_H_
#include <stdbool.h> #include <stdbool.h>

View File

@ -4650,7 +4650,7 @@ wasm_runtime_dump_line_buf_impl(const char *line_buf, bool dump_or_print,
return dump_len; return dump_len;
} }
else { else {
return strlen(line_buf); return (uint32)strlen(line_buf);
} }
} }

View File

@ -214,19 +214,6 @@ dwarf_gen_comp_unit_info(AOTCompContext *comp_ctx)
return comp_unit; return comp_unit;
} }
bool
dwarf_get_func_info(dwar_extractor_handle_t handle, uint64_t offset)
{
dwar_extractor *extractor = TO_EXTACTOR(handle);
auto sbaddr = extractor->target.ResolveFileAddress(offset);
SBSymbolContext sc(sbaddr.GetSymbolContext(eSymbolContextFunction));
if (sc.IsValid()) {
SBFunction function(sc.GetFunction());
if (function.IsValid()) {
}
}
}
static LLVMDWARFTypeEncoding static LLVMDWARFTypeEncoding
lldb_get_basic_type_encoding(BasicType basic_type) lldb_get_basic_type_encoding(BasicType basic_type)
{ {

View File

@ -262,6 +262,9 @@ pack_argv(JitCompContext *cc)
stack_base = cc->total_frame_size + offsetof(WASMInterpFrame, lp); stack_base = cc->total_frame_size + offsetof(WASMInterpFrame, lp);
argv = jit_cc_new_reg_ptr(cc); argv = jit_cc_new_reg_ptr(cc);
GEN_INSN(ADD, argv, cc->fp_reg, NEW_CONST(PTR, stack_base)); GEN_INSN(ADD, argv, cc->fp_reg, NEW_CONST(PTR, stack_base));
if (jit_get_last_error(cc)) {
return (JitReg)0;
}
return argv; return argv;
} }
@ -341,7 +344,9 @@ jit_compile_op_call_indirect(JitCompContext *cc, uint32 type_idx,
} }
argv = pack_argv(cc); argv = pack_argv(cc);
if (!argv) {
goto fail;
}
native_ret = jit_cc_new_reg_I32(cc); native_ret = jit_cc_new_reg_I32(cc);
arg_regs[0] = cc->exec_env_reg; arg_regs[0] = cc->exec_env_reg;
arg_regs[1] = NEW_CONST(I32, tbl_idx); arg_regs[1] = NEW_CONST(I32, tbl_idx);

View File

@ -380,9 +380,19 @@ jit_cc_init(JitCompContext *cc, unsigned htab_size)
/* Create entry and exit blocks. They must be the first two /* Create entry and exit blocks. They must be the first two
blocks respectively. */ blocks respectively. */
if (!(entry_block = jit_cc_new_basic_block(cc, 0)) if (!(entry_block = jit_cc_new_basic_block(cc, 0)))
|| !(exit_block = jit_cc_new_basic_block(cc, 0)))
goto fail; goto fail;
if (!(exit_block = jit_cc_new_basic_block(cc, 0))) {
jit_basic_block_delete(entry_block);
goto fail;
}
/* Record the entry and exit labels, whose indexes must be 0 and 1
respectively. */
cc->entry_label = jit_basic_block_label(entry_block);
cc->exit_label = jit_basic_block_label(exit_block);
bh_assert(jit_reg_no(cc->entry_label) == 0
&& jit_reg_no(cc->exit_label) == 1);
if (!(cc->exce_basic_blocks = if (!(cc->exce_basic_blocks =
jit_calloc(sizeof(JitBasicBlock *) * JIT_EXCE_NUM))) jit_calloc(sizeof(JitBasicBlock *) * JIT_EXCE_NUM)))
@ -392,13 +402,6 @@ jit_cc_init(JitCompContext *cc, unsigned htab_size)
jit_calloc(sizeof(JitIncomingInsnList) * JIT_EXCE_NUM))) jit_calloc(sizeof(JitIncomingInsnList) * JIT_EXCE_NUM)))
goto fail; goto fail;
/* Record the entry and exit labels, whose indexes must be 0 and 1
respectively. */
cc->entry_label = jit_basic_block_label(entry_block);
cc->exit_label = jit_basic_block_label(exit_block);
bh_assert(jit_reg_no(cc->entry_label) == 0
&& jit_reg_no(cc->exit_label) == 1);
cc->hreg_info = jit_codegen_get_hreg_info(); cc->hreg_info = jit_codegen_get_hreg_info();
bh_assert(cc->hreg_info->info[JIT_REG_KIND_I32].num > 3); bh_assert(cc->hreg_info->info[JIT_REG_KIND_I32].num > 3);

View File

@ -198,6 +198,30 @@ popcount64(uint64 u)
return ret; return ret;
} }
static float
local_copysignf(float x, float y)
{
union {
float f;
uint32_t i;
} ux = { x }, uy = { y };
ux.i &= 0x7fffffff;
ux.i |= uy.i & 0x80000000;
return ux.f;
}
static double
local_copysign(double x, double y)
{
union {
double f;
uint64_t i;
} ux = { x }, uy = { y };
ux.i &= -1ULL / 2;
ux.i |= uy.i & 1ULL << 63;
return ux.f;
}
static uint64 static uint64
read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign) read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
{ {
@ -2580,7 +2604,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
/* numberic instructions of f32 */ /* numberic instructions of f32 */
HANDLE_OP(WASM_OP_F32_ABS) HANDLE_OP(WASM_OP_F32_ABS)
{ {
DEF_OP_MATH(float32, F32, fabs); DEF_OP_MATH(float32, F32, fabsf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -2597,31 +2621,31 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_F32_CEIL) HANDLE_OP(WASM_OP_F32_CEIL)
{ {
DEF_OP_MATH(float32, F32, ceil); DEF_OP_MATH(float32, F32, ceilf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
HANDLE_OP(WASM_OP_F32_FLOOR) HANDLE_OP(WASM_OP_F32_FLOOR)
{ {
DEF_OP_MATH(float32, F32, floor); DEF_OP_MATH(float32, F32, floorf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
HANDLE_OP(WASM_OP_F32_TRUNC) HANDLE_OP(WASM_OP_F32_TRUNC)
{ {
DEF_OP_MATH(float32, F32, trunc); DEF_OP_MATH(float32, F32, truncf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
HANDLE_OP(WASM_OP_F32_NEAREST) HANDLE_OP(WASM_OP_F32_NEAREST)
{ {
DEF_OP_MATH(float32, F32, rint); DEF_OP_MATH(float32, F32, rintf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
HANDLE_OP(WASM_OP_F32_SQRT) HANDLE_OP(WASM_OP_F32_SQRT)
{ {
DEF_OP_MATH(float32, F32, sqrt); DEF_OP_MATH(float32, F32, sqrtf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -2687,7 +2711,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
b = POP_F32(); b = POP_F32();
a = POP_F32(); a = POP_F32();
PUSH_F32(signbit(b) ? -fabs(a) : fabs(a)); PUSH_F32(local_copysignf(a, b));
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -2801,7 +2825,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
b = POP_F64(); b = POP_F64();
a = POP_F64(); a = POP_F64();
PUSH_F64(signbit(b) ? -fabs(a) : fabs(a)); PUSH_F64(local_copysign(a, b));
HANDLE_OP_END(); HANDLE_OP_END();
} }

View File

@ -189,6 +189,30 @@ popcount64(uint64 u)
return ret; return ret;
} }
static float
local_copysignf(float x, float y)
{
union {
float f;
uint32_t i;
} ux = { x }, uy = { y };
ux.i &= 0x7fffffff;
ux.i |= uy.i & 0x80000000;
return ux.f;
}
static double
local_copysign(double x, double y)
{
union {
double f;
uint64_t i;
} ux = { x }, uy = { y };
ux.i &= -1ULL / 2;
ux.i |= uy.i & 1ULL << 63;
return ux.f;
}
#if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS != 0
#define LOAD_U32_WITH_2U16S(addr) (*(uint32 *)(addr)) #define LOAD_U32_WITH_2U16S(addr) (*(uint32 *)(addr))
#define LOAD_PTR(addr) (*(void **)(addr)) #define LOAD_PTR(addr) (*(void **)(addr))
@ -2415,7 +2439,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
/* numberic instructions of f32 */ /* numberic instructions of f32 */
HANDLE_OP(WASM_OP_F32_ABS) HANDLE_OP(WASM_OP_F32_ABS)
{ {
DEF_OP_MATH(float32, F32, fabs); DEF_OP_MATH(float32, F32, fabsf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -2433,31 +2457,31 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
HANDLE_OP(WASM_OP_F32_CEIL) HANDLE_OP(WASM_OP_F32_CEIL)
{ {
DEF_OP_MATH(float32, F32, ceil); DEF_OP_MATH(float32, F32, ceilf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
HANDLE_OP(WASM_OP_F32_FLOOR) HANDLE_OP(WASM_OP_F32_FLOOR)
{ {
DEF_OP_MATH(float32, F32, floor); DEF_OP_MATH(float32, F32, floorf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
HANDLE_OP(WASM_OP_F32_TRUNC) HANDLE_OP(WASM_OP_F32_TRUNC)
{ {
DEF_OP_MATH(float32, F32, trunc); DEF_OP_MATH(float32, F32, truncf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
HANDLE_OP(WASM_OP_F32_NEAREST) HANDLE_OP(WASM_OP_F32_NEAREST)
{ {
DEF_OP_MATH(float32, F32, rint); DEF_OP_MATH(float32, F32, rintf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
HANDLE_OP(WASM_OP_F32_SQRT) HANDLE_OP(WASM_OP_F32_SQRT)
{ {
DEF_OP_MATH(float32, F32, sqrt); DEF_OP_MATH(float32, F32, sqrtf);
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -2525,8 +2549,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
b = *(float32 *)(frame_lp + GET_OFFSET()); b = *(float32 *)(frame_lp + GET_OFFSET());
a = *(float32 *)(frame_lp + GET_OFFSET()); a = *(float32 *)(frame_lp + GET_OFFSET());
*(float32 *)(frame_lp + GET_OFFSET()) = *(float32 *)(frame_lp + GET_OFFSET()) = local_copysignf(a, b);
(float32)(signbit(b) ? -fabs(a) : fabs(a));
HANDLE_OP_END(); HANDLE_OP_END();
} }
@ -2642,7 +2665,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
b = POP_F64(); b = POP_F64();
a = POP_F64(); a = POP_F64();
PUSH_F64(signbit(b) ? -fabs(a) : fabs(a)); PUSH_F64(local_copysign(a, b));
HANDLE_OP_END(); HANDLE_OP_END();
} }

View File

@ -1950,8 +1950,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
local_type_index = 0; local_type_index = 0;
for (j = 0; j < local_set_count; j++) { for (j = 0; j < local_set_count; j++) {
read_leb_uint32(p_code, buf_code_end, sub_local_count); read_leb_uint32(p_code, buf_code_end, sub_local_count);
if (!sub_local_count /* Note: sub_local_count is allowed to be 0 */
|| local_type_index > UINT32_MAX - sub_local_count if (local_type_index > UINT32_MAX - sub_local_count
|| local_type_index + sub_local_count > local_count) { || local_type_index + sub_local_count > local_count) {
set_error_buf(error_buf, error_buf_size, set_error_buf(error_buf, error_buf_size,
"invalid local count"); "invalid local count");
@ -2907,7 +2907,7 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
section->name_addr = (char *)p; section->name_addr = (char *)p;
section->name_len = name_len; section->name_len = name_len;
section->content_addr = (uint8 *)(p + name_len); section->content_addr = (uint8 *)(p + name_len);
section->content_len = p_end - p - name_len; section->content_len = (uint32)(p_end - p - name_len);
section->next = module->custom_section_list; section->next = module->custom_section_list;
module->custom_section_list = section; module->custom_section_list = section;
@ -3278,6 +3278,13 @@ load_from_sections(WASMModule *module, WASMSection *sections,
error_buf_size)) { error_buf_size)) {
return false; return false;
} }
if (i == module->function_count - 1
&& func->code + func->code_size != buf_code_end) {
set_error_buf(error_buf, error_buf_size,
"code section size mismatch");
return false;
}
} }
if (!module->possible_memory_grow) { if (!module->possible_memory_grow) {
@ -7344,7 +7351,7 @@ re_scan:
else if (is_64bit_type(*(loader_ctx->frame_ref - 1))) { else if (is_64bit_type(*(loader_ctx->frame_ref - 1))) {
loader_ctx->frame_ref -= 2; loader_ctx->frame_ref -= 2;
loader_ctx->stack_cell_num -= 2; loader_ctx->stack_cell_num -= 2;
#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0) #if WASM_ENABLE_FAST_INTERP == 0
*(p - 1) = WASM_OP_DROP_64; *(p - 1) = WASM_OP_DROP_64;
#endif #endif
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
@ -7406,7 +7413,7 @@ re_scan:
break; break;
case REF_I64_2: case REF_I64_2:
case REF_F64_2: case REF_F64_2:
#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0) #if WASM_ENABLE_FAST_INTERP == 0
*(p - 1) = WASM_OP_SELECT_64; *(p - 1) = WASM_OP_SELECT_64;
#endif #endif
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0

View File

@ -1013,8 +1013,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
local_type_index = 0; local_type_index = 0;
for (j = 0; j < local_set_count; j++) { for (j = 0; j < local_set_count; j++) {
read_leb_uint32(p_code, buf_code_end, sub_local_count); read_leb_uint32(p_code, buf_code_end, sub_local_count);
bh_assert(sub_local_count /* Note: sub_local_count is allowed to be 0 */
&& local_type_index <= UINT32_MAX - sub_local_count bh_assert(local_type_index <= UINT32_MAX - sub_local_count
&& local_type_index + sub_local_count <= local_count); && local_type_index + sub_local_count <= local_count);
CHECK_BUF(p_code, buf_code_end, 1); CHECK_BUF(p_code, buf_code_end, 1);
@ -2115,6 +2115,10 @@ load_from_sections(WASMModule *module, WASMSection *sections,
error_buf_size)) { error_buf_size)) {
return false; return false;
} }
if (i == module->function_count - 1) {
bh_assert(func->code + func->code_size == buf_code_end);
}
} }
if (!module->possible_memory_grow) { if (!module->possible_memory_grow) {
@ -5545,7 +5549,7 @@ re_scan:
else if (is_64bit_type(*(loader_ctx->frame_ref - 1))) { else if (is_64bit_type(*(loader_ctx->frame_ref - 1))) {
loader_ctx->frame_ref -= 2; loader_ctx->frame_ref -= 2;
loader_ctx->stack_cell_num -= 2; loader_ctx->stack_cell_num -= 2;
#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0) #if WASM_ENABLE_FAST_INTERP == 0
*(p - 1) = WASM_OP_DROP_64; *(p - 1) = WASM_OP_DROP_64;
#endif #endif
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0
@ -5591,7 +5595,7 @@ re_scan:
break; break;
case REF_I64_2: case REF_I64_2:
case REF_F64_2: case REF_F64_2:
#if (WASM_ENABLE_FAST_INTERP == 0) || (WASM_ENABLE_JIT != 0) #if WASM_ENABLE_FAST_INTERP == 0
*(p - 1) = WASM_OP_SELECT_64; *(p - 1) = WASM_OP_SELECT_64;
#endif #endif
#if WASM_ENABLE_FAST_INTERP != 0 #if WASM_ENABLE_FAST_INTERP != 0

View File

@ -1587,17 +1587,21 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size,
#endif #endif
/* init vec(funcidx) or vec(expr) */ /* init vec(funcidx) or vec(expr) */
bh_assert( #if WASM_ENABLE_REF_TYPES != 0
table_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST bh_assert(table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_I32_CONST
|| table_seg->base_offset.init_expr_type || table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL == INIT_EXPR_TYPE_GET_GLOBAL
#if WASM_ENABLE_REF_TYPES != 0
|| table_seg->base_offset.init_expr_type || table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_FUNCREF_CONST == INIT_EXPR_TYPE_FUNCREF_CONST
|| table_seg->base_offset.init_expr_type || table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_REFNULL_CONST == INIT_EXPR_TYPE_REFNULL_CONST);
#else
bh_assert(table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_I32_CONST
|| table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL);
#endif #endif
);
if (table_seg->base_offset.init_expr_type if (table_seg->base_offset.init_expr_type
== INIT_EXPR_TYPE_GET_GLOBAL) { == INIT_EXPR_TYPE_GET_GLOBAL) {
@ -2503,9 +2507,12 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
#if WASM_ENABLE_SHARED_MEMORY != 0 #if WASM_ENABLE_SHARED_MEMORY != 0
if (memory->is_shared) { if (memory->is_shared) {
memory->num_bytes_per_page = UINT32_MAX; memory->num_bytes_per_page = num_bytes_per_page;
memory->cur_page_count = total_page_count; memory->cur_page_count = total_page_count;
memory->max_page_count = max_page_count; memory->max_page_count = max_page_count;
/* No need to update memory->memory_data_size as it is
initialized with the maximum memory data size for
shared memory */
return true; return true;
} }
#endif #endif
@ -3080,7 +3087,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf,
return 0; return 0;
} }
total_frames = bh_vector_size(module_inst->frames); total_frames = (uint32)bh_vector_size(module_inst->frames);
if (total_frames == 0) { if (total_frames == 0) {
return 0; return 0;
} }

View File

@ -140,8 +140,10 @@ struct addrinfo {
struct addrinfo *ai_next; /* Pointer to next in list. */ struct addrinfo *ai_next; /* Pointer to next in list. */
}; };
#ifndef __WASI_RIGHTS_SOCK_ACCEPT
int int
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
#endif
int int
bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
@ -191,21 +193,30 @@ void
freeaddrinfo(struct addrinfo *res); freeaddrinfo(struct addrinfo *res);
#endif #endif
/**
* __wasi_sock_accept was introduced in wasi-sdk v15. To
* temporarily maintain backward compatibility with the old
* wasi-sdk, we explicitly add that implementation here so it works
* with older versions of the SDK.
*/
#ifndef __WASI_RIGHTS_SOCK_ACCEPT
/** /**
* Accept a connection on a socket * Accept a connection on a socket
* Note: This is similar to `accept` * Note: This is similar to `accept`
*/ */
int32_t int32_t
__imported_wasi_snapshot_preview1_sock_accept(int32_t arg0, int32_t arg1) __imported_wasi_snapshot_preview1_sock_accept(int32_t arg0, int32_t arg1,
int32_t arg2)
__attribute__((__import_module__("wasi_snapshot_preview1"), __attribute__((__import_module__("wasi_snapshot_preview1"),
__import_name__("sock_accept"))); __import_name__("sock_accept")));
static inline __wasi_errno_t static inline __wasi_errno_t
__wasi_sock_accept(__wasi_fd_t fd, __wasi_fd_t *fd_new) __wasi_sock_accept(__wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new)
{ {
return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_accept( return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_accept(
(int32_t)fd, (int32_t)fd_new); (int32_t)fd, (int32_t)flags, (int32_t)fd_new);
} }
#endif
/** /**
* Returns the local address to which the socket is bound. * Returns the local address to which the socket is bound.

View File

@ -6,8 +6,8 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <wasi/api.h> #include <wasi/api.h>
#include <wasi_socket_ext.h> #include <wasi_socket_ext.h>
@ -136,15 +136,18 @@ wasi_addr_to_sockaddr(const __wasi_addr_t *wasi_addr,
int int
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{ {
__wasi_addr_t wasi_addr = { 0 }; __wasi_addr_t wasi_addr;
__wasi_fd_t new_sockfd; __wasi_fd_t new_sockfd;
__wasi_errno_t error; __wasi_errno_t error;
error = __wasi_sock_accept(sockfd, &new_sockfd); memset(&wasi_addr, 0, sizeof(wasi_addr));
error = __wasi_sock_accept(sockfd, 0, &new_sockfd);
HANDLE_ERROR(error) HANDLE_ERROR(error)
error = getpeername(new_sockfd, addr, addrlen); if (getpeername(new_sockfd, addr, addrlen) == -1) {
HANDLE_ERROR(error) return -1;
}
return new_sockfd; return new_sockfd;
} }
@ -152,9 +155,11 @@ accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
int int
bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{ {
__wasi_addr_t wasi_addr = { 0 }; __wasi_addr_t wasi_addr;
__wasi_errno_t error; __wasi_errno_t error;
memset(&wasi_addr, 0, sizeof(wasi_addr));
error = sockaddr_to_wasi_addr(addr, addrlen, &wasi_addr); error = sockaddr_to_wasi_addr(addr, addrlen, &wasi_addr);
HANDLE_ERROR(error) HANDLE_ERROR(error)
@ -167,9 +172,11 @@ bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
int int
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{ {
__wasi_addr_t wasi_addr = { 0 }; __wasi_addr_t wasi_addr;
__wasi_errno_t error; __wasi_errno_t error;
memset(&wasi_addr, 0, sizeof(wasi_addr));
if (NULL == addr) { if (NULL == addr) {
HANDLE_ERROR(__WASI_ERRNO_INVAL) HANDLE_ERROR(__WASI_ERRNO_INVAL)
} }
@ -210,12 +217,13 @@ recvmsg(int sockfd, struct msghdr *msg, int flags)
} }
// __wasi_ciovec_t -> struct iovec // __wasi_ciovec_t -> struct iovec
if (!(ri_data = malloc(sizeof(__wasi_iovec_t) * msg->msg_iovlen))) { if (!(ri_data = (__wasi_iovec_t *)malloc(sizeof(__wasi_iovec_t)
* msg->msg_iovlen))) {
HANDLE_ERROR(__WASI_ERRNO_NOMEM) HANDLE_ERROR(__WASI_ERRNO_NOMEM)
} }
for (i = 0; i < msg->msg_iovlen; i++) { for (i = 0; i < msg->msg_iovlen; i++) {
ri_data[i].buf = msg->msg_iov[i].iov_base; ri_data[i].buf = (uint8_t *)msg->msg_iov[i].iov_base;
ri_data[i].buf_len = msg->msg_iov[i].iov_len; ri_data[i].buf_len = msg->msg_iov[i].iov_len;
} }
@ -246,12 +254,13 @@ sendmsg(int sockfd, const struct msghdr *msg, int flags)
} }
// struct iovec -> __wasi_ciovec_t // struct iovec -> __wasi_ciovec_t
if (!(si_data = malloc(sizeof(__wasi_ciovec_t) * msg->msg_iovlen))) { if (!(si_data = (__wasi_ciovec_t *)malloc(sizeof(__wasi_ciovec_t)
* msg->msg_iovlen))) {
HANDLE_ERROR(__WASI_ERRNO_NOMEM) HANDLE_ERROR(__WASI_ERRNO_NOMEM)
} }
for (i = 0; i < msg->msg_iovlen; i++) { for (i = 0; i < msg->msg_iovlen; i++) {
si_data[i].buf = msg->msg_iov[i].iov_base; si_data[i].buf = (uint8_t *)msg->msg_iov[i].iov_base;
si_data[i].buf_len = msg->msg_iov[i].iov_len; si_data[i].buf_len = msg->msg_iov[i].iov_len;
} }
@ -269,7 +278,7 @@ sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen) const struct sockaddr *dest_addr, socklen_t addrlen)
{ {
// Prepare input parameters. // Prepare input parameters.
__wasi_ciovec_t iov = { .buf = buf, .buf_len = len }; __wasi_ciovec_t iov = { .buf = (uint8_t *)buf, .buf_len = len };
uint32_t so_datalen = 0; uint32_t so_datalen = 0;
__wasi_addr_t wasi_addr; __wasi_addr_t wasi_addr;
__wasi_errno_t error; __wasi_errno_t error;
@ -297,7 +306,7 @@ recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen) struct sockaddr *src_addr, socklen_t *addrlen)
{ {
// Prepare input parameters. // Prepare input parameters.
__wasi_ciovec_t iov = { .buf = buf, .buf_len = len }; __wasi_ciovec_t iov = { .buf = (uint8_t *)buf, .buf_len = len };
uint32_t so_datalen = 0; uint32_t so_datalen = 0;
__wasi_addr_t wasi_addr; __wasi_addr_t wasi_addr;
__wasi_errno_t error; __wasi_errno_t error;
@ -363,9 +372,11 @@ socket(int domain, int type, int protocol)
int int
getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{ {
__wasi_addr_t wasi_addr = { 0 }; __wasi_addr_t wasi_addr;
__wasi_errno_t error; __wasi_errno_t error;
memset(&wasi_addr, 0, sizeof(wasi_addr));
error = __wasi_sock_addr_local(sockfd, &wasi_addr); error = __wasi_sock_addr_local(sockfd, &wasi_addr);
HANDLE_ERROR(error) HANDLE_ERROR(error)
@ -378,9 +389,11 @@ getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
int int
getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen) getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{ {
__wasi_addr_t wasi_addr = { 0 }; __wasi_addr_t wasi_addr;
__wasi_errno_t error; __wasi_errno_t error;
memset(&wasi_addr, 0, sizeof(wasi_addr));
error = __wasi_sock_addr_remote(sockfd, &wasi_addr); error = __wasi_sock_addr_remote(sockfd, &wasi_addr);
HANDLE_ERROR(error) HANDLE_ERROR(error)
@ -504,7 +517,8 @@ getaddrinfo(const char *node, const char *service, const struct addrinfo *hints,
return __WASI_ERRNO_SUCCESS; return __WASI_ERRNO_SUCCESS;
} }
aibuf_res = calloc(1, addr_info_size * sizeof(struct aibuf)); aibuf_res =
(struct aibuf *)calloc(1, addr_info_size * sizeof(struct aibuf));
if (!aibuf_res) { if (!aibuf_res) {
free(addr_info); free(addr_info);
HANDLE_ERROR(__WASI_ERRNO_NOMEM) HANDLE_ERROR(__WASI_ERRNO_NOMEM)
@ -543,7 +557,7 @@ freeaddrinfo(struct addrinfo *res)
free(res); free(res);
} }
struct timeval static struct timeval
time_us_to_timeval(uint64_t time_us) time_us_to_timeval(uint64_t time_us)
{ {
struct timeval tv; struct timeval tv;
@ -552,13 +566,13 @@ time_us_to_timeval(uint64_t time_us)
return tv; return tv;
} }
uint64_t static uint64_t
timeval_to_time_us(struct timeval tv) timeval_to_time_us(struct timeval tv)
{ {
return (tv.tv_sec * 1000000UL) + tv.tv_usec; return (tv.tv_sec * 1000000UL) + tv.tv_usec;
} }
int static int
get_sol_socket_option(int sockfd, int optname, void *__restrict optval, get_sol_socket_option(int sockfd, int optname, void *__restrict optval,
socklen_t *__restrict optlen) socklen_t *__restrict optlen)
{ {
@ -625,7 +639,7 @@ get_sol_socket_option(int sockfd, int optname, void *__restrict optval,
} }
} }
int static int
get_ipproto_tcp_option(int sockfd, int optname, void *__restrict optval, get_ipproto_tcp_option(int sockfd, int optname, void *__restrict optval,
socklen_t *__restrict optlen) socklen_t *__restrict optlen)
{ {
@ -664,7 +678,7 @@ get_ipproto_tcp_option(int sockfd, int optname, void *__restrict optval,
} }
} }
int static int
get_ipproto_ip_option(int sockfd, int optname, void *__restrict optval, get_ipproto_ip_option(int sockfd, int optname, void *__restrict optval,
socklen_t *__restrict optlen) socklen_t *__restrict optlen)
{ {
@ -694,7 +708,7 @@ get_ipproto_ip_option(int sockfd, int optname, void *__restrict optval,
} }
} }
int static int
get_ipproto_ipv6_option(int sockfd, int optname, void *__restrict optval, get_ipproto_ipv6_option(int sockfd, int optname, void *__restrict optval,
socklen_t *__restrict optlen) socklen_t *__restrict optlen)
{ {
@ -741,7 +755,7 @@ getsockopt(int sockfd, int level, int optname, void *__restrict optval,
} }
} }
int static int
set_sol_socket_option(int sockfd, int optname, const void *optval, set_sol_socket_option(int sockfd, int optname, const void *optval,
socklen_t optlen) socklen_t optlen)
{ {
@ -750,62 +764,82 @@ set_sol_socket_option(int sockfd, int optname, const void *optval,
switch (optname) { switch (optname) {
case SO_RCVTIMEO: case SO_RCVTIMEO:
{
assert(optlen == sizeof(struct timeval)); assert(optlen == sizeof(struct timeval));
timeout_us = timeval_to_time_us(*(struct timeval *)optval); timeout_us = timeval_to_time_us(*(struct timeval *)optval);
error = __wasi_sock_set_recv_timeout(sockfd, timeout_us); error = __wasi_sock_set_recv_timeout(sockfd, timeout_us);
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
}
case SO_SNDTIMEO: case SO_SNDTIMEO:
{
assert(optlen == sizeof(struct timeval)); assert(optlen == sizeof(struct timeval));
timeout_us = timeval_to_time_us(*(struct timeval *)optval); timeout_us = timeval_to_time_us(*(struct timeval *)optval);
error = __wasi_sock_set_send_timeout(sockfd, timeout_us); error = __wasi_sock_set_send_timeout(sockfd, timeout_us);
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
}
case SO_SNDBUF: case SO_SNDBUF:
{
assert(optlen == sizeof(int)); assert(optlen == sizeof(int));
error = __wasi_sock_set_send_buf_size(sockfd, *(size_t *)optval); error = __wasi_sock_set_send_buf_size(sockfd, *(size_t *)optval);
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
}
case SO_RCVBUF: case SO_RCVBUF:
{
assert(optlen == sizeof(int)); assert(optlen == sizeof(int));
error = __wasi_sock_set_recv_buf_size(sockfd, *(size_t *)optval); error = __wasi_sock_set_recv_buf_size(sockfd, *(size_t *)optval);
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
}
case SO_KEEPALIVE: case SO_KEEPALIVE:
{
assert(optlen == sizeof(int)); assert(optlen == sizeof(int));
error = __wasi_sock_set_keep_alive(sockfd, *(bool *)optval); error = __wasi_sock_set_keep_alive(sockfd, *(bool *)optval);
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
}
case SO_REUSEADDR: case SO_REUSEADDR:
{
assert(optlen == sizeof(int)); assert(optlen == sizeof(int));
error = __wasi_sock_set_reuse_addr(sockfd, *(bool *)optval); error = __wasi_sock_set_reuse_addr(sockfd, *(bool *)optval);
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
}
case SO_REUSEPORT: case SO_REUSEPORT:
{
assert(optlen == sizeof(int)); assert(optlen == sizeof(int));
error = __wasi_sock_set_reuse_port(sockfd, *(bool *)optval); error = __wasi_sock_set_reuse_port(sockfd, *(bool *)optval);
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
}
case SO_LINGER: case SO_LINGER:
{
assert(optlen == sizeof(struct linger)); assert(optlen == sizeof(struct linger));
struct linger *linger_opt = ((struct linger *)optval); struct linger *linger_opt = ((struct linger *)optval);
error = __wasi_sock_set_linger(sockfd, (bool)linger_opt->l_onoff, error = __wasi_sock_set_linger(sockfd, (bool)linger_opt->l_onoff,
linger_opt->l_linger); linger_opt->l_linger);
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
}
case SO_BROADCAST: case SO_BROADCAST:
{
assert(optlen == sizeof(int)); assert(optlen == sizeof(int));
error = __wasi_sock_set_broadcast(sockfd, *(bool *)optval); error = __wasi_sock_set_broadcast(sockfd, *(bool *)optval);
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
}
default: default:
{
error = __WASI_ERRNO_NOTSUP; error = __WASI_ERRNO_NOTSUP;
HANDLE_ERROR(error); HANDLE_ERROR(error);
return error; return error;
} }
}
} }
int static int
set_ipproto_tcp_option(int sockfd, int optname, const void *optval, set_ipproto_tcp_option(int sockfd, int optname, const void *optval,
socklen_t optlen) socklen_t optlen)
{ {
@ -845,7 +879,7 @@ set_ipproto_tcp_option(int sockfd, int optname, const void *optval,
} }
} }
int static int
set_ipproto_ip_option(int sockfd, int optname, const void *optval, set_ipproto_ip_option(int sockfd, int optname, const void *optval,
socklen_t optlen) socklen_t optlen)
{ {
@ -898,7 +932,7 @@ set_ipproto_ip_option(int sockfd, int optname, const void *optval,
} }
} }
int static int
set_ipproto_ipv6_option(int sockfd, int optname, const void *optval, set_ipproto_ipv6_option(int sockfd, int optname, const void *optval,
socklen_t optlen) socklen_t optlen)
{ {

View File

@ -345,9 +345,24 @@ sprintf_out(int c, struct str_context *ctx)
return c; return c;
} }
#ifdef BH_PLATFORM_OPENRTOS #ifndef BUILTIN_LIBC_BUFFERED_PRINTF
PRIVILEGED_DATA static char print_buf[128] = { 0 }; #define BUILTIN_LIBC_BUFFERED_PRINTF 0
PRIVILEGED_DATA static int print_buf_size = 0; #endif
#ifndef BUILTIN_LIBC_BUFFERED_PRINT_SIZE
#define BUILTIN_LIBC_BUFFERED_PRINT_SIZE 128
#endif
#ifndef BUILTIN_LIBC_BUFFERED_PRINT_PREFIX
#define BUILTIN_LIBC_BUFFERED_PRINT_PREFIX
#endif
#if BUILTIN_LIBC_BUFFERED_PRINTF != 0
BUILTIN_LIBC_BUFFERED_PRINT_PREFIX
static char print_buf[BUILTIN_LIBC_BUFFERED_PRINT_SIZE] = { 0 };
BUILTIN_LIBC_BUFFERED_PRINT_PREFIX
static int print_buf_size = 0;
static int static int
printf_out(int c, struct str_context *ctx) printf_out(int c, struct str_context *ctx)

View File

@ -1004,7 +1004,8 @@ wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32 buf_len)
} }
static wasi_errno_t static wasi_errno_t
wasi_sock_accept(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_fd_t *fd_new) wasi_sock_accept(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_fdflags_t flags,
wasi_fd_t *fd_new)
{ {
wasm_module_inst_t module_inst = get_module_inst(exec_env); wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
@ -1015,7 +1016,7 @@ wasi_sock_accept(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_fd_t *fd_new)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_accept(curfds, fd, fd_new); return wasi_ssp_sock_accept(curfds, fd, flags, fd_new);
} }
static wasi_errno_t static wasi_errno_t
@ -2156,7 +2157,7 @@ static NativeSymbol native_symbols_libc_wasi[] = {
REG_NATIVE_FUNC(proc_exit, "(i)"), REG_NATIVE_FUNC(proc_exit, "(i)"),
REG_NATIVE_FUNC(proc_raise, "(i)i"), REG_NATIVE_FUNC(proc_raise, "(i)i"),
REG_NATIVE_FUNC(random_get, "(*~)i"), REG_NATIVE_FUNC(random_get, "(*~)i"),
REG_NATIVE_FUNC(sock_accept, "(i*)i"), REG_NATIVE_FUNC(sock_accept, "(ii*)i"),
REG_NATIVE_FUNC(sock_addr_local, "(i*)i"), REG_NATIVE_FUNC(sock_addr_local, "(i*)i"),
REG_NATIVE_FUNC(sock_addr_remote, "(i*)i"), REG_NATIVE_FUNC(sock_addr_remote, "(i*)i"),
REG_NATIVE_FUNC(sock_addr_resolve, "($$**i*)i"), REG_NATIVE_FUNC(sock_addr_resolve, "($$**i*)i"),

View File

@ -1008,7 +1008,7 @@ wasi_ssp_sock_accept(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) #if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds, struct fd_table *curfds,
#endif #endif
__wasi_fd_t fd, __wasi_fd_t *fd_new __wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new
) __attribute__((__warn_unused_result__)); ) __attribute__((__warn_unused_result__));
__wasi_errno_t __wasi_errno_t

View File

@ -2905,7 +2905,7 @@ wasi_ssp_sock_accept(
#if !defined(WASMTIME_SSP_STATIC_CURFDS) #if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds, struct fd_table *curfds,
#endif #endif
__wasi_fd_t fd, __wasi_fd_t *fd_new) __wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new)
{ {
__wasi_filetype_t wasi_type; __wasi_filetype_t wasi_type;
__wasi_rights_t max_base, max_inheriting; __wasi_rights_t max_base, max_inheriting;

View File

@ -705,7 +705,7 @@ wasm_cluster_detach_thread(WASMExecEnv *exec_env)
os_mutex_unlock(&cluster_list_lock); os_mutex_unlock(&cluster_list_lock);
return 0; return 0;
} }
if (exec_env->wait_count == 0) { if (exec_env->wait_count == 0 && !exec_env->thread_is_detached) {
/* Only detach current thread when there is no other thread /* Only detach current thread when there is no other thread
joining it, otherwise let the system resources for the joining it, otherwise let the system resources for the
thread be released after joining */ thread be released after joining */

View File

@ -52,11 +52,13 @@ double fmax(double x, double y);
double rint(double x); double rint(double x);
double fabs(double x); double fabs(double x);
double trunc(double x); double trunc(double x);
float sqrtf(float x);
float floorf(float x); float floorf(float x);
float ceilf(float x); float ceilf(float x);
float fminf(float x, float y); float fminf(float x, float y);
float fmaxf(float x, float y); float fmaxf(float x, float y);
float rintf(float x); float rintf(float x);
float fabsf(float x);
float truncf(float x); float truncf(float x);
int signbit(double x); int signbit(double x);
int isnan(double x); int isnan(double x);

View File

@ -622,6 +622,74 @@ freebsd_atan2(double y, double x)
} }
} }
static float
freebsd_sqrtf(float x)
{
float z;
int32_t sign = (int)0x80000000;
int32_t ix, s, q, m, t, i;
u_int32_t r;
GET_FLOAT_WORD(ix, x);
/* take care of Inf and NaN */
if ((ix & 0x7f800000) == 0x7f800000) {
return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if (ix <= 0) {
if ((ix & (~sign)) == 0)
return x; /* sqrt(+-0) = +-0 */
else if (ix < 0)
return (x - x) / (x - x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix >> 23);
if (m == 0) { /* subnormal x */
for (i = 0; (ix & 0x00800000) == 0; i++)
ix <<= 1;
m -= i - 1;
}
m -= 127; /* unbias exponent */
ix = (ix & 0x007fffff) | 0x00800000;
if (m & 1) /* odd m, double x to make it even */
ix += ix;
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix += ix;
q = s = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
while (r != 0) {
t = s + r;
if (t <= ix) {
s = t + r;
ix -= t;
q += r;
}
ix += ix;
r >>= 1;
}
/* use floating add to find out rounding direction */
if (ix != 0) {
z = one - tiny; /* trigger inexact flag */
if (z >= one) {
z = one + tiny;
if (z > one)
q += 2;
else
q += (q & 1);
}
}
ix = (q >> 1) + 0x3f000000;
ix += (m << 23);
SET_FLOAT_WORD(z, ix);
return z;
}
static double static double
freebsd_sqrt(double x) /* wrapper sqrt */ freebsd_sqrt(double x) /* wrapper sqrt */
{ {
@ -935,6 +1003,15 @@ freebsd_isnan(double d)
} }
} }
static float
freebsd_fabsf(float x)
{
u_int32_t ix;
GET_FLOAT_WORD(ix, x);
SET_FLOAT_WORD(x, ix & 0x7fffffff);
return x;
}
static double static double
freebsd_fabs(double x) freebsd_fabs(double x)
{ {
@ -1537,6 +1614,12 @@ signbit(double x)
return ((__HI(x) & 0x80000000) >> 31); return ((__HI(x) & 0x80000000) >> 31);
} }
float
fabsf(float x)
{
return freebsd_fabsf(x);
}
float float
truncf(float x) truncf(float x)
{ {
@ -1573,6 +1656,12 @@ fmaxf(float x, float y)
return freebsd_fmaxf(x, y); return freebsd_fmaxf(x, y);
} }
float
sqrtf(float x)
{
return freebsd_sqrtf(x);
}
double double
pow(double x, double y) pow(double x, double y)
{ {

View File

@ -426,7 +426,7 @@ os_socket_getbooloption(bh_socket_t socket, int level, int optname,
assert(is_enabled); assert(is_enabled);
int optval; int optval;
int optval_size = sizeof(optval); socklen_t optval_size = sizeof(optval);
if (getsockopt(socket, level, optname, &optval, &optval_size) != 0) { if (getsockopt(socket, level, optname, &optval, &optval_size) != 0) {
return BHT_ERROR; return BHT_ERROR;
} }
@ -523,15 +523,25 @@ os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
int int
os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled) os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
{ {
#if defined(SO_REUSEPORT) /* NuttX doesn't have SO_REUSEPORT */
return os_socket_setbooloption(socket, SOL_SOCKET, SO_REUSEPORT, return os_socket_setbooloption(socket, SOL_SOCKET, SO_REUSEPORT,
is_enabled); is_enabled);
#else
errno = ENOTSUP;
return BHT_ERROR;
#endif /* defined(SO_REUSEPORT) */
} }
int int
os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled) os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
{ {
#if defined(SO_REUSEPORT) /* NuttX doesn't have SO_REUSEPORT */
return os_socket_getbooloption(socket, SOL_SOCKET, SO_REUSEPORT, return os_socket_getbooloption(socket, SOL_SOCKET, SO_REUSEPORT,
is_enabled); is_enabled);
#else
errno = ENOTSUP;
return BHT_ERROR;
#endif /* defined(SO_REUSEPORT) */
} }
int int

View File

@ -228,12 +228,14 @@ fdopendir(int fd)
return NULL; return NULL;
} }
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(4, 4, 2)
int int
ftruncate(int fd, off_t length) ftruncate(int fd, off_t length)
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
} }
#endif
int int
futimens(int fd, const struct timespec times[2]) futimens(int fd, const struct timespec times[2])

View File

@ -7,6 +7,10 @@
#include "sgx_error.h" #include "sgx_error.h"
#include "sgx_file.h" #include "sgx_file.h"
#if WASM_ENABLE_SGX_IPFS != 0
#include "sgx_ipfs.h"
#endif
#ifndef SGX_DISABLE_WASI #ifndef SGX_DISABLE_WASI
#define TRACE_FUNC() os_printf("undefined %s\n", __FUNCTION__) #define TRACE_FUNC() os_printf("undefined %s\n", __FUNCTION__)
@ -184,6 +188,22 @@ openat(int dirfd, const char *pathname, int flags, ...)
if (fd == -1) if (fd == -1)
errno = get_errno(); errno = get_errno();
#if WASM_ENABLE_SGX_IPFS != 0
// When WAMR uses Intel SGX IPFS to enabled, it opens a second
// file descriptor to interact with the secure file.
// The first file descriptor opened earlier is used to interact
// with the metadata of the file (e.g., time, flags, etc.).
int ret;
void *file_ptr = ipfs_fopen(fd, pathname, flags);
if (file_ptr == NULL) {
if (ocall_close(&ret, fd) != SGX_SUCCESS) {
TRACE_OCALL_FAIL();
}
return -1;
}
#endif
return fd; return fd;
} }
@ -192,6 +212,13 @@ close(int fd)
{ {
int ret; int ret;
#if WASM_ENABLE_SGX_IPFS != 0
// Close the IPFS file pointer in addition of the file descriptor
ret = ipfs_close(fd);
if (ret == -1)
errno = get_errno();
#endif
if (ocall_close(&ret, fd) != SGX_SUCCESS) { if (ocall_close(&ret, fd) != SGX_SUCCESS) {
TRACE_OCALL_FAIL(); TRACE_OCALL_FAIL();
return -1; return -1;
@ -345,6 +372,12 @@ readv_internal(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
if (total_size >= UINT32_MAX) if (total_size >= UINT32_MAX)
return -1; return -1;
#if WASM_ENABLE_SGX_IPFS != 0
if (fd > 2) {
return ipfs_read(fd, iov, iovcnt, has_offset, offset);
}
#endif
iov1 = BH_MALLOC((uint32)total_size); iov1 = BH_MALLOC((uint32)total_size);
if (iov1 == NULL) if (iov1 == NULL)
@ -410,6 +443,12 @@ writev_internal(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
if (total_size >= UINT32_MAX) if (total_size >= UINT32_MAX)
return -1; return -1;
#if WASM_ENABLE_SGX_IPFS != 0
if (fd > 2) {
return ipfs_write(fd, iov, iovcnt, has_offset, offset);
}
#endif
iov1 = BH_MALLOC((uint32)total_size); iov1 = BH_MALLOC((uint32)total_size);
if (iov1 == NULL) if (iov1 == NULL)
@ -468,12 +507,18 @@ off_t
lseek(int fd, off_t offset, int whence) lseek(int fd, off_t offset, int whence)
{ {
off_t ret; off_t ret;
#if WASM_ENABLE_SGX_IPFS != 0
ret = ipfs_lseek(fd, offset, whence);
#else
if (ocall_lseek(&ret, fd, (long)offset, whence) != SGX_SUCCESS) { if (ocall_lseek(&ret, fd, (long)offset, whence) != SGX_SUCCESS) {
TRACE_OCALL_FAIL(); TRACE_OCALL_FAIL();
return -1; return -1;
} }
if (ret == -1) if (ret == -1)
errno = get_errno(); errno = get_errno();
#endif
return ret; return ret;
} }
@ -482,12 +527,17 @@ ftruncate(int fd, off_t length)
{ {
int ret; int ret;
#if WASM_ENABLE_SGX_IPFS != 0
ret = ipfs_ftruncate(fd, length);
#else
if (ocall_ftruncate(&ret, fd, length) != SGX_SUCCESS) { if (ocall_ftruncate(&ret, fd, length) != SGX_SUCCESS) {
TRACE_OCALL_FAIL(); TRACE_OCALL_FAIL();
return -1; return -1;
} }
if (ret == -1) if (ret == -1)
errno = get_errno(); errno = get_errno();
#endif
return ret; return ret;
} }
@ -554,12 +604,17 @@ fsync(int fd)
{ {
int ret; int ret;
#if WASM_ENABLE_SGX_IPFS != 0
ret = ipfs_fflush(fd);
#else
if (ocall_fsync(&ret, fd) != SGX_SUCCESS) { if (ocall_fsync(&ret, fd) != SGX_SUCCESS) {
TRACE_OCALL_FAIL(); TRACE_OCALL_FAIL();
return -1; return -1;
} }
if (ret == -1) if (ret == -1)
errno = get_errno(); errno = get_errno();
#endif
return ret; return ret;
} }
@ -568,12 +623,17 @@ fdatasync(int fd)
{ {
int ret; int ret;
#if WASM_ENABLE_SGX_IPFS != 0
ret = ipfs_fflush(fd);
#else
if (ocall_fdatasync(&ret, fd) != SGX_SUCCESS) { if (ocall_fdatasync(&ret, fd) != SGX_SUCCESS) {
TRACE_OCALL_FAIL(); TRACE_OCALL_FAIL();
return -1; return -1;
} }
if (ret == -1) if (ret == -1)
errno = get_errno(); errno = get_errno();
#endif
return ret; return ret;
} }
@ -801,10 +861,14 @@ posix_fallocate(int fd, off_t offset, off_t len)
{ {
int ret; int ret;
#if WASM_ENABLE_SGX_IPFS != 0
ret = ipfs_posix_fallocate(fd, offset, len);
#else
if (ocall_posix_fallocate(&ret, fd, offset, len) != SGX_SUCCESS) { if (ocall_posix_fallocate(&ret, fd, offset, len) != SGX_SUCCESS) {
TRACE_OCALL_FAIL(); TRACE_OCALL_FAIL();
return -1; return -1;
} }
#endif
return ret; return ret;
} }

View File

@ -0,0 +1,460 @@
/*
* Copyright (C) 2022 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#if WASM_ENABLE_SGX_IPFS != 0
#include "ssp_config.h"
#include "bh_platform.h"
#include "sgx_ipfs.h"
#include <errno.h>
#include "sgx_tprotected_fs.h"
#define SGX_ERROR_FILE_LOWEST_ERROR_ID SGX_ERROR_FILE_BAD_STATUS
#define SGX_ERROR_FILE_HIGHEST_ERROR_ID SGX_ERROR_FILE_CLOSE_FAILED
// The mapping between file descriptors and IPFS file pointers.
static HashMap *ipfs_file_list;
// Converts an SGX error code to a POSIX error code.
static __wasi_errno_t
convert_sgx_errno(int error)
{
if (error >= SGX_ERROR_FILE_LOWEST_ERROR_ID
&& error <= SGX_ERROR_FILE_HIGHEST_ERROR_ID) {
switch (error) {
/* The file is in bad status */
case SGX_ERROR_FILE_BAD_STATUS:
return ENOTRECOVERABLE;
/* The Key ID field is all zeros, can't re-generate the encryption
* key */
case SGX_ERROR_FILE_NO_KEY_ID:
return EKEYREJECTED;
/* The current file name is different then the original file name
* (not allowed, substitution attack) */
case SGX_ERROR_FILE_NAME_MISMATCH:
return EIO;
/* The file is not an SGX file */
case SGX_ERROR_FILE_NOT_SGX_FILE:
return EEXIST;
/* A recovery file can't be opened, so flush operation can't
* continue (only used when no EXXX is returned) */
case SGX_ERROR_FILE_CANT_OPEN_RECOVERY_FILE:
return EIO;
/* A recovery file can't be written, so flush operation can't
* continue (only used when no EXXX is returned) */
case SGX_ERROR_FILE_CANT_WRITE_RECOVERY_FILE:
return EIO;
/* When openeing the file, recovery is needed, but the recovery
* process failed */
case SGX_ERROR_FILE_RECOVERY_NEEDED:
return EIO;
/* fflush operation (to disk) failed (only used when no EXXX is
* returned) */
case SGX_ERROR_FILE_FLUSH_FAILED:
return EIO;
/* fclose operation (to disk) failed (only used when no EXXX is
* returned) */
case SGX_ERROR_FILE_CLOSE_FAILED:
return EIO;
}
}
return error;
}
static void *
fd2file(int fd)
{
return bh_hash_map_find(ipfs_file_list, (void *)(intptr_t)fd);
}
static void
ipfs_file_destroy(void *sgx_file)
{
sgx_fclose(sgx_file);
}
int
ipfs_init()
{
ipfs_file_list =
bh_hash_map_create(32, true, (HashFunc)fd_hash, (KeyEqualFunc)fd_equal,
NULL, (ValueDestroyFunc)ipfs_file_destroy);
return ipfs_file_list != NULL ? BHT_OK : BHT_ERROR;
}
void
ipfs_destroy()
{
bh_hash_map_destroy(ipfs_file_list);
}
int
ipfs_posix_fallocate(int fd, off_t offset, size_t len)
{
void *sgx_file = fd2file(fd);
if (!sgx_file) {
return EBADF;
}
// The wrapper for fseek takes care of extending the file if sought beyond
// the end
if (ipfs_lseek(fd, offset + len, SEEK_CUR) == -1) {
return errno;
}
// Make sure the file is allocated by flushing it
if (sgx_fflush(sgx_file) != 0) {
return errno;
}
return 0;
}
size_t
ipfs_read(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
off_t offset)
{
int i;
off_t original_offset = 0;
void *sgx_file = fd2file(fd);
size_t read_result, number_of_read_bytes = 0;
if (!sgx_file) {
errno = EBADF;
return -1;
}
if (has_offset) {
// Save the current offset, to restore it after the read operation
original_offset = (off_t)sgx_ftell(sgx_file);
if (original_offset == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
// Move to the desired location
if (sgx_fseek(sgx_file, offset, SEEK_SET) == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
}
// For each element in the vector
for (i = 0; i < iovcnt; i++) {
if (iov[i].iov_len == 0)
continue;
read_result = sgx_fread(iov[i].iov_base, 1, iov[i].iov_len, sgx_file);
number_of_read_bytes += read_result;
if (read_result != iov[i].iov_len) {
if (!sgx_feof(sgx_file)) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
}
}
if (has_offset) {
// Restore the position of the cursor
if (sgx_fseek(sgx_file, original_offset, SEEK_SET) == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
}
return number_of_read_bytes;
}
size_t
ipfs_write(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
off_t offset)
{
int i;
off_t original_offset = 0;
void *sgx_file = fd2file(fd);
size_t write_result, number_of_written_bytes = 0;
if (!sgx_file) {
errno = EBADF;
return -1;
}
if (has_offset) {
// Save the current offset, to restore it after the read operation
original_offset = (off_t)sgx_ftell(sgx_file);
if (original_offset == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
// Move to the desired location
if (sgx_fseek(sgx_file, offset, SEEK_SET) == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
}
// For each element in the vector
for (i = 0; i < iovcnt; i++) {
if (iov[i].iov_len == 0)
continue;
write_result = sgx_fwrite(iov[i].iov_base, 1, iov[i].iov_len, sgx_file);
number_of_written_bytes += write_result;
if (write_result != iov[i].iov_len) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
}
if (has_offset) {
// Restore the position of the cursor
if (sgx_fseek(sgx_file, original_offset, SEEK_SET) == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
}
return number_of_written_bytes;
}
int
ipfs_close(int fd)
{
void *sgx_file;
if (!bh_hash_map_remove(ipfs_file_list, (void *)(intptr_t)fd, NULL,
&sgx_file)) {
errno = EBADF;
return -1;
}
if (sgx_fclose(sgx_file)) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
return 0;
}
void *
ipfs_fopen(int fd, const char *filename, int flags)
{
// Mapping back the mode
const char *mode;
bool must_create = (flags & O_CREAT) != 0;
bool must_truncate = (flags & O_TRUNC) != 0;
bool must_append = (flags & O_APPEND) != 0;
bool read_only = (flags & O_ACCMODE) == O_RDONLY;
bool write_only = (flags & O_ACCMODE) == O_WRONLY;
bool read_write = (flags & O_ACCMODE) == O_RDWR;
// The mapping of the mode are described in the table in the official
// specifications:
// https://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html
if (read_only)
mode = "r";
else if (write_only && must_create && must_truncate)
mode = "w";
else if (write_only && must_create && must_append)
mode = "a";
else if (read_write && must_create && must_truncate)
mode = "w+";
else if (read_write && must_create && must_append)
mode = "a+";
else if (read_write && must_create)
mode = "w+";
else if (read_write)
mode = "r+";
else
mode = NULL;
// Cannot map the requested access to the SGX IPFS
if (mode == NULL) {
errno = __WASI_ENOTCAPABLE;
return NULL;
}
// Opening the file
void *sgx_file = sgx_fopen_auto_key(filename, mode);
if (sgx_file == NULL) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return NULL;
}
if (!bh_hash_map_insert(ipfs_file_list, (void *)(intptr_t)fd, sgx_file)) {
errno = __WASI_ECANCELED;
sgx_fclose(sgx_file);
os_printf("An error occurred while inserting the IPFS file pointer in "
"the map.");
return NULL;
}
return sgx_file;
}
int
ipfs_fflush(int fd)
{
void *sgx_file = fd2file(fd);
if (!sgx_file) {
errno = EBADF;
return EOF;
}
int ret = sgx_fflush(sgx_file);
if (ret == 1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return EOF;
}
return ret;
}
off_t
ipfs_lseek(int fd, off_t offset, int nwhence)
{
off_t new_offset;
void *sgx_file = fd2file(fd);
if (!sgx_file) {
errno = EBADF;
return -1;
}
// Optimization: if the offset is 0 and the whence is SEEK_CUR,
// this is equivalent of a call to ftell.
if (offset == 0 && nwhence == SEEK_CUR) {
int64_t ftell_result = (off_t)sgx_ftell(sgx_file);
if (ftell_result == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
return ftell_result;
}
int fseek_result = sgx_fseek(sgx_file, offset, nwhence);
if (fseek_result == 0) {
new_offset = (__wasi_filesize_t)sgx_ftell(sgx_file);
if (new_offset == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
return new_offset;
}
else {
// In the case fseek returned an error
int sgx_error = sgx_ferror(sgx_file);
if (sgx_error != EINVAL) {
errno = convert_sgx_errno(sgx_error);
return -1;
}
// We must consider a difference in behavior of sgx_fseek and the POSIX
// fseek. If the cursor is moved beyond the end of the file, sgx_fseek
// returns an error, whereas POSIX fseek accepts the cursor move and
// fill with zeroes the difference for the next write. This
// implementation handle zeroes completion and moving the cursor forward
// the end of the file, but does it now (during the fseek), which is
// different compared to POSIX implementation, that writes zeroes on the
// next write. This avoids the runtime to keep track of the cursor
// manually.
// Assume the error is raised because the cursor is moved beyond the end
// of the file. Try to move the cursor at the end of the file.
if (sgx_fseek(sgx_file, 0, SEEK_END) == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
// Write the missing zeroes
char zero = 0;
int64_t number_of_zeroes = offset - sgx_ftell(sgx_file);
if (sgx_fwrite(&zero, 1, number_of_zeroes, sgx_file) == 0) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
// Move again at the end of the file
if (sgx_fseek(sgx_file, 0, SEEK_END) == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
return offset;
}
}
// The official API does not provide a way to truncate files.
// Only files extension is supported.
int
ipfs_ftruncate(int fd, off_t len)
{
void *sgx_file = fd2file(fd);
if (!sgx_file) {
errno = EBADF;
return -1;
}
off_t original_offset = sgx_ftell(sgx_file);
// Optimization path: if the length is smaller than the offset,
// IPFS does not support truncate to a smaller size.
if (len < original_offset) {
os_printf(
"SGX IPFS does not support truncate files to smaller sizes.\n");
return __WASI_ECANCELED;
}
// Move to the end of the file to determine whether this is
// a file extension or reduction.
if (sgx_fseek(sgx_file, 0, SEEK_END) == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
off_t file_size = sgx_ftell(sgx_file);
// Reducing the file space is not supported by IPFS.
if (len < file_size) {
os_printf(
"SGX IPFS does not support truncate files to smaller sizes.\n");
return __WASI_ECANCELED;
}
// Increasing the size is equal to writing from the end of the file
// with null bytes.
char null_byte = 0;
if (sgx_fwrite(&null_byte, 1, len - file_size, sgx_file) == 0) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
// Restore the position of the cursor
if (sgx_fseek(sgx_file, original_offset, SEEK_SET) == -1) {
errno = convert_sgx_errno(sgx_ferror(sgx_file));
return -1;
}
return 0;
}
#endif /* end of WASM_ENABLE_SGX_IPFS */

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2022 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _LIBC_WASI_SGX_PFS_H
#define _LIBC_WASI_SGX_PFS_H
#include "bh_hashmap.h"
#include "wasmtime_ssp.h"
#ifdef __cplusplus
extern "C" {
#endif
int
ipfs_init();
void
ipfs_destroy();
int
ipfs_posix_fallocate(int fd, off_t offset, size_t len);
size_t
ipfs_read(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
off_t offset);
size_t
ipfs_write(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
off_t offset);
int
ipfs_close(int fd);
void *
ipfs_fopen(int fd, const char *filename, int flags);
int
ipfs_fflush(int fd);
off_t
ipfs_lseek(int fd, off_t offset, int nwhence);
int
ipfs_ftruncate(int fd, off_t len);
/**
* Whether two file descriptors are equal.
*/
inline static bool
fd_equal(int left, int right)
{
return left == right ? true : false;
}
/**
* Returns the file descriptor as a hash value.
*/
inline static uint32
fd_hash(int fd)
{
return (uint32)fd;
}
#ifdef __cplusplus
}
#endif
#endif /* end of _LIBC_WASI_SGX_PFS_H */

View File

@ -7,17 +7,31 @@
#include "platform_api_extension.h" #include "platform_api_extension.h"
#include "sgx_rsrv_mem_mngr.h" #include "sgx_rsrv_mem_mngr.h"
#if WASM_ENABLE_SGX_IPFS != 0
#include "sgx_ipfs.h"
#endif
static os_print_function_t print_function = NULL; static os_print_function_t print_function = NULL;
int int
bh_platform_init() bh_platform_init()
{ {
return 0; int ret = BHT_OK;
#if WASM_ENABLE_SGX_IPFS != 0
ret = ipfs_init();
#endif
return ret;
} }
void void
bh_platform_destroy() bh_platform_destroy()
{} {
#if WASM_ENABLE_SGX_IPFS != 0
ipfs_destroy();
#endif
}
void * void *
os_malloc(unsigned size) os_malloc(unsigned size)

View File

@ -22,6 +22,7 @@
#include <unistd.h> #include <unistd.h>
#include <math.h> #include <math.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -77,6 +78,10 @@ typedef sem_t korp_sem;
#define CONFIG_HAS_ISATTY 0 #define CONFIG_HAS_ISATTY 0
#endif #endif
#define BUILTIN_LIBC_BUFFERED_PRINTF 1
#define BUILTIN_LIBC_BUFFERED_PRINT_SIZE 128
#define BUILTIN_LIBC_BUFFERED_PRINT_PREFIX
/* /*
* NuttX doesn't have openat family. * NuttX doesn't have openat family.
*/ */

View File

@ -63,11 +63,13 @@ double fmax(double x, double y);
double rint(double x); double rint(double x);
double fabs(double x); double fabs(double x);
double trunc(double x); double trunc(double x);
float sqrtf(float x);
float floorf(float x); float floorf(float x);
float ceilf(float x); float ceilf(float x);
float fminf(float x, float y); float fminf(float x, float y);
float fmaxf(float x, float y); float fmaxf(float x, float y);
float rintf(float x); float rintf(float x);
float fabsf(float x);
float truncf(float x); float truncf(float x);
int signbit(double x); int signbit(double x);
int isnan(double x); int isnan(double x);

View File

@ -78,11 +78,13 @@ double fmax(double x, double y);
double rint(double x); double rint(double x);
double fabs(double x); double fabs(double x);
double trunc(double x); double trunc(double x);
float sqrtf(float x);
float floorf(float x); float floorf(float x);
float ceilf(float x); float ceilf(float x);
float fminf(float x, float y); float fminf(float x, float y);
float fmaxf(float x, float y); float fmaxf(float x, float y);
float rintf(float x); float rintf(float x);
float fabsf(float x);
float truncf(float x); float truncf(float x);
int signbit(double x); int signbit(double x);
int isnan(double x); int isnan(double x);

View File

@ -25,12 +25,12 @@ typedef uint32 (*HashFunc)(const void *key);
typedef bool (*KeyEqualFunc)(void *key1, void *key2); typedef bool (*KeyEqualFunc)(void *key1, void *key2);
/* Key destroy function: to destroy the key, auto called /* Key destroy function: to destroy the key, auto called
when an hash element is removed. */ for each key when the hash map is destroyed. */
typedef void (*KeyDestroyFunc)(void *key); typedef void (*KeyDestroyFunc)(void *key);
/* Value destroy function: to destroy the value, auto called /* Value destroy function: to destroy the value, auto called
when an hash element is removed. */ for each value when the hash map is destroyed. */
typedef void (*ValueDestroyFunc)(void *key); typedef void (*ValueDestroyFunc)(void *value);
/* traverse callback function: /* traverse callback function:
auto called when traverse every hash element */ auto called when traverse every hash element */
@ -44,10 +44,10 @@ typedef void (*TraverseCallbackFunc)(void *key, void *value, void *user_data);
* @param hash_func hash function of the key, must be specified * @param hash_func hash function of the key, must be specified
* @param key_equal_func key equal function, check whether two keys * @param key_equal_func key equal function, check whether two keys
* are equal, must be specified * are equal, must be specified
* @param key_destroy_func key destroy function, called when an hash element * @param key_destroy_func key destroy function, called for each key if not NULL
* is removed if it is not NULL * when the hash map is destroyed
* @param value_destroy_func value destroy function, called when an hash * @param value_destroy_func value destroy function, called for each value if
* element is removed if it is not NULL * not NULL when the hash map is destroyed
* *
* @return the hash map created, NULL if failed * @return the hash map created, NULL if failed
*/ */

25
doc/devcontainer.md Normal file
View File

@ -0,0 +1,25 @@
# Visual Studio Code development container
We all know Docker containers and may use them a lot in school or work. It resolves dependency management for our projects/applications, prevents package version confusion and conflict, and contamination of the local environment.
Now WAMR has a Dockerfile under path `.devontainer` to create a container image, dev container images that you could easily use in VS Code. In case you prefer other IDE like Clion, you can also build it and use for the IDE you like.
## How to use it
It's straightforward to use Docker in VS Code! First, you have VS Code and Docker installed(if not yet, check [next section](#learn-more-about-docker-and-vs-code) for howto). Then you need to download Docker in VS Code extensions marketplace.
And that's it, and you are good to go! When you open the root folder of WAMR, in the bottom right corner, the Docker extension will pop a notification and ask if you like to reopen the folder in a container.
If you encounter any problems or get stuck somewhere, may this video [demo](https://youtu.be/Uvf2FVS1F8k) for docker usage in VS Code will help.
## Learn more about Docker and VS Code
[Install Docker](https://docs.docker.com/get-docker/)
[Install VS Code](https://code.visualstudio.com/)
[Docker extension for VS Code](https://code.visualstudio.com/docs/containers/overview)
[Remote development with Docker in VS Code](https://code.visualstudio.com/docs/remote/containers#_getting-started)
[What is dev container image in VS Code](https://code.visualstudio.com/docs/remote/containers#_prebuilding-dev-container-images)

View File

@ -195,6 +195,57 @@ typedef enum EcallCmd {
}; };
``` ```
SGX Intel Protected File System
-------------------------------
Intel SGX introduced a feature called [Intel Protection File System Library (IPFS)](https://www.intel.com/content/www/us/en/developer/articles/technical/overview-of-intel-protected-file-system-library-using-software-guard-extensions.html) to create, operate and delete files inside the enclave.
WAMR supports the mapping of IPFS on WASI functions related to file interactions, providing seamless persistence with confidentiality and integrity to the hosted WebAssembly applications in the enclave.
The usage of SGX IPFS is an optional feature.
To opt-in, the support of IPFS requires the following changes:
- set the flag `WAMR_BUILD_SGX_IPFS=1` when running `cmake`,
- the enclave must be linked with the trusted IPFS library (`-lsgx_tprotected_fs`),
- the application outside of the enclave must be linked with the untrusted IPFS library (`-lsgx_uprotected_fs`),
- the EDL file must include the following import statement:
```edl
from "sgx_tprotected_fs.edl" import *;
```
When using the [enclave-sample](../product-mini/platforms/linux-sgx/enclave-sample/) project, setting the flag `WAMR_BUILD_SGX_IPFS=1` when running `cmake` enables these changes automatically.
### Verification of SGX IPFS
One can observe the usage of IPFS by running the [file sample](../samples/file/) WebAssembly application.
Enabling the SGX IPFS on this sample project leads to the generation of an encrypted text file.
### Mapping of WASI/POSIX to IPFS
This table summarizes how WASI is mapped to POSIX and IPFS.
Since IPFS is a subset of the WASI/POSIX, emulation is performed to fill the missing implementation.
| WASI | POSIX | IPFS |
|------------------------|-------------------|-------------------------------------------------------------------------------------------------------------------------|
| `fd_read` | `readv` | `sgx_fread` |
| `fd_write` | `writev` | `sgx_fwrite` |
| `fd_close` | `close` | `sgx_fclose` |
| `path_open` | `openat` | `sgx_fopen` |
| `fd_datasync` | `fsync` | `sgx_fflush` |
| `fd_tell` | `lseek` | `sgx_ftell` |
| `fd_filestat_set_size` | `ftruncate` | Shrinking files is not supported, nor emulated. Extending files is emulated using `sgx_fseek`/`sgx_ftell`/`sgx_fwrite`. |
| `fd_seek` | `lseek` | The POSIX and IPFS behaviors differ. Emulated using `sgx_fseek`/`sgx_ftell`/`sgx_fwrite`. |
| `fd_pwrite` | `pwrite` | Not supported. Emulated using `sgx_fseek`/`sgx_ftell`/`sgx_fwrite`. |
| `fd_pread` | `pread` | Not supported. Emulated using `sgx_fseek`/`sgx_ftell`/`sgx_fread`. |
| `fd_allocate` | `posix_fallocate` | Not supported. Emulated using `sgx_fseek`/`sgx_ftell`/`sgx_fwrite`/`sgx_fflush`. |
### Performance overheads
Many benchmarks have assessed the overheads caused by IPFS through WASI functions using Twine, an early and academic adaptation of WAMR in Intel SGX with WASI support.
The results can be found in [this paper](https://arxiv.org/abs/2103.15860).
### Limitations
The threat model and the limitations of SGX IPFS can be found in [the official documentation](https://www.intel.com/content/dam/develop/external/us/en/documents/overviewofintelprotectedfilesystemlibrary.pdf).
Others Others
------ ------

View File

@ -60,7 +60,7 @@ Then you can use lldb commands to debug your applications. Please refer to [lldb
1. Build lldb (assume you have already built llvm) 1. Build lldb (assume you have already built llvm)
``` bash ``` bash
cd ${WAMR_ROOT}/core/deps/llvm/build cd ${WAMR_ROOT}/core/deps/llvm/build
cmake . -DLLVM_ENABLE_PROJECTS="clang;lldb" cmake ../llvm -DLLVM_ENABLE_PROJECTS="clang;lldb" -DLLDB_INCLUDE_TESTS=OFF
make -j $(nproc) make -j $(nproc)
``` ```
@ -86,11 +86,71 @@ wamrc -o test.aot test.wasm
``` ```
5. Execute iwasm using lldb 5. Execute iwasm using lldb
``` bash
lldb-12 iwasm -- test.aot
```
Then you can use lldb commands to debug both wamr runtime and your wasm application in ***current terminal*** Then you can use lldb commands to debug both wamr runtime and your wasm application in ***current terminal***.
``` bash
% lldb iwasm -- test.aot
(lldb) target create "iwasm"
Current executable set to 'iwasm' (x86_64).
(lldb) settings set -- target.run-args "test.aot"
(lldb) settings set plugin.jit-loader.gdb.enable on
(lldb) b main
Breakpoint 1: where = iwasm`main + 48 at main.c:294:11, address = 0x0000000100001020
(lldb) run
Process 27954 launched: '/tmp/bin/iwasm' (x86_64)
Process 27954 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100001020 iwasm`main(argc=2, argv=0x00007ff7bfeff678) at main.c:294:11
291 int
292 main(int argc, char *argv[])
293 {
-> 294 int32 ret = -1;
295 char *wasm_file = NULL;
296 const char *func_name = NULL;
297 uint8 *wasm_file_buf = NULL;
Target 0: (iwasm) stopped.
(lldb) c
Process 27954 resuming
1 location added to breakpoint 1
error: need to add support for DW_TAG_base_type 'void' encoded with DW_ATE = 0x0, bit_size = 0
Process 27954 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.2
frame #0: 0x00000001002980a0 JIT(0x100298004)`main(exenv=0x0000000301808200) at hello.c:6:9
3 int
4 main(void)
5 {
-> 6 printf("hello\n");
7
8 return 0;
9 }
Target 0: (iwasm) stopped.
(lldb) br l
Current breakpoints:
1: name = 'main', locations = 2, resolved = 2, hit count = 2
1.1: where = iwasm`main + 48 at main.c:294:11, address = 0x0000000100001020, resolved, hit count = 1
1.2: where = JIT(0x100298004)`main + 12 at hello.c:6:9, address = 0x00000001002980a0, resolved, hit count = 1
(lldb)
```
* In the above example,
* The first `main` function, which is in `main.c`, is the main
function of the iwasm command.
* The second `main` function, which is in `hello.c`, is the main
function of the AOT-compiled wasm module.
* WAMR AOT debugging uses the GDB JIT loader mechanism to load
the debug info of the debugee module.
On some platforms including macOS, you need to enable it explicitly.
(`settings set plugin.jit-loader.gdb.enable on`)
References:
* https://github.com/llvm/llvm-project/blob/main/llvm/docs/DebuggingJITedCode.rst
* https://sourceware.org/gdb/current/onlinedocs/gdb/JIT-Interface.html
## Enable debugging in embedders (for interpreter) ## Enable debugging in embedders (for interpreter)

View File

@ -134,8 +134,7 @@ func (self *Module) SetWasiAddrPool(addrPool [][]byte) {
} }
/* Set module's wasi domain lookup pool */ /* Set module's wasi domain lookup pool */
func(self *Module) SetWasiNsLookupPool(nsLookupPool[][] byte) func(self *Module) SetWasiNsLookupPool(nsLookupPool [][]byte) {
{
var nsLookupPoolPtr **C.char var nsLookupPoolPtr **C.char
var nsLookupPoolSize C.uint var nsLookupPoolSize C.uint

View File

@ -3,4 +3,4 @@
# Copyright (C) 2020 Intel Corporation. All rights reserved. # Copyright (C) 2020 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
/usr/bin/env python3 ../../../build-scripts/build_llvm.py --platform android /usr/bin/env python3 ../../../build-scripts/build_llvm.py --platform android "$@"

View File

@ -3,4 +3,4 @@
# Copyright (C) 2020 Intel Corporation. All rights reserved. # Copyright (C) 2020 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
/usr/bin/env python3 ../../../build-scripts/build_llvm.py --platform darwin /usr/bin/env python3 ../../../build-scripts/build_llvm.py --platform darwin "$@"

View File

@ -84,6 +84,11 @@ if (NOT DEFINED WAMR_BUILD_SIMD)
set (WAMR_BUILD_SIMD 0) set (WAMR_BUILD_SIMD 0)
endif () endif ()
if (NOT DEFINED WAMR_BUILD_SGX_IPFS)
# Disable SGX IPFS by default
set (WAMR_BUILD_SGX_IPFS 0)
endif ()
if (COLLECT_CODE_COVERAGE EQUAL 1) if (COLLECT_CODE_COVERAGE EQUAL 1)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
endif () endif ()
@ -117,3 +122,23 @@ else()
OUTPUT_VARIABLE cmdOutput OUTPUT_VARIABLE cmdOutput
) )
endif() endif()
if (WAMR_BUILD_SGX_IPFS EQUAL 1)
execute_process(
COMMAND bash -c "sed -i -E 's/^#define SGX_IPFS 0/#define SGX_IPFS 1/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Enclave/Enclave.edl"
OUTPUT_VARIABLE cmdOutput
)
execute_process(
COMMAND bash -c "sed -i -E 's/^SGX_IPFS = 0/SGX_IPFS = 1/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Makefile"
OUTPUT_VARIABLE cmdOutput
)
else()
execute_process(
COMMAND bash -c "sed -i -E 's/^#define SGX_IPFS 1/#define SGX_IPFS 0/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Enclave/Enclave.edl"
OUTPUT_VARIABLE cmdOutput
)
execute_process(
COMMAND bash -c "sed -i -E 's/^SGX_IPFS = 1/SGX_IPFS = 0/g' ${CMAKE_CURRENT_SOURCE_DIR}/enclave-sample/Makefile"
OUTPUT_VARIABLE cmdOutput
)
endif()

View File

@ -4,6 +4,7 @@
*/ */
#define LIB_RATS 0 #define LIB_RATS 0
#define SGX_IPFS 0
enclave { enclave {
from "sgx_tstdc.edl" import *; from "sgx_tstdc.edl" import *;
@ -12,6 +13,9 @@ enclave {
#if LIB_RATS != 0 #if LIB_RATS != 0
from "rats.edl" import *; from "rats.edl" import *;
#endif #endif
#if SGX_IPFS != 0
from "sgx_tprotected_fs.edl" import *;
#endif
trusted { trusted {
/* define ECALLs here. */ /* define ECALLs here. */

View File

@ -9,6 +9,9 @@ SGX_ARCH ?= x64
SGX_DEBUG ?= 0 SGX_DEBUG ?= 0
SPEC_TEST ?= 0 SPEC_TEST ?= 0
# This variable is automatically set by CMakeLists.txt
SGX_IPFS = 0
VMLIB_BUILD_DIR ?= $(CURDIR)/../build VMLIB_BUILD_DIR ?= $(CURDIR)/../build
LIB_RATS_SRC ?= $(VMLIB_BUILD_DIR)/_deps/librats-build LIB_RATS_SRC ?= $(VMLIB_BUILD_DIR)/_deps/librats-build
LIB_RATS := $(shell if [ -d $(LIB_RATS_SRC) ]; then echo 1; else echo 0; fi) LIB_RATS := $(shell if [ -d $(LIB_RATS_SRC) ]; then echo 1; else echo 0; fi)
@ -106,6 +109,12 @@ else
Trts_Library_Name := sgx_trts Trts_Library_Name := sgx_trts
Service_Library_Name := sgx_tservice Service_Library_Name := sgx_tservice
endif endif
ifeq ($(SGX_IPFS), 1)
Intel_Ipfs_Trusted_Flag = -lsgx_tprotected_fs
App_Link_Flags += -lsgx_uprotected_fs
endif
Crypto_Library_Name := sgx_tcrypto Crypto_Library_Name := sgx_tcrypto
WAMR_ROOT := $(CURDIR)/../../../../ WAMR_ROOT := $(CURDIR)/../../../../
@ -139,7 +148,7 @@ endif
Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++ Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++11 -nostdinc++
Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) ${Rats_Lib_Link_Dirs} \ Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) ${Rats_Lib_Link_Dirs} \
-Wl,--whole-archive -l$(Trts_Library_Name) ${Rats_Lib_Link_libs} -Wl,--no-whole-archive \ -Wl,--whole-archive -l$(Trts_Library_Name) ${Rats_Lib_Link_libs} $(Intel_Ipfs_Trusted_Flag) -Wl,--no-whole-archive \
-Wl,--start-group -lsgx_tstdc -lsgx_tcxx -lsgx_pthread -lsgx_tkey_exchange -l$(Crypto_Library_Name) -l$(Service_Library_Name) -lsgx_dcap_tvl -Wl,--end-group \ -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -lsgx_pthread -lsgx_tkey_exchange -l$(Crypto_Library_Name) -l$(Service_Library_Name) -lsgx_dcap_tvl -Wl,--end-group \
-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
-Wl,-pie,-eenclave_entry -Wl,--export-dynamic \ -Wl,-pie,-eenclave_entry -Wl,--export-dynamic \
@ -217,7 +226,6 @@ $(App_Name): App/Enclave_u.o $(App_Cpp_Objects) libvmlib_untrusted.a
######## Enclave Objects ######## ######## Enclave Objects ########
Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl librats Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl librats
@cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl $(Enclave_Edl_Search_Path) @cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl $(Enclave_Edl_Search_Path)
@echo "GEN => $@" @echo "GEN => $@"

View File

@ -3,4 +3,4 @@
# Copyright (C) 2020 Intel Corporation. All rights reserved. # Copyright (C) 2020 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
/usr/bin/env python3 ../../../build-scripts/build_llvm.py /usr/bin/env python3 ../../../build-scripts/build_llvm.py "$@"

View File

@ -1,37 +0,0 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
FROM ubuntu:20.04
ARG DOCKER_UID=1000
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -qq update && apt-get -qq dist-upgrade && apt install -qq -y python3-pip git wget ninja-build
WORKDIR /tmp
RUN mkdir /opt/cmake && wget -q https://github.com/Kitware/CMake/releases/download/v3.22.1/cmake-3.22.1-linux-x86_64.sh && sh cmake-3.22.1-linux-x86_64.sh --skip-license --prefix=/opt/cmake && rm cmake-3.22.1-linux-x86_64.sh
ENV PATH="/opt/cmake/bin:$PATH"
RUN useradd -m wamr -u ${DOCKER_UID} -G dialout
USER wamr
ENV PATH="/home/wamr/.local/bin:$PATH"
RUN pip3 install --user west
RUN west init ~/zephyrproject && cd ~/zephyrproject && west update && west zephyr-export
RUN pip3 install --user -r ~/zephyrproject/zephyr/scripts/requirements.txt
WORKDIR /home/wamr/zephyrproject
RUN west espressif install
ENV ZEPHYR_BASE=/home/wamr/zephyrproject/zephyr
ENV ESPRESSIF_TOOLCHAIN_PATH=/home/wamr/.espressif/tools/zephyr
WORKDIR /home/wamr/source/product-mini/platforms/zephyr/simple

View File

@ -0,0 +1,9 @@
# Copyright (C) 2022 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 3.0)
project(file)
################ wasm application ###############
add_subdirectory(src)
add_subdirectory(wasm-app)

112
samples/file/README.md Normal file
View File

@ -0,0 +1,112 @@
# "file" sample introduction
This sample demonstrates the supported file interaction API of WASI.
This sample can also demonstrate the SGX IPFS (Intel Protected File System), enabling an enclave to seal and unseal data at rest.
## Preparation
Please install WASI SDK, download the [wasi-sdk release](https://github.com/CraneStation/wasi-sdk/releases) and extract the archive to default path `/opt/wasi-sdk`.
For testing with SGX IPFS, follow the instructions in [the documentation of SGX for WAMR](../../doc/linux_sgx.md#sgx-intel-protected-file-system).
## Build the sample
```bash
mkdir build
cd build
cmake ..
make
```
The WebAssembly application is the file located at `wasm-app/file.wasm`.
## Run workload
Either use [iwasm-sample](../../product-mini/platforms/linux/) for Linux, or [enclave-sample](../../product-mini/platforms/linux-sgx/enclave-sample/) for Intel SGX to run the sample, with the argument to allow the file system interaction with the current folder (`--dir=.`).
The output with Linux and POSIX is like:
```bash
Opening a file..
[Test] File opening passed.
Writing to the file..
[Test] File writing passed.
Moving the cursor to the start of the file..
Reading from the file, up to 1000 characters..
Text read: Hello, world!
[Test] File reading passed.
Determine whether we reach the end of the file..
Is the end of file? 1
[Test] End of file detection passed.
Getting the plaintext size..
The plaintext size is 13.
[Test] Retrieving file offset passed.
Force actual write of all the cached data to the disk..
[Test] Retrieving file offset passed.
Writing 5 characters at offset 7..
File current offset: 13
[Test] Writing at specified offset passed.
Reading 5 characters at offset 7..
Text read: James
File current offset: 13
[Test] Reading at specified offset passed.
Allocate more space to the file..
File current offset: 13
Moving to the end..
File current offset: 23
[Test] Allocation or more space passed.
Extend the file size of 10 bytes using ftruncate..
File current offset: 23
Moving to the end..
File current offset: 33
[Test] Extension of the file size passed.
Closing from the file..
[Test] Closing file passed.
Getting the size of the file on disk..
The file size is 33.
All the tests passed!
```
The output with SGX and IPFS is like:
```bash
Opening a file..
[Test] File opening passed.
Writing to the file..
[Test] File writing passed.
Moving the cursor to the start of the file..
Reading from the file, up to 1000 characters..
Text read: Hello, world!
[Test] File reading passed.
Determine whether we reach the end of the file..
Is the end of file? 1
[Test] End of file detection passed.
Getting the plaintext size..
The plaintext size is 13.
[Test] Retrieving file offset passed.
Force actual write of all the cached data to the disk..
[Test] Retrieving file offset passed.
Writing 5 characters at offset 7..
File current offset: 13
[Test] Writing at specified offset passed.
Reading 5 characters at offset 7..
Text read: James
File current offset: 13
[Test] Reading at specified offset passed.
Allocate more space to the file..
File current offset: 23
Moving to the end..
File current offset: 23
[Test] Allocation or more space passed.
Extend the file size of 10 bytes using ftruncate..
File current offset: 23
Moving to the end..
File current offset: 33
[Test] Extension of the file size passed.
Closing from the file..
[Test] Closing file passed.
Getting the size of the file on disk..
The file size is 4096.
All the tests passed!
```
For SGX IPFS, refer to [SGX Intel Protected File System](../../doc/linux_sgx.md#sgx-intel-protected-file-system) for more details.

View File

@ -0,0 +1,87 @@
# Copyright (C) 2022 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required (VERSION 3.0)
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
project (iwasm)
else()
project (iwasm C ASM)
enable_language (ASM_MASM)
endif()
################ runtime settings ################
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
if (APPLE)
add_definitions(-DBH_PLATFORM_DARWIN)
endif ()
# Reset default linker flags
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
# WAMR features switch
# Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
if (NOT DEFINED WAMR_BUILD_TARGET)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
set (WAMR_BUILD_TARGET "AARCH64")
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
set (WAMR_BUILD_TARGET "RISCV64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform
set (WAMR_BUILD_TARGET "X86_64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
# Build as X86_32 by default in 32-bit platform
set (WAMR_BUILD_TARGET "X86_32")
else ()
message(SEND_ERROR "Unsupported build target platform!")
endif ()
endif ()
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release)
endif ()
set (WAMR_BUILD_INTERP 1)
set (WAMR_BUILD_AOT 1)
set (WAMR_BUILD_JIT 0)
set (WAMR_BUILD_LIBC_BUILTIN 1)
if (NOT MSVC)
set (WAMR_BUILD_LIBC_WASI 1)
endif ()
if (NOT MSVC)
# linker flags
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie -fPIE")
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
endif ()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
endif ()
endif ()
endif ()
# build out vmlib
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../..)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
################ application related ################
include_directories(${CMAKE_CURRENT_LIST_DIR})
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
add_executable (iwasm main.c ${UNCOMMON_SHARED_SOURCE})
if (APPLE)
target_link_libraries (iwasm vmlib -lm -ldl -lpthread)
else ()
target_link_libraries (iwasm vmlib -lm -ldl -lpthread -lrt)
endif ()

117
samples/file/src/main.c Normal file
View File

@ -0,0 +1,117 @@
/*
* Copyright (C) 2022 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "wasm_export.h"
#include "bh_read_file.h"
void
print_usage(void)
{
fprintf(stdout, "Required arguments:\r\n");
fprintf(stdout, " -f [path of wasm file] \n");
fprintf(stdout, " -d [path of host directory] \n");
}
int
main(int argc, char *argv_main[])
{
static char global_heap_buf[512 * 1024];
char *buffer, error_buf[128];
const char *wasm_path = NULL, *wasi_dir = NULL;
int opt;
wasm_module_t module = NULL;
wasm_module_inst_t module_inst = NULL;
wasm_exec_env_t exec_env = NULL;
uint32 buf_size, stack_size = 8092, heap_size = 8092;
uint32_t wasm_buffer = 0;
RuntimeInitArgs init_args;
memset(&init_args, 0, sizeof(RuntimeInitArgs));
while ((opt = getopt(argc, argv_main, "hf:d:")) != -1) {
switch (opt) {
case 'f':
wasm_path = optarg;
break;
case 'd':
wasi_dir = optarg;
break;
case 'h':
print_usage();
return 0;
case '?':
print_usage();
return 0;
}
}
if (wasm_path == NULL || wasi_dir == NULL) {
print_usage();
return 0;
}
init_args.mem_alloc_type = Alloc_With_Pool;
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
if (!wasm_runtime_full_init(&init_args)) {
printf("Init runtime environment failed.\n");
return -1;
}
buffer = bh_read_file_to_buffer(wasm_path, &buf_size);
if (!buffer) {
printf("Open wasm app file [%s] failed.\n", wasm_path);
goto fail;
}
module = wasm_runtime_load(buffer, buf_size, error_buf, sizeof(error_buf));
if (!module) {
printf("Load wasm module failed. error: %s\n", error_buf);
goto fail;
}
wasm_runtime_set_wasi_args_ex(module, &wasi_dir, 1, NULL, 0, NULL, 0, NULL,
0, 0, 1, 2);
module_inst = wasm_runtime_instantiate(module, stack_size, heap_size,
error_buf, sizeof(error_buf));
if (!module_inst) {
printf("Instantiate wasm module failed. error: %s\n", error_buf);
goto fail;
}
exec_env = wasm_runtime_create_exec_env(module_inst, stack_size);
if (!exec_env) {
printf("Create wasm execution environment failed.\n");
goto fail;
}
if (wasm_application_execute_main(module_inst, 0, NULL)) {
printf("Main wasm function successfully finished.\n");
}
else {
printf("call wasm function main failed. error: %s\n",
wasm_runtime_get_exception(module_inst));
goto fail;
}
fail:
if (exec_env)
wasm_runtime_destroy_exec_env(exec_env);
if (module_inst) {
if (wasm_buffer)
wasm_runtime_module_free(module_inst, wasm_buffer);
wasm_runtime_deinstantiate(module_inst);
}
if (module)
wasm_runtime_unload(module);
if (buffer)
BH_FREE(buffer);
wasm_runtime_destroy();
return 0;
}

View File

@ -0,0 +1,26 @@
# Copyright (C) 2022 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 3.0)
project(wasm-app)
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
if (APPLE)
set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
set (CMAKE_C_LINK_FLAGS "")
set (CMAKE_CXX_LINK_FLAGS "")
endif ()
set (CMAKE_SYSTEM_PROCESSOR wasm32)
if (NOT DEFINED WASI_SDK_DIR)
set (WASI_SDK_DIR "/opt/wasi-sdk")
endif ()
set (CMAKE_C_COMPILER_TARGET "wasm32-wasi")
set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wno-unused-command-line-argument")
add_executable(file.wasm main.c)
target_link_libraries(file.wasm)

View File

@ -0,0 +1,132 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#define PATH_TEST_FILE "test.txt"
#define FILE_TEXT "Hello, world!"
#define WORLD_OFFSET 7
#define NAME_REPLACMENT "James"
#define NAME_REPLACMENT_LEN (sizeof(NAME_REPLACMENT) - 1)
#define ADDITIONAL_SPACE 10
int
main(int argc, char **argv)
{
FILE *file;
const char *text = FILE_TEXT;
char buffer[1000];
int ret;
// Test: File opening (fopen)
printf("Opening a file..\n");
file = fopen(PATH_TEST_FILE, "w+");
if (file == NULL) {
printf("Error! errno: %d\n", errno);
}
assert(file != NULL);
printf("[Test] File opening passed.\n");
// Test: Writing to a file (fprintf)
printf("Writing to the file..\n");
ret = fprintf(file, "%s", text);
assert(ret == strlen(text));
printf("[Test] File writing passed.\n");
// Test: Reading from a file (fseek)
printf("Moving the cursor to the start of the file..\n");
ret = fseek(file, 0, SEEK_SET);
assert(ret == 0);
printf("Reading from the file, up to 1000 characters..\n");
fread(buffer, 1, sizeof(buffer), file);
printf("Text read: %s\n", buffer);
assert(strncmp(text, buffer, strlen(text)) == 0);
printf("[Test] File reading passed.\n");
// Test: end of file detection (feof)
printf("Determine whether we reach the end of the file..\n");
int is_end_of_file = feof(file);
printf("Is the end of file? %d\n", is_end_of_file);
assert(is_end_of_file == 1);
printf("[Test] End of file detection passed.\n");
// Test: retrieving file offset (ftell)
printf("Getting the plaintext size..\n");
long plaintext_size = ftell(file);
printf("The plaintext size is %ld.\n", plaintext_size);
assert(plaintext_size == 13);
printf("[Test] Retrieving file offset passed.\n");
// Test: persist changes on disk (fflush)
printf("Force actual write of all the cached data to the disk..\n");
ret = fflush(file);
assert(ret == 0);
printf("[Test] Retrieving file offset passed.\n");
// Test: writing at specified offset (pwrite)
printf("Writing 5 characters at offset %d..\n", WORLD_OFFSET);
ret = pwrite(fileno(file), NAME_REPLACMENT, NAME_REPLACMENT_LEN,
WORLD_OFFSET);
printf("File current offset: %ld\n", ftell(file));
assert(ret == NAME_REPLACMENT_LEN);
assert(ftell(file) == strlen(FILE_TEXT));
printf("[Test] Writing at specified offset passed.\n");
// Test: reading at specified offset (pread)
printf("Reading %ld characters at offset %d..\n", NAME_REPLACMENT_LEN,
WORLD_OFFSET);
buffer[NAME_REPLACMENT_LEN] = '\0';
pread(fileno(file), buffer, NAME_REPLACMENT_LEN, WORLD_OFFSET);
printf("Text read: %s\n", buffer);
printf("File current offset: %ld\n", ftell(file));
assert(strcmp(NAME_REPLACMENT, buffer) == 0);
assert(ftell(file) == strlen(FILE_TEXT));
printf("[Test] Reading at specified offset passed.\n");
// Test: allocate more space to the file (posix_fallocate)
printf("Allocate more space to the file..\n");
posix_fallocate(fileno(file), ftell(file), ADDITIONAL_SPACE);
printf("File current offset: %ld\n", ftell(file));
printf("Moving to the end..\n");
fseek(file, 0, SEEK_END);
printf("File current offset: %ld\n", ftell(file));
assert(ftell(file) == strlen(text) + ADDITIONAL_SPACE);
printf("[Test] Allocation or more space passed.\n");
// Test: allocate more space to the file (ftruncate)
printf("Extend the file size of 10 bytes using ftruncate..\n");
ftruncate(fileno(file), ftell(file) + 10);
assert(ftell(file) == strlen(text) + ADDITIONAL_SPACE);
printf("File current offset: %ld\n", ftell(file));
printf("Moving to the end..\n");
fseek(file, 0, SEEK_END);
printf("File current offset: %ld\n", ftell(file));
assert(ftell(file) == strlen(text) + 2 * ADDITIONAL_SPACE);
printf("[Test] Extension of the file size passed.\n");
// Test: closing the file (fclose)
printf("Closing from the file..\n");
ret = fclose(file);
assert(ret == 0);
printf("[Test] Closing file passed.\n");
// Display some debug information
printf("Getting the size of the file on disk..\n");
struct stat st;
stat(PATH_TEST_FILE, &st);
printf("The file size is %lld.\n", st.st_size);
printf("All the tests passed!\n");
return 0;
}

View File

@ -87,6 +87,7 @@ ExternalProject_Add(wasm-app
${CMAKE_CURRENT_SOURCE_DIR}/wasm-src ${CMAKE_CURRENT_SOURCE_DIR}/wasm-src
BUILD_COMMAND ${CMAKE_COMMAND} --build . BUILD_COMMAND ${CMAKE_COMMAND} --build .
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy INSTALL_COMMAND ${CMAKE_COMMAND} -E copy
addr_resolve.wasm ${CMAKE_BINARY_DIR}
tcp_client.wasm ${CMAKE_BINARY_DIR} tcp_client.wasm ${CMAKE_BINARY_DIR}
tcp_server.wasm ${CMAKE_BINARY_DIR} tcp_server.wasm ${CMAKE_BINARY_DIR}
send_recv.wasm ${CMAKE_BINARY_DIR} send_recv.wasm ${CMAKE_BINARY_DIR}

View File

@ -18,14 +18,21 @@ cmake ..
make make
``` ```
`iwasm` and three Wasm modules, `tcp_server.wasm`, `tcp_client.wasm`, `send_recv.wasm` `iwasm` and the following Wasm modules (along with their corresponding native version) will be generated:
will be generated. And their corresponding native version, `tcp_server`, * `addr_resolve.wasm`, `addr_resolve`
`tcp_client`, `send_recv` are generated too. * `send_recv.wasm`, `send_recv`
* `socket_opts.wasm`, `socket_opts`
* `tcp_client.wasm`, `tcp_client`
* `tcp_server.wasm`, `tcp_server`
* `udp_client.wasm`, `udp_client`
* `udp_server.wasm`, `udp_server`
> Note that iwasm is built with libc-wasi and lib-pthread enabled. > Note that iwasm is built with libc-wasi and lib-pthread enabled.
## Run workload ## Run workload
### TCP client/server
Start the tcp server, which opens port 1234 and waits for clients to connect. Start the tcp server, which opens port 1234 and waits for clients to connect.
```bash ```bash
@ -82,6 +89,8 @@ Data:
And mourns for us And mourns for us
``` ```
### Socket options
`socket_opts.wasm` shows an example of getting and setting various supported socket options `socket_opts.wasm` shows an example of getting and setting various supported socket options
```bash ```bash
$ ./iwasm ./socket_opts.wasm $ ./iwasm ./socket_opts.wasm
@ -98,4 +107,53 @@ SO_RCVTIMEO tv_usec is expected
[Client] Close sockets [Client] Close sockets
``` ```
### Domain name server resolution
`addr_resolve.wasm` demonstrates the usage of resolving a domain name
```
$ ./iwasm --allow-resolve=*.com addr_resolve.wasm github.com
```
The command displays the host name and its corresponding IP address:
```
Host: github.com
IPv4 address: 140.82.121.4 (TCP)
```
### UDP client/server
Start the UDP server, which opens port 1234 and waits for clients to send a message.
```bash
cd build
./iwasm --addr-pool=0.0.0.0/15 udp_server.wasm
```
Start the tcp client, which sends a message to the server and waits for the response.
```bash
cd build
./iwasm --addr-pool=127.0.0.1/15 udp_client.wasm
```
The output of client is like:
```bash
[Client] Create socket
[Client] Client send
[Client] Client receive
[Client] Buffer recieved: Hello from server
[Client] BYE
```
The output of the server is like:
```
[Server] Create socket
[Server] Bind socket
[Server] Wait for clients to connect ..
[Server] received 17 bytes from 127.0.0.1:60927: Hello from client
```
## Documentation
Refer to [socket api document](../../doc/socket_api.md) for more details. Refer to [socket api document](../../doc/socket_api.md) for more details.

View File

@ -31,10 +31,18 @@ int
set_and_get_bool_opt(int socket_fd, int level, int optname, int val) set_and_get_bool_opt(int socket_fd, int level, int optname, int val)
{ {
int bool_opt = val; int bool_opt = val;
int ret = -1;
socklen_t opt_len = sizeof(bool_opt); socklen_t opt_len = sizeof(bool_opt);
setsockopt(socket_fd, level, optname, &bool_opt, sizeof(bool_opt));
ret = setsockopt(socket_fd, level, optname, &bool_opt, sizeof(bool_opt));
if (ret != 0)
return !val;
bool_opt = !bool_opt; bool_opt = !bool_opt;
getsockopt(socket_fd, level, optname, &bool_opt, &opt_len); ret = getsockopt(socket_fd, level, optname, &bool_opt, &opt_len);
if (ret != 0)
return !val;
return bool_opt; return bool_opt;
} }
@ -77,36 +85,54 @@ main(int argc, char *argv[])
// SO_RCVTIMEO // SO_RCVTIMEO
tv = to_timeval(123, 1000); tv = to_timeval(123, 1000);
result =
setsockopt(tcp_socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); setsockopt(tcp_socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
OPTION_ASSERT(result, 0, "setsockopt SO_RCVTIMEO result")
tv = to_timeval(0, 0); tv = to_timeval(0, 0);
opt_len = sizeof(tv); opt_len = sizeof(tv);
getsockopt(tcp_socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &opt_len); result = getsockopt(tcp_socket_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, &opt_len);
OPTION_ASSERT(result, 0, "getsockopt SO_RCVTIMEO result")
OPTION_ASSERT(tv.tv_sec, 123, "SO_RCVTIMEO tv_sec"); OPTION_ASSERT(tv.tv_sec, 123, "SO_RCVTIMEO tv_sec");
OPTION_ASSERT(tv.tv_usec, 1000, "SO_RCVTIMEO tv_usec"); // OPTION_ASSERT(tv.tv_usec, 1000, "SO_RCVTIMEO tv_usec");
// SO_SNDTIMEO // SO_SNDTIMEO
tv = to_timeval(456, 2000); tv = to_timeval(456, 2000);
result =
setsockopt(tcp_socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); setsockopt(tcp_socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
OPTION_ASSERT(result, 0, "setsockopt SO_SNDTIMEO result")
tv = to_timeval(0, 0); tv = to_timeval(0, 0);
opt_len = sizeof(tv); opt_len = sizeof(tv);
getsockopt(tcp_socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &opt_len); result = getsockopt(tcp_socket_fd, SOL_SOCKET, SO_SNDTIMEO, &tv, &opt_len);
OPTION_ASSERT(result, 0, "getsockopt SO_SNDTIMEO result")
OPTION_ASSERT(tv.tv_sec, 456, "SO_SNDTIMEO tv_sec"); OPTION_ASSERT(tv.tv_sec, 456, "SO_SNDTIMEO tv_sec");
OPTION_ASSERT(tv.tv_usec, 2000, "SO_SNDTIMEO tv_usec"); // OPTION_ASSERT(tv.tv_usec, 2000, "SO_SNDTIMEO tv_usec");
// SO_SNDBUF // SO_SNDBUF
buf_len = 8192; buf_len = 8192;
setsockopt(tcp_socket_fd, SOL_SOCKET, SO_SNDBUF, &buf_len, sizeof(buf_len)); result = setsockopt(tcp_socket_fd, SOL_SOCKET, SO_SNDBUF, &buf_len,
sizeof(buf_len));
OPTION_ASSERT(result, 0, "setsockopt SO_SNDBUF result")
buf_len = 0; buf_len = 0;
opt_len = sizeof(buf_len); opt_len = sizeof(buf_len);
result =
getsockopt(tcp_socket_fd, SOL_SOCKET, SO_SNDBUF, &buf_len, &opt_len); getsockopt(tcp_socket_fd, SOL_SOCKET, SO_SNDBUF, &buf_len, &opt_len);
OPTION_ASSERT(result, 0, "getsockopt SO_SNDBUF result")
OPTION_ASSERT(buf_len, 16384, "SO_SNDBUF buf_len"); OPTION_ASSERT(buf_len, 16384, "SO_SNDBUF buf_len");
// SO_RCVBUF // SO_RCVBUF
buf_len = 4096; buf_len = 4096;
setsockopt(tcp_socket_fd, SOL_SOCKET, SO_RCVBUF, &buf_len, sizeof(buf_len)); result = setsockopt(tcp_socket_fd, SOL_SOCKET, SO_RCVBUF, &buf_len,
sizeof(buf_len));
OPTION_ASSERT(result, 0, "setsockopt SO_RCVBUF result")
buf_len = 0; buf_len = 0;
opt_len = sizeof(buf_len); opt_len = sizeof(buf_len);
result =
getsockopt(tcp_socket_fd, SOL_SOCKET, SO_RCVBUF, &buf_len, &opt_len); getsockopt(tcp_socket_fd, SOL_SOCKET, SO_RCVBUF, &buf_len, &opt_len);
OPTION_ASSERT(result, 0, "getsockopt SO_RCVBUF result")
OPTION_ASSERT(buf_len, 8192, "SO_RCVBUF buf_len"); OPTION_ASSERT(buf_len, 8192, "SO_RCVBUF buf_len");
// SO_KEEPALIVE // SO_KEEPALIVE
@ -136,12 +162,16 @@ main(int argc, char *argv[])
// SO_LINGER // SO_LINGER
linger_opt.l_onoff = 1; linger_opt.l_onoff = 1;
linger_opt.l_linger = 10; linger_opt.l_linger = 10;
setsockopt(tcp_socket_fd, SOL_SOCKET, SO_LINGER, &linger_opt, result = setsockopt(tcp_socket_fd, SOL_SOCKET, SO_LINGER, &linger_opt,
sizeof(linger_opt)); sizeof(linger_opt));
OPTION_ASSERT(result, 0, "setsockopt SO_LINGER result")
linger_opt.l_onoff = 0; linger_opt.l_onoff = 0;
linger_opt.l_linger = 0; linger_opt.l_linger = 0;
opt_len = sizeof(linger_opt); opt_len = sizeof(linger_opt);
result =
getsockopt(tcp_socket_fd, SOL_SOCKET, SO_LINGER, &linger_opt, &opt_len); getsockopt(tcp_socket_fd, SOL_SOCKET, SO_LINGER, &linger_opt, &opt_len);
OPTION_ASSERT(result, 0, "getsockopt SO_LINGER result")
OPTION_ASSERT(linger_opt.l_onoff, 1, "SO_LINGER l_onoff"); OPTION_ASSERT(linger_opt.l_onoff, 1, "SO_LINGER l_onoff");
OPTION_ASSERT(linger_opt.l_linger, 10, "SO_LINGER l_linger"); OPTION_ASSERT(linger_opt.l_linger, 10, "SO_LINGER l_linger");
@ -155,20 +185,28 @@ main(int argc, char *argv[])
// TCP_KEEPIDLE // TCP_KEEPIDLE
time_s = 16; time_s = 16;
setsockopt(tcp_socket_fd, IPPROTO_TCP, TCP_KEEPIDLE, &time_s, result = setsockopt(tcp_socket_fd, IPPROTO_TCP, TCP_KEEPIDLE, &time_s,
sizeof(time_s)); sizeof(time_s));
OPTION_ASSERT(result, 0, "setsockopt TCP_KEEPIDLE result")
time_s = 0; time_s = 0;
opt_len = sizeof(time_s); opt_len = sizeof(time_s);
result =
getsockopt(tcp_socket_fd, IPPROTO_TCP, TCP_KEEPIDLE, &time_s, &opt_len); getsockopt(tcp_socket_fd, IPPROTO_TCP, TCP_KEEPIDLE, &time_s, &opt_len);
OPTION_ASSERT(result, 0, "getsockopt TCP_KEEPIDLE result")
OPTION_ASSERT(time_s, 16, "TCP_KEEPIDLE"); OPTION_ASSERT(time_s, 16, "TCP_KEEPIDLE");
// TCP_KEEPINTVL // TCP_KEEPINTVL
time_s = 8; time_s = 8;
setsockopt(tcp_socket_fd, IPPROTO_TCP, TCP_KEEPINTVL, &time_s, result = setsockopt(tcp_socket_fd, IPPROTO_TCP, TCP_KEEPINTVL, &time_s,
sizeof(time_s)); sizeof(time_s));
OPTION_ASSERT(result, 0, "setsockopt TCP_KEEPINTVL result")
time_s = 0; time_s = 0;
opt_len = sizeof(time_s); opt_len = sizeof(time_s);
getsockopt(tcp_socket_fd, IPPROTO_TCP, TCP_KEEPINTVL, &time_s, &opt_len); result = getsockopt(tcp_socket_fd, IPPROTO_TCP, TCP_KEEPINTVL, &time_s,
&opt_len);
OPTION_ASSERT(result, 0, "getsockopt TCP_KEEPINTVL result")
OPTION_ASSERT(time_s, 8, "TCP_KEEPINTVL"); OPTION_ASSERT(time_s, 8, "TCP_KEEPINTVL");
// TCP_FASTOPEN_CONNECT // TCP_FASTOPEN_CONNECT
@ -197,11 +235,13 @@ main(int argc, char *argv[])
// IP_TTL // IP_TTL
ttl = 8; ttl = 8;
setsockopt(tcp_socket_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)); result = setsockopt(tcp_socket_fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
OPTION_ASSERT(result, 0, "IP_TIL");
ttl = 0; ttl = 0;
opt_len = sizeof(ttl); opt_len = sizeof(ttl);
getsockopt(tcp_socket_fd, IPPROTO_IP, IP_TTL, &ttl, &opt_len); result = getsockopt(tcp_socket_fd, IPPROTO_IP, IP_TTL, &ttl, &opt_len);
OPTION_ASSERT(ttl, 8, "IP_TTL"); OPTION_ASSERT(ttl, 8, "IP_TTL");
OPTION_ASSERT(result, 0, "IP_TIL");
// IPV6_V6ONLY // IPV6_V6ONLY
OPTION_ASSERT( OPTION_ASSERT(
@ -233,11 +273,15 @@ main(int argc, char *argv[])
// IP_MULTICAST_TTL // IP_MULTICAST_TTL
ttl = 8; ttl = 8;
setsockopt(udp_socket_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); result = setsockopt(udp_socket_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
sizeof(ttl));
OPTION_ASSERT(result, 0, "IP_MULTICAST_TTL");
ttl = 0; ttl = 0;
opt_len = sizeof(ttl); opt_len = sizeof(ttl);
result =
getsockopt(udp_socket_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, &opt_len); getsockopt(udp_socket_fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, &opt_len);
OPTION_ASSERT(ttl, 8, "IP_MULTICAST_TTL"); OPTION_ASSERT(ttl, 8, "IP_MULTICAST_TTL");
OPTION_ASSERT(result, 0, "IP_MULTICAST_TTL");
// IPV6_MULTICAST_LOOP // IPV6_MULTICAST_LOOP
OPTION_ASSERT(set_and_get_bool_opt(udp_ipv6_socket_fd, IPPROTO_IPV6, OPTION_ASSERT(set_and_get_bool_opt(udp_ipv6_socket_fd, IPPROTO_IPV6,
@ -248,12 +292,14 @@ main(int argc, char *argv[])
0, "IPV6_MULTICAST_LOOP disabled"); 0, "IPV6_MULTICAST_LOOP disabled");
// IPV6_JOIN_GROUP // IPV6_JOIN_GROUP
setsockopt(udp_ipv6_socket_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mcast_ipv6, result = setsockopt(udp_ipv6_socket_fd, IPPROTO_IPV6, IPV6_JOIN_GROUP,
sizeof(mcast_ipv6)); &mcast_ipv6, sizeof(mcast_ipv6));
// OPTION_ASSERT(result, 0, "IPV6_JOIN_GROUP");
// IPV6_LEAVE_GROUP // IPV6_LEAVE_GROUP
setsockopt(udp_ipv6_socket_fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mcast_ipv6, result = setsockopt(udp_ipv6_socket_fd, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
sizeof(mcast_ipv6)); &mcast_ipv6, sizeof(mcast_ipv6));
// OPTION_ASSERT(result, 0, "IPV6_LEAVE_GROUP");
printf("[Client] Close sockets\n"); printf("[Client] Close sockets\n");
close(tcp_socket_fd); close(tcp_socket_fd);

View File

@ -69,10 +69,12 @@ main(int argc, char *argv[])
printf("[Client] Client receive\n"); printf("[Client] Client receive\n");
serverlen = sizeof(server_address); serverlen = sizeof(server_address);
ret = recvfrom(socket_fd, buffer, sizeof(buffer), 0, /* make sure there is space for the string terminator */
ret = recvfrom(socket_fd, buffer, sizeof(buffer) - 1, 0,
(struct sockaddr *)&server_address, &serverlen); (struct sockaddr *)&server_address, &serverlen);
if (ret > 0) { if (ret > 0) {
buffer[ret] = '\0';
printf("[Client] Buffer recieved: %s\n", buffer); printf("[Client] Buffer recieved: %s\n", buffer);
} }

View File

@ -43,8 +43,8 @@ main(int argc, char *argv[])
struct sockaddr_storage addr = { 0 }; struct sockaddr_storage addr = { 0 };
char *reply_message = "Hello from server"; char *reply_message = "Hello from server";
unsigned connections = 0; unsigned connections = 0;
char ip_string[64]; char ip_string[64] = { 0 };
char buffer[1024]; char buffer[1024] = { 0 };
if (argc > 1 && strcmp(argv[1], "inet6") == 0) { if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
af = AF_INET6; af = AF_INET6;
@ -73,12 +73,14 @@ main(int argc, char *argv[])
printf("[Server] Wait for clients to connect ..\n"); printf("[Server] Wait for clients to connect ..\n");
while (connections < MAX_CONNECTIONS_COUNT) { while (connections < MAX_CONNECTIONS_COUNT) {
addrlen = sizeof(addr); addrlen = sizeof(addr);
int ret = recvfrom(socket_fd, buffer, sizeof(buffer), 0, /* make sure there is space for the string terminator */
int ret = recvfrom(socket_fd, buffer, sizeof(buffer) - 1, 0,
(struct sockaddr *)&addr, &addrlen); (struct sockaddr *)&addr, &addrlen);
if (ret < 0) { if (ret < 0) {
perror("Read failed"); perror("Read failed");
goto fail; goto fail;
} }
buffer[ret] = '\0';
if (sockaddr_to_string((struct sockaddr *)&addr, ip_string, if (sockaddr_to_string((struct sockaddr *)&addr, ip_string,
sizeof(ip_string) / sizeof(ip_string[0])) sizeof(ip_string) / sizeof(ip_string[0]))

View File

@ -13,7 +13,7 @@ readonly VARIANT=$(lsb_release -c | awk '{print $2}')
docker build \ docker build \
--build-arg VARIANT=${VARIANT} \ --build-arg VARIANT=${VARIANT} \
--memory 4G --cpu-quota 50000 \ --memory 4G --cpu-quota 50000 \
-t wamr_dev_${VARIANT}:0.1 -f "${ROOT}"/ci/Dockerfile "${ROOT}"/ci && -t wamr_dev_${VARIANT}:0.1 -f "${ROOT}"/.devcontainer/Dockerfile "${ROOT}"/.devcontainer &&
docker run --rm -it \ docker run --rm -it \
--memory 4G \ --memory 4G \
--cpus ".5" \ --cpus ".5" \

View File

@ -1,9 +1,9 @@
FROM python:3.5 FROM python:3.5
WORKDIR /app WORKDIR /app
ADD . /app COPY . /app
RUN pip install django # hadolint ignore=DL3013
RUN pip install django --no-cache-dir
ENTRYPOINT ["python", "manage.py", "runserver", "0.0.0.0:80"] ENTRYPOINT ["python", "manage.py", "runserver", "0.0.0.0:80"]

View File

@ -268,6 +268,6 @@ def removeapps(req):
return render(req, 'appstore.html', {'alist': json.dumps(avaliable_list),'flist': json.dumps(user_file_list)}) return render(req, 'appstore.html', {'alist': json.dumps(avaliable_list),'flist': json.dumps(user_file_list)})
# Test # Test
if __name__ == "__main__": # if __name__ == "__main__":
print(device_list[0]['IP']) # print(device_list[0]['IP'])
print(device['IP']) # print(device['IP'])

View File

@ -1,6 +1,6 @@
FROM python:3.5 FROM python:3.5
WORKDIR /app WORKDIR /app
ADD server/wasm_server.py /app/server/ COPY server/wasm_server.py /app/server/
ENTRYPOINT ["python", "server/wasm_server.py"] ENTRYPOINT ["python", "server/wasm_server.py"]

View File

@ -1,3 +1,4 @@
from __future__ import print_function
# #
# Copyright (C) 2019 Intel Corporation. All rights reserved. # Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@ -28,7 +29,7 @@ def read_cases_from_file(file_path):
content = f.readlines() content = f.readlines()
content = [x.strip() for x in content] content = [x.strip() for x in content]
print content print(content)
if len(content) == 0: if len(content) == 0:
return False, None return False, None

View File

@ -1,3 +1,4 @@
from __future__ import print_function
# #
# Copyright (C) 2019 Intel Corporation. All rights reserved. # Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@ -66,7 +67,7 @@ class CTestFramework(object):
api_set_root_path(path) api_set_root_path(path)
print "root_path is " + self.root_path print("root_path is " + self.root_path)
def gen_execution_stats(self): def gen_execution_stats(self):
return '\nTest Execution Summary: ' \ return '\nTest Execution Summary: ' \
@ -103,7 +104,7 @@ class CTestFramework(object):
module_name = 'suites.' + suite + ".cases." + case + ".case" module_name = 'suites.' + suite + ".cases." + case + ".case"
try: try:
module = my_import(module_name) module = my_import(module_name)
except Exception, e: except Exception as e:
report_fail("load case fail: " + str(e)) report_fail("load case fail: " + str(e))
api_log_error("load case fail: " + str(e)) api_log_error("load case fail: " + str(e))
self.load_fails = self.load_fails +1 self.load_fails = self.load_fails +1
@ -112,7 +113,7 @@ class CTestFramework(object):
try: try:
case = module.CTestCase(suite_instance) case = module.CTestCase(suite_instance)
except Exception, e: except Exception as e:
report_fail("initialize case fail: " + str(e)) report_fail("initialize case fail: " + str(e))
api_log_error("initialize case fail: " + str(e)) api_log_error("initialize case fail: " + str(e))
self.load_fails = self.load_fails +1 self.load_fails = self.load_fails +1
@ -122,7 +123,7 @@ class CTestFramework(object):
try: try:
case_description = case.on_get_case_description() case_description = case.on_get_case_description()
result, message = case.on_setup_case() result, message = case.on_setup_case()
except Exception, e: except Exception as e:
result = False result = False
message = str(e); message = str(e);
if not result: if not result:
@ -134,7 +135,7 @@ class CTestFramework(object):
# call the case execution callaback # call the case execution callaback
try: try:
result, message = case.on_run_case() result, message = case.on_run_case()
except Exception, e: except Exception as e:
result = False result = False
message = str(e); message = str(e);
if not result: if not result:
@ -148,7 +149,7 @@ class CTestFramework(object):
# call the case cleanup callback # call the case cleanup callback
try: try:
clean_result, message = case.on_cleanup_case() clean_result, message = case.on_cleanup_case()
except Exception, e: except Exception as e:
clean_result = False clean_result = False
message = str(e) message = str(e)
@ -166,7 +167,7 @@ class CTestFramework(object):
module_name = 'suites.' + suite + ".suite_setup" module_name = 'suites.' + suite + ".suite_setup"
try: try:
module = my_import(module_name) module = my_import(module_name)
except Exception, e: except Exception as e:
report_fail("load suite [" + suite +"] fail: " + str(e)) report_fail("load suite [" + suite +"] fail: " + str(e))
self.load_fails = self.load_fails +1 self.load_fails = self.load_fails +1
return False return False
@ -174,7 +175,7 @@ class CTestFramework(object):
try: try:
suite_instance = module.CTestSuite(suite, \ suite_instance = module.CTestSuite(suite, \
self.root_path + '/suites/' + suite, running_folder) self.root_path + '/suites/' + suite, running_folder)
except Exception, e: except Exception as e:
report_fail("initialize suite fail: " + str(e)) report_fail("initialize suite fail: " + str(e))
self.load_fails = self.load_fails +1 self.load_fails = self.load_fails +1
return False return False
@ -187,7 +188,7 @@ class CTestFramework(object):
try: try:
result, message = suite_instance.on_suite_setup() result, message = suite_instance.on_suite_setup()
except Exception, e: except Exception as e:
result = False result = False
message = str(e); message = str(e);
if not result: if not result:
@ -213,7 +214,7 @@ class CTestFramework(object):
self.running_suite = '' self.running_suite = ''
try: try:
result, message = suite_instance.on_suite_cleanup() result, message = suite_instance.on_suite_cleanup()
except Exception, e: except Exception as e:
result = False result = False
message = str(e); message = str(e);
if not result: if not result:
@ -224,7 +225,7 @@ class CTestFramework(object):
def start_run(self): def start_run(self):
if self.target_suites is None: if self.target_suites is None:
print "\n\nstart run: no target suites, exit.." print("\n\nstart run: no target suites, exit..")
return return
cur_time = time.localtime() cur_time = time.localtime()
@ -268,7 +269,7 @@ class CTestFramework(object):
self.report.write(summary); self.report.write(summary);
self.report.flush() self.report.flush()
self.report.close() self.report.close()
print summary print(summary)
def report_fail(message, case_description=''): def report_fail(message, case_description=''):

View File

@ -1,3 +1,4 @@
from __future__ import print_function
# #
# Copyright (C) 2019 Intel Corporation. All rights reserved. # Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@ -12,7 +13,7 @@ logger = None
def api_init_log(log_path): def api_init_log(log_path):
global logger global logger
print "api_init_log: " + log_path print("api_init_log: " + log_path)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logger.setLevel(level = logging.INFO) logger.setLevel(level = logging.INFO)
@ -32,7 +33,7 @@ def api_init_log(log_path):
def api_log(message): def api_log(message):
global logger global logger
if logger is None: if logger is None:
print message print(message)
else: else:
logger.info (message) logger.info (message)
return return
@ -40,7 +41,7 @@ def api_log(message):
def api_log_error(message): def api_log_error(message):
global logger global logger
if logger is None: if logger is None:
print message print(message)
else: else:
logger.error (message) logger.error (message)
return return
@ -48,7 +49,7 @@ def api_log_error(message):
def api_logv(message): def api_logv(message):
global logger global logger
if logger is None: if logger is None:
print message print(message)
else: else:
logger.info(message) logger.info(message)
return return

View File

@ -1,3 +1,4 @@
from __future__ import print_function
# #
# Copyright (C) 2019 Intel Corporation. All rights reserved. # Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@ -52,7 +53,7 @@ def t_process_exists(proc, kill = 0):
if kill == 0: if kill == 0:
return True return True
else: else:
print "kill [" + proc + "], pid=" + str(pid) print("kill [" + proc + "], pid=" + str(pid))
os.kill((pid), 9) os.kill((pid), 9)
ret = True ret = True
return ret return ret
@ -60,11 +61,11 @@ def t_process_exists(proc, kill = 0):
def t_copy_files(source_dir, pattern, dest_dir): def t_copy_files(source_dir, pattern, dest_dir):
files = os.listdir(source_dir) files = os.listdir(source_dir)
for file in files: for file in files:
if file is '/' or file is '.' or file is '..': if file in ('/', '.', '..'):
continue continue
if pattern == '*' or pattern is '' or files.endswith(pattern): if pattern in ('*', '') or files.endswith(pattern):
shutil.copy(source_dir+"/"+ file,dest_dir) shutil.copy(source_dir+"/"+ file, dest_dir)

View File

@ -10,6 +10,7 @@
It is the entrance of the iagent test framework. It is the entrance of the iagent test framework.
""" """
from __future__ import print_function
import argparse import argparse
import datetime import datetime
@ -84,9 +85,9 @@ if __name__ == "__main__":
help = 'rebuild all test binaries') help = 'rebuild all test binaries')
args = parser.parse_args() args = parser.parse_args()
print "------------------------------------------------------------" print("------------------------------------------------------------")
print "parsing arguments ... ..." print("parsing arguments ... ...")
print args print(args)
''' '''
logger = logging.getLogger('coapthon.server.coap') logger = logging.getLogger('coapthon.server.coap')
@ -95,8 +96,8 @@ if __name__ == "__main__":
console.setLevel(logging.DEBUG) console.setLevel(logging.DEBUG)
logger.addHandler(console) logger.addHandler(console)
''' '''
print "------------------------------------------------------------" print("------------------------------------------------------------")
print "preparing wamr binary and test tools ... ..." print("preparing wamr binary and test tools ... ...")
os.system("cd ../../samples/simple/ && bash build.sh -p host-interp") os.system("cd ../../samples/simple/ && bash build.sh -p host-interp")
Register_signal_handler() Register_signal_handler()
@ -124,9 +125,9 @@ if __name__ == "__main__":
if binary_path is None: if binary_path is None:
binary_path = os.path.abspath(dirname + '/../..') binary_path = os.path.abspath(dirname + '/../..')
print "checking execution binary path: " + binary_path print("checking execution binary path: " + binary_path)
if not os.path.exists(binary_path): if not os.path.exists(binary_path):
print "The execution binary path was not available. quit..." print("The execution binary path was not available. quit...")
os._exit(0) os._exit(0)
api_set_value('binary_path', binary_path) api_set_value('binary_path', binary_path)
@ -138,11 +139,11 @@ if __name__ == "__main__":
framework.target_cases = cases_list framework.target_cases = cases_list
framework.start_run() framework.start_run()
print "\n\n------------------------------------------------------------" print("\n\n------------------------------------------------------------")
print "The run folder is [" + framework.running_folder +"]" print("The run folder is [" + framework.running_folder +"]")
print "that's all. bye" print("that's all. bye")
print "kill to quit.." print("kill to quit..")
t_kill_process_by_name("start.py") t_kill_process_by_name("start.py")
sys.exit(0) sys.exit(0)

View File

@ -8,18 +8,20 @@ WORKDIR /root/
COPY resource /root/ COPY resource /root/
## - download cmake with wget and set up ## - download cmake with wget and set up
RUN wget https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1-linux-x86_64.tar.gz \ # hadolint ignore=DL3008
RUN wget --progress=dot:giga https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1-linux-x86_64.tar.gz \
&& tar -zxvf cmake-3.21.1-linux-x86_64.tar.gz \ && tar -zxvf cmake-3.21.1-linux-x86_64.tar.gz \
&& rm -f cmake-3.21.1-linux-x86_64.tar.gz \ && rm -f cmake-3.21.1-linux-x86_64.tar.gz \
&& mv cmake-3.21.1-linux-x86_64 /opt/cmake \ && mv cmake-3.21.1-linux-x86_64 /opt/cmake \
&& ln -s /opt/cmake/bin/cmake /bin/cmake \ && ln -s /opt/cmake/bin/cmake /bin/cmake \
&& apt-get install make && apt-get -y install make --no-install-recommends
## -clone wamr-repo and build iwasm ## -clone wamr-repo and build iwasm
RUN git clone -b main --depth=1 https://github.com/bytecodealliance/wasm-micro-runtime.git \ RUN git clone -b main --depth=1 https://github.com/bytecodealliance/wasm-micro-runtime.git \
&& cd /root/wasm-micro-runtime/product-mini/platforms/linux \ && mkdir -p /root/wasm-micro-runtime/product-mini/platforms/linux/build
&& mkdir build && cd build \
&& cmake .. -DWAMR_BUILD_DEBUG_INTERP=1 && make \ WORKDIR /root/wasm-micro-runtime/product-mini/platforms/linux/build
RUN cmake .. -DWAMR_BUILD_DEBUG_INTERP=1 && make \
&& cp /root/wasm-micro-runtime/product-mini/platforms/linux/build/iwasm /root/iwasm \ && cp /root/wasm-micro-runtime/product-mini/platforms/linux/build/iwasm /root/iwasm \
&& rm -fr /root/wasm-micro-runtime && rm -fr /root/wasm-micro-runtime

View File

@ -10,12 +10,13 @@ WORKDIR /root/
COPY resource /root/ COPY resource /root/
## - download cmake with wget and set up ## - download cmake with wget and set up
RUN wget https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1-linux-x86_64.tar.gz \ # hadolint ignore=DL3008
RUN wget --progress=dot:giga https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1-linux-x86_64.tar.gz \
&& tar -zxvf cmake-3.21.1-linux-x86_64.tar.gz \ && tar -zxvf cmake-3.21.1-linux-x86_64.tar.gz \
&& rm -f cmake-3.21.1-linux-x86_64.tar.gz \ && rm -f cmake-3.21.1-linux-x86_64.tar.gz \
&& mv cmake-3.21.1-linux-x86_64 /opt/cmake \ && mv cmake-3.21.1-linux-x86_64 /opt/cmake \
&& ln -s /opt/cmake/bin/cmake /bin/cmake \ && ln -s /opt/cmake/bin/cmake /bin/cmake \
&& apt-get install make && apt-get -y install make --no-install-recommends
## set compilation environment for wamrc ## set compilation environment for wamrc
# - wamr repo # - wamr repo
@ -24,19 +25,20 @@ RUN wget https://github.com/Kitware/CMake/releases/download/v3.21.1/cmake-3.21.1
# - wamr-sdk # - wamr-sdk
## - download wasi-sdk with wget and set up to /opt/wasi-sdk ## - download wasi-sdk with wget and set up to /opt/wasi-sdk
RUN wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-14/wasi-sdk-14.0-linux.tar.gz \ RUN wget --progress=dot:giga https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-14/wasi-sdk-14.0-linux.tar.gz \
&& tar -zxvf wasi-sdk-14.0-linux.tar.gz \ && tar -zxvf wasi-sdk-14.0-linux.tar.gz \
&& mv wasi-sdk-14.0 /opt/wasi-sdk/ \ && mv wasi-sdk-14.0 /opt/wasi-sdk/ \
&& rm -f wasi-sdk-14.0-linux.tar.gz && rm -f wasi-sdk-14.0-linux.tar.gz
## - clone wamr repo ## - clone wamr repo
RUN git clone -b main --depth=1 https://github.com/bytecodealliance/wasm-micro-runtime.git \ RUN git clone -b main --depth=1 https://github.com/bytecodealliance/wasm-micro-runtime.git
&& cd /root/wasm-micro-runtime/wamr-compiler \
&& ./build_llvm.sh \ WORKDIR /root/wasm-micro-runtime/wamr-compiler
&& cd /root/wasm-micro-runtime/wamr-compiler \ RUN ./build_llvm.sh \
&& mkdir build \ && mkdir build
&& cd build \
&& cmake .. \ WORKDIR /root/wasm-micro-runtime/wamr-compiler/build
RUN cmake .. \
&& make \ && make \
# - copy the wamrc to /root # - copy the wamrc to /root
&& cp /root/wasm-micro-runtime/wamr-compiler/build/wamrc /root/wamrc \ && cp /root/wasm-micro-runtime/wamr-compiler/build/wamrc /root/wamrc \
@ -65,6 +67,9 @@ COPY --from=BASE /root/build_wasm.sh ${HOME_DIR}
RUN ln -s /opt/cmake/bin/cmake /usr/bin/cmake \ RUN ln -s /opt/cmake/bin/cmake /usr/bin/cmake \
&& ln -s ${HOME_DIR}/wamrc /usr/bin/wamrc && ln -s ${HOME_DIR}/wamrc /usr/bin/wamrc
RUN apt-get update && apt-get install make # hadolint ignore=DL3008
RUN apt-get update && apt-get install -y make --no-install-recommends \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
WORKDIR ${HOME_DIR} WORKDIR ${HOME_DIR}

View File

@ -2,6 +2,7 @@
from __future__ import print_function from __future__ import print_function
import os, sys, re import os, sys, re
from pickletools import long1
import argparse, time import argparse, time
import signal, atexit, tempfile, subprocess import signal, atexit, tempfile, subprocess
@ -17,7 +18,12 @@ import struct
import math import math
import traceback import traceback
IS_PY_3 = sys.version_info[0] == 3 try:
long
IS_PY_3 = False
except NameError:
long = int
IS_PY_3 = True
test_aot = False test_aot = False
# "x86_64", "i386", "aarch64", "armv7" or "thumbv7" # "x86_64", "i386", "aarch64", "armv7" or "thumbv7"
@ -312,7 +318,7 @@ def get_module_exp_from_assert(string):
def string_to_unsigned(number_in_string, lane_type): def string_to_unsigned(number_in_string, lane_type):
if not lane_type in ['i8x16', 'i16x8', 'i32x4', 'i64x2']: if not lane_type in ['i8x16', 'i16x8', 'i32x4', 'i64x2']:
raise Exception("invalid value {} and type {} and lane_type {}".format(numbers, type, lane_type)) raise Exception("invalid value {} and type {} and lane_type {}".format(number_in_string, type, lane_type))
number = int(number_in_string, 16) if '0x' in number_in_string else int(number_in_string) number = int(number_in_string, 16) if '0x' in number_in_string else int(number_in_string)
@ -896,7 +902,7 @@ def skip_test(form, skip_list):
def compile_wast_to_wasm(form, wast_tempfile, wasm_tempfile, opts): def compile_wast_to_wasm(form, wast_tempfile, wasm_tempfile, opts):
log("Writing WAST module to '%s'" % wast_tempfile) log("Writing WAST module to '%s'" % wast_tempfile)
file(wast_tempfile, 'w').write(form) open(wast_tempfile, 'w').write(form)
log("Compiling WASM to '%s'" % wasm_tempfile) log("Compiling WASM to '%s'" % wasm_tempfile)
# default arguments # default arguments
@ -1122,7 +1128,7 @@ if __name__ == "__main__":
# workaround: spec test changes error message to "malformed" while iwasm still use "invalid" # workaround: spec test changes error message to "malformed" while iwasm still use "invalid"
error_msg = m.group(2).replace("malformed", "invalid") error_msg = m.group(2).replace("malformed", "invalid")
log("Testing(malformed)") log("Testing(malformed)")
f = file(wasm_tempfile, 'w') f = open(wasm_tempfile, 'w')
s = m.group(1) s = m.group(1)
while s: while s:
res = re.match("[^\"]*\"([^\"]*)\"(.*)", s, re.DOTALL) res = re.match("[^\"]*\"([^\"]*)\"(.*)", s, re.DOTALL)

View File

@ -219,7 +219,7 @@ function unit_test()
make -ki clean | true make -ki clean | true
cmake ${compile_flag} ${WORK_DIR}/../../unit && make -j 4 cmake ${compile_flag} ${WORK_DIR}/../../unit && make -j 4
if [ "$?" != 0 ];then if [ "$?" != 0 ];then
echo -e "\033[31mbuild unit test failed, you may need to change wamr into dev/aot branch and ensure llvm is built \033[0m" echo -e "build unit test failed, you may need to change wamr into dev/aot branch and ensure llvm is built"
exit 1 exit 1
fi fi
@ -486,7 +486,7 @@ function build_iwasm_with_cfg()
fi fi
if [ "$?" != 0 ];then if [ "$?" != 0 ];then
echo -e "\033[31mbuild iwasm failed \033[0m" echo -e "build iwasm failed"
exit 1 exit 1
fi fi
} }
@ -644,7 +644,7 @@ else
# Add more suites here # Add more suites here
fi fi
echo -e "\033[32mTest finish. Reports are under ${REPORT_DIR} \033[0m" echo -e "Test finish. Reports are under ${REPORT_DIR}"
DEBUG set +xv pipefail DEBUG set +xv pipefail
echo "TEST SUCCESSFUL" echo "TEST SUCCESSFUL"
exit 0 exit 0

View File

@ -151,7 +151,7 @@ if (WAMR_BUILD_DEBUG_AOT EQUAL 1)
include_directories(${LLVM_BUILD_BINARY_DIR}/tools/lldb/include) include_directories(${LLVM_BUILD_BINARY_DIR}/tools/lldb/include)
endif() endif()
link_directories(${LLVM_LIBRARY_DIRS}) link_directories(${LLVM_LIBRARY_DIRS})
find_library(lib_lldb NAMES lldb HINTS ${LLVM_LIBRARY_DIRS}) find_library(lib_lldb NAMES lldb HINTS ${LLVM_LIBRARY_DIRS} REQUIRED)
message(STATUS "find lldb ${LLDB_ALL_PLUGINS} in: ${LLVM_LIBRARY_DIRS}") message(STATUS "find lldb ${LLDB_ALL_PLUGINS} in: ${LLVM_LIBRARY_DIRS}")
endif() endif()

View File

@ -11,4 +11,4 @@ import sys
script = ( script = (
pathlib.Path(__file__).parent.joinpath("../build-scripts/build_llvm.py").resolve() pathlib.Path(__file__).parent.joinpath("../build-scripts/build_llvm.py").resolve()
) )
subprocess.check_call([sys.executable, script.name]) subprocess.check_call([sys.executable, script])

View File

@ -3,4 +3,4 @@
# Copyright (C) 2020 Intel Corporation. All rights reserved. # Copyright (C) 2020 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
/usr/bin/env python3 ../build-scripts/build_llvm.py /usr/bin/env python3 ../build-scripts/build_llvm.py "$@"

View File

@ -3,4 +3,4 @@
# Copyright (C) 2020 Intel Corporation. All rights reserved. # Copyright (C) 2020 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
/usr/bin/env python3 ../build-scripts/build_llvm.py --platform arc /usr/bin/env python3 ../build-scripts/build_llvm.py --platform arc "$@"

View File

@ -3,4 +3,4 @@
# Copyright (C) 2020 Intel Corporation. All rights reserved. # Copyright (C) 2020 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
/usr/bin/env python3 ../build-scripts/build_llvm.py --platform xtensa /usr/bin/env python3 ../build-scripts/build_llvm.py --platform xtensa "$@"