| Index: fusl/src/ldso/dlerror.c
|
| diff --git a/fusl/src/ldso/dlerror.c b/fusl/src/ldso/dlerror.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..378f035647c520e7b8a31026a2ba4654a5ee2852
|
| --- /dev/null
|
| +++ b/fusl/src/ldso/dlerror.c
|
| @@ -0,0 +1,64 @@
|
| +#include <dlfcn.h>
|
| +#include <stdlib.h>
|
| +#include <stdarg.h>
|
| +#include "pthread_impl.h"
|
| +#include "libc.h"
|
| +
|
| +char *dlerror()
|
| +{
|
| + pthread_t self = __pthread_self();
|
| + if (!self->dlerror_flag) return 0;
|
| + self->dlerror_flag = 0;
|
| + char *s = self->dlerror_buf;
|
| + if (s == (void *)-1)
|
| + return "Dynamic linker failed to allocate memory for error message";
|
| + else
|
| + return s;
|
| +}
|
| +
|
| +void __dl_thread_cleanup(void)
|
| +{
|
| + pthread_t self = __pthread_self();
|
| + if (self->dlerror_buf != (void *)-1)
|
| + free(self->dlerror_buf);
|
| +}
|
| +
|
| +__attribute__((__visibility__("hidden")))
|
| +void __dl_vseterr(const char *fmt, va_list ap)
|
| +{
|
| + va_list ap2;
|
| + va_copy(ap2, ap);
|
| + pthread_t self = __pthread_self();
|
| + if (self->dlerror_buf != (void *)-1)
|
| + free(self->dlerror_buf);
|
| + size_t len = vsnprintf(0, 0, fmt, ap2);
|
| + va_end(ap2);
|
| + char *buf = malloc(len+1);
|
| + if (buf) {
|
| + vsnprintf(buf, len+1, fmt, ap);
|
| + } else {
|
| + buf = (void *)-1;
|
| + }
|
| + self->dlerror_buf = buf;
|
| + self->dlerror_flag = 1;
|
| +}
|
| +
|
| +__attribute__((__visibility__("hidden")))
|
| +void __dl_seterr(const char *fmt, ...)
|
| +{
|
| + va_list ap;
|
| + va_start(ap, fmt);
|
| + __dl_vseterr(fmt, ap);
|
| + va_end(ap);
|
| +}
|
| +
|
| +__attribute__((__visibility__("hidden")))
|
| +int __dl_invalid_handle(void *);
|
| +
|
| +static int stub_invalid_handle(void *h)
|
| +{
|
| + __dl_seterr("Invalid library handle %p", (void *)h);
|
| + return 1;
|
| +}
|
| +
|
| +weak_alias(stub_invalid_handle, __dl_invalid_handle);
|
|
|