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