1 /* Compute size of an aggregate type from DWARF.
2 Copyright (C) 2010 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
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
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
18 or both in parallel, as here.
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.
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/>. */
38 get_type (Dwarf_Die *die, Dwarf_Attribute *attr_mem, Dwarf_Die *type_mem)
40 return INTUSE(dwarf_formref_die)
41 (INTUSE(dwarf_attr_integrate) (die, DW_AT_type, attr_mem), type_mem);
45 array_size (Dwarf_Die *die, Dwarf_Word *size,
46 Dwarf_Attribute *attr_mem, Dwarf_Die *type_mem)
49 if (INTUSE(dwarf_aggregate_size) (get_type (die, attr_mem, type_mem),
53 /* An array can have DW_TAG_subrange_type or DW_TAG_enumeration_type
54 children instead that give the size of each dimension. */
57 if (INTUSE(dwarf_child) (die, &child) != 0)
65 switch (INTUSE(dwarf_tag) (&child))
67 case DW_TAG_subrange_type:
68 /* This has either DW_AT_count or DW_AT_upper_bound. */
69 if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_count,
72 if (INTUSE(dwarf_formudata) (attr_mem, &count) != 0)
79 if (INTUSE(dwarf_formsdata) (INTUSE(dwarf_attr_integrate)
80 (&child, DW_AT_upper_bound,
81 attr_mem), &upper) != 0)
84 /* Having DW_AT_lower_bound is optional. */
85 if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_lower_bound,
88 if (INTUSE(dwarf_formsdata) (attr_mem, &lower) != 0)
93 /* Determine default lower bound from language,
94 as per "4.12 Subrange Type Entries". */
95 Dwarf_Die cu = CUDIE (die->cu);
96 switch (INTUSE(dwarf_srclang) (&cu))
101 case DW_LANG_C_plus_plus:
103 case DW_LANG_ObjC_plus_plus:
112 case DW_LANG_Cobol74:
113 case DW_LANG_Cobol85:
114 case DW_LANG_Fortran77:
115 case DW_LANG_Fortran90:
116 case DW_LANG_Fortran95:
117 case DW_LANG_Pascal83:
118 case DW_LANG_Modula2:
127 if (unlikely (lower > upper))
129 count = upper - lower + 1;
133 case DW_TAG_enumeration_type:
134 /* We have to find the DW_TAG_enumerator child with the
135 highest value to know the array's element count. */
137 Dwarf_Die enum_child;
138 int has_children = INTUSE(dwarf_child) (die, &enum_child);
139 if (has_children < 0)
141 if (has_children > 0)
143 if (INTUSE(dwarf_tag) (&enum_child) == DW_TAG_enumerator)
146 if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate)
147 (&enum_child, DW_AT_const_value,
148 attr_mem), &value) != 0)
153 while (INTUSE(dwarf_siblingof) (&enum_child, &enum_child) > 0);
160 /* This is a subrange_type or enumeration_type and we've set COUNT.
161 Now determine the stride for this array dimension. */
162 Dwarf_Word stride = eltsize;
163 if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_byte_stride,
166 if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
169 else if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_bit_stride,
172 if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
174 if (stride % 8) /* XXX maybe compute in bits? */
180 total += stride * count;
182 while (INTUSE(dwarf_siblingof) (&child, &child) == 0);
192 aggregate_size (Dwarf_Die *die, Dwarf_Word *size, Dwarf_Die *type_mem)
194 Dwarf_Attribute attr_mem;
196 if (INTUSE(dwarf_attr_integrate) (die, DW_AT_byte_size, &attr_mem) != NULL)
197 return INTUSE(dwarf_formudata) (&attr_mem, size);
199 switch (INTUSE(dwarf_tag) (die))
202 case DW_TAG_subrange_type:
203 return aggregate_size (get_type (die, &attr_mem, type_mem),
204 size, type_mem); /* Tail call. */
206 case DW_TAG_array_type:
207 return array_size (die, size, &attr_mem, type_mem);
210 /* Most types must give their size directly. */
215 dwarf_aggregate_size (die, size)
220 return aggregate_size (die, size, &type_mem);
222 INTDEF (dwarf_aggregate_size)