[PATCH v3 00/35] wasm: Add Wasm TCG backend based on wasm64

Kohei Tokunaga posted 35 patches 5 months, 1 week ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/cover.1756724464.git.ktokunaga.mail@gmail.com
Maintainers: "Alex Bennée" <alex.bennee@linaro.org>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Thomas Huth <thuth@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Richard Henderson <richard.henderson@linaro.org>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, WANG Xuerui <git@xen0n.name>, Aurelien Jarno <aurelien@aurel32.net>, Huacai Chen <chenhuacai@kernel.org>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Aleksandar Rikalo <arikalo@gmail.com>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <Alistair.Francis@wdc.com>, Stefan Weil <sw@weilnetz.de>, Kohei Tokunaga <ktokunaga.mail@gmail.com>
There is a newer version of this series
.gitlab-ci.d/buildtest.yml                    |   26 +-
.gitlab-ci.d/container-cross.yml              |   20 +-
.gitlab-ci.d/container-template.yml           |    4 +-
MAINTAINERS                                   |    9 +-
configure                                     |   14 +-
include/accel/tcg/getpc.h                     |    2 +-
include/tcg/helper-info.h                     |    4 +-
include/tcg/tcg.h                             |    2 +-
meson.build                                   |   16 +-
meson_options.txt                             |    3 +
scripts/meson-buildoptions.sh                 |    5 +
tcg/aarch64/tcg-target.c.inc                  |   11 +
tcg/arm/tcg-target.c.inc                      |   11 +
tcg/i386/tcg-target.c.inc                     |   11 +
tcg/loongarch64/tcg-target.c.inc              |   11 +
tcg/meson.build                               |    5 +
tcg/mips/tcg-target.c.inc                     |   11 +
tcg/ppc/tcg-target.c.inc                      |   11 +
tcg/region.c                                  |   10 +-
tcg/riscv/tcg-target.c.inc                    |   11 +
tcg/s390x/tcg-target.c.inc                    |   11 +
tcg/sparc64/tcg-target.c.inc                  |   11 +
tcg/tcg.c                                     |   21 +-
tcg/tci/tcg-target.c.inc                      |   11 +
tcg/wasm.c                                    |  855 +++++
tcg/wasm.h                                    |  117 +
tcg/wasm/tcg-target-con-set.h                 |   19 +
tcg/wasm/tcg-target-con-str.h                 |   14 +
tcg/wasm/tcg-target-has.h                     |   14 +
tcg/wasm/tcg-target-mo.h                      |   20 +
tcg/wasm/tcg-target-opc.h.inc                 |   18 +
tcg/wasm/tcg-target-reg-bits.h                |   11 +
tcg/wasm/tcg-target.c.inc                     | 2843 +++++++++++++++++
tcg/wasm/tcg-target.h                         |   61 +
...2-cross.docker => emsdk-wasm-cross.docker} |   29 +-
35 files changed, 4218 insertions(+), 34 deletions(-)
create mode 100644 tcg/wasm.c
create mode 100644 tcg/wasm.h
create mode 100644 tcg/wasm/tcg-target-con-set.h
create mode 100644 tcg/wasm/tcg-target-con-str.h
create mode 100644 tcg/wasm/tcg-target-has.h
create mode 100644 tcg/wasm/tcg-target-mo.h
create mode 100644 tcg/wasm/tcg-target-opc.h.inc
create mode 100644 tcg/wasm/tcg-target-reg-bits.h
create mode 100644 tcg/wasm/tcg-target.c.inc
create mode 100644 tcg/wasm/tcg-target.h
rename tests/docker/dockerfiles/{emsdk-wasm32-cross.docker => emsdk-wasm-cross.docker} (85%)
[PATCH v3 00/35] wasm: Add Wasm TCG backend based on wasm64
Posted by Kohei Tokunaga 5 months, 1 week ago
V3:
- Fixed init_wasm_js to correctly cast pointers to Numbers when passing the
  arguments to the getInt32 and setInt32 methods.
- Lowered the the maximum number of instances (MAX_INSTANCES) to avoid the
  out of memory error in recent versions of FireFox.

V2:

- Reorganized commits to implement the backend incrementally from a clean
  state.
