Branch data Line data Source code
1 : : /* Try to get an ELF or debug file through the debuginfod. 2 : : Copyright (C) 2019 Red Hat, Inc. 3 : : Copyright (C) 2022 Mark J. Wielaard <mark@klomp.org> 4 : : This file is part of elfutils. 5 : : 6 : : This file is free software; you can redistribute it and/or modify 7 : : it under the terms of either 8 : : 9 : : * the GNU Lesser General Public License as published by the Free 10 : : Software Foundation; either version 3 of the License, or (at 11 : : your option) any later version 12 : : 13 : : or 14 : : 15 : : * the GNU General Public License as published by the Free 16 : : Software Foundation; either version 2 of the License, or (at 17 : : your option) any later version 18 : : 19 : : or both in parallel, as here. 20 : : 21 : : elfutils is distributed in the hope that it will be useful, but 22 : : WITHOUT ANY WARRANTY; without even the implied warranty of 23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 : : General Public License for more details. 25 : : 26 : : You should have received copies of the GNU General Public License and 27 : : the GNU Lesser General Public License along with this program. If 28 : : not, see <http://www.gnu.org/licenses/>. */ 29 : : 30 : : #ifdef HAVE_CONFIG_H 31 : : # include <config.h> 32 : : #endif 33 : : 34 : : #include "libdwflP.h" 35 : : 36 : : #ifdef ENABLE_LIBDEBUGINFOD 37 : : 38 : : #include <pthread.h> 39 : : #include <dlfcn.h> 40 : : 41 : : static __typeof__ (debuginfod_begin) *fp_debuginfod_begin; 42 : : static __typeof__ (debuginfod_find_executable) *fp_debuginfod_find_executable; 43 : : static __typeof__ (debuginfod_find_debuginfo) *fp_debuginfod_find_debuginfo; 44 : : static __typeof__ (debuginfod_end) *fp_debuginfod_end; 45 : : 46 : : static void __libdwfl_debuginfod_init (void); 47 : : 48 : : static pthread_once_t init_control = PTHREAD_ONCE_INIT; 49 : : 50 : : /* NB: this is slightly thread-unsafe */ 51 : : 52 : : debuginfod_client * 53 : 80 : dwfl_get_debuginfod_client (Dwfl *dwfl) 54 : : { 55 [ + + ]: 80 : if (dwfl->debuginfod != NULL) 56 : : return dwfl->debuginfod; 57 : : 58 : 49 : pthread_once (&init_control, __libdwfl_debuginfod_init); 59 : : 60 [ + - ]: 49 : if (fp_debuginfod_begin != NULL) 61 : : { 62 : 49 : dwfl->debuginfod = (*fp_debuginfod_begin) (); 63 : 49 : return dwfl->debuginfod; 64 : : } 65 : : 66 : : return NULL; 67 : : } 68 : : INTDEF(dwfl_get_debuginfod_client) 69 : : 70 : : int 71 : 14 : __libdwfl_debuginfod_find_executable (Dwfl *dwfl, 72 : : const unsigned char *build_id_bits, 73 : : size_t build_id_len) 74 : : { 75 : 14 : int fd = -1; 76 [ - + ]: 14 : if (build_id_len > 0) 77 : : { 78 : 14 : debuginfod_client *c = INTUSE (dwfl_get_debuginfod_client) (dwfl); 79 [ - + ]: 14 : if (c != NULL) 80 : 14 : fd = (*fp_debuginfod_find_executable) (c, build_id_bits, 81 : : build_id_len, NULL); 82 : : } 83 : : 84 : 14 : return fd; 85 : : } 86 : : 87 : : int 88 : 66 : __libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl, 89 : : const unsigned char *build_id_bits, 90 : : size_t build_id_len) 91 : : { 92 : 66 : int fd = -1; 93 [ - + ]: 66 : if (build_id_len > 0) 94 : : { 95 : 66 : debuginfod_client *c = INTUSE (dwfl_get_debuginfod_client) (dwfl); 96 [ - + ]: 66 : if (c != NULL) 97 : 66 : fd = (*fp_debuginfod_find_debuginfo) (c, build_id_bits, 98 : : build_id_len, NULL); 99 : : } 100 : : 101 : 66 : return fd; 102 : : } 103 : : 104 : : void 105 : 5708 : __libdwfl_debuginfod_end (debuginfod_client *c) 106 : : { 107 [ + + ]: 5708 : if (c != NULL) 108 : 49 : (*fp_debuginfod_end) (c); 109 : 5708 : } 110 : : 111 : : /* Try to get the libdebuginfod library functions. 112 : : Only needs to be called once from dwfl_get_debuginfod_client. */ 113 : : static void 114 : 49 : __libdwfl_debuginfod_init (void) 115 : : { 116 : 49 : void *debuginfod_so = dlopen(DEBUGINFOD_SONAME, RTLD_LAZY); 117 : : 118 [ + - ]: 49 : if (debuginfod_so != NULL) 119 : : { 120 : 49 : fp_debuginfod_begin = dlsym (debuginfod_so, "debuginfod_begin"); 121 : 49 : fp_debuginfod_find_executable = dlsym (debuginfod_so, 122 : : "debuginfod_find_executable"); 123 : 49 : fp_debuginfod_find_debuginfo = dlsym (debuginfod_so, 124 : : "debuginfod_find_debuginfo"); 125 : 49 : fp_debuginfod_end = dlsym (debuginfod_so, "debuginfod_end"); 126 : : 127 : : /* We either get them all, or we get none. */ 128 [ + - ]: 49 : if (fp_debuginfod_begin == NULL 129 [ + - ]: 49 : || fp_debuginfod_find_executable == NULL 130 [ + - ]: 49 : || fp_debuginfod_find_debuginfo == NULL 131 [ - + ]: 49 : || fp_debuginfod_end == NULL) 132 : : { 133 : 0 : fp_debuginfod_begin = NULL; 134 : 0 : fp_debuginfod_find_executable = NULL; 135 : 0 : fp_debuginfod_find_debuginfo = NULL; 136 : 0 : fp_debuginfod_end = NULL; 137 : 0 : dlclose (debuginfod_so); 138 : : } 139 : : } 140 : 49 : } 141 : : 142 : : #else // ENABLE_LIBDEBUGINFOD 143 : : 144 : : debuginfod_client * 145 : : dwfl_get_debuginfod_client (Dwfl *dummy __attribute__ ((unused))) 146 : : { 147 : : return NULL; 148 : : } 149 : : 150 : : #endif // ENABLE_LIBDEBUGINFOD