1*7304104dSAndroid Build Coastguard Worker /* Iterate through the CU units for a given Dwarf.
2*7304104dSAndroid Build Coastguard Worker Copyright (C) 2016, 2017 Red Hat, Inc.
3*7304104dSAndroid Build Coastguard Worker This file is part of elfutils.
4*7304104dSAndroid Build Coastguard Worker
5*7304104dSAndroid Build Coastguard Worker This file is free software; you can redistribute it and/or modify
6*7304104dSAndroid Build Coastguard Worker it under the terms of either
7*7304104dSAndroid Build Coastguard Worker
8*7304104dSAndroid Build Coastguard Worker * the GNU Lesser General Public License as published by the Free
9*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 3 of the License, or (at
10*7304104dSAndroid Build Coastguard Worker your option) any later version
11*7304104dSAndroid Build Coastguard Worker
12*7304104dSAndroid Build Coastguard Worker or
13*7304104dSAndroid Build Coastguard Worker
14*7304104dSAndroid Build Coastguard Worker * the GNU General Public License as published by the Free
15*7304104dSAndroid Build Coastguard Worker Software Foundation; either version 2 of the License, or (at
16*7304104dSAndroid Build Coastguard Worker your option) any later version
17*7304104dSAndroid Build Coastguard Worker
18*7304104dSAndroid Build Coastguard Worker or both in parallel, as here.
19*7304104dSAndroid Build Coastguard Worker
20*7304104dSAndroid Build Coastguard Worker elfutils is distributed in the hope that it will be useful, but
21*7304104dSAndroid Build Coastguard Worker WITHOUT ANY WARRANTY; without even the implied warranty of
22*7304104dSAndroid Build Coastguard Worker MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23*7304104dSAndroid Build Coastguard Worker General Public License for more details.
24*7304104dSAndroid Build Coastguard Worker
25*7304104dSAndroid Build Coastguard Worker You should have received copies of the GNU General Public License and
26*7304104dSAndroid Build Coastguard Worker the GNU Lesser General Public License along with this program. If
27*7304104dSAndroid Build Coastguard Worker not, see <http://www.gnu.org/licenses/>. */
28*7304104dSAndroid Build Coastguard Worker
29*7304104dSAndroid Build Coastguard Worker
30*7304104dSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
31*7304104dSAndroid Build Coastguard Worker # include <config.h>
32*7304104dSAndroid Build Coastguard Worker #endif
33*7304104dSAndroid Build Coastguard Worker
34*7304104dSAndroid Build Coastguard Worker #include <string.h>
35*7304104dSAndroid Build Coastguard Worker
36*7304104dSAndroid Build Coastguard Worker #include "libdwP.h"
37*7304104dSAndroid Build Coastguard Worker
38*7304104dSAndroid Build Coastguard Worker int
dwarf_get_units(Dwarf * dwarf,Dwarf_CU * cu,Dwarf_CU ** next_cu,Dwarf_Half * version,uint8_t * unit_type,Dwarf_Die * cudie,Dwarf_Die * subdie)39*7304104dSAndroid Build Coastguard Worker dwarf_get_units (Dwarf *dwarf, Dwarf_CU *cu, Dwarf_CU **next_cu,
40*7304104dSAndroid Build Coastguard Worker Dwarf_Half *version, uint8_t *unit_type,
41*7304104dSAndroid Build Coastguard Worker Dwarf_Die *cudie, Dwarf_Die *subdie)
42*7304104dSAndroid Build Coastguard Worker {
43*7304104dSAndroid Build Coastguard Worker /* Handle existing error. */
44*7304104dSAndroid Build Coastguard Worker if (dwarf == NULL)
45*7304104dSAndroid Build Coastguard Worker return -1;
46*7304104dSAndroid Build Coastguard Worker
47*7304104dSAndroid Build Coastguard Worker Dwarf_Off off;
48*7304104dSAndroid Build Coastguard Worker bool v4type;
49*7304104dSAndroid Build Coastguard Worker if (cu == NULL)
50*7304104dSAndroid Build Coastguard Worker {
51*7304104dSAndroid Build Coastguard Worker off = 0;
52*7304104dSAndroid Build Coastguard Worker v4type = false;
53*7304104dSAndroid Build Coastguard Worker }
54*7304104dSAndroid Build Coastguard Worker else
55*7304104dSAndroid Build Coastguard Worker {
56*7304104dSAndroid Build Coastguard Worker off = cu->end;
57*7304104dSAndroid Build Coastguard Worker v4type = cu->sec_idx != IDX_debug_info;
58*7304104dSAndroid Build Coastguard Worker
59*7304104dSAndroid Build Coastguard Worker /* Make sure we got a real (not fake) CU. */
60*7304104dSAndroid Build Coastguard Worker if (cu->sec_idx != IDX_debug_info && cu->sec_idx != IDX_debug_types)
61*7304104dSAndroid Build Coastguard Worker {
62*7304104dSAndroid Build Coastguard Worker __libdw_seterrno (DWARF_E_INVALID_OFFSET);
63*7304104dSAndroid Build Coastguard Worker return -1;
64*7304104dSAndroid Build Coastguard Worker }
65*7304104dSAndroid Build Coastguard Worker
66*7304104dSAndroid Build Coastguard Worker /* Do we have to switch to the other section, or are we at the end? */
67*7304104dSAndroid Build Coastguard Worker if (! v4type)
68*7304104dSAndroid Build Coastguard Worker {
69*7304104dSAndroid Build Coastguard Worker if (off >= cu->dbg->sectiondata[IDX_debug_info]->d_size)
70*7304104dSAndroid Build Coastguard Worker {
71*7304104dSAndroid Build Coastguard Worker if (cu->dbg->sectiondata[IDX_debug_types] == NULL)
72*7304104dSAndroid Build Coastguard Worker return 1;
73*7304104dSAndroid Build Coastguard Worker
74*7304104dSAndroid Build Coastguard Worker off = 0;
75*7304104dSAndroid Build Coastguard Worker v4type = true;
76*7304104dSAndroid Build Coastguard Worker }
77*7304104dSAndroid Build Coastguard Worker }
78*7304104dSAndroid Build Coastguard Worker else
79*7304104dSAndroid Build Coastguard Worker if (off >= cu->dbg->sectiondata[IDX_debug_types]->d_size)
80*7304104dSAndroid Build Coastguard Worker return 1;
81*7304104dSAndroid Build Coastguard Worker }
82*7304104dSAndroid Build Coastguard Worker
83*7304104dSAndroid Build Coastguard Worker *next_cu = __libdw_findcu (dwarf, off, v4type);
84*7304104dSAndroid Build Coastguard Worker if (*next_cu == NULL)
85*7304104dSAndroid Build Coastguard Worker return -1;
86*7304104dSAndroid Build Coastguard Worker
87*7304104dSAndroid Build Coastguard Worker Dwarf_CU *next = (*next_cu);
88*7304104dSAndroid Build Coastguard Worker
89*7304104dSAndroid Build Coastguard Worker if (version != NULL)
90*7304104dSAndroid Build Coastguard Worker *version = next->version;
91*7304104dSAndroid Build Coastguard Worker
92*7304104dSAndroid Build Coastguard Worker if (unit_type != NULL)
93*7304104dSAndroid Build Coastguard Worker *unit_type = next->unit_type;
94*7304104dSAndroid Build Coastguard Worker
95*7304104dSAndroid Build Coastguard Worker if (cudie != NULL)
96*7304104dSAndroid Build Coastguard Worker {
97*7304104dSAndroid Build Coastguard Worker if (next->version >= 2 && next->version <= 5
98*7304104dSAndroid Build Coastguard Worker && next->unit_type >= DW_UT_compile
99*7304104dSAndroid Build Coastguard Worker && next->unit_type <= DW_UT_split_type)
100*7304104dSAndroid Build Coastguard Worker *cudie = CUDIE (next);
101*7304104dSAndroid Build Coastguard Worker else
102*7304104dSAndroid Build Coastguard Worker memset (cudie, '\0', sizeof (Dwarf_Die));
103*7304104dSAndroid Build Coastguard Worker }
104*7304104dSAndroid Build Coastguard Worker
105*7304104dSAndroid Build Coastguard Worker if (subdie != NULL)
106*7304104dSAndroid Build Coastguard Worker {
107*7304104dSAndroid Build Coastguard Worker if (next->version >= 2 && next->version <= 5)
108*7304104dSAndroid Build Coastguard Worker {
109*7304104dSAndroid Build Coastguard Worker /* For types, return the actual type DIE. For skeletons,
110*7304104dSAndroid Build Coastguard Worker find the associated split compile unit and return its
111*7304104dSAndroid Build Coastguard Worker DIE. */
112*7304104dSAndroid Build Coastguard Worker if (next->unit_type == DW_UT_type
113*7304104dSAndroid Build Coastguard Worker || next->unit_type == DW_UT_split_type)
114*7304104dSAndroid Build Coastguard Worker *subdie = SUBDIE(next);
115*7304104dSAndroid Build Coastguard Worker else if (next->unit_type == DW_UT_skeleton)
116*7304104dSAndroid Build Coastguard Worker {
117*7304104dSAndroid Build Coastguard Worker Dwarf_CU *split_cu = __libdw_find_split_unit (next);
118*7304104dSAndroid Build Coastguard Worker if (split_cu != NULL)
119*7304104dSAndroid Build Coastguard Worker *subdie = CUDIE(split_cu);
120*7304104dSAndroid Build Coastguard Worker else
121*7304104dSAndroid Build Coastguard Worker memset (subdie, '\0', sizeof (Dwarf_Die));
122*7304104dSAndroid Build Coastguard Worker }
123*7304104dSAndroid Build Coastguard Worker else
124*7304104dSAndroid Build Coastguard Worker memset (subdie, '\0', sizeof (Dwarf_Die));
125*7304104dSAndroid Build Coastguard Worker }
126*7304104dSAndroid Build Coastguard Worker else
127*7304104dSAndroid Build Coastguard Worker memset (subdie, '\0', sizeof (Dwarf_Die));
128*7304104dSAndroid Build Coastguard Worker }
129*7304104dSAndroid Build Coastguard Worker
130*7304104dSAndroid Build Coastguard Worker return 0;
131*7304104dSAndroid Build Coastguard Worker }
132*7304104dSAndroid Build Coastguard Worker INTDEF(dwarf_get_units)
133