diff --git a/libc-bottom-half/crt/crt1-command.c b/libc-bottom-half/crt/crt1-command.c index 6e2bcd942..48be79f7e 100644 --- a/libc-bottom-half/crt/crt1-command.c +++ b/libc-bottom-half/crt/crt1-command.c @@ -1,19 +1,33 @@ +#ifdef _REENTRANT +#include +#endif #include extern void __wasm_call_ctors(void); extern int __main_void(void); extern void __wasm_call_dtors(void); -// Commands should only be called once per instance. This simple check ensures -// that the `_start` function isn't started more than once. -static volatile int started = 0; - __attribute__((export_name("_start"))) void _start(void) { - // Don't allow the program to be called multiple times. + // Commands should only be called once per instance. This simple check + // ensures that the `_start` function isn't started more than once. + // + // We use `volatile` here to prevent the store to `started` from being + // sunk past any subsequent code, and to prevent any compiler from + // optimizing based on the knowledge that `_start` is the program + // entrypoint. +#ifdef _REENTRANT + static volatile _Atomic int started = 0; + int expected = 0; + if (!atomic_compare_exchange_strong(&started, &expected, 1)) { + __builtin_trap(); + } +#else + static volatile int started = 0; if (started != 0) { __builtin_trap(); } started = 1; +#endif // The linker synthesizes this to call constructors. __wasm_call_ctors();