Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Docker/Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ RUN install -D -m 0755 /home/${USERNAME}/lind-wasm/scripts/bin/lind_compile /usr
# Replace copied helper scripts with symlinks so local edits are reflected.
RUN rm -f /usr/local/bin/lind_compile /usr/local/bin/lind_run \
&& ln -sf /home/${USERNAME}/lind-wasm/scripts/bin/lind_compile /usr/local/bin/lind_compile \
&& ln -sf /home/${USERNAME}/lind-wasm/scripts/bin/lind_run /usr/local/bin/lind_run
&& ln -sf /home/${USERNAME}/lind-wasm/scripts/bin/lind_run /usr/local/bin/lind_run \
&& ln -sf /home/${USERNAME}/lind-wasm/scripts/bin/lind_checkenv /usr/local/bin/lind_checkenv
USER ${USERNAME}

CMD ["/bin/bash"]
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,13 @@ md_generation:
@echo "Wrote $(OUT)/e2e_comment.md"


# Verify the host has everything needed to build and run lind-wasm.
# Use `make checkenv BUILD_ONLY=1` on a fresh checkout to skip the checks for
# artifacts that `make build` has not produced yet.
.PHONY: checkenv
checkenv:
./scripts/bin/lind_checkenv $(if $(BUILD_ONLY),--build)

