From: Gleb Fotengauer-Malinovskiy Date: Mon, 30 Nov 2020 21:55:32 +0300 Subject: Load libdebuginfod library on demand diff --git a/binutils/Makefile.am b/binutils/Makefile.am index defaced..defaced 100644 --- a/binutils/Makefile.am +++ b/binutils/Makefile.am @@ -53,7 +53,7 @@ AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) AM_CFLAGS_FOR_BUILD = $(WARN_CFLAGS_FOR_BUILD) $(ZLIBINC) LIBICONV = @LIBICONV@ -DEBUGINFOD_LIBS = @DEBUGINFOD_LIBS@ +DEBUGINFOD_LIBS = # these two are almost the same program AR_PROG=ar diff --git a/binutils/Makefile.in b/binutils/Makefile.in index defaced..defaced 100644 --- a/binutils/Makefile.in +++ b/binutils/Makefile.in @@ -425,7 +425,7 @@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DEBUGINFOD_CFLAGS = @DEBUGINFOD_CFLAGS@ -DEBUGINFOD_LIBS = @DEBUGINFOD_LIBS@ +DEBUGINFOD_LIBS = DEFS = @DEFS@ DEMANGLER_NAME = @DEMANGLER_NAME@ DEPDIR = @DEPDIR@ diff --git a/binutils/dwarf.c b/binutils/dwarf.c index defaced..defaced 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -33,7 +33,12 @@ #include #ifdef HAVE_LIBDEBUGINFOD +#include #include + +static __typeof__ (debuginfod_begin) *fp_debuginfod_begin; +static __typeof__ (debuginfod_find_debuginfo) *fp_debuginfod_find_debuginfo; +static __typeof__ (debuginfod_end) *fp_debuginfod_end; #endif #include @@ -10936,6 +10941,44 @@ add_separate_debug_file (const char * filename, void * handle) } #if HAVE_LIBDEBUGINFOD +static int +debuginfod_load(void) +{ + static int debuginfod_loaded = -1; + + if (debuginfod_loaded >= 0) + return debuginfod_loaded; + + debuginfod_loaded = 0; + + char *urls = getenv (DEBUGINFOD_URLS_ENV_VAR); + if (urls == NULL || urls[0] == '\0') + return debuginfod_loaded; + + void *debuginfod_so = dlopen("libdebuginfod.so.1", RTLD_LAZY); + if (debuginfod_so != NULL) + { + fp_debuginfod_begin = dlsym (debuginfod_so, "debuginfod_begin"); + 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_debuginfo == NULL + || fp_debuginfod_end == NULL) + { + fp_debuginfod_begin = NULL; + fp_debuginfod_find_debuginfo = NULL; + fp_debuginfod_end = NULL; + dlclose (debuginfod_so); + } + else + debuginfod_loaded = 1; + } + return debuginfod_loaded; +} + /* Query debuginfod servers for the target debuglink or debugaltlink file. If successful, store the path of the file in filename and return TRUE, otherwise return FALSE. */ @@ -10978,14 +11021,14 @@ debuginfod_fetch_separate_debug_info (struct dwarf_section * section, int fd; debuginfod_client * client; - client = debuginfod_begin (); + client = fp_debuginfod_begin (); if (client == NULL) return false; /* Query debuginfod servers for the target file. If found its path will be stored in filename. */ - fd = debuginfod_find_debuginfo (client, build_id, build_id_len, filename); - debuginfod_end (client); + fd = fp_debuginfod_find_debuginfo (client, build_id, build_id_len, filename); + fp_debuginfod_end (client); /* Only free build_id if we allocated space for a hex string in get_build_id (). */ @@ -11117,7 +11160,8 @@ load_separate_debug_info (const char * main_filename, { char * tmp_filename; - if (debuginfod_fetch_separate_debug_info (xlink, + if (debuginfod_load() > 0 && + debuginfod_fetch_separate_debug_info (xlink, & tmp_filename, file)) {