#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "libdwflP.h"
#ifdef ENABLE_LIBDEBUGINFOD
#include "debuginfod.h"
#include <pthread.h>
#include <dlfcn.h>
static __typeof__ (debuginfod_begin) *fp_debuginfod_begin;
static __typeof__ (debuginfod_find_executable) *fp_debuginfod_find_executable;
static __typeof__ (debuginfod_find_debuginfo) *fp_debuginfod_find_debuginfo;
static __typeof__ (debuginfod_end) *fp_debuginfod_end;
static void __libdwfl_debuginfod_init (void);
static pthread_once_t init_control = PTHREAD_ONCE_INIT;
debuginfod_client *
dwfl_get_debuginfod_client (Dwfl *dwfl)
{
if (dwfl->debuginfod != NULL)
return dwfl->debuginfod;
pthread_once (&init_control, __libdwfl_debuginfod_init);
if (fp_debuginfod_begin != NULL)
{
dwfl->debuginfod = (*fp_debuginfod_begin) ();
return dwfl->debuginfod;
}
return NULL;
}
INTDEF(dwfl_get_debuginfod_client)
int
__libdwfl_debuginfod_find_executable (Dwfl *dwfl,
const unsigned char *build_id_bits,
size_t build_id_len)
{
int fd = -1;
if (build_id_len > 0)
{
debuginfod_client *c = INTUSE (dwfl_get_debuginfod_client) (dwfl);
if (c != NULL)
fd = (*fp_debuginfod_find_executable) (c, build_id_bits,
build_id_len, NULL);
}
return fd;
}
int
__libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl,
const unsigned char *build_id_bits,
size_t build_id_len)
{
int fd = -1;
if (build_id_len > 0)
{
debuginfod_client *c = INTUSE (dwfl_get_debuginfod_client) (dwfl);
if (c != NULL)
fd = (*fp_debuginfod_find_debuginfo) (c, build_id_bits,
build_id_len, NULL);
}
return fd;
}
void
__libdwfl_debuginfod_end (debuginfod_client *c)
{
if (c != NULL)
(*fp_debuginfod_end) (c);
}
static void
__libdwfl_debuginfod_init (void)
{
void *debuginfod_so = dlopen(DEBUGINFOD_SONAME, RTLD_LAZY);
if (debuginfod_so != NULL)
{
fp_debuginfod_begin = dlsym (debuginfod_so, "debuginfod_begin");
fp_debuginfod_find_executable = dlsym (debuginfod_so,
"debuginfod_find_executable");
fp_debuginfod_find_debuginfo = dlsym (debuginfod_so,
"debuginfod_find_debuginfo");
fp_debuginfod_end = dlsym (debuginfod_so, "debuginfod_end");
if (fp_debuginfod_begin == NULL
|| fp_debuginfod_find_executable == NULL
|| fp_debuginfod_find_debuginfo == NULL
|| fp_debuginfod_end == NULL)
{
fp_debuginfod_begin = NULL;
fp_debuginfod_find_executable = NULL;
fp_debuginfod_find_debuginfo = NULL;
fp_debuginfod_end = NULL;
dlclose (debuginfod_so);
}
}
}
#else
debuginfod_client *
dwfl_get_debuginfod_client (Dwfl *dummy __attribute__ ((unused)))
{
return NULL;
}
#endif