- Removed the andc, orc, eqv, nand and nor operations to rely on default
  expansion.
- Removed the bswap operations to use default expansion.
- Removed the extract and deposit oprations to use default expansion.
- Updated the sextract to emit only when the corresponding Wasm instruction
  is available
- Removed the not operation to rely on default expansion.
- Fixed the neg implementation to "ret = 0 - arg"
- Added Wasm implementation of the mb operation using the atomic.fence
  instruction.

Note:
The first four commits are temporarily imported from a separated patch
series which enables 64bit guests using wasm64 [2]. These commits are under
review in that series and are included here only to allow subsequent patches
to build. Please ignore them when reviewing this series.

V1:

This patch series adds a TCG backend for WebAssembly. Unlike eariler
attempts [1], it is implemented using Emscripten's wasm64 target to support
64bit guests.

The first four commits are temporarily imported from a separated patch
series which enables 64bit guests using wasm64 [2]. These commits are under
review in that series and are included here only to allow subsequent patches
to build. Please ignore them when reviewing this series.

# New TCG Backend for Browsers

A new TCG backend translates IR instructions into Wasm instructions and runs
them using the browser's WebAssembly APIs (WebAssembly.Module and
WebAssembly.instantiate). To minimize compilation overhead and avoid hitting
the browser's limitation of the number of instances, this backend integrates
a forked TCI. TBs run on TCI by default, with frequently executed TBs
compiled into WebAssembly.

# 64bit guests support by wasm64

Support for 64bit guests is being reviewed in a separated patch series [2],
which enables QEMU to use 64bit pointers by compiling with the --cpu=wasm64
flag. The Wasm TCG backend is based on this feature and also requires
--cpu=wasm64.

QEMU compiled with --cpu=wasm64 runs on wasm64-capable engines. To support
engines which don't support wasm64 (e.g. Safari), the Wasm backend can use
the compatibility flag "--enable-wasm64-32bit-address-limit" also introduced
in [2]. This flag enables 64bit pointers in the C code while Emscripten
lowers the output binary to wasm32 and limits the maximum memory size to
4GB. As a result, the Wasm backend can run on wasm32 engiens while
supporting 64bit guests.

Note: The flag was originally named --wasm64-32bit-address-limit but this
patch series moved it from the configure script into meson_options.txt. To
follow Meson's naming conventions, it was renamed to
--enable-wasm64-32bit-address-limit.

# Overview of build process

To compile QEMU with Emscripten, the following dependencies are required.
The emsdk-wasm-cross.docker environment includes all necessary components
and can be used as the build environment:

- Emscripten SDK (emsdk) v4.0.10
- Libraries cross-compiled with Emscripten (please see also
  emsdk-wasm-cross.docker for build steps)
  - GLib v2.84.0
  - zlib v1.3.1
  - libffi v3.5.2
  - Pixman v0.44.2

The configure script supports --cpu=wasm64 flag to compile QEMU with 64bit
pointer support.

emconfigure ./configure --cpu=wasm64 \
                        --static --disable-tools \
                        --target-list=x86_64-softmmu
emmake make -j$(nproc)

If the output needs to run on wasm32 engines, use
"--enable-wasm64-32bit-address-limit" flag.

emconfigure ./configure --cpu=wasm64 --enable-wasm64-32bit-address-limit \
                        --static --disable-tools \
                        --target-list=x86_64-softmmu
emmake make -j$(nproc)

Either of the above commands generates the following files:

- qemu-system-x86_64.js
- qemu-system-x86_64.wasm

Guest images can be packaged using Emscripten's file_packager.py tool.
For example, if the images are stored in a directory named "pack", the
following command packages them, allowing QEMU to access them through
Emscripten's virtual filesystem:

/path/to/file_packager.py qemu-system-x86_64.data --preload pack > load.js

This process generates the following files:

- qemu-system-x86_64.data
- load.js

Emscripten allows passing arguments to the QEMU command via the Module
object in JavaScript:

Module['arguments'] = [
    '-nographic', '-m', '512M',
    '-L', 'pack/',
    '-drive', 'if=virtio,format=raw,file=pack/rootfs.bin',
    '-kernel', 'pack/bzImage',
    '-append', 'earlyprintk=ttyS0 console=ttyS0 root=/dev/vda loglevel=7',
];

