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 71 : 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 57 : __libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl,
77 : const unsigned char *build_id_bits,
78 : size_t build_id_len)
79 : {
80 57 : int fd = -1;
81 57 : if (build_id_len > 0)
82 : {
83 57 : 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 57 : return fd;
90 : }
91 :
92 : void
93 5592 : __libdwfl_debuginfod_end (debuginfod_client *c)
94 : {
95 5592 : if (c != NULL)
96 0 : (*fp_debuginfod_end) (c);
97 5592 : }
98 :
99 : /* Try to get the libdebuginfod library functions to make sure
100 : everything is initialized early. */
101 : void __attribute__ ((constructor))
102 685 : __libdwfl_debuginfod_init (void)
103 : {
104 685 : void *debuginfod_so = dlopen("libdebuginfod-" VERSION ".so", RTLD_LAZY);
105 :
106 685 : if (debuginfod_so == NULL)
107 685 : debuginfod_so = dlopen("libdebuginfod.so", RTLD_LAZY);
108 :
109 685 : if (debuginfod_so != NULL)
110 : {
111 0 : fp_debuginfod_begin = dlsym (debuginfod_so, "debuginfod_begin");
112 0 : fp_debuginfod_find_executable = dlsym (debuginfod_so,
113 : "debuginfod_find_executable");
114 0 : fp_debuginfod_find_debuginfo = dlsym (debuginfod_so,
115 : "debuginfod_find_debuginfo");
116 0 : fp_debuginfod_end = dlsym (debuginfod_so, "debuginfod_end");
117 :
118 : /* We either get them all, or we get none. */
119 0 : if (fp_debuginfod_begin == NULL
120 0 : || fp_debuginfod_find_executable == NULL
121 0 : || fp_debuginfod_find_debuginfo == NULL
122 0 : || fp_debuginfod_end == NULL)
123 : {
124 0 : fp_debuginfod_begin = NULL;
125 0 : fp_debuginfod_find_executable = NULL;
126 0 : fp_debuginfod_find_debuginfo = NULL;
127 0 : fp_debuginfod_end = NULL;
128 0 : dlclose (debuginfod_so);
129 : }
130 : }
131 685 : }
|