1 /* 2 3 Copyright (C) 2000,2001 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., 1600 Amphitheatre Pky, 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 43 int 44 dwarf_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_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL); 86 return (DW_DLV_ERROR); 87 } 88 89 90 *abbr_count = 0; 91 if (length != NULL) 92 *length = 1; 93 94 abbrev_ptr = dbg->de_debug_abbrev + offset; 95 abbrev_section_end = 96 dbg->de_debug_abbrev + dbg->de_debug_abbrev_size; 97 98 DECODE_LEB128_UWORD(abbrev_ptr, utmp); 99 ret_abbrev->ab_code = (Dwarf_Word) utmp; 100 if (ret_abbrev->ab_code == 0) { 101 *returned_abbrev = ret_abbrev; 102 *abbr_count = 0; 103 if (length) { 104 *length = 1; 105 } 106 return (DW_DLV_OK); 107 } 108 109 DECODE_LEB128_UWORD(abbrev_ptr, utmp); 110 ret_abbrev->ab_tag = utmp; 111 ret_abbrev->ab_has_child = *(abbrev_ptr++); 112 ret_abbrev->ab_abbrev_ptr = abbrev_ptr; 113 114 do { 115 Dwarf_Unsigned utmp2; 116 117 DECODE_LEB128_UWORD(abbrev_ptr, utmp2) 118 attr = (Dwarf_Half) utmp2; 119 DECODE_LEB128_UWORD(abbrev_ptr, utmp2) 120 attr_form = (Dwarf_Half) utmp2; 121 122 if (attr != 0) 123 (labbr_count)++; 124 125 } while (abbrev_ptr < abbrev_section_end && 126 (attr != 0 || attr_form != 0)); 127 128 if (abbrev_ptr > abbrev_section_end) { 129 _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); 130 return (DW_DLV_ERROR); 131 } 132 133 if (length != NULL) 134 *length = abbrev_ptr - dbg->de_debug_abbrev - offset; 135 136 *returned_abbrev = ret_abbrev; 137 *abbr_count = labbr_count; 138 return (DW_DLV_OK); 139 } 140 141 int 142 dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, 143 Dwarf_Unsigned * returned_code, 144 Dwarf_Error * error) 145 { 146 if (abbrev == NULL) { 147 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 148 return (DW_DLV_ERROR); 149 } 150 151 *returned_code = abbrev->ab_code; 152 return (DW_DLV_OK); 153 } 154 155 int 156 dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, 157 Dwarf_Half * returned_tag, Dwarf_Error * error) 158 { 159 if (abbrev == NULL) { 160 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 161 return (DW_DLV_ERROR); 162 } 163 164 *returned_tag = abbrev->ab_tag; 165 return (DW_DLV_OK); 166 } 167 168 169 int 170 dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, 171 Dwarf_Signed * returned_flag, 172 Dwarf_Error * error) 173 { 174 if (abbrev == NULL) { 175 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 176 return (DW_DLV_ERROR); 177 } 178 179 *returned_flag = abbrev->ab_has_child; 180 return (DW_DLV_OK); 181 } 182 183 184 int 185 dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, 186 Dwarf_Signed index, 187 Dwarf_Half * returned_attr_num, 188 Dwarf_Signed * form, 189 Dwarf_Off * offset, Dwarf_Error * error) 190 { 191 Dwarf_Byte_Ptr abbrev_ptr; 192 Dwarf_Byte_Ptr abbrev_end; 193 Dwarf_Byte_Ptr mark_abbrev_ptr; 194 Dwarf_Half attr; 195 Dwarf_Half attr_form; 196 197 if (index < 0) 198 return (DW_DLV_NO_ENTRY); 199 200 if (abbrev == NULL) { 201 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 202 return (DW_DLV_ERROR); 203 } 204 205 if (abbrev->ab_code == 0) { 206 return (DW_DLV_NO_ENTRY); 207 } 208 209 if (abbrev->ab_dbg == NULL) { 210 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 211 return (DW_DLV_ERROR); 212 } 213 214 abbrev_ptr = abbrev->ab_abbrev_ptr; 215 abbrev_end = 216 abbrev->ab_dbg->de_debug_abbrev + 217 abbrev->ab_dbg->de_debug_abbrev_size; 218 219 for (attr = 1, attr_form = 1; 220 index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 || 221 attr_form != 0); 222 index--) { 223 Dwarf_Unsigned utmp4; 224 225 mark_abbrev_ptr = abbrev_ptr; 226 DECODE_LEB128_UWORD(abbrev_ptr, utmp4) 227 attr = (Dwarf_Half) utmp4; 228 DECODE_LEB128_UWORD(abbrev_ptr, utmp4) 229 attr_form = (Dwarf_Half) utmp4; 230 } 231 232 if (abbrev_ptr >= abbrev_end) { 233 _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR); 234 return (DW_DLV_ERROR); 235 } 236 237 if (index >= 0) { 238 return (DW_DLV_NO_ENTRY); 239 } 240 241 if (form != NULL) 242 *form = attr_form; 243 if (offset != NULL) 244 *offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev; 245 246 *returned_attr_num = (attr); 247 return DW_DLV_OK; 248 } 249