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 : 0 : get_client (Dwfl *dwfl)
45 : : {
46 [ # # ]: 0 : if (dwfl->debuginfod != NULL)
47 : 0 : return dwfl->debuginfod;
48 : :
49 [ - + ]: 73 : if (fp_debuginfod_begin != NULL)
[ - + # # ]
50 : : {
51 : 0 : dwfl->debuginfod = (*fp_debuginfod_begin) ();
52 : 0 : 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 [ # # ]: 0 : if (c != NULL)
68 : 0 : 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 : 59 : __libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl,
77 : : const unsigned char *build_id_bits,
78 : : size_t build_id_len)
79 : : {
80 : 59 : int fd = -1;
81 [ + - ]: 59 : if (build_id_len > 0)
82 : : {
83 [ + - ]: 59 : debuginfod_client *c = get_client (dwfl);
84 [ # # ]: 0 : if (c != NULL)
85 : 0 : fd = (*fp_debuginfod_find_debuginfo) (c, build_id_bits,
86 : : build_id_len, NULL);
87 : : }
88 : :
89 : 59 : return fd;
90 : : }
91 : :
92 : : void
93 : 5598 : __libdwfl_debuginfod_end (debuginfod_client *c)
94 : : {
95 [ - + ]: 5598 : if (c != NULL)
96 : 0 : (*fp_debuginfod_end) (c);
97 : 5598 : }
98 : :
99 : : /* Try to get the libdebuginfod library functions to make sure
100 : : everything is initialized early. */
101 : : void __attribute__ ((constructor))
102 : 689 : __libdwfl_debuginfod_init (void)
103 : : {
104 : 689 : void *debuginfod_so = dlopen(DEBUGINFOD_SONAME, RTLD_LAZY);
105 : :
106 [ - + ]: 689 : if (debuginfod_so != NULL)
107 : : {
108 : 0 : fp_debuginfod_begin = dlsym (debuginfod_so, "debuginfod_begin");
109 : 0 : fp_debuginfod_find_executable = dlsym (debuginfod_so,
110 : : "debuginfod_find_executable");
111 : 0 : fp_debuginfod_find_debuginfo = dlsym (debuginfod_so,
112 : : "debuginfod_find_debuginfo");
113 : 0 : fp_debuginfod_end = dlsym (debuginfod_so, "debuginfod_end");
114 : :
115 : : /* We either get them all, or we get none. */
116 [ # # ]: 0 : if (fp_debuginfod_begin == NULL
117 [ # # ]: 0 : || fp_debuginfod_find_executable == NULL
118 [ # # ]: 0 : || fp_debuginfod_find_debuginfo == NULL
119 [ # # ]: 0 : || 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 : 689 : }
|