Skip to content

Commit

Permalink
WASI libc prototype implementation.
Browse files Browse the repository at this point in the history
This incoporates pieces from musl-libc, cloudlibc, cloudabi, libpreopen,
and dlmalloc, as well as a significant amount of new code.
  • Loading branch information
sunfishcode committed Mar 27, 2019
1 parent 0e98504 commit 320054e
Show file tree
Hide file tree
Showing 2,691 changed files with 131,460 additions and 173 deletions.
12 changes: 10 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,13 @@ Please see the LICENSE file in each top-level directory for the terms applicable

The relevant directories and licenses are:

basics/ - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
dlmalloc/ - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
basics/ - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
dlmalloc/ - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
libc-bottom-half/cloudlibc/ - BSD-2-Clause; see libc-bottom-half/cloudlibc/LICENSE for details
libc-bottom-half/libpreopen/ - BSD-2-Clause; see the individual files for details
libc-bottom-half/headers/ - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
libc-bottom-half/sources/ - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
libc-bottom-half/mman/ - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
libc-top-half/musl - MIT; see libc-top-half/musl/COPYRIGHT for details
libc-top-half/headers - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
libc-top-half/sources - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
457 changes: 427 additions & 30 deletions Makefile

Large diffs are not rendered by default.

52 changes: 26 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
# WebAssembly Reference Sysroot
# WASI Sysroot

Caution: This is currently quite experimental and not generally usable yet!
This is a work in progress. It's usable for many purposes, though the APIs
aren't stable yet.

## What is this?

This is a "reference sysroot", which is meant to be part of a common C ABI
that can be shared across C libraries and compilers. While it's intended to
(eventually) be usable in its own right, we fully expect other
implementations to be used in practice by many different systems, though
we do hope that in those cases, this library defines a useful ABI that can
be followed.
It's several things.

First, it's a usable libc. It builds a "sysroot" which can be pointed to by
compilers, such as Clang 8.0, using the wasm32-unknown-wasi target triple.
It's a work in progress, but it is already sufficient to run basic programs.

Second, it's a "reference" implementation, which means the interfaces defined
here can be used by other tools and libraries, even if they don't use all the
actual implementations here. For example, we don't expect everyone will want
to use the exact `malloc` implementation provided here, but tools and
libraries using an ABI-compatible `malloc` interface will be able to
interoperate regardless of which actual implementation is used.

Third, it's an example showing the use of the WASI API. The libc functionality
is implemented using calls to WASI functions.

## Usage

Obtain a WebAssembly-supporting C compiler, and then run:
The easiest way to get started with this is to use one of the
[prepackaged releases](https://github.com/CraneStation/wasmtime-wasi/blob/wasi/docs/WASI-intro.md#how-can-i-write-programs-that-use-wasi).

## Building from source

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

```
make WASM_CC=/path/to/wasm/supporting/c/compiler
Expand All @@ -29,20 +46,3 @@ To use the sysroot, use the `--sysroot=` option:
```

to run the compiler using the newly built sysroot.

## Why doesn't this contain a full libc implementation?

In the short term, one of the main goals is just to provide a reference
point for people already maintaining their own libc codebases, to help
reduce interface incompatibilities between the several different
environments out there.

In the long term, there may some day be some form of standardized
syscall/import layer for wasm which would could support a full
"reference libc", at which point this repository might make sense as
a place to host such a thing.

In between, if there are specific pieces of libc functionality which
people would find useful to have here, and which don't depend on any
syscalls, we could add them, using code from existing third-party
codebases as appropriate.
20 changes: 20 additions & 0 deletions basics/include/__errno.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __wasm_basics___errno_h
#define __wasm_basics___errno_h

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
extern thread_local int errno;
#else
extern _Thread_local int errno;
#endif

#define errno errno

#ifdef __cplusplus
}
#endif

#endif
22 changes: 22 additions & 0 deletions basics/include/__functions_malloc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef __wasm___functions_malloc_h
#define __wasm___functions_malloc_h

#define __need_size_t
#define __need_wchar_t
#define __need_NULL
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

void *malloc(size_t size) __attribute__((__malloc__, __warn_unused_result__));
void free(void *ptr);
void *calloc(size_t nmemb, size_t size) __attribute__((__malloc__, __warn_unused_result__));
void *realloc(void *ptr, size_t size) __attribute__((__warn_unused_result__));

#ifdef __cplusplus
}
#endif

#endif
20 changes: 20 additions & 0 deletions basics/include/__functions_memcpy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __wasm___functions_memcpy_h
#define __wasm___functions_memcpy_h

