xref: /aosp_15_r20/external/elfutils/libdw/dwarf_get_units.c (revision 7304104da70ce23c86437a01be71edd1a2d7f37e)
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