.PHONY: lint
lint:
cargo fmt --check --all --manifest-path src/wasmtime/Cargo.toml
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@ Check out the [Getting started](https://lind-project.github.io/lind-wasm/getting
guide for a Hello World! example and [our docs](https://lind-project.github.io/lind-wasm/)
to learn more about Lind!

**Supported platforms:** `lind-wasm` targets **linux/amd64**. A native build

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about other platforms tested like Windows, WSL

requires x86-64 Linux (tested on Ubuntu 22.04) and roughly 20 GB of free disk
space.

| Host | How to run |
| --- | --- |
| x86-64 Linux | native build, or the development image |
| Windows | Ubuntu 22.04 under WSL2, covered in the [Native Linux setup](https://lind-project.github.io/lind-wasm/contribute/running-on-native-linux/) guide; or Docker Desktop with `--platform=linux/amd64` |
| macOS (Intel or Apple Silicon) | the development image with `--platform=linux/amd64`; on Apple Silicon this runs under emulation and is slower |

On Windows and macOS, clone into a case-sensitive filesystem — the WSL2 ext4
filesystem rather than `/mnt/c`, for example. The glibc sources contain
case-colliding filenames (see
[#1246](https://github.com/Lind-Project/lind-wasm/issues/1246)).

Run `make checkenv` to verify a machine.



## Repository Structure and Components
Expand Down
35 changes: 26 additions & 9 deletions docs/contribute/debug-programs.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,52 @@

## Debugging with GDB

To debug a WebAssembly module using GDB, ensure that your module is compiled with debugging information (e.g., using the -g flag during compilation). Additionally, Wasmtime itself must be compiled in debug mode (i.e., without the --release flag) to enable effective debugging of both the runtime and the module. This allows GDB to access symbol information from both your program and Wasmtime.
To debug a WebAssembly module using GDB, ensure that your module is compiled with debugging information (e.g., using the -g flag during compilation). Additionally, the runtime itself must be built in debug mode, with `make lind-debug`, to enable effective debugging of both the runtime and the module. This allows GDB to access symbol information from both your program and the runtime.

> **Note:** Current limitations in GDB support for WebAssembly include lack of instruction-level inspection. Commands like `layout split` and `si` (step instruction) may break the terminal. It’s recommended to use `layout src` for source-level debugging.

> **Note:** GDB debugs the Rust runtime, not the C code running inside the WebAssembly module.

---

### Running GDB with Wasmtime
### Running GDB with the runtime

Build the debug runtime, then start GDB against it. Which invocation you need
depends on how the program was compiled.

Use the following command to start GDB with Wasmtime:
For a **dynamic build** — what `lind_compile` produces by default:

```sh
gdb --args ../wasmtime/target/debug/wasmtime run -D debug-info -O opt-level=0 malloc-test.wasm
make lind-debug
sudo gdb --args ./build/lind-boot --preload env=/lib/libc.cwasm --preload env=/lib/libm.cwasm malloc-test.cwasm
```

For a **static build** (`lind_compile -s`), the preloads are not needed:

Comment thread
Yaxuan-w marked this conversation as resolved.
```sh
Comment thread
Yaxuan-w marked this conversation as resolved.
make lind-debug
sudo gdb --args ./build/lind-boot malloc-test.cwasm
```

**Explanation of arguments:**

- `gdb --args`: Passes arguments to the program through GDB.
- `../wasmtime/target/debug/wasmtime run`: Runs your WebAssembly module using the Wasmtime binary.
- `-D debug-info`: Enables Wasmtime’s debug information support.
- `-O opt-level=0`: Disables optimizations for easier debugging.
- `sudo`: The runtime `chroot`s into `lindfs`, which requires root. `scripts/bin/lind_run` normally does this for you.
- `./build/lind-boot`: The runtime binary. `make lind-debug` installs the debug build here, at the same path as the release build.
- `--preload env=/lib/libc.cwasm --preload env=/lib/libm.cwasm`: The shared *lind-glibc* and libm a dynamic build resolves its imports against. `lind_run` passes these for you; running `lind-boot` directly under GDB means passing them yourself.
- `malloc-test.cwasm`: Your program, as a path *inside* `lindfs` (see [Getting Started](../getting-started.md#what-just-happened)).

Run `./build/lind-boot --help` for the full set of runtime options.

---

### Example Debugging Session

1. **Start GDB**
Launch GDB with Wasmtime and your WebAssembly module:
Launch GDB with the runtime and your WebAssembly module (dynamic build shown,
see [above](#running-gdb-with-the-runtime) for the static variant):
```sh
gdb --args ../wasmtime/target/debug/wasmtime run -D debug-info -O opt-level=0 malloc-test.wasm
sudo gdb --args ./build/lind-boot --preload env=/lib/libc.cwasm --preload env=/lib/libm.cwasm malloc-test.cwasm
```

2. **Set Breakpoints**
Expand Down
10 changes: 10 additions & 0 deletions docs/contribute/dev-container.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Development setup

To access an environment with the source code and tooling, there is a development image available as well.
(Note: If you intend to use perf, you will need to install the appropriate `linux-tools-xxx` for your kernel)

> **Note:** Despite the page name, this is a plain Docker image — there is no
> `.devcontainer/` in the repository, so VS Code's "Reopen in Container" will not
> pick it up automatically.

The published image is prebuilt: it already contains a compiled runtime, sysroot
and `lindfs`, so you can run a program without building anything. See
[Getting Started](../getting-started.md) for the quickest path.

```
docker pull --platform=linux/amd64 securesystemslab/lind-wasm-dev # this might take a while ...
docker run --platform=linux/amd64 -it --privileged --ipc=host --init --cap-add=SYS_PTRACE securesystemslab/lind-wasm-dev /bin/bash
Expand Down
7 changes: 4 additions & 3 deletions docs/contribute/e2e-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ Runs `scripts/build/make_glibc_and_sysroot.sh` to:



### make wasmtime
### make lind-boot

- Builds the embedded Wasmtime with Cargo (release) from `src/wasmtime/`.
- Builds the runtime with Cargo (release) from `src/lind-boot/`, which embeds the
customized Wasmtime, and installs it as `build/lind-boot`.


### make test
Expand Down Expand Up @@ -132,7 +133,7 @@ High level:
`docker buildx create --use --name lind-builder || docker buildx use lind-builder`

#### Build with cache import/export
`docker buildx build --platform=linux/amd64 -f Docker/Dockerfile.e2e --cache-from type=local,src=~/.cache/docker-buildx --cache-to type=type=local,dest=.~/.cache/docker-buildx,mode=max .`
`docker buildx build --platform=linux/amd64 -f Docker/Dockerfile.e2e --cache-from type=local,src=~/.cache/docker-buildx --cache-to type=local,dest=~/.cache/docker-buildx,mode=max .`

> CI typically uses type=gha; locally a local cache is simple and reliable.

Expand Down
71 changes: 51 additions & 20 deletions docs/contribute/running-on-native-linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,15 @@ The dependencies require a significant amount of storage so 15-20gb of free spac
source "$HOME/.cargo/env"
```

Install the pinned nightly toolchain and `rust-src` component:
The repository pins its toolchain in
[`rust-toolchain.toml`](https://github.com/Lind-Project/lind-wasm/blob/main/rust-toolchain.toml),
and `rustup` installs and selects that channel automatically the first time you
build inside the repository. Do not pin a different nightly by hand:
`rust-toolchain.toml` wins at build time, so a toolchain you select manually —
and any components you add to it — is silently ignored.

```bash
rustup toolchain install nightly-2026-02-11 \
--profile minimal \
--component rust-src
```

Verify the installation:

```bash
rustc +nightly-2026-02-11 --version
```
The `rust-src` component still has to be added explicitly. Because that must
happen against the pinned channel, it is done after cloning, in step 8.

4. __Install WABT 1.0.38__

Expand Down Expand Up @@ -243,16 +239,36 @@ The dependencies require a significant amount of storage so 15-20gb of free spac

8. __Build Lind-Wasm__

From the repository root, build the development runtime, Lind filesystem,
custom glibc, and sysroot:
From the repository root, add `rust-src` to the pinned toolchain. Running this
inside the repository is what makes `rustup` resolve `rust-toolchain.toml`:

```bash
cd ~/lind-wasm
make lind-debug
rustup component add rust-src
rustup show active-toolchain
```

Check that the machine has everything else it needs. Every `FAIL` comes with
the command that fixes it:

```bash
make checkenv BUILD_ONLY=1
```

Then build the runtime, Lind filesystem, custom glibc, and sysroot:

```bash
make build
```

Use `make build` rather than the individual targets: `make lind-boot sysroot`
skips the `lindfs` target, and `make sysroot` on its own fails on a clean
checkout because building the shared libc needs `lind-boot` to exist already.
For a debug runtime use `make lind-debug` instead — but do not mix the two, or
you will get `unknown import: debug::lind_debug_num` at run time.

See the project [`Makefile`](https://github.com/Lind-Project/lind-wasm/blob/main/Makefile) for the individual build
targets.
targets and build knobs.

9. __Install the Lind helper commands__

Expand Down Expand Up @@ -301,9 +317,12 @@ The dependencies require a significant amount of storage so 15-20gb of free spac

10. __Create the Lind filesystem compatibility link__

The current runtime expects `lindfs` at
`/home/lind/lind-wasm/lindfs`. When the WSL username is not `lind`,
create a compatibility symbolic link:
The runtime `chroot`s into a path that is compiled in as a constant —
`LINDFS_ROOT` in `src/sysdefs/src/constants/lind_platform_const.rs`, currently
`/home/lind/lind-wasm/lindfs`. It is not read from the environment, so a
checkout anywhere else panics at startup with `The configured lindfs does not
exist`. Unless your home directory is literally `/home/lind`, create a
compatibility symbolic link:

```bash
sudo mkdir -p /home/lind
Expand Down Expand Up @@ -333,7 +352,7 @@ The dependencies require a significant amount of storage so 15-20gb of free spac

```bash
cd ~/lind-wasm
lind_compile -s hello.c
lind_compile hello.c
```

Run the compiled program using its path inside `lindfs`:
Expand All @@ -348,6 +367,18 @@ The dependencies require a significant amount of storage so 15-20gb of free spac
Hello, World!
```

Two things to expect the first time:

- `lind_run` prompts for a password. It re-executes itself under `sudo -E`
because the runtime needs root to `chroot`.
- The path is `/hello.cwasm`, not `./hello.cwasm`. `lind_compile` copies its
output into `lindfs/`, and the runtime `chroot`s there, so paths are relative
to `lindfs` rather than to your shell's working directory.

`lind_compile` builds dynamically by default, resolving *lind-glibc* from
`lindfs/lib/libc.cwasm` at run time. Pass `-s` for a statically linked binary,
which does not need the shared libc to be present.

12. __Run the full test suite__

From the repository root, run the full test suite. It can take a while, so
Expand Down
6 changes: 2 additions & 4 deletions docs/contribute/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,16 @@ docker build --platform=linux/amd64 -f Docker/Dockerfile.e2e -t dev --target bas

docker run --platform=linux/amd64 -v $(PWD):/lind -w /lind -it dev /bin/bash
```
5. Build toolchain (glibc and wasmtime)
5. Build the toolchain (runtime, glibc sysroot and `lindfs`)
```
# this may take a while ...
make lind-boot sysroot
make build
```
6. Run the test suite
```
./scripts/test/harnesses/wasmtestreport.py
./scripts/test/harnesses/wasmtestreport.py
```
Run `scripts/test/harnesses/wasmtestreport.py --help` to list available usage options.
Run `scripts/test/harnesses/wasmtestreport.py --help` to list available usage options.

## Directory Structure

Expand Down
7 changes: 4 additions & 3 deletions docs/contribute/toolchain.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ options.
along with headers and a pre-built C runtime into a
sysroot directory structure as required by *Clang*.

4. __Build custom wasmtime__ (see [`make wasmtime`](https://github.com/Lind-Project/lind-wasm/blob/main/Makefile))
4. __Build the runtime__ (see [`make lind-boot`](https://github.com/Lind-Project/lind-wasm/blob/main/Makefile))

Builds `src/wasmtime` workspace. Custom dependencies `fdtables`, `RawPOSIX`
and `sysdefs` are included in the build automatically.
Builds the `src/lind-boot` workspace into `build/lind-boot`. The customized
`wasmtime` and the `fdtables`, `RawPOSIX`, `threei` and `sysdefs` crates are
included in the build automatically.


A customized `wasm-opt` binary is included in the *lind-wasm* repo under
Expand Down
Loading