xref: /titanic_52/usr/src/lib/libdwarf/common/dwarf_query.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi 
3*7fd79137SRobert Mustacchi   Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
4*7fd79137SRobert Mustacchi   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5*7fd79137SRobert Mustacchi 
6*7fd79137SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7*7fd79137SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8*7fd79137SRobert Mustacchi   as published by the Free Software Foundation.
9*7fd79137SRobert Mustacchi 
10*7fd79137SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11*7fd79137SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12*7fd79137SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*7fd79137SRobert Mustacchi 
14*7fd79137SRobert Mustacchi   Further, this software is distributed without any warranty that it is
15*7fd79137SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16*7fd79137SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17*7fd79137SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18*7fd79137SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19*7fd79137SRobert Mustacchi   other software, or any other product whatsoever.
20*7fd79137SRobert Mustacchi 
21*7fd79137SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22*7fd79137SRobert Mustacchi   License along with this program; if not, write the Free Software
23*7fd79137SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*7fd79137SRobert Mustacchi   USA.
25*7fd79137SRobert Mustacchi 
26*7fd79137SRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
27*7fd79137SRobert Mustacchi   Mountain View, CA 94043, or:
28*7fd79137SRobert Mustacchi 
29*7fd79137SRobert Mustacchi   http://www.sgi.com
30*7fd79137SRobert Mustacchi 
31*7fd79137SRobert Mustacchi   For further information regarding this notice, see:
32*7fd79137SRobert Mustacchi 
33*7fd79137SRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*7fd79137SRobert Mustacchi 
35*7fd79137SRobert Mustacchi */
36*7fd79137SRobert Mustacchi /* The address of the Free Software Foundation is
37*7fd79137SRobert Mustacchi    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*7fd79137SRobert Mustacchi    Boston, MA 02110-1301, USA.
39*7fd79137SRobert Mustacchi    SGI has moved from the Crittenden Lane address.
40*7fd79137SRobert Mustacchi */
41*7fd79137SRobert Mustacchi 
42*7fd79137SRobert Mustacchi 
43*7fd79137SRobert Mustacchi 
44*7fd79137SRobert Mustacchi 
45*7fd79137SRobert Mustacchi #include "config.h"
46*7fd79137SRobert Mustacchi #include "dwarf_incl.h"
47*7fd79137SRobert Mustacchi #include <stdio.h>
48*7fd79137SRobert Mustacchi #include "dwarf_die_deliv.h"
49*7fd79137SRobert Mustacchi 
50*7fd79137SRobert Mustacchi /* This is normally reliable.
51*7fd79137SRobert Mustacchi But not always.
52*7fd79137SRobert Mustacchi If different compilation
53*7fd79137SRobert Mustacchi units have different address sizes
54*7fd79137SRobert Mustacchi this may not give the correct value in all contexts.
55*7fd79137SRobert Mustacchi If the Elf offset size != address_size
56*7fd79137SRobert Mustacchi (for example if address_size = 4 but recorded in elf64 object)
57*7fd79137SRobert Mustacchi this may not give the correct value in all contexts.
58*7fd79137SRobert Mustacchi */
59*7fd79137SRobert Mustacchi int
60*7fd79137SRobert Mustacchi dwarf_get_address_size(Dwarf_Debug dbg,
61*7fd79137SRobert Mustacchi     Dwarf_Half * ret_addr_size, Dwarf_Error * error)
62*7fd79137SRobert Mustacchi {
63*7fd79137SRobert Mustacchi     Dwarf_Half address_size = 0;
64*7fd79137SRobert Mustacchi 
65*7fd79137SRobert Mustacchi     if (dbg == 0) {
66*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
67*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
68*7fd79137SRobert Mustacchi     }
69*7fd79137SRobert Mustacchi     address_size = dbg->de_pointer_size;
70*7fd79137SRobert Mustacchi     *ret_addr_size = address_size;
71*7fd79137SRobert Mustacchi     return DW_DLV_OK;
72*7fd79137SRobert Mustacchi }
73*7fd79137SRobert Mustacchi 
74*7fd79137SRobert Mustacchi /* This will be correct in all contexts where the
75*7fd79137SRobert Mustacchi    CU context of a DIE is known.
76*7fd79137SRobert Mustacchi */
77*7fd79137SRobert Mustacchi int
78*7fd79137SRobert Mustacchi dwarf_get_die_address_size(Dwarf_Die die,
79*7fd79137SRobert Mustacchi     Dwarf_Half * ret_addr_size, Dwarf_Error * error)
80*7fd79137SRobert Mustacchi {
81*7fd79137SRobert Mustacchi     Dwarf_Half address_size = 0;
82*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
83*7fd79137SRobert Mustacchi     address_size = die->di_cu_context->cc_address_size;
84*7fd79137SRobert Mustacchi     *ret_addr_size = address_size;
85*7fd79137SRobert Mustacchi     return DW_DLV_OK;
86*7fd79137SRobert Mustacchi }
87*7fd79137SRobert Mustacchi 
88*7fd79137SRobert Mustacchi int
89*7fd79137SRobert Mustacchi dwarf_dieoffset(Dwarf_Die die,
90*7fd79137SRobert Mustacchi     Dwarf_Off * ret_offset, Dwarf_Error * error)
91*7fd79137SRobert Mustacchi {
92*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
93*7fd79137SRobert Mustacchi 
94*7fd79137SRobert Mustacchi     *ret_offset = (die->di_debug_info_ptr -
95*7fd79137SRobert Mustacchi         die->di_cu_context->cc_dbg->de_debug_info.dss_data);
96*7fd79137SRobert Mustacchi     return DW_DLV_OK;
97*7fd79137SRobert Mustacchi }
98*7fd79137SRobert Mustacchi 
99*7fd79137SRobert Mustacchi 
100*7fd79137SRobert Mustacchi /*
101*7fd79137SRobert Mustacchi     This function returns the offset of
102*7fd79137SRobert Mustacchi     the die relative to the start of its
103*7fd79137SRobert Mustacchi     compilation-unit rather than .debug_info.
104*7fd79137SRobert Mustacchi     Returns DW_DLV_ERROR on error.
105*7fd79137SRobert Mustacchi */
106*7fd79137SRobert Mustacchi int
107*7fd79137SRobert Mustacchi dwarf_die_CU_offset(Dwarf_Die die,
108*7fd79137SRobert Mustacchi     Dwarf_Off * cu_off, Dwarf_Error * error)
109*7fd79137SRobert Mustacchi {
110*7fd79137SRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
111*7fd79137SRobert Mustacchi 
112*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
113*7fd79137SRobert Mustacchi     cu_context = die->di_cu_context;
114*7fd79137SRobert Mustacchi 
115*7fd79137SRobert Mustacchi     *cu_off =
116*7fd79137SRobert Mustacchi         (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info.dss_data -
117*7fd79137SRobert Mustacchi          cu_context->cc_debug_info_offset);
118*7fd79137SRobert Mustacchi     return DW_DLV_OK;
119*7fd79137SRobert Mustacchi }
120*7fd79137SRobert Mustacchi 
121*7fd79137SRobert Mustacchi /*
122*7fd79137SRobert Mustacchi     This function returns the global offset
123*7fd79137SRobert Mustacchi     (meaning the section offset) and length of
124*7fd79137SRobert Mustacchi     the CU that this die is a part of.
125*7fd79137SRobert Mustacchi     Used for correctness checking by dwarfdump.
126*7fd79137SRobert Mustacchi */
127*7fd79137SRobert Mustacchi int
128*7fd79137SRobert Mustacchi dwarf_die_CU_offset_range(Dwarf_Die die,
129*7fd79137SRobert Mustacchi      Dwarf_Off * cu_off,
130*7fd79137SRobert Mustacchi      Dwarf_Off * cu_length,
131*7fd79137SRobert Mustacchi      Dwarf_Error * error)
132*7fd79137SRobert Mustacchi {
133*7fd79137SRobert Mustacchi     Dwarf_CU_Context cu_context = 0;
134*7fd79137SRobert Mustacchi 
135*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
136*7fd79137SRobert Mustacchi     cu_context = die->di_cu_context;
137*7fd79137SRobert Mustacchi 
138*7fd79137SRobert Mustacchi     *cu_off = cu_context->cc_debug_info_offset;
139*7fd79137SRobert Mustacchi     *cu_length = cu_context->cc_length + cu_context->cc_length_size
140*7fd79137SRobert Mustacchi             + cu_context->cc_extension_size;
141*7fd79137SRobert Mustacchi     return DW_DLV_OK;
142*7fd79137SRobert Mustacchi }
143*7fd79137SRobert Mustacchi 
144*7fd79137SRobert Mustacchi 
145*7fd79137SRobert Mustacchi 
146*7fd79137SRobert Mustacchi int
147*7fd79137SRobert Mustacchi dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
148*7fd79137SRobert Mustacchi {
149*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
150*7fd79137SRobert Mustacchi     *tag = (die->di_abbrev_list->ab_tag);
151*7fd79137SRobert Mustacchi     return DW_DLV_OK;
152*7fd79137SRobert Mustacchi }
153*7fd79137SRobert Mustacchi 
154*7fd79137SRobert Mustacchi 
155*7fd79137SRobert Mustacchi int
156*7fd79137SRobert Mustacchi dwarf_attrlist(Dwarf_Die die,
157*7fd79137SRobert Mustacchi     Dwarf_Attribute ** attrbuf,
158*7fd79137SRobert Mustacchi     Dwarf_Signed * attrcnt, Dwarf_Error * error)
159*7fd79137SRobert Mustacchi {
160*7fd79137SRobert Mustacchi     Dwarf_Word attr_count = 0;
161*7fd79137SRobert Mustacchi     Dwarf_Word i = 0;
162*7fd79137SRobert Mustacchi     Dwarf_Half attr = 0;
163*7fd79137SRobert Mustacchi     Dwarf_Half attr_form = 0;
164*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr abbrev_ptr = 0;
165*7fd79137SRobert Mustacchi     Dwarf_Abbrev_List abbrev_list = 0;
166*7fd79137SRobert Mustacchi     Dwarf_Attribute new_attr = 0;
167*7fd79137SRobert Mustacchi     Dwarf_Attribute head_attr = NULL;
168*7fd79137SRobert Mustacchi     Dwarf_Attribute curr_attr = NULL;
169*7fd79137SRobert Mustacchi     Dwarf_Attribute *attr_ptr = 0;
170*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
171*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr info_ptr = 0;
172*7fd79137SRobert Mustacchi 
173*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
174*7fd79137SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
175*7fd79137SRobert Mustacchi 
176*7fd79137SRobert Mustacchi     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
177*7fd79137SRobert Mustacchi                                              die->di_abbrev_list->
178*7fd79137SRobert Mustacchi                                              ab_code);
179*7fd79137SRobert Mustacchi     if (abbrev_list == NULL) {
180*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD);
181*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
182*7fd79137SRobert Mustacchi     }
183*7fd79137SRobert Mustacchi     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
184*7fd79137SRobert Mustacchi 
185*7fd79137SRobert Mustacchi     info_ptr = die->di_debug_info_ptr;
186*7fd79137SRobert Mustacchi     SKIP_LEB128_WORD(info_ptr);
187*7fd79137SRobert Mustacchi 
188*7fd79137SRobert Mustacchi     do {
189*7fd79137SRobert Mustacchi         Dwarf_Unsigned utmp2;
190*7fd79137SRobert Mustacchi 
191*7fd79137SRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
192*7fd79137SRobert Mustacchi         attr = (Dwarf_Half) utmp2;
193*7fd79137SRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
194*7fd79137SRobert Mustacchi         attr_form = (Dwarf_Half) utmp2;
195*7fd79137SRobert Mustacchi 
196*7fd79137SRobert Mustacchi         if (attr != 0) {
197*7fd79137SRobert Mustacchi             new_attr =
198*7fd79137SRobert Mustacchi                 (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
199*7fd79137SRobert Mustacchi             if (new_attr == NULL) {
200*7fd79137SRobert Mustacchi                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
201*7fd79137SRobert Mustacchi                 return (DW_DLV_ERROR);
202*7fd79137SRobert Mustacchi             }
203*7fd79137SRobert Mustacchi 
204*7fd79137SRobert Mustacchi             new_attr->ar_attribute = attr;
205*7fd79137SRobert Mustacchi             new_attr->ar_attribute_form_direct = attr_form;
206*7fd79137SRobert Mustacchi             new_attr->ar_attribute_form = attr_form;
207*7fd79137SRobert Mustacchi             if (attr_form == DW_FORM_indirect) {
208*7fd79137SRobert Mustacchi                 Dwarf_Unsigned utmp6;
209*7fd79137SRobert Mustacchi 
210*7fd79137SRobert Mustacchi                 /* DECODE_LEB128_UWORD does info_ptr update */
211*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(info_ptr, utmp6);
212*7fd79137SRobert Mustacchi                 attr_form = (Dwarf_Half) utmp6;
213*7fd79137SRobert Mustacchi                 new_attr->ar_attribute_form = attr_form;
214*7fd79137SRobert Mustacchi             }
215*7fd79137SRobert Mustacchi             new_attr->ar_cu_context = die->di_cu_context;
216*7fd79137SRobert Mustacchi             new_attr->ar_debug_info_ptr = info_ptr;
217*7fd79137SRobert Mustacchi 
218*7fd79137SRobert Mustacchi             {
219*7fd79137SRobert Mustacchi                 Dwarf_Unsigned sov = _dwarf_get_size_of_val(dbg,
220*7fd79137SRobert Mustacchi                     attr_form,
221*7fd79137SRobert Mustacchi                     die->di_cu_context->cc_address_size,
222*7fd79137SRobert Mustacchi                     info_ptr,
223*7fd79137SRobert Mustacchi                     die->di_cu_context->cc_length_size);
224*7fd79137SRobert Mustacchi                 info_ptr += sov;
225*7fd79137SRobert Mustacchi             }
226*7fd79137SRobert Mustacchi 
227*7fd79137SRobert Mustacchi 
228*7fd79137SRobert Mustacchi             if (head_attr == NULL)
229*7fd79137SRobert Mustacchi                 head_attr = curr_attr = new_attr;
230*7fd79137SRobert Mustacchi             else {
231*7fd79137SRobert Mustacchi                 curr_attr->ar_next = new_attr;
232*7fd79137SRobert Mustacchi                 curr_attr = new_attr;
233*7fd79137SRobert Mustacchi             }
234*7fd79137SRobert Mustacchi             attr_count++;
235*7fd79137SRobert Mustacchi         }
236*7fd79137SRobert Mustacchi     } while (attr != 0 || attr_form != 0);
237*7fd79137SRobert Mustacchi 
238*7fd79137SRobert Mustacchi     if (attr_count == 0) {
239*7fd79137SRobert Mustacchi         *attrbuf = NULL;
240*7fd79137SRobert Mustacchi         *attrcnt = 0;
241*7fd79137SRobert Mustacchi         return (DW_DLV_NO_ENTRY);
242*7fd79137SRobert Mustacchi     }
243*7fd79137SRobert Mustacchi 
244*7fd79137SRobert Mustacchi     attr_ptr = (Dwarf_Attribute *)
245*7fd79137SRobert Mustacchi         _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
246*7fd79137SRobert Mustacchi     if (attr_ptr == NULL) {
247*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
248*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
249*7fd79137SRobert Mustacchi     }
250*7fd79137SRobert Mustacchi 
251*7fd79137SRobert Mustacchi     curr_attr = head_attr;
252*7fd79137SRobert Mustacchi     for (i = 0; i < attr_count; i++) {
253*7fd79137SRobert Mustacchi         *(attr_ptr + i) = curr_attr;
254*7fd79137SRobert Mustacchi         curr_attr = curr_attr->ar_next;
255*7fd79137SRobert Mustacchi     }
256*7fd79137SRobert Mustacchi 
257*7fd79137SRobert Mustacchi     *attrbuf = attr_ptr;
258*7fd79137SRobert Mustacchi     *attrcnt = attr_count;
259*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
260*7fd79137SRobert Mustacchi }
261*7fd79137SRobert Mustacchi 
262*7fd79137SRobert Mustacchi 
263*7fd79137SRobert Mustacchi /*
264*7fd79137SRobert Mustacchi     This function takes a die, and an attr, and returns
265*7fd79137SRobert Mustacchi     a pointer to the start of the value of that attr in
266*7fd79137SRobert Mustacchi     the given die in the .debug_info section.  The form
267*7fd79137SRobert Mustacchi     is returned in *attr_form.
268*7fd79137SRobert Mustacchi 
269*7fd79137SRobert Mustacchi     Returns NULL on error, or if attr is not found.
270*7fd79137SRobert Mustacchi     However, *attr_form is 0 on error, and positive
271*7fd79137SRobert Mustacchi     otherwise.
272*7fd79137SRobert Mustacchi */
273*7fd79137SRobert Mustacchi static Dwarf_Byte_Ptr
274*7fd79137SRobert Mustacchi _dwarf_get_value_ptr(Dwarf_Die die,
275*7fd79137SRobert Mustacchi     Dwarf_Half attr, Dwarf_Half * attr_form)
276*7fd79137SRobert Mustacchi {
277*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr abbrev_ptr = 0;
278*7fd79137SRobert Mustacchi     Dwarf_Abbrev_List abbrev_list;
279*7fd79137SRobert Mustacchi     Dwarf_Half curr_attr = 0;
280*7fd79137SRobert Mustacchi     Dwarf_Half curr_attr_form = 0;
281*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr info_ptr = 0;
282*7fd79137SRobert Mustacchi 
283*7fd79137SRobert Mustacchi     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
284*7fd79137SRobert Mustacchi         die->di_abbrev_list->ab_code);
285*7fd79137SRobert Mustacchi     if (abbrev_list == NULL) {
286*7fd79137SRobert Mustacchi         *attr_form = 0;
287*7fd79137SRobert Mustacchi         return (NULL);
288*7fd79137SRobert Mustacchi     }
289*7fd79137SRobert Mustacchi     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
290*7fd79137SRobert Mustacchi 
291*7fd79137SRobert Mustacchi     info_ptr = die->di_debug_info_ptr;
292*7fd79137SRobert Mustacchi     SKIP_LEB128_WORD(info_ptr);
293*7fd79137SRobert Mustacchi 
294*7fd79137SRobert Mustacchi     do {
295*7fd79137SRobert Mustacchi         Dwarf_Unsigned utmp3;
296*7fd79137SRobert Mustacchi 
297*7fd79137SRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
298*7fd79137SRobert Mustacchi         curr_attr = (Dwarf_Half) utmp3;
299*7fd79137SRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
300*7fd79137SRobert Mustacchi         curr_attr_form = (Dwarf_Half) utmp3;
301*7fd79137SRobert Mustacchi         if (curr_attr_form == DW_FORM_indirect) {
302*7fd79137SRobert Mustacchi             Dwarf_Unsigned utmp6;
303*7fd79137SRobert Mustacchi 
304*7fd79137SRobert Mustacchi             /* DECODE_LEB128_UWORD updates info_ptr */
305*7fd79137SRobert Mustacchi             DECODE_LEB128_UWORD(info_ptr, utmp6);
306*7fd79137SRobert Mustacchi             curr_attr_form = (Dwarf_Half) utmp6;
307*7fd79137SRobert Mustacchi         }
308*7fd79137SRobert Mustacchi 
309*7fd79137SRobert Mustacchi         if (curr_attr == attr) {
310*7fd79137SRobert Mustacchi             *attr_form = curr_attr_form;
311*7fd79137SRobert Mustacchi             return (info_ptr);
312*7fd79137SRobert Mustacchi         }
313*7fd79137SRobert Mustacchi 
314*7fd79137SRobert Mustacchi         info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg,
315*7fd79137SRobert Mustacchi                          curr_attr_form,
316*7fd79137SRobert Mustacchi                          die->di_cu_context->cc_address_size,
317*7fd79137SRobert Mustacchi                          info_ptr,
318*7fd79137SRobert Mustacchi                          die->di_cu_context->cc_length_size);
319*7fd79137SRobert Mustacchi     } while (curr_attr != 0 || curr_attr_form != 0);
320*7fd79137SRobert Mustacchi 
321*7fd79137SRobert Mustacchi     *attr_form = 1;
322*7fd79137SRobert Mustacchi     return (NULL);
323*7fd79137SRobert Mustacchi }
324*7fd79137SRobert Mustacchi 
325*7fd79137SRobert Mustacchi 
326*7fd79137SRobert Mustacchi int
327*7fd79137SRobert Mustacchi dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error)
328*7fd79137SRobert Mustacchi {
329*7fd79137SRobert Mustacchi     Dwarf_Half attr_form = 0;
330*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
331*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr info_ptr = 0;
332*7fd79137SRobert Mustacchi     Dwarf_Unsigned string_offset = 0;
333*7fd79137SRobert Mustacchi     int res = DW_DLV_ERROR;
334*7fd79137SRobert Mustacchi 
335*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
336*7fd79137SRobert Mustacchi 
337*7fd79137SRobert Mustacchi     info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form);
338*7fd79137SRobert Mustacchi     if (info_ptr == NULL) {
339*7fd79137SRobert Mustacchi         if (attr_form == 0) {
340*7fd79137SRobert Mustacchi             _dwarf_error(die->di_cu_context->cc_dbg, error,
341*7fd79137SRobert Mustacchi                          DW_DLE_DIE_BAD);
342*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
343*7fd79137SRobert Mustacchi         }
344*7fd79137SRobert Mustacchi         return DW_DLV_NO_ENTRY;
345*7fd79137SRobert Mustacchi     }
346*7fd79137SRobert Mustacchi 
347*7fd79137SRobert Mustacchi     if (attr_form == DW_FORM_string) {
348*7fd79137SRobert Mustacchi         *ret_name = (char *) (info_ptr);
349*7fd79137SRobert Mustacchi         return DW_DLV_OK;
350*7fd79137SRobert Mustacchi     }
351*7fd79137SRobert Mustacchi 
352*7fd79137SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
353*7fd79137SRobert Mustacchi     if (attr_form != DW_FORM_strp) {
354*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
355*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
356*7fd79137SRobert Mustacchi     }
357*7fd79137SRobert Mustacchi 
358*7fd79137SRobert Mustacchi     READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned,
359*7fd79137SRobert Mustacchi         info_ptr, die->di_cu_context->cc_length_size);
360*7fd79137SRobert Mustacchi 
361*7fd79137SRobert Mustacchi     if (string_offset >= dbg->de_debug_str.dss_size) {
362*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD);
363*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
364*7fd79137SRobert Mustacchi     }
365*7fd79137SRobert Mustacchi 
366*7fd79137SRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
367*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
368*7fd79137SRobert Mustacchi         return res;
369*7fd79137SRobert Mustacchi     }
370*7fd79137SRobert Mustacchi 
371*7fd79137SRobert Mustacchi     *ret_name = (char *) (dbg->de_debug_str.dss_data + string_offset);
372*7fd79137SRobert Mustacchi     return DW_DLV_OK;
373*7fd79137SRobert Mustacchi }
374*7fd79137SRobert Mustacchi 
375*7fd79137SRobert Mustacchi 
376*7fd79137SRobert Mustacchi int
377*7fd79137SRobert Mustacchi dwarf_hasattr(Dwarf_Die die,
378*7fd79137SRobert Mustacchi     Dwarf_Half attr,
379*7fd79137SRobert Mustacchi     Dwarf_Bool * return_bool, Dwarf_Error * error)
380*7fd79137SRobert Mustacchi {
381*7fd79137SRobert Mustacchi     Dwarf_Half attr_form = 0;
382*7fd79137SRobert Mustacchi 
383*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
384*7fd79137SRobert Mustacchi 
385*7fd79137SRobert Mustacchi     if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) {
386*7fd79137SRobert Mustacchi         if (attr_form == 0) {
387*7fd79137SRobert Mustacchi             _dwarf_error(die->di_cu_context->cc_dbg, error,
388*7fd79137SRobert Mustacchi                 DW_DLE_DIE_BAD);
389*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
390*7fd79137SRobert Mustacchi         }
391*7fd79137SRobert Mustacchi         *return_bool = false;
392*7fd79137SRobert Mustacchi         return DW_DLV_OK;
393*7fd79137SRobert Mustacchi     }
394*7fd79137SRobert Mustacchi 
395*7fd79137SRobert Mustacchi     *return_bool = (true);
396*7fd79137SRobert Mustacchi     return DW_DLV_OK;
397*7fd79137SRobert Mustacchi }
398*7fd79137SRobert Mustacchi 
399*7fd79137SRobert Mustacchi 
400*7fd79137SRobert Mustacchi int
401*7fd79137SRobert Mustacchi dwarf_attr(Dwarf_Die die,
402*7fd79137SRobert Mustacchi     Dwarf_Half attr,
403*7fd79137SRobert Mustacchi     Dwarf_Attribute * ret_attr, Dwarf_Error * error)
404*7fd79137SRobert Mustacchi {
405*7fd79137SRobert Mustacchi     Dwarf_Half attr_form = 0;
406*7fd79137SRobert Mustacchi     Dwarf_Attribute attrib = 0;
407*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr info_ptr = 0;
408*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
409*7fd79137SRobert Mustacchi 
410*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
411*7fd79137SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
412*7fd79137SRobert Mustacchi 
413*7fd79137SRobert Mustacchi     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
414*7fd79137SRobert Mustacchi     if (info_ptr == NULL) {
415*7fd79137SRobert Mustacchi         if (attr_form == 0) {
416*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
417*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
418*7fd79137SRobert Mustacchi         }
419*7fd79137SRobert Mustacchi         return DW_DLV_NO_ENTRY;
420*7fd79137SRobert Mustacchi     }
421*7fd79137SRobert Mustacchi 
422*7fd79137SRobert Mustacchi     attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
423*7fd79137SRobert Mustacchi     if (attrib == NULL) {
424*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
425*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
426*7fd79137SRobert Mustacchi     }
427*7fd79137SRobert Mustacchi 
428*7fd79137SRobert Mustacchi     attrib->ar_attribute = attr;
429*7fd79137SRobert Mustacchi     attrib->ar_attribute_form = attr_form;
430*7fd79137SRobert Mustacchi     attrib->ar_attribute_form_direct = attr_form;
431*7fd79137SRobert Mustacchi     attrib->ar_cu_context = die->di_cu_context;
432*7fd79137SRobert Mustacchi     attrib->ar_debug_info_ptr = info_ptr;
433*7fd79137SRobert Mustacchi     *ret_attr = (attrib);
434*7fd79137SRobert Mustacchi     return DW_DLV_OK;
435*7fd79137SRobert Mustacchi }
436*7fd79137SRobert Mustacchi 
437*7fd79137SRobert Mustacchi 
438*7fd79137SRobert Mustacchi int
439*7fd79137SRobert Mustacchi dwarf_lowpc(Dwarf_Die die,
440*7fd79137SRobert Mustacchi     Dwarf_Addr * return_addr, Dwarf_Error * error)
441*7fd79137SRobert Mustacchi {
442*7fd79137SRobert Mustacchi     Dwarf_Addr ret_addr = 0;
443*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr info_ptr = 0;
444*7fd79137SRobert Mustacchi     Dwarf_Half attr_form = 0;
445*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
446*7fd79137SRobert Mustacchi     Dwarf_Half address_size = 0;
447*7fd79137SRobert Mustacchi 
448*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
449*7fd79137SRobert Mustacchi 
450*7fd79137SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
451*7fd79137SRobert Mustacchi     address_size = die->di_cu_context->cc_address_size;
452*7fd79137SRobert Mustacchi     info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form);
453*7fd79137SRobert Mustacchi     if ((info_ptr == NULL && attr_form == 0) ||
454*7fd79137SRobert Mustacchi         (info_ptr != NULL && attr_form != DW_FORM_addr)) {
455*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
456*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
457*7fd79137SRobert Mustacchi     }
458*7fd79137SRobert Mustacchi     if (info_ptr == NULL) {
459*7fd79137SRobert Mustacchi         return (DW_DLV_NO_ENTRY);
460*7fd79137SRobert Mustacchi     }
461*7fd79137SRobert Mustacchi 
462*7fd79137SRobert Mustacchi 
463*7fd79137SRobert Mustacchi     READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
464*7fd79137SRobert Mustacchi                    info_ptr, address_size);
465*7fd79137SRobert Mustacchi 
466*7fd79137SRobert Mustacchi     *return_addr = ret_addr;
467*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
468*7fd79137SRobert Mustacchi }
469*7fd79137SRobert Mustacchi 
470*7fd79137SRobert Mustacchi 
471*7fd79137SRobert Mustacchi int
472*7fd79137SRobert Mustacchi dwarf_highpc(Dwarf_Die die,
473*7fd79137SRobert Mustacchi     Dwarf_Addr * return_addr, Dwarf_Error * error)
474*7fd79137SRobert Mustacchi {
475*7fd79137SRobert Mustacchi     Dwarf_Addr ret_addr = 0;
476*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr info_ptr = 0;
477*7fd79137SRobert Mustacchi     Dwarf_Half attr_form = 0;
478*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
479*7fd79137SRobert Mustacchi     Dwarf_Half address_size = 0;
480*7fd79137SRobert Mustacchi 
481*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
482*7fd79137SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
483*7fd79137SRobert Mustacchi     address_size = die->di_cu_context->cc_address_size;
484*7fd79137SRobert Mustacchi     info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form);
485*7fd79137SRobert Mustacchi     if ((info_ptr == NULL && attr_form == 0) ||
486*7fd79137SRobert Mustacchi         (info_ptr != NULL && attr_form != DW_FORM_addr)) {
487*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
488*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
489*7fd79137SRobert Mustacchi     }
490*7fd79137SRobert Mustacchi     if (info_ptr == NULL) {
491*7fd79137SRobert Mustacchi         return (DW_DLV_NO_ENTRY);
492*7fd79137SRobert Mustacchi     }
493*7fd79137SRobert Mustacchi 
494*7fd79137SRobert Mustacchi     READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
495*7fd79137SRobert Mustacchi                    info_ptr, address_size);
496*7fd79137SRobert Mustacchi 
497*7fd79137SRobert Mustacchi     *return_addr = ret_addr;
498*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
499*7fd79137SRobert Mustacchi }
500*7fd79137SRobert Mustacchi 
501*7fd79137SRobert Mustacchi 
502*7fd79137SRobert Mustacchi /*
503*7fd79137SRobert Mustacchi     Takes a die, an attribute attr, and checks if attr
504*7fd79137SRobert Mustacchi     occurs in die.  Attr is required to be an attribute
505*7fd79137SRobert Mustacchi     whose form is in the "constant" class.  If attr occurs
506*7fd79137SRobert Mustacchi     in die, the value is returned.
507*7fd79137SRobert Mustacchi   Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as
508*7fd79137SRobert Mustacchi     appropriate. Sets the value thru the pointer return_val.
509*7fd79137SRobert Mustacchi     This function is meant to do all the
510*7fd79137SRobert Mustacchi     processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset,
511*7fd79137SRobert Mustacchi     and dwarf_srclang.
512*7fd79137SRobert Mustacchi */
513*7fd79137SRobert Mustacchi static int
514*7fd79137SRobert Mustacchi _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
515*7fd79137SRobert Mustacchi     Dwarf_Half attr,
516*7fd79137SRobert Mustacchi     Dwarf_Unsigned * return_val,
517*7fd79137SRobert Mustacchi     Dwarf_Error * error)
518*7fd79137SRobert Mustacchi {
519*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr info_ptr;
520*7fd79137SRobert Mustacchi     Dwarf_Half attr_form;
521*7fd79137SRobert Mustacchi     Dwarf_Unsigned ret_value;
522*7fd79137SRobert Mustacchi     Dwarf_Debug dbg;
523*7fd79137SRobert Mustacchi 
524*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
525*7fd79137SRobert Mustacchi 
526*7fd79137SRobert Mustacchi     dbg = die->di_cu_context->cc_dbg;
527*7fd79137SRobert Mustacchi     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
528*7fd79137SRobert Mustacchi     if (info_ptr != NULL) {
529*7fd79137SRobert Mustacchi         switch (attr_form) {
530*7fd79137SRobert Mustacchi 
531*7fd79137SRobert Mustacchi         case DW_FORM_data1:
532*7fd79137SRobert Mustacchi             *return_val = (*(Dwarf_Small *) info_ptr);
533*7fd79137SRobert Mustacchi             return (DW_DLV_OK);
534*7fd79137SRobert Mustacchi 
535*7fd79137SRobert Mustacchi         case DW_FORM_data2:
536*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
537*7fd79137SRobert Mustacchi                            info_ptr, sizeof(Dwarf_Shalf));
538*7fd79137SRobert Mustacchi             *return_val = ret_value;
539*7fd79137SRobert Mustacchi             return (DW_DLV_OK);
540*7fd79137SRobert Mustacchi 
541*7fd79137SRobert Mustacchi         case DW_FORM_data4:
542*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
543*7fd79137SRobert Mustacchi                            info_ptr, sizeof(Dwarf_sfixed));
544*7fd79137SRobert Mustacchi             *return_val = ret_value;
545*7fd79137SRobert Mustacchi             return (DW_DLV_OK);
546*7fd79137SRobert Mustacchi 
547*7fd79137SRobert Mustacchi         case DW_FORM_data8:
548*7fd79137SRobert Mustacchi             READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
549*7fd79137SRobert Mustacchi                            info_ptr, sizeof(Dwarf_Unsigned));
550*7fd79137SRobert Mustacchi             *return_val = ret_value;
551*7fd79137SRobert Mustacchi             return (DW_DLV_OK);
552*7fd79137SRobert Mustacchi 
553*7fd79137SRobert Mustacchi         case DW_FORM_udata:
554*7fd79137SRobert Mustacchi             *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
555*7fd79137SRobert Mustacchi             return (DW_DLV_OK);
556*7fd79137SRobert Mustacchi 
557*7fd79137SRobert Mustacchi         default:
558*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
559*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
560*7fd79137SRobert Mustacchi         }
561*7fd79137SRobert Mustacchi     }
562*7fd79137SRobert Mustacchi     if (attr_form == 0) {
563*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
564*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
565*7fd79137SRobert Mustacchi     }
566*7fd79137SRobert Mustacchi     return DW_DLV_NO_ENTRY;
567*7fd79137SRobert Mustacchi }
568*7fd79137SRobert Mustacchi 
569*7fd79137SRobert Mustacchi 
570*7fd79137SRobert Mustacchi int
571*7fd79137SRobert Mustacchi dwarf_bytesize(Dwarf_Die die,
572*7fd79137SRobert Mustacchi     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
573*7fd79137SRobert Mustacchi {
574*7fd79137SRobert Mustacchi     Dwarf_Unsigned luns = 0;
575*7fd79137SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size,
576*7fd79137SRobert Mustacchi         &luns, error);
577*7fd79137SRobert Mustacchi     *ret_size = luns;
578*7fd79137SRobert Mustacchi     return res;
579*7fd79137SRobert Mustacchi }
580*7fd79137SRobert Mustacchi 
581*7fd79137SRobert Mustacchi 
582*7fd79137SRobert Mustacchi int
583*7fd79137SRobert Mustacchi dwarf_bitsize(Dwarf_Die die,
584*7fd79137SRobert Mustacchi     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
585*7fd79137SRobert Mustacchi {
586*7fd79137SRobert Mustacchi     Dwarf_Unsigned luns = 0;
587*7fd79137SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size,
588*7fd79137SRobert Mustacchi         &luns, error);
589*7fd79137SRobert Mustacchi     *ret_size = luns;
590*7fd79137SRobert Mustacchi     return res;
591*7fd79137SRobert Mustacchi }
592*7fd79137SRobert Mustacchi 
593*7fd79137SRobert Mustacchi 
594*7fd79137SRobert Mustacchi int
595*7fd79137SRobert Mustacchi dwarf_bitoffset(Dwarf_Die die,
596*7fd79137SRobert Mustacchi     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
597*7fd79137SRobert Mustacchi {
598*7fd79137SRobert Mustacchi     Dwarf_Unsigned luns = 0;
599*7fd79137SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die,
600*7fd79137SRobert Mustacchi         DW_AT_bit_offset, &luns, error);
601*7fd79137SRobert Mustacchi     *ret_size = luns;
602*7fd79137SRobert Mustacchi     return res;
603*7fd79137SRobert Mustacchi }
604*7fd79137SRobert Mustacchi 
605*7fd79137SRobert Mustacchi 
606*7fd79137SRobert Mustacchi /* Refer section 3.1, page 21 in Dwarf Definition. */
607*7fd79137SRobert Mustacchi int
608*7fd79137SRobert Mustacchi dwarf_srclang(Dwarf_Die die,
609*7fd79137SRobert Mustacchi     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
610*7fd79137SRobert Mustacchi {
611*7fd79137SRobert Mustacchi     Dwarf_Unsigned luns = 0;
612*7fd79137SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language,
613*7fd79137SRobert Mustacchi         &luns, error);
614*7fd79137SRobert Mustacchi     *ret_size = luns;
615*7fd79137SRobert Mustacchi     return res;
616*7fd79137SRobert Mustacchi }
617*7fd79137SRobert Mustacchi 
618*7fd79137SRobert Mustacchi 
619*7fd79137SRobert Mustacchi /* Refer section 5.4, page 37 in Dwarf Definition. */
620*7fd79137SRobert Mustacchi int
621*7fd79137SRobert Mustacchi dwarf_arrayorder(Dwarf_Die die,
622*7fd79137SRobert Mustacchi     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
623*7fd79137SRobert Mustacchi {
624*7fd79137SRobert Mustacchi     Dwarf_Unsigned luns = 0;
625*7fd79137SRobert Mustacchi     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering,
626*7fd79137SRobert Mustacchi         &luns, error);
627*7fd79137SRobert Mustacchi     *ret_size = luns;
628*7fd79137SRobert Mustacchi     return res;
629*7fd79137SRobert Mustacchi }
630*7fd79137SRobert Mustacchi 
631*7fd79137SRobert Mustacchi /*
632*7fd79137SRobert Mustacchi         Return DW_DLV_OK if ok
633*7fd79137SRobert Mustacchi         DW_DLV_ERROR if failure.
634*7fd79137SRobert Mustacchi 
635*7fd79137SRobert Mustacchi         If the die and the attr are not related the result is
636*7fd79137SRobert Mustacchi         meaningless.
637*7fd79137SRobert Mustacchi */
638*7fd79137SRobert Mustacchi int
639*7fd79137SRobert Mustacchi dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr,
640*7fd79137SRobert Mustacchi     Dwarf_Off * offset /* return offset thru this ptr */,
641*7fd79137SRobert Mustacchi     Dwarf_Error * error)
642*7fd79137SRobert Mustacchi {
643*7fd79137SRobert Mustacchi     Dwarf_Off attroff = 0;
644*7fd79137SRobert Mustacchi 
645*7fd79137SRobert Mustacchi     CHECK_DIE(die, DW_DLV_ERROR);
646*7fd79137SRobert Mustacchi 
647*7fd79137SRobert Mustacchi     attroff = (attr->ar_debug_info_ptr -
648*7fd79137SRobert Mustacchi                die->di_cu_context->cc_dbg->de_debug_info.dss_data);
649*7fd79137SRobert Mustacchi     *offset = attroff;
650*7fd79137SRobert Mustacchi     return DW_DLV_OK;
651*7fd79137SRobert Mustacchi }
652*7fd79137SRobert Mustacchi 
653*7fd79137SRobert Mustacchi int
654*7fd79137SRobert Mustacchi dwarf_die_abbrev_code(Dwarf_Die die)
655*7fd79137SRobert Mustacchi {
656*7fd79137SRobert Mustacchi     return die->di_abbrev_code;
657*7fd79137SRobert Mustacchi }
658*7fd79137SRobert Mustacchi 
659*7fd79137SRobert Mustacchi /* Helper function for finding form class. */
660*7fd79137SRobert Mustacchi static enum Dwarf_Form_Class
661*7fd79137SRobert Mustacchi dw_get_special_offset(Dwarf_Half attrnum)
662*7fd79137SRobert Mustacchi {
663*7fd79137SRobert Mustacchi     switch(attrnum) {
664*7fd79137SRobert Mustacchi     case DW_AT_stmt_list:
665*7fd79137SRobert Mustacchi              return DW_FORM_CLASS_LINEPTR;
666*7fd79137SRobert Mustacchi     case DW_AT_macro_info:
667*7fd79137SRobert Mustacchi              return DW_FORM_CLASS_MACPTR;
668*7fd79137SRobert Mustacchi     case DW_AT_ranges:
669*7fd79137SRobert Mustacchi              return DW_FORM_CLASS_RANGELISTPTR;
670*7fd79137SRobert Mustacchi     case DW_AT_location:
671*7fd79137SRobert Mustacchi     case DW_AT_string_length:
672*7fd79137SRobert Mustacchi     case DW_AT_return_addr:
673*7fd79137SRobert Mustacchi     case DW_AT_data_member_location:
674*7fd79137SRobert Mustacchi     case DW_AT_frame_base:
675*7fd79137SRobert Mustacchi     case DW_AT_segment:
676*7fd79137SRobert Mustacchi     case DW_AT_static_link:
677*7fd79137SRobert Mustacchi     case DW_AT_use_location:
678*7fd79137SRobert Mustacchi     case DW_AT_vtable_elem_location:
679*7fd79137SRobert Mustacchi              return DW_FORM_CLASS_LOCLISTPTR;
680*7fd79137SRobert Mustacchi     case DW_AT_sibling:
681*7fd79137SRobert Mustacchi     case DW_AT_byte_size :
682*7fd79137SRobert Mustacchi     case DW_AT_bit_offset :
683*7fd79137SRobert Mustacchi     case DW_AT_bit_size :
684*7fd79137SRobert Mustacchi     case DW_AT_discr :
685*7fd79137SRobert Mustacchi     case DW_AT_import :
686*7fd79137SRobert Mustacchi     case DW_AT_common_reference:
687*7fd79137SRobert Mustacchi     case DW_AT_containing_type:
688*7fd79137SRobert Mustacchi     case DW_AT_default_value:
689*7fd79137SRobert Mustacchi     case DW_AT_lower_bound:
690*7fd79137SRobert Mustacchi     case DW_AT_bit_stride:
691*7fd79137SRobert Mustacchi     case DW_AT_upper_bound:
692*7fd79137SRobert Mustacchi     case DW_AT_abstract_origin:
693*7fd79137SRobert Mustacchi     case DW_AT_base_types:
694*7fd79137SRobert Mustacchi     case DW_AT_count:
695*7fd79137SRobert Mustacchi     case DW_AT_friend:
696*7fd79137SRobert Mustacchi     case DW_AT_namelist_item:
697*7fd79137SRobert Mustacchi     case DW_AT_priority:
698*7fd79137SRobert Mustacchi     case DW_AT_specification:
699*7fd79137SRobert Mustacchi     case DW_AT_type:
700*7fd79137SRobert Mustacchi     case DW_AT_allocated:
701*7fd79137SRobert Mustacchi     case DW_AT_associated:
702*7fd79137SRobert Mustacchi     case DW_AT_byte_stride:
703*7fd79137SRobert Mustacchi     case DW_AT_extension:
704*7fd79137SRobert Mustacchi     case DW_AT_trampoline:
705*7fd79137SRobert Mustacchi     case DW_AT_small:
706*7fd79137SRobert Mustacchi     case DW_AT_object_pointer:
707*7fd79137SRobert Mustacchi     case DW_AT_signature:
708*7fd79137SRobert Mustacchi                 return DW_FORM_CLASS_REFERENCE;
709*7fd79137SRobert Mustacchi     case DW_AT_MIPS_fde: /* SGI/IRIX extension */
710*7fd79137SRobert Mustacchi                 return DW_FORM_CLASS_FRAMEPTR;
711*7fd79137SRobert Mustacchi     }
712*7fd79137SRobert Mustacchi     return DW_FORM_CLASS_UNKNOWN;
713*7fd79137SRobert Mustacchi }
714*7fd79137SRobert Mustacchi 
715*7fd79137SRobert Mustacchi /* It takes 4 pieces of data (including the FORM)
716*7fd79137SRobert Mustacchi    to accurately determine the form 'class' as documented
717*7fd79137SRobert Mustacchi    in the DWARF spec. This is per DWARF4, but will work
718*7fd79137SRobert Mustacchi    for DWARF2 or 3 as well.  */
719*7fd79137SRobert Mustacchi enum Dwarf_Form_Class dwarf_get_form_class(
720*7fd79137SRobert Mustacchi     Dwarf_Half dwversion,
721*7fd79137SRobert Mustacchi     Dwarf_Half attrnum,
722*7fd79137SRobert Mustacchi     Dwarf_Half offset_size,
723*7fd79137SRobert Mustacchi     Dwarf_Half form)
724*7fd79137SRobert Mustacchi {
725*7fd79137SRobert Mustacchi     switch(form) {
726*7fd79137SRobert Mustacchi     case  DW_FORM_addr: return DW_FORM_CLASS_ADDRESS;
727*7fd79137SRobert Mustacchi 
728*7fd79137SRobert Mustacchi     case  DW_FORM_data2:  return DW_FORM_CLASS_CONSTANT;
729*7fd79137SRobert Mustacchi 
730*7fd79137SRobert Mustacchi     case  DW_FORM_data4:
731*7fd79137SRobert Mustacchi         if(dwversion <= 3 && offset_size == 4) {
732*7fd79137SRobert Mustacchi             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
733*7fd79137SRobert Mustacchi             if(class != DW_FORM_CLASS_UNKNOWN) {
734*7fd79137SRobert Mustacchi                 return class;
735*7fd79137SRobert Mustacchi             }
736*7fd79137SRobert Mustacchi         }
737*7fd79137SRobert Mustacchi         return DW_FORM_CLASS_CONSTANT;
738*7fd79137SRobert Mustacchi     case  DW_FORM_data8:
739*7fd79137SRobert Mustacchi         if(dwversion <= 3 && offset_size == 8) {
740*7fd79137SRobert Mustacchi             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
741*7fd79137SRobert Mustacchi             if(class != DW_FORM_CLASS_UNKNOWN) {
742*7fd79137SRobert Mustacchi                 return class;
743*7fd79137SRobert Mustacchi             }
744*7fd79137SRobert Mustacchi         }
745*7fd79137SRobert Mustacchi         return DW_FORM_CLASS_CONSTANT;
746*7fd79137SRobert Mustacchi 
747*7fd79137SRobert Mustacchi     case  DW_FORM_sec_offset:
748*7fd79137SRobert Mustacchi         {
749*7fd79137SRobert Mustacchi             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
750*7fd79137SRobert Mustacchi             if(class != DW_FORM_CLASS_UNKNOWN) {
751*7fd79137SRobert Mustacchi                 return class;
752*7fd79137SRobert Mustacchi             }
753*7fd79137SRobert Mustacchi         }
754*7fd79137SRobert Mustacchi         /* We do not know what this is. */
755*7fd79137SRobert Mustacchi         break;
756*7fd79137SRobert Mustacchi 
757*7fd79137SRobert Mustacchi     case  DW_FORM_string: return DW_FORM_CLASS_STRING;
758*7fd79137SRobert Mustacchi     case  DW_FORM_strp:   return DW_FORM_CLASS_STRING;
759*7fd79137SRobert Mustacchi 
760*7fd79137SRobert Mustacchi     case  DW_FORM_block:  return DW_FORM_CLASS_BLOCK;
761*7fd79137SRobert Mustacchi     case  DW_FORM_block1: return DW_FORM_CLASS_BLOCK;
762*7fd79137SRobert Mustacchi     case  DW_FORM_block2: return DW_FORM_CLASS_BLOCK;
763*7fd79137SRobert Mustacchi     case  DW_FORM_block4: return DW_FORM_CLASS_BLOCK;
764*7fd79137SRobert Mustacchi 
765*7fd79137SRobert Mustacchi     case  DW_FORM_data1:  return DW_FORM_CLASS_CONSTANT;
766*7fd79137SRobert Mustacchi     case  DW_FORM_sdata:  return DW_FORM_CLASS_CONSTANT;
767*7fd79137SRobert Mustacchi     case  DW_FORM_udata:  return DW_FORM_CLASS_CONSTANT;
768*7fd79137SRobert Mustacchi 
769*7fd79137SRobert Mustacchi     case  DW_FORM_ref_addr:    return DW_FORM_CLASS_REFERENCE;
770*7fd79137SRobert Mustacchi     case  DW_FORM_ref1:        return DW_FORM_CLASS_REFERENCE;
771*7fd79137SRobert Mustacchi     case  DW_FORM_ref2:        return DW_FORM_CLASS_REFERENCE;
772*7fd79137SRobert Mustacchi     case  DW_FORM_ref4:        return DW_FORM_CLASS_REFERENCE;
773*7fd79137SRobert Mustacchi     case  DW_FORM_ref8:        return DW_FORM_CLASS_REFERENCE;
774*7fd79137SRobert Mustacchi     case  DW_FORM_ref_udata:   return DW_FORM_CLASS_REFERENCE;
775*7fd79137SRobert Mustacchi     case  DW_FORM_ref_sig8:    return DW_FORM_CLASS_REFERENCE;
776*7fd79137SRobert Mustacchi 
777*7fd79137SRobert Mustacchi     case  DW_FORM_exprloc:      return DW_FORM_CLASS_EXPRLOC;
778*7fd79137SRobert Mustacchi 
779*7fd79137SRobert Mustacchi     case  DW_FORM_flag:         return DW_FORM_CLASS_FLAG;
780*7fd79137SRobert Mustacchi     case  DW_FORM_flag_present: return DW_FORM_CLASS_FLAG;
781*7fd79137SRobert Mustacchi 
782*7fd79137SRobert Mustacchi 
783*7fd79137SRobert Mustacchi     case  DW_FORM_indirect:
784*7fd79137SRobert Mustacchi     default:
785*7fd79137SRobert Mustacchi         break;
786*7fd79137SRobert Mustacchi     };
787*7fd79137SRobert Mustacchi     return DW_FORM_CLASS_UNKNOWN;
788*7fd79137SRobert Mustacchi }
789*7fd79137SRobert Mustacchi 
790