The sample repository [3] (tcgdev64 branch) provides a complete setup,
including an HTML file that implements a terminal UI.

[1] https://patchew.org/QEMU/cover.1747744132.git.ktokunaga.mail@gmail.com/
[2] https://patchew.org/QEMU/cover.1754534225.git.ktokunaga.mail@gmail.com/
[3] https://github.com/ktock/qemu-wasm-sample/tree/tcgdev64

Kohei Tokunaga (35):
  meson: Add wasm64 support to the --cpu flag
  configure: Enable to propagate -sMEMORY64 flag to Emscripten
  dockerfiles: Add support for wasm64 to the wasm Dockerfile
  .gitlab-ci.d: Add build tests for wasm64
  tcg/wasm: Add tcg-target.h and tcg-target-reg-bits.h
  tcg/wasm: Add register-related definitions
  tcg/wasm: Add constraint definitions
  tcg/wasm: Add relocation callbacks
  tcg/wasm: Add and/or/xor instructions
  tcg/wasm: Add add/sub/mul instructions
  tcg/wasm: Add shl/shr/sar instructions
  tcg/wasm: Add setcond/negsetcond/movcond instructions
  tcg/wasm: Add sextract instruction
  tcg/wasm: Add load and store instructions
  tcg/wasm: Add mov/movi instructions
  tcg/wasm: Add ext instructions
  tcg/wasm: Add div/rem instructions
  tcg/wasm: Add neg/ctpop instructions
  tcg/wasm: Add rot/clz/ctz instructions
  tcg/wasm: Add br/brcond instructions
  tcg/wasm: Add exit_tb/goto_tb/goto_ptr instructions
  tcg/wasm: Add call instruction
  tcg/wasm: Add qemu_ld/qemu_st instructions
  tcg/wasm: Add mb instruction
  tcg/wasm: Mark unimplemented instructions
  tcg/wasm: Add initialization of fundamental registers
  tcg/wasm: Write wasm binary to TB
  tcg/wasm: Implement instantiation of Wasm binary
  tcg/wasm: Allow switching coroutine from a helper
  tcg/wasm: Enable instantiation of TBs executed many times
  tcg/wasm: Enable TLB lookup
  tcg/wasm: Add tcg_target_init function
  meson.build: enable to build Wasm backend
  meson.build: Propagate optimization flag for linking on Emscripten
  .gitlab-ci.d: build wasm backend in CI

 .gitlab-ci.d/buildtest.yml                    |   26 +-
 .gitlab-ci.d/container-cross.yml              |   20 +-
 .gitlab-ci.d/container-template.yml           |    4 +-
 MAINTAINERS                                   |    9 +-
 configure                                     |   14 +-
 include/accel/tcg/getpc.h                     |    2 +-
 include/tcg/helper-info.h                     |    4 +-
 include/tcg/tcg.h                             |    2 +-
 meson.build                                   |   16 +-
 meson_options.txt                             |    3 +
 scripts/meson-buildoptions.sh                 |    5 +
 tcg/aarch64/tcg-target.c.inc                  |   11 +
 tcg/arm/tcg-target.c.inc                      |   11 +
 tcg/i386/tcg-target.c.inc                     |   11 +
 tcg/loongarch64/tcg-target.c.inc              |   11 +
 tcg/meson.build                               |    5 +
 tcg/mips/tcg-target.c.inc                     |   11 +
 tcg/ppc/tcg-target.c.inc                      |   11 +
 tcg/region.c                                  |   10 +-
 tcg/riscv/tcg-target.c.inc                    |   11 +
 tcg/s390x/tcg-target.c.inc                    |   11 +
 tcg/sparc64/tcg-target.c.inc                  |   11 +
 tcg/tcg.c                                     |   21 +-
 tcg/tci/tcg-target.c.inc                      |   11 +
 tcg/wasm.c                                    |  855 +++++
 tcg/wasm.h                                    |  117 +
 tcg/wasm/tcg-target-con-set.h                 |   19 +
 tcg/wasm/tcg-target-con-str.h                 |   14 +
 tcg/wasm/tcg-target-has.h                     |   14 +
 tcg/wasm/tcg-target-mo.h                      |   20 +
 tcg/wasm/tcg-target-opc.h.inc                 |   18 +
 tcg/wasm/tcg-target-reg-bits.h                |   11 +
 tcg/wasm/tcg-target.c.inc                     | 2843 +++++++++++++++++
 tcg/wasm/tcg-target.h                         |   61 +
 ...2-cross.docker => emsdk-wasm-cross.docker} |   29 +-
 35 files changed, 4218 insertions(+), 34 deletions(-)
 create mode 100644 tcg/wasm.c
 create mode 100644 tcg/wasm.h
 create mode 100644 tcg/wasm/tcg-target-con-set.h
 create mode 100644 tcg/wasm/tcg-target-con-str.h
 create mode 100644 tcg/wasm/tcg-target-has.h
 create mode 100644 tcg/wasm/tcg-target-mo.h
 create mode 100644 tcg/wasm/tcg-target-opc.h.inc
 create mode 100644 tcg/wasm/tcg-target-reg-bits.h
 create mode 100644 tcg/wasm/tcg-target.c.inc
 create mode 100644 tcg/wasm/tcg-target.h
 rename tests/docker/dockerfiles/{emsdk-wasm32-cross.docker => emsdk-wasm-cross.docker} (85%)

