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 : : This file is part of elfutils. 4 : : 5 : : This file is free software; you can redistribute it and/or modify 6 : : it under the terms of either 7 : : 8 : : * the GNU Lesser General Public License as published by the Free 9 : : Software Foundation; either version 3 of the License, or (at 10 : : your option) any later version 11 : : 12 : : or 13 : : 14 : : * the GNU General Public License as published by the Free 15 : : Software Foundation; either version 2 of the License, or (at 16 : : your option) any later version 17 : : 18 : : or both in parallel, as here. 19 : : 20 : : elfutils is distributed in the hope that it will be useful, but 21 : : WITHOUT ANY WARRANTY; without even the implied warranty of 22 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 : : General Public License for more details. 24 : : 25 : : You should have received copies of the GNU General Public License and 26 : : the GNU Lesser General Public License along with this program. If 27 : : not, see <http://www.gnu.org/licenses/>. */ 28 : : 29 : : #ifdef HAVE_CONFIG_H 30 : : # include <config.h> 31 : : #endif 32 : : 33 : : #include "libdwflP.h" 34 : : #include <dlfcn.h> 35 : : 36 : : static __typeof__ (debuginfod_begin) *fp_debuginfod_begin; 37 : : static __typeof__ (debuginfod_find_executable) *fp_debuginfod_find_executable; 38 : : static __typeof__ (debuginfod_find_debuginfo) *fp_debuginfod_find_debuginfo; 39 : : static __typeof__ (debuginfod_end) *fp_debuginfod_end; 40 : : 41 : : /* NB: this is slightly thread-unsafe */ 42 : : 43 : : static debuginfod_client * 44 : 69 : get_client (Dwfl *dwfl) 45 : : { 46 [ + + ]: 69 : if (dwfl->debuginfod != NULL) 47 : : return dwfl->debuginfod; 48 : : 49 [ + - ]: 42 : if (fp_debuginfod_begin != NULL) 50 : : { 51 : 42 : dwfl->debuginfod = (*fp_debuginfod_begin) (); 52 : 42 : return dwfl->debuginfod; 53 : : } 54 : : 55 : : return NULL; 56 : : } 57 : : 58 : : int 59 : 14 : __libdwfl_debuginfod_find_executable (Dwfl *dwfl, 60 : : const unsigned char *build_id_bits, 61 : : size_t build_id_len) 62 : : { 63 : 14 : int fd = -1; 64 [ + - ]: 14 : if (build_id_len > 0) 65 : : { 66 : 14 : debuginfod_client *c = get_client (dwfl); 67 [ + - ]: 14 : if (c != NULL) 68 : 14 : fd = (*fp_debuginfod_find_executable) (c, build_id_bits, 69 : : build_id_len, NULL); 70 : : } 71 : : 72 : 14 : return fd; 73 : : } 74 : : 75 : : int 76 : 55 : __libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl, 77 : : const unsigned char *build_id_bits, 78 : : size_t build_id_len) 79 : : { 80 : 55 : int fd = -1; 81 [ + - ]: 55 : if (build_id_len > 0) 82 : : { 83 : 55 : debuginfod_client *c = get_client (dwfl); 84 [ + - ]: 55 : if (c != NULL) 85 : 55 : fd = (*fp_debuginfod_find_debuginfo) (c, build_id_bits, 86 : : build_id_len, NULL); 87 : : } 88 : : 89 : 55 : return fd; 90 : : } 91 : : 92 : : void 93 : 5607 : __libdwfl_debuginfod_end (debuginfod_client *c) 94 : : { 95 [ + + ]: 5607 : if (c != NULL) 96 : 42 : (*fp_debuginfod_end) (c); 97 : 5607 : } 98 : : 99 : : /* Try to get the libdebuginfod library functions to make sure 100 : : everything is initialized early. */ 101 : : void __attribute__ ((constructor)) 102 : 693 : __libdwfl_debuginfod_init (void) 103 : : { 104 : 693 : void *debuginfod_so = dlopen(DEBUGINFOD_SONAME, RTLD_LAZY); 105 : : 106 [ + + ]: 693 : if (debuginfod_so != NULL) 107 : : { 108 : 692 : fp_debuginfod_begin = dlsym (debuginfod_so, "debuginfod_begin"); 109 : 692 : fp_debuginfod_find_executable = dlsym (debuginfod_so, 110 : : "debuginfod_find_executable"); 111 : 692 : fp_debuginfod_find_debuginfo = dlsym (debuginfod_so, 112 : : "debuginfod_find_debuginfo"); 113 : 692 : fp_debuginfod_end = dlsym (debuginfod_so, "debuginfod_end"); 114 : : 115 : : /* We either get them all, or we get none. */ 116 [ + - ]: 692 : if (fp_debuginfod_begin == NULL 117 [ + - ]: 692 : || fp_debuginfod_find_executable == NULL 118 [ + - ]: 692 : || fp_debuginfod_find_debuginfo == NULL 119 [ - + ]: 692 : || fp_debuginfod_end == NULL) 120 : : { 121 : 0 : fp_debuginfod_begin = NULL; 122 : 0 : fp_debuginfod_find_executable = NULL; 123 : 0 : fp_debuginfod_find_debuginfo = NULL; 124 : 0 : fp_debuginfod_end = NULL; 125 : 0 : dlclose (debuginfod_so); 126 : : } 127 : : } 128 : 693 : }