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 7272 : 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 7272 : if (dwarf == NULL)
45 : return -1;
46 :
47 : Dwarf_Off off;
48 : bool v4type;
49 7272 : if (cu == NULL)
50 : {
51 : off = 0;
52 : v4type = false;
53 : }
54 : else
55 : {
56 5628 : off = cu->end;
57 5628 : v4type = cu->sec_idx != IDX_debug_info;
58 :
59 : /* Make sure we got a real (not fake) CU. */
60 5628 : 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 5628 : if (! v4type)
68 : {
69 5616 : if (off >= cu->dbg->sectiondata[IDX_debug_info]->d_size)
70 : {
71 182 : if (cu->dbg->sectiondata[IDX_debug_types] == NULL)
72 : return 1;
73 :
74 : off = 0;
75 : v4type = true;
76 : }
77 : }
78 : else
79 12 : if (off >= cu->dbg->sectiondata[IDX_debug_types]->d_size)
80 : return 1;
81 : }
82 :
83 7091 : *next_cu = __libdw_findcu (dwarf, off, v4type);
84 7091 : if (*next_cu == NULL)
85 : return -1;
86 :
87 7085 : Dwarf_CU *next = (*next_cu);
88 :
89 7085 : if (version != NULL)
90 2053 : *version = next->version;
91 :
92 7085 : if (unit_type != NULL)
93 4727 : *unit_type = next->unit_type;
94 :
95 7085 : if (cudie != NULL)
96 : {
97 3853 : if (next->version >= 2 && next->version <= 5
98 3853 : && next->unit_type >= DW_UT_compile
99 3853 : && next->unit_type <= DW_UT_split_type)
100 7706 : *cudie = CUDIE (next);
101 : else
102 : memset (cudie, '\0', sizeof (Dwarf_Die));
103 : }
104 :
105 7085 : if (subdie != NULL)
106 : {
107 3561 : 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 7122 : if (next->unit_type == DW_UT_type
113 3561 : || next->unit_type == DW_UT_split_type)
114 8 : *subdie = SUBDIE(next);
115 3553 : else if (next->unit_type == DW_UT_skeleton)
116 : {
117 20 : Dwarf_CU *split_cu = __libdw_find_split_unit (next);
118 20 : if (split_cu != NULL)
119 40 : *subdie = CUDIE(split_cu);
120 : else
121 : memset (subdie, '\0', sizeof (Dwarf_Die));
122 : }
123 : else
124 : memset (subdie, '\0', sizeof (Dwarf_Die));
125 : }
126 : else
127 : memset (subdie, '\0', sizeof (Dwarf_Die));
128 : }
129 :
130 : return 0;
131 : }
|