-- 
2.43.0
Re: [PATCH v3 00/35] wasm: Add Wasm TCG backend based on wasm64
Posted by Pierrick Bouvier 4 months, 1 week ago
Hi Kohei,

On 9/1/25 4:44 AM, Kohei Tokunaga wrote:
> V3:
> - Fixed init_wasm_js to correctly cast pointers to Numbers when passing the
>    arguments to the getInt32 and setInt32 methods.
> - Lowered the the maximum number of instances (MAX_INSTANCES) to avoid the
>    out of memory error in recent versions of FireFox.
> 
> V2:
> 
> - Reorganized commits to implement the backend incrementally from a clean
>    state.
> - Removed the andc, orc, eqv, nand and nor operations to rely on default
>    expansion.
> - Removed the bswap operations to use default expansion.
> - Removed the extract and deposit oprations to use default expansion.
> - Updated the sextract to emit only when the corresponding Wasm instruction
>    is available
> - Removed the not operation to rely on default expansion.
> - Fixed the neg implementation to "ret = 0 - arg"
> - Added Wasm implementation of the mb operation using the atomic.fence
>    instruction.
> 
> Note:
> The first four commits are temporarily imported from a separated patch
> series which enables 64bit guests using wasm64 [2]. These commits are under
> review in that series and are included here only to allow subsequent patches
> to build. Please ignore them when reviewing this series.
> 
> V1:
> 
> This patch series adds a TCG backend for WebAssembly. Unlike eariler
> attempts [1], it is implemented using Emscripten's wasm64 target to support
> 64bit guests.
> 
> The first four commits are temporarily imported from a separated patch
> series which enables 64bit guests using wasm64 [2]. These commits are under
> review in that series and are included here only to allow subsequent patches
> to build. Please ignore them when reviewing this series.
> 
> # New TCG Backend for Browsers
> 
> A new TCG backend translates IR instructions into Wasm instructions and runs
> them using the browser's WebAssembly APIs (WebAssembly.Module and
> WebAssembly.instantiate). To minimize compilation overhead and avoid hitting
> the browser's limitation of the number of instances, this backend integrates
> a forked TCI. TBs run on TCI by default, with frequently executed TBs
> compiled into WebAssembly.
> 
> # 64bit guests support by wasm64
> 
> Support for 64bit guests is being reviewed in a separated patch series [2],
> which enables QEMU to use 64bit pointers by compiling with the --cpu=wasm64
> flag. The Wasm TCG backend is based on this feature and also requires
> --cpu=wasm64.
> 
> QEMU compiled with --cpu=wasm64 runs on wasm64-capable engines. To support
> engines which don't support wasm64 (e.g. Safari), the Wasm backend can use
> the compatibility flag "--enable-wasm64-32bit-address-limit" also introduced
> in [2]. This flag enables 64bit pointers in the C code while Emscripten
> lowers the output binary to wasm32 and limits the maximum memory size to
> 4GB. As a result, the Wasm backend can run on wasm32 engiens while
> supporting 64bit guests.
> 
> Note: The flag was originally named --wasm64-32bit-address-limit but this
> patch series moved it from the configure script into meson_options.txt. To
> follow Meson's naming conventions, it was renamed to
> --enable-wasm64-32bit-address-limit.
> 
> # Overview of build process
> 
> To compile QEMU with Emscripten, the following dependencies are required.
> The emsdk-wasm-cross.docker environment includes all necessary components
> and can be used as the build environment:
> 
> - Emscripten SDK (emsdk) v4.0.10
> - Libraries cross-compiled with Emscripten (please see also
>    emsdk-wasm-cross.docker for build steps)
>    - GLib v2.84.0
>    - zlib v1.3.1
>    - libffi v3.5.2
>    - Pixman v0.44.2
> 
> The configure script supports --cpu=wasm64 flag to compile QEMU with 64bit
> pointer support.
> 
> emconfigure ./configure --cpu=wasm64 \
>                          --static --disable-tools \
>                          --target-list=x86_64-softmmu
> emmake make -j$(nproc)
> 
> If the output needs to run on wasm32 engines, use
> "--enable-wasm64-32bit-address-limit" flag.
> 
> emconfigure ./configure --cpu=wasm64 --enable-wasm64-32bit-address-limit \
>                          --static --disable-tools \
>                          --target-list=x86_64-softmmu
> emmake make -j$(nproc)
> 
> Either of the above commands generates the following files:
> 
> - qemu-system-x86_64.js
> - qemu-system-x86_64.wasm
> 
> Guest images can be packaged using Emscripten's file_packager.py tool.
> For example, if the images are stored in a directory named "pack", the
> following command packages them, allowing QEMU to access them through
> Emscripten's virtual filesystem:
> 
> /path/to/file_packager.py qemu-system-x86_64.data --preload pack > load.js
> 
> This process generates the following files:
> 
> - qemu-system-x86_64.data
> - load.js
> 
> Emscripten allows passing arguments to the QEMU command via the Module
> object in JavaScript:
> 
> Module['arguments'] = [
>      '-nographic', '-m', '512M',
>      '-L', 'pack/',
>      '-drive', 'if=virtio,format=raw,file=pack/rootfs.bin',
>      '-kernel', 'pack/bzImage',
>      '-append', 'earlyprintk=ttyS0 console=ttyS0 root=/dev/vda loglevel=7',
> ];
> 
> The sample repository [3] (tcgdev64 branch) provides a complete setup,
> including an HTML file that implements a terminal UI.
> 
> [1] https://patchew.org/QEMU/cover.1747744132.git.ktokunaga.mail@gmail.com/
> [2] https://patchew.org/QEMU/cover.1754534225.git.ktokunaga.mail@gmail.com/
> [3] https://github.com/ktock/qemu-wasm-sample/tree/tcgdev64
> 
> Kohei Tokunaga (35):
>    meson: Add wasm64 support to the --cpu flag
>    configure: Enable to propagate -sMEMORY64 flag to Emscripten
>    dockerfiles: Add support for wasm64 to the wasm Dockerfile
>    .gitlab-ci.d: Add build tests for wasm64
>    tcg/wasm: Add tcg-target.h and tcg-target-reg-bits.h
>    tcg/wasm: Add register-related definitions
>    tcg/wasm: Add constraint definitions
>    tcg/wasm: Add relocation callbacks
>    tcg/wasm: Add and/or/xor instructions
>    tcg/wasm: Add add/sub/mul instructions
>    tcg/wasm: Add shl/shr/sar instructions
>    tcg/wasm: Add setcond/negsetcond/movcond instructions
>    tcg/wasm: Add sextract instruction
>    tcg/wasm: Add load and store instructions
>    tcg/wasm: Add mov/movi instructions
>    tcg/wasm: Add ext instructions
>    tcg/wasm: Add div/rem instructions
>    tcg/wasm: Add neg/ctpop instructions
>    tcg/wasm: Add rot/clz/ctz instructions
>    tcg/wasm: Add br/brcond instructions
>    tcg/wasm: Add exit_tb/goto_tb/goto_ptr instructions
>    tcg/wasm: Add call instruction
>    tcg/wasm: Add qemu_ld/qemu_st instructions
>    tcg/wasm: Add mb instruction
>    tcg/wasm: Mark unimplemented instructions
>    tcg/wasm: Add initialization of fundamental registers
>    tcg/wasm: Write wasm binary to TB
>    tcg/wasm: Implement instantiation of Wasm binary
>    tcg/wasm: Allow switching coroutine from a helper
>    tcg/wasm: Enable instantiation of TBs executed many times
>    tcg/wasm: Enable TLB lookup
>    tcg/wasm: Add tcg_target_init function
>    meson.build: enable to build Wasm backend
>    meson.build: Propagate optimization flag for linking on Emscripten
>    .gitlab-ci.d: build wasm backend in CI
> 
>   .gitlab-ci.d/buildtest.yml                    |   26 +-
>   .gitlab-ci.d/container-cross.yml              |   20 +-
>   .gitlab-ci.d/container-template.yml           |    4 +-
>   MAINTAINERS                                   |    9 +-
>   configure                                     |   14 +-
>   include/accel/tcg/getpc.h                     |    2 +-
>   include/tcg/helper-info.h                     |    4 +-
>   include/tcg/tcg.h                             |    2 +-
>   meson.build                                   |   16 +-
>   meson_options.txt                             |    3 +
>   scripts/meson-buildoptions.sh                 |    5 +
>   tcg/aarch64/tcg-target.c.inc                  |   11 +
>   tcg/arm/tcg-target.c.inc                      |   11 +
>   tcg/i386/tcg-target.c.inc                     |   11 +
>   tcg/loongarch64/tcg-target.c.inc              |   11 +
>   tcg/meson.build                               |    5 +
>   tcg/mips/tcg-target.c.inc                     |   11 +
>   tcg/ppc/tcg-target.c.inc                      |   11 +
>   tcg/region.c                                  |   10 +-
>   tcg/riscv/tcg-target.c.inc                    |   11 +
>   tcg/s390x/tcg-target.c.inc                    |   11 +
>   tcg/sparc64/tcg-target.c.inc                  |   11 +
>   tcg/tcg.c                                     |   21 +-
>   tcg/tci/tcg-target.c.inc                      |   11 +
>   tcg/wasm.c                                    |  855 +++++
>   tcg/wasm.h                                    |  117 +
>   tcg/wasm/tcg-target-con-set.h                 |   19 +
>   tcg/wasm/tcg-target-con-str.h                 |   14 +
>   tcg/wasm/tcg-target-has.h                     |   14 +
>   tcg/wasm/tcg-target-mo.h                      |   20 +
>   tcg/wasm/tcg-target-opc.h.inc                 |   18 +
>   tcg/wasm/tcg-target-reg-bits.h                |   11 +
>   tcg/wasm/tcg-target.c.inc                     | 2843 +++++++++++++++++
>   tcg/wasm/tcg-target.h                         |   61 +
>   ...2-cross.docker => emsdk-wasm-cross.docker} |   29 +-
>   35 files changed, 4218 insertions(+), 34 deletions(-)
>   create mode 100644 tcg/wasm.c
>   create mode 100644 tcg/wasm.h
>   create mode 100644 tcg/wasm/tcg-target-con-set.h
>   create mode 100644 tcg/wasm/tcg-target-con-str.h
>   create mode 100644 tcg/wasm/tcg-target-has.h
>   create mode 100644 tcg/wasm/tcg-target-mo.h
>   create mode 100644 tcg/wasm/tcg-target-opc.h.inc
>   create mode 100644 tcg/wasm/tcg-target-reg-bits.h
>   create mode 100644 tcg/wasm/tcg-target.c.inc
>   create mode 100644 tcg/wasm/tcg-target.h
>   rename tests/docker/dockerfiles/{emsdk-wasm32-cross.docker => emsdk-wasm-cross.docker} (85%)
> 

