#include <sys/types.h>
#include <stddef.h>
#include <stdio.h>
#include <link.h>
#include <dlfcn.h>
#include <tib.h>
#include "init.h"
static int dlerror_ret;
void *
dlopen(const char *libname, int how)
{
if (_dl_cb != NULL && _dl_cb->dlopen != NULL)
return _dl_cb->dlopen(libname, how);
return NULL;
}
int
dlclose(void *handle)
{
if (_dl_cb != NULL && _dl_cb->dlclose != NULL)
return _dl_cb->dlclose(handle);
dlerror_ret = 1;
return -1;
}
void *
dlsym(void *handle, const char *name)
{
if (_dl_cb != NULL && _dl_cb->dlsym != NULL)
return _dl_cb->dlsym(handle, name);
dlerror_ret = 1;
return NULL;
}
int
dlctl(void *handle, int command, void *data)
{
if (_dl_cb != NULL && _dl_cb->dlctl != NULL)
return _dl_cb->dlctl(handle, command, data);
dlerror_ret = 1;
return -1;
}
DEF_WEAK(dlctl);
char *
dlerror(void)
{
if (_dl_cb != NULL && _dl_cb->dlerror != NULL)
return _dl_cb->dlerror();
if (dlerror_ret) {
dlerror_ret = 0;
return _dl_cb == NULL ? "No dynamic linker" :
"Incompatible dynamic linker";
}
return NULL;
}
int
dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *),
void *data)
{
if (_dl_cb != NULL && _dl_cb->dl_iterate_phdr != NULL)
return _dl_cb->dl_iterate_phdr(callback, data);
#ifndef PIC
if (_static_phdr_info.dlpi_phdr != NULL)
return callback(&_static_phdr_info, sizeof(_static_phdr_info),
data);
#endif
return -1;
}
DEF_WEAK(dl_iterate_phdr);
int
dladdr(const void *addr, struct dl_info *info)
{
if (_dl_cb != NULL && _dl_cb->dladdr != NULL)
return _dl_cb->dladdr(addr, info);
dlerror_ret = 1;
return 0;
}
DEF_WEAK(dladdr);
#if 0
typedef struct {
unsigned long int ti_module;
unsigned long int ti_offset;
} tls_index;
void *__tls_get_addr(tls_index *) __attribute__((weak));
#ifdef __i386
void *___tls_get_addr(tls_index *) __attribute__((weak, __regparm__(1)));
#endif
#if defined(__amd64) || defined(__i386) || defined(__sparc64)
void *
__tls_get_addr(tls_index *ti)
{
return NULL;
}
#ifdef __i386
__attribute__((__regparm__(1))) void *
___tls_get_addr(tls_index *ti)
{
return NULL;
}
#endif
#endif
#endif