diff -r 1af5c1be89f8 -r 92d87f2e53c2 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.c Fri Jan 15 09:07:44 2010 +0000 @@ -0,0 +1,257 @@ +/* + + Copyright (C) 2000,2001,2004,2005 Silicon Graphics, Inc. All Rights Reserved. + Portions Copyright (C) David Anderson. All Rights Reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2.1 of the GNU Lesser General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it would be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Further, this software is distributed without any warranty that it is + free of the rightful claim of any third person regarding infringement + or the like. Any license provided herein, whether implied or + otherwise, applies only to this software file. Patent licenses, if + any, provided herein do not apply to combinations of this program with + other software, or any other product whatsoever. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, + USA. + + Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, + Mountain View, CA 94043, or: + + http://www.sgi.com + + For further information regarding this notice, see: + + http://oss.sgi.com/projects/GenInfo/NoticeExplan + +*/ +/* The address of the Free Software Foundation is + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + Boston, MA 02110-1301, USA. + SGI has moved from the above address. +*/ + + + + +#include "config.h" +#include "dwarf_incl.h" +#include +#include "dwarf_abbrev.h" + +int +dwarf_get_abbrev(Dwarf_Debug dbg, + Dwarf_Unsigned offset, + Dwarf_Abbrev * returned_abbrev, + Dwarf_Unsigned * length, + Dwarf_Unsigned * abbr_count, Dwarf_Error * error) +{ + Dwarf_Small *abbrev_ptr; + Dwarf_Small *abbrev_section_end; + Dwarf_Half attr; + Dwarf_Half attr_form; + Dwarf_Abbrev ret_abbrev; + Dwarf_Unsigned labbr_count = 0; + Dwarf_Unsigned utmp; + + + if (dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + if (dbg->de_debug_abbrev == 0) { + /* Loads abbrev section (and .debug_info as we do those + together). */ + int res = _dwarf_load_debug_info(dbg, error); + + if (res != DW_DLV_OK) { + return res; + } + } + + if (offset >= dbg->de_debug_abbrev_size) { + return (DW_DLV_NO_ENTRY); + } + + + ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1); + if (ret_abbrev == NULL) { + _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); + return (DW_DLV_ERROR); + } + ret_abbrev->ab_dbg = dbg; + if (returned_abbrev == 0 || abbr_count == 0) { + dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); + _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + + *abbr_count = 0; + if (length != NULL) + *length = 1; + + abbrev_ptr = dbg->de_debug_abbrev + offset; + abbrev_section_end = + dbg->de_debug_abbrev + dbg->de_debug_abbrev_size; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp); + ret_abbrev->ab_code = (Dwarf_Word) utmp; + if (ret_abbrev->ab_code == 0) { + *returned_abbrev = ret_abbrev; + *abbr_count = 0; + if (length) { + *length = 1; + } + return (DW_DLV_OK); + } + + DECODE_LEB128_UWORD(abbrev_ptr, utmp); + ret_abbrev->ab_tag = utmp; + ret_abbrev->ab_has_child = *(abbrev_ptr++); + ret_abbrev->ab_abbrev_ptr = abbrev_ptr; + + do { + Dwarf_Unsigned utmp2; + + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr = (Dwarf_Half) utmp2; + DECODE_LEB128_UWORD(abbrev_ptr, utmp2); + attr_form = (Dwarf_Half) utmp2; + + if (attr != 0) + (labbr_count)++; + + } while (abbrev_ptr < abbrev_section_end && + (attr != 0 || attr_form != 0)); + + if (abbrev_ptr > abbrev_section_end) { + dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); + _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); + return (DW_DLV_ERROR); + } + + if (length != NULL) + *length = abbrev_ptr - dbg->de_debug_abbrev - offset; + + *returned_abbrev = ret_abbrev; + *abbr_count = labbr_count; + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, + Dwarf_Unsigned * returned_code, + Dwarf_Error * error) +{ + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + *returned_code = abbrev->ab_code; + return (DW_DLV_OK); +} + +int +dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, + Dwarf_Half * returned_tag, Dwarf_Error * error) +{ + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + *returned_tag = abbrev->ab_tag; + return (DW_DLV_OK); +} + + +int +dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, + Dwarf_Signed * returned_flag, + Dwarf_Error * error) +{ + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + *returned_flag = abbrev->ab_has_child; + return (DW_DLV_OK); +} + + +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) +{ + Dwarf_Byte_Ptr abbrev_ptr = 0; + Dwarf_Byte_Ptr abbrev_end = 0; + Dwarf_Byte_Ptr mark_abbrev_ptr = 0; + Dwarf_Half attr = 0; + Dwarf_Half attr_form = 0; + + if (index < 0) + return (DW_DLV_NO_ENTRY); + + if (abbrev == NULL) { + _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); + return (DW_DLV_ERROR); + } + + if (abbrev->ab_code == 0) { + return (DW_DLV_NO_ENTRY); + } + + if (abbrev->ab_dbg == NULL) { + _dwarf_error(NULL, error, DW_DLE_DBG_NULL); + return (DW_DLV_ERROR); + } + + abbrev_ptr = abbrev->ab_abbrev_ptr; + abbrev_end = + abbrev->ab_dbg->de_debug_abbrev + + abbrev->ab_dbg->de_debug_abbrev_size; + + for (attr = 1, attr_form = 1; + index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 || + attr_form != 0); + index--) { + Dwarf_Unsigned utmp4; + + mark_abbrev_ptr = abbrev_ptr; + DECODE_LEB128_UWORD(abbrev_ptr, utmp4); + attr = (Dwarf_Half) utmp4; + DECODE_LEB128_UWORD(abbrev_ptr, utmp4); + attr_form = (Dwarf_Half) utmp4; + } + + if (abbrev_ptr >= abbrev_end) { + _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR); + return (DW_DLV_ERROR); + } + + if (index >= 0) { + return (DW_DLV_NO_ENTRY); + } + + if (form != NULL) + *form = attr_form; + if (offset != NULL) + *offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev; + + *returned_attr_num = (attr); + return DW_DLV_OK; +}