I tried to build this series to test it, but unfortunately, I have some 
errors:

$ podman build -t wasm - --build-arg TARGET_CPU=wasm64 \
   --build-arg WASM64_MEMORY64=1 \
   < ./tests/docker/dockerfiles/emsdk-wasm-cross.docker
$ podman run -it --rm -w $(pwd) -v $(pwd):$(pwd) wasm bash
$ emconfigure ./configure --cpu=wasm64 \
   --static --disable-tools --target-list=x86_64-softmmu
$ emmake make -j$(nproc)

* /builddeps/target/include/ffi.h:430:6: error: 'FFI_NATIVE_RAW_API' is 
not defined, evaluates to 0 [-Werror,-Wundef]
* various "format specifies type 'long long' but the argument has type 
'long' [-Werror,-Wformat]"

Is it working fine on your side? If yes, what am I missing?

Note: To build with podman, I needed those changes (that you can 
probably integrate as they are compatible with docker also):
--- a/tests/docker/dockerfiles/emsdk-wasm-cross.docker
+++ b/tests/docker/dockerfiles/emsdk-wasm-cross.docker
@@ -10,7 +10,7 @@ ARG MESON_VERSION=1.5.0
  ARG TARGET_CPU=wasm32
  ARG WASM64_MEMORY64=0

