tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2001,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
       
     4   Portions Copyright (C) David Anderson. All Rights Reserved.
       
     5 
       
     6   This program is free software; you can redistribute it and/or modify it
       
     7   under the terms of version 2.1 of the GNU Lesser General Public License 
       
     8   as published by the Free Software Foundation.
       
     9 
       
    10   This program is distributed in the hope that it would be useful, but
       
    11   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
       
    13 
       
    14   Further, this software is distributed without any warranty that it is
       
    15   free of the rightful claim of any third person regarding infringement 
       
    16   or the like.  Any license provided herein, whether implied or 
       
    17   otherwise, applies only to this software file.  Patent licenses, if
       
    18   any, provided herein do not apply to combinations of this program with 
       
    19   other software, or any other product whatsoever.  
       
    20 
       
    21   You should have received a copy of the GNU Lesser General Public 
       
    22   License along with this program; if not, write the Free Software 
       
    23   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
       
    24   USA.
       
    25 
       
    26   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    27   Mountain View, CA 94043, or:
       
    28 
       
    29   http://www.sgi.com
       
    30 
       
    31   For further information regarding this notice, see:
       
    32 
       
    33   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    34 
       
    35 */
       
    36 /* The address of the Free Software Foundation is 
       
    37    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
       
    38    Boston, MA 02110-1301, USA.
       
    39    SGI has moved from the above address.
       
    40 */
       
    41 
       
    42 
       
    43 
       
    44 
       
    45 #include "config.h"
       
    46 #include "dwarf_incl.h"
       
    47 #include <stdio.h>
       
    48 #include "dwarf_abbrev.h"
       
    49 
       
    50 int
       
    51 dwarf_get_abbrev(Dwarf_Debug dbg,
       
    52 		 Dwarf_Unsigned offset,
       
    53 		 Dwarf_Abbrev * returned_abbrev,
       
    54 		 Dwarf_Unsigned * length,
       
    55 		 Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
       
    56 {
       
    57     Dwarf_Small *abbrev_ptr;
       
    58     Dwarf_Small *abbrev_section_end;
       
    59     Dwarf_Half attr;
       
    60     Dwarf_Half attr_form;
       
    61     Dwarf_Abbrev ret_abbrev;
       
    62     Dwarf_Unsigned labbr_count = 0;
       
    63     Dwarf_Unsigned utmp;
       
    64 
       
    65 
       
    66     if (dbg == NULL) {
       
    67 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
       
    68 	return (DW_DLV_ERROR);
       
    69     }
       
    70     if (dbg->de_debug_abbrev == 0) {
       
    71 	/* Loads abbrev section (and .debug_info as we do those
       
    72 	   together). */
       
    73 	int res = _dwarf_load_debug_info(dbg, error);
       
    74 
       
    75 	if (res != DW_DLV_OK) {
       
    76 	    return res;
       
    77 	}
       
    78     }
       
    79 
       
    80     if (offset >= dbg->de_debug_abbrev_size) {
       
    81 	return (DW_DLV_NO_ENTRY);
       
    82     }
       
    83 
       
    84 
       
    85     ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1);
       
    86     if (ret_abbrev == NULL) {
       
    87 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
    88 	return (DW_DLV_ERROR);
       
    89     }
       
    90     ret_abbrev->ab_dbg = dbg;
       
    91     if (returned_abbrev == 0 || abbr_count == 0) {
       
    92 	dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
       
    93 	_dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
       
    94 	return (DW_DLV_ERROR);
       
    95     }
       
    96 
       
    97 
       
    98     *abbr_count = 0;
       
    99     if (length != NULL)
       
   100 	*length = 1;
       
   101 
       
   102     abbrev_ptr = dbg->de_debug_abbrev + offset;
       
   103     abbrev_section_end =
       
   104 	dbg->de_debug_abbrev + dbg->de_debug_abbrev_size;
       
   105 
       
   106     DECODE_LEB128_UWORD(abbrev_ptr, utmp);
       
   107     ret_abbrev->ab_code = (Dwarf_Word) utmp;
       
   108     if (ret_abbrev->ab_code == 0) {
       
   109 	*returned_abbrev = ret_abbrev;
       
   110 	*abbr_count = 0;
       
   111 	if (length) {
       
   112 	    *length = 1;
       
   113 	}
       
   114 	return (DW_DLV_OK);
       
   115     }
       
   116 
       
   117     DECODE_LEB128_UWORD(abbrev_ptr, utmp);
       
   118     ret_abbrev->ab_tag = utmp;
       
   119     ret_abbrev->ab_has_child = *(abbrev_ptr++);
       
   120     ret_abbrev->ab_abbrev_ptr = abbrev_ptr;
       
   121 
       
   122     do {
       
   123 	Dwarf_Unsigned utmp2;
       
   124 
       
   125 	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
       
   126 	attr = (Dwarf_Half) utmp2;
       
   127 	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
       
   128 	attr_form = (Dwarf_Half) utmp2;
       
   129 
       
   130 	if (attr != 0)
       
   131 	    (labbr_count)++;
       
   132 
       
   133     } while (abbrev_ptr < abbrev_section_end &&
       
   134 	     (attr != 0 || attr_form != 0));
       
   135 
       
   136     if (abbrev_ptr > abbrev_section_end) {
       
   137 	dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
       
   138 	_dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
       
   139 	return (DW_DLV_ERROR);
       
   140     }
       
   141 
       
   142     if (length != NULL)
       
   143 	*length = abbrev_ptr - dbg->de_debug_abbrev - offset;
       
   144 
       
   145     *returned_abbrev = ret_abbrev;
       
   146     *abbr_count = labbr_count;
       
   147     return (DW_DLV_OK);
       
   148 }
       
   149 
       
   150 int
       
   151 dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
       
   152 		      Dwarf_Unsigned * returned_code,
       
   153 		      Dwarf_Error * error)
       
   154 {
       
   155     if (abbrev == NULL) {
       
   156 	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
       
   157 	return (DW_DLV_ERROR);
       
   158     }
       
   159 
       
   160     *returned_code = abbrev->ab_code;
       
   161     return (DW_DLV_OK);
       
   162 }
       
   163 
       
   164 int
       
   165 dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
       
   166 		     Dwarf_Half * returned_tag, Dwarf_Error * error)
       
   167 {
       
   168     if (abbrev == NULL) {
       
   169 	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
       
   170 	return (DW_DLV_ERROR);
       
   171     }
       
   172 
       
   173     *returned_tag = abbrev->ab_tag;
       
   174     return (DW_DLV_OK);
       
   175 }
       
   176 
       
   177 
       
   178 int
       
   179 dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
       
   180 			       Dwarf_Signed * returned_flag,
       
   181 			       Dwarf_Error * error)
       
   182 {
       
   183     if (abbrev == NULL) {
       
   184 	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
       
   185 	return (DW_DLV_ERROR);
       
   186     }
       
   187 
       
   188     *returned_flag = abbrev->ab_has_child;
       
   189     return (DW_DLV_OK);
       
   190 }
       
   191 
       
   192 
       
   193 int
       
   194 dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,
       
   195 		       Dwarf_Signed index,
       
   196 		       Dwarf_Half * returned_attr_num,
       
   197 		       Dwarf_Signed * form,
       
   198 		       Dwarf_Off * offset, Dwarf_Error * error)
       
   199 {
       
   200     Dwarf_Byte_Ptr abbrev_ptr = 0;
       
   201     Dwarf_Byte_Ptr abbrev_end = 0;
       
   202     Dwarf_Byte_Ptr mark_abbrev_ptr = 0;
       
   203     Dwarf_Half attr = 0;
       
   204     Dwarf_Half attr_form = 0;
       
   205 
       
   206     if (index < 0)
       
   207 	return (DW_DLV_NO_ENTRY);
       
   208 
       
   209     if (abbrev == NULL) {
       
   210 	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
       
   211 	return (DW_DLV_ERROR);
       
   212     }
       
   213 
       
   214     if (abbrev->ab_code == 0) {
       
   215 	return (DW_DLV_NO_ENTRY);
       
   216     }
       
   217 
       
   218     if (abbrev->ab_dbg == NULL) {
       
   219 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
       
   220 	return (DW_DLV_ERROR);
       
   221     }
       
   222 
       
   223     abbrev_ptr = abbrev->ab_abbrev_ptr;
       
   224     abbrev_end =
       
   225 	abbrev->ab_dbg->de_debug_abbrev +
       
   226 	abbrev->ab_dbg->de_debug_abbrev_size;
       
   227 
       
   228     for (attr = 1, attr_form = 1;
       
   229 	 index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 ||
       
   230 						   attr_form != 0);
       
   231 	 index--) {
       
   232 	Dwarf_Unsigned utmp4;
       
   233 
       
   234 	mark_abbrev_ptr = abbrev_ptr;
       
   235 	DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
       
   236 	attr = (Dwarf_Half) utmp4;
       
   237 	DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
       
   238 	attr_form = (Dwarf_Half) utmp4;
       
   239     }
       
   240 
       
   241     if (abbrev_ptr >= abbrev_end) {
       
   242 	_dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
       
   243 	return (DW_DLV_ERROR);
       
   244     }
       
   245 
       
   246     if (index >= 0) {
       
   247 	return (DW_DLV_NO_ENTRY);
       
   248     }
       
   249 
       
   250     if (form != NULL)
       
   251 	*form = attr_form;
       
   252     if (offset != NULL)
       
   253 	*offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev;
       
   254 
       
   255     *returned_attr_num = (attr);
       
   256     return DW_DLV_OK;
       
   257 }