xref: /titanic_44/usr/src/tools/ctf/dwarf/common/dwarf_abbrev.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe 
3*07dc1947SRichard Lowe   Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
4*07dc1947SRichard Lowe   Portions Copyright (C) 2009-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 above address.
40*07dc1947SRichard Lowe */
41*07dc1947SRichard Lowe 
4249d3bc91SRichard 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_abbrev.h"
4949d3bc91SRichard Lowe 
5049d3bc91SRichard Lowe int
dwarf_get_abbrev(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Abbrev * returned_abbrev,Dwarf_Unsigned * length,Dwarf_Unsigned * abbr_count,Dwarf_Error * error)5149d3bc91SRichard Lowe dwarf_get_abbrev(Dwarf_Debug dbg,
5249d3bc91SRichard Lowe     Dwarf_Unsigned offset,
5349d3bc91SRichard Lowe     Dwarf_Abbrev * returned_abbrev,
5449d3bc91SRichard Lowe     Dwarf_Unsigned * length,
5549d3bc91SRichard Lowe     Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
5649d3bc91SRichard Lowe {
57*07dc1947SRichard Lowe     Dwarf_Small *abbrev_ptr = 0;
58*07dc1947SRichard Lowe     Dwarf_Small *abbrev_section_end = 0;
59*07dc1947SRichard Lowe     Dwarf_Half attr = 0;
60*07dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
61*07dc1947SRichard Lowe     Dwarf_Abbrev ret_abbrev = 0;
6249d3bc91SRichard Lowe     Dwarf_Unsigned labbr_count = 0;
63*07dc1947SRichard Lowe     Dwarf_Unsigned utmp = 0;
6449d3bc91SRichard Lowe 
6549d3bc91SRichard Lowe 
6649d3bc91SRichard Lowe     if (dbg == NULL) {
6749d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
6849d3bc91SRichard Lowe         return (DW_DLV_ERROR);
6949d3bc91SRichard Lowe     }
70*07dc1947SRichard Lowe     if (dbg->de_debug_abbrev.dss_data == 0) {
7149d3bc91SRichard Lowe         /* Loads abbrev section (and .debug_info as we do those
7249d3bc91SRichard Lowe            together). */
7349d3bc91SRichard Lowe         int res = _dwarf_load_debug_info(dbg, error);
7449d3bc91SRichard Lowe 
7549d3bc91SRichard Lowe         if (res != DW_DLV_OK) {
7649d3bc91SRichard Lowe             return res;
7749d3bc91SRichard Lowe         }
7849d3bc91SRichard Lowe     }
7949d3bc91SRichard Lowe 
80*07dc1947SRichard Lowe     if (offset >= dbg->de_debug_abbrev.dss_size) {
8149d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
8249d3bc91SRichard Lowe     }
8349d3bc91SRichard Lowe 
8449d3bc91SRichard Lowe 
8549d3bc91SRichard Lowe     ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1);
8649d3bc91SRichard Lowe     if (ret_abbrev == NULL) {
8749d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
8849d3bc91SRichard Lowe         return (DW_DLV_ERROR);
8949d3bc91SRichard Lowe     }
9049d3bc91SRichard Lowe     ret_abbrev->ab_dbg = dbg;
9149d3bc91SRichard Lowe     if (returned_abbrev == 0 || abbr_count == 0) {
92*07dc1947SRichard Lowe         dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
9349d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
9449d3bc91SRichard Lowe         return (DW_DLV_ERROR);
9549d3bc91SRichard Lowe     }
9649d3bc91SRichard Lowe 
9749d3bc91SRichard Lowe 
9849d3bc91SRichard Lowe     *abbr_count = 0;
9949d3bc91SRichard Lowe     if (length != NULL)
10049d3bc91SRichard Lowe         *length = 1;
10149d3bc91SRichard Lowe 
102*07dc1947SRichard Lowe     abbrev_ptr = dbg->de_debug_abbrev.dss_data + offset;
10349d3bc91SRichard Lowe     abbrev_section_end =
104*07dc1947SRichard Lowe         dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size;
10549d3bc91SRichard Lowe 
10649d3bc91SRichard Lowe     DECODE_LEB128_UWORD(abbrev_ptr, utmp);
10749d3bc91SRichard Lowe     ret_abbrev->ab_code = (Dwarf_Word) utmp;
10849d3bc91SRichard Lowe     if (ret_abbrev->ab_code == 0) {
10949d3bc91SRichard Lowe         *returned_abbrev = ret_abbrev;
11049d3bc91SRichard Lowe         *abbr_count = 0;
11149d3bc91SRichard Lowe         if (length) {
11249d3bc91SRichard Lowe             *length = 1;
11349d3bc91SRichard Lowe         }
11449d3bc91SRichard Lowe         return (DW_DLV_OK);
11549d3bc91SRichard Lowe     }
11649d3bc91SRichard Lowe 
11749d3bc91SRichard Lowe     DECODE_LEB128_UWORD(abbrev_ptr, utmp);
11849d3bc91SRichard Lowe     ret_abbrev->ab_tag = utmp;
11949d3bc91SRichard Lowe     ret_abbrev->ab_has_child = *(abbrev_ptr++);
12049d3bc91SRichard Lowe     ret_abbrev->ab_abbrev_ptr = abbrev_ptr;
12149d3bc91SRichard Lowe 
12249d3bc91SRichard Lowe     do {
12349d3bc91SRichard Lowe         Dwarf_Unsigned utmp2;
12449d3bc91SRichard Lowe 
125*07dc1947SRichard Lowe         DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
12649d3bc91SRichard Lowe         attr = (Dwarf_Half) utmp2;
127*07dc1947SRichard Lowe         DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
12849d3bc91SRichard Lowe         attr_form = (Dwarf_Half) utmp2;
12949d3bc91SRichard Lowe 
13049d3bc91SRichard Lowe         if (attr != 0)
13149d3bc91SRichard Lowe             (labbr_count)++;
13249d3bc91SRichard Lowe 
13349d3bc91SRichard Lowe     } while (abbrev_ptr < abbrev_section_end &&
13449d3bc91SRichard Lowe              (attr != 0 || attr_form != 0));
13549d3bc91SRichard Lowe 
13649d3bc91SRichard Lowe     if (abbrev_ptr > abbrev_section_end) {
137*07dc1947SRichard Lowe         dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
13849d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
13949d3bc91SRichard Lowe         return (DW_DLV_ERROR);
14049d3bc91SRichard Lowe     }
14149d3bc91SRichard Lowe 
14249d3bc91SRichard Lowe     if (length != NULL)
143*07dc1947SRichard Lowe         *length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset;
14449d3bc91SRichard Lowe 
14549d3bc91SRichard Lowe     *returned_abbrev = ret_abbrev;
14649d3bc91SRichard Lowe     *abbr_count = labbr_count;
14749d3bc91SRichard Lowe     return (DW_DLV_OK);
14849d3bc91SRichard Lowe }
14949d3bc91SRichard Lowe 
15049d3bc91SRichard Lowe int
dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,Dwarf_Unsigned * returned_code,Dwarf_Error * error)15149d3bc91SRichard Lowe dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
15249d3bc91SRichard Lowe     Dwarf_Unsigned * returned_code,
15349d3bc91SRichard Lowe     Dwarf_Error * error)
15449d3bc91SRichard Lowe {
15549d3bc91SRichard Lowe     if (abbrev == NULL) {
15649d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
15749d3bc91SRichard Lowe         return (DW_DLV_ERROR);
15849d3bc91SRichard Lowe     }
15949d3bc91SRichard Lowe 
16049d3bc91SRichard Lowe     *returned_code = abbrev->ab_code;
16149d3bc91SRichard Lowe     return (DW_DLV_OK);
16249d3bc91SRichard Lowe }
16349d3bc91SRichard Lowe 
164*07dc1947SRichard Lowe /* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be
165*07dc1947SRichard Lowe    over 16 bits.  */
16649d3bc91SRichard Lowe int
dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,Dwarf_Half * returned_tag,Dwarf_Error * error)16749d3bc91SRichard Lowe dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
16849d3bc91SRichard Lowe     Dwarf_Half * returned_tag, Dwarf_Error * error)
16949d3bc91SRichard Lowe {
17049d3bc91SRichard Lowe     if (abbrev == NULL) {
17149d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
17249d3bc91SRichard Lowe         return (DW_DLV_ERROR);
17349d3bc91SRichard Lowe     }
17449d3bc91SRichard Lowe 
17549d3bc91SRichard Lowe     *returned_tag = abbrev->ab_tag;
17649d3bc91SRichard Lowe     return (DW_DLV_OK);
17749d3bc91SRichard Lowe }
17849d3bc91SRichard Lowe 
17949d3bc91SRichard Lowe 
18049d3bc91SRichard Lowe int
dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,Dwarf_Signed * returned_flag,Dwarf_Error * error)18149d3bc91SRichard Lowe dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
18249d3bc91SRichard Lowe     Dwarf_Signed * returned_flag,
18349d3bc91SRichard Lowe     Dwarf_Error * error)
18449d3bc91SRichard Lowe {
18549d3bc91SRichard Lowe     if (abbrev == NULL) {
18649d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
18749d3bc91SRichard Lowe         return (DW_DLV_ERROR);
18849d3bc91SRichard Lowe     }
18949d3bc91SRichard Lowe 
19049d3bc91SRichard Lowe     *returned_flag = abbrev->ab_has_child;
19149d3bc91SRichard Lowe     return (DW_DLV_OK);
19249d3bc91SRichard Lowe }
19349d3bc91SRichard Lowe 
19449d3bc91SRichard Lowe 
19549d3bc91SRichard Lowe int
dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,Dwarf_Signed index,Dwarf_Half * returned_attr_num,Dwarf_Signed * form,Dwarf_Off * offset,Dwarf_Error * error)19649d3bc91SRichard Lowe dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,
19749d3bc91SRichard Lowe     Dwarf_Signed index,
19849d3bc91SRichard Lowe     Dwarf_Half * returned_attr_num,
19949d3bc91SRichard Lowe     Dwarf_Signed * form,
20049d3bc91SRichard Lowe     Dwarf_Off * offset, Dwarf_Error * error)
20149d3bc91SRichard Lowe {
202*07dc1947SRichard Lowe     Dwarf_Byte_Ptr abbrev_ptr = 0;
203*07dc1947SRichard Lowe     Dwarf_Byte_Ptr abbrev_end = 0;
204*07dc1947SRichard Lowe     Dwarf_Byte_Ptr mark_abbrev_ptr = 0;
205*07dc1947SRichard Lowe     Dwarf_Half attr = 0;
206*07dc1947SRichard Lowe     Dwarf_Half attr_form = 0;
20749d3bc91SRichard Lowe 
20849d3bc91SRichard Lowe     if (index < 0)
20949d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
21049d3bc91SRichard Lowe 
21149d3bc91SRichard Lowe     if (abbrev == NULL) {
21249d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
21349d3bc91SRichard Lowe         return (DW_DLV_ERROR);
21449d3bc91SRichard Lowe     }
21549d3bc91SRichard Lowe 
21649d3bc91SRichard Lowe     if (abbrev->ab_code == 0) {
21749d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
21849d3bc91SRichard Lowe     }
21949d3bc91SRichard Lowe 
22049d3bc91SRichard Lowe     if (abbrev->ab_dbg == NULL) {
22149d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
22249d3bc91SRichard Lowe         return (DW_DLV_ERROR);
22349d3bc91SRichard Lowe     }
22449d3bc91SRichard Lowe 
22549d3bc91SRichard Lowe     abbrev_ptr = abbrev->ab_abbrev_ptr;
22649d3bc91SRichard Lowe     abbrev_end =
227*07dc1947SRichard Lowe         abbrev->ab_dbg->de_debug_abbrev.dss_data +
228*07dc1947SRichard Lowe         abbrev->ab_dbg->de_debug_abbrev.dss_size;
22949d3bc91SRichard Lowe 
23049d3bc91SRichard Lowe     for (attr = 1, attr_form = 1;
23149d3bc91SRichard Lowe          index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 ||
23249d3bc91SRichard Lowe              attr_form != 0);
23349d3bc91SRichard Lowe          index--) {
23449d3bc91SRichard Lowe         Dwarf_Unsigned utmp4;
23549d3bc91SRichard Lowe 
23649d3bc91SRichard Lowe         mark_abbrev_ptr = abbrev_ptr;
237*07dc1947SRichard Lowe         DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
23849d3bc91SRichard Lowe         attr = (Dwarf_Half) utmp4;
239*07dc1947SRichard Lowe         DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
24049d3bc91SRichard Lowe         attr_form = (Dwarf_Half) utmp4;
24149d3bc91SRichard Lowe     }
24249d3bc91SRichard Lowe 
24349d3bc91SRichard Lowe     if (abbrev_ptr >= abbrev_end) {
24449d3bc91SRichard Lowe         _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
24549d3bc91SRichard Lowe         return (DW_DLV_ERROR);
24649d3bc91SRichard Lowe     }
24749d3bc91SRichard Lowe 
24849d3bc91SRichard Lowe     if (index >= 0) {
24949d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
25049d3bc91SRichard Lowe     }
25149d3bc91SRichard Lowe 
25249d3bc91SRichard Lowe     if (form != NULL)
25349d3bc91SRichard Lowe         *form = attr_form;
25449d3bc91SRichard Lowe     if (offset != NULL)
255*07dc1947SRichard Lowe         *offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev.dss_data;
25649d3bc91SRichard Lowe 
25749d3bc91SRichard Lowe     *returned_attr_num = (attr);
25849d3bc91SRichard Lowe     return DW_DLV_OK;
25949d3bc91SRichard Lowe }
260