-FROM emscripten/emsdk:$EMSDK_VERSION_QEMU AS build-base-common
+FROM docker.io/emscripten/emsdk:$EMSDK_VERSION_QEMU AS build-base-common
  ARG TARGET_CPU
  ARG MESON_VERSION
  ENV TARGET=/builddeps/target
@@ -130,8 +130,8 @@ RUN mkdir -p /glib
  RUN curl -Lks 
https://download.gnome.org/sources/glib/${GLIB_MINOR_VERSION}/glib-$GLIB_VERSION.tar.xz 
| \
      tar xJC /glib --strip-components=1

-COPY --link --from=zlib-dev /builddeps/ /builddeps/
-COPY --link --from=libffi-dev /builddeps/ /builddeps/
+COPY --from=zlib-dev /builddeps/ /builddeps/
+COPY --from=libffi-dev /builddeps/ /builddeps/

  WORKDIR /glib
  RUN <<EOF
@@ -156,5 +156,5 @@ RUN sed -i -E "/#define HAVE_PTHREAD_GETNAME_NP 1/d" 
./_build/config.h
  RUN meson install -C _build

  FROM build-base
-COPY --link --from=glib-dev /builddeps/ /builddeps/
-COPY --link --from=pixman-dev /builddeps/ /builddeps/
+COPY --from=glib-dev /builddeps/ /builddeps/
+COPY --from=pixman-dev /builddeps/ /builddeps/

