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