1 /* 2 Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. 3 Portions Copyright (C) 2009-2019 David Anderson. 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., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 23 USA. 24 25 */ 26 27 #include "config.h" 28 #include <stdio.h> 29 #include "dwarf_incl.h" 30 #include "dwarf_abbrev.h" 31 #include "dwarf_alloc.h" 32 #include "dwarf_error.h" 33 #include "dwarf_util.h" 34 #include "dwarfstring.h" 35 36 #define TRUE 1 37 #define FALSE 0 38 39 /* This is used to print a .debug_abbrev section without 40 knowing about the DIEs that use the abbrevs. 41 42 dwarf_get_abbrev() and, 43 in dwarf_util.c, _dwarf_get_abbrev_for_code() 44 45 46 When we have a simple .o 47 there is at least a hope of iterating through 48 the abbrevs meaningfully without knowing 49 a CU context. 50 51 This often fails or gets incorrect info 52 because there is no guarantee the .debug_abbrev 53 section is free of garbage bytes. 54 55 In an object with multiple CU/TUs the 56 output is difficult/impossible to usefully interpret. 57 58 In a dwp (Package File) it is really impossible 59 to associate abbrevs with a CU. 60 61 */ 62 63 int 64 _dwarf_count_abbrev_entries(Dwarf_Debug dbg, 65 Dwarf_Byte_Ptr abbrev_ptr, 66 Dwarf_Byte_Ptr abbrev_section_end, 67 Dwarf_Unsigned *abbrev_count_out, 68 Dwarf_Byte_Ptr *abbrev_ptr_out, 69 Dwarf_Error *error) 70 { 71 Dwarf_Unsigned abbrev_count = 0; 72 Dwarf_Unsigned attr_name = 0; 73 Dwarf_Unsigned attr_form = 0; 74 UNUSEDARG Dwarf_Unsigned implicit_const = 0; 75 76 /* The abbreviations table ends with an entry with a single 77 byte of zero for the abbreviation code. 78 Padding bytes following that zero are allowed, but 79 here we simply stop looking past that zero abbrev. 80 81 We also stop looking if the block/section ends, 82 though the DWARF2 and later standards do not specifically 83 allow section/block end to terminate an abbreviations 84 list. */ 85 86 do { 87 DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_name, 88 dbg,error,abbrev_section_end); 89 if (attr_name > DW_AT_hi_user) { 90 _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); 91 return DW_DLV_ERROR; 92 } 93 DECODE_LEB128_UWORD_CK(abbrev_ptr, attr_form, 94 dbg,error,abbrev_section_end); 95 if (!_dwarf_valid_form_we_know(attr_form,attr_name)) { 96 dwarfstring m; 97 98 dwarfstring_constructor(&m); 99 dwarfstring_append_printf_u(&m, 100 "DW_DLE_UNKNOWN_FORM: Abbrev invalid form 0x%" 101 DW_PR_DUx,attr_form); 102 dwarfstring_append_printf_u(&m, 103 " with attribute 0x%" DW_PR_DUx,attr_name); 104 dwarfstring_append(&m," so abbreviations unusable. "); 105 _dwarf_error_string(dbg, error, DW_DLE_UNKNOWN_FORM, 106 dwarfstring_string(&m)); 107 dwarfstring_destructor(&m); 108 return DW_DLV_ERROR; 109 } 110 if (attr_form == DW_FORM_implicit_const) { 111 /* The value is here, not in a DIE. */ 112 DECODE_LEB128_SWORD_CK(abbrev_ptr, implicit_const, 113 dbg,error,abbrev_section_end); 114 } 115 abbrev_count++; 116 } while ((abbrev_ptr < abbrev_section_end) && 117 (attr_name != 0 || attr_form != 0)); 118 /* We counted one too high,we included the 0,0 */ 119 *abbrev_count_out = abbrev_count-1; 120 *abbrev_ptr_out = abbrev_ptr; 121 return DW_DLV_OK; 122 } 123 124 int 125 dwarf_get_abbrev(Dwarf_Debug dbg, 126 Dwarf_Unsigned offset, 127 Dwarf_Abbrev * returned_abbrev, 128 Dwarf_Unsigned * length, 129 Dwarf_Unsigned * abbr_count, Dwarf_Error * error) 130 { 131 Dwarf_Byte_Ptr abbrev_ptr = 0; 132 Dwarf_Byte_Ptr abbrev_ptr_out = 0; 133 Dwarf_Byte_Ptr abbrev_section_end = 0; 134 Dwarf_Abbrev ret_abbrev = 0; 135 Dwarf_Unsigned labbr_count = 0; 136 Dwarf_Unsigned utmp = 0; 137 int res = 0; 138 139 if (!dbg) { 140 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 141 return DW_DLV_ERROR; 142 } 143 if (dbg->de_debug_abbrev.dss_data == 0) { 144 /* Loads abbrev section (and .debug_info as we do those 145 together). */ 146 res = _dwarf_load_debug_info(dbg, error); 147 148 if (res != DW_DLV_OK) { 149 return res; 150 } 151 } 152 153 if (offset >= dbg->de_debug_abbrev.dss_size) { 154 return DW_DLV_NO_ENTRY; 155 } 156 ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1); 157 if (ret_abbrev == NULL) { 158 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 159 return DW_DLV_ERROR; 160 } 161 ret_abbrev->dab_dbg = dbg; 162 if (returned_abbrev == 0 || abbr_count == 0) { 163 dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); 164 _dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL); 165 return DW_DLV_ERROR; 166 } 167 168 169 *abbr_count = 0; 170 if (length) { 171 *length = 1; 172 } 173 174 175 abbrev_ptr = dbg->de_debug_abbrev.dss_data + offset; 176 abbrev_section_end = 177 dbg->de_debug_abbrev.dss_data + dbg->de_debug_abbrev.dss_size; 178 #if 0 179 DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp, 180 dbg,error,abbrev_section_end); 181 #endif 182 res = _dwarf_leb128_uword_wrapper(dbg,&abbrev_ptr, 183 abbrev_section_end,&utmp,error); 184 if (res == DW_DLV_ERROR) { 185 dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); 186 return res; 187 } 188 ret_abbrev->dab_code = utmp; 189 if (ret_abbrev->dab_code == 0) { 190 *returned_abbrev = ret_abbrev; 191 *abbr_count = 0; 192 if (length) { 193 *length = 1; 194 } 195 return DW_DLV_OK; 196 } 197 198 #if 0 199 DECODE_LEB128_UWORD_CK(abbrev_ptr, utmp, 200 dbg,error,abbrev_section_end); 201 #endif 202 res = _dwarf_leb128_uword_wrapper(dbg,&abbrev_ptr, 203 abbrev_section_end,&utmp,error); 204 if (res == DW_DLV_ERROR) { 205 dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); 206 return res; 207 } 208 if (utmp > DW_TAG_hi_user) { 209 return _dwarf_format_TAG_err_msg(dbg, 210 utmp,"DW_DLE_TAG_CORRUPT", 211 error); 212 } 213 ret_abbrev->dab_tag = utmp; 214 if (abbrev_ptr >= abbrev_section_end) { 215 dwarfstring m; 216 dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); 217 218 dwarfstring_constructor(&m); 219 dwarfstring_append_printf_u(&m, 220 "DW_DLE_ABBREV_DECODE_ERROR: Ran off the end " 221 "of the abbrev section reading tag, starting at" 222 " abbrev section offset 0x%x",offset); 223 _dwarf_error_string(dbg, error, 224 DW_DLE_ABBREV_DECODE_ERROR, 225 dwarfstring_string(&m)); 226 dwarfstring_destructor(&m); 227 return DW_DLV_ERROR; 228 } 229 ret_abbrev->dab_has_child = *(abbrev_ptr++); 230 ret_abbrev->dab_abbrev_ptr = abbrev_ptr; 231 ret_abbrev->dab_next_ptr = abbrev_ptr; 232 ret_abbrev->dab_next_index = 0; 233 res = _dwarf_count_abbrev_entries(dbg,abbrev_ptr, 234 abbrev_section_end,&labbr_count,&abbrev_ptr_out,error); 235 if (res == DW_DLV_ERROR) { 236 dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); 237 return res; 238 } 239 abbrev_ptr = abbrev_ptr_out; 240 241 /* Global section offset. */ 242 ret_abbrev->dab_goffset = offset; 243 ret_abbrev->dab_count = labbr_count; 244 if (abbrev_ptr > abbrev_section_end) { 245 dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV); 246 _dwarf_error_string(dbg, error, 247 DW_DLE_ABBREV_DECODE_ERROR, 248 "DW_DLE_ABBREV_DECODE_ERROR: Ran off the end " 249 "of the abbrev section reading abbrev_entries."); 250 _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR); 251 return DW_DLV_ERROR; 252 } 253 if (length) { 254 *length = abbrev_ptr - dbg->de_debug_abbrev.dss_data - offset; 255 } 256 *returned_abbrev = ret_abbrev; 257 *abbr_count = labbr_count; 258 return DW_DLV_OK; 259 } 260 261 int 262 dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, 263 Dwarf_Unsigned * returned_code, 264 Dwarf_Error * error) 265 { 266 if (abbrev == NULL) { 267 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 268 return DW_DLV_ERROR; 269 } 270 271 *returned_code = abbrev->dab_code; 272 return DW_DLV_OK; 273 } 274 275 /* DWARF defines DW_TAG_hi_user as 0xffff so no tag should be 276 over 16 bits. */ 277 int 278 dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, 279 Dwarf_Half * returned_tag, Dwarf_Error * error) 280 { 281 if (abbrev == NULL) { 282 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 283 return (DW_DLV_ERROR); 284 } 285 286 *returned_tag = abbrev->dab_tag; 287 return (DW_DLV_OK); 288 } 289 290 291 int 292 dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, 293 Dwarf_Signed * returned_flag, 294 Dwarf_Error * error) 295 { 296 if (abbrev == NULL) { 297 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 298 return (DW_DLV_ERROR); 299 } 300 301 *returned_flag = abbrev->dab_has_child; 302 return (DW_DLV_OK); 303 } 304 305 306 /* This does not return the implicit const, nor 307 does it return all bits of the uleb attribute 308 nor does it return all bits of the uleb form 309 value. 310 See dwarf_get_abbrev_entry_b(). 311 */ 312 313 int 314 dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, 315 Dwarf_Signed indx, 316 Dwarf_Half * returned_attr_num, 317 Dwarf_Signed * returned_form, 318 Dwarf_Off * returned_offset, 319 Dwarf_Error * error) 320 { 321 int res; 322 Dwarf_Unsigned attr = 0; 323 Dwarf_Unsigned form = 0; 324 Dwarf_Signed implicitconst = 0; 325 Dwarf_Unsigned uindex = (Dwarf_Unsigned)indx; 326 Dwarf_Bool filter_outliers = TRUE; 327 328 res = dwarf_get_abbrev_entry_b(abbrev, 329 uindex, 330 filter_outliers, 331 &attr, 332 &form, 333 &implicitconst, 334 returned_offset, 335 error); 336 if (res != DW_DLV_OK) { 337 return res; 338 } 339 /* returned_offset already set by dwarf_get_abbrev_entry_b; */ 340 if (returned_attr_num) { 341 *returned_attr_num = (Dwarf_Half)attr; 342 } 343 if (returned_form) { 344 *returned_form = (Dwarf_Signed)form; 345 } 346 return DW_DLV_OK; 347 } 348 349 /* If filter_outliers is non-zero then 350 the routine will return DW_DLV_ERROR 351 if the leb reading generates a number that 352 is so large it cannot be correct. 353 354 If filter_outliers is 0 the uleb/sleb 355 values read are returned, even if 356 the values are unreasonable. This is 357 a useful option if one wishes to 358 have callers examine the return values 359 in greater detail than the checking here 360 provides. 361 362 */ 363 int 364 dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev, 365 Dwarf_Unsigned indx, 366 Dwarf_Bool filter_outliers, 367 Dwarf_Unsigned * returned_attr_num, 368 Dwarf_Unsigned * returned_form, 369 Dwarf_Signed * returned_implicitconst, 370 Dwarf_Off * offset, 371 Dwarf_Error * error) 372 { 373 Dwarf_Byte_Ptr abbrev_ptr = 0; 374 Dwarf_Byte_Ptr abbrev_end = 0; 375 Dwarf_Byte_Ptr mark_abbrev_ptr = 0; 376 Dwarf_Unsigned attr = 0; 377 Dwarf_Unsigned form = 0; 378 Dwarf_Unsigned implicitconst = 0; 379 Dwarf_Debug dbg = 0; 380 Dwarf_Signed local_indx = (Dwarf_Signed)indx; 381 382 if (abbrev == NULL) { 383 _dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL); 384 return (DW_DLV_ERROR); 385 } 386 if (abbrev->dab_code == 0) { 387 return (DW_DLV_NO_ENTRY); 388 } 389 390 if (abbrev->dab_dbg == NULL) { 391 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 392 return (DW_DLV_ERROR); 393 } 394 dbg = abbrev->dab_dbg; 395 abbrev_ptr = abbrev->dab_abbrev_ptr; 396 abbrev_end = dbg->de_debug_abbrev.dss_data + 397 dbg->de_debug_abbrev.dss_size; 398 if ((Dwarf_Unsigned)local_indx >= abbrev->dab_next_index) { 399 /* We want a part not yet scanned , 400 so we can start closer to the desired value. */ 401 abbrev_ptr = abbrev->dab_next_ptr; 402 local_indx -= abbrev->dab_next_index; 403 } 404 405 for (attr = 1, form = 1; 406 local_indx >= 0 && abbrev_ptr < abbrev_end && 407 (attr != 0 || form != 0); 408 local_indx--) { 409 410 mark_abbrev_ptr = abbrev_ptr; 411 DECODE_LEB128_UWORD_CK(abbrev_ptr, attr,dbg, 412 error,abbrev_end); 413 if (filter_outliers && attr > DW_AT_hi_user) { 414 _dwarf_error(dbg, error,DW_DLE_ATTR_CORRUPT); 415 return DW_DLV_ERROR; 416 } 417 DECODE_LEB128_UWORD_CK(abbrev_ptr, form,dbg, 418 error,abbrev_end); 419 if (filter_outliers && 420 !_dwarf_valid_form_we_know(form,attr)) { 421 _dwarf_error(dbg, error, DW_DLE_UNKNOWN_FORM); 422 return (DW_DLV_ERROR); 423 } 424 if (form == DW_FORM_implicit_const) { 425 /* The value is here, not in a DIE. */ 426 DECODE_LEB128_SWORD_CK( abbrev_ptr, implicitconst, 427 dbg,error,abbrev_end); 428 } else { 429 implicitconst = 0; 430 } 431 } 432 433 if (abbrev_ptr >= abbrev_end) { 434 _dwarf_error_string(dbg, error, 435 DW_DLE_ABBREV_DECODE_ERROR, 436 "DW_DLE_ABBREV_DECODE_ERROR: Ran off the end " 437 "of the abbrev section reading abbrev entries.."); 438 return DW_DLV_ERROR; 439 } 440 441 if (local_indx >= 0) { 442 return DW_DLV_NO_ENTRY; 443 } 444 445 if (returned_form != NULL) { 446 *returned_form = form; 447 } 448 if (offset != NULL) { 449 *offset = mark_abbrev_ptr - dbg->de_debug_abbrev.dss_data; 450 } 451 if (returned_attr_num) { 452 *returned_attr_num = attr; 453 } 454 if (returned_implicitconst) { 455 /* Callers should only examine implict const value 456 if the form is DW_FORM_implicit_const. */ 457 *returned_implicitconst = implicitconst; 458 } 459 abbrev->dab_next_ptr = abbrev_ptr; 460 abbrev->dab_next_index = (Dwarf_Unsigned)local_indx ; 461 return DW_DLV_OK; 462 } 463 464 /* This function is not entirely safe to call. 465 The problem is that the DWARF[234] specification does not insist 466 that bytes in .debug_abbrev that are not referenced by .debug_info 467 or .debug_types need to be initialized to anything specific. 468 Any garbage bytes may cause trouble. Not all compilers/linkers 469 leave unreferenced garbage bytes in .debug_abbrev, so this may 470 work for most objects. 471 In case of error could return a bogus value, there is 472 no documented way to detect error. 473 */ 474 int 475 dwarf_get_abbrev_count(Dwarf_Debug dbg) 476 { 477 Dwarf_Abbrev ab; 478 Dwarf_Unsigned offset = 0; 479 Dwarf_Unsigned length = 0; 480 Dwarf_Unsigned attr_count = 0; 481 Dwarf_Unsigned abbrev_count = 0; 482 int abres = DW_DLV_OK; 483 Dwarf_Error err = 0; 484 485 while ((abres = dwarf_get_abbrev(dbg, offset, &ab, 486 &length, &attr_count, 487 &err)) == DW_DLV_OK) { 488 489 ++abbrev_count; 490 offset += length; 491 dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); 492 } 493 if (err) { 494 dwarf_dealloc(dbg,err,DW_DLA_ERROR); 495 err = 0; 496 } 497 return abbrev_count; 498 } 499