Branch data Line data Source code
1 : : /* Create descriptor from ELF descriptor for processing file.
2 : : Copyright (C) 2002-2011, 2014, 2015, 2017, 2018 Red Hat, Inc.
3 : : Copyright (C) 2023, 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 <system.h>
35 : :
36 : : #include <assert.h>
37 : : #include <stdbool.h>
38 : : #include <stddef.h>
39 : : #include <stdlib.h>
40 : : #include <stdio.h>
41 : : #include <string.h>
42 : : #include <sys/types.h>
43 : : #include <sys/stat.h>
44 : : #include <fcntl.h>
45 : :
46 : : #include "libelfP.h"
47 : : #include "libdwP.h"
48 : :
49 : :
50 : : /* Section names. (Note .debug_str_offsets is the largest 19 chars.) */
51 : : static const char dwarf_scnnames[IDX_last][19] =
52 : : {
53 : : [IDX_debug_info] = ".debug_info",
54 : : [IDX_debug_types] = ".debug_types",
55 : : [IDX_debug_abbrev] = ".debug_abbrev",
56 : : [IDX_debug_addr] = ".debug_addr",
57 : : [IDX_debug_aranges] = ".debug_aranges",
58 : : [IDX_debug_line] = ".debug_line",
59 : : [IDX_debug_line_str] = ".debug_line_str",
60 : : [IDX_debug_frame] = ".debug_frame",
61 : : [IDX_debug_loc] = ".debug_loc",
62 : : [IDX_debug_loclists] = ".debug_loclists",
63 : : [IDX_debug_pubnames] = ".debug_pubnames",
64 : : [IDX_debug_str] = ".debug_str",
65 : : [IDX_debug_str_offsets] = ".debug_str_offsets",
66 : : [IDX_debug_macinfo] = ".debug_macinfo",
67 : : [IDX_debug_macro] = ".debug_macro",
68 : : [IDX_debug_ranges] = ".debug_ranges",
69 : : [IDX_debug_rnglists] = ".debug_rnglists",
70 : : [IDX_debug_cu_index] = ".debug_cu_index",
71 : : [IDX_debug_tu_index] = ".debug_tu_index",
72 : : [IDX_gnu_debugaltlink] = ".gnu_debugaltlink"
73 : : };
74 : : #define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
75 : :
76 : : /* Map from section index to string section index.
77 : : Non-string sections should have STR_SCN_IDX_last. */
78 : : static const enum string_section_index scn_to_string_section_idx[IDX_last] =
79 : : {
80 : : [IDX_debug_info] = STR_SCN_IDX_last,
81 : : [IDX_debug_types] = STR_SCN_IDX_last,
82 : : [IDX_debug_abbrev] = STR_SCN_IDX_last,
83 : : [IDX_debug_addr] = STR_SCN_IDX_last,
84 : : [IDX_debug_aranges] = STR_SCN_IDX_last,
85 : : [IDX_debug_line] = STR_SCN_IDX_last,
86 : : [IDX_debug_line_str] = STR_SCN_IDX_debug_line_str,
87 : : [IDX_debug_frame] = STR_SCN_IDX_last,
88 : : [IDX_debug_loc] = STR_SCN_IDX_last,
89 : : [IDX_debug_loclists] = STR_SCN_IDX_last,
90 : : [IDX_debug_pubnames] = STR_SCN_IDX_last,
91 : : [IDX_debug_str] = STR_SCN_IDX_debug_str,
92 : : [IDX_debug_str_offsets] = STR_SCN_IDX_last,
93 : : [IDX_debug_macinfo] = STR_SCN_IDX_last,
94 : : [IDX_debug_macro] = STR_SCN_IDX_last,
95 : : [IDX_debug_ranges] = STR_SCN_IDX_last,
96 : : [IDX_debug_rnglists] = STR_SCN_IDX_last,
97 : : [IDX_debug_cu_index] = STR_SCN_IDX_last,
98 : : [IDX_debug_tu_index] = STR_SCN_IDX_last,
99 : : [IDX_gnu_debugaltlink] = STR_SCN_IDX_last
100 : : };
101 : :
102 : : static enum dwarf_type
103 : 361280 : scn_dwarf_type (Dwarf *result, size_t shstrndx, Elf_Scn *scn)
104 : : {
105 : 361280 : GElf_Shdr shdr_mem;
106 : 361280 : GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
107 [ - + ]: 361280 : if (shdr == NULL)
108 : : return TYPE_UNKNOWN;
109 : :
110 : 722560 : const char *scnname = elf_strptr (result->elf, shstrndx,
111 : 361280 : shdr->sh_name);
112 [ + + ]: 361280 : if (scnname != NULL)
113 : : {
114 [ + + ]: 361198 : if (startswith (scnname, ".gnu.debuglto_.debug"))
115 : : return TYPE_GNU_LTO;
116 [ + + ]: 361188 : else if (strcmp (scnname, ".debug_cu_index") == 0
117 [ + + ]: 361148 : || strcmp (scnname, ".debug_tu_index") == 0
118 [ + - ]: 361108 : || strcmp (scnname, ".debug_dwp") == 0
119 [ + - ]: 361108 : || strcmp (scnname, ".zdebug_cu_index") == 0
120 [ + - ]: 361108 : || strcmp (scnname, ".zdebug_tu_index") == 0
121 [ + - ]: 361108 : || strcmp (scnname, ".zdebug_dwp") == 0)
122 : : return TYPE_DWO;
123 [ + + + + ]: 361108 : else if (startswith (scnname, ".debug_") || startswith (scnname, ".zdebug_"))
124 : : {
125 : 13098 : size_t len = strlen (scnname);
126 [ + + ]: 13098 : if (strcmp (scnname + len - 4, ".dwo") == 0)
127 : : return TYPE_DWO;
128 : : else
129 : 11894 : return TYPE_PLAIN;
130 : : }
131 : : }
132 : : return TYPE_UNKNOWN;
133 : : }
134 : : static Dwarf *
135 : 609824 : check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp)
136 : : {
137 : 609824 : GElf_Shdr shdr_mem;
138 : 609824 : GElf_Shdr *shdr;
139 : :
140 : : /* Get the section header data. */
141 : 609824 : shdr = gelf_getshdr (scn, &shdr_mem);
142 [ - + ]: 609824 : if (shdr == NULL)
143 : : /* We may read /proc/PID/mem with only program headers mapped and section
144 : : headers out of the mapped pages. */
145 : 0 : goto err;
146 : :
147 : : /* Ignore any SHT_NOBITS sections. Debugging sections should not
148 : : have been stripped, but in case of a corrupt file we won't try
149 : : to look at the missing data. */
150 [ + + ]: 609824 : if (unlikely (shdr->sh_type == SHT_NOBITS))
151 : : return result;
152 : :
153 : : /* Make sure the section is part of a section group only iff we
154 : : really need it. If we are looking for the global (= non-section
155 : : group debug info) we have to ignore all the info in section
156 : : groups. If we are looking into a section group we cannot look at
157 : : a section which isn't part of the section group. */
158 [ + - + + ]: 574490 : if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
159 : : /* Ignore the section. */
160 : : return result;
161 : :
162 : :
163 : : /* We recognize the DWARF section by their names. This is not very
164 : : safe and stable but the best we can do. */
165 : 1148976 : const char *scnname = elf_strptr (result->elf, shstrndx,
166 : 574488 : shdr->sh_name);
167 [ + + ]: 574488 : if (scnname == NULL)
168 : : {
169 : : /* The section name must be valid. Otherwise is the ELF file
170 : : invalid. */
171 : 2 : err:
172 : 2 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
173 : 2 : __libdw_seterrno (DWARF_E_INVALID_ELF);
174 : 2 : free (result);
175 : 2 : return NULL;
176 : : }
177 : :
178 : : /* Recognize the various sections. Most names start with .debug_.
179 : : They might be compressed (and start with .z). Or end with .dwo
180 : : for split dwarf sections. Or start with .gnu.debuglto_ for
181 : : LTO debug sections. We should only use one consistent set at
182 : : a time. We prefer PLAIN over DWO over LTO. */
183 : : size_t cnt;
184 : 10798598 : bool gnu_compressed = false;
185 [ + + ]: 10798598 : for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
186 : : {
187 : : /* .debug_cu_index and .debug_tu_index don't have a .dwo suffix,
188 : : but they are for DWO. */
189 [ + + ]: 10317420 : if (result->type != TYPE_DWO
190 [ + + ]: 10296634 : && (cnt == IDX_debug_cu_index || cnt == IDX_debug_tu_index))
191 : 961964 : continue;
192 : 18710912 : bool need_dot_dwo =
193 : : (result->type == TYPE_DWO
194 : : && cnt != IDX_debug_cu_index
195 [ + + + + ]: 9355456 : && cnt != IDX_debug_tu_index);
196 : 9355456 : size_t dbglen = strlen (dwarf_scnnames[cnt]);
197 : 9355456 : size_t scnlen = strlen (scnname);
198 [ + + ]: 9355456 : if (strncmp (scnname, dwarf_scnnames[cnt], dbglen) == 0
199 [ + + ]: 114452 : && ((!need_dot_dwo && dbglen == scnlen)
200 [ + + ]: 22512 : || (need_dot_dwo
201 [ + + ]: 1478 : && scnlen == dbglen + 4
202 [ - + ]: 1204 : && strstr (scnname, ".dwo") == scnname + dbglen)))
203 : : break;
204 [ + + + + ]: 9262312 : else if (scnname[0] == '.' && scnname[1] == 'z'
205 [ + + ]: 1188 : && (strncmp (&scnname[2], &dwarf_scnnames[cnt][1],
206 : : dbglen - 1) == 0
207 [ + - - + ]: 164 : && ((!need_dot_dwo && scnlen == dbglen + 1)
208 : : || (need_dot_dwo
209 [ # # ]: 0 : && scnlen == dbglen + 5
210 : 0 : && strstr (scnname,
211 [ # # ]: 0 : ".dwo") == scnname + dbglen + 1))))
212 : : {
213 : : gnu_compressed = true;
214 : : break;
215 : : }
216 [ + + ]: 9262148 : else if (scnlen > 14 /* .gnu.debuglto_ prefix. */
217 [ + + ]: 801094 : && startswith (scnname, ".gnu.debuglto_")
218 [ + + ]: 180 : && strcmp (&scnname[14], dwarf_scnnames[cnt]) == 0)
219 : : {
220 [ + - ]: 10 : if (result->type == TYPE_GNU_LTO)
221 : : break;
222 : : }
223 : : }
224 : :
225 [ + + ]: 574486 : if (cnt >= ndwarf_scnnames)
226 : : /* Not a debug section; ignore it. */
227 : : return result;
228 : :
229 [ - + ]: 93308 : if (unlikely (result->sectiondata[cnt] != NULL))
230 : : /* A section appears twice. That's bad. We ignore the section. */
231 : : return result;
232 : :
233 : : /* We cannot know whether or not a GNU compressed section has already
234 : : been uncompressed or not, so ignore any errors. */
235 [ + + ]: 93308 : if (gnu_compressed)
236 : 164 : elf_compress_gnu (scn, 0, 0);
237 : :
238 [ + + ]: 93308 : if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
239 : : {
240 [ - + ]: 848 : if (elf_compress (scn, 0, 0) < 0)
241 : : {
242 : : /* It would be nice if we could fail with a specific error.
243 : : But we don't know if this was an essential section or not.
244 : : So just continue for now. See also valid_p(). */
245 : : return result;
246 : : }
247 : : }
248 : :
249 : : /* Get the section data. Should be raw bytes, no conversion needed. */
250 : 93308 : Elf_Data *data = elf_rawdata (scn, NULL);
251 [ - + ]: 93308 : if (data == NULL)
252 : 0 : goto err;
253 : :
254 [ + + - + ]: 93308 : if (data->d_buf == NULL || data->d_size == 0)
255 : : /* No data actually available, ignore it. */
256 : : return result;
257 : :
258 : : /* We can now read the section data into results. */
259 : 93296 : result->sectiondata[cnt] = data;
260 : :
261 : : /* If the section contains string data, we want to know a size of a prefix
262 : : where any string will be null-terminated. */
263 : 93296 : enum string_section_index string_section_idx = scn_to_string_section_idx[cnt];
264 [ + + ]: 93296 : if (string_section_idx < STR_SCN_IDX_last)
265 : : {
266 : : size_t size = data->d_size;
267 : : /* Reduce the size by the number of non-zero bytes at the end of the
268 : : section. */
269 [ + - - + ]: 22430 : while (size > 0 && *((const char *) data->d_buf + size - 1) != '\0')
270 : : --size;
271 : 22430 : result->string_section_size[string_section_idx] = size;
272 : : }
273 : :
274 : : return result;
275 : : }
276 : :
277 : : char *
278 : 13492 : __libdw_elfpath (int fd)
279 : : {
280 : : /* strlen ("/proc/self/fd/") = 14 + strlen (<MAXINT>) = 10 + 1 = 25. */
281 : 13492 : char devfdpath[25];
282 [ + - ]: 13492 : sprintf (devfdpath, "/proc/self/fd/%u", fd);
283 [ + - ]: 13492 : return realpath (devfdpath, NULL);
284 : : }
285 : :
286 : :
287 : : void
288 : 12810 : __libdw_set_debugdir (Dwarf *dbg)
289 : : {
290 [ + + + - ]: 12810 : if (dbg->elfpath == NULL || dbg->elfpath[0] != '/')
291 : : return;
292 : 11578 : size_t dirlen = strrchr (dbg->elfpath, '/') - dbg->elfpath + 1;
293 : 11578 : dbg->debugdir = malloc (dirlen + 1);
294 [ + - ]: 11578 : if (dbg->debugdir == NULL)
295 : : return;
296 : 11578 : memcpy (dbg->debugdir, dbg->elfpath, dirlen);
297 : 11578 : dbg->debugdir[dirlen] = '\0';
298 : : }
299 : :
300 : :
301 : : /* Check whether all the necessary DWARF information is available. */
302 : : static Dwarf *
303 : 12390 : valid_p (Dwarf *result)
304 : : {
305 : : /* We looked at all the sections. Now determine whether all the
306 : : sections with debugging information we need are there.
307 : :
308 : : Require at least one section that can be read "standalone". */
309 [ + + ]: 12390 : if (likely (result != NULL)
310 [ + + + + : 12388 : && unlikely (result->sectiondata[IDX_debug_info] == NULL
+ + ]
311 : : && result->sectiondata[IDX_debug_line] == NULL
312 : : && result->sectiondata[IDX_debug_frame] == NULL))
313 : : {
314 : 306 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
315 : 306 : __libdw_seterrno (DWARF_E_NO_DWARF);
316 : 306 : free (result);
317 : 306 : result = NULL;
318 : : }
319 : :
320 : : /* We are setting up some "fake" CUs, which need an address size.
321 : : Check the ELF class to come up with something reasonable. */
322 : 12388 : int elf_addr_size = 8;
323 : 306 : if (result != NULL)
324 : : {
325 : 12082 : GElf_Ehdr ehdr;
326 [ - + ]: 12082 : if (gelf_getehdr (result->elf, &ehdr) == NULL)
327 : : {
328 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
329 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
330 : 0 : free (result);
331 : 0 : result = NULL;
332 : : }
333 [ + + ]: 12082 : else if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
334 : 228 : elf_addr_size = 4;
335 : : }
336 : :
337 : : /* For dwarf_location_attr () we need a "fake" CU to indicate
338 : : where the "fake" attribute data comes from. This is a block
339 : : inside the .debug_loc or .debug_loclists section. */
340 [ + + ]: 12082 : if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
341 : : {
342 : 328 : result->fake_loc_cu = malloc (sizeof (Dwarf_CU));
343 [ - + ]: 328 : if (unlikely (result->fake_loc_cu == NULL))
344 : : {
345 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
346 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
347 : 0 : free (result);
348 : 0 : result = NULL;
349 : : }
350 : : else
351 : : {
352 : 328 : result->fake_loc_cu->sec_idx = IDX_debug_loc;
353 : 328 : result->fake_loc_cu->dbg = result;
354 : 328 : result->fake_loc_cu->startp
355 : 328 : = result->sectiondata[IDX_debug_loc]->d_buf;
356 : 328 : result->fake_loc_cu->endp
357 : 328 : = (result->sectiondata[IDX_debug_loc]->d_buf
358 : 328 : + result->sectiondata[IDX_debug_loc]->d_size);
359 : 328 : result->fake_loc_cu->address_size = elf_addr_size;
360 : 328 : result->fake_loc_cu->offset_size = 4;
361 : 328 : result->fake_loc_cu->version = 4;
362 : 328 : result->fake_loc_cu->split = NULL;
363 : : }
364 : : }
365 : :
366 [ + + ]: 12082 : if (result != NULL && result->sectiondata[IDX_debug_loclists] != NULL)
367 : : {
368 : 10452 : result->fake_loclists_cu = malloc (sizeof (Dwarf_CU));
369 [ - + ]: 10452 : if (unlikely (result->fake_loclists_cu == NULL))
370 : : {
371 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
372 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
373 : 0 : free (result->fake_loc_cu);
374 : 0 : free (result);
375 : 0 : result = NULL;
376 : : }
377 : : else
378 : : {
379 : 10452 : result->fake_loclists_cu->sec_idx = IDX_debug_loclists;
380 : 10452 : result->fake_loclists_cu->dbg = result;
381 : 10452 : result->fake_loclists_cu->startp
382 : 10452 : = result->sectiondata[IDX_debug_loclists]->d_buf;
383 : 10452 : result->fake_loclists_cu->endp
384 : 10452 : = (result->sectiondata[IDX_debug_loclists]->d_buf
385 : 10452 : + result->sectiondata[IDX_debug_loclists]->d_size);
386 : 10452 : result->fake_loclists_cu->address_size = elf_addr_size;
387 : 10452 : result->fake_loclists_cu->offset_size = 4;
388 : 10452 : result->fake_loclists_cu->version = 5;
389 : 10452 : result->fake_loclists_cu->split = NULL;
390 : : }
391 : : }
392 : :
393 : : /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index
394 : : the dwarf_location_attr () will need a "fake" address CU to
395 : : indicate where the attribute data comes from. This is a just
396 : : inside the .debug_addr section, if it exists. */
397 [ + + ]: 12082 : if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL)
398 : : {
399 : 132 : result->fake_addr_cu = malloc (sizeof (Dwarf_CU));
400 [ - + ]: 132 : if (unlikely (result->fake_addr_cu == NULL))
401 : : {
402 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
403 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
404 : 0 : free (result->fake_loc_cu);
405 : 0 : free (result->fake_loclists_cu);
406 : 0 : free (result);
407 : 0 : result = NULL;
408 : : }
409 : : else
410 : : {
411 : 132 : result->fake_addr_cu->sec_idx = IDX_debug_addr;
412 : 132 : result->fake_addr_cu->dbg = result;
413 : 132 : result->fake_addr_cu->startp
414 : 132 : = result->sectiondata[IDX_debug_addr]->d_buf;
415 : 132 : result->fake_addr_cu->endp
416 : 132 : = (result->sectiondata[IDX_debug_addr]->d_buf
417 : 132 : + result->sectiondata[IDX_debug_addr]->d_size);
418 : 132 : result->fake_addr_cu->address_size = elf_addr_size;
419 : 132 : result->fake_addr_cu->offset_size = 4;
420 : 132 : result->fake_addr_cu->version = 5;
421 : 132 : result->fake_addr_cu->split = NULL;
422 : : }
423 : : }
424 : :
425 : 132 : if (result != NULL)
426 : : {
427 [ - + ]: 12082 : if (pthread_rwlock_init(&result->mem_rwl, NULL) != 0)
428 : : {
429 : 0 : free (result->fake_loc_cu);
430 : 0 : free (result->fake_loclists_cu);
431 : 0 : free (result->fake_addr_cu);
432 : 0 : free (result);
433 : 0 : __libdw_seterrno (DWARF_E_NOMEM); /* no memory. */
434 : 0 : return NULL;
435 : : }
436 : :
437 : 12082 : result->elfpath = __libdw_elfpath (result->elf->fildes);
438 : 12082 : __libdw_set_debugdir(result);
439 : :
440 : : /* Initialize locks and search_trees. */
441 : 12082 : mutex_init (result->dwarf_lock);
442 : 12082 : mutex_init (result->macro_lock);
443 : 12082 : eu_search_tree_init (&result->cu_tree);
444 : 12082 : eu_search_tree_init (&result->tu_tree);
445 : 12082 : eu_search_tree_init (&result->split_tree);
446 : 12082 : eu_search_tree_init (&result->macro_ops_tree);
447 : 12082 : eu_search_tree_init (&result->files_lines_tree);
448 : :
449 [ + + ]: 12082 : if (result->fake_loc_cu != NULL)
450 : : {
451 : 328 : eu_search_tree_init (&result->fake_loc_cu->locs_tree);
452 : 328 : rwlock_init (result->fake_loc_cu->split_lock);
453 : 328 : mutex_init (result->fake_loc_cu->abbrev_lock);
454 : 328 : mutex_init (result->fake_loc_cu->src_lock);
455 : 328 : mutex_init (result->fake_loc_cu->str_off_base_lock);
456 : 328 : mutex_init (result->fake_loc_cu->intern_lock);
457 : : }
458 : :
459 [ + + ]: 12082 : if (result->fake_loclists_cu != NULL)
460 : : {
461 : 10452 : eu_search_tree_init (&result->fake_loclists_cu->locs_tree);
462 : 10452 : rwlock_init (result->fake_loclists_cu->split_lock);
463 : 10452 : mutex_init (result->fake_loclists_cu->abbrev_lock);
464 : 10452 : mutex_init (result->fake_loclists_cu->src_lock);
465 : 10452 : mutex_init (result->fake_loclists_cu->str_off_base_lock);
466 : 10452 : mutex_init (result->fake_loclists_cu->intern_lock);
467 : : }
468 : :
469 [ + + ]: 12082 : if (result->fake_addr_cu != NULL)
470 : : {
471 : 132 : eu_search_tree_init (&result->fake_addr_cu->locs_tree);
472 : 132 : rwlock_init (result->fake_addr_cu->split_lock);
473 : 132 : mutex_init (result->fake_addr_cu->abbrev_lock);
474 : 132 : mutex_init (result->fake_addr_cu->src_lock);
475 : 132 : mutex_init (result->fake_addr_cu->str_off_base_lock);
476 : 132 : mutex_init (result->fake_addr_cu->intern_lock);
477 : : }
478 : : }
479 : :
480 : : return result;
481 : : }
482 : :
483 : :
484 : : static Dwarf *
485 : 12390 : global_read (Dwarf *result, Elf *elf, size_t shstrndx)
486 : : {
487 : 12390 : Elf_Scn *scn = NULL;
488 : :
489 : : /* First check the type (PLAIN, DWO, LTO) we are looking for. We
490 : : prefer PLAIN if available over DWO, over LTO. */
491 [ + + + + ]: 373670 : while ((scn = elf_nextscn (elf, scn)) != NULL && result->type != TYPE_PLAIN)
492 : : {
493 : 361280 : enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn);
494 [ + + ]: 361280 : if (type > result->type)
495 : 12084 : result->type = type;
496 : : }
497 : :
498 : : scn = NULL;
499 [ + + + + ]: 622214 : while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
500 : 609824 : result = check_section (result, shstrndx, scn, false);
501 : :
502 : 12390 : return valid_p (result);
503 : : }
504 : :
505 : :
506 : : static Dwarf *
507 : 0 : scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp)
508 : : {
509 : 0 : GElf_Shdr shdr_mem;
510 : 0 : GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
511 [ # # ]: 0 : if (shdr == NULL)
512 : : {
513 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
514 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
515 : 0 : free (result);
516 : 0 : return NULL;
517 : : }
518 : :
519 [ # # ]: 0 : if ((shdr->sh_flags & SHF_COMPRESSED) != 0
520 [ # # ]: 0 : && elf_compress (scngrp, 0, 0) < 0)
521 : : {
522 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
523 : 0 : __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
524 : 0 : free (result);
525 : 0 : return NULL;
526 : : }
527 : :
528 : : /* SCNGRP is the section descriptor for a section group which might
529 : : contain debug sections. */
530 : 0 : Elf_Data *data = elf_getdata (scngrp, NULL);
531 [ # # ]: 0 : if (data == NULL)
532 : : {
533 : : /* We cannot read the section content. Fail! */
534 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
535 : 0 : free (result);
536 : 0 : return NULL;
537 : : }
538 : :
539 : : /* The content of the section is a number of 32-bit words which
540 : : represent section indices. The first word is a flag word. */
541 : 0 : Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
542 : 0 : size_t cnt;
543 : :
544 : : /* First check the type (PLAIN, DWO, LTO) we are looking for. We
545 : : prefer PLAIN if available over DWO, over LTO. */
546 [ # # ]: 0 : for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
547 : : {
548 : 0 : Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
549 [ # # ]: 0 : if (scn == NULL)
550 : : {
551 : : /* A section group refers to a non-existing section. Should
552 : : never happen. */
553 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
554 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
555 : 0 : free (result);
556 : 0 : return NULL;
557 : : }
558 : :
559 : 0 : enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn);
560 [ # # ]: 0 : if (type > result->type)
561 : 0 : result->type = type;
562 : : }
563 : :
564 [ # # # # ]: 0 : for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size && result != NULL; ++cnt)
565 : : {
566 : 0 : Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
567 [ # # ]: 0 : assert (scn != NULL); // checked above
568 : 0 : result = check_section (result, shstrndx, scn, true);
569 [ # # ]: 0 : if (result == NULL)
570 : : break;
571 : : }
572 : :
573 : 0 : return valid_p (result);
574 : : }
575 : :
576 : :
577 : : Dwarf *
578 : 12390 : dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
579 : : {
580 : 12390 : GElf_Ehdr *ehdr;
581 : 12390 : GElf_Ehdr ehdr_mem;
582 : :
583 : : /* Get the ELF header of the file. We need various pieces of
584 : : information from it. */
585 : 12390 : ehdr = gelf_getehdr (elf, &ehdr_mem);
586 [ - + ]: 12390 : if (ehdr == NULL)
587 : : {
588 [ # # ]: 0 : if (elf_kind (elf) != ELF_K_ELF)
589 : 0 : __libdw_seterrno (DWARF_E_NOELF);
590 : : else
591 : 0 : __libdw_seterrno (DWARF_E_GETEHDR_ERROR);
592 : :
593 : 0 : return NULL;
594 : : }
595 : :
596 : :
597 : : /* Default memory allocation size. */
598 : 12390 : size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
599 [ - + ]: 12390 : assert (sizeof (struct Dwarf) < mem_default_size);
600 : :
601 : : /* Allocate the data structure. */
602 : 12390 : Dwarf *result = calloc (1, sizeof (Dwarf));
603 [ + - ]: 12390 : if (unlikely (result == NULL)
604 [ - + ]: 12390 : || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
605 : : {
606 : 0 : free (result);
607 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
608 : 0 : return NULL;
609 : : }
610 : :
611 : : /* Fill in some values. */
612 [ + + ]: 12390 : if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
613 : : || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
614 : 132 : result->other_byte_order = true;
615 : :
616 : 12390 : result->elf = elf;
617 : 12390 : result->alt_fd = -1;
618 : 12390 : result->dwp_fd = -1;
619 : :
620 : : /* Initialize the memory handling. Initial blocks are allocated on first
621 : : actual allocation. */
622 : 12390 : result->mem_default_size = mem_default_size;
623 : 12390 : result->oom_handler = __libdw_oom;
624 : :
625 : 12390 : result->mem_stacks = 0;
626 : 12390 : result->mem_tails = NULL;
627 : :
628 [ + - ]: 12390 : if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
629 : : {
630 : : /* All sections are recognized by name, so pass the section header
631 : : string index along to easily get the section names. */
632 : 12390 : size_t shstrndx;
633 [ - + ]: 12390 : if (elf_getshdrstrndx (elf, &shstrndx) != 0)
634 : : {
635 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
636 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
637 : 0 : free (result);
638 : 0 : return NULL;
639 : : }
640 : :
641 : : /* If the caller provides a section group we get the DWARF
642 : : sections only from this section group. Otherwise we search
643 : : for the first section with the required name. Further
644 : : sections with the name are ignored. The DWARF specification
645 : : does not really say this is allowed. */
646 [ + - ]: 12390 : if (scngrp == NULL)
647 : 12390 : return global_read (result, elf, shstrndx);
648 : : else
649 : 0 : return scngrp_read (result, elf, shstrndx, scngrp);
650 : : }
651 [ # # ]: 0 : else if (cmd == DWARF_C_WRITE)
652 : : {
653 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
654 : 0 : __libdw_seterrno (DWARF_E_UNIMPL);
655 : 0 : free (result);
656 : 0 : return NULL;
657 : : }
658 : :
659 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
660 : 0 : __libdw_seterrno (DWARF_E_INVALID_CMD);
661 : 0 : free (result);
662 : 0 : return NULL;
663 : : }
664 : : INTDEF(dwarf_begin_elf)
|