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