]> git.proxmox.com Git - wasi-libc.git/commitdiff
Don't link in libpreopen initialization code when it isn't needed. (#127)
authorDan Gohman <sunfish@mozilla.com>
Fri, 8 Nov 2019 19:08:22 +0000 (11:08 -0800)
committerGitHub <noreply@github.com>
Fri, 8 Nov 2019 19:08:22 +0000 (11:08 -0800)
* Avoid linking in `populate_libpreopen` when it isn't needed.

* Merge adjacent `if`s using `&&`.

expected/wasm32-wasi/defined-symbols.txt
libc-bottom-half/crt/crt1.c
libc-bottom-half/libpreopen/libpreopen.c

index d50f745b8f5bdc68d575d73cb08848dd6355dc5e..fda1ec8c44f7a3311629c127e1c1c5397a0c54a0 100644 (file)
@@ -254,6 +254,7 @@ __wasilibc_find_relpath
 __wasilibc_open_nomode
 __wasilibc_openat_nomode
 __wasilibc_populate_environ
+__wasilibc_populate_libpreopen
 __wasilibc_register_preopened_fd
 __wasilibc_rmdirat
 __wasilibc_tell
index ddf352f5144e4b149f0301b1de62708fb2bef4d8..59ca2bf5250c3ff0bcbf9f5d07da4a2f7fbba585 100644 (file)
@@ -9,57 +9,21 @@ extern void __wasm_call_ctors(void);
 extern int __original_main(void);
 extern void __prepare_for_exit(void);
 void _Exit(int) __attribute__((noreturn));
-
-static __wasi_errno_t populate_libpreopen(void) {
-    // Skip stdin, stdout, and stderr, and count up until we reach an invalid
-    // file descriptor.
-    for (__wasi_fd_t fd = 3; fd != 0; ++fd) {
-        __wasi_prestat_t prestat;
-        __wasi_errno_t ret = __wasi_fd_prestat_get(fd, &prestat);
-        if (ret == __WASI_EBADF)
-            break;
-        if (ret != __WASI_ESUCCESS)
-            return ret;
-        switch (prestat.pr_type) {
-        case __WASI_PREOPENTYPE_DIR: {
-            char *path = malloc(prestat.u.dir.pr_name_len + 1);
-            if (path == NULL)
-                return __WASI_ENOMEM;
-
-            ret = __wasi_fd_prestat_dir_name(fd, path, prestat.u.dir.pr_name_len);
-            if (ret != __WASI_ESUCCESS) {
-                free(path);
-                return ret;
-            }
-            path[prestat.u.dir.pr_name_len] = '\0';
-
-            if (__wasilibc_register_preopened_fd(fd, path) != 0) {
-                free(path);
-                return __WASI_ENOMEM;
-            }
-
-            free(path);
-            break;
-        }
-        default:
-            break;
-        }
-    }
-
-    return __WASI_ESUCCESS;
-}
+__wasi_errno_t __wasilibc_populate_libpreopen(void) __attribute__((weak));
 
 void _start(void) {
-    // Record the preopened resources.
-    if (populate_libpreopen() != __WASI_ESUCCESS) {
+    // Record the preopened resources, if needed.
+    if (&__wasilibc_populate_libpreopen != NULL &&
+        __wasilibc_populate_libpreopen() != __WASI_ESUCCESS)
+    {
         _Exit(EX_OSERR);
     }
 
     // Fill in the environment from WASI syscalls, if needed.
-    if (&__wasilibc_populate_environ != NULL) {
-        if (__wasilibc_populate_environ() != __WASI_ESUCCESS) {
-            _Exit(EX_OSERR);
-        }
+    if (&__wasilibc_populate_environ != NULL &&
+        __wasilibc_populate_environ() != __WASI_ESUCCESS)
+    {
+        _Exit(EX_OSERR);
     }
 
     // The linker synthesizes this to call constructors.
index 8a17a4268171a40242c9f60efb1f78c4361dcf8d..5cded23e647e2ddb17ac889b46c45c88bcffaf64 100644 (file)
@@ -555,3 +555,46 @@ __wasilibc_find_relpath(
     *relative_path = relpath;
     return best;
 }
+
+/// 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
+__wasilibc_populate_libpreopen(void)
+{
+    // Skip stdin, stdout, and stderr, and count up until we reach an invalid
+    // file descriptor.
+    for (__wasi_fd_t fd = 3; fd != 0; ++fd) {
+        __wasi_prestat_t prestat;
+        __wasi_errno_t ret = __wasi_fd_prestat_get(fd, &prestat);
+        if (ret == __WASI_EBADF)
+            break;
+        if (ret != __WASI_ESUCCESS)
+            return ret;
+        switch (prestat.pr_type) {
+        case __WASI_PREOPENTYPE_DIR: {
+            char *path = malloc(prestat.u.dir.pr_name_len + 1);
+            if (path == NULL)
+                return __WASI_ENOMEM;
+
+            ret = __wasi_fd_prestat_dir_name(fd, path, prestat.u.dir.pr_name_len);
+            if (ret != __WASI_ESUCCESS) {
+                free(path);
+                return ret;
+            }
+            path[prestat.u.dir.pr_name_len] = '\0';
+
+            if (__wasilibc_register_preopened_fd(fd, path) != 0) {
+                free(path);
+                return __WASI_ENOMEM;
+            }
+
+            free(path);
+            break;
+        }
+        default:
+            break;
+        }
+    }
+
+    return __WASI_ESUCCESS;
+}