Regards,
Pierrick
Re: [PATCH v3 00/35] wasm: Add Wasm TCG backend based on wasm64
Posted by Pierrick Bouvier 4 months, 1 week ago
Hi Kohei,

I've been able to build qemu-system-x86_64 for wasm.

When running it, I could not get any output following instructions on 
https://github.com/ktock/qemu-wasm-sample/tcgdev64.
Anyway, I could run this using emrun, even though output is limited to 
javascript console, and not the graphical console printed on webpage.

Am I missing something obvious here?

As well, I tested this setup (edk2 + linux):
$ git clone https://github.com/pbo-linaro/qemu-linux-stack
$ cd qemu-linux-stack
$ git checkout x86_64
$ ./build.sh
$ rm out/host.ext4 # too big for file_packager, does not handle sparse

# copy needed bios files (.bin, .rom) from qemu/pc-bios
$ /usr/share/emscripten/tools/file_packager.py \
   qemu-system-x86_64.data --preload out \
   kvmvapic.bin vgabios-stdvga.bin  efi-e1000.rom > load.js

When booting with:
Module['arguments'] = [
     '-m', '1G',
     '--nographic',
     '-bios', 'out/OVMF.fd',
     '-kernel', 'out/bzImage',
     '-append', 'console=ttyS0',
];

Boot fails with:
ASSERT_EFI_ERROR (Status = Device Error)

While it boots linux with native qemu. Do we have any restriction on 
WASM build that could create this, out of a bug in tcg backend?

Thanks,
Pierrick
Re: [PATCH v3 00/35] wasm: Add Wasm TCG backend based on wasm64
Posted by Kohei Tokunaga 4 months, 1 week ago
Hi Pierrick,

