Skip to content

Commit 70099d4

Browse files
authored
Don't link in libpreopen initialization code when it isn't needed. (#127)
* Avoid linking in `populate_libpreopen` when it isn't needed. * Merge adjacent `if`s using `&&`.
1 parent ec4549d commit 70099d4

3 files changed

Lines changed: 53 additions & 45 deletions

File tree

expected/wasm32-wasi/defined-symbols.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ __wasilibc_find_relpath
254254
__wasilibc_open_nomode
255255
__wasilibc_openat_nomode
256256
__wasilibc_populate_environ
257+
__wasilibc_populate_libpreopen
257258
__wasilibc_register_preopened_fd
258259
__wasilibc_rmdirat
259260
__wasilibc_tell

libc-bottom-half/crt/crt1.c

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,57 +9,21 @@ extern void __wasm_call_ctors(void);
99
extern int __original_main(void);
1010
extern void __prepare_for_exit(void);
1111
void _Exit(int) __attribute__((noreturn));
12-
13-
static __wasi_errno_t populate_libpreopen(void) {
14-
// Skip stdin, stdout, and stderr, and count up until we reach an invalid
15-
// file descriptor.
16-
for (__wasi_fd_t fd = 3; fd != 0; ++fd) {
17-
__wasi_prestat_t prestat;
18-
__wasi_errno_t ret = __wasi_fd_prestat_get(fd, &prestat);
19-
if (ret == __WASI_EBADF)
20-
break;
21-
if (ret != __WASI_ESUCCESS)
22-
return ret;
23-
switch (prestat.pr_type) {
24-
case __WASI_PREOPENTYPE_DIR: {
25-
char *path = malloc(prestat.u.dir.pr_name_len + 1);
26-
if (path == NULL)
27-
return __WASI_ENOMEM;
28-
29-
ret = __wasi_fd_prestat_dir_name(fd, path, prestat.u.dir.pr_name_len);
30-
if (ret != __WASI_ESUCCESS) {
31-
free(path);
32-
return ret;
33-
}
34-
path[prestat.u.dir.pr_name_len] = '\0';
35-
36-
if (__wasilibc_register_preopened_fd(fd, path) != 0) {
37-
free(path);
38-
return __WASI_ENOMEM;
39-
}
40-
41-
free(path);
42-
break;
43-
}
44-
default:
45-
break;
46-
}
47-
}
48-
49-
return __WASI_ESUCCESS;
50-
}
12+
__wasi_errno_t __wasilibc_populate_libpreopen(void) __attribute__((weak));
5113

5214
void _start(void) {
53-
// Record the preopened resources.
54-
if (populate_libpreopen() != __WASI_ESUCCESS) {
15+
// Record the preopened resources, if needed.
16+
if (&__wasilibc_populate_libpreopen != NULL &&
17+
__wasilibc_populate_libpreopen() != __WASI_ESUCCESS)
18+
{
5519
_Exit(EX_OSERR);
5620
}
5721

5822
// Fill in the environment from WASI syscalls, if needed.
59-
if (&__wasilibc_populate_environ != NULL) {
60-
if (__wasilibc_populate_environ() != __WASI_ESUCCESS) {
61-
_Exit(EX_OSERR);
62-
}
23+
if (&__wasilibc_populate_environ != NULL &&
24+
__wasilibc_populate_environ() != __WASI_ESUCCESS)
25+
{
26+
_Exit(EX_OSERR);
6327
}
6428

6529
// The linker synthesizes this to call constructors.

libc-bottom-half/libpreopen/libpreopen.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,3 +555,46 @@ __wasilibc_find_relpath(
555555
*relative_path = relpath;
556556
return best;
557557
}
558+
559+
/// This is referenced by weak reference from crt1.c and lives in the same source
560+
/// file as `__wasilibc_find_relpath` so that it's linked in when it's needed.
561+
__wasi_errno_t
562+
__wasilibc_populate_libpreopen(void)
563+
{
564+
// Skip stdin, stdout, and stderr, and count up until we reach an invalid
565+
// file descriptor.
566+
for (__wasi_fd_t fd = 3; fd != 0; ++fd) {
567+
__wasi_prestat_t prestat;
568+
__wasi_errno_t ret = __wasi_fd_prestat_get(fd, &prestat);
569+
if (ret == __WASI_EBADF)
570+
break;
571+
if (ret != __WASI_ESUCCESS)
572+
return ret;
573+
switch (prestat.pr_type) {
574+
case __WASI_PREOPENTYPE_DIR: {
575+
char *path = malloc(prestat.u.dir.pr_name_len + 1);
576+
if (path == NULL)
577+
return __WASI_ENOMEM;
578+
579+
ret = __wasi_fd_prestat_dir_name(fd, path, prestat.u.dir.pr_name_len);
580+
if (ret != __WASI_ESUCCESS) {
581+
free(path);
582+
return ret;
583+
}
584+
path[prestat.u.dir.pr_name_len] = '\0';
585+
586+
if (__wasilibc_register_preopened_fd(fd, path) != 0) {
587+
free(path);
588+
return __WASI_ENOMEM;
589+
}
590+
591+
free(path);
592+
break;
593+
}
594+
default:
595+
break;
596+
}
597+
}
598+
599+
return __WASI_ESUCCESS;
600+
}

0 commit comments

Comments
 (0)