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