You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.5 KiB
129 lines
3.5 KiB
/* Try to get an ELF or debug file through the debuginfod.
|
|
Copyright (C) 2019 Red Hat, Inc.
|
|
This file is part of elfutils.
|
|
|
|
This file is free software; you can redistribute it and/or modify
|
|
it under the terms of either
|
|
|
|
* the GNU Lesser General Public License as published by the Free
|
|
Software Foundation; either version 3 of the License, or (at
|
|
your option) any later version
|
|
|
|
or
|
|
|
|
* the GNU General Public License as published by the Free
|
|
Software Foundation; either version 2 of the License, or (at
|
|
your option) any later version
|
|
|
|
or both in parallel, as here.
|
|
|
|
elfutils is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received copies of the GNU General Public License and
|
|
the GNU Lesser General Public License along with this program. If
|
|
not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#include "libdwflP.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;
|
|
|
|
/* NB: this is slightly thread-unsafe */
|
|
|
|
static debuginfod_client *
|
|
get_client (Dwfl *dwfl)
|
|
{
|
|
if (dwfl->debuginfod != NULL)
|
|
return dwfl->debuginfod;
|
|
|
|
if (fp_debuginfod_begin != NULL)
|
|
{
|
|
dwfl->debuginfod = (*fp_debuginfod_begin) ();
|
|
return dwfl->debuginfod;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
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 = get_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 = get_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);
|
|
}
|
|
|
|
/* Try to get the libdebuginfod library functions to make sure
|
|
everything is initialized early. */
|
|
void __attribute__ ((constructor))
|
|
__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");
|
|
|
|
/* We either get them all, or we get none. */
|
|
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);
|
|
}
|
|
}
|
|
}
|