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 : 353648 : scn_dwarf_type (Dwarf *result, size_t shstrndx, Elf_Scn *scn)
104 : : {
105 : 353648 : GElf_Shdr shdr_mem;
106 : 353648 : GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
107 [ - + ]: 353648 : if (shdr == NULL)
108 : : return TYPE_UNKNOWN;
109 : :
110 : 707296 : const char *scnname = elf_strptr (result->elf, shstrndx,
111 : 353648 : shdr->sh_name);
112 [ + + ]: 353648 : if (scnname != NULL)
113 : : {
114 [ + + ]: 353566 : if (startswith (scnname, ".gnu.debuglto_.debug"))
115 : : return TYPE_GNU_LTO;
116 [ + - ]: 353556 : else if (strcmp (scnname, ".debug_cu_index") == 0
117 [ + - ]: 353556 : || strcmp (scnname, ".debug_tu_index") == 0
118 [ + - ]: 353556 : || strcmp (scnname, ".zdebug_cu_index") == 0
119 [ + - ]: 353556 : || strcmp (scnname, ".zdebug_tu_index") == 0)
120 : : return TYPE_DWO;
121 [ + + + + ]: 353556 : else if (startswith (scnname, ".debug_") || startswith (scnname, ".zdebug_"))
122 : : {
123 : 12290 : size_t len = strlen (scnname);
124 [ + + ]: 12290 : if (strcmp (scnname + len - 4, ".dwo") == 0)
125 : : return TYPE_DWO;
126 : : else
127 : 11454 : return TYPE_PLAIN;
128 : : }
129 : : }
130 : : return TYPE_UNKNOWN;
131 : : }
132 : : static Dwarf *
133 : 598572 : check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp)
134 : : {
135 : 598572 : GElf_Shdr shdr_mem;
136 : 598572 : GElf_Shdr *shdr;
137 : :
138 : : /* Get the section header data. */
139 : 598572 : shdr = gelf_getshdr (scn, &shdr_mem);
140 [ - + ]: 598572 : 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 [ + + ]: 598572 : 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 [ + - + + ]: 566166 : 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 : 1132328 : const char *scnname = elf_strptr (result->elf, shstrndx,
164 : 566164 : shdr->sh_name);
165 [ + + ]: 566164 : 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 : 10664834 : bool gnu_compressed = false;
183 [ + + ]: 10664834 : 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 [ + + ]: 10188878 : if (result->type != TYPE_DWO
188 [ + + ]: 10174290 : && (cnt == IDX_debug_cu_index || cnt == IDX_debug_tu_index))
189 : 951296 : continue;
190 : 18475164 : bool need_dot_dwo =
191 : : (result->type == TYPE_DWO
192 : : && cnt != IDX_debug_cu_index
193 [ + + + + ]: 9237582 : && cnt != IDX_debug_tu_index);
194 : 9237582 : size_t dbglen = strlen (dwarf_scnnames[cnt]);
195 : 9237582 : size_t scnlen = strlen (scnname);
196 [ + + ]: 9237582 : if (strncmp (scnname, dwarf_scnnames[cnt], dbglen) == 0
197 [ + + ]: 110942 : && ((!need_dot_dwo && dbglen == scnlen)
198 [ + + ]: 21736 : || (need_dot_dwo
199 [ + + ]: 1040 : && scnlen == dbglen + 4
200 [ - + ]: 836 : && strstr (scnname, ".dwo") == scnname + dbglen)))
201 : : break;
202 [ + + + + ]: 9147540 : 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 [ + + ]: 9147376 : else if (scnlen > 14 /* .gnu.debuglto_ prefix. */
215 [ + + ]: 769596 : && 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 [ + + ]: 566162 : if (cnt >= ndwarf_scnnames)
224 : : /* Not a debug section; ignore it. */
225 : : return result;
226 : :
227 [ - + ]: 90206 : 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 [ + + ]: 90206 : if (gnu_compressed)
234 : 164 : elf_compress_gnu (scn, 0, 0);
235 : :
236 [ + + ]: 90206 : if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
237 : : {
238 [ - + ]: 806 : 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 : 90206 : Elf_Data *data = elf_rawdata (scn, NULL);
249 [ - + ]: 90206 : if (data == NULL)
250 : 0 : goto err;
251 : :
252 [ + + - + ]: 90206 : 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 : 90194 : 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 : 90194 : enum string_section_index string_section_idx = scn_to_string_section_idx[cnt];
262 [ + + ]: 90194 : 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 [ + - - + ]: 21864 : while (size > 0 && *((const char *) data->d_buf + size - 1) != '\0')
268 : : --size;
269 : 21864 : result->string_section_size[string_section_idx] = size;
270 : : }
271 : :
272 : : return result;
273 : : }
274 : :
275 : : char *
276 : 12998 : __libdw_elfpath (int fd)
277 : : {
278 : : /* strlen ("/proc/self/fd/") = 14 + strlen (<MAXINT>) = 10 + 1 = 25. */
279 : 12998 : char devfdpath[25];
280 [ + - ]: 12998 : sprintf (devfdpath, "/proc/self/fd/%u", fd);
281 [ + - ]: 12998 : return realpath (devfdpath, NULL);
282 : : }
283 : :
284 : :
285 : : void
286 : 12300 : __libdw_set_debugdir (Dwarf *dbg)
287 : : {
288 [ + + + - ]: 12300 : if (dbg->elfpath == NULL || dbg->elfpath[0] != '/')
289 : : return;
290 : 11418 : size_t dirlen = strrchr (dbg->elfpath, '/') - dbg->elfpath + 1;
291 : 11418 : dbg->debugdir = malloc (dirlen + 1);
292 [ + - ]: 11418 : if (dbg->debugdir == NULL)
293 : : return;
294 : 11418 : memcpy (dbg->debugdir, dbg->elfpath, dirlen);
295 : 11418 : dbg->debugdir[dirlen] = '\0';
296 : : }
297 : :
298 : :
299 : : /* Check whether all the necessary DWARF information is available. */
300 : : static Dwarf *
301 : 11916 : 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 [ + + ]: 11916 : if (likely (result != NULL)
308 [ + + + + : 11914 : && unlikely (result->sectiondata[IDX_debug_info] == NULL
+ + ]
309 : : && result->sectiondata[IDX_debug_line] == NULL
310 : : && result->sectiondata[IDX_debug_frame] == NULL))
311 : : {
312 : 320 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
313 : 320 : __libdw_seterrno (DWARF_E_NO_DWARF);
314 : 320 : free (result);
315 : 320 : 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 : 23498 : int elf_addr_size = 8;
321 [ + + ]: 11904 : if (result != NULL)
322 : : {
323 : 11594 : GElf_Ehdr ehdr;
324 [ - + ]: 11594 : 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 [ + + ]: 11594 : else if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
332 : 236 : 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 [ + + ]: 11594 : if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
339 : : {
340 : 296 : result->fake_loc_cu = malloc (sizeof (Dwarf_CU));
341 [ - + ]: 296 : 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 : 296 : result->fake_loc_cu->sec_idx = IDX_debug_loc;
351 : 296 : result->fake_loc_cu->dbg = result;
352 : 296 : result->fake_loc_cu->startp
353 : 296 : = result->sectiondata[IDX_debug_loc]->d_buf;
354 : 296 : result->fake_loc_cu->endp
355 : 296 : = (result->sectiondata[IDX_debug_loc]->d_buf
356 : 296 : + result->sectiondata[IDX_debug_loc]->d_size);
357 : 296 : result->fake_loc_cu->locs = NULL;
358 : 296 : result->fake_loc_cu->address_size = elf_addr_size;
359 : 296 : result->fake_loc_cu->offset_size = 4;
360 : 296 : result->fake_loc_cu->version = 4;
361 : 296 : result->fake_loc_cu->split = NULL;
362 : : }
363 : : }
364 : :
365 [ + + ]: 11594 : if (result != NULL && result->sectiondata[IDX_debug_loclists] != NULL)
366 : : {
367 : 10380 : result->fake_loclists_cu = malloc (sizeof (Dwarf_CU));
368 [ - + ]: 10380 : if (unlikely (result->fake_loclists_cu == NULL))
369 : : {
370 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
371 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
372 : 0 : free (result->fake_loc_cu);
373 : 0 : free (result);
374 : 0 : result = NULL;
375 : : }
376 : : else
377 : : {
378 : 10380 : result->fake_loclists_cu->sec_idx = IDX_debug_loclists;
379 : 10380 : result->fake_loclists_cu->dbg = result;
380 : 10380 : result->fake_loclists_cu->startp
381 : 10380 : = result->sectiondata[IDX_debug_loclists]->d_buf;
382 : 10380 : result->fake_loclists_cu->endp
383 : 10380 : = (result->sectiondata[IDX_debug_loclists]->d_buf
384 : 10380 : + result->sectiondata[IDX_debug_loclists]->d_size);
385 : 10380 : result->fake_loclists_cu->locs = NULL;
386 : 10380 : result->fake_loclists_cu->address_size = elf_addr_size;
387 : 10380 : result->fake_loclists_cu->offset_size = 4;
388 : 10380 : result->fake_loclists_cu->version = 5;
389 : 10380 : 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 [ + + ]: 11594 : if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL)
398 : : {
399 : 82 : result->fake_addr_cu = malloc (sizeof (Dwarf_CU));
400 [ - + ]: 82 : 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 : 82 : result->fake_addr_cu->sec_idx = IDX_debug_addr;
412 : 82 : result->fake_addr_cu->dbg = result;
413 : 82 : result->fake_addr_cu->startp
414 : 82 : = result->sectiondata[IDX_debug_addr]->d_buf;
415 : 82 : result->fake_addr_cu->endp
416 : 82 : = (result->sectiondata[IDX_debug_addr]->d_buf
417 : 82 : + result->sectiondata[IDX_debug_addr]->d_size);
418 : 82 : result->fake_addr_cu->locs = NULL;
419 : 82 : result->fake_addr_cu->address_size = elf_addr_size;
420 : 82 : result->fake_addr_cu->offset_size = 4;
421 : 82 : result->fake_addr_cu->version = 5;
422 : 82 : result->fake_addr_cu->split = NULL;
423 : : }
424 : : }
425 : :
426 : 82 : if (result != NULL)
427 : : {
428 : 11594 : result->elfpath = __libdw_elfpath (result->elf->fildes);
429 : 11594 : __libdw_set_debugdir(result);
430 : : }
431 : :
432 : 11916 : return result;
433 : : }
434 : :
435 : :
436 : : static Dwarf *
437 : 11916 : global_read (Dwarf *result, Elf *elf, size_t shstrndx)
438 : : {
439 : 11916 : Elf_Scn *scn = NULL;
440 : :
441 : : /* First check the type (PLAIN, DWO, LTO) we are looking for. We
442 : : prefer PLAIN if available over DWO, over LTO. */
443 [ + + + + ]: 365564 : while ((scn = elf_nextscn (elf, scn)) != NULL && result->type != TYPE_PLAIN)
444 : : {
445 : 353648 : enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn);
446 [ + + ]: 353648 : if (type > result->type)
447 : 11596 : result->type = type;
448 : : }
449 : :
450 : : scn = NULL;
451 [ + + + + ]: 610488 : while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
452 : 598572 : result = check_section (result, shstrndx, scn, false);
453 : :
454 : 11916 : return valid_p (result);
455 : : }
456 : :
457 : :
458 : : static Dwarf *
459 : 0 : scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp)
460 : : {
461 : 0 : GElf_Shdr shdr_mem;
462 : 0 : GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
463 [ # # ]: 0 : if (shdr == NULL)
464 : : {
465 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
466 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
467 : 0 : free (result);
468 : 0 : return NULL;
469 : : }
470 : :
471 [ # # ]: 0 : if ((shdr->sh_flags & SHF_COMPRESSED) != 0
472 [ # # ]: 0 : && elf_compress (scngrp, 0, 0) < 0)
473 : : {
474 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
475 : 0 : __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
476 : 0 : free (result);
477 : 0 : return NULL;
478 : : }
479 : :
480 : : /* SCNGRP is the section descriptor for a section group which might
481 : : contain debug sections. */
482 : 0 : Elf_Data *data = elf_getdata (scngrp, NULL);
483 [ # # ]: 0 : if (data == NULL)
484 : : {
485 : : /* We cannot read the section content. Fail! */
486 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
487 : 0 : free (result);
488 : 0 : return NULL;
489 : : }
490 : :
491 : : /* The content of the section is a number of 32-bit words which
492 : : represent section indices. The first word is a flag word. */
493 : 0 : Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
494 : 0 : size_t cnt;
495 : :
496 : : /* First check the type (PLAIN, DWO, LTO) we are looking for. We
497 : : prefer PLAIN if available over DWO, over LTO. */
498 [ # # ]: 0 : for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
499 : : {
500 : 0 : Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
501 [ # # ]: 0 : if (scn == NULL)
502 : : {
503 : : /* A section group refers to a non-existing section. Should
504 : : never happen. */
505 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
506 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
507 : 0 : free (result);
508 : 0 : return NULL;
509 : : }
510 : :
511 : 0 : enum dwarf_type type = scn_dwarf_type (result, shstrndx, scn);
512 [ # # ]: 0 : if (type > result->type)
513 : 0 : result->type = type;
514 : : }
515 : :
516 [ # # # # ]: 0 : for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size && result != NULL; ++cnt)
517 : : {
518 : 0 : Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
519 [ # # ]: 0 : assert (scn != NULL); // checked above
520 : 0 : result = check_section (result, shstrndx, scn, true);
521 [ # # ]: 0 : if (result == NULL)
522 : : break;
523 : : }
524 : :
525 : 0 : return valid_p (result);
526 : : }
527 : :
528 : :
529 : : Dwarf *
530 : 11916 : dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
531 : : {
532 : 11916 : GElf_Ehdr *ehdr;
533 : 11916 : GElf_Ehdr ehdr_mem;
534 : :
535 : : /* Get the ELF header of the file. We need various pieces of
536 : : information from it. */
537 : 11916 : ehdr = gelf_getehdr (elf, &ehdr_mem);
538 [ - + ]: 11916 : if (ehdr == NULL)
539 : : {
540 [ # # ]: 0 : if (elf_kind (elf) != ELF_K_ELF)
541 : 0 : __libdw_seterrno (DWARF_E_NOELF);
542 : : else
543 : 0 : __libdw_seterrno (DWARF_E_GETEHDR_ERROR);
544 : :
545 : 0 : return NULL;
546 : : }
547 : :
548 : :
549 : : /* Default memory allocation size. */
550 : 11916 : size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
551 [ - + ]: 11916 : assert (sizeof (struct Dwarf) < mem_default_size);
552 : :
553 : : /* Allocate the data structure. */
554 : 11916 : Dwarf *result = calloc (1, sizeof (Dwarf));
555 [ + - ]: 11916 : if (unlikely (result == NULL)
556 [ - + ]: 11916 : || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
557 : : {
558 : 0 : free (result);
559 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
560 : 0 : return NULL;
561 : : }
562 : :
563 : : /* Fill in some values. */
564 [ + + ]: 11916 : if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
565 : : || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
566 : 132 : result->other_byte_order = true;
567 : :
568 : 11916 : result->elf = elf;
569 : 11916 : result->alt_fd = -1;
570 : :
571 : : /* Initialize the memory handling. Initial blocks are allocated on first
572 : : actual allocation. */
573 : 11916 : result->mem_default_size = mem_default_size;
574 : 11916 : result->oom_handler = __libdw_oom;
575 [ - + ]: 11916 : if (pthread_rwlock_init(&result->mem_rwl, NULL) != 0)
576 : : {
577 : 0 : free (result);
578 : 0 : __libdw_seterrno (DWARF_E_NOMEM); /* no memory. */
579 : 0 : return NULL;
580 : : }
581 : 11916 : result->mem_stacks = 0;
582 : 11916 : result->mem_tails = NULL;
583 : :
584 [ + - ]: 11916 : if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
585 : : {
586 : : /* All sections are recognized by name, so pass the section header
587 : : string index along to easily get the section names. */
588 : 11916 : size_t shstrndx;
589 [ - + ]: 11916 : if (elf_getshdrstrndx (elf, &shstrndx) != 0)
590 : : {
591 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
592 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
593 : 0 : free (result);
594 : 0 : return NULL;
595 : : }
596 : :
597 : : /* If the caller provides a section group we get the DWARF
598 : : sections only from this section group. Otherwise we search
599 : : for the first section with the required name. Further
600 : : sections with the name are ignored. The DWARF specification
601 : : does not really say this is allowed. */
602 [ + - ]: 11916 : if (scngrp == NULL)
603 : 11916 : return global_read (result, elf, shstrndx);
604 : : else
605 : 0 : return scngrp_read (result, elf, shstrndx, scngrp);
606 : : }
607 [ # # ]: 0 : else if (cmd == DWARF_C_WRITE)
608 : : {
609 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
610 : 0 : __libdw_seterrno (DWARF_E_UNIMPL);
611 : 0 : free (result);
612 : 0 : return NULL;
613 : : }
614 : :
615 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
616 : 0 : __libdw_seterrno (DWARF_E_INVALID_CMD);
617 : 0 : free (result);
618 : 0 : return NULL;
619 : : }
620 : : INTDEF(dwarf_begin_elf)
|