LibC: Improve symbol visibility and naming consistency

This is largely inspired by https://github.com/ziglang/zig/issues/23879.
This commit is contained in:
Linus Groh
2025-05-27 23:03:30 +01:00
committed by Nico Weber
parent 6244c66593
commit a1bff1e1b6
12 changed files with 40 additions and 41 deletions

View File

@@ -41,7 +41,7 @@ private:
return Processor::current_thread()->get_allocation_enabled();
#elif defined(AK_OS_SERENITY)
// This extern thread-local lives in our LibC, which doesn't exist on other systems.
return s_allocation_enabled;
return __allocation_enabled;
#else
return true;
#endif
@@ -52,7 +52,7 @@ private:
#if defined(KERNEL)
Processor::current_thread()->set_allocation_enabled(value);
#elif defined(AK_OS_SERENITY)
s_allocation_enabled = value;
__allocation_enabled = value;
#else
(void)value;
#endif

View File

@@ -16,8 +16,6 @@
extern "C" {
extern bool __stdio_is_initialized;
void __assertion_failed(char const* msg)
{
if (__heap_is_stable) {

View File

@@ -17,7 +17,7 @@ inline void __pthread_maybe_cancel(void)
{
}
#else
void __pthread_maybe_cancel(void);
__attribute__((visibility("hidden"))) void __pthread_maybe_cancel(void);
#endif
__END_DECLS

View File

@@ -11,18 +11,18 @@
__BEGIN_DECLS
void __pthread_fork_prepare(void);
void __pthread_fork_child(void);
void __pthread_fork_parent(void);
void __pthread_fork_atfork_register_prepare(void (*)(void));
void __pthread_fork_atfork_register_parent(void (*)(void));
void __pthread_fork_atfork_register_child(void (*)(void));
__attribute__((visibility("hidden"))) void __pthread_fork_prepare(void);
__attribute__((visibility("hidden"))) void __pthread_fork_child(void);
__attribute__((visibility("hidden"))) void __pthread_fork_parent(void);
__attribute__((visibility("hidden"))) void __pthread_fork_atfork_register_prepare(void (*)(void));
__attribute__((visibility("hidden"))) void __pthread_fork_atfork_register_parent(void (*)(void));
__attribute__((visibility("hidden"))) void __pthread_fork_atfork_register_child(void (*)(void));
int __pthread_mutex_lock_pessimistic_np(pthread_mutex_t*);
__attribute__((visibility("hidden"))) int __pthread_mutex_lock_pessimistic_np(pthread_mutex_t*);
typedef void (*KeyDestructor)(void*);
void __pthread_key_destroy_for_current_thread(void);
__attribute__((visibility("hidden"))) void __pthread_key_destroy_for_current_thread(void);
#define __PTHREAD_MUTEX_NORMAL 0
#define __PTHREAD_MUTEX_RECURSIVE 1

View File

@@ -13,6 +13,6 @@
__BEGIN_DECLS
int __utimens(int fd, char const* path, struct timespec const times[2], int flag);
__attribute__((visibility("hidden"))) int __utimens(int fd, char const* path, struct timespec const times[2], int flag);
__END_DECLS

View File

@@ -17,8 +17,8 @@
[[gnu::weak]] Result<void, DlErrorMessage> __dladdr(void const*, Dl_info*) asm("__dladdr");
// FIXME: use thread_local and a String once TLS works
__thread char* s_dlerror_text = NULL;
__thread bool s_dlerror_retrieved = false;
static __thread char* s_dlerror_text = NULL;
static __thread bool s_dlerror_retrieved = false;
static void store_error(ByteString const& error)
{

View File

@@ -16,9 +16,9 @@
extern "C" {
#ifdef NO_TLS
int errno_storage;
static int s_errno_storage;
#else
__thread int errno_storage;
static __thread int s_errno_storage;
#endif
bool __environ_is_malloced = false;
bool __stdio_is_initialized = false;
@@ -31,7 +31,7 @@ uintptr_t __stack_chk_guard;
int* __errno_location()
{
return &errno_storage;
return &s_errno_storage;
}
void __libc_init()

View File

@@ -249,13 +249,13 @@ enum class CallerWillInitializeMemory {
};
#ifndef NO_TLS
__thread bool s_allocation_enabled = true;
__thread bool __allocation_enabled = true;
#endif
static ErrorOr<void*> malloc_impl(size_t size, size_t align, CallerWillInitializeMemory caller_will_initialize_memory)
{
#ifndef NO_TLS
VERIFY(s_allocation_enabled);
VERIFY(__allocation_enabled);
#endif
// Align must be a power of 2.
@@ -397,7 +397,7 @@ static ErrorOr<void*> malloc_impl(size_t size, size_t align, CallerWillInitializ
static void free_impl(void* ptr)
{
#ifndef NO_TLS
VERIFY(s_allocation_enabled);
VERIFY(__allocation_enabled);
#endif
ScopedValueRollback rollback(errno);

View File

@@ -21,7 +21,7 @@ static constexpr size_t num_size_classes = (sizeof(size_classes) / sizeof(unsign
#ifndef NO_TLS
extern "C" {
extern __thread bool s_allocation_enabled;
extern __thread bool __allocation_enabled;
}
#endif

View File

@@ -35,11 +35,11 @@ using PthreadAttrImpl = Syscall::SC_create_thread_params;
static constexpr size_t required_stack_alignment = 4 * MiB;
static constexpr size_t highest_reasonable_guard_size = 32 * PAGE_SIZE;
__thread void* s_stack_location;
__thread size_t s_stack_size;
static __thread void* s_stack_location;
static __thread size_t s_stack_size;
__thread int s_thread_cancel_state = PTHREAD_CANCEL_ENABLE;
__thread int s_thread_cancel_type = PTHREAD_CANCEL_DEFERRED;
static __thread int s_thread_cancel_state = PTHREAD_CANCEL_ENABLE;
static __thread int s_thread_cancel_type = PTHREAD_CANCEL_DEFERRED;
#define __RETURN_PTHREAD_ERROR(rc) \
return ((rc) < 0 ? -(rc) : 0)
@@ -49,9 +49,9 @@ struct CleanupHandler {
void* argument;
};
static thread_local SinglyLinkedList<CleanupHandler> cleanup_handlers;
static thread_local SinglyLinkedList<CleanupHandler> s_cleanup_handlers;
static __thread bool pending_cancellation = false;
static __thread bool s_pending_cancellation = false;
[[gnu::weak]] extern ErrorOr<FlatPtr> __create_new_tls_region() asm("__create_new_tls_region");
[[gnu::weak]] extern ErrorOr<void> __free_tls_region(FlatPtr thread_pointer) asm("__free_tls_region");
@@ -166,8 +166,8 @@ int pthread_create(pthread_t* thread, pthread_attr_t const* attributes, void* (*
// https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_exit.html
void pthread_exit(void* value_ptr)
{
while (!cleanup_handlers.is_empty()) {
auto handler = cleanup_handlers.take_first();
while (!s_cleanup_handlers.is_empty()) {
auto handler = s_cleanup_handlers.take_first();
handler.routine(handler.argument);
}
@@ -182,7 +182,7 @@ void __pthread_maybe_cancel()
return;
// Check if a cancellation request is pending.
if (!pending_cancellation)
if (!s_pending_cancellation)
return;
// Exit the thread via `pthread_exit`. This handles passing the
@@ -194,15 +194,15 @@ void __pthread_maybe_cancel()
// https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cleanup_push.html
void pthread_cleanup_push(void (*routine)(void*), void* arg)
{
cleanup_handlers.prepend({ routine, arg });
s_cleanup_handlers.prepend({ routine, arg });
}
// https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cleanup_pop.html
void pthread_cleanup_pop(int execute)
{
VERIFY(!cleanup_handlers.is_empty());
VERIFY(!s_cleanup_handlers.is_empty());
auto handler = cleanup_handlers.take_first();
auto handler = s_cleanup_handlers.take_first();
if (execute)
handler.routine(handler.argument);
@@ -545,7 +545,7 @@ static void pthread_cancel_signal_handler(int signal)
// Note: We don't handle PTHREAD_CANCEL_ASYNCHRONOUS any different from PTHREAD_CANCEL_DEFERRED,
// since ASYNCHRONOUS just means that the thread can be cancelled at any time (instead of just
// at the next cancellation point) and it seems to be generally discouraged to use it at all.
pending_cancellation = true;
s_pending_cancellation = true;
}
// https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_cancel.html

View File

@@ -26,7 +26,7 @@ struct SpecificTable {
static KeyTable s_keys;
__thread SpecificTable t_specifics;
static __thread SpecificTable s_specifics;
// https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_key_create.html
int pthread_key_create(pthread_key_t* key, KeyDestructor destructor)
@@ -62,7 +62,7 @@ void* pthread_getspecific(pthread_key_t key)
return nullptr;
if (key >= max_keys)
return nullptr;
return t_specifics.values[key];
return s_specifics.values[key];
}
// https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_setspecific.html
@@ -73,7 +73,7 @@ int pthread_setspecific(pthread_key_t key, void const* value)
if (key >= max_keys)
return EINVAL;
t_specifics.values[key] = const_cast<void*>(value);
s_specifics.values[key] = const_cast<void*>(value);
return 0;
}
@@ -91,7 +91,7 @@ void __pthread_key_destroy_for_current_thread()
for (size_t destruct_iteration = 0; destruct_iteration < PTHREAD_DESTRUCTOR_ITERATIONS; ++destruct_iteration) {
bool any_nonnull_destructors = false;
for (size_t key_index = 0; key_index < num_used_keys; ++key_index) {
void* value = exchange(t_specifics.values[key_index], nullptr);
void* value = exchange(s_specifics.values[key_index], nullptr);
if (value && s_keys.destructors[key_index]) {
any_nonnull_destructors = true;

View File

@@ -13,11 +13,12 @@ __BEGIN_DECLS
typedef void (*AtExitFunction)(void*);
// NOTE: Ideally these symbols would be hidden but some of them are needed by crt0, ubsan, and the dynamic linker.
extern void __libc_init();
extern void __malloc_init(void);
extern void __stdio_init(void);
extern void __begin_atexit_locking(void);
extern void _init(void);
extern bool __environ_is_malloced;
extern bool __stdio_is_initialized;
extern bool __heap_is_stable;