Go to file
Joel Dice b85d65528d
add stubs for dlopen, dlsym, etc. (#443)
* add stubs for dlopen, dlsym, etc.

This adds weak exports for the POSIX `dlopen`, `dlsym`, `dlclose`, and `dlerror`
functions, allowing code which uses those features to compile.  The
implementations are stubs which always fail since there is currently no official
standard for runtime dynamic linking.

Since the symbols are weak, they can be overriden with useful, runtime-specific
implementations, e.g. based on host functions or statically-generated tables
(see https://github.com/dicej/component-linking-demo for an example of the
latter).

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* move `dlopen` stubs out of libc and into libdl

Per review feedback, it's easier to simply replace libdl.so with a working
implementation at runtime than it is to override a handful of symbols in libc.

Note that I've both added libdl.so and replaced the empty libdl.a we were
previously creating with one that contains the stubs.  I'm thinking we might as
well be consistent about what symbols the .so and the .a contain.  Otherwise,
e.g. the CPython build gets confused when the dlfcn.h says `dlopen` etc. exist
but libdl.a is empty.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* customize dlfcn.h for WASI

For WASI, we use flag values which match MacOS rather than musl.  This gives
`RTLD_LOCAL` a non-zero value, avoiding ambiguity and allowing us to defer the
decision of whether `RTLD_LOCAL` or `RTLD_GLOBAL` should be the default when
neither is specified.

We also avoid declaring `dladdr`, `dlinfo`, and friends on WASI since they are
neither supported nor stubbed at this time.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* use musl's RTLD_* flags except for RTLD_LOCAL

This minimizes the divergence from upstream while still giving us the
flexibility to choose a default value later.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* use `NULL` instead of `0` for null pointers

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

---------

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
2023-11-14 16:34:57 -08:00
.github/workflows dlmalloc: require __heap_end (#394) 2023-07-11 15:32:08 -07:00
dlmalloc Acquire the global lock before initializing malloc (#410) 2023-07-11 15:33:07 -07:00
emmalloc Port emmalloc to wasi-libc. 2022-11-01 12:54:26 -07:00
expected add stubs for dlopen, dlsym, etc. (#443) 2023-11-14 16:34:57 -08:00
libc-bottom-half add shared library support (#429) 2023-09-28 06:11:09 -07:00
libc-top-half add stubs for dlopen, dlsym, etc. (#443) 2023-11-14 16:34:57 -08:00
test test: run a subset of tests using libc-test (#346) 2022-12-02 18:27:42 -08:00
tools/wasi-headers build: update WASI and partially regenerate api.h 2022-04-20 13:39:57 -07:00
.gitattributes Correct the version of #136 on master (#141) 2019-11-21 20:55:26 -08:00
.gitignore gitignore build 2019-04-19 11:16:25 -07:00
.gitmodules Correct the version of #136 on master (#141) 2019-11-21 20:55:26 -08:00
CODE_OF_CONDUCT.md Add a CODE_OF_CONDUCT.md file. (#101) 2019-10-03 14:15:49 +02:00
LICENSE Beginning porting Emscripten's emmalloc to wasi-libc. 2022-11-01 12:54:26 -07:00
LICENSE-APACHE Multi-license wasi-libc under Apache and MIT licenses. (#174) 2020-02-29 10:52:28 +01:00
LICENSE-APACHE-LLVM Multi-license wasi-libc under Apache and MIT licenses. (#174) 2020-02-29 10:52:28 +01:00
LICENSE-MIT Multi-license wasi-libc under Apache and MIT licenses. (#174) 2020-02-29 10:52:28 +01:00
Makefile add stubs for dlopen, dlsym, etc. (#443) 2023-11-14 16:34:57 -08:00
README.md Improve README.md (#425) 2023-06-23 13:24:08 -07:00

wasi-libc

wasi-libc is a libc for WebAssembly programs built on top of WASI system calls. It provides a wide array of POSIX-compatible C APIs, including support for standard I/O, file I/O, filesystem manipulation, memory management, time, string, environment variables, program startup, and many other APIs.

wasi-libc is sufficiently stable and usable for many purposes, as most of the POSIX-compatible APIs are stable, though it is continuing to evolve to better align with wasm and WASI. For example, pthread support is experimentally provided via the wasi-threads proposal.`

Usage

The easiest way to get started with this is to use wasi-sdk, which includes a build of wasi-libc in its sysroot.

Building from source

To build a WASI sysroot from source, obtain a WebAssembly-supporting C compiler (currently this is only clang 10+, though we'd like to support other compilers as well), and then run:

make CC=/path/to/clang/with/wasm/support \
     AR=/path/to/llvm-ar \
     NM=/path/to/llvm-nm

This makes a directory called "sysroot" by default. See the top of the Makefile for customization options.

To use the sysroot, use the --sysroot= option:

/path/to/wasm/supporting/c/compiler --sysroot=/path/to/the/newly/built/sysroot ...

to run the compiler using the newly built sysroot.

Note that Clang packages typically don't include cross-compiled builds of compiler-rt, libcxx, or libcxxabi, for libclang_rt.builtins-wasm32.a, libc++.a, or libc++abi.a, respectively, so they may not be usable without extra setup. This is one of the things wasi-sdk simplifies, as it includes cross-compiled builds of compiler-rt, libc++.a, and libc++abi.a.

Building in pthread support

To enable pthreads support via the wasi-threads proposal, follow the above build directions with one addition: make ... THREAD_MODEL=posix. This creates additional artifacts in sysroot/lib/wasm32-wasi-threads to support --target wasm32-wasi-threads.

Arch Linux AUR package

For Arch Linux users, there's an official wasi-libc package tracking this Git repository. You might want to install other WASI related packages as well.