1#include "libc.h" 2#include "threads_impl.h" 3#include <dlfcn.h> 4#include <stdarg.h> 5#include <stdlib.h> 6 7char* dlerror(void) { 8 thrd_t self = __thrd_current(); 9 if (!self->dlerror_flag) 10 return 0; 11 self->dlerror_flag = 0; 12 char* s = self->dlerror_buf; 13 if (s == (void*)-1) 14 return (char*)"Dynamic linker failed to allocate memory for error message"; 15 else 16 return s; 17} 18 19void __dl_thread_cleanup(void) { 20 thrd_t self = __thrd_current(); 21 if (self->dlerror_buf != (void*)-1) 22 free(self->dlerror_buf); 23} 24 25__attribute__((__visibility__("hidden"))) void __dl_vseterr(const char* fmt, va_list ap) { 26 va_list ap2; 27 va_copy(ap2, ap); 28 thrd_t self = __thrd_current(); 29 if (self->dlerror_buf != (void*)-1) 30 free(self->dlerror_buf); 31 size_t len = vsnprintf(0, 0, fmt, ap2); 32 va_end(ap2); 33 char* buf = malloc(len + 1); 34 if (buf) { 35 vsnprintf(buf, len + 1, fmt, ap); 36 } else { 37 buf = (void*)-1; 38 } 39 self->dlerror_buf = buf; 40 self->dlerror_flag = 1; 41} 42 43__attribute__((__visibility__("hidden"))) void __dl_seterr(const char* fmt, ...) { 44 va_list ap; 45 va_start(ap, fmt); 46 __dl_vseterr(fmt, ap); 47 va_end(ap); 48} 49 50__attribute__((__visibility__("hidden"))) int __dl_invalid_handle(void*); 51 52static int stub_invalid_handle(void* h) { 53 __dl_seterr("Invalid library handle %p", (void*)h); 54 return 1; 55} 56 57weak_alias(stub_invalid_handle, __dl_invalid_handle); 58