]> git.proxmox.com Git - wasi-libc.git/commitdiff
Use constructor functions for optional init routines. (#142)
authorDan Gohman <sunfish@mozilla.com>
Mon, 25 Nov 2019 22:04:45 +0000 (14:04 -0800)
committerGitHub <noreply@github.com>
Mon, 25 Nov 2019 22:04:45 +0000 (14:04 -0800)
* Use constructor functions for optional init routines.

Instead of using weak symbols, use constructor function attributes for the
environment and preopen initialization routines. This is simpler, uses
less code, and is more LTO-friendly.

* Change the constructor priorities to start at 50.

We don't currently have specific plans for other levels in the reserved
range (0-100), so leave room for both lower and higher priorities.

expected/wasm32-wasi/defined-symbols.txt
libc-bottom-half/crt/crt1.c
libc-bottom-half/headers/private/wasi/libc-internal.h [deleted file]
libc-bottom-half/libpreopen/libpreopen.c
libc-bottom-half/sources/__environ.c

index fda1ec8c44f7a3311629c127e1c1c5397a0c54a0..b3a46b869d597cf941ed06d10577d399c8b57f5a 100644 (file)
@@ -253,8 +253,6 @@ __wasilibc_fd_renumber
 __wasilibc_find_relpath
 __wasilibc_open_nomode
 __wasilibc_openat_nomode
-__wasilibc_populate_environ
-__wasilibc_populate_libpreopen
 __wasilibc_register_preopened_fd
 __wasilibc_rmdirat
 __wasilibc_tell
index c9f6644a83df49520bfe03482a2a75e35bbbc676..1b9cadb46999f2a0e1590f6bdcd6b29547855932 100644 (file)
@@ -1,31 +1,10 @@
-#include <stdlib.h>
-#include <sysexits.h>
 #include <wasi/api.h>
 #include <wasi/libc.h>
-#include <wasi/libc-internal.h>
-
-__wasi_errno_t __wasilibc_populate_environ(void) __attribute__((weak));
 extern void __wasm_call_ctors(void);
 extern int __original_main(void);
 extern void __prepare_for_exit(void);
-void _Exit(int) __attribute__((noreturn));
-__wasi_errno_t __wasilibc_populate_libpreopen(void) __attribute__((weak));
 
 void _start(void) {
-    // Record the preopened resources, if needed.
-    if (&__wasilibc_populate_libpreopen != NULL &&
-        __wasilibc_populate_libpreopen() != __WASI_ERRNO_SUCCESS)
-    {
-        _Exit(EX_OSERR);
-    }
-
-    // Fill in the environment from WASI syscalls, if needed.
-    if (&__wasilibc_populate_environ != NULL &&
-        __wasilibc_populate_environ() != __WASI_ERRNO_SUCCESS)
-    {
-        _Exit(EX_OSERR);
-    }
-
     // The linker synthesizes this to call constructors.
     __wasm_call_ctors();
 
@@ -38,8 +17,9 @@ void _start(void) {
     // Call atexit functions, destructors, stdio cleanup, etc.
     __prepare_for_exit();
 
-    // If main exited successfully, just return, otherwise call _Exit.
+    // If main exited successfully, just return, otherwise call
+    // `__wasi_proc_exit`.
     if (r != 0) {
-        _Exit(r);
+        __wasi_proc_exit(r);
     }
 }
diff --git a/libc-bottom-half/headers/private/wasi/libc-internal.h b/libc-bottom-half/headers/private/wasi/libc-internal.h
deleted file mode 100644 (file)
index e0dfd9b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __wasi_libc_internal_h
-#define __wasi_libc_internal_h
-
-#include <wasi/api.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void __wasilibc_init_preopen(void);
-__wasi_errno_t __wasilibc_populate_environ(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
index 8800b89e5d4db58ebd4bbf7ea8a9143a80955914..25c104066f3f1df23c1f3d2fa7205889c6facf21 100644 (file)
@@ -54,6 +54,7 @@
 #include <errno.h>
 #include <dirent.h>
 #include <assert.h>
+#include <sysexits.h>
 #include <wasi/libc.h>
 #include <wasi/libc-find-relpath.h>
 
@@ -522,7 +523,10 @@ __wasilibc_find_relpath(
 
 /// This is referenced by weak reference from crt1.c and lives in the same source
 /// file as `__wasilibc_find_relpath` so that it's linked in when it's needed.
-__wasi_errno_t
+// Concerning the 51 -- see the comment by the constructor priority in
+// libc-bottom-half/sources/__environ.c.
+__attribute__((constructor(51)))
+static void
 __wasilibc_populate_libpreopen(void)
 {
     // Skip stdin, stdout, and stderr, and count up until we reach an invalid
@@ -533,24 +537,24 @@ __wasilibc_populate_libpreopen(void)
         if (ret == __WASI_ERRNO_BADF)
             break;
         if (ret != __WASI_ERRNO_SUCCESS)
-            return ret;
+            goto oserr;
         switch (prestat.pr_type) {
         case __WASI_PREOPENTYPE_DIR: {
             char *path = malloc(prestat.u.dir.pr_name_len + 1);
             if (path == NULL)
-                return __WASI_ERRNO_NOMEM;
+                goto software;
 
             // TODO: Remove the cast on `path` once the witx is updated with char8 support.
             ret = __wasi_fd_prestat_dir_name(fd, (uint8_t *)path, prestat.u.dir.pr_name_len);
             if (ret != __WASI_ERRNO_SUCCESS) {
                 free(path);
-                return ret;
+                goto oserr;
             }
             path[prestat.u.dir.pr_name_len] = '\0';
 
             if (internal_register_preopened_fd(fd, path) != 0) {
                 free(path);
-                return __WASI_ERRNO_NOMEM;
+                goto software;
             }
 
             break;
@@ -560,5 +564,9 @@ __wasilibc_populate_libpreopen(void)
         }
     }
 
-    return __WASI_ERRNO_SUCCESS;
+    return;
+oserr:
+    _Exit(EX_OSERR);
+software:
+    _Exit(EX_SOFTWARE);
 }
index 38c82d44bcb6d9a5edb3815b6830a1524c13d0f6..ae1d8ac22a07c0ab69302ab7b42905f2f4b6a0a1 100644 (file)
@@ -1,18 +1,21 @@
 #include <unistd.h>
 #include <stdlib.h>
+#include <sysexits.h>
 #include <wasi/api.h>
 #include <wasi/libc.h>
-#include <wasi/libc-internal.h>
 
 static char *empty_environ[1] = { NULL };
 char **__environ = empty_environ;
 extern __typeof(__environ) _environ __attribute__((weak, alias("__environ")));
 extern __typeof(__environ) environ __attribute__((weak, alias("__environ")));
 
-// This function is referenced by a weak symbol in crt1.c, and we define
-// it here in the same source file as __environ, so that this function is
-// linked in iff environment variable support is used.
-__wasi_errno_t __wasilibc_populate_environ(void) {
+// We define this function here in the same source file as __environ, so that
+// this function is called in iff environment variable support is used.
+// Concerning the 50 -- levels up to 100 are reserved for the implementation,
+// so we an arbitrary number in the middle of the range to allow other
+// reserved things to go before or after.
+__attribute__((constructor(50)))
+static void __wasilibc_populate_environ(void) {
     __wasi_errno_t err;
 
     // Get the sizes of the arrays we'll have to create to copy in the environment.
@@ -20,22 +23,22 @@ __wasi_errno_t __wasilibc_populate_environ(void) {
     size_t environ_buf_size;
     err = __wasi_environ_sizes_get(&environ_count, &environ_buf_size);
     if (err != __WASI_ERRNO_SUCCESS) {
-        return err;
+        goto oserr;
     }
     if (environ_count == 0) {
-        return __WASI_ERRNO_SUCCESS;
+        return;
     }
 
     // Add 1 for the NULL pointer to mark the end, and check for overflow.
     size_t num_ptrs = environ_count + 1;
     if (num_ptrs == 0) {
-        return __WASI_ERRNO_NOMEM;
+        goto software;
     }
 
     // Allocate memory for storing the environment chars.
     char *environ_buf = malloc(environ_buf_size);
     if (environ_buf == NULL) {
-        return __WASI_ERRNO_NOMEM;
+        goto software;
     }
 
     // Allocate memory for the array of pointers. This uses `calloc` both to
@@ -43,17 +46,21 @@ __wasi_errno_t __wasilibc_populate_environ(void) {
     char **environ_ptrs = calloc(num_ptrs, sizeof(char *));
     if (environ_ptrs == NULL) {
         free(environ_buf);
-        return __WASI_ERRNO_NOMEM;
+        goto software;
     }
 
     // Fill the environment chars, and the __environ array with pointers into those chars.
     // TODO: Remove the casts on `environ_ptrs` and `environ_buf` once the witx is updated with char8 support.
     err = __wasi_environ_get((uint8_t **)environ_ptrs, (uint8_t *)environ_buf);
-    if (err == __WASI_ERRNO_SUCCESS) {
-        __environ = environ_ptrs;
-    } else {
+    if (err != __WASI_ERRNO_SUCCESS) {
         free(environ_buf);
         free(environ_ptrs);
+        goto oserr;
     }
-    return err;
+
+    __environ = environ_ptrs;
+oserr:
+    _Exit(EX_OSERR);
+software:
+    _Exit(EX_SOFTWARE);
 }