#define __need_size_t
#define __need_NULL
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

void *memcpy(void *__restrict__ dst, const void *__restrict__ src, size_t n) __attribute__((__nothrow__, __leaf__, __nonnull__(1, 2)));
void *memmove(void *dst, const void *src, size_t n) __attribute__((__nothrow__, __leaf__, __nonnull__(1, 2)));
void *memset(void *dst, int c, size_t n) __attribute__((__nothrow__, __leaf__, __nonnull__(1)));

#ifdef __cplusplus
}
#endif

#endif
11 changes: 11 additions & 0 deletions basics/include/__macro_PAGESIZE.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef __wasm_basics___macro_PAGESIZE_h
#define __wasm_basics___macro_PAGESIZE_h

/*
* The page size in WebAssembly is fixed at 64 KiB. If this ever changes,
* it's expected that applications will need to opt in, so we can change
* this.
*/
#define PAGESIZE (0x10000)

#endif
6 changes: 3 additions & 3 deletions basics/include/__struct_stat.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___struct_stat_h
#define __wasm_sysroot___struct_stat_h
#ifndef __wasm_basics___struct_stat_h
#define __wasm_basics___struct_stat_h

#include <__typedef_dev_t.h>
#include <__typedef_ino_t.h>
Expand Down Expand Up @@ -29,7 +29,7 @@ struct stat {
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
long long __unused[3];
long long __reserved[3];
};

#endif
6 changes: 3 additions & 3 deletions basics/include/__struct_timespec.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef __wasm_sysroot___struct_timespec_h
#define __wasm_sysroot___struct_timespec_h
#ifndef __wasm_basics___struct_timespec_h
#define __wasm_basics___struct_timespec_h

#include "__typedef_time_t.h"
#include <__typedef_time_t.h>

