summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src
diff options
context:
space:
mode:
Diffstat (limited to 'libc-top-half/musl/src')
-rw-r--r--libc-top-half/musl/src/env/__init_tls.c36
-rw-r--r--libc-top-half/musl/src/internal/locale_impl.h8
-rw-r--r--libc-top-half/musl/src/misc/dl.c45
-rw-r--r--libc-top-half/musl/src/setjmp/wasm32/rt.c83
-rw-r--r--libc-top-half/musl/src/thread/pthread_create.c17
-rw-r--r--libc-top-half/musl/src/thread/pthread_getattr_np.c6
6 files changed, 179 insertions, 16 deletions
diff --git a/libc-top-half/musl/src/env/__init_tls.c b/libc-top-half/musl/src/env/__init_tls.c
index c3e407c..4f4c221 100644
--- a/libc-top-half/musl/src/env/__init_tls.c
+++ b/libc-top-half/musl/src/env/__init_tls.c
@@ -31,25 +31,35 @@ extern unsigned char __global_base;
extern weak unsigned char __stack_high;
extern weak unsigned char __stack_low;
-static inline void setup_default_stack_size()
+struct stack_bounds {
+ void *base;
+ size_t size;
+};
+
+static inline struct stack_bounds get_stack_bounds()
{
- ptrdiff_t stack_size;
+ struct stack_bounds bounds;
- if (&__stack_high)
- stack_size = &__stack_high - &__stack_low;
- else {
+ if (&__stack_high) {
+ bounds.base = &__stack_high;
+ bounds.size = &__stack_high - &__stack_low;
+ } else {
unsigned char *sp;
__asm__(
".globaltype __stack_pointer, i32\n"
"global.get __stack_pointer\n"
"local.set %0\n"
: "=r"(sp));
- stack_size = sp > &__global_base ? &__heap_base - &__data_end : (ptrdiff_t)&__global_base;
+ if (sp > &__global_base) {
+ bounds.base = &__heap_base;
+ bounds.size = &__heap_base - &__data_end;
+ } else {
+ bounds.base = &__global_base;
+ bounds.size = (size_t)&__global_base;
+ }
}
- __default_stacksize =
- stack_size < DEFAULT_STACK_MAX ?
- stack_size : DEFAULT_STACK_MAX;
+ return bounds;
}
void __wasi_init_tp() {
@@ -68,8 +78,14 @@ int __init_tp(void *p)
td->detach_state = DT_JOINABLE;
td->tid = __syscall(SYS_set_tid_address, &__thread_list_lock);
#else
- setup_default_stack_size();
+ struct stack_bounds bounds = get_stack_bounds();
+ __default_stacksize =
+ bounds.size < DEFAULT_STACK_MAX ?
+ bounds.size : DEFAULT_STACK_MAX;
td->detach_state = DT_JOINABLE;
+ td->stack = bounds.base;
+ td->stack_size = bounds.size;
+ td->guard_size = 0;
/*
* Initialize the TID to a value which doesn't conflict with
* host-allocated TIDs, so that TID-based locks can work.
diff --git a/libc-top-half/musl/src/internal/locale_impl.h b/libc-top-half/musl/src/internal/locale_impl.h
index 7f79b7f..4649a43 100644
--- a/libc-top-half/musl/src/internal/locale_impl.h
+++ b/libc-top-half/musl/src/internal/locale_impl.h
@@ -28,7 +28,15 @@ extern hidden const struct __locale_struct __c_dot_utf8_locale;
hidden const struct __locale_map *__get_locale(int, const char *);
hidden const char *__mo_lookup(const void *, size_t, const char *);
hidden const char *__lctrans(const char *, const struct __locale_map *);
+#ifdef __wasilibc_unmodified_upstream
hidden const char *__lctrans_cur(const char *);
+#else
+// We make this visible in the wasi-libc build because
+// libwasi-emulated-signal.so needs to import it from libc.so. If we ever
+// decide to merge libwasi-emulated-signal.so into libc.so, this will no longer
+// be necessary.
+const char *__lctrans_cur(const char *);
+#endif
hidden const char *__lctrans_impl(const char *, const struct __locale_map *);
hidden int __loc_is_allocated(locale_t);
hidden char *__gettextdomain(void);
diff --git a/libc-top-half/musl/src/misc/dl.c b/libc-top-half/musl/src/misc/dl.c
new file mode 100644
index 0000000..266594f
--- /dev/null
+++ b/libc-top-half/musl/src/misc/dl.c
@@ -0,0 +1,45 @@
+/* This file is used to build libdl.so with stub versions of `dlopen`, `dlsym`,
+ * etc. The intention is that this stubbed libdl.so can be used to build
+ * libraries and applications which use `dlopen` without committing to a
+ * specific runtime implementation. Later, it can be replaced with a real,
+ * working libdl.so (e.g. at runtime or component composition time).
+ *
+ * For example, the `wasm-tools component link` subcommand can be used to create
+ * a component that bundles any `dlopen`-able libraries in such a way that their
+ * function exports can be resolved symbolically at runtime using an
+ * implementation of libdl.so designed for that purpose. In other cases, a
+ * runtime might provide Emscripten-style dynamic linking via URLs or else a
+ * more traditional, filesystem-based implementation. Finally, even this
+ * stubbed version of libdl.so can be used at runtime in cases where dynamic
+ * library resolution cannot or should not be supported (and the application can
+ * handle this situation gracefully). */
+
+#include <stddef.h>
+#include <dlfcn.h>
+
+static const char *error = NULL;
+
+weak int dlclose(void *library)
+{
+ error = "dlclose not implemented";
+ return -1;
+}
+
+weak char *dlerror(void)
+{
+ const char *var = error;
+ error = NULL;
+ return (char*) var;
+}
+
+weak void *dlopen(const char *name, int flags)
+{
+ error = "dlopen not implemented";
+ return NULL;
+}
+
+weak void *dlsym(void *library, const char *name)
+{
+ error = "dlsym not implemented";
+ return NULL;
+}
diff --git a/libc-top-half/musl/src/setjmp/wasm32/rt.c b/libc-top-half/musl/src/setjmp/wasm32/rt.c
new file mode 100644
index 0000000..24e4e33
--- /dev/null
+++ b/libc-top-half/musl/src/setjmp/wasm32/rt.c
@@ -0,0 +1,83 @@
+/*
+ * a runtime implementation for
+ * https://github.com/llvm/llvm-project/pull/84137
+ * https://docs.google.com/document/d/1ZvTPT36K5jjiedF8MCXbEmYjULJjI723aOAks1IdLLg/edit
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+
+/*
+ * function prototypes
+ */
+void __wasm_setjmp(void *env, uint32_t label, void *func_invocation_id);
+uint32_t __wasm_setjmp_test(void *env, void *func_invocation_id);
+void __wasm_longjmp(void *env, int val);
+
+/*
+ * jmp_buf should have large enough size and alignment to contain
+ * this structure.
+ */
+struct jmp_buf_impl {
+ void *func_invocation_id;
+ uint32_t label;
+
+ /*
+ * this is a temorary storage used by the communication between
+ * __wasm_sjlj_longjmp and WebAssemblyLowerEmscriptenEHSjL-generated
+ * logic.
+ * ideally, this can be replaced with multivalue.
+ */
+ struct arg {
+ void *env;
+ int val;
+ } arg;
+};
+
+void
+__wasm_setjmp(void *env, uint32_t label, void *func_invocation_id)
+{
+ struct jmp_buf_impl *jb = env;
+ if (label == 0) { /* ABI contract */
+ __builtin_trap();
+ }
+ if (func_invocation_id == NULL) { /* sanity check */
+ __builtin_trap();
+ }
+ jb->func_invocation_id = func_invocation_id;
+ jb->label = label;
+}
+
+uint32_t
+__wasm_setjmp_test(void *env, void *func_invocation_id)
+{
+ struct jmp_buf_impl *jb = env;
+ if (jb->label == 0) { /* ABI contract */
+ __builtin_trap();
+ }
+ if (func_invocation_id == NULL) { /* sanity check */
+ __builtin_trap();
+ }
+ if (jb->func_invocation_id == func_invocation_id) {
+ return jb->label;
+ }
+ return 0;
+}
+
+void
+__wasm_longjmp(void *env, int val)
+{
+ struct jmp_buf_impl *jb = env;
+ struct arg *arg = &jb->arg;
+ /*
+ * C standard says:
+ * The longjmp function cannot cause the setjmp macro to return
+ * the value 0; if val is 0, the setjmp macro returns the value 1.
+ */
+ if (val == 0) {
+ val = 1;
+ }
+ arg->env = env;
+ arg->val = val;
+ __builtin_wasm_throw(1, arg); /* 1 == C_LONGJMP */
+}
diff --git a/libc-top-half/musl/src/thread/pthread_create.c b/libc-top-half/musl/src/thread/pthread_create.c
index 5de9f5a..450fe15 100644
--- a/libc-top-half/musl/src/thread/pthread_create.c
+++ b/libc-top-half/musl/src/thread/pthread_create.c
@@ -13,6 +13,7 @@
#endif
#include <stdalign.h>
+#include <assert.h>
static void dummy_0()
{
@@ -558,13 +559,17 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
__wait(&args->control, 0, 3, 0);
}
#else
+#define WASI_THREADS_MAX_TID 0x1FFFFFFF
/* `wasi_thread_spawn` will either return a host-provided thread ID (TID)
- * (`>= 0`) or an error code (`< 0`). As in the unmodified version, all
- * spawn failures translate to EAGAIN; unlike the modified version, there is
- * no need to "start up" the child thread--the host does this. If the spawn
- * did succeed, then we store the TID atomically, since this parent thread
- * is racing with the child thread to set this field; this way, whichever
- * thread reaches this point first can continue without waiting. */
+ * (`<1, 0x1FFFFFFF>`) or an error code (`< 0`). Please note that `0` is
+ * reserved for compatibility reasons and must not be returned by the runtime.
+ * As in the unmodified version, all spawn failures translate to EAGAIN;
+ * unlike the modified version, there is no need to "start up" the child
+ * thread--the host does this. If the spawn did succeed, then we store the
+ * TID atomically, since this parent thread is racing with the child thread
+ * to set this field; this way, whichever thread reaches this point first
+ * can continue without waiting. */
+ assert(ret != 0 && ret <= WASI_THREADS_MAX_TID);
if (ret < 0) {
ret = -EAGAIN;
} else {
diff --git a/libc-top-half/musl/src/thread/pthread_getattr_np.c b/libc-top-half/musl/src/thread/pthread_getattr_np.c
index 2881831..c23e5d7 100644
--- a/libc-top-half/musl/src/thread/pthread_getattr_np.c
+++ b/libc-top-half/musl/src/thread/pthread_getattr_np.c
@@ -1,7 +1,9 @@
#define _GNU_SOURCE
#include "pthread_impl.h"
#include "libc.h"
+#ifdef __wasilibc_unmodified_upstream
#include <sys/mman.h>
+#endif
int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
{
@@ -12,6 +14,7 @@ int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
a->_a_stackaddr = (uintptr_t)t->stack;
a->_a_stacksize = t->stack_size;
} else {
+#ifdef __wasilibc_unmodified_upstream
char *p = (void *)libc.auxv;
size_t l = PAGE_SIZE;
p += -(uintptr_t)p & PAGE_SIZE-1;
@@ -19,6 +22,9 @@ int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
while (mremap(p-l-PAGE_SIZE, PAGE_SIZE, 2*PAGE_SIZE, 0)==MAP_FAILED && errno==ENOMEM)
l += PAGE_SIZE;
a->_a_stacksize = l;
+#else
+ return ENOSYS;
+#endif
}
return 0;
}