From 5c047e0e365aaae178a01f86221718a79483b533 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 8 Aug 2025 16:05:07 +0900 Subject: [PATCH] always use __errno_location for user ABI upsides: * by avoiding direct accesses to the TLS, increase the chances for third-party libraries to provide a single binary for threaded and non-threaded wasi targets. see [1] for an example. downsides: * increase the overhead of errno accesses. i suppose it isn't critical as errno is typically only accessed in the error handling logic. there are a few apis like strtoul which require errno accesses even in successful cases though. [1] https://github.com/bytecodealliance/wasm-micro-runtime/blob/d95b0e3d46da8e88f484f236cb4222f5a6dc5926/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c#L15-L33 --- Makefile | 3 ++- expected/wasm32-wasip1-threads/predefined-macros.txt | 2 +- expected/wasm32-wasip1/predefined-macros.txt | 2 +- expected/wasm32-wasip2/predefined-macros.txt | 2 +- libc-bottom-half/headers/public/__errno.h | 8 +++++++- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 19145f7ea..c39ce84f7 100644 --- a/Makefile +++ b/Makefile @@ -475,6 +475,7 @@ endif endif endif +CFLAGS += -D_BUILDING_WASI_LIBC ifeq ($(WASI_SNAPSHOT), p2) CFLAGS += -D__wasilibc_use_wasip2 endif @@ -971,7 +972,7 @@ check-symbols: $(STARTUP_FILES) libc @# TODO: Undefine __wasm_nontrapping_fptoint__, __wasm_bulk_memory__ and @# __wasm_bulk_memory_opt__, that are new to clang 20. @# TODO: As of clang 16, __GNUC_VA_LIST is #defined without a value. - $(CC) $(CFLAGS) "$(SYSROOT_SHARE)/include-all.c" \ + $(CC) $(CFLAGS) -U_BUILDING_WASI_LIBC "$(SYSROOT_SHARE)/include-all.c" \ -isystem $(SYSROOT_INC) \ -std=gnu17 \ -E -dM -Wno-\#warnings \ diff --git a/expected/wasm32-wasip1-threads/predefined-macros.txt b/expected/wasm32-wasip1-threads/predefined-macros.txt index f691c853a..093d6d73a 100644 --- a/expected/wasm32-wasip1-threads/predefined-macros.txt +++ b/expected/wasm32-wasip1-threads/predefined-macros.txt @@ -3255,7 +3255,7 @@ #define dirent64 dirent #define erf(x) __tg_real(erf, (x)) #define erfc(x) __tg_real(erfc, (x)) -#define errno errno +#define errno (*__errno_location()) #define exp(x) __tg_real_complex(exp, (x)) #define exp2(x) __tg_real(exp2, (x)) #define expm1(x) __tg_real(expm1, (x)) diff --git a/expected/wasm32-wasip1/predefined-macros.txt b/expected/wasm32-wasip1/predefined-macros.txt index 66f4c4c88..a91a454d5 100644 --- a/expected/wasm32-wasip1/predefined-macros.txt +++ b/expected/wasm32-wasip1/predefined-macros.txt @@ -3250,7 +3250,7 @@ #define dirent64 dirent #define erf(x) __tg_real(erf, (x)) #define erfc(x) __tg_real(erfc, (x)) -#define errno errno +#define errno (*__errno_location()) #define exp(x) __tg_real_complex(exp, (x)) #define exp2(x) __tg_real(exp2, (x)) #define expm1(x) __tg_real(expm1, (x)) diff --git a/expected/wasm32-wasip2/predefined-macros.txt b/expected/wasm32-wasip2/predefined-macros.txt index 1ae2e1fd2..99589ae5c 100644 --- a/expected/wasm32-wasip2/predefined-macros.txt +++ b/expected/wasm32-wasip2/predefined-macros.txt @@ -3403,7 +3403,7 @@ #define dirent64 dirent #define erf(x) __tg_real(erf, (x)) #define erfc(x) __tg_real(erfc, (x)) -#define errno errno +#define errno (*__errno_location()) #define exp(x) __tg_real_complex(exp, (x)) #define exp2(x) __tg_real(exp2, (x)) #define expm1(x) __tg_real(expm1, (x)) diff --git a/libc-bottom-half/headers/public/__errno.h b/libc-bottom-half/headers/public/__errno.h index 008245d97..6e1e91d3a 100644 --- a/libc-bottom-half/headers/public/__errno.h +++ b/libc-bottom-half/headers/public/__errno.h @@ -5,9 +5,15 @@ extern "C" { #endif +#ifdef _BUILDING_WASI_LIBC +/* libc internal access */ extern _Thread_local int errno; - #define errno errno +#else +/* user exposed ABI */ +__attribute__((__const__)) int *__errno_location(void); +#define errno (*__errno_location()) +#endif #ifdef __cplusplus }