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 38 #include "config.h" 39 #include "dwarf_incl.h" 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include "dwarf_frame.h" 43 #include "dwarf_arange.h" /* using Arange as a way to build a 44 list */ 45 46 47 static int 48 __dwarf_get_fde_list_internal(Dwarf_Debug dbg, 49 Dwarf_Cie ** cie_data, 50 Dwarf_Signed * cie_element_count, 51 Dwarf_Fde ** fde_data, 52 Dwarf_Signed * fde_element_count, 53 Dwarf_Small * section_ptr, 54 Dwarf_Unsigned section_length, 55 Dwarf_Unsigned cie_id_value, 56 int use_gnu_cie_calc, 57 Dwarf_Error * error); 58 59 /* 60 This function is the heart of the debug_frame stuff. Don't even 61 think of reading this without reading both the Libdwarf and 62 consumer API carefully first. This function basically executes 63 frame instructions contained in a Cie or an Fde, but does in a 64 number of different ways depending on the information sought. 65 Start_instr_ptr points to the first byte of the frame instruction 66 stream, and final_instr_ptr to the to the first byte after the 67 last. 68 69 The offsets returned in the frame instructions are factored. That 70 is they need to be multiplied by either the code_alignment_factor 71 or the data_alignment_factor, as appropriate to obtain the actual 72 offset. This makes it possible to expand an instruction stream 73 without the corresponding Cie. However, when an Fde frame instr 74 sequence is being expanded there must be a valid Cie with a pointer 75 to an initial table row. 76 77 78 If successful, returns DW_DLV_OK 79 And sets returned_count thru the pointer 80 if make_instr is true. 81 If make_instr is false returned_count 82 should NOT be used by the caller (returned_count 83 is set to 0 thru the pointer by this routine...) 84 If unsuccessful, returns DW_DLV_ERROR 85 and sets returned_error to the error code 86 87 It does not do a whole lot of input validation being a private 88 function. Please make sure inputs are valid. 89 90 (1) If make_instr is true, it makes a list of pointers to 91 Dwarf_Frame_Op structures containing the frame instructions 92 executed. A pointer to this list is returned in ret_frame_instr. 93 Make_instr is true only when a list of frame instructions is to be 94 returned. In this case since we are not interested in the contents 95 of the table, the input Cie can be NULL. This is the only case 96 where the inpute Cie can be NULL. 97 98 (2) If search_pc is true, frame instructions are executed till 99 either a location is reached that is greater than the search_pc_val 100 provided, or all instructions are executed. At this point the 101 last row of the table generated is returned in a structure. 102 A pointer to this structure is supplied in table. 103 104 (3) This function is also used to create the initial table row 105 defined by a Cie. In this case, the Dwarf_Cie pointer cie, is 106 NULL. For an FDE, however, cie points to the associated Cie. 107 */ 108 static int 109 _dwarf_exec_frame_instr(Dwarf_Bool make_instr, /* Make list of frame 110 instr? */ 111 Dwarf_Frame_Op ** ret_frame_instr, /* Ptr 112 to 113 list 114 of 115 ptrs 116 to 117 fr 118 instrs 119 */ 120 Dwarf_Bool search_pc, /* Search for a pc 121 value? */ 122 Dwarf_Addr search_pc_val, /* Search for 123 this pc 124 value */ 125 Dwarf_Addr loc, /* initial location value */ 126 Dwarf_Small * start_instr_ptr, /* Ptr to start 127 of frame 128 instrs. */ 129 Dwarf_Small * final_instr_ptr, /* Ptr just 130 past frame 131 instrs. */ 132 Dwarf_Frame table, /* Ptr to struct with 133 last row. */ 134 Dwarf_Cie cie, /* Ptr to Cie used by the Fde. 135 */ 136 Dwarf_Debug dbg, /* Associated 137 Dwarf_Debug */ 138 Dwarf_Sword * returned_count, 139 int *returned_error) 140 { 141 /* Sweeps the frame instructions. */ 142 Dwarf_Small *instr_ptr; 143 144 /* Obvious from the documents. */ 145 Dwarf_Small instr, opcode; 146 Dwarf_Small reg_no, reg_noA, reg_noB; 147 Dwarf_Unsigned factored_N_value; 148 Dwarf_Addr new_loc; /* must be min de_pointer_size bytes */ 149 Dwarf_Unsigned adv_loc; /* must be min de_pointer_size bytes 150 and must be at least sizeof 151 Dwarf_ufixed */ 152 153 struct Dwarf_Reg_Rule_s reg[DW_FRAME_LAST_REG_NUM]; 154 155 156 /* This is used to end executing frame instructions. */ 157 /* Becomes true when search_pc is true and loc */ 158 /* is greater than search_pc_val. */ 159 Dwarf_Bool search_over = false; 160 161 /* Used by the DW_FRAME_advance_loc instr */ 162 /* to hold the increment in pc value. */ 163 Dwarf_Addr adv_pc; 164 165 /* Contains the length in bytes of */ 166 /* an leb128 encoded number. */ 167 Dwarf_Word leb128_length; 168 169 /* Counts the number of frame instructions executed. */ 170 Dwarf_Word instr_count = 0; 171 172 /* 173 These contain the current fields of the current frame 174 instruction. */ 175 Dwarf_Small fp_base_op = 0; 176 Dwarf_Small fp_extended_op; 177 Dwarf_Half fp_register; 178 Dwarf_Unsigned fp_offset; 179 Dwarf_Off fp_instr_offset; 180 181 /* 182 Stack_table points to the row (Dwarf_Frame ie) being pushed or 183 popped by a remember or restore instruction. Top_stack points to 184 the top of the stack of rows. */ 185 Dwarf_Frame stack_table; 186 Dwarf_Frame top_stack = NULL; 187 188 /* 189 These are used only when make_instr is true. Curr_instr is a 190 pointer to the current frame instruction executed. 191 Curr_instr_ptr, head_instr_list, and curr_instr_list are used 192 to form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr 193 is used to deallocate the structs used to form the chain. 194 Head_instr_block points to a contiguous list of pointers to the 195 Dwarf_Frame_Op structs executed. */ 196 Dwarf_Frame_Op *curr_instr; 197 Dwarf_Chain curr_instr_item, dealloc_instr_item; 198 Dwarf_Chain head_instr_chain = NULL; 199 Dwarf_Chain tail_instr_chain = NULL; 200 Dwarf_Frame_Op *head_instr_block; 201 202 /* 203 These are the alignment_factors taken from the Cie provided. 204 When no input Cie is provided they are set to 1, because only 205 factored offsets are required. */ 206 Dwarf_Sword code_alignment_factor = 1; 207 Dwarf_Sword data_alignment_factor = 1; 208 209 /* 210 This flag indicates when an actual alignment factor is needed. 211 So if a frame instruction that computes an offset using an 212 alignment factor is encountered when this flag is set, an error 213 is returned because the Cie did not have a valid augmentation. */ 214 Dwarf_Bool need_augmentation = false; 215 216 Dwarf_Word i; 217 218 /* Initialize first row from associated Cie. Using temp regs 219 explicity */ 220 struct Dwarf_Reg_Rule_s *t1reg; 221 struct Dwarf_Reg_Rule_s *t1end; 222 struct Dwarf_Reg_Rule_s *t2reg; 223 224 225 t1reg = reg; 226 t1end = t1reg + DW_FRAME_LAST_REG_NUM; 227 if (cie != NULL && cie->ci_initial_table != NULL) { 228 t2reg = cie->ci_initial_table->fr_reg; 229 for (; t1reg < t1end; t1reg++, t2reg++) { 230 *t1reg = *t2reg; 231 } 232 } else { /* initialize with same_value */ 233 for (; t1reg < t1end; t1reg++) { 234 t1reg->ru_is_off = 0; 235 t1reg->ru_register = DW_FRAME_SAME_VAL; 236 t1reg->ru_offset = 0; 237 } 238 } 239 240 /* 241 The idea here is that the code_alignment_factor and 242 data_alignment_factor which are needed for certain instructions 243 are valid only when the Cie has a proper augmentation string. 244 So if the augmentation is not right, only Frame instruction can 245 be read. */ 246 if (cie != NULL && cie->ci_augmentation != NULL) { 247 code_alignment_factor = cie->ci_code_alignment_factor; 248 data_alignment_factor = cie->ci_data_alignment_factor; 249 } else 250 need_augmentation = !make_instr; 251 252 instr_ptr = start_instr_ptr; 253 while ((instr_ptr < final_instr_ptr) && (!search_over)) { 254 255 256 fp_instr_offset = instr_ptr - start_instr_ptr; 257 instr = *(Dwarf_Small *) instr_ptr; 258 instr_ptr += sizeof(Dwarf_Small); 259 260 fp_base_op = (instr & 0xc0) >> 6; 261 if ((instr & 0xc0) == 0x00) { 262 opcode = instr; /* is really extended op */ 263 fp_extended_op = (instr & (~(0xc0))) & 0xff; 264 } else { 265 opcode = instr & 0xc0; /* is base op */ 266 fp_extended_op = 0; 267 } 268 269 fp_register = 0; 270 fp_offset = 0; 271 switch (opcode) { 272 273 case DW_CFA_advance_loc:{ 274 /* base op */ 275 fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK; 276 277 if (need_augmentation) { 278 279 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION); 280 return DW_DLV_ERROR; 281 } 282 adv_pc = adv_pc * code_alignment_factor; 283 284 search_over = search_pc && 285 (loc + adv_pc > search_pc_val); 286 /* If gone past pc needed, retain old pc. */ 287 if (!search_over) 288 loc = loc + adv_pc; 289 break; 290 } 291 292 case DW_CFA_offset:{ /* base op */ 293 reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK); 294 if (reg_no > DW_FRAME_LAST_REG_NUM) { 295 *returned_error = DW_DLE_DF_REG_NUM_TOO_HIGH; 296 return DW_DLV_ERROR; 297 } 298 299 factored_N_value = 300 _dwarf_decode_u_leb128(instr_ptr, &leb128_length); 301 instr_ptr = instr_ptr + leb128_length; 302 303 fp_register = reg_no; 304 fp_offset = factored_N_value; 305 306 if (need_augmentation) { 307 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION); 308 return DW_DLV_ERROR; 309 } 310 311 reg[reg_no].ru_is_off = 1; 312 reg[reg_no].ru_register = DW_FRAME_CFA_COL; 313 reg[reg_no].ru_offset = factored_N_value * 314 data_alignment_factor; 315 316 break; 317 } 318 319 case DW_CFA_restore:{ /* base op */ 320 reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK); 321 if (reg_no > DW_FRAME_LAST_REG_NUM) { 322 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); 323 return DW_DLV_ERROR; 324 } 325 326 fp_register = reg_no; 327 328 if (cie != NULL && cie->ci_initial_table != NULL) 329 reg[reg_no] = cie->ci_initial_table->fr_reg[reg_no]; 330 else if (!make_instr) { 331 *returned_error = (DW_DLE_DF_MAKE_INSTR_NO_INIT); 332 return DW_DLV_ERROR; 333 } 334 335 break; 336 } 337 case DW_CFA_set_loc:{ 338 READ_UNALIGNED(dbg, new_loc, Dwarf_Addr, 339 instr_ptr, dbg->de_pointer_size); 340 instr_ptr += dbg->de_pointer_size; 341 if (new_loc <= loc) { 342 *returned_error = (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC); 343 return DW_DLV_ERROR; 344 } 345 346 search_over = search_pc && (new_loc > search_pc_val); 347 348 /* If gone past pc needed, retain old pc. */ 349 if (!search_over) 350 loc = new_loc; 351 fp_offset = new_loc; 352 break; 353 } 354 355 case DW_CFA_advance_loc1:{ 356 fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr; 357 instr_ptr += sizeof(Dwarf_Small); 358 359 if (need_augmentation) { 360 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION); 361 return DW_DLV_ERROR; 362 } 363 adv_loc *= code_alignment_factor; 364 365 search_over = search_pc && 366 (loc + adv_loc > search_pc_val); 367 368 /* If gone past pc needed, retain old pc. */ 369 if (!search_over) 370 loc = loc + adv_loc; 371 break; 372 } 373 374 case DW_CFA_advance_loc2:{ 375 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned, 376 instr_ptr, sizeof(Dwarf_Half)); 377 instr_ptr += sizeof(Dwarf_Half); 378 fp_offset = adv_loc; 379 380 if (need_augmentation) { 381 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION); 382 return DW_DLV_ERROR; 383 } 384 adv_loc *= code_alignment_factor; 385 386 search_over = search_pc && 387 (loc + adv_loc > search_pc_val); 388 389 /* If gone past pc needed, retain old pc. */ 390 if (!search_over) 391 loc = loc + adv_loc; 392 break; 393 } 394 395 case DW_CFA_advance_loc4:{ 396 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned, 397 instr_ptr, sizeof(Dwarf_ufixed)); 398 instr_ptr += sizeof(Dwarf_ufixed); 399 fp_offset = adv_loc; 400 401 if (need_augmentation) { 402 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION); 403 return DW_DLV_ERROR; 404 } 405 adv_loc *= code_alignment_factor; 406 407 search_over = search_pc && 408 (loc + adv_loc > search_pc_val); 409 410 /* If gone past pc needed, retain old pc. */ 411 if (!search_over) 412 loc = loc + adv_loc; 413 break; 414 } 415 416 case DW_CFA_offset_extended:{ 417 Dwarf_Unsigned lreg; 418 419 DECODE_LEB128_UWORD(instr_ptr, lreg) 420 reg_no = (Dwarf_Small) lreg; 421 if (reg_no > DW_FRAME_LAST_REG_NUM) { 422 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); 423 return DW_DLV_ERROR; 424 } 425 factored_N_value = 426 _dwarf_decode_u_leb128(instr_ptr, &leb128_length); 427 instr_ptr += leb128_length; 428 429 if (need_augmentation) { 430 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION); 431 return DW_DLV_ERROR; 432 } 433 reg[reg_no].ru_is_off = 1; 434 reg[reg_no].ru_register = DW_FRAME_CFA_COL; 435 reg[reg_no].ru_offset = factored_N_value * 436 data_alignment_factor; 437 438 fp_register = reg_no; 439 fp_offset = factored_N_value; 440 break; 441 } 442 443 case DW_CFA_restore_extended:{ 444 Dwarf_Unsigned lreg; 445 446 DECODE_LEB128_UWORD(instr_ptr, lreg) 447 reg_no = (Dwarf_Small) lreg; 448 449 if (reg_no > DW_FRAME_LAST_REG_NUM) { 450 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); 451 return DW_DLV_ERROR; 452 } 453 454 if (cie != NULL && cie->ci_initial_table != NULL) { 455 reg[reg_no] = cie->ci_initial_table->fr_reg[reg_no]; 456 } else { 457 if (!make_instr) { 458 *returned_error = 459 (DW_DLE_DF_MAKE_INSTR_NO_INIT); 460 return DW_DLV_ERROR; 461 } 462 } 463 464 fp_register = reg_no; 465 break; 466 } 467 468 case DW_CFA_undefined:{ 469 Dwarf_Unsigned lreg; 470 471 DECODE_LEB128_UWORD(instr_ptr, lreg) 472 reg_no = (Dwarf_Small) lreg; 473 if (reg_no > DW_FRAME_LAST_REG_NUM) { 474 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); 475 return DW_DLV_ERROR; 476 } 477 478 reg[reg_no].ru_is_off = 0; 479 reg[reg_no].ru_register = DW_FRAME_UNDEFINED_VAL; 480 reg[reg_no].ru_offset = 0; 481 482 fp_register = reg_no; 483 break; 484 } 485 486 case DW_CFA_same_value:{ 487 Dwarf_Unsigned lreg; 488 489 DECODE_LEB128_UWORD(instr_ptr, lreg) 490 reg_no = (Dwarf_Small) lreg; 491 if (reg_no > DW_FRAME_LAST_REG_NUM) { 492 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); 493 return DW_DLV_ERROR; 494 } 495 496 reg[reg_no].ru_is_off = 0; 497 reg[reg_no].ru_register = DW_FRAME_SAME_VAL; 498 reg[reg_no].ru_offset = 0; 499 fp_register = reg_no; 500 break; 501 } 502 503 case DW_CFA_register:{ 504 Dwarf_Unsigned lreg; 505 506 DECODE_LEB128_UWORD(instr_ptr, lreg) 507 reg_noA = (Dwarf_Small) lreg; 508 509 if (reg_noA > DW_FRAME_LAST_REG_NUM) { 510 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); 511 return DW_DLV_ERROR; 512 } 513 514 DECODE_LEB128_UWORD(instr_ptr, lreg) 515 reg_noB = (Dwarf_Small) lreg; 516 517 if (reg_noB > DW_FRAME_LAST_REG_NUM) { 518 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); 519 return DW_DLV_ERROR; 520 } 521 522 523 reg[reg_noA].ru_is_off = 0; 524 reg[reg_noA].ru_register = reg_noB; 525 526 reg[reg_noA].ru_offset = 0; 527 528 fp_register = reg_noA; 529 fp_offset = reg_noB; 530 break; 531 } 532 533 case DW_CFA_remember_state:{ 534 stack_table = (Dwarf_Frame) 535 _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1); 536 if (stack_table == NULL) { 537 *returned_error = (DW_DLE_DF_ALLOC_FAIL); 538 return DW_DLV_ERROR; 539 } 540 541 for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++) 542 stack_table->fr_reg[i] = reg[i]; 543 544 if (top_stack != NULL) 545 stack_table->fr_next = top_stack; 546 top_stack = stack_table; 547 548 break; 549 } 550 551 case DW_CFA_restore_state:{ 552 if (top_stack == NULL) { 553 *returned_error = (DW_DLE_DF_POP_EMPTY_STACK); 554 return DW_DLV_ERROR; 555 } 556 stack_table = top_stack; 557 top_stack = stack_table->fr_next; 558 559 for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++) 560 reg[i] = stack_table->fr_reg[i]; 561 562 dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME); 563 break; 564 } 565 566 case DW_CFA_def_cfa:{ 567 Dwarf_Unsigned lreg; 568 569 DECODE_LEB128_UWORD(instr_ptr, lreg) 570 reg_no = (Dwarf_Small) lreg; 571 572 if (reg_no > DW_FRAME_LAST_REG_NUM) { 573 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); 574 return (DW_DLV_ERROR); 575 } 576 577 factored_N_value = 578 _dwarf_decode_u_leb128(instr_ptr, &leb128_length); 579 instr_ptr += leb128_length; 580 581 if (need_augmentation) { 582 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION); 583 return DW_DLV_ERROR; 584 } 585 reg[DW_FRAME_CFA_COL].ru_is_off = 1; 586 reg[DW_FRAME_CFA_COL].ru_register = reg_no; 587 reg[DW_FRAME_CFA_COL].ru_offset = factored_N_value; 588 589 fp_register = reg_no; 590 fp_offset = factored_N_value; 591 break; 592 } 593 594 case DW_CFA_def_cfa_register:{ 595 Dwarf_Unsigned lreg; 596 597 DECODE_LEB128_UWORD(instr_ptr, lreg) 598 reg_no = (Dwarf_Small) lreg; 599 600 if (reg_no > DW_FRAME_LAST_REG_NUM) { 601 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH); 602 return DW_DLV_ERROR; 603 } 604 605 reg[DW_FRAME_CFA_COL].ru_is_off = 0; 606 reg[DW_FRAME_CFA_COL].ru_register = reg_no; 607 reg[DW_FRAME_CFA_COL].ru_offset = 0; 608 fp_register = reg_no; 609 break; 610 } 611 612 case DW_CFA_def_cfa_offset:{ 613 factored_N_value = 614 _dwarf_decode_u_leb128(instr_ptr, &leb128_length); 615 instr_ptr += leb128_length; 616 617 if (need_augmentation) { 618 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION); 619 return DW_DLV_ERROR; 620 } 621 reg[DW_FRAME_CFA_COL].ru_offset = factored_N_value; 622 623 fp_offset = factored_N_value; 624 break; 625 } 626 627 case DW_CFA_nop:{ 628 break; 629 } 630 631 #ifdef DW_CFA_GNU_window_save 632 case DW_CFA_GNU_window_save:{ 633 /* no information: this just tells unwinder to restore 634 the window registers from the previous frame's 635 window save area */ 636 break; 637 } 638 #endif 639 #ifdef DW_CFA_GNU_args_size 640 /* single uleb128 is the current arg area size in bytes. No 641 register exists yet to save this in */ 642 case DW_CFA_GNU_args_size:{ 643 Dwarf_Unsigned lreg; 644 645 DECODE_LEB128_UWORD(instr_ptr, lreg) 646 reg_no = (Dwarf_Small) lreg; 647 648 break; 649 } 650 #endif 651 } 652 653 if (make_instr) { 654 instr_count++; 655 656 curr_instr = (Dwarf_Frame_Op *) 657 _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1); 658 if (curr_instr == NULL) { 659 *returned_error = (DW_DLE_DF_ALLOC_FAIL); 660 return DW_DLV_ERROR; 661 } 662 663 curr_instr->fp_base_op = fp_base_op; 664 curr_instr->fp_extended_op = fp_extended_op; 665 curr_instr->fp_register = fp_register; 666 curr_instr->fp_offset = fp_offset; 667 curr_instr->fp_instr_offset = fp_instr_offset; 668 669 curr_instr_item = (Dwarf_Chain) 670 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 671 if (curr_instr_item == NULL) { 672 *returned_error = (DW_DLE_DF_ALLOC_FAIL); 673 return DW_DLV_ERROR; 674 } 675 676 curr_instr_item->ch_item = curr_instr; 677 if (head_instr_chain == NULL) 678 head_instr_chain = tail_instr_chain = curr_instr_item; 679 else { 680 tail_instr_chain->ch_next = curr_instr_item; 681 tail_instr_chain = curr_instr_item; 682 } 683 } 684 } 685 686 /* 687 If frame instruction decoding was right we would stop exactly 688 at final_instr_ptr. */ 689 if (instr_ptr > final_instr_ptr) { 690 *returned_error = (DW_DLE_DF_FRAME_DECODING_ERROR); 691 return DW_DLV_ERROR; 692 } 693 694 /* Create the last row generated. */ 695 if (table != NULL) { 696 t1reg = reg; 697 t1end = t1reg + DW_FRAME_LAST_REG_NUM; 698 table->fr_loc = loc; 699 t2reg = table->fr_reg; 700 for (; t1reg < t1end; t1reg++, t2reg++) { 701 *t2reg = *t1reg; 702 } 703 } 704 705 /* Dealloc anything remaining on stack. */ 706 for (; top_stack != NULL;) { 707 stack_table = top_stack; 708 top_stack = top_stack->fr_next; 709 dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME); 710 } 711 712 if (make_instr) { 713 /* Allocate list of pointers to Dwarf_Frame_Op's. */ 714 head_instr_block = (Dwarf_Frame_Op *) 715 _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count); 716 if (head_instr_block == NULL) { 717 *returned_error = DW_DLE_DF_ALLOC_FAIL; 718 return DW_DLV_ERROR; 719 } 720 721 /* 722 Store pointers to Dwarf_Frame_Op's in this list and 723 deallocate the structs that chain the Dwarf_Frame_Op's. */ 724 curr_instr_item = head_instr_chain; 725 for (i = 0; i < instr_count; i++) { 726 *(head_instr_block + i) = 727 *(Dwarf_Frame_Op *) curr_instr_item->ch_item; 728 dealloc_instr_item = curr_instr_item; 729 curr_instr_item = curr_instr_item->ch_next; 730 dwarf_dealloc(dbg, dealloc_instr_item->ch_item, 731 DW_DLA_FRAME_OP); 732 dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN); 733 } 734 *ret_frame_instr = head_instr_block; 735 736 *returned_count = (Dwarf_Sword) instr_count; 737 } else { 738 *returned_count = 0; 739 } 740 return DW_DLV_OK; 741 } 742 743 static int 744 qsort_compare(const void *elem1, const void *elem2) 745 { 746 Dwarf_Fde fde1 = *(Dwarf_Fde *) elem1; 747 Dwarf_Fde fde2 = *(Dwarf_Fde *) elem2; 748 Dwarf_Addr addr1 = fde1->fd_initial_location; 749 Dwarf_Addr addr2 = fde2->fd_initial_location; 750 751 if (addr1 < addr2) { 752 return -1; 753 } else if (addr1 > addr2) { 754 return 1; 755 } 756 return 0; 757 } 758 759 /* 760 * This function expects as input a pointer to Dwarf_Debug (dbg) and a 761 * a pointer to Cie. It finds the augmentation string and returns after 762 * setting *augmentation to point to it. 763 */ 764 static int 765 get_augmentation_string(Dwarf_Debug dbg, 766 Dwarf_Small * cie_ptr, 767 Dwarf_Unsigned cie_id_value, 768 Dwarf_Small ** augmentation, 769 Dwarf_Error * error) 770 { 771 Dwarf_Unsigned cie_id; /* must be min de_length_size bytes in 772 size */ 773 Dwarf_Small version; 774 int local_length_size; 775 Dwarf_Unsigned length; 776 /*REFERENCED*/ /* Not used in this instance of the macro */ 777 int local_extension_size; 778 779 780 /* READ_AREA_LENGTH updates cie_ptr for consumed bytes */ 781 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, 782 cie_ptr, local_length_size, local_extension_size); 783 784 785 786 /* Read the Cie Id field. */ 787 READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned, 788 cie_ptr, local_length_size); 789 SIGN_EXTEND(cie_id, local_length_size); 790 if (cie_id != cie_id_value) { 791 /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi 792 uses -1 in .debug_frame. .eh_frame not quite identical to 793 .debug_frame */ 794 _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD); 795 return (DW_DLV_ERROR); 796 } 797 cie_ptr += local_length_size; 798 799 800 /* Read the version. */ 801 version = *(Dwarf_Small *) cie_ptr; 802 cie_ptr++; 803 if (version != DW_CIE_VERSION) { 804 _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD); 805 return (DW_DLV_ERROR); 806 } 807 808 /* At this point, cie_ptr is pointing at the augmentation string. */ 809 *augmentation = cie_ptr; 810 return DW_DLV_OK; 811 } 812 813 int 814 dwarf_get_cie_of_fde(Dwarf_Fde fde, 815 Dwarf_Cie * cie_returned, Dwarf_Error * error) 816 { 817 if (fde == NULL) { 818 _dwarf_error(NULL, error, DW_DLE_FDE_NULL); 819 return (DW_DLV_ERROR); 820 } 821 822 *cie_returned = fde->fd_cie; 823 return DW_DLV_OK; 824 825 } 826 827 /* 828 For g++ .eh_frame fde and cie. 829 the cie id is different as the 830 definition of the cie_id in an fde 831 is the distance back from the address of the 832 value to the cie. 833 Or 0 if this is a true cie. 834 Non standard dwarf, designed this way to be 835 convenient at run time for an allocated 836 (mapped into memory as part of the running image) section. 837 */ 838 int 839 dwarf_get_fde_list_eh(Dwarf_Debug dbg, 840 Dwarf_Cie ** cie_data, 841 Dwarf_Signed * cie_element_count, 842 Dwarf_Fde ** fde_data, 843 Dwarf_Signed * fde_element_count, 844 Dwarf_Error * error) 845 { 846 int res; 847 848 res = 849 _dwarf_load_section(dbg, 850 dbg->de_debug_frame_eh_gnu_index, 851 &dbg->de_debug_frame_eh_gnu, 852 error); 853 854 if (res != DW_DLV_OK) { 855 return res; 856 } 857 858 res = 859 __dwarf_get_fde_list_internal(dbg, 860 cie_data, 861 cie_element_count, 862 fde_data, 863 fde_element_count, 864 dbg->de_debug_frame_eh_gnu, 865 dbg->de_debug_frame_size_eh_gnu, 866 /* cie_id_value */ 0, 867 /* use_gnu_cie_calc= */ 1, 868 error); 869 return res; 870 } 871 872 873 874 /* 875 For standard dwarf .debug_frame 876 cie_id is -1 in a cie, and 877 is the section offset in the .debug_frame section 878 of the cie otherwise. Standard dwarf 879 */ 880 int 881 dwarf_get_fde_list(Dwarf_Debug dbg, 882 Dwarf_Cie ** cie_data, 883 Dwarf_Signed * cie_element_count, 884 Dwarf_Fde ** fde_data, 885 Dwarf_Signed * fde_element_count, 886 Dwarf_Error * error) 887 { 888 int res; 889 890 res = 891 _dwarf_load_section(dbg, 892 dbg->de_debug_frame_index, 893 &dbg->de_debug_frame, 894 error); 895 896 if (res != DW_DLV_OK) { 897 return res; 898 } 899 900 res = 901 __dwarf_get_fde_list_internal(dbg, cie_data, 902 cie_element_count, 903 fde_data, 904 fde_element_count, 905 dbg->de_debug_frame, 906 dbg->de_debug_frame_size, 907 DW_CIE_ID, 908 /* use_gnu_cie_calc= */ 0, 909 error); 910 return res; 911 } 912 913 static int 914 __dwarf_get_fde_list_internal(Dwarf_Debug dbg, 915 Dwarf_Cie ** cie_data, 916 Dwarf_Signed * cie_element_count, 917 Dwarf_Fde ** fde_data, 918 Dwarf_Signed * fde_element_count, 919 Dwarf_Small * section_ptr, 920 Dwarf_Unsigned section_length, 921 Dwarf_Unsigned cie_id_value, 922 int use_gnu_cie_calc, Dwarf_Error * error) 923 { 924 /* Scans the debug_frame section. */ 925 Dwarf_Small *frame_ptr = 0; 926 927 /* Points to the start of the current Fde or Cie. */ 928 Dwarf_Small *start_frame_ptr = 0; 929 930 /* Points to the start of the augmented entries of Fde or Cie. */ 931 Dwarf_Small *saved_frame_ptr = 0; 932 933 /* Fields for the current Cie being read. */ 934 Dwarf_Unsigned length = 0; /* READ_UNALIGNED needs min 935 de_length_size byte dest */ 936 Dwarf_Unsigned cie_base_offset = 0; /* needs to be min 937 de_length_size byte dest */ 938 Dwarf_Unsigned cie_id; 939 Dwarf_Small version = 0; 940 Dwarf_Small *augmentation = 0; 941 Dwarf_Word code_alignment_factor = 4; 942 Dwarf_Sword data_alignment_factor = -1; 943 Dwarf_Small return_address_register = 31; 944 Dwarf_Word length_of_augmented_fields = 0; 945 946 /* 947 New_cie points to the Cie being read, and head_cie_ptr and 948 cur_cie_ptr are used for chaining them up in sequence. */ 949 Dwarf_Cie new_cie; 950 Dwarf_Cie head_cie_ptr = NULL; 951 Dwarf_Cie cur_cie_ptr; 952 Dwarf_Word cie_count = 0; 953 954 /* 955 Points to a list of contiguous pointers to Dwarf_Cie 956 structures. */ 957 Dwarf_Cie *cie_list_ptr; 958 959 /* Fields for the current Fde being read. */ 960 Dwarf_Addr initial_location; /* must be min de_pointer_size 961 bytes in size */ 962 Dwarf_Addr address_range; /* must be min de_pointer_size bytes in 963 size */ 964 965 /* 966 New_fde points to the current Fde being read, and head_fde_ptr 967 and cur_fde_ptr are used to chain them up. */ 968 Dwarf_Fde new_fde; 969 Dwarf_Fde head_fde_ptr = NULL; 970 Dwarf_Fde cur_fde_ptr; 971 Dwarf_Word fde_count = 0; 972 973 /* 974 Points to a list of contiguous pointers to Dwarf_Fde 975 structures. */ 976 Dwarf_Fde *fde_list_ptr; 977 978 /* 979 Is used to check the offset field in the Fde by checking for a 980 Cie at this address. */ 981 Dwarf_Small *fde_cie_ptr; 982 983 Dwarf_Word leb128_length; 984 Dwarf_Word i, j; 985 int res; 986 Dwarf_Word last_cie_index; 987 988 989 Dwarf_Small *prev_augmentation_cie_ptr = 0; 990 Dwarf_Small *prev_augmentation_ptr = 0; 991 992 993 frame_ptr = section_ptr; 994 995 if (frame_ptr == 0) { 996 return DW_DLV_NO_ENTRY; 997 } 998 999 while (frame_ptr < section_ptr + section_length) { 1000 Dwarf_Small *cie_ptr_addr = 0; 1001 int local_extension_size = 0; 1002 int local_length_size = 0; 1003 1004 start_frame_ptr = frame_ptr; 1005 1006 /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */ 1007 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, 1008 frame_ptr, local_length_size, 1009 local_extension_size); 1010 1011 1012 if (length % local_length_size != 0) { 1013 _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); 1014 return (DW_DLV_ERROR); 1015 } 1016 1017 if (length == 0) { 1018 /* nul bytes at end of section, seen at end of egcs 1019 eh_frame sections (in a.out). Take this as meaning no 1020 more CIE/FDE data. We should be very close to end of 1021 section. */ 1022 break; 1023 } 1024 1025 cie_ptr_addr = frame_ptr; 1026 READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned, 1027 frame_ptr, local_length_size); 1028 SIGN_EXTEND(cie_id, local_length_size); 1029 cie_base_offset = cie_id; /* if this is a CIE, this is 1030 ignored. If it is an FDE, 1031 this is the section offset 1032 that allows us to get to the 1033 cie of this fde. Save it for 1034 the fde part of the 'if' 1035 below */ 1036 1037 frame_ptr += local_length_size; 1038 1039 if (cie_id == cie_id_value) { 1040 /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. 1041 sgi uses -1 (in .debug_frame). .eh_frame not quite 1042 identical to .debug_frame */ 1043 1044 1045 1046 /* this is a CIE, Common Information Entry: See the dwarf 1047 spec, section 6.4.1 */ 1048 version = *(Dwarf_Small *) frame_ptr; 1049 frame_ptr++; 1050 if (version != DW_CIE_VERSION) { 1051 _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD); 1052 return (DW_DLV_ERROR); 1053 } 1054 1055 augmentation = frame_ptr; 1056 frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1; 1057 if ((strcmp((char *) augmentation, 1058 DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) || 1059 (strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) { 1060 1061 Dwarf_Unsigned lreg; 1062 1063 DECODE_LEB128_UWORD(frame_ptr, lreg) 1064 code_alignment_factor = (Dwarf_Word) lreg; 1065 1066 1067 data_alignment_factor = 1068 (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr, 1069 &leb128_length); 1070 1071 frame_ptr = frame_ptr + leb128_length; 1072 1073 return_address_register = *(Dwarf_Small *) frame_ptr; 1074 if (return_address_register > DW_FRAME_LAST_REG_NUM) { 1075 _dwarf_error(dbg, error, 1076 DW_DLE_CIE_RET_ADDR_REG_ERROR); 1077 return (DW_DLV_ERROR); 1078 } 1079 frame_ptr++; 1080 } else if (augmentation[0] == 'z') { 1081 /* The augmentation starts with a known prefix. See the 1082 dwarf_frame.h for details on the layout. */ 1083 1084 Dwarf_Unsigned lreg; 1085 1086 DECODE_LEB128_UWORD(frame_ptr, lreg) 1087 code_alignment_factor = (Dwarf_Word) lreg; 1088 1089 1090 data_alignment_factor = 1091 (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr, 1092 &leb128_length); 1093 frame_ptr = frame_ptr + leb128_length; 1094 1095 return_address_register = *(Dwarf_Small *) frame_ptr; 1096 if (return_address_register > DW_FRAME_LAST_REG_NUM) { 1097 _dwarf_error(dbg, error, 1098 DW_DLE_CIE_RET_ADDR_REG_ERROR); 1099 return (DW_DLV_ERROR); 1100 } 1101 frame_ptr++; 1102 1103 /* Decode the length of augmented fields. */ 1104 DECODE_LEB128_UWORD(frame_ptr, lreg) 1105 length_of_augmented_fields = (Dwarf_Word) lreg; 1106 1107 1108 /* set the frame_ptr to point at the instruction start. 1109 */ 1110 frame_ptr += length_of_augmented_fields; 1111 } else if (0 == strcmp((const char *) augmentation, "eh")) { 1112 1113 /*REFERENCED*/ /* Not used in this instance of the macro */ 1114 Dwarf_Unsigned exception_table_addr; 1115 1116 /* this is per egcs-1.1.2 as on RH 6.0 */ 1117 READ_UNALIGNED(dbg, exception_table_addr, 1118 Dwarf_Unsigned, frame_ptr, 1119 local_length_size); 1120 frame_ptr += local_length_size; 1121 1122 code_alignment_factor = 1123 (Dwarf_Word) _dwarf_decode_s_leb128(frame_ptr, 1124 &leb128_length); 1125 frame_ptr = frame_ptr + leb128_length; 1126 1127 1128 data_alignment_factor = 1129 (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr, 1130 &leb128_length); 1131 1132 frame_ptr = frame_ptr + leb128_length; 1133 1134 return_address_register = *(Dwarf_Small *) frame_ptr; 1135 if (return_address_register > DW_FRAME_LAST_REG_NUM) { 1136 _dwarf_error(dbg, error, 1137 DW_DLE_CIE_RET_ADDR_REG_ERROR); 1138 return (DW_DLV_ERROR); 1139 } 1140 frame_ptr++; 1141 1142 } else { 1143 /* We do not understand the augmentation string. No 1144 assumption can be made about any fields other than 1145 what we have already read. */ 1146 frame_ptr = start_frame_ptr + length + local_length_size 1147 + local_extension_size; 1148 /* FIX -- What are the values of data_alignment_factor, 1149 code_alignement_factor, return_address_register and 1150 instruction start? They were clearly uninitalized in 1151 the previous version and I am leaving them the same 1152 way. */ 1153 } 1154 1155 new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1); 1156 if (new_cie == NULL) { 1157 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1158 return (DW_DLV_ERROR); 1159 } 1160 1161 new_cie->ci_initial_table = NULL; 1162 new_cie->ci_length = (Dwarf_Word) length; 1163 new_cie->ci_length_size = local_length_size; 1164 new_cie->ci_extension_size = local_extension_size; 1165 new_cie->ci_augmentation = (char *) augmentation; 1166 1167 new_cie->ci_data_alignment_factor = 1168 (Dwarf_Sbyte) data_alignment_factor; 1169 new_cie->ci_code_alignment_factor = 1170 (Dwarf_Small) code_alignment_factor; 1171 new_cie->ci_return_address_register = 1172 return_address_register; 1173 new_cie->ci_cie_start = start_frame_ptr; 1174 new_cie->ci_cie_instr_start = frame_ptr; 1175 new_cie->ci_dbg = dbg; 1176 1177 cie_count++; 1178 if (head_cie_ptr == NULL) 1179 head_cie_ptr = cur_cie_ptr = new_cie; 1180 else { 1181 cur_cie_ptr->ci_next = new_cie; 1182 cur_cie_ptr = new_cie; 1183 } 1184 } else { 1185 1186 1187 1188 /* this is an FDE, Frame Description Entry, see the Dwarf 1189 Spec, section 6.4.1 */ 1190 Dwarf_Small *cieptr; 1191 1192 Dwarf_Small *initloc = frame_ptr; 1193 Dwarf_Signed offset_into_exception_tables 1194 /* must be min dwarf_sfixed in size */ 1195 = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET; 1196 1197 READ_UNALIGNED(dbg, initial_location, Dwarf_Addr, 1198 frame_ptr, dbg->de_pointer_size); 1199 frame_ptr += dbg->de_pointer_size; 1200 1201 READ_UNALIGNED(dbg, address_range, Dwarf_Addr, 1202 frame_ptr, dbg->de_pointer_size); 1203 frame_ptr += dbg->de_pointer_size; 1204 /* Get the augmentation string from Cie to identify the 1205 layout of this Fde. */ 1206 if (use_gnu_cie_calc) { 1207 /* cie_id value is offset, in section, of the cie_id 1208 itself, to use vm ptr of the value, less the value, 1209 to get to the cie itself. In addition, munge 1210 cie_base_offset to look *as if* it was from real 1211 dwarf. */ 1212 cieptr = cie_ptr_addr - cie_base_offset; 1213 cie_base_offset = cieptr - section_ptr; 1214 } else { 1215 /* Traditional dwarf section offset is in cie_id */ 1216 cieptr = 1217 (Dwarf_Small *) (section_ptr + cie_base_offset); 1218 } 1219 1220 1221 if (prev_augmentation_cie_ptr == cieptr && 1222 prev_augmentation_ptr != NULL) { 1223 augmentation = prev_augmentation_ptr; 1224 } else { 1225 res = get_augmentation_string(dbg, 1226 cieptr, 1227 cie_id_value, 1228 &augmentation, error); 1229 if (res != DW_DLV_OK) { 1230 return res; 1231 } 1232 prev_augmentation_cie_ptr = cieptr; 1233 prev_augmentation_ptr = augmentation; 1234 } 1235 if ((strcmp((char *) augmentation, 1236 DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) || 1237 (strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) { 1238 /* We are pointing at the start of instructions. Do 1239 nothing. */ 1240 } else if (augmentation[0] == 'z') { 1241 Dwarf_Unsigned lreg; 1242 1243 DECODE_LEB128_UWORD(frame_ptr, lreg) 1244 length_of_augmented_fields = (Dwarf_Word) lreg; 1245 1246 saved_frame_ptr = frame_ptr; 1247 if (strcmp((char *) augmentation, 1248 DW_CIE_AUGMENTER_STRING_V0) == 0) { 1249 /* The first word is an offset into execption 1250 tables. */ 1251 /* ?? THis presumes that the offset is always 32 1252 bits */ 1253 READ_UNALIGNED(dbg, offset_into_exception_tables, 1254 Dwarf_Addr, frame_ptr, 1255 sizeof(Dwarf_sfixed)); 1256 SIGN_EXTEND(offset_into_exception_tables, 1257 sizeof(Dwarf_sfixed)); 1258 frame_ptr += local_length_size; 1259 } 1260 frame_ptr = 1261 saved_frame_ptr + length_of_augmented_fields; 1262 } else if (strcmp((const char *) augmentation, "eh") == 0) { 1263 /* gnu eh fde case. we do not need to do anything */ 1264 /*REFERENCED*/ /* Not used in this instance of the macro */ 1265 Dwarf_Unsigned exception_table_addr; 1266 1267 READ_UNALIGNED(dbg, exception_table_addr, 1268 Dwarf_Unsigned, frame_ptr, 1269 dbg->de_pointer_size); 1270 frame_ptr += dbg->de_pointer_size; 1271 } else { 1272 /* We do not understand the augmentation string. No 1273 assumption can be made about if the instructions is 1274 present. */ 1275 /* FIX -- The old code assumed that the instruction 1276 table starts at the location pointed to by 1277 frame_ptr, clearly incorrect. */ 1278 } 1279 new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1); 1280 if (new_fde == NULL) { 1281 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1282 return (DW_DLV_ERROR); 1283 } 1284 1285 new_fde->fd_length = (Dwarf_Word) length; 1286 new_fde->fd_length_size = local_length_size; 1287 new_fde->fd_extension_size = local_extension_size; 1288 new_fde->fd_cie_offset = cie_base_offset; 1289 new_fde->fd_initial_location = initial_location; 1290 new_fde->fd_initial_loc_pos = initloc; 1291 new_fde->fd_address_range = address_range; 1292 new_fde->fd_fde_start = start_frame_ptr; 1293 new_fde->fd_fde_instr_start = frame_ptr; 1294 new_fde->fd_dbg = dbg; 1295 new_fde->fd_offset_into_exception_tables = 1296 offset_into_exception_tables; 1297 1298 fde_count++; 1299 if (head_fde_ptr == NULL) 1300 head_fde_ptr = cur_fde_ptr = new_fde; 1301 else { 1302 cur_fde_ptr->fd_next = new_fde; 1303 cur_fde_ptr = new_fde; 1304 } 1305 } 1306 1307 /* Skip over instructions to start of next frame. */ 1308 frame_ptr = start_frame_ptr + length + local_length_size + 1309 local_extension_size; 1310 } 1311 1312 if (cie_count > 0) { 1313 cie_list_ptr = (Dwarf_Cie *) 1314 _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count); 1315 } else { 1316 return (DW_DLV_NO_ENTRY); 1317 } 1318 if (cie_list_ptr == NULL) { 1319 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1320 return (DW_DLV_ERROR); 1321 } 1322 /* Return arguments. */ 1323 *cie_data = cie_list_ptr; 1324 *cie_element_count = cie_count; 1325 dbg->de_cie_data = cie_list_ptr; 1326 dbg->de_cie_count = cie_count; 1327 1328 cur_cie_ptr = head_cie_ptr; 1329 for (i = 0; i < cie_count; i++) { 1330 *(cie_list_ptr + i) = cur_cie_ptr; 1331 cur_cie_ptr = cur_cie_ptr->ci_next; 1332 } 1333 1334 if (fde_count > 0) { 1335 fde_list_ptr = (Dwarf_Fde *) 1336 _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count); 1337 } else { 1338 return (DW_DLV_NO_ENTRY); 1339 } 1340 if (fde_list_ptr == NULL) { 1341 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1342 return (DW_DLV_ERROR); 1343 } 1344 /* Return arguments. */ 1345 *fde_data = fde_list_ptr; 1346 *fde_element_count = fde_count; 1347 dbg->de_fde_data = fde_list_ptr; 1348 dbg->de_fde_count = fde_count; 1349 last_cie_index = 0; 1350 1351 cur_fde_ptr = head_fde_ptr; 1352 for (i = 0; i < fde_count; i++) { 1353 Dwarf_Sword new_cie_index = (Dwarf_Sword) cie_count; 1354 1355 *(fde_list_ptr + i) = cur_fde_ptr; 1356 1357 fde_cie_ptr = (Dwarf_Small *) (section_ptr + 1358 cur_fde_ptr->fd_cie_offset); 1359 1360 1361 /* we assume that the next fde has the same cie as the ** last 1362 fde and resume the search where we left off */ 1363 for (j = last_cie_index; j < cie_count; j++) { 1364 Dwarf_Cie ciep = (Dwarf_Cie) * (cie_list_ptr + j); 1365 1366 if (ciep->ci_cie_start == fde_cie_ptr) { 1367 new_cie_index = (Dwarf_Sword) j; 1368 break; 1369 } 1370 } 1371 /* did not find it above, start from 0 and try again */ 1372 if (new_cie_index == cie_count) { 1373 for (j = 0; j < last_cie_index; ++j) { 1374 Dwarf_Cie ciep = (Dwarf_Cie) * (cie_list_ptr + j); 1375 1376 if (ciep->ci_cie_start == fde_cie_ptr) { 1377 new_cie_index = (Dwarf_Sword) j; 1378 break; 1379 } 1380 } 1381 } 1382 j = new_cie_index; 1383 last_cie_index = new_cie_index; 1384 if (j == cie_count) { 1385 _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE); 1386 return (DW_DLV_ERROR); 1387 } else { 1388 cur_fde_ptr->fd_cie_index = (Dwarf_Sword) j; 1389 cur_fde_ptr->fd_cie = *(cie_list_ptr + j); 1390 } 1391 1392 cur_fde_ptr = cur_fde_ptr->fd_next; 1393 } 1394 1395 /* sort the list by the address, so that dwarf_get_fde_at_pc() can 1396 binary search this list. */ 1397 qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr), 1398 qsort_compare); 1399 1400 return (DW_DLV_OK); 1401 } 1402 1403 /* 1404 Only works on dwarf sections, not eh_frame 1405 */ 1406 int 1407 dwarf_get_fde_for_die(Dwarf_Debug dbg, 1408 Dwarf_Die die, 1409 Dwarf_Fde * ret_fde, Dwarf_Error * error) 1410 { 1411 Dwarf_Attribute attr; 1412 Dwarf_Unsigned fde_offset; 1413 Dwarf_Signed signdval; 1414 Dwarf_Unsigned length; /* must be min de_length_size bytes */ 1415 Dwarf_Signed signed_offset; /* must be min de_length_size bytes */ 1416 Dwarf_Addr initial_location; /* must be min de_pointer_size 1417 bytes */ 1418 Dwarf_Addr address_range; /* must be min de_pointer_size bytes */ 1419 Dwarf_Fde new_fde; 1420 unsigned char *fde_ptr; 1421 Dwarf_Small *saved_fde_ptr; 1422 unsigned char *cie_ptr; 1423 unsigned char *start_cie_ptr; 1424 Dwarf_Cie new_cie; 1425 1426 /* Fields for the current Cie being read. */ 1427 Dwarf_Small version; 1428 Dwarf_Small *augmentation; 1429 Dwarf_Word code_alignment_factor; 1430 Dwarf_Sword data_alignment_factor; 1431 Dwarf_Small return_address_register; 1432 Dwarf_Word length_of_augmented_fields; 1433 Dwarf_Signed offset_into_exception_tables = 1434 (Dwarf_Signed) DW_DLX_NO_EH_OFFSET; 1435 int res; 1436 int resattr; 1437 int sdatares; 1438 int fde_local_extension_size = 0; 1439 int fde_local_length_size = 0; 1440 int cie_local_extension_size = 0; 1441 int cie_local_length_size = 0; 1442 1443 1444 Dwarf_Word leb128_length; 1445 1446 if (die == NULL) { 1447 _dwarf_error(NULL, error, DW_DLE_DIE_NULL); 1448 return (DW_DLV_ERROR); 1449 } 1450 1451 resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error); 1452 if (resattr != DW_DLV_OK) { 1453 return resattr; 1454 } 1455 1456 /* why is this formsdata? FIX */ 1457 sdatares = dwarf_formsdata(attr, &signdval, error); 1458 if (sdatares != DW_DLV_OK) { 1459 return sdatares; 1460 } 1461 1462 res = 1463 _dwarf_load_section(dbg, 1464 dbg->de_debug_frame_index, 1465 &dbg->de_debug_frame, 1466 error); 1467 if (res != DW_DLV_OK) { 1468 return res; 1469 } 1470 1471 fde_offset = signdval; 1472 fde_ptr = (dbg->de_debug_frame + fde_offset); 1473 1474 /* READ_AREA_LENGTH updates fde_ptr for consumed bytes */ 1475 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, 1476 fde_ptr, fde_local_length_size, 1477 fde_local_extension_size); 1478 1479 1480 if (length % fde_local_length_size != 0) { 1481 _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); 1482 return (DW_DLV_ERROR); 1483 } 1484 1485 READ_UNALIGNED(dbg, signed_offset, Dwarf_Signed, 1486 fde_ptr, fde_local_length_size); 1487 SIGN_EXTEND(signed_offset, fde_local_length_size); 1488 fde_ptr += fde_local_length_size; 1489 1490 READ_UNALIGNED(dbg, initial_location, Dwarf_Addr, 1491 fde_ptr, dbg->de_pointer_size); 1492 fde_ptr += dbg->de_pointer_size; 1493 1494 READ_UNALIGNED(dbg, address_range, Dwarf_Addr, 1495 fde_ptr, dbg->de_pointer_size); 1496 fde_ptr += dbg->de_pointer_size; 1497 1498 res = get_augmentation_string(dbg, 1499 (Dwarf_Small *) (dbg->de_debug_frame + 1500 signed_offset), 1501 DW_CIE_ID, &augmentation, error); 1502 if (res != DW_DLV_OK) { 1503 return res; 1504 } 1505 1506 if ((strcmp((char *) augmentation, DW_DEBUG_FRAME_AUGMENTER_STRING) 1507 == 0) || 1508 (strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) { 1509 /* Do nothing. The fde_ptr is pointing at start of 1510 instructions. */ 1511 } else if (augmentation[0] == 'z') { 1512 /* The augmentation starts with a known prefix. See the 1513 dwarf_frame.h for details on the layout. */ 1514 1515 Dwarf_Unsigned lreg; 1516 1517 DECODE_LEB128_UWORD(fde_ptr, lreg) 1518 length_of_augmented_fields = (Dwarf_Word) lreg; 1519 1520 saved_fde_ptr = fde_ptr; 1521 if (strcmp((char *) augmentation, DW_CIE_AUGMENTER_STRING_V0) == 1522 0) { 1523 /* The first word is an offset into execption tables. */ 1524 READ_UNALIGNED(dbg, offset_into_exception_tables, 1525 Dwarf_Signed, fde_ptr, sizeof(Dwarf_sfixed)); 1526 SIGN_EXTEND(offset_into_exception_tables, 1527 sizeof(Dwarf_sfixed)); 1528 fde_ptr += sizeof(Dwarf_sfixed); 1529 } 1530 fde_ptr = saved_fde_ptr + length_of_augmented_fields; 1531 } else { 1532 /* We do not understand the augmentation string. No assumption 1533 can be made about if the instructions is present. */ 1534 /* FIX -- The old code assumed that the instruction table 1535 starts at location pointed to by fde_ptr, clearly incorrect. 1536 */ 1537 } 1538 1539 new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1); 1540 if (new_fde == NULL) { 1541 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1542 return (DW_DLV_ERROR); 1543 } 1544 1545 new_fde->fd_length = (Dwarf_Word) length; 1546 new_fde->fd_length_size = fde_local_length_size; 1547 new_fde->fd_extension_size = fde_local_extension_size; 1548 new_fde->fd_cie_offset = signed_offset; 1549 new_fde->fd_initial_location = initial_location; 1550 new_fde->fd_address_range = address_range; 1551 new_fde->fd_fde_start = dbg->de_debug_frame + fde_offset; 1552 new_fde->fd_fde_instr_start = (Dwarf_Small *) fde_ptr; 1553 new_fde->fd_dbg = dbg; 1554 new_fde->fd_offset_into_exception_tables = 1555 offset_into_exception_tables; 1556 1557 /* now read the cie corresponding to the fde */ 1558 cie_ptr = (dbg->de_debug_frame + signed_offset); 1559 start_cie_ptr = cie_ptr; 1560 1561 /* READ_AREA_LENGTH updates cie_ptr for consumed bytes */ 1562 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, 1563 cie_ptr, cie_local_length_size, 1564 cie_local_extension_size); 1565 1566 1567 if (length % cie_local_length_size != 0) { 1568 _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); 1569 return (DW_DLV_ERROR); 1570 } 1571 1572 READ_UNALIGNED(dbg, signed_offset, Dwarf_Signed, 1573 cie_ptr, cie_local_length_size); 1574 SIGN_EXTEND(signed_offset, cie_local_length_size); 1575 cie_ptr += cie_local_length_size; 1576 1577 if (signed_offset == DW_CIE_ID) { 1578 1579 version = *(Dwarf_Small *) cie_ptr; 1580 cie_ptr++; 1581 if (version != DW_CIE_VERSION) { 1582 _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD); 1583 return (DW_DLV_ERROR); 1584 } 1585 1586 augmentation = cie_ptr; 1587 cie_ptr = cie_ptr + strlen((char *) cie_ptr) + 1; 1588 if ((strcmp((char *) augmentation, 1589 DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) || 1590 (strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) { 1591 1592 Dwarf_Unsigned lreg; 1593 1594 DECODE_LEB128_UWORD(cie_ptr, lreg) 1595 code_alignment_factor = (Dwarf_Word) lreg; 1596 1597 1598 data_alignment_factor = (Dwarf_Sword) 1599 _dwarf_decode_s_leb128(cie_ptr, &leb128_length); 1600 cie_ptr = cie_ptr + leb128_length; 1601 1602 return_address_register = *(Dwarf_Small *) cie_ptr; 1603 if (return_address_register > DW_FRAME_LAST_REG_NUM) { 1604 _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR); 1605 return (DW_DLV_ERROR); 1606 } 1607 cie_ptr++; 1608 } else if (augmentation[0] == 'z') { 1609 /* The augmentation starts with a known prefix. We can 1610 asssume that the first field is the length of the 1611 augmented fields. */ 1612 1613 Dwarf_Unsigned lreg; 1614 1615 DECODE_LEB128_UWORD(cie_ptr, lreg) 1616 code_alignment_factor = (Dwarf_Word) lreg; 1617 data_alignment_factor = (Dwarf_Sword) 1618 _dwarf_decode_s_leb128(cie_ptr, &leb128_length); 1619 cie_ptr = cie_ptr + leb128_length; 1620 1621 return_address_register = *(Dwarf_Small *) cie_ptr; 1622 if (return_address_register > DW_FRAME_LAST_REG_NUM) { 1623 _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR); 1624 return (DW_DLV_ERROR); 1625 } 1626 cie_ptr++; 1627 /* Decode the length of augmented fields. */ 1628 DECODE_LEB128_UWORD(cie_ptr, lreg) 1629 length_of_augmented_fields = (Dwarf_Word) lreg; 1630 1631 /* set the cie_ptr to point at the instruction start. */ 1632 cie_ptr += length_of_augmented_fields; 1633 } else if (strcmp((const char *) augmentation, "eh") == 0) { 1634 Dwarf_Unsigned lreg; 1635 1636 DECODE_LEB128_UWORD(cie_ptr, lreg) 1637 code_alignment_factor = (Dwarf_Word) lreg; 1638 1639 1640 data_alignment_factor = (Dwarf_Sword) 1641 _dwarf_decode_s_leb128(cie_ptr, &leb128_length); 1642 cie_ptr = cie_ptr + leb128_length; 1643 1644 return_address_register = *(Dwarf_Small *) cie_ptr; 1645 if (return_address_register > DW_FRAME_LAST_REG_NUM) { 1646 _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR); 1647 return (DW_DLV_ERROR); 1648 } 1649 cie_ptr++; 1650 1651 } else { 1652 /* We do not understand the augmentation string. No 1653 assumption can be made about any fields other than what 1654 we have already read. */ 1655 cie_ptr = start_cie_ptr + length + cie_local_length_size 1656 + cie_local_extension_size; 1657 /* FIX -- What are the values of data_alignment_factor, 1658 code_alignement_factor, return_address_register and 1659 instruction start? They were clearly uninitalized in 1660 the previous version and I am leaving them the same way. 1661 */ 1662 } 1663 1664 new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1); 1665 if (new_cie == NULL) { 1666 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1667 return (DW_DLV_ERROR); 1668 } 1669 1670 new_cie->ci_initial_table = NULL; 1671 new_cie->ci_length = (Dwarf_Word) length; 1672 new_cie->ci_length_size = cie_local_length_size; 1673 new_cie->ci_extension_size = cie_local_extension_size; 1674 new_cie->ci_augmentation = (char *) augmentation; 1675 new_cie->ci_data_alignment_factor = 1676 (Dwarf_Sbyte) data_alignment_factor; 1677 new_cie->ci_code_alignment_factor = 1678 (Dwarf_Small) code_alignment_factor; 1679 new_cie->ci_return_address_register = return_address_register; 1680 new_cie->ci_cie_start = start_cie_ptr; 1681 new_cie->ci_cie_instr_start = cie_ptr; 1682 new_cie->ci_dbg = dbg; 1683 } else { 1684 _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE); 1685 return (DW_DLV_ERROR); 1686 } 1687 new_fde->fd_cie = new_cie; 1688 1689 *ret_fde = new_fde; 1690 return DW_DLV_OK; 1691 } 1692 1693 1694 int 1695 dwarf_get_fde_range(Dwarf_Fde fde, 1696 Dwarf_Addr * low_pc, 1697 Dwarf_Unsigned * func_length, 1698 Dwarf_Ptr * fde_bytes, 1699 Dwarf_Unsigned * fde_byte_length, 1700 Dwarf_Off * cie_offset, 1701 Dwarf_Signed * cie_index, 1702 Dwarf_Off * fde_offset, Dwarf_Error * error) 1703 { 1704 int res; 1705 Dwarf_Debug dbg; 1706 1707 if (fde == NULL) { 1708 _dwarf_error(NULL, error, DW_DLE_FDE_NULL); 1709 return (DW_DLV_ERROR); 1710 } 1711 1712 dbg = fde->fd_dbg; 1713 if (dbg == NULL) { 1714 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); 1715 return (DW_DLV_ERROR); 1716 } 1717 1718 res = 1719 _dwarf_load_section(dbg, 1720 dbg->de_debug_frame_index, 1721 &dbg->de_debug_frame, 1722 error); 1723 if (res != DW_DLV_OK) { 1724 return res; 1725 } 1726 1727 if (low_pc != NULL) 1728 *low_pc = fde->fd_initial_location; 1729 if (func_length != NULL) 1730 *func_length = fde->fd_address_range; 1731 if (fde_bytes != NULL) 1732 *fde_bytes = fde->fd_fde_start; 1733 if (fde_byte_length != NULL) 1734 *fde_byte_length = fde->fd_length; 1735 if (cie_offset != NULL) 1736 *cie_offset = fde->fd_cie_offset; 1737 if (cie_index != NULL) 1738 *cie_index = fde->fd_cie_index; 1739 if (fde_offset != NULL) 1740 *fde_offset = fde->fd_fde_start - dbg->de_debug_frame; 1741 1742 return DW_DLV_OK; 1743 } 1744 1745 int 1746 dwarf_get_fde_exception_info(Dwarf_Fde fde, 1747 Dwarf_Signed * 1748 offset_into_exception_tables, 1749 Dwarf_Error * error) 1750 { 1751 Dwarf_Debug dbg; 1752 1753 dbg = fde->fd_dbg; 1754 if (dbg == NULL) { 1755 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); 1756 return (DW_DLV_ERROR); 1757 } 1758 *offset_into_exception_tables = 1759 fde->fd_offset_into_exception_tables; 1760 return DW_DLV_OK; 1761 } 1762 1763 1764 int 1765 dwarf_get_cie_info(Dwarf_Cie cie, 1766 Dwarf_Unsigned * bytes_in_cie, 1767 Dwarf_Small * version, 1768 char **augmenter, 1769 Dwarf_Unsigned * code_alignment_factor, 1770 Dwarf_Signed * data_alignment_factor, 1771 Dwarf_Half * return_address_register, 1772 Dwarf_Ptr * initial_instructions, 1773 Dwarf_Unsigned * initial_instructions_length, 1774 Dwarf_Error * error) 1775 { 1776 Dwarf_Debug dbg; 1777 1778 if (cie == NULL) { 1779 _dwarf_error(NULL, error, DW_DLE_CIE_NULL); 1780 return (DW_DLV_ERROR); 1781 } 1782 1783 dbg = cie->ci_dbg; 1784 if (dbg == NULL) { 1785 _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL); 1786 return (DW_DLV_ERROR); 1787 } 1788 1789 if (version != NULL) 1790 *version = DW_CIE_VERSION; 1791 if (augmenter != NULL) 1792 *augmenter = cie->ci_augmentation; 1793 if (code_alignment_factor != NULL) 1794 *code_alignment_factor = cie->ci_code_alignment_factor; 1795 if (data_alignment_factor != NULL) 1796 *data_alignment_factor = cie->ci_data_alignment_factor; 1797 if (return_address_register != NULL) 1798 *return_address_register = cie->ci_return_address_register; 1799 if (initial_instructions != NULL) 1800 *initial_instructions = cie->ci_cie_instr_start; 1801 if (initial_instructions_length != NULL) { 1802 *initial_instructions_length = cie->ci_length + 1803 cie->ci_length_size + 1804 cie->ci_extension_size - 1805 (cie->ci_cie_instr_start - cie->ci_cie_start); 1806 1807 } 1808 *bytes_in_cie = (cie->ci_length); 1809 return (DW_DLV_OK); 1810 } 1811 1812 static int 1813 _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde, 1814 Dwarf_Addr pc_requested, 1815 Dwarf_Frame table, Dwarf_Error * error) 1816 /* Return the register rules for all registers at a given pc. */ 1817 { 1818 Dwarf_Debug dbg; 1819 Dwarf_Cie cie; 1820 Dwarf_Sword i; 1821 int dw_err; 1822 Dwarf_Sword icount; 1823 int res; 1824 1825 if (fde == NULL) { 1826 _dwarf_error(NULL, error, DW_DLE_FDE_NULL); 1827 return (DW_DLV_ERROR); 1828 } 1829 1830 dbg = fde->fd_dbg; 1831 if (dbg == NULL) { 1832 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); 1833 return (DW_DLV_ERROR); 1834 } 1835 1836 if (pc_requested < fde->fd_initial_location || 1837 pc_requested >= 1838 fde->fd_initial_location + fde->fd_address_range) { 1839 _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); 1840 return (DW_DLV_ERROR); 1841 } 1842 1843 cie = fde->fd_cie; 1844 if (cie->ci_initial_table == NULL) { 1845 cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1); 1846 if (cie->ci_initial_table == NULL) { 1847 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1848 return (DW_DLV_ERROR); 1849 } 1850 for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++) { 1851 cie->ci_initial_table->fr_reg[i].ru_is_off = 0; 1852 cie->ci_initial_table->fr_reg[i].ru_register = 1853 DW_FRAME_SAME_VAL; 1854 cie->ci_initial_table->fr_reg[i].ru_offset = 0; 1855 } 1856 1857 res = _dwarf_exec_frame_instr( /* make_instr= */ false, 1858 /* ret_frame_instr= */ NULL, 1859 /* search_pc */ false, 1860 /* search_pc_val */ 0, 1861 /* location */ 0, 1862 cie->ci_cie_instr_start, 1863 cie->ci_cie_instr_start + 1864 (cie->ci_length + 1865 cie->ci_length_size + 1866 cie->ci_extension_size - 1867 (cie->ci_cie_instr_start - 1868 cie->ci_cie_start)), 1869 cie->ci_initial_table, cie, dbg, 1870 &icount, &dw_err); 1871 if (res == DW_DLV_ERROR) { 1872 _dwarf_error(dbg, error, dw_err); 1873 return (res); 1874 } else if (res == DW_DLV_NO_ENTRY) { 1875 return res; 1876 } 1877 } 1878 1879 res = _dwarf_exec_frame_instr( /* make_instr= */ false, 1880 /* ret_frame_instr= */ NULL, 1881 /* search_pc */ true, 1882 /* search_pc_val */ pc_requested, 1883 fde->fd_initial_location, 1884 fde->fd_fde_instr_start, 1885 fde->fd_fde_start + fde->fd_length + 1886 fde->fd_length_size + 1887 fde->fd_extension_size, 1888 table, cie, dbg, &icount, &dw_err); 1889 if (res == DW_DLV_ERROR) { 1890 _dwarf_error(dbg, error, dw_err); 1891 return (res); 1892 } else if (res == DW_DLV_NO_ENTRY) { 1893 return res; 1894 } 1895 1896 return DW_DLV_OK; 1897 } 1898 1899 int 1900 dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, 1901 Dwarf_Addr pc_requested, 1902 Dwarf_Regtable * reg_table, 1903 Dwarf_Addr * row_pc, 1904 Dwarf_Error * error) 1905 { 1906 1907 struct Dwarf_Frame_s fde_table; 1908 Dwarf_Sword i; 1909 int res; 1910 1911 /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 1912 */ 1913 res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, 1914 &fde_table, error); 1915 if (res != DW_DLV_OK) { 1916 return res; 1917 } 1918 1919 for (i = 0; i < DW_REG_TABLE_SIZE; i++) { 1920 reg_table->rules[i].dw_offset_relevant = 1921 fde_table.fr_reg[i].ru_is_off; 1922 reg_table->rules[i].dw_regnum = fde_table.fr_reg[i].ru_register; 1923 reg_table->rules[i].dw_offset = fde_table.fr_reg[i].ru_offset; 1924 } 1925 1926 if (row_pc != NULL) 1927 *row_pc = fde_table.fr_loc; 1928 1929 return DW_DLV_OK; 1930 } 1931 1932 1933 int 1934 dwarf_get_fde_info_for_reg(Dwarf_Fde fde, 1935 Dwarf_Half table_column, 1936 Dwarf_Addr pc_requested, 1937 Dwarf_Signed * offset_relevant, 1938 Dwarf_Signed * register_num, 1939 Dwarf_Signed * offset, 1940 Dwarf_Addr * row_pc, Dwarf_Error * error) 1941 { 1942 struct Dwarf_Frame_s fde_table; 1943 int res; 1944 1945 1946 if (table_column > DW_FRAME_LAST_REG_NUM) { 1947 _dwarf_error(NULL, error, DW_DLE_FRAME_TABLE_COL_BAD); 1948 return (DW_DLV_ERROR); 1949 } 1950 1951 /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 1952 */ 1953 res = 1954 _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table, 1955 error); 1956 if (res != DW_DLV_OK) { 1957 return res; 1958 } 1959 1960 if (register_num != NULL) 1961 *register_num = fde_table.fr_reg[table_column].ru_register; 1962 if (offset != NULL) 1963 *offset = fde_table.fr_reg[table_column].ru_offset; 1964 if (row_pc != NULL) 1965 *row_pc = fde_table.fr_loc; 1966 1967 *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off); 1968 return DW_DLV_OK; 1969 } 1970 1971 /* 1972 Return pointer to the instructions in the dwarf 1973 fde. 1974 */ 1975 int 1976 dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr, 1977 Dwarf_Unsigned * outaddrlen, 1978 Dwarf_Error * error) 1979 { 1980 Dwarf_Unsigned len; 1981 unsigned char *instrs; 1982 Dwarf_Debug dbg; 1983 1984 if (inFde == NULL) { 1985 _dwarf_error(NULL, error, DW_DLE_FDE_NULL); 1986 return (DW_DLV_ERROR); 1987 } 1988 1989 dbg = inFde->fd_dbg; 1990 if (dbg == NULL) { 1991 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); 1992 return (DW_DLV_ERROR); 1993 } 1994 1995 instrs = inFde->fd_fde_instr_start, 1996 len = (inFde->fd_fde_start + inFde->fd_length + 1997 inFde->fd_length_size + inFde->fd_extension_size) 1998 - instrs; 1999 2000 *outinstraddr = instrs; 2001 *outaddrlen = len; 2002 return DW_DLV_OK; 2003 } 2004 2005 int 2006 dwarf_get_fde_n(Dwarf_Fde * fde_data, 2007 Dwarf_Unsigned fde_index, 2008 Dwarf_Fde * returned_fde, Dwarf_Error * error) 2009 { 2010 Dwarf_Debug dbg; 2011 2012 if (fde_data == NULL) { 2013 _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL); 2014 return (DW_DLV_ERROR); 2015 } 2016 2017 if (*fde_data == NULL) { 2018 _dwarf_error(NULL, error, DW_DLE_FDE_NULL); 2019 return (DW_DLV_ERROR); 2020 } 2021 2022 dbg = (*fde_data)->fd_dbg; 2023 if (dbg == NULL) { 2024 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); 2025 return (DW_DLV_ERROR); 2026 } 2027 2028 if (fde_index >= dbg->de_fde_count) { 2029 return (DW_DLV_NO_ENTRY); 2030 } 2031 *returned_fde = (*(fde_data + fde_index)); 2032 return DW_DLV_OK; 2033 } 2034 2035 2036 /* 2037 Lopc and hipc are extensions to the interface to 2038 return the range of addresses that are described 2039 by the returned fde. 2040 */ 2041 int 2042 dwarf_get_fde_at_pc(Dwarf_Fde * fde_data, 2043 Dwarf_Addr pc_of_interest, 2044 Dwarf_Fde * returned_fde, 2045 Dwarf_Addr * lopc, 2046 Dwarf_Addr * hipc, Dwarf_Error * error) 2047 { 2048 Dwarf_Debug dbg; 2049 Dwarf_Fde fde = NULL; 2050 2051 if (fde_data == NULL) { 2052 _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL); 2053 return (DW_DLV_ERROR); 2054 } 2055 2056 if (*fde_data == NULL) { 2057 _dwarf_error(NULL, error, DW_DLE_FDE_NULL); 2058 return (DW_DLV_ERROR); 2059 } 2060 2061 dbg = (*fde_data)->fd_dbg; 2062 if (dbg == NULL) { 2063 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL); 2064 return (DW_DLV_ERROR); 2065 } 2066 { 2067 /* The fde's are sorted by their addresses. Binary search to 2068 find correct fde. */ 2069 int low = 0; 2070 int high = dbg->de_fde_count - 1; 2071 int middle = 0; 2072 Dwarf_Fde cur_fde; 2073 2074 while (low <= high) { 2075 middle = (low + high) / 2; 2076 cur_fde = fde_data[middle]; 2077 if (pc_of_interest < cur_fde->fd_initial_location) { 2078 high = middle - 1; 2079 } else if (pc_of_interest >= 2080 (cur_fde->fd_initial_location + 2081 cur_fde->fd_address_range)) { 2082 low = middle + 1; 2083 } else { 2084 fde = fde_data[middle]; 2085 break; 2086 } 2087 } 2088 } 2089 2090 if (fde) { 2091 if (lopc != NULL) 2092 *lopc = fde->fd_initial_location; 2093 if (hipc != NULL) 2094 *hipc = fde->fd_initial_location + 2095 fde->fd_address_range - 1; 2096 *returned_fde = fde; 2097 return (DW_DLV_OK); 2098 } 2099 2100 return (DW_DLV_NO_ENTRY); 2101 } 2102 2103 2104 int 2105 dwarf_expand_frame_instructions(Dwarf_Debug dbg, 2106 Dwarf_Ptr instruction, 2107 Dwarf_Unsigned i_length, 2108 Dwarf_Frame_Op ** returned_op_list, 2109 Dwarf_Signed * returned_op_count, 2110 Dwarf_Error * error) 2111 { 2112 Dwarf_Sword instr_count; 2113 int res; 2114 int dw_err; 2115 2116 if (dbg == 0) { 2117 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 2118 return (DW_DLV_ERROR); 2119 } 2120 2121 if (returned_op_list == 0 || returned_op_count == 0) { 2122 _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL); 2123 return (DW_DLV_ERROR); 2124 } 2125 2126 /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe 2127 as it is just an i_length offset from 'instruction' itself. A 2128 caller has made a big mistake if the result is not a valid 2129 pointer. */ 2130 res = _dwarf_exec_frame_instr( /* make_instr= */ true, 2131 returned_op_list, 2132 /* search_pc */ false, 2133 /* search_pc_val */ 0, 2134 /* location */ 0, 2135 instruction, 2136 (Dwarf_Ptr)((char *)instruction + i_length), 2137 /* Dwarf_Frame */ NULL, 2138 /* cie_ptr */ NULL, 2139 dbg, &instr_count, &dw_err); 2140 if (res != DW_DLV_OK) { 2141 if (res == DW_DLV_ERROR) { 2142 _dwarf_error(dbg, error, dw_err); 2143 } 2144 return (res); 2145 } 2146 2147 *returned_op_count = instr_count; 2148 return DW_DLV_OK; 2149 } 2150 2151 2152 2153 /* 2154 Used by rqs. Returns DW_DLV_OK if returns the arrays. 2155 Returns DW_DLV_NO_ENTRY if no section. ?? (How do I tell?) 2156 Returns DW_DLV_ERROR if there is an error. 2157 2158 */ 2159 int 2160 _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist, 2161 Dwarf_Off ** offsetlist, 2162 Dwarf_Signed * returncount, 2163 Dwarf_Error * err) 2164 { 2165 int retval = DW_DLV_OK; 2166 int res; 2167 Dwarf_Cie *cie_data; 2168 Dwarf_Signed cie_count; 2169 Dwarf_Fde *fde_data; 2170 Dwarf_Signed fde_count; 2171 Dwarf_Signed i; 2172 Dwarf_Frame_Op *frame_inst; 2173 Dwarf_Fde fdep; 2174 Dwarf_Cie ciep; 2175 Dwarf_Chain curr_chain = 0; 2176 Dwarf_Chain head_chain = 0; 2177 Dwarf_Chain prev_chain = 0; 2178 Dwarf_Arange arange; 2179 Dwarf_Unsigned arange_count = 0; 2180 Dwarf_Addr *arange_addrs = 0; 2181 Dwarf_Off *arange_offsets = 0; 2182 2183 res = dwarf_get_fde_list(dbg, &cie_data, &cie_count, 2184 &fde_data, &fde_count, err); 2185 if (res != DW_DLV_OK) { 2186 return res; 2187 } 2188 2189 res = 2190 _dwarf_load_section(dbg, 2191 dbg->de_debug_frame_index, 2192 &dbg->de_debug_frame, 2193 err); 2194 if (res != DW_DLV_OK) { 2195 return res; 2196 } 2197 2198 for (i = 0; i < cie_count; i++) { 2199 Dwarf_Off instoff = 0; 2200 Dwarf_Signed initial_instructions_length = 0; 2201 Dwarf_Small *instr_end = 0; 2202 Dwarf_Sword icount = 0; 2203 int j; 2204 int dw_err; 2205 2206 ciep = cie_data[i]; 2207 instoff = ciep->ci_cie_instr_start - dbg->de_debug_frame; 2208 initial_instructions_length = ciep->ci_length + 2209 ciep->ci_length_size + ciep->ci_extension_size - 2210 (ciep->ci_cie_instr_start - ciep->ci_cie_start); 2211 instr_end = ciep->ci_cie_instr_start + 2212 initial_instructions_length; 2213 res = _dwarf_exec_frame_instr( /* make_instr */ true, 2214 &frame_inst, 2215 /* search_pc= */ false, 2216 /* search_pc_val= */ 0, 2217 /* location */ 0, 2218 ciep->ci_cie_instr_start, 2219 instr_end, 2220 /* Dwarf_frame= */ 0, 2221 /* cie= */ 0, 2222 dbg, &icount, &dw_err); 2223 if (res == DW_DLV_ERROR) { 2224 _dwarf_error(dbg, err, dw_err); 2225 return (res); 2226 } else if (res == DW_DLV_NO_ENTRY) { 2227 continue; 2228 } 2229 2230 for (j = 0; j < icount; ++j) { 2231 Dwarf_Frame_Op *finst = frame_inst + j; 2232 2233 if (finst->fp_base_op == 0 && finst->fp_extended_op == 1) { 2234 /* is DW_CFA_set_loc */ 2235 Dwarf_Addr add = (Dwarf_Addr) finst->fp_offset; 2236 Dwarf_Off off = finst->fp_instr_offset + instoff; 2237 2238 arange = (Dwarf_Arange) 2239 _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); 2240 if (arange == NULL) { 2241 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 2242 return (DW_DLV_ERROR); 2243 } 2244 arange->ar_address = add; 2245 arange->ar_info_offset = off; 2246 arange_count++; 2247 curr_chain = (Dwarf_Chain) 2248 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 2249 if (curr_chain == NULL) { 2250 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 2251 return (DW_DLV_ERROR); 2252 } 2253 curr_chain->ch_item = arange; 2254 if (head_chain == NULL) 2255 head_chain = prev_chain = curr_chain; 2256 else { 2257 prev_chain->ch_next = curr_chain; 2258 prev_chain = curr_chain; 2259 } 2260 } 2261 } 2262 dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK); 2263 2264 } 2265 for (i = 0; i < fde_count; i++) { 2266 Dwarf_Small *instr_end = 0; 2267 Dwarf_Sword icount = 0; 2268 Dwarf_Signed instructions_length = 0; 2269 Dwarf_Off instoff = 0; 2270 Dwarf_Off off = 0; 2271 Dwarf_Addr addr = 0; 2272 int j; 2273 int dw_err; 2274 2275 fdep = fde_data[i]; 2276 off = fdep->fd_initial_loc_pos - dbg->de_debug_frame; 2277 addr = fdep->fd_initial_location; 2278 arange = (Dwarf_Arange) 2279 _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); 2280 if (arange == NULL) { 2281 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 2282 return (DW_DLV_ERROR); 2283 } 2284 arange->ar_address = addr; 2285 arange->ar_info_offset = off; 2286 arange_count++; 2287 curr_chain = (Dwarf_Chain) 2288 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 2289 if (curr_chain == NULL) { 2290 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 2291 return (DW_DLV_ERROR); 2292 } 2293 curr_chain->ch_item = arange; 2294 if (head_chain == NULL) 2295 head_chain = prev_chain = curr_chain; 2296 else { 2297 prev_chain->ch_next = curr_chain; 2298 prev_chain = curr_chain; 2299 } 2300 2301 2302 instoff = fdep->fd_fde_instr_start - dbg->de_debug_frame; 2303 instructions_length = fdep->fd_length + 2304 fdep->fd_length_size + fdep->fd_extension_size - 2305 (fdep->fd_fde_instr_start - fdep->fd_fde_start); 2306 instr_end = fdep->fd_fde_instr_start + instructions_length; 2307 res = _dwarf_exec_frame_instr( /* make_instr */ true, 2308 &frame_inst, 2309 /* search_pc= */ false, 2310 /* search_pc_val= */ 0, 2311 /* location */ 0, 2312 fdep->fd_fde_instr_start, 2313 instr_end, 2314 /* Dwarf_frame= */ 0, 2315 /* cie= */ 0, 2316 dbg, &icount, &dw_err); 2317 if (res == DW_DLV_ERROR) { 2318 _dwarf_error(dbg, err, dw_err); 2319 return (res); 2320 } else if (res == DW_DLV_NO_ENTRY) { 2321 continue; 2322 } 2323 2324 for (j = 0; j < icount; ++j) { 2325 Dwarf_Frame_Op *finst2 = frame_inst + j; 2326 2327 if (finst2->fp_base_op == 0 && finst2->fp_extended_op == 1) { 2328 /* is DW_CFA_set_loc */ 2329 Dwarf_Addr add = (Dwarf_Addr) finst2->fp_offset; 2330 Dwarf_Off off = finst2->fp_instr_offset + instoff; 2331 2332 arange = (Dwarf_Arange) 2333 _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); 2334 if (arange == NULL) { 2335 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 2336 return (DW_DLV_ERROR); 2337 } 2338 arange->ar_address = add; 2339 arange->ar_info_offset = off; 2340 arange_count++; 2341 curr_chain = (Dwarf_Chain) 2342 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 2343 if (curr_chain == NULL) { 2344 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 2345 return (DW_DLV_ERROR); 2346 } 2347 curr_chain->ch_item = arange; 2348 if (head_chain == NULL) 2349 head_chain = prev_chain = curr_chain; 2350 else { 2351 prev_chain->ch_next = curr_chain; 2352 prev_chain = curr_chain; 2353 } 2354 2355 } 2356 } 2357 dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK); 2358 2359 } 2360 dwarf_dealloc(dbg, fde_data, DW_DLA_LIST); 2361 dwarf_dealloc(dbg, cie_data, DW_DLA_LIST); 2362 arange_addrs = (Dwarf_Addr *) 2363 _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); 2364 if (arange_addrs == NULL) { 2365 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 2366 return (DW_DLV_ERROR); 2367 } 2368 arange_offsets = (Dwarf_Off *) 2369 _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); 2370 if (arange_offsets == NULL) { 2371 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 2372 return (DW_DLV_ERROR); 2373 } 2374 2375 curr_chain = head_chain; 2376 for (i = 0; i < arange_count; i++) { 2377 Dwarf_Arange ar = curr_chain->ch_item; 2378 2379 arange_addrs[i] = ar->ar_address; 2380 arange_offsets[i] = ar->ar_info_offset; 2381 prev_chain = curr_chain; 2382 curr_chain = curr_chain->ch_next; 2383 dwarf_dealloc(dbg, ar, DW_DLA_ARANGE); 2384 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); 2385 } 2386 *returncount = arange_count; 2387 *offsetlist = arange_offsets; 2388 *addrlist = arange_addrs; 2389 return retval; 2390 } 2391 2392 /* Used by dwarfdump -v to print offsets, for debugging 2393 dwarf info 2394 */ 2395 /* ARGSUSED 4 */ 2396 int 2397 _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde, 2398 Dwarf_Off * fde_off, Dwarf_Off * cie_off, 2399 Dwarf_Error * err) 2400 { 2401 int res; 2402 char *start; 2403 char *loc; 2404 2405 res = 2406 _dwarf_load_section(dbg, 2407 dbg->de_debug_frame_index, 2408 &dbg->de_debug_frame, 2409 err); 2410 if (res != DW_DLV_OK) { 2411 return res; 2412 } 2413 2414 start = (char *) dbg->de_debug_frame; 2415 loc = (char *) in_fde->fd_fde_start; 2416 2417 *fde_off = (loc - start); 2418 *cie_off = in_fde->fd_cie_offset; 2419 return DW_DLV_OK; 2420 } 2421 2422 /* Used by dwarfdump -v to print offsets, for debugging 2423 dwarf info 2424 */ 2425 /* ARGSUSED 4 */ 2426 int 2427 _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie, 2428 Dwarf_Off * cie_off, Dwarf_Error * err) 2429 { 2430 int res; 2431 char *start; 2432 char *loc; 2433 2434 res = 2435 _dwarf_load_section(dbg, 2436 dbg->de_debug_frame_index, 2437 &dbg->de_debug_frame, 2438 err); 2439 if (res != DW_DLV_OK) { 2440 return res; 2441 } 2442 2443 start = (char *) dbg->de_debug_frame; 2444 loc = (char *) in_cie->ci_cie_start; 2445 2446 *cie_off = (loc - start); 2447 return DW_DLV_OK; 2448 } 2449