1 /* 2 3 Copyright (C) 2000, 2002 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 #include "config.h" 38 #include "dwarf_incl.h" 39 #include <stdio.h> 40 #include "dwarf_die_deliv.h" 41 42 int 43 dwarf_get_address_size(Dwarf_Debug dbg, 44 Dwarf_Half * ret_addr_size, Dwarf_Error * error) 45 { 46 Dwarf_Half address_size; 47 48 if (dbg == 0) { 49 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 50 return (DW_DLV_ERROR); 51 } 52 /* length size same as address size */ 53 address_size = dbg->de_pointer_size; 54 *ret_addr_size = address_size; 55 return DW_DLV_OK; 56 } 57 58 int 59 dwarf_dieoffset(Dwarf_Die die, 60 Dwarf_Off * ret_offset, Dwarf_Error * error) 61 { 62 CHECK_DIE(die, DW_DLV_ERROR) 63 64 * ret_offset = (die->di_debug_info_ptr - 65 die->di_cu_context->cc_dbg->de_debug_info); 66 return DW_DLV_OK; 67 } 68 69 70 /* 71 This function returns the offset of 72 the die relative to the start of its 73 compilation-unit rather than .debug_info. 74 Returns DW_DLV_ERROR on error. 75 */ 76 int 77 dwarf_die_CU_offset(Dwarf_Die die, 78 Dwarf_Off * cu_off, Dwarf_Error * error) 79 { 80 Dwarf_CU_Context cu_context; 81 82 CHECK_DIE(die, DW_DLV_ERROR) 83 cu_context = die->di_cu_context; 84 85 *cu_off = 86 (die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info - 87 cu_context->cc_debug_info_offset); 88 return DW_DLV_OK; 89 } 90 91 92 int 93 dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error) 94 { 95 CHECK_DIE(die, DW_DLV_ERROR) 96 97 98 * tag = (die->di_abbrev_list->ab_tag); 99 return DW_DLV_OK; 100 } 101 102 103 int 104 dwarf_attrlist(Dwarf_Die die, 105 Dwarf_Attribute ** attrbuf, 106 Dwarf_Signed * attrcnt, Dwarf_Error * error) 107 { 108 Dwarf_Word attr_count = 0; 109 Dwarf_Word i; 110 Dwarf_Half attr; 111 Dwarf_Half attr_form; 112 Dwarf_Byte_Ptr abbrev_ptr; 113 Dwarf_Abbrev_List abbrev_list; 114 Dwarf_Attribute new_attr; 115 Dwarf_Attribute head_attr = NULL, curr_attr; 116 Dwarf_Attribute *attr_ptr; 117 Dwarf_Debug dbg; 118 Dwarf_Byte_Ptr info_ptr; 119 120 CHECK_DIE(die, DW_DLV_ERROR) 121 dbg = die->di_cu_context->cc_dbg; 122 123 abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context, 124 die->di_abbrev_list-> 125 ab_code); 126 if (abbrev_list == NULL) { 127 _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD); 128 return (DW_DLV_ERROR); 129 } 130 abbrev_ptr = abbrev_list->ab_abbrev_ptr; 131 132 info_ptr = die->di_debug_info_ptr; 133 SKIP_LEB128_WORD(info_ptr) 134 135 do { 136 Dwarf_Unsigned utmp2; 137 138 DECODE_LEB128_UWORD(abbrev_ptr, utmp2) 139 attr = (Dwarf_Half) utmp2; 140 DECODE_LEB128_UWORD(abbrev_ptr, utmp2) 141 attr_form = (Dwarf_Half) utmp2; 142 143 if (attr != 0) { 144 new_attr = 145 (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); 146 if (new_attr == NULL) { 147 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 148 return (DW_DLV_ERROR); 149 } 150 151 new_attr->ar_attribute = attr; 152 new_attr->ar_attribute_form_direct = attr_form; 153 new_attr->ar_attribute_form = attr_form; 154 if(attr_form == DW_FORM_indirect) { 155 Dwarf_Unsigned utmp6; 156 /* DECODE_LEB128_UWORD does info_ptr update */ 157 DECODE_LEB128_UWORD(info_ptr, utmp6) 158 attr_form = (Dwarf_Half) utmp6; 159 new_attr->ar_attribute_form = attr_form; 160 } 161 new_attr->ar_cu_context = die->di_cu_context; 162 new_attr->ar_debug_info_ptr = info_ptr; 163 164 info_ptr += _dwarf_get_size_of_val(dbg, attr_form, info_ptr, 165 die->di_cu_context-> 166 cc_length_size); 167 168 if (head_attr == NULL) 169 head_attr = curr_attr = new_attr; 170 else { 171 curr_attr->ar_next = new_attr; 172 curr_attr = new_attr; 173 } 174 attr_count++; 175 } 176 } while (attr != 0 || attr_form != 0); 177 178 if (attr_count == 0) { 179 *attrbuf = NULL; 180 *attrcnt = 0; 181 return (DW_DLV_NO_ENTRY); 182 } 183 184 attr_ptr = (Dwarf_Attribute *) 185 _dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count); 186 if (attr_ptr == NULL) { 187 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 188 return (DW_DLV_ERROR); 189 } 190 191 curr_attr = head_attr; 192 for (i = 0; i < attr_count; i++) { 193 *(attr_ptr + i) = curr_attr; 194 curr_attr = curr_attr->ar_next; 195 } 196 197 *attrbuf = attr_ptr; 198 *attrcnt = attr_count; 199 return (DW_DLV_OK); 200 } 201 202 203 /* 204 This function takes a die, and an attr, and returns 205 a pointer to the start of the value of that attr in 206 the given die in the .debug_info section. The form 207 is returned in *attr_form. 208 209 Returns NULL on error, or if attr is not found. 210 However, *attr_form is 0 on error, and positive 211 otherwise. 212 */ 213 static Dwarf_Byte_Ptr 214 _dwarf_get_value_ptr(Dwarf_Die die, 215 Dwarf_Half attr, Dwarf_Half * attr_form) 216 { 217 Dwarf_Byte_Ptr abbrev_ptr; 218 Dwarf_Abbrev_List abbrev_list; 219 Dwarf_Half curr_attr; 220 Dwarf_Half curr_attr_form; 221 Dwarf_Byte_Ptr info_ptr; 222 223 abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context, 224 die->di_abbrev_list-> 225 ab_code); 226 if (abbrev_list == NULL) { 227 *attr_form = 0; 228 return (NULL); 229 } 230 abbrev_ptr = abbrev_list->ab_abbrev_ptr; 231 232 info_ptr = die->di_debug_info_ptr; 233 SKIP_LEB128_WORD(info_ptr) 234 235 do { 236 Dwarf_Unsigned utmp3; 237 238 DECODE_LEB128_UWORD(abbrev_ptr, utmp3) 239 curr_attr = (Dwarf_Half) utmp3; 240 DECODE_LEB128_UWORD(abbrev_ptr, utmp3) 241 curr_attr_form = (Dwarf_Half) utmp3; 242 if(curr_attr_form == DW_FORM_indirect) { 243 Dwarf_Unsigned utmp6; 244 245 /* DECODE_LEB128_UWORD updates info_ptr */ 246 DECODE_LEB128_UWORD(info_ptr, utmp6) 247 curr_attr_form = (Dwarf_Half) utmp6; 248 } 249 250 if (curr_attr == attr) { 251 *attr_form = curr_attr_form; 252 return (info_ptr); 253 } 254 255 info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg, 256 curr_attr_form, info_ptr, 257 die->di_cu_context-> 258 cc_length_size); 259 } while (curr_attr != 0 || curr_attr_form != 0); 260 261 *attr_form = 1; 262 return (NULL); 263 } 264 265 266 int 267 dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error) 268 { 269 Dwarf_Half attr_form; 270 Dwarf_Debug dbg; 271 Dwarf_Byte_Ptr info_ptr; 272 Dwarf_Unsigned string_offset; 273 int res; 274 275 CHECK_DIE(die, DW_DLV_ERROR) 276 277 info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form); 278 if (info_ptr == NULL) { 279 if (attr_form == 0) { 280 _dwarf_error(die->di_cu_context->cc_dbg, error, 281 DW_DLE_DIE_BAD); 282 return (DW_DLV_ERROR); 283 } 284 return DW_DLV_NO_ENTRY; 285 } 286 287 if (attr_form == DW_FORM_string) { 288 *ret_name = (char *) (info_ptr); 289 return DW_DLV_OK; 290 } 291 292 dbg = die->di_cu_context->cc_dbg; 293 if (attr_form != DW_FORM_strp) { 294 _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); 295 return (DW_DLV_ERROR); 296 } 297 298 READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned, 299 info_ptr, die->di_cu_context->cc_length_size); 300 301 if (string_offset >= dbg->de_debug_str_size) { 302 _dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD); 303 return (DW_DLV_ERROR); 304 } 305 306 res = 307 _dwarf_load_section(dbg, 308 dbg->de_debug_str_index, 309 &dbg->de_debug_str, 310 error); 311 if (res != DW_DLV_OK) { 312 return res; 313 } 314 315 *ret_name = (char *) (dbg->de_debug_str + string_offset); 316 return DW_DLV_OK; 317 } 318 319 320 int 321 dwarf_hasattr(Dwarf_Die die, 322 Dwarf_Half attr, 323 Dwarf_Bool * return_bool, Dwarf_Error * error) 324 { 325 Dwarf_Half attr_form; 326 327 CHECK_DIE(die, DW_DLV_ERROR) 328 329 if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) { 330 if (attr_form == 0) { 331 _dwarf_error(die->di_cu_context->cc_dbg, error, 332 DW_DLE_DIE_BAD); 333 return (DW_DLV_ERROR); 334 } 335 *return_bool = false; 336 return DW_DLV_OK; 337 } 338 339 *return_bool = (true); 340 return DW_DLV_OK; 341 } 342 343 344 int 345 dwarf_attr(Dwarf_Die die, 346 Dwarf_Half attr, 347 Dwarf_Attribute * ret_attr, Dwarf_Error * error) 348 { 349 Dwarf_Half attr_form; 350 Dwarf_Attribute attrib; 351 Dwarf_Byte_Ptr info_ptr; 352 Dwarf_Debug dbg; 353 354 CHECK_DIE(die, DW_DLV_ERROR) 355 dbg = die->di_cu_context->cc_dbg; 356 357 info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form); 358 if (info_ptr == NULL) { 359 if (attr_form == 0) { 360 _dwarf_error(dbg, error, DW_DLE_DIE_BAD); 361 return (DW_DLV_ERROR); 362 } 363 return DW_DLV_NO_ENTRY; 364 } 365 366 attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1); 367 if (attrib == NULL) { 368 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 369 return (DW_DLV_ERROR); 370 } 371 372 attrib->ar_attribute = attr; 373 attrib->ar_attribute_form = attr_form; 374 attrib->ar_attribute_form_direct = attr_form; 375 attrib->ar_cu_context = die->di_cu_context; 376 attrib->ar_debug_info_ptr = info_ptr; 377 *ret_attr = (attrib); 378 return DW_DLV_OK; 379 } 380 381 382 int 383 dwarf_lowpc(Dwarf_Die die, 384 Dwarf_Addr * return_addr, Dwarf_Error * error) 385 { 386 Dwarf_Addr ret_addr; 387 Dwarf_Byte_Ptr info_ptr; 388 Dwarf_Half attr_form; 389 Dwarf_Debug dbg; 390 391 CHECK_DIE(die, DW_DLV_ERROR) 392 393 dbg = die->di_cu_context->cc_dbg; 394 info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form); 395 if ((info_ptr == NULL && attr_form == 0) || 396 (info_ptr != NULL && attr_form != DW_FORM_addr)) { 397 _dwarf_error(dbg, error, DW_DLE_DIE_BAD); 398 return (DW_DLV_ERROR); 399 } 400 if (info_ptr == NULL) { 401 return (DW_DLV_NO_ENTRY); 402 } 403 404 405 READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, 406 info_ptr, dbg->de_pointer_size); 407 408 *return_addr = ret_addr; 409 return (DW_DLV_OK); 410 } 411 412 413 int 414 dwarf_highpc(Dwarf_Die die, 415 Dwarf_Addr * return_addr, Dwarf_Error * error) 416 { 417 Dwarf_Addr ret_addr; 418 Dwarf_Byte_Ptr info_ptr; 419 Dwarf_Half attr_form; 420 Dwarf_Debug dbg; 421 422 CHECK_DIE(die, DW_DLV_ERROR) 423 424 dbg = die->di_cu_context->cc_dbg; 425 info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form); 426 if ((info_ptr == NULL && attr_form == 0) || 427 (info_ptr != NULL && attr_form != DW_FORM_addr)) { 428 _dwarf_error(dbg, error, DW_DLE_DIE_BAD); 429 return (DW_DLV_ERROR); 430 } 431 if (info_ptr == NULL) { 432 return (DW_DLV_NO_ENTRY); 433 } 434 435 READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, 436 info_ptr, dbg->de_pointer_size); 437 438 *return_addr = ret_addr; 439 return (DW_DLV_OK); 440 } 441 442 443 /* 444 Takes a die, an attribute attr, and checks if attr 445 occurs in die. Attr is required to be an attribute 446 whose form is in the "constant" class. If attr occurs 447 in die, the value is returned. 448 Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as 449 appropriate. Sets the value thru the pointer return_val. 450 This function is meant to do all the 451 processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset, 452 and dwarf_srclang. 453 */ 454 static int 455 _dwarf_die_attr_unsigned_constant(Dwarf_Die die, 456 Dwarf_Half attr, 457 Dwarf_Unsigned * return_val, 458 Dwarf_Error * error) 459 { 460 Dwarf_Byte_Ptr info_ptr; 461 Dwarf_Half attr_form; 462 Dwarf_Unsigned ret_value; 463 Dwarf_Debug dbg; 464 465 CHECK_DIE(die, DW_DLV_ERROR) 466 467 dbg = die->di_cu_context->cc_dbg; 468 info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form); 469 if (info_ptr != NULL) { 470 switch (attr_form) { 471 472 case DW_FORM_data1: 473 *return_val = (*(Dwarf_Small *) info_ptr); 474 return (DW_DLV_OK); 475 476 case DW_FORM_data2: 477 READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 478 info_ptr, sizeof(Dwarf_Shalf)); 479 *return_val = ret_value; 480 return (DW_DLV_OK); 481 482 case DW_FORM_data4: 483 READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 484 info_ptr, sizeof(Dwarf_sfixed)); 485 *return_val = ret_value; 486 return (DW_DLV_OK); 487 488 case DW_FORM_data8: 489 READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 490 info_ptr, sizeof(Dwarf_Unsigned)); 491 *return_val = ret_value; 492 return (DW_DLV_OK); 493 494 case DW_FORM_udata: 495 *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL)); 496 return (DW_DLV_OK); 497 498 default: 499 _dwarf_error(dbg, error, DW_DLE_DIE_BAD); 500 return (DW_DLV_ERROR); 501 } 502 } 503 if (attr_form == 0) { 504 _dwarf_error(dbg, error, DW_DLE_DIE_BAD); 505 return (DW_DLV_ERROR); 506 } 507 return DW_DLV_NO_ENTRY; 508 } 509 510 511 int 512 dwarf_bytesize(Dwarf_Die die, 513 Dwarf_Unsigned * ret_size, Dwarf_Error * error) 514 { 515 Dwarf_Unsigned luns; 516 int res = 517 _dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns, 518 error); 519 *ret_size = luns; 520 return res; 521 } 522 523 524 int 525 dwarf_bitsize(Dwarf_Die die, 526 Dwarf_Unsigned * ret_size, Dwarf_Error * error) 527 { 528 Dwarf_Unsigned luns; 529 int res; 530 531 res = 532 _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, &luns, 533 error); 534 *ret_size = luns; 535 return res; 536 } 537 538 539 int 540 dwarf_bitoffset(Dwarf_Die die, 541 Dwarf_Unsigned * ret_size, Dwarf_Error * error) 542 { 543 Dwarf_Unsigned luns; 544 int res; 545 546 res = 547 _dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset, &luns, 548 error); 549 *ret_size = luns; 550 return res; 551 } 552 553 554 /* Refer section 3.1, page 21 in Dwarf Definition. */ 555 int 556 dwarf_srclang(Dwarf_Die die, 557 Dwarf_Unsigned * ret_size, Dwarf_Error * error) 558 { 559 Dwarf_Unsigned luns; 560 int res; 561 562 res = 563 _dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns, 564 error); 565 *ret_size = luns; 566 return res; 567 } 568 569 570 /* Refer section 5.4, page 37 in Dwarf Definition. */ 571 int 572 dwarf_arrayorder(Dwarf_Die die, 573 Dwarf_Unsigned * ret_size, Dwarf_Error * error) 574 { 575 Dwarf_Unsigned luns; 576 int res; 577 578 res = 579 _dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, &luns, 580 error); 581 *ret_size = luns; 582 return res; 583 } 584 585 /* 586 Return DW_DLV_OK if ok 587 DW_DLV_ERROR if failure. 588 589 If the die and the attr are not related the result is 590 meaningless. 591 */ 592 int 593 dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Off * offset, /* return 594 offset 595 thru 596 this 597 ptr 598 */ 599 Dwarf_Error * error) 600 { 601 Dwarf_Off attroff; 602 603 CHECK_DIE(die, DW_DLV_ERROR) 604 605 attroff = (attr->ar_debug_info_ptr - 606 die->di_cu_context->cc_dbg->de_debug_info); 607 *offset = attroff; 608 return DW_DLV_OK; 609 } 610