1 /* 2 3 Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. 4 Portions Copyright (C) 2009-2010 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 = 0; 58 Dwarf_Small *abbrev_section_end = 0; 59 Dwarf_Half attr = 0; 60 Dwarf_Half attr_form = 0; 61 Dwarf_Abbrev ret_abbrev = 0; 62 Dwarf_Unsigned labbr_count = 0; 63 Dwarf_Unsigned utmp = 0; 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.dss_data == 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.dss_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.dss_data + offset; 103 abbrev_section_end = 104 dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_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.dss_data - 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 /* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be 165 over 16 bits. */ 166 int 167 dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, 168 Dwarf_Half * returned_tag, Dwarf_Error * error) 169 { 170 if (abbrev == NULL) { 171 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 172 return (DW_DLV_ERROR); 173 } 174 175 *returned_tag = abbrev->ab_tag; 176 return (DW_DLV_OK); 177 } 178 179 180 int 181 dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, 182 Dwarf_Signed * returned_flag, 183 Dwarf_Error * error) 184 { 185 if (abbrev == NULL) { 186 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 187 return (DW_DLV_ERROR); 188 } 189 190 *returned_flag = abbrev->ab_has_child; 191 return (DW_DLV_OK); 192 } 193 194 195 int 196 dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, 197 Dwarf_Signed index, 198 Dwarf_Half * returned_attr_num, 199 Dwarf_Signed * form, 200 Dwarf_Off * offset, Dwarf_Error * error) 201 { 202 Dwarf_Byte_Ptr abbrev_ptr = 0; 203 Dwarf_Byte_Ptr abbrev_end = 0; 204 Dwarf_Byte_Ptr mark_abbrev_ptr = 0; 205 Dwarf_Half attr = 0; 206 Dwarf_Half attr_form = 0; 207 208 if (index < 0) 209 return (DW_DLV_NO_ENTRY); 210 211 if (abbrev == NULL) { 212 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 213 return (DW_DLV_ERROR); 214 } 215 216 if (abbrev->ab_code == 0) { 217 return (DW_DLV_NO_ENTRY); 218 } 219 220 if (abbrev->ab_dbg == NULL) { 221 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 222 return (DW_DLV_ERROR); 223 } 224 225 abbrev_ptr = abbrev->ab_abbrev_ptr; 226 abbrev_end = 227 abbrev->ab_dbg->de_debug_abbrev.dss_data + 228 abbrev->ab_dbg->de_debug_abbrev.dss_size; 229 230 for (attr = 1, attr_form = 1; 231 index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 || 232 attr_form != 0); 233 index--) { 234 Dwarf_Unsigned utmp4; 235 236 mark_abbrev_ptr = abbrev_ptr; 237 DECODE_LEB128_UWORD(abbrev_ptr, utmp4); 238 attr = (Dwarf_Half) utmp4; 239 DECODE_LEB128_UWORD(abbrev_ptr, utmp4); 240 attr_form = (Dwarf_Half) utmp4; 241 } 242 243 if (abbrev_ptr >= abbrev_end) { 244 _dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR); 245 return (DW_DLV_ERROR); 246 } 247 248 if (index >= 0) { 249 return (DW_DLV_NO_ENTRY); 250 } 251 252 if (form != NULL) 253 *form = attr_form; 254 if (offset != NULL) 255 *offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev.dss_data; 256 257 *returned_attr_num = (attr); 258 return DW_DLV_OK; 259 } 260