xref: /titanic_41/usr/src/tools/ctf/dwarf/common/dwarf_query.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe 
3*07dc1947SRichard Lowe   Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
4*07dc1947SRichard Lowe   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
549d3bc91SRichard Lowe 
649d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
749d3bc91SRichard Lowe   under the terms of version 2.1 of the GNU Lesser General Public License
849d3bc91SRichard Lowe   as published by the Free Software Foundation.
949d3bc91SRichard Lowe 
1049d3bc91SRichard Lowe   This program is distributed in the hope that it would be useful, but
1149d3bc91SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc91SRichard Lowe   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc91SRichard Lowe 
1449d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
1549d3bc91SRichard Lowe   free of the rightful claim of any third person regarding infringement
1649d3bc91SRichard Lowe   or the like.  Any license provided herein, whether implied or
1749d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
1849d3bc91SRichard Lowe   any, provided herein do not apply to combinations of this program with
1949d3bc91SRichard Lowe   other software, or any other product whatsoever.
2049d3bc91SRichard Lowe 
2149d3bc91SRichard Lowe   You should have received a copy of the GNU Lesser General Public
2249d3bc91SRichard Lowe   License along with this program; if not, write the Free Software
23*07dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc91SRichard Lowe   USA.
2549d3bc91SRichard Lowe 
26*07dc1947SRichard Lowe   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2749d3bc91SRichard Lowe   Mountain View, CA 94043, or:
2849d3bc91SRichard Lowe 
2949d3bc91SRichard Lowe   http://www.sgi.com
3049d3bc91SRichard Lowe 
3149d3bc91SRichard Lowe   For further information regarding this notice, see:
3249d3bc91SRichard Lowe 
3349d3bc91SRichard Lowe   http://oss.sgi.com/projects/GenInfo/NoticeExplan
3449d3bc91SRichard Lowe 
3549d3bc91SRichard Lowe */
36*07dc1947SRichard Lowe /* The address of the Free Software Foundation is
37*07dc1947SRichard Lowe    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*07dc1947SRichard Lowe    Boston, MA 02110-1301, USA.
39*07dc1947SRichard Lowe    SGI has moved from the Crittenden Lane address.
40*07dc1947SRichard Lowe */
41*07dc1947SRichard Lowe 
42*07dc1947SRichard Lowe 
4349d3bc91SRichard Lowe 
4449d3bc91SRichard Lowe 
4549d3bc91SRichard Lowe #include "config.h"
4649d3bc91SRichard Lowe #include "dwarf_incl.h"
4749d3bc91SRichard Lowe #include <stdio.h>
4849d3bc91SRichard Lowe #include "dwarf_die_deliv.h"
4949d3bc91SRichard Lowe 
50*07dc1947SRichard Lowe /* This is normally reliable.
51*07dc1947SRichard Lowe But not always.
52*07dc1947SRichard Lowe If different compilation
53*07dc1947SRichard Lowe units have different address sizes
54*07dc1947SRichard Lowe this may not give the correct value in all contexts.
55*07dc1947SRichard Lowe If the Elf offset size != address_size
56*07dc1947SRichard Lowe (for example if address_size = 4 but recorded in elf64 object)
57*07dc1947SRichard Lowe this may not give the correct value in all contexts.
58*07dc1947SRichard Lowe */
5949d3bc91SRichard Lowe int
dwarf_get_address_size(Dwarf_Debug dbg,Dwarf_Half * ret_addr_size,Dwarf_Error * error)6049d3bc91SRichard Lowe dwarf_get_address_size(Dwarf_Debug dbg,
6149d3bc91SRichard Lowe     Dwarf_Half * ret_addr_size, Dwarf_Error * error)
6249d3bc91SRichard Lowe {
63*07dc1947SRichard Lowe     Dwarf_Half address_size = 0;
6449d3bc91SRichard Lowe 
6549d3bc91SRichard Lowe     if (dbg == 0) {
6649d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
6749d3bc91SRichard Lowe         return (DW_DLV_ERROR);
6849d3bc91SRichard Lowe     }
6949d3bc91SRichard Lowe     address_size = dbg->de_pointer_size;
7049d3bc91SRichard Lowe     *ret_addr_size = address_size;
7149d3bc91SRichard Lowe     return DW_DLV_OK;
7249d3bc91SRichard Lowe }
7349d3bc91SRichard Lowe 
74*07dc1947SRichard Lowe /* This will be correct in all contexts where the
75*07dc1947SRichard Lowe    CU context of a DIE is known.
76*07dc1947SRichard Lowe */
77*07dc1947SRichard Lowe int
dwarf_get_die_address_size(Dwarf_Die die,Dwarf_Half * ret_addr_size,Dwarf_Error * error)78*07dc1947SRichard Lowe dwarf_get_die_address_size(Dwarf_Die die,
79*07dc1947SRichard Lowe     Dwarf_Half * ret_addr_size, Dwarf_Error * error)
80*07dc1947SRichard Lowe {
81*07dc1947SRichard Lowe     Dwarf_Half address_size = 0;
82*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
83*07dc1947SRichard Lowe     address_size = die->di_cu_context->cc_address_size;
84*07dc1947SRichard Lowe     *ret_addr_size = address_size;
85*07dc1947SRichard Lowe     return DW_DLV_OK;
86*07dc1947SRichard Lowe }
87*07dc1947SRichard Lowe 
8849d3bc91SRichard Lowe int
dwarf_dieoffset(Dwarf_Die die,Dwarf_Off * ret_offset,Dwarf_Error * error)8949d3bc91SRichard Lowe dwarf_dieoffset(Dwarf_Die die,
9049d3bc91SRichard Lowe     Dwarf_Off * ret_offset, Dwarf_Error * error)
9149d3bc91SRichard Lowe {
92*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
9349d3bc91SRichard Lowe 
9449d3bc91SRichard Lowe     *ret_offset = (die->di_debug_info_ptr -
95*07dc1947SRichard Lowe         die->di_cu_context->cc_dbg->de_debug_info.dss_data);
9649d3bc91SRichard Lowe     return DW_DLV_OK;
9749d3bc91SRichard Lowe }
9849d3bc91SRichard Lowe 
9949d3bc91SRichard Lowe 
10049d3bc91SRichard Lowe /*
10149d3bc91SRichard Lowe     This function returns the offset of
10249d3bc91SRichard Lowe     the die relative to the start of its
10349d3bc91SRichard Lowe     compilation-unit rather than .debug_info.
10449d3bc91SRichard Lowe     Returns DW_DLV_ERROR on error.
10549d3bc91SRichard Lowe */
10649d3bc91SRichard Lowe int
dwarf_die_CU_offset(Dwarf_Die die,Dwarf_Off * cu_off,Dwarf_Error * error)10749d3bc91SRichard Lowe dwarf_die_CU_offset(Dwarf_Die die,
10849d3bc91SRichard Lowe     Dwarf_Off * cu_off, Dwarf_Error * error)
10949d3bc91SRichard Lowe {
110*07dc1947SRichard Lowe     Dwarf_CU_Context cu_context = 0;
11149d3bc91SRichard Lowe 
112*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
11349d3bc91SRichard Lowe     cu_context = die->di_cu_context;
11449d3bc91SRichard Lowe 
11549d3bc91SRichard Lowe     *cu_off =
116*07dc1947SRichard Lowe         (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info.dss_data -
11749d3bc91SRichard Lowe          cu_context->cc_debug_info_offset);
11849d3bc91SRichard Lowe     return DW_DLV_OK;
11949d3bc91SRichard Lowe }
12049d3bc91SRichard Lowe 
121*07dc1947SRichard Lowe /*
122*07dc1947SRichard Lowe     This function returns the global offset
123*07dc1947SRichard Lowe     (meaning the section offset) and length of
124*07dc1947SRichard Lowe     the CU that this die is a part of.
125*07dc1947SRichard Lowe     Used for correctness checking by dwarfdump.
126*07dc1947SRichard Lowe */
127*07dc1947SRichard Lowe int
dwarf_die_CU_offset_range(Dwarf_Die die,Dwarf_Off * cu_off,Dwarf_Off * cu_length,Dwarf_Error * error)128*07dc1947SRichard Lowe dwarf_die_CU_offset_range(Dwarf_Die die,
129*07dc1947SRichard Lowe      Dwarf_Off * cu_off,
130*07dc1947SRichard Lowe      Dwarf_Off * cu_length,
131*07dc1947SRichard Lowe      Dwarf_Error * error)
132*07dc1947SRichard Lowe {
133*07dc1947SRichard Lowe     Dwarf_CU_Context cu_context = 0;
134*07dc1947SRichard Lowe 
135*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
136*07dc1947SRichard Lowe     cu_context = die->di_cu_context;
137*07dc1947SRichard Lowe 
138*07dc1947SRichard Lowe     *cu_off = cu_context->cc_debug_info_offset;
139*07dc1947SRichard Lowe     *cu_length = cu_context->cc_length + cu_context->cc_length_size
140*07dc1947SRichard Lowe             + cu_context->cc_extension_size;
141*07dc1947SRichard Lowe     return DW_DLV_OK;
142*07dc1947SRichard Lowe }
143*07dc1947SRichard Lowe 
144*07dc1947SRichard Lowe 
14549d3bc91SRichard Lowe 
14649d3bc91SRichard Lowe int
dwarf_tag(Dwarf_Die die,Dwarf_Half * tag,Dwarf_Error * error)14749d3bc91SRichard Lowe dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
14849d3bc91SRichard Lowe {
149*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
15049d3bc91SRichard Lowe     *tag = (die->di_abbrev_list->ab_tag);
15149d3bc91SRichard Lowe     return DW_DLV_OK;
15249d3bc91SRichard Lowe }
15349d3bc91SRichard Lowe 
15449d3bc91SRichard Lowe 
15549d3bc91SRichard Lowe int
dwarf_attrlist(Dwarf_Die die,Dwarf_Attribute ** attrbuf,Dwarf_Signed * attrcnt,Dwarf_Error * error)15649d3bc91SRichard Lowe dwarf_attrlist(Dwarf_Die die,
15749d3bc91SRichard Lowe     Dwarf_Attribute ** attrbuf,
15849d3bc91SRichard Lowe     Dwarf_Signed * attrcnt, Dwarf_Error * error)
15949d3bc91SRichard Lowe {
16049d3bc91SRichard Lowe     Dwarf_Word attr_count = 0;
161*07dc1947SRichard Lowe     Dwarf_Word i = 0;
162*07dc1947SRichard Lowe     Dwarf_Half attr = 0;
163*07dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
164*07dc1947SRichard Lowe     Dwarf_Byte_Ptr abbrev_ptr = 0;
165*07dc1947SRichard Lowe     Dwarf_Abbrev_List abbrev_list = 0;
166*07dc1947SRichard Lowe     Dwarf_Attribute new_attr = 0;
167*07dc1947SRichard Lowe     Dwarf_Attribute head_attr = NULL;
168*07dc1947SRichard Lowe     Dwarf_Attribute curr_attr = NULL;
169*07dc1947SRichard Lowe     Dwarf_Attribute *attr_ptr = 0;
170*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
171*07dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
17249d3bc91SRichard Lowe 
173*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
17449d3bc91SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
17549d3bc91SRichard Lowe 
17649d3bc91SRichard Lowe     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
17749d3bc91SRichard Lowe                                              die->di_abbrev_list->
17849d3bc91SRichard Lowe                                              ab_code);
17949d3bc91SRichard Lowe     if (abbrev_list == NULL) {
18049d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD);
18149d3bc91SRichard Lowe         return (DW_DLV_ERROR);
18249d3bc91SRichard Lowe     }
18349d3bc91SRichard Lowe     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
18449d3bc91SRichard Lowe 
18549d3bc91SRichard Lowe     info_ptr = die->di_debug_info_ptr;
186*07dc1947SRichard Lowe     SKIP_LEB128_WORD(info_ptr);
18749d3bc91SRichard Lowe 
18849d3bc91SRichard Lowe     do {
18949d3bc91SRichard Lowe         Dwarf_Unsigned utmp2;
19049d3bc91SRichard Lowe 
191*07dc1947SRichard Lowe         DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
19249d3bc91SRichard Lowe         attr = (Dwarf_Half) utmp2;
193*07dc1947SRichard Lowe         DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
19449d3bc91SRichard Lowe         attr_form = (Dwarf_Half) utmp2;
19549d3bc91SRichard Lowe 
19649d3bc91SRichard Lowe         if (attr != 0) {
19749d3bc91SRichard Lowe             new_attr =
19849d3bc91SRichard Lowe                 (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
19949d3bc91SRichard Lowe             if (new_attr == NULL) {
20049d3bc91SRichard Lowe                 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
20149d3bc91SRichard Lowe                 return (DW_DLV_ERROR);
20249d3bc91SRichard Lowe             }
20349d3bc91SRichard Lowe 
20449d3bc91SRichard Lowe             new_attr->ar_attribute = attr;
20549d3bc91SRichard Lowe             new_attr->ar_attribute_form_direct = attr_form;
20649d3bc91SRichard Lowe             new_attr->ar_attribute_form = attr_form;
20749d3bc91SRichard Lowe             if (attr_form == DW_FORM_indirect) {
20849d3bc91SRichard Lowe                 Dwarf_Unsigned utmp6;
209*07dc1947SRichard Lowe 
21049d3bc91SRichard Lowe                 /* DECODE_LEB128_UWORD does info_ptr update */
211*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(info_ptr, utmp6);
21249d3bc91SRichard Lowe                 attr_form = (Dwarf_Half) utmp6;
21349d3bc91SRichard Lowe                 new_attr->ar_attribute_form = attr_form;
21449d3bc91SRichard Lowe             }
21549d3bc91SRichard Lowe             new_attr->ar_cu_context = die->di_cu_context;
21649d3bc91SRichard Lowe             new_attr->ar_debug_info_ptr = info_ptr;
21749d3bc91SRichard Lowe 
218*07dc1947SRichard Lowe             {
219*07dc1947SRichard Lowe                 Dwarf_Unsigned sov = _dwarf_get_size_of_val(dbg,
220*07dc1947SRichard Lowe                     attr_form,
221*07dc1947SRichard Lowe                     die->di_cu_context->cc_address_size,
222*07dc1947SRichard Lowe                     info_ptr,
223*07dc1947SRichard Lowe                     die->di_cu_context->cc_length_size);
224*07dc1947SRichard Lowe                 info_ptr += sov;
225*07dc1947SRichard Lowe             }
226*07dc1947SRichard Lowe 
22749d3bc91SRichard Lowe 
22849d3bc91SRichard Lowe             if (head_attr == NULL)
22949d3bc91SRichard Lowe                 head_attr = curr_attr = new_attr;
23049d3bc91SRichard Lowe             else {
23149d3bc91SRichard Lowe                 curr_attr->ar_next = new_attr;
23249d3bc91SRichard Lowe                 curr_attr = new_attr;
23349d3bc91SRichard Lowe             }
23449d3bc91SRichard Lowe             attr_count++;
23549d3bc91SRichard Lowe         }
23649d3bc91SRichard Lowe     } while (attr != 0 || attr_form != 0);
23749d3bc91SRichard Lowe 
23849d3bc91SRichard Lowe     if (attr_count == 0) {
23949d3bc91SRichard Lowe         *attrbuf = NULL;
24049d3bc91SRichard Lowe         *attrcnt = 0;
24149d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
24249d3bc91SRichard Lowe     }
24349d3bc91SRichard Lowe 
24449d3bc91SRichard Lowe     attr_ptr = (Dwarf_Attribute *)
24549d3bc91SRichard Lowe         _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
24649d3bc91SRichard Lowe     if (attr_ptr == NULL) {
24749d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
24849d3bc91SRichard Lowe         return (DW_DLV_ERROR);
24949d3bc91SRichard Lowe     }
25049d3bc91SRichard Lowe 
25149d3bc91SRichard Lowe     curr_attr = head_attr;
25249d3bc91SRichard Lowe     for (i = 0; i < attr_count; i++) {
25349d3bc91SRichard Lowe         *(attr_ptr + i) = curr_attr;
25449d3bc91SRichard Lowe         curr_attr = curr_attr->ar_next;
25549d3bc91SRichard Lowe     }
25649d3bc91SRichard Lowe 
25749d3bc91SRichard Lowe     *attrbuf = attr_ptr;
25849d3bc91SRichard Lowe     *attrcnt = attr_count;
25949d3bc91SRichard Lowe     return (DW_DLV_OK);
26049d3bc91SRichard Lowe }
26149d3bc91SRichard Lowe 
26249d3bc91SRichard Lowe 
26349d3bc91SRichard Lowe /*
26449d3bc91SRichard Lowe     This function takes a die, and an attr, and returns
26549d3bc91SRichard Lowe     a pointer to the start of the value of that attr in
26649d3bc91SRichard Lowe     the given die in the .debug_info section.  The form
26749d3bc91SRichard Lowe     is returned in *attr_form.
26849d3bc91SRichard Lowe 
26949d3bc91SRichard Lowe     Returns NULL on error, or if attr is not found.
27049d3bc91SRichard Lowe     However, *attr_form is 0 on error, and positive
27149d3bc91SRichard Lowe     otherwise.
27249d3bc91SRichard Lowe */
27349d3bc91SRichard Lowe static Dwarf_Byte_Ptr
_dwarf_get_value_ptr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Half * attr_form)27449d3bc91SRichard Lowe _dwarf_get_value_ptr(Dwarf_Die die,
27549d3bc91SRichard Lowe     Dwarf_Half attr, Dwarf_Half * attr_form)
27649d3bc91SRichard Lowe {
277*07dc1947SRichard Lowe     Dwarf_Byte_Ptr abbrev_ptr = 0;
27849d3bc91SRichard Lowe     Dwarf_Abbrev_List abbrev_list;
279*07dc1947SRichard Lowe     Dwarf_Half curr_attr = 0;
280*07dc1947SRichard Lowe     Dwarf_Half curr_attr_form = 0;
281*07dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
28249d3bc91SRichard Lowe 
28349d3bc91SRichard Lowe     abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
284*07dc1947SRichard Lowe         die->di_abbrev_list->ab_code);
28549d3bc91SRichard Lowe     if (abbrev_list == NULL) {
28649d3bc91SRichard Lowe         *attr_form = 0;
28749d3bc91SRichard Lowe         return (NULL);
28849d3bc91SRichard Lowe     }
28949d3bc91SRichard Lowe     abbrev_ptr = abbrev_list->ab_abbrev_ptr;
29049d3bc91SRichard Lowe 
29149d3bc91SRichard Lowe     info_ptr = die->di_debug_info_ptr;
292*07dc1947SRichard Lowe     SKIP_LEB128_WORD(info_ptr);
29349d3bc91SRichard Lowe 
29449d3bc91SRichard Lowe     do {
29549d3bc91SRichard Lowe         Dwarf_Unsigned utmp3;
29649d3bc91SRichard Lowe 
297*07dc1947SRichard Lowe         DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
29849d3bc91SRichard Lowe         curr_attr = (Dwarf_Half) utmp3;
299*07dc1947SRichard Lowe         DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
30049d3bc91SRichard Lowe         curr_attr_form = (Dwarf_Half) utmp3;
30149d3bc91SRichard Lowe         if (curr_attr_form == DW_FORM_indirect) {
30249d3bc91SRichard Lowe             Dwarf_Unsigned utmp6;
30349d3bc91SRichard Lowe 
30449d3bc91SRichard Lowe             /* DECODE_LEB128_UWORD updates info_ptr */
305*07dc1947SRichard Lowe             DECODE_LEB128_UWORD(info_ptr, utmp6);
30649d3bc91SRichard Lowe             curr_attr_form = (Dwarf_Half) utmp6;
30749d3bc91SRichard Lowe         }
30849d3bc91SRichard Lowe 
30949d3bc91SRichard Lowe         if (curr_attr == attr) {
31049d3bc91SRichard Lowe             *attr_form = curr_attr_form;
31149d3bc91SRichard Lowe             return (info_ptr);
31249d3bc91SRichard Lowe         }
31349d3bc91SRichard Lowe 
31449d3bc91SRichard Lowe         info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg,
315*07dc1947SRichard Lowe                          curr_attr_form,
316*07dc1947SRichard Lowe                          die->di_cu_context->cc_address_size,
317*07dc1947SRichard Lowe                          info_ptr,
318*07dc1947SRichard Lowe                          die->di_cu_context->cc_length_size);
31949d3bc91SRichard Lowe     } while (curr_attr != 0 || curr_attr_form != 0);
32049d3bc91SRichard Lowe 
32149d3bc91SRichard Lowe     *attr_form = 1;
32249d3bc91SRichard Lowe     return (NULL);
32349d3bc91SRichard Lowe }
32449d3bc91SRichard Lowe 
32549d3bc91SRichard Lowe 
32649d3bc91SRichard Lowe int
dwarf_diename(Dwarf_Die die,char ** ret_name,Dwarf_Error * error)32749d3bc91SRichard Lowe dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error)
32849d3bc91SRichard Lowe {
329*07dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
330*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
331*07dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
332*07dc1947SRichard Lowe     Dwarf_Unsigned string_offset = 0;
333*07dc1947SRichard Lowe     int res = DW_DLV_ERROR;
33449d3bc91SRichard Lowe 
335*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
33649d3bc91SRichard Lowe 
33749d3bc91SRichard Lowe     info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form);
33849d3bc91SRichard Lowe     if (info_ptr == NULL) {
33949d3bc91SRichard Lowe         if (attr_form == 0) {
34049d3bc91SRichard Lowe             _dwarf_error(die->di_cu_context->cc_dbg, error,
34149d3bc91SRichard Lowe                          DW_DLE_DIE_BAD);
34249d3bc91SRichard Lowe             return (DW_DLV_ERROR);
34349d3bc91SRichard Lowe         }
34449d3bc91SRichard Lowe         return DW_DLV_NO_ENTRY;
34549d3bc91SRichard Lowe     }
34649d3bc91SRichard Lowe 
34749d3bc91SRichard Lowe     if (attr_form == DW_FORM_string) {
34849d3bc91SRichard Lowe         *ret_name = (char *) (info_ptr);
34949d3bc91SRichard Lowe         return DW_DLV_OK;
35049d3bc91SRichard Lowe     }
35149d3bc91SRichard Lowe 
35249d3bc91SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
35349d3bc91SRichard Lowe     if (attr_form != DW_FORM_strp) {
35449d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
35549d3bc91SRichard Lowe         return (DW_DLV_ERROR);
35649d3bc91SRichard Lowe     }
35749d3bc91SRichard Lowe 
35849d3bc91SRichard Lowe     READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned,
35949d3bc91SRichard Lowe         info_ptr, die->di_cu_context->cc_length_size);
36049d3bc91SRichard Lowe 
361*07dc1947SRichard Lowe     if (string_offset >= dbg->de_debug_str.dss_size) {
36249d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD);
36349d3bc91SRichard Lowe         return (DW_DLV_ERROR);
36449d3bc91SRichard Lowe     }
36549d3bc91SRichard Lowe 
366*07dc1947SRichard Lowe     res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
36749d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
36849d3bc91SRichard Lowe         return res;
36949d3bc91SRichard Lowe     }
37049d3bc91SRichard Lowe 
371*07dc1947SRichard Lowe     *ret_name = (char *) (dbg->de_debug_str.dss_data + string_offset);
37249d3bc91SRichard Lowe     return DW_DLV_OK;
37349d3bc91SRichard Lowe }
37449d3bc91SRichard Lowe 
37549d3bc91SRichard Lowe 
37649d3bc91SRichard Lowe int
dwarf_hasattr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Bool * return_bool,Dwarf_Error * error)37749d3bc91SRichard Lowe dwarf_hasattr(Dwarf_Die die,
37849d3bc91SRichard Lowe     Dwarf_Half attr,
37949d3bc91SRichard Lowe     Dwarf_Bool * return_bool, Dwarf_Error * error)
38049d3bc91SRichard Lowe {
381*07dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
38249d3bc91SRichard Lowe 
383*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
38449d3bc91SRichard Lowe 
38549d3bc91SRichard Lowe     if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) {
38649d3bc91SRichard Lowe         if (attr_form == 0) {
38749d3bc91SRichard Lowe             _dwarf_error(die->di_cu_context->cc_dbg, error,
38849d3bc91SRichard Lowe                 DW_DLE_DIE_BAD);
38949d3bc91SRichard Lowe             return (DW_DLV_ERROR);
39049d3bc91SRichard Lowe         }
39149d3bc91SRichard Lowe         *return_bool = false;
39249d3bc91SRichard Lowe         return DW_DLV_OK;
39349d3bc91SRichard Lowe     }
39449d3bc91SRichard Lowe 
39549d3bc91SRichard Lowe     *return_bool = (true);
39649d3bc91SRichard Lowe     return DW_DLV_OK;
39749d3bc91SRichard Lowe }
39849d3bc91SRichard Lowe 
39949d3bc91SRichard Lowe 
40049d3bc91SRichard Lowe int
dwarf_attr(Dwarf_Die die,Dwarf_Half attr,Dwarf_Attribute * ret_attr,Dwarf_Error * error)40149d3bc91SRichard Lowe dwarf_attr(Dwarf_Die die,
40249d3bc91SRichard Lowe     Dwarf_Half attr,
40349d3bc91SRichard Lowe     Dwarf_Attribute * ret_attr, Dwarf_Error * error)
40449d3bc91SRichard Lowe {
405*07dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
406*07dc1947SRichard Lowe     Dwarf_Attribute attrib = 0;
407*07dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
408*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
40949d3bc91SRichard Lowe 
410*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
41149d3bc91SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
41249d3bc91SRichard Lowe 
41349d3bc91SRichard Lowe     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
41449d3bc91SRichard Lowe     if (info_ptr == NULL) {
41549d3bc91SRichard Lowe         if (attr_form == 0) {
41649d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
41749d3bc91SRichard Lowe             return (DW_DLV_ERROR);
41849d3bc91SRichard Lowe         }
41949d3bc91SRichard Lowe         return DW_DLV_NO_ENTRY;
42049d3bc91SRichard Lowe     }
42149d3bc91SRichard Lowe 
42249d3bc91SRichard Lowe     attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
42349d3bc91SRichard Lowe     if (attrib == NULL) {
42449d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
42549d3bc91SRichard Lowe         return (DW_DLV_ERROR);
42649d3bc91SRichard Lowe     }
42749d3bc91SRichard Lowe 
42849d3bc91SRichard Lowe     attrib->ar_attribute = attr;
42949d3bc91SRichard Lowe     attrib->ar_attribute_form = attr_form;
43049d3bc91SRichard Lowe     attrib->ar_attribute_form_direct = attr_form;
43149d3bc91SRichard Lowe     attrib->ar_cu_context = die->di_cu_context;
43249d3bc91SRichard Lowe     attrib->ar_debug_info_ptr = info_ptr;
43349d3bc91SRichard Lowe     *ret_attr = (attrib);
43449d3bc91SRichard Lowe     return DW_DLV_OK;
43549d3bc91SRichard Lowe }
43649d3bc91SRichard Lowe 
43749d3bc91SRichard Lowe 
43849d3bc91SRichard Lowe int
dwarf_lowpc(Dwarf_Die die,Dwarf_Addr * return_addr,Dwarf_Error * error)43949d3bc91SRichard Lowe dwarf_lowpc(Dwarf_Die die,
44049d3bc91SRichard Lowe     Dwarf_Addr * return_addr, Dwarf_Error * error)
44149d3bc91SRichard Lowe {
442*07dc1947SRichard Lowe     Dwarf_Addr ret_addr = 0;
443*07dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
444*07dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
445*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
446*07dc1947SRichard Lowe     Dwarf_Half address_size = 0;
44749d3bc91SRichard Lowe 
448*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
44949d3bc91SRichard Lowe 
45049d3bc91SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
451*07dc1947SRichard Lowe     address_size = die->di_cu_context->cc_address_size;
45249d3bc91SRichard Lowe     info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form);
45349d3bc91SRichard Lowe     if ((info_ptr == NULL && attr_form == 0) ||
45449d3bc91SRichard Lowe         (info_ptr != NULL && attr_form != DW_FORM_addr)) {
45549d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
45649d3bc91SRichard Lowe         return (DW_DLV_ERROR);
45749d3bc91SRichard Lowe     }
45849d3bc91SRichard Lowe     if (info_ptr == NULL) {
45949d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
46049d3bc91SRichard Lowe     }
46149d3bc91SRichard Lowe 
46249d3bc91SRichard Lowe 
46349d3bc91SRichard Lowe     READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
464*07dc1947SRichard Lowe                    info_ptr, address_size);
46549d3bc91SRichard Lowe 
46649d3bc91SRichard Lowe     *return_addr = ret_addr;
46749d3bc91SRichard Lowe     return (DW_DLV_OK);
46849d3bc91SRichard Lowe }
46949d3bc91SRichard Lowe 
47049d3bc91SRichard Lowe 
47149d3bc91SRichard Lowe int
dwarf_highpc(Dwarf_Die die,Dwarf_Addr * return_addr,Dwarf_Error * error)47249d3bc91SRichard Lowe dwarf_highpc(Dwarf_Die die,
47349d3bc91SRichard Lowe     Dwarf_Addr * return_addr, Dwarf_Error * error)
47449d3bc91SRichard Lowe {
475*07dc1947SRichard Lowe     Dwarf_Addr ret_addr = 0;
476*07dc1947SRichard Lowe     Dwarf_Byte_Ptr info_ptr = 0;
477*07dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
478*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
479*07dc1947SRichard Lowe     Dwarf_Half address_size = 0;
48049d3bc91SRichard Lowe 
481*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
48249d3bc91SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
483*07dc1947SRichard Lowe     address_size = die->di_cu_context->cc_address_size;
48449d3bc91SRichard Lowe     info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form);
48549d3bc91SRichard Lowe     if ((info_ptr == NULL && attr_form == 0) ||
48649d3bc91SRichard Lowe         (info_ptr != NULL && attr_form != DW_FORM_addr)) {
48749d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
48849d3bc91SRichard Lowe         return (DW_DLV_ERROR);
48949d3bc91SRichard Lowe     }
49049d3bc91SRichard Lowe     if (info_ptr == NULL) {
49149d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
49249d3bc91SRichard Lowe     }
49349d3bc91SRichard Lowe 
49449d3bc91SRichard Lowe     READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
495*07dc1947SRichard Lowe                    info_ptr, address_size);
49649d3bc91SRichard Lowe 
49749d3bc91SRichard Lowe     *return_addr = ret_addr;
49849d3bc91SRichard Lowe     return (DW_DLV_OK);
49949d3bc91SRichard Lowe }
50049d3bc91SRichard Lowe 
50149d3bc91SRichard Lowe 
50249d3bc91SRichard Lowe /*
50349d3bc91SRichard Lowe     Takes a die, an attribute attr, and checks if attr
50449d3bc91SRichard Lowe     occurs in die.  Attr is required to be an attribute
50549d3bc91SRichard Lowe     whose form is in the "constant" class.  If attr occurs
50649d3bc91SRichard Lowe     in die, the value is returned.
50749d3bc91SRichard Lowe   Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as
50849d3bc91SRichard Lowe     appropriate. Sets the value thru the pointer return_val.
50949d3bc91SRichard Lowe     This function is meant to do all the
51049d3bc91SRichard Lowe     processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset,
51149d3bc91SRichard Lowe     and dwarf_srclang.
51249d3bc91SRichard Lowe */
51349d3bc91SRichard Lowe static int
_dwarf_die_attr_unsigned_constant(Dwarf_Die die,Dwarf_Half attr,Dwarf_Unsigned * return_val,Dwarf_Error * error)51449d3bc91SRichard Lowe _dwarf_die_attr_unsigned_constant(Dwarf_Die die,
51549d3bc91SRichard Lowe     Dwarf_Half attr,
51649d3bc91SRichard Lowe     Dwarf_Unsigned * return_val,
51749d3bc91SRichard Lowe     Dwarf_Error * error)
51849d3bc91SRichard Lowe {
51949d3bc91SRichard Lowe     Dwarf_Byte_Ptr info_ptr;
52049d3bc91SRichard Lowe     Dwarf_Half attr_form;
52149d3bc91SRichard Lowe     Dwarf_Unsigned ret_value;
52249d3bc91SRichard Lowe     Dwarf_Debug dbg;
52349d3bc91SRichard Lowe 
524*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
52549d3bc91SRichard Lowe 
52649d3bc91SRichard Lowe     dbg = die->di_cu_context->cc_dbg;
52749d3bc91SRichard Lowe     info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
52849d3bc91SRichard Lowe     if (info_ptr != NULL) {
52949d3bc91SRichard Lowe         switch (attr_form) {
53049d3bc91SRichard Lowe 
53149d3bc91SRichard Lowe         case DW_FORM_data1:
53249d3bc91SRichard Lowe             *return_val = (*(Dwarf_Small *) info_ptr);
53349d3bc91SRichard Lowe             return (DW_DLV_OK);
53449d3bc91SRichard Lowe 
53549d3bc91SRichard Lowe         case DW_FORM_data2:
53649d3bc91SRichard Lowe             READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
53749d3bc91SRichard Lowe                            info_ptr, sizeof(Dwarf_Shalf));
53849d3bc91SRichard Lowe             *return_val = ret_value;
53949d3bc91SRichard Lowe             return (DW_DLV_OK);
54049d3bc91SRichard Lowe 
54149d3bc91SRichard Lowe         case DW_FORM_data4:
54249d3bc91SRichard Lowe             READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
54349d3bc91SRichard Lowe                            info_ptr, sizeof(Dwarf_sfixed));
54449d3bc91SRichard Lowe             *return_val = ret_value;
54549d3bc91SRichard Lowe             return (DW_DLV_OK);
54649d3bc91SRichard Lowe 
54749d3bc91SRichard Lowe         case DW_FORM_data8:
54849d3bc91SRichard Lowe             READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
54949d3bc91SRichard Lowe                            info_ptr, sizeof(Dwarf_Unsigned));
55049d3bc91SRichard Lowe             *return_val = ret_value;
55149d3bc91SRichard Lowe             return (DW_DLV_OK);
55249d3bc91SRichard Lowe 
55349d3bc91SRichard Lowe         case DW_FORM_udata:
55449d3bc91SRichard Lowe             *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
55549d3bc91SRichard Lowe             return (DW_DLV_OK);
55649d3bc91SRichard Lowe 
55749d3bc91SRichard Lowe         default:
55849d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
55949d3bc91SRichard Lowe             return (DW_DLV_ERROR);
56049d3bc91SRichard Lowe         }
56149d3bc91SRichard Lowe     }
56249d3bc91SRichard Lowe     if (attr_form == 0) {
56349d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
56449d3bc91SRichard Lowe         return (DW_DLV_ERROR);
56549d3bc91SRichard Lowe     }
56649d3bc91SRichard Lowe     return DW_DLV_NO_ENTRY;
56749d3bc91SRichard Lowe }
56849d3bc91SRichard Lowe 
56949d3bc91SRichard Lowe 
57049d3bc91SRichard Lowe int
dwarf_bytesize(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)57149d3bc91SRichard Lowe dwarf_bytesize(Dwarf_Die die,
57249d3bc91SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
57349d3bc91SRichard Lowe {
574*07dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
575*07dc1947SRichard Lowe     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size,
576*07dc1947SRichard Lowe         &luns, error);
57749d3bc91SRichard Lowe     *ret_size = luns;
57849d3bc91SRichard Lowe     return res;
57949d3bc91SRichard Lowe }
58049d3bc91SRichard Lowe 
58149d3bc91SRichard Lowe 
58249d3bc91SRichard Lowe int
dwarf_bitsize(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)58349d3bc91SRichard Lowe dwarf_bitsize(Dwarf_Die die,
58449d3bc91SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
58549d3bc91SRichard Lowe {
586*07dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
587*07dc1947SRichard Lowe     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size,
588*07dc1947SRichard Lowe         &luns, error);
58949d3bc91SRichard Lowe     *ret_size = luns;
59049d3bc91SRichard Lowe     return res;
59149d3bc91SRichard Lowe }
59249d3bc91SRichard Lowe 
59349d3bc91SRichard Lowe 
59449d3bc91SRichard Lowe int
dwarf_bitoffset(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)59549d3bc91SRichard Lowe dwarf_bitoffset(Dwarf_Die die,
59649d3bc91SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
59749d3bc91SRichard Lowe {
598*07dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
599*07dc1947SRichard Lowe     int res = _dwarf_die_attr_unsigned_constant(die,
600*07dc1947SRichard Lowe         DW_AT_bit_offset, &luns, error);
60149d3bc91SRichard Lowe     *ret_size = luns;
60249d3bc91SRichard Lowe     return res;
60349d3bc91SRichard Lowe }
60449d3bc91SRichard Lowe 
60549d3bc91SRichard Lowe 
60649d3bc91SRichard Lowe /* Refer section 3.1, page 21 in Dwarf Definition. */
60749d3bc91SRichard Lowe int
dwarf_srclang(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)60849d3bc91SRichard Lowe dwarf_srclang(Dwarf_Die die,
60949d3bc91SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
61049d3bc91SRichard Lowe {
611*07dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
612*07dc1947SRichard Lowe     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_language,
613*07dc1947SRichard Lowe         &luns, error);
61449d3bc91SRichard Lowe     *ret_size = luns;
61549d3bc91SRichard Lowe     return res;
61649d3bc91SRichard Lowe }
61749d3bc91SRichard Lowe 
61849d3bc91SRichard Lowe 
61949d3bc91SRichard Lowe /* Refer section 5.4, page 37 in Dwarf Definition. */
62049d3bc91SRichard Lowe int
dwarf_arrayorder(Dwarf_Die die,Dwarf_Unsigned * ret_size,Dwarf_Error * error)62149d3bc91SRichard Lowe dwarf_arrayorder(Dwarf_Die die,
62249d3bc91SRichard Lowe     Dwarf_Unsigned * ret_size, Dwarf_Error * error)
62349d3bc91SRichard Lowe {
624*07dc1947SRichard Lowe     Dwarf_Unsigned luns = 0;
625*07dc1947SRichard Lowe     int res = _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering,
626*07dc1947SRichard Lowe         &luns, error);
62749d3bc91SRichard Lowe     *ret_size = luns;
62849d3bc91SRichard Lowe     return res;
62949d3bc91SRichard Lowe }
63049d3bc91SRichard Lowe 
63149d3bc91SRichard Lowe /*
63249d3bc91SRichard Lowe         Return DW_DLV_OK if ok
63349d3bc91SRichard Lowe         DW_DLV_ERROR if failure.
63449d3bc91SRichard Lowe 
63549d3bc91SRichard Lowe         If the die and the attr are not related the result is
63649d3bc91SRichard Lowe         meaningless.
63749d3bc91SRichard Lowe */
63849d3bc91SRichard Lowe int
dwarf_attr_offset(Dwarf_Die die,Dwarf_Attribute attr,Dwarf_Off * offset,Dwarf_Error * error)639*07dc1947SRichard Lowe dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr,
640*07dc1947SRichard Lowe     Dwarf_Off * offset /* return offset thru this ptr */,
64149d3bc91SRichard Lowe     Dwarf_Error * error)
64249d3bc91SRichard Lowe {
643*07dc1947SRichard Lowe     Dwarf_Off attroff = 0;
64449d3bc91SRichard Lowe 
645*07dc1947SRichard Lowe     CHECK_DIE(die, DW_DLV_ERROR);
64649d3bc91SRichard Lowe 
64749d3bc91SRichard Lowe     attroff = (attr->ar_debug_info_ptr -
648*07dc1947SRichard Lowe                die->di_cu_context->cc_dbg->de_debug_info.dss_data);
64949d3bc91SRichard Lowe     *offset = attroff;
65049d3bc91SRichard Lowe     return DW_DLV_OK;
65149d3bc91SRichard Lowe }
652*07dc1947SRichard Lowe 
653*07dc1947SRichard Lowe int
dwarf_die_abbrev_code(Dwarf_Die die)654*07dc1947SRichard Lowe dwarf_die_abbrev_code(Dwarf_Die die)
655*07dc1947SRichard Lowe {
656*07dc1947SRichard Lowe     return die->di_abbrev_code;
657*07dc1947SRichard Lowe }
658*07dc1947SRichard Lowe 
659*07dc1947SRichard Lowe /* Helper function for finding form class. */
660*07dc1947SRichard Lowe static enum Dwarf_Form_Class
dw_get_special_offset(Dwarf_Half attrnum)661*07dc1947SRichard Lowe dw_get_special_offset(Dwarf_Half attrnum)
662*07dc1947SRichard Lowe {
663*07dc1947SRichard Lowe     switch(attrnum) {
664*07dc1947SRichard Lowe     case DW_AT_stmt_list:
665*07dc1947SRichard Lowe              return DW_FORM_CLASS_LINEPTR;
666*07dc1947SRichard Lowe     case DW_AT_macro_info:
667*07dc1947SRichard Lowe              return DW_FORM_CLASS_MACPTR;
668*07dc1947SRichard Lowe     case DW_AT_ranges:
669*07dc1947SRichard Lowe              return DW_FORM_CLASS_RANGELISTPTR;
670*07dc1947SRichard Lowe     case DW_AT_location:
671*07dc1947SRichard Lowe     case DW_AT_string_length:
672*07dc1947SRichard Lowe     case DW_AT_return_addr:
673*07dc1947SRichard Lowe     case DW_AT_data_member_location:
674*07dc1947SRichard Lowe     case DW_AT_frame_base:
675*07dc1947SRichard Lowe     case DW_AT_segment:
676*07dc1947SRichard Lowe     case DW_AT_static_link:
677*07dc1947SRichard Lowe     case DW_AT_use_location:
678*07dc1947SRichard Lowe     case DW_AT_vtable_elem_location:
679*07dc1947SRichard Lowe              return DW_FORM_CLASS_LOCLISTPTR;
680*07dc1947SRichard Lowe     case DW_AT_sibling:
681*07dc1947SRichard Lowe     case DW_AT_byte_size :
682*07dc1947SRichard Lowe     case DW_AT_bit_offset :
683*07dc1947SRichard Lowe     case DW_AT_bit_size :
684*07dc1947SRichard Lowe     case DW_AT_discr :
685*07dc1947SRichard Lowe     case DW_AT_import :
686*07dc1947SRichard Lowe     case DW_AT_common_reference:
687*07dc1947SRichard Lowe     case DW_AT_containing_type:
688*07dc1947SRichard Lowe     case DW_AT_default_value:
689*07dc1947SRichard Lowe     case DW_AT_lower_bound:
690*07dc1947SRichard Lowe     case DW_AT_bit_stride:
691*07dc1947SRichard Lowe     case DW_AT_upper_bound:
692*07dc1947SRichard Lowe     case DW_AT_abstract_origin:
693*07dc1947SRichard Lowe     case DW_AT_base_types:
694*07dc1947SRichard Lowe     case DW_AT_count:
695*07dc1947SRichard Lowe     case DW_AT_friend:
696*07dc1947SRichard Lowe     case DW_AT_namelist_item:
697*07dc1947SRichard Lowe     case DW_AT_priority:
698*07dc1947SRichard Lowe     case DW_AT_specification:
699*07dc1947SRichard Lowe     case DW_AT_type:
700*07dc1947SRichard Lowe     case DW_AT_allocated:
701*07dc1947SRichard Lowe     case DW_AT_associated:
702*07dc1947SRichard Lowe     case DW_AT_byte_stride:
703*07dc1947SRichard Lowe     case DW_AT_extension:
704*07dc1947SRichard Lowe     case DW_AT_trampoline:
705*07dc1947SRichard Lowe     case DW_AT_small:
706*07dc1947SRichard Lowe     case DW_AT_object_pointer:
707*07dc1947SRichard Lowe     case DW_AT_signature:
708*07dc1947SRichard Lowe                 return DW_FORM_CLASS_REFERENCE;
709*07dc1947SRichard Lowe     case DW_AT_MIPS_fde: /* SGI/IRIX extension */
710*07dc1947SRichard Lowe                 return DW_FORM_CLASS_FRAMEPTR;
711*07dc1947SRichard Lowe     }
712*07dc1947SRichard Lowe     return DW_FORM_CLASS_UNKNOWN;
713*07dc1947SRichard Lowe }
714*07dc1947SRichard Lowe 
715*07dc1947SRichard Lowe /* It takes 4 pieces of data (including the FORM)
716*07dc1947SRichard Lowe    to accurately determine the form 'class' as documented
717*07dc1947SRichard Lowe    in the DWARF spec. This is per DWARF4, but will work
718*07dc1947SRichard Lowe    for DWARF2 or 3 as well.  */
dwarf_get_form_class(Dwarf_Half dwversion,Dwarf_Half attrnum,Dwarf_Half offset_size,Dwarf_Half form)719*07dc1947SRichard Lowe enum Dwarf_Form_Class dwarf_get_form_class(
720*07dc1947SRichard Lowe     Dwarf_Half dwversion,
721*07dc1947SRichard Lowe     Dwarf_Half attrnum,
722*07dc1947SRichard Lowe     Dwarf_Half offset_size,
723*07dc1947SRichard Lowe     Dwarf_Half form)
724*07dc1947SRichard Lowe {
725*07dc1947SRichard Lowe     switch(form) {
726*07dc1947SRichard Lowe     case  DW_FORM_addr: return DW_FORM_CLASS_ADDRESS;
727*07dc1947SRichard Lowe 
728*07dc1947SRichard Lowe     case  DW_FORM_data2:  return DW_FORM_CLASS_CONSTANT;
729*07dc1947SRichard Lowe 
730*07dc1947SRichard Lowe     case  DW_FORM_data4:
731*07dc1947SRichard Lowe         if(dwversion <= 3 && offset_size == 4) {
732*07dc1947SRichard Lowe             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
733*07dc1947SRichard Lowe             if(class != DW_FORM_CLASS_UNKNOWN) {
734*07dc1947SRichard Lowe                 return class;
735*07dc1947SRichard Lowe             }
736*07dc1947SRichard Lowe         }
737*07dc1947SRichard Lowe         return DW_FORM_CLASS_CONSTANT;
738*07dc1947SRichard Lowe     case  DW_FORM_data8:
739*07dc1947SRichard Lowe         if(dwversion <= 3 && offset_size == 8) {
740*07dc1947SRichard Lowe             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
741*07dc1947SRichard Lowe             if(class != DW_FORM_CLASS_UNKNOWN) {
742*07dc1947SRichard Lowe                 return class;
743*07dc1947SRichard Lowe             }
744*07dc1947SRichard Lowe         }
745*07dc1947SRichard Lowe         return DW_FORM_CLASS_CONSTANT;
746*07dc1947SRichard Lowe 
747*07dc1947SRichard Lowe     case  DW_FORM_sec_offset:
748*07dc1947SRichard Lowe         {
749*07dc1947SRichard Lowe             enum Dwarf_Form_Class class = dw_get_special_offset(attrnum);
750*07dc1947SRichard Lowe             if(class != DW_FORM_CLASS_UNKNOWN) {
751*07dc1947SRichard Lowe                 return class;
752*07dc1947SRichard Lowe             }
753*07dc1947SRichard Lowe         }
754*07dc1947SRichard Lowe         /* We do not know what this is. */
755*07dc1947SRichard Lowe         break;
756*07dc1947SRichard Lowe 
757*07dc1947SRichard Lowe     case  DW_FORM_string: return DW_FORM_CLASS_STRING;
758*07dc1947SRichard Lowe     case  DW_FORM_strp:   return DW_FORM_CLASS_STRING;
759*07dc1947SRichard Lowe 
760*07dc1947SRichard Lowe     case  DW_FORM_block:  return DW_FORM_CLASS_BLOCK;
761*07dc1947SRichard Lowe     case  DW_FORM_block1: return DW_FORM_CLASS_BLOCK;
762*07dc1947SRichard Lowe     case  DW_FORM_block2: return DW_FORM_CLASS_BLOCK;
763*07dc1947SRichard Lowe     case  DW_FORM_block4: return DW_FORM_CLASS_BLOCK;
764*07dc1947SRichard Lowe 
765*07dc1947SRichard Lowe     case  DW_FORM_data1:  return DW_FORM_CLASS_CONSTANT;
766*07dc1947SRichard Lowe     case  DW_FORM_sdata:  return DW_FORM_CLASS_CONSTANT;
767*07dc1947SRichard Lowe     case  DW_FORM_udata:  return DW_FORM_CLASS_CONSTANT;
768*07dc1947SRichard Lowe 
769*07dc1947SRichard Lowe     case  DW_FORM_ref_addr:    return DW_FORM_CLASS_REFERENCE;
770*07dc1947SRichard Lowe     case  DW_FORM_ref1:        return DW_FORM_CLASS_REFERENCE;
771*07dc1947SRichard Lowe     case  DW_FORM_ref2:        return DW_FORM_CLASS_REFERENCE;
772*07dc1947SRichard Lowe     case  DW_FORM_ref4:        return DW_FORM_CLASS_REFERENCE;
773*07dc1947SRichard Lowe     case  DW_FORM_ref8:        return DW_FORM_CLASS_REFERENCE;
774*07dc1947SRichard Lowe     case  DW_FORM_ref_udata:   return DW_FORM_CLASS_REFERENCE;
775*07dc1947SRichard Lowe     case  DW_FORM_ref_sig8:    return DW_FORM_CLASS_REFERENCE;
776*07dc1947SRichard Lowe 
777*07dc1947SRichard Lowe     case  DW_FORM_exprloc:      return DW_FORM_CLASS_EXPRLOC;
778*07dc1947SRichard Lowe 
779*07dc1947SRichard Lowe     case  DW_FORM_flag:         return DW_FORM_CLASS_FLAG;
780*07dc1947SRichard Lowe     case  DW_FORM_flag_present: return DW_FORM_CLASS_FLAG;
781*07dc1947SRichard Lowe 
782*07dc1947SRichard Lowe 
783*07dc1947SRichard Lowe     case  DW_FORM_indirect:
784*07dc1947SRichard Lowe     default:
785*07dc1947SRichard Lowe         break;
786*07dc1947SRichard Lowe     };
787*07dc1947SRichard Lowe     return DW_FORM_CLASS_UNKNOWN;
788*07dc1947SRichard Lowe }
789*07dc1947SRichard Lowe 
790