#include <mdb/mdb_tdb.h>
#include <mdb/mdb_modapi.h>
#include <mdb/mdb_err.h>
#include <strings.h>
#include <unistd.h>
#include <dlfcn.h>
#include <link.h>
static mdb_tdb_lib_t *tdb_list;
static td_err_e
tdb_notsup()
{
return (TD_NOCAPAB);
}
const mdb_tdb_ops_t *
mdb_tdb_load(const char *path)
{
td_err_e (*tdb_init)(void);
mdb_tdb_lib_t *t;
td_err_e err;
void *hdl;
for (t = tdb_list; t != NULL; t = t->tdb_next) {
if (strcmp(path, t->tdb_pathname) == 0)
break;
}
if (t != NULL)
return (&t->tdb_ops);
if (access(path, F_OK) == -1)
return (NULL);
if ((hdl = dlmopen(LM_ID_BASE, path, RTLD_LAZY | RTLD_LOCAL)) == NULL) {
(void) set_errno(EMDB_RTLD);
return (NULL);
}
if ((tdb_init = (td_err_e (*)(void))dlsym(hdl, "td_init")) == NULL) {
(void) dlclose(hdl);
(void) set_errno(tdb_to_errno(TD_NOCAPAB));
return (NULL);
}
if ((err = tdb_init()) != TD_OK) {
(void) dlclose(hdl);
(void) set_errno(tdb_to_errno(err));
return (NULL);
}
t = mdb_alloc(sizeof (mdb_tdb_lib_t), UM_SLEEP);
(void) strncpy(t->tdb_pathname, path, MAXPATHLEN);
t->tdb_pathname[MAXPATHLEN - 1] = '\0';
t->tdb_handle = hdl;
t->tdb_next = tdb_list;
tdb_list = t;
t->tdb_ops.td_ta_new = (td_err_e (*)())dlsym(hdl, "td_ta_new");
if (t->tdb_ops.td_ta_new == NULL)
t->tdb_ops.td_ta_new = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_ta_delete = (td_err_e (*)())dlsym(hdl, "td_ta_delete");
if (t->tdb_ops.td_ta_delete == NULL)
t->tdb_ops.td_ta_delete = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_ta_thr_iter = (td_err_e (*)())
dlsym(hdl, "td_ta_thr_iter");
if (t->tdb_ops.td_ta_thr_iter == NULL)
t->tdb_ops.td_ta_thr_iter = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_ta_map_id2thr = (td_err_e (*)())
dlsym(hdl, "td_ta_map_id2thr");
if (t->tdb_ops.td_ta_map_id2thr == NULL)
t->tdb_ops.td_ta_map_id2thr = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_ta_map_lwp2thr = (td_err_e (*)())
dlsym(hdl, "td_ta_map_lwp2thr");
if (t->tdb_ops.td_ta_map_lwp2thr == NULL)
t->tdb_ops.td_ta_map_lwp2thr = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_thr_get_info = (td_err_e (*)())
dlsym(hdl, "td_thr_get_info");
if (t->tdb_ops.td_thr_get_info == NULL)
t->tdb_ops.td_thr_get_info = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_thr_getgregs = (td_err_e (*)())
dlsym(hdl, "td_thr_getgregs");
if (t->tdb_ops.td_thr_getgregs == NULL)
t->tdb_ops.td_thr_getgregs = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_thr_setgregs = (td_err_e (*)())
dlsym(hdl, "td_thr_setgregs");
if (t->tdb_ops.td_thr_setgregs == NULL)
t->tdb_ops.td_thr_setgregs = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_thr_getfpregs = (td_err_e (*)())
dlsym(hdl, "td_thr_getfpregs");
if (t->tdb_ops.td_thr_getfpregs == NULL)
t->tdb_ops.td_thr_getfpregs = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_thr_setfpregs = (td_err_e (*)())
dlsym(hdl, "td_thr_setfpregs");
if (t->tdb_ops.td_thr_setfpregs == NULL)
t->tdb_ops.td_thr_setfpregs = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_thr_tlsbase = (td_err_e (*)())
dlsym(hdl, "td_thr_tlsbase");
if (t->tdb_ops.td_thr_tlsbase == NULL)
t->tdb_ops.td_thr_tlsbase = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_thr_getxregsize = (td_err_e (*)())
dlsym(hdl, "td_thr_getxregsize");
if (t->tdb_ops.td_thr_getxregsize == NULL)
t->tdb_ops.td_thr_getxregsize = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_thr_getxregs = (td_err_e (*)())
dlsym(hdl, "td_thr_getxregs");
if (t->tdb_ops.td_thr_getxregs == NULL)
t->tdb_ops.td_thr_getxregs = (td_err_e (*)())tdb_notsup;
t->tdb_ops.td_thr_setxregs = (td_err_e (*)())
dlsym(hdl, "td_thr_setxregs");
if (t->tdb_ops.td_thr_setxregs == NULL)
t->tdb_ops.td_thr_setxregs = (td_err_e (*)())tdb_notsup;
return (&t->tdb_ops);
}
void
mdb_tdb_flush(void)
{
mdb_tdb_lib_t *t, *u;
for (t = tdb_list; t != NULL; t = u) {
u = t->tdb_next;
(void) dlclose(t->tdb_handle);
mdb_free(t, sizeof (mdb_tdb_lib_t));
}
tdb_list = NULL;
}