Skip to content

Commit

Permalink
Don't link in libpreopen initialization code when it isn't needed. (W…
Browse files Browse the repository at this point in the history
…ebAssembly#127)

* Avoid linking in `populate_libpreopen` when it isn't needed.

* Merge adjacent `if`s using `&&`.
  • Loading branch information
sunfishcode authored Nov 8, 2019
1 parent ec4549d commit 70099d4
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 45 deletions.
1 change: 1 addition & 0 deletions expected/wasm32-wasi/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
54 changes: 9 additions & 45 deletions libc-bottom-half/crt/crt1.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
43 changes: 43 additions & 0 deletions libc-bottom-half/libpreopen/libpreopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 70099d4

Please sign in to comment.