Branch data Line data Source code
1 : : /* Iterate through the CU units for a given Dwarf.
2 : : Copyright (C) 2016, 2017 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 : :
30 : : #ifdef HAVE_CONFIG_H
31 : : # include <config.h>
32 : : #endif
33 : :
34 : : #include <string.h>
35 : :
36 : : #include "libdwP.h"
37 : :
38 : : int
39 : 21360 : dwarf_get_units (Dwarf *dwarf, Dwarf_CU *cu, Dwarf_CU **next_cu,
40 : : Dwarf_Half *version, uint8_t *unit_type,
41 : : Dwarf_Die *cudie, Dwarf_Die *subdie)
42 : : {
43 : : /* Handle existing error. */
44 [ + - ]: 21360 : if (dwarf == NULL)
45 : : return -1;
46 : :
47 : 21360 : Dwarf_Off off;
48 : 21360 : bool v4type;
49 [ + + ]: 21360 : if (cu == NULL)
50 : : {
51 : : off = 0;
52 : : v4type = false;
53 : : }
54 : : else
55 : : {
56 : 16264 : off = cu->end;
57 : 16264 : v4type = cu->sec_idx != IDX_debug_info;
58 : :
59 : : /* Make sure we got a real (not fake) CU. */
60 [ - + ]: 16264 : if (cu->sec_idx != IDX_debug_info && cu->sec_idx != IDX_debug_types)
61 : : {
62 : 0 : __libdw_seterrno (DWARF_E_INVALID_OFFSET);
63 : 0 : return -1;
64 : : }
65 : :
66 : : /* Do we have to switch to the other section, or are we at the end? */
67 [ + + ]: 16264 : if (! v4type)
68 : : {
69 [ + + ]: 16232 : if (off >= cu->dbg->sectiondata[IDX_debug_info]->d_size)
70 : : {
71 [ + + ]: 532 : if (cu->dbg->sectiondata[IDX_debug_types] == NULL)
72 : : return 1;
73 : :
74 : : off = 0;
75 : : v4type = true;
76 : : }
77 : : }
78 : : else
79 [ + + ]: 32 : if (off >= cu->dbg->sectiondata[IDX_debug_types]->d_size)
80 : : return 1;
81 : : }
82 : :
83 : 20830 : *next_cu = __libdw_findcu (dwarf, off, v4type);
84 [ + + ]: 20830 : if (*next_cu == NULL)
85 : : return -1;
86 : :
87 : 20812 : Dwarf_CU *next = (*next_cu);
88 : :
89 [ + + ]: 20812 : if (version != NULL)
90 : 6194 : *version = next->version;
91 : :
92 [ + + ]: 20812 : if (unit_type != NULL)
93 : 13580 : *unit_type = next->unit_type;
94 : :
95 [ + + ]: 20812 : if (cudie != NULL)
96 : : {
97 [ + - ]: 11232 : if (next->version >= 2 && next->version <= 5
98 [ + - ]: 11232 : && next->unit_type >= DW_UT_compile
99 [ + - ]: 11232 : && next->unit_type <= DW_UT_split_type)
100 : 11232 : *cudie = CUDIE (next);
101 : : else
102 : 0 : memset (cudie, '\0', sizeof (Dwarf_Die));
103 : : }
104 : :
105 [ + + ]: 20812 : if (subdie != NULL)
106 : : {
107 [ + - ]: 9816 : if (next->version >= 2 && next->version <= 5)
108 : : {
109 : : /* For types, return the actual type DIE. For skeletons,
110 : : find the associated split compile unit and return its
111 : : DIE. */
112 : 9816 : if (next->unit_type == DW_UT_type
113 [ + + ]: 9816 : || next->unit_type == DW_UT_split_type)
114 : 16 : *subdie = SUBDIE(next);
115 [ + + ]: 9800 : else if (next->unit_type == DW_UT_skeleton)
116 : : {
117 : 102 : Dwarf_CU *split_cu = __libdw_find_split_unit (next);
118 [ + - ]: 102 : if (split_cu != NULL)
119 : 102 : *subdie = CUDIE(split_cu);
120 : : else
121 : 0 : memset (subdie, '\0', sizeof (Dwarf_Die));
122 : : }
123 : : else
124 : 9698 : memset (subdie, '\0', sizeof (Dwarf_Die));
125 : : }
126 : : else
127 : 0 : memset (subdie, '\0', sizeof (Dwarf_Die));
128 : : }
129 : :
130 : : return 0;
131 : : }
132 : : INTDEF(dwarf_get_units)
|