/* As specified in POSIX. */
struct timespec {
Expand Down
4 changes: 2 additions & 2 deletions basics/include/__typedef_blkcnt_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_blkcnt_t_h
#define __wasm_sysroot___typedef_blkcnt_t_h
#ifndef __wasm_basics___typedef_blkcnt_t_h
#define __wasm_basics___typedef_blkcnt_t_h

/* Define these as 64-bit signed integers to support files larger than 2 GiB. */
typedef long long blkcnt_t;
Expand Down
7 changes: 3 additions & 4 deletions basics/include/__typedef_blksize_t.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#ifndef __wasm_sysroot___typedef_blksize_t_h
#define __wasm_sysroot___typedef_blksize_t_h
#ifndef __wasm_basics___typedef_blksize_t_h
#define __wasm_basics___typedef_blksize_t_h

/* Define these as 64-bit signed integers to support files larger than 2 GiB. */
typedef long long blksize_t;
typedef long blksize_t;

#endif
4 changes: 2 additions & 2 deletions basics/include/__typedef_clock_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_clock_t_h
#define __wasm_sysroot___typedef_clock_t_h
#ifndef __wasm_basics___typedef_clock_t_h
#define __wasm_basics___typedef_clock_t_h

/* Define this as a 64-bit signed integer to avoid wraparounds. */
typedef long long clock_t;
Expand Down
4 changes: 2 additions & 2 deletions basics/include/__typedef_dev_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_dev_t_h
#define __wasm_sysroot___typedef_dev_t_h
#ifndef __wasm_basics___typedef_dev_t_h
#define __wasm_basics___typedef_dev_t_h

/* Define these as 64-bit integers to support billions of devices. */
typedef unsigned long long dev_t;
Expand Down
4 changes: 2 additions & 2 deletions basics/include/__typedef_gid_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_gid_t_h
#define __wasm_sysroot___typedef_gid_t_h
#ifndef __wasm_basics___typedef_gid_t_h
#define __wasm_basics___typedef_gid_t_h

typedef unsigned gid_t;

Expand Down
4 changes: 2 additions & 2 deletions basics/include/__typedef_ino_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_ino_t_h
#define __wasm_sysroot___typedef_ino_t_h
#ifndef __wasm_basics___typedef_ino_t_h
#define __wasm_basics___typedef_ino_t_h

/* Define these as 64-bit integers to support billions of inodes. */
typedef unsigned long long ino_t;
Expand Down
4 changes: 2 additions & 2 deletions basics/include/__typedef_mode_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_mode_t_h
#define __wasm_sysroot___typedef_mode_t_h
#ifndef __wasm_basics___typedef_mode_t_h
#define __wasm_basics___typedef_mode_t_h

typedef unsigned mode_t;

Expand Down
8 changes: 4 additions & 4 deletions basics/include/__typedef_nlink_t.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef __wasm_sysroot___typedef_nlink_t_h
#define __wasm_sysroot___typedef_nlink_t_h
#ifndef __wasm_basics___typedef_nlink_t_h
#define __wasm_basics___typedef_nlink_t_h

/* Define these as 64-bit signed integers to support billions of links. */
typedef long long nlink_t;
/* Define these as 64-bit unsigned integers to support billions of links. */
typedef unsigned long long nlink_t;

#endif
4 changes: 2 additions & 2 deletions basics/include/__typedef_off_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_off_t_h
#define __wasm_sysroot___typedef_off_t_h
#ifndef __wasm_basics___typedef_off_t_h
#define __wasm_basics___typedef_off_t_h

/* Define these as 64-bit signed integers to support files larger than 2 GiB. */
typedef long long off_t;
Expand Down
4 changes: 2 additions & 2 deletions basics/include/__typedef_ssize_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_ssize_t_h
#define __wasm_sysroot___typedef_ssize_t_h
#ifndef __wasm_basics___typedef_ssize_t_h
#define __wasm_basics___typedef_ssize_t_h

/* This is defined to be the same size as size_t. */
typedef long ssize_t;
Expand Down
4 changes: 2 additions & 2 deletions basics/include/__typedef_suseconds_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_suseconds_t_h
#define __wasm_sysroot___typedef_suseconds_t_h
#ifndef __wasm_basics___typedef_suseconds_t_h
#define __wasm_basics___typedef_suseconds_t_h

/* Define this to be 64-bit as its main use is in struct timeval where the
extra space would otherwise be padding. */
Expand Down
4 changes: 2 additions & 2 deletions basics/include/__typedef_time_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_time_t_h
#define __wasm_sysroot___typedef_time_t_h
#ifndef __wasm_basics___typedef_time_t_h
#define __wasm_basics___typedef_time_t_h

/* Define this as a 64-bit signed integer to avoid the 2038 bug. */
typedef long long time_t;
Expand Down
4 changes: 2 additions & 2 deletions basics/include/__typedef_uid_t.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot___typedef_uid_t_h
#define __wasm_sysroot___typedef_uid_t_h
#ifndef __wasm_basics___typedef_uid_t_h
#define __wasm_basics___typedef_uid_t_h

typedef unsigned uid_t;

Expand Down
24 changes: 3 additions & 21 deletions basics/include/errno.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,6 @@
#ifndef __wasm_sysroot_errno_h
#define __wasm_sysroot_errno_h
#ifndef __wasm_basics_errno_h
#define __wasm_basics_errno_h

#ifdef __cplusplus
extern "C" {
#endif

#ifdef WASM_THREAD_MODEL_SINGLE
extern int errno;
#else
#ifdef __cplusplus
extern thread_local int errno;
#else
extern _Thread_local int errno;
#endif
#endif

#define errno errno

#ifdef __cplusplus
}
#endif
#include <__errno.h>

#endif
28 changes: 8 additions & 20 deletions basics/include/stdlib.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
#ifndef __wasm_sysroot_stdlib_h
#define __wasm_sysroot_stdlib_h

#define __need_size_t
#define __need_wchar_t
#define __need_NULL
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);

#ifdef __cplusplus
}
#endif
#ifndef __wasm_stdlib_h
#define __wasm_stdlib_h

/*
* Include the real implementation, which is factored into a separate file so
* that it can be reused by other libc stdlib implementations.
*/
#include <__functions_malloc.h>

#endif
26 changes: 8 additions & 18 deletions basics/include/string.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
#ifndef __wasm_sysroot_string_h
#define __wasm_sysroot_string_h

#define __need_size_t
#define __need_NULL
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

void *memcpy(void *dst, const void *src, size_t n);
void *memmove(void *dst, const void *src, size_t n);
void *memset(void *dst, int c, size_t n);

#ifdef __cplusplus
}
#endif
#ifndef __wasm_string_h
#define __wasm_string_h

/*
* Include the real implementation, which is factored into a separate file so
* that it can be reused by other libc string implementations.
*/
#include <__functions_memcpy.h>

#endif
4 changes: 2 additions & 2 deletions basics/include/sys/stat.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef __wasm_sysroot_sys_stat_h
#define __wasm_sysroot_sys_stat_h
#ifndef __wasm_basics_sys_stat_h
#define __wasm_basics_sys_stat_h

#include <__struct_stat.h>

Expand Down
Loading

0 comments on commit 320054e

Please sign in to comment.