Browse Source

Don't run static constructors on arbitrary user exports.

Previously, "new-style commmands" considered every user-defined
export to be a potential command entrypoint, so wasi-libc and wasm-ld
cooperated to run the user's static constructors on each entrypoint.

This form of new-style command turned out not to be useful, and it
interferes with some use cases, so disable it.

This is done by making an explicit call to `__wasm_call_ctors`, which
tells wasm-ld that it shouldn't synthesize any calls to
`__wasm_call_ctors` on its own.
pull/329/head
Dan Gohman 2 years ago
parent
commit
907d10fecb
  1. 12
      libc-bottom-half/crt/crt1-command.c
  2. 27
      libc-bottom-half/crt/crt1.c

12
libc-bottom-half/crt/crt1-command.c

@ -1,18 +1,24 @@
#include <wasi/api.h> #include <wasi/api.h>
#include <stdlib.h>
extern void __wasm_call_ctors(void); extern void __wasm_call_ctors(void);
extern int __main_void(void); extern int __main_void(void);
extern void __wasm_call_dtors(void); extern void __wasm_call_dtors(void);
__attribute__((export_name("_start"))) __attribute__((export_name("_start")))
void _start(void) { void _start(void) {
// The linker synthesizes this to call constructors.
__wasm_call_ctors();
// Call `__main_void` which will either be the application's zero-argument // Call `__main_void` which will either be the application's zero-argument
// `__main_void` function or a libc routine which obtains the command-line // `__main_void` function or a libc routine which obtains the command-line
// arguments and calls `__main_argv_argc`. // arguments and calls `__main_argv_argc`.
int r = __main_void(); int r = __main_void();
// If main exited successfully, just return, otherwise call `exit`. // Call atexit functions, destructors, stdio cleanup, etc.
__wasm_call_dtors();
// If main exited successfully, just return, otherwise call
// `__wasi_proc_exit`.
if (r != 0) { if (r != 0) {
exit(r); __wasi_proc_exit(r);
} }
} }

27
libc-bottom-half/crt/crt1.c

@ -1,24 +1,3 @@
#include <wasi/api.h> // We compile a plain crt1.o for toolchain compatibility, but it's
extern void __wasm_call_ctors(void); // identical to crt1-command.o.
extern int __main_void(void); #include <crt1-command.c>
extern void __wasm_call_dtors(void);
__attribute__((export_name("_start")))
void _start(void) {
// The linker synthesizes this to call constructors.
__wasm_call_ctors();
// Call `__main_void` which will either be the application's zero-argument
// `__main_void` function or a libc routine which obtains the command-line
// arguments and calls `__main_argv_argc`.
int r = __main_void();
// Call atexit functions, destructors, stdio cleanup, etc.
__wasm_call_dtors();
// If main exited successfully, just return, otherwise call
// `__wasi_proc_exit`.
if (r != 0) {
__wasi_proc_exit(r);
}
}

Loading…
Cancel
Save