> I've been able to build qemu-system-x86_64 for wasm.
>
> When running it, I could not get any output following instructions on
> https://github.com/ktock/qemu-wasm-sample/tcgdev64.
> Anyway, I could run this using emrun, even though output is limited to
> javascript console, and not the graphical console printed on webpage.
>
> Am I missing something obvious here?

By default, Emscripten's runtime sends output to the JavaScript console, so
the example repo (qemu-wasm-sample) relies on xterm-pty[1] to setup a
terminal UI on the page.

If you compiled QEMU using the emsdk-wasm-cross.docker environment (instead
of the additional Dockerfile provided in the qemu-wasm-sample repo) please
make sure that xterm-pty is linked to the final QEMU build. A simplest way
to do this is to add an extra -l flag to emcc to link with xterm-pty, using
an envvar.

npm install xterm-pty@v0.10.1
cp ./node_modules/xterm-pty/emscripten-pty.js ./libemscripten-pty.js
export EMCC_CFLAGS="-L $(pwd) -lemscripten-pty.js
-Wno-unused-command-line-argument"
emconfigure ./configure --cpu=wasm64 --static --disable-tools \
            --target-list=x86_64-softmmu
emmake make -j$(nproc)

[1] https://github.com/mame/xterm-pty

> As well, I tested this setup (edk2 + linux):
> $ git clone https://github.com/pbo-linaro/qemu-linux-stack
> $ cd qemu-linux-stack
> $ git checkout x86_64
> $ ./build.sh
> $ rm out/host.ext4 # too big for file_packager, does not handle sparse
>
> # copy needed bios files (.bin, .rom) from qemu/pc-bios
> $ /usr/share/emscripten/tools/file_packager.py \
>    qemu-system-x86_64.data --preload out \
>    kvmvapic.bin vgabios-stdvga.bin  efi-e1000.rom > load.js
>
> When booting with:
> Module['arguments'] = [
>      '-m', '1G',
>      '--nographic',
>      '-bios', 'out/OVMF.fd',
>      '-kernel', 'out/bzImage',
>      '-append', 'console=ttyS0',
> ];
>
> Boot fails with:
> ASSERT_EFI_ERROR (Status = Device Error)
>
> While it boots linux with native qemu. Do we have any restriction on
> WASM build that could create this, out of a bug in tcg backend?

Thank you for pointing this out, I'm working on investigating this issue.

Regards,
Kohei
Re: [PATCH v3 00/35] wasm: Add Wasm TCG backend based on wasm64
Posted by Kohei Tokunaga 4 months, 1 week ago
Hi Pierrick,

Thank you for testing this patch.

> * /builddeps/target/include/ffi.h:430:6: error: 'FFI_NATIVE_RAW_API' is
> not defined, evaluates to 0 [-Werror,-Wundef]
> * various "format specifies type 'long long' but the argument has type
> 'long' [-Werror,-Wformat]"

On my side and also on the GitLab CI, these appear only as warnings and the
build completes without errors[1]. I'm curious why -Werror is being
triggered in your build. Have you applied additional configurations that
enabled -Werror?

[1] https://gitlab.com/ktock/qemu/-/jobs/11544442966#L7016

Regards,
Kohei
Re: [PATCH v3 00/35] wasm: Add Wasm TCG backend based on wasm64
Posted by Pierrick Bouvier 4 months, 1 week ago
On 9/30/25 1:26 AM, Kohei Tokunaga wrote:
> Hi Pierrick,
> 
> Thank you for testing this patch.
> 
>  > * /builddeps/target/include/ffi.h:430:6: error: 'FFI_NATIVE_RAW_API' is
>  > not defined, evaluates to 0 [-Werror,-Wundef]
>  > * various "format specifies type 'long long' but the argument has type
>  > 'long' [-Werror,-Wformat]"
> 
> On my side and also on the GitLab CI, these appear only as warnings and the
> build completes without errors[1]. I'm curious why -Werror is being
> triggered in your build. Have you applied additional configurations that
> enabled -Werror?
> 
> [1] https://gitlab.com/ktock/qemu/-/jobs/11544442966#L7016 <https:// 
> gitlab.com/ktock/qemu/-/jobs/11544442966#L7016>
> 
> Regards,
> Kohei

You're right, I indeed have a local patch forcing werror on my side that 
I forgot I had. Sorry for the noise.

I have been able to build successfully, thanks.