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