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 : : 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 <assert.h>
34 : : #include <stdbool.h>
35 : : #include <stddef.h>
36 : : #include <stdlib.h>
37 : : #include <stdio.h>
38 : : #include <string.h>
39 : : #include <unistd.h>
40 : : #include <sys/types.h>
41 : : #include <sys/stat.h>
42 : : #include <fcntl.h>
43 : : #include <endian.h>
44 : :
45 : : #include "libelfP.h"
46 : : #include "libdwP.h"
47 : :
48 : :
49 : : /* Section names. (Note .debug_str_offsets is the largest 19 chars.) */
50 : : static const char dwarf_scnnames[IDX_last][19] =
51 : : {
52 : : [IDX_debug_info] = ".debug_info",
53 : : [IDX_debug_types] = ".debug_types",
54 : : [IDX_debug_abbrev] = ".debug_abbrev",
55 : : [IDX_debug_addr] = ".debug_addr",
56 : : [IDX_debug_aranges] = ".debug_aranges",
57 : : [IDX_debug_line] = ".debug_line",
58 : : [IDX_debug_line_str] = ".debug_line_str",
59 : : [IDX_debug_frame] = ".debug_frame",
60 : : [IDX_debug_loc] = ".debug_loc",
61 : : [IDX_debug_loclists] = ".debug_loclists",
62 : : [IDX_debug_pubnames] = ".debug_pubnames",
63 : : [IDX_debug_str] = ".debug_str",
64 : : [IDX_debug_str_offsets] = ".debug_str_offsets",
65 : : [IDX_debug_macinfo] = ".debug_macinfo",
66 : : [IDX_debug_macro] = ".debug_macro",
67 : : [IDX_debug_ranges] = ".debug_ranges",
68 : : [IDX_debug_rnglists] = ".debug_rnglists",
69 : : [IDX_gnu_debugaltlink] = ".gnu_debugaltlink"
70 : : };
71 : : #define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
72 : :
73 : : static Dwarf *
74 : 281697 : check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp)
75 : : {
76 : 281697 : GElf_Shdr shdr_mem;
77 : 281697 : GElf_Shdr *shdr;
78 : :
79 : : /* Get the section header data. */
80 : 281697 : shdr = gelf_getshdr (scn, &shdr_mem);
81 [ + - ]: 281697 : if (shdr == NULL)
82 : : /* We may read /proc/PID/mem with only program headers mapped and section
83 : : headers out of the mapped pages. */
84 : : goto err;
85 : :
86 : : /* Ignore any SHT_NOBITS sections. Debugging sections should not
87 : : have been stripped, but in case of a corrupt file we won't try
88 : : to look at the missing data. */
89 [ + + ]: 281697 : if (unlikely (shdr->sh_type == SHT_NOBITS))
90 : : return result;
91 : :
92 : : /* Make sure the section is part of a section group only iff we
93 : : really need it. If we are looking for the global (= non-section
94 : : group debug info) we have to ignore all the info in section
95 : : groups. If we are looking into a section group we cannot look at
96 : : a section which isn't part of the section group. */
97 [ + - ][ + + ]: 268424 : if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
98 : : /* Ignore the section. */
99 : : return result;
100 : :
101 : :
102 : : /* We recognize the DWARF section by their names. This is not very
103 : : safe and stable but the best we can do. */
104 : 805269 : const char *scnname = elf_strptr (result->elf, shstrndx,
105 : 268423 : shdr->sh_name);
106 [ + + ]: 268423 : if (scnname == NULL)
107 : : {
108 : : /* The section name must be valid. Otherwise is the ELF file
109 : : invalid. */
110 : 1 : err:
111 : 1 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
112 : 1 : __libdw_seterrno (DWARF_E_INVALID_ELF);
113 : 1 : free (result);
114 : 1 : return NULL;
115 : : }
116 : :
117 : : /* Recognize the various sections. Most names start with .debug_. */
118 : : size_t cnt;
119 : : bool gnu_compressed = false;
120 [ + + ]: 4643703 : for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
121 : : {
122 : 4414082 : size_t dbglen = strlen (dwarf_scnnames[cnt]);
123 : 4414082 : size_t scnlen = strlen (scnname);
124 [ + + ]: 4414082 : if (strncmp (scnname, dwarf_scnnames[cnt], dbglen) == 0
125 [ + + ]: 38843 : && (dbglen == scnlen
126 [ + + ]: 542 : || (scnlen == dbglen + 4
127 [ + + ]: 427 : && strstr (scnname, ".dwo") == scnname + dbglen)))
128 : : break;
129 [ + + ][ + + ]: 4375363 : else if (scnname[0] == '.' && scnname[1] == 'z'
130 [ + + ]: 594 : && (strncmp (&scnname[2], &dwarf_scnnames[cnt][1],
131 : : dbglen - 1) == 0
132 [ - + ]: 82 : && (scnlen == dbglen + 1
133 [ # # ]: 0 : || (scnlen == dbglen + 5
134 : 0 : && strstr (scnname,
135 [ # # ]: 0 : ".dwo") == scnname + dbglen + 1))))
136 : : {
137 : : gnu_compressed = true;
138 : : break;
139 : : }
140 [ + + ]: 4375281 : else if (scnlen > 14 /* .gnu.debuglto_ prefix. */
141 [ - + ]: 123286 : && strncmp (scnname, ".gnu.debuglto_", 14) == 0
142 [ # # ]: 0 : && strcmp (&scnname[14], dwarf_scnnames[cnt]) == 0)
143 : : break;
144 : : }
145 : :
146 [ + + ]: 268422 : if (cnt >= ndwarf_scnnames)
147 : : /* Not a debug section; ignore it. */
148 : : return result;
149 : :
150 [ + - ]: 38801 : if (unlikely (result->sectiondata[cnt] != NULL))
151 : : /* A section appears twice. That's bad. We ignore the section. */
152 : : return result;
153 : :
154 : : /* We cannot know whether or not a GNU compressed section has already
155 : : been uncompressed or not, so ignore any errors. */
156 [ + + ]: 38801 : if (gnu_compressed)
157 : 82 : elf_compress_gnu (scn, 0, 0);
158 : :
159 [ + + ]: 38801 : if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
160 : : {
161 [ + - ]: 298 : if (elf_compress (scn, 0, 0) < 0)
162 : : {
163 : : /* It would be nice if we could fail with a specific error.
164 : : But we don't know if this was an essential section or not.
165 : : So just continue for now. See also valid_p(). */
166 : : return result;
167 : : }
168 : : }
169 : :
170 : : /* Get the section data. */
171 : 38801 : Elf_Data *data = elf_getdata (scn, NULL);
172 [ - + ]: 38801 : if (data == NULL)
173 : : goto err;
174 : :
175 [ + + ][ + - ]: 38801 : if (data->d_buf == NULL || data->d_size == 0)
176 : : /* No data actually available, ignore it. */
177 : : return result;
178 : :
179 : : /* We can now read the section data into results. */
180 : 38795 : result->sectiondata[cnt] = data;
181 : :
182 : 38795 : return result;
183 : : }
184 : :
185 : :
186 : : /* Helper function to set debugdir field. We want to cache the dir
187 : : where we found this Dwarf ELF file to locate alt and dwo files. */
188 : : char *
189 : 6134 : __libdw_debugdir (int fd)
190 : : {
191 : : /* strlen ("/proc/self/fd/") = 14 + strlen (<MAXINT>) = 10 + 1 = 25. */
192 : 6134 : char devfdpath[25];
193 [ - + ]: 6134 : sprintf (devfdpath, "/proc/self/fd/%u", fd);
194 [ - + ]: 6134 : char *fdpath = realpath (devfdpath, NULL);
195 : 6134 : char *fddir;
196 [ + + ][ + - ]: 6134 : if (fdpath != NULL && fdpath[0] == '/'
197 [ + - ]: 5836 : && (fddir = strrchr (fdpath, '/')) != NULL)
198 : : {
199 : 5836 : *++fddir = '\0';
200 : 5836 : return fdpath;
201 : : }
202 : : return NULL;
203 : : }
204 : :
205 : :
206 : : /* Check whether all the necessary DWARF information is available. */
207 : : static Dwarf *
208 : 5726 : valid_p (Dwarf *result)
209 : : {
210 : : /* We looked at all the sections. Now determine whether all the
211 : : sections with debugging information we need are there.
212 : :
213 : : Require at least one section that can be read "standalone". */
214 [ + + ]: 5726 : if (likely (result != NULL)
215 [ + + ][ + + ]: 5725 : && unlikely (result->sectiondata[IDX_debug_info] == NULL
[ + + ]
216 : : && result->sectiondata[IDX_debug_line] == NULL
217 : : && result->sectiondata[IDX_debug_frame] == NULL))
218 : : {
219 : 125 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
220 : 125 : __libdw_seterrno (DWARF_E_NO_DWARF);
221 : 125 : free (result);
222 : 125 : result = NULL;
223 : : }
224 : :
225 : : /* For dwarf_location_attr () we need a "fake" CU to indicate
226 : : where the "fake" attribute data comes from. This is a block
227 : : inside the .debug_loc or .debug_loclists section. */
228 [ + + ][ + + ]: 5726 : if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
229 : : {
230 : 5256 : result->fake_loc_cu = (Dwarf_CU *) malloc (sizeof (Dwarf_CU));
231 [ - + ]: 5256 : if (unlikely (result->fake_loc_cu == NULL))
232 : : {
233 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
234 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
235 : 0 : free (result);
236 : 0 : result = NULL;
237 : : }
238 : : else
239 : : {
240 : 5256 : result->fake_loc_cu->sec_idx = IDX_debug_loc;
241 : 5256 : result->fake_loc_cu->dbg = result;
242 : 5256 : result->fake_loc_cu->startp
243 : 5256 : = result->sectiondata[IDX_debug_loc]->d_buf;
244 : 5256 : result->fake_loc_cu->endp
245 : 5256 : = (result->sectiondata[IDX_debug_loc]->d_buf
246 : 5256 : + result->sectiondata[IDX_debug_loc]->d_size);
247 : 5256 : result->fake_loc_cu->locs = NULL;
248 : 5256 : result->fake_loc_cu->address_size = 0;
249 : 5256 : result->fake_loc_cu->version = 0;
250 : 5256 : result->fake_loc_cu->split = NULL;
251 : : }
252 : : }
253 : :
254 [ + + ][ + + ]: 5726 : if (result != NULL && result->sectiondata[IDX_debug_loclists] != NULL)
255 : : {
256 : 45 : result->fake_loclists_cu = (Dwarf_CU *) malloc (sizeof (Dwarf_CU));
257 [ - + ]: 45 : if (unlikely (result->fake_loclists_cu == NULL))
258 : : {
259 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
260 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
261 : 0 : free (result->fake_loc_cu);
262 : 0 : free (result);
263 : 0 : result = NULL;
264 : : }
265 : : else
266 : : {
267 : 45 : result->fake_loclists_cu->sec_idx = IDX_debug_loclists;
268 : 45 : result->fake_loclists_cu->dbg = result;
269 : 45 : result->fake_loclists_cu->startp
270 : 45 : = result->sectiondata[IDX_debug_loclists]->d_buf;
271 : 45 : result->fake_loclists_cu->endp
272 : 45 : = (result->sectiondata[IDX_debug_loclists]->d_buf
273 : 45 : + result->sectiondata[IDX_debug_loclists]->d_size);
274 : 45 : result->fake_loclists_cu->locs = NULL;
275 : 45 : result->fake_loclists_cu->address_size = 0;
276 : 45 : result->fake_loclists_cu->version = 0;
277 : 45 : result->fake_loclists_cu->split = NULL;
278 : : }
279 : : }
280 : :
281 : : /* For DW_OP_constx/GNU_const_index and DW_OP_addrx/GNU_addr_index
282 : : the dwarf_location_attr () will need a "fake" address CU to
283 : : indicate where the attribute data comes from. This is a just
284 : : inside the .debug_addr section, if it exists. */
285 [ + + ][ + + ]: 5726 : if (result != NULL && result->sectiondata[IDX_debug_addr] != NULL)
286 : : {
287 : 39 : result->fake_addr_cu = (Dwarf_CU *) malloc (sizeof (Dwarf_CU));
288 [ - + ]: 39 : if (unlikely (result->fake_addr_cu == NULL))
289 : : {
290 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
291 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
292 : 0 : free (result->fake_loc_cu);
293 : 0 : free (result->fake_loclists_cu);
294 : 0 : free (result);
295 : 0 : result = NULL;
296 : : }
297 : : else
298 : : {
299 : 39 : result->fake_addr_cu->sec_idx = IDX_debug_addr;
300 : 39 : result->fake_addr_cu->dbg = result;
301 : 39 : result->fake_addr_cu->startp
302 : 39 : = result->sectiondata[IDX_debug_addr]->d_buf;
303 : 39 : result->fake_addr_cu->endp
304 : 39 : = (result->sectiondata[IDX_debug_addr]->d_buf
305 : 39 : + result->sectiondata[IDX_debug_addr]->d_size);
306 : 39 : result->fake_addr_cu->locs = NULL;
307 : 39 : result->fake_addr_cu->address_size = 0;
308 : 39 : result->fake_addr_cu->version = 0;
309 : 39 : result->fake_addr_cu->split = NULL;
310 : : }
311 : : }
312 : :
313 [ + + ]: 5726 : if (result != NULL)
314 : 5600 : result->debugdir = __libdw_debugdir (result->elf->fildes);
315 : :
316 : 5726 : return result;
317 : : }
318 : :
319 : :
320 : : static Dwarf *
321 : 5726 : global_read (Dwarf *result, Elf *elf, size_t shstrndx)
322 : : {
323 : 5726 : Elf_Scn *scn = NULL;
324 : :
325 [ + + ][ + + ]: 287423 : while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
326 : 281697 : result = check_section (result, shstrndx, scn, false);
327 : :
328 : 5726 : return valid_p (result);
329 : : }
330 : :
331 : :
332 : : static Dwarf *
333 : 0 : scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp)
334 : : {
335 : 0 : GElf_Shdr shdr_mem;
336 : 0 : GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
337 [ # # ]: 0 : if (shdr == NULL)
338 : : {
339 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
340 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
341 : 0 : free (result);
342 : 0 : return NULL;
343 : : }
344 : :
345 [ # # ]: 0 : if ((shdr->sh_flags & SHF_COMPRESSED) != 0
346 [ # # ]: 0 : && elf_compress (scngrp, 0, 0) < 0)
347 : : {
348 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
349 : 0 : __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
350 : 0 : free (result);
351 : 0 : return NULL;
352 : : }
353 : :
354 : : /* SCNGRP is the section descriptor for a section group which might
355 : : contain debug sections. */
356 : 0 : Elf_Data *data = elf_getdata (scngrp, NULL);
357 [ # # ]: 0 : if (data == NULL)
358 : : {
359 : : /* We cannot read the section content. Fail! */
360 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
361 : 0 : free (result);
362 : 0 : return NULL;
363 : : }
364 : :
365 : : /* The content of the section is a number of 32-bit words which
366 : : represent section indices. The first word is a flag word. */
367 : 0 : Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
368 : 0 : size_t cnt;
369 [ # # ]: 0 : for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
370 : : {
371 : 0 : Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
372 [ # # ]: 0 : if (scn == NULL)
373 : : {
374 : : /* A section group refers to a non-existing section. Should
375 : : never happen. */
376 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
377 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
378 : 0 : free (result);
379 : 0 : return NULL;
380 : : }
381 : :
382 : 0 : result = check_section (result, shstrndx, scn, true);
383 [ # # ]: 0 : if (result == NULL)
384 : : break;
385 : : }
386 : :
387 : 0 : return valid_p (result);
388 : : }
389 : :
390 : :
391 : : Dwarf *
392 : 5726 : dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
393 : : {
394 : 5726 : GElf_Ehdr *ehdr;
395 : 5726 : GElf_Ehdr ehdr_mem;
396 : :
397 : : /* Get the ELF header of the file. We need various pieces of
398 : : information from it. */
399 : 5726 : ehdr = gelf_getehdr (elf, &ehdr_mem);
400 [ - + ]: 5726 : if (ehdr == NULL)
401 : : {
402 [ # # ]: 0 : if (elf_kind (elf) != ELF_K_ELF)
403 : 0 : __libdw_seterrno (DWARF_E_NOELF);
404 : : else
405 : 0 : __libdw_seterrno (DWARF_E_GETEHDR_ERROR);
406 : :
407 : 0 : return NULL;
408 : : }
409 : :
410 : :
411 : : /* Default memory allocation size. */
412 : 5726 : size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
413 [ - + ]: 5726 : assert (sizeof (struct Dwarf) < mem_default_size);
414 : :
415 : : /* Allocate the data structure. */
416 : 5726 : Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf));
417 [ + - ]: 5726 : if (unlikely (result == NULL)
418 [ - + ]: 5726 : || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
419 : : {
420 : 0 : free (result);
421 : 0 : __libdw_seterrno (DWARF_E_NOMEM);
422 : 0 : return NULL;
423 : : }
424 : :
425 : : /* Fill in some values. */
426 [ + + ]: 5726 : if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
427 : : || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
428 : 78 : result->other_byte_order = true;
429 : :
430 : 5726 : result->elf = elf;
431 : 5726 : result->alt_fd = -1;
432 : :
433 : : /* Initialize the memory handling. Initial blocks are allocated on first
434 : : actual allocation. */
435 : 5726 : result->mem_default_size = mem_default_size;
436 : 5726 : result->oom_handler = __libdw_oom;
437 [ - + ]: 5726 : if (pthread_rwlock_init(&result->mem_rwl, NULL) != 0)
438 : : {
439 : 0 : free (result);
440 : 0 : __libdw_seterrno (DWARF_E_NOMEM); /* no memory. */
441 : 0 : return NULL;
442 : : }
443 : 5726 : result->mem_stacks = 0;
444 : 5726 : result->mem_tails = NULL;
445 : :
446 [ + - ]: 5726 : if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
447 : : {
448 : : /* All sections are recognized by name, so pass the section header
449 : : string index along to easily get the section names. */
450 : 5726 : size_t shstrndx;
451 [ - + ]: 5726 : if (elf_getshdrstrndx (elf, &shstrndx) != 0)
452 : : {
453 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
454 : 0 : __libdw_seterrno (DWARF_E_INVALID_ELF);
455 : 0 : free (result);
456 : 0 : return NULL;
457 : : }
458 : :
459 : : /* If the caller provides a section group we get the DWARF
460 : : sections only from this section group. Otherwise we search
461 : : for the first section with the required name. Further
462 : : sections with the name are ignored. The DWARF specification
463 : : does not really say this is allowed. */
464 [ + - ]: 5726 : if (scngrp == NULL)
465 : 5726 : return global_read (result, elf, shstrndx);
466 : : else
467 : 0 : return scngrp_read (result, elf, shstrndx, scngrp);
468 : : }
469 [ # # ]: 0 : else if (cmd == DWARF_C_WRITE)
470 : : {
471 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
472 : 0 : __libdw_seterrno (DWARF_E_UNIMPL);
473 : 0 : free (result);
474 : 0 : return NULL;
475 : : }
476 : :
477 : 0 : Dwarf_Sig8_Hash_free (&result->sig8_hash);
478 : 0 : __libdw_seterrno (DWARF_E_INVALID_CMD);
479 : 0 : free (result);
480 : 0 : return NULL;
481 : : }
482 : : INTDEF(dwarf_begin_elf)
|