00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "config.h"
00043 #include "dwarf_incl.h"
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include "dwarf_frame.h"
00047 #include "dwarf_arange.h"
00048
00049
00050
00051 static int
00052 __dwarf_get_fde_list_internal(Dwarf_Debug dbg,
00053 Dwarf_Cie ** cie_data,
00054 Dwarf_Signed * cie_element_count,
00055 Dwarf_Fde ** fde_data,
00056 Dwarf_Signed * fde_element_count,
00057 Dwarf_Small * section_ptr,
00058 Dwarf_Unsigned section_length,
00059 Dwarf_Unsigned section_index,
00060 Dwarf_Unsigned cie_id_value,
00061 int use_gnu_cie_calc,
00062 Dwarf_Error * error);
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 static int
00114 _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
00115
00116 Dwarf_Frame_Op ** ret_frame_instr,
00117
00118
00119
00120
00121
00122
00123
00124
00125 Dwarf_Bool search_pc,
00126
00127 Dwarf_Addr search_pc_val,
00128
00129
00130 Dwarf_Addr loc,
00131 Dwarf_Small * start_instr_ptr,
00132
00133
00134 Dwarf_Small * final_instr_ptr,
00135
00136
00137 Dwarf_Frame table,
00138
00139 Dwarf_Cie cie,
00140
00141 Dwarf_Debug dbg,
00142
00143 Dwarf_Sword * returned_count,
00144 int *returned_error)
00145 {
00146
00147 Dwarf_Small *instr_ptr;
00148
00149
00150 Dwarf_Small instr, opcode;
00151 Dwarf_Small reg_no, reg_noA, reg_noB;
00152 Dwarf_Unsigned factored_N_value;
00153 Dwarf_Addr new_loc;
00154 Dwarf_Unsigned adv_loc;
00155
00156
00157
00158 struct Dwarf_Reg_Rule_s reg[DW_FRAME_LAST_REG_NUM];
00159
00160
00161
00162
00163
00164 Dwarf_Bool search_over = false;
00165
00166
00167
00168 Dwarf_Addr adv_pc;
00169
00170
00171
00172 Dwarf_Word leb128_length;
00173
00174
00175 Dwarf_Word instr_count = 0;
00176
00177
00178
00179
00180 Dwarf_Small fp_base_op = 0;
00181 Dwarf_Small fp_extended_op;
00182 Dwarf_Half fp_register;
00183 Dwarf_Unsigned fp_offset;
00184 Dwarf_Off fp_instr_offset;
00185
00186
00187
00188
00189
00190 Dwarf_Frame stack_table;
00191 Dwarf_Frame top_stack = NULL;
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 Dwarf_Frame_Op *curr_instr;
00202 Dwarf_Chain curr_instr_item, dealloc_instr_item;
00203 Dwarf_Chain head_instr_chain = NULL;
00204 Dwarf_Chain tail_instr_chain = NULL;
00205 Dwarf_Frame_Op *head_instr_block;
00206
00207
00208
00209
00210
00211 Dwarf_Sword code_alignment_factor = 1;
00212 Dwarf_Sword data_alignment_factor = 1;
00213
00214
00215
00216
00217
00218
00219 Dwarf_Bool need_augmentation = false;
00220
00221 Dwarf_Word i;
00222
00223
00224
00225 struct Dwarf_Reg_Rule_s *t1reg;
00226 struct Dwarf_Reg_Rule_s *t1end;
00227 struct Dwarf_Reg_Rule_s *t2reg;
00228
00229
00230 t1reg = reg;
00231 t1end = t1reg + DW_FRAME_LAST_REG_NUM;
00232 if (cie != NULL && cie->ci_initial_table != NULL) {
00233 t2reg = cie->ci_initial_table->fr_reg;
00234 for (; t1reg < t1end; t1reg++, t2reg++) {
00235 *t1reg = *t2reg;
00236 }
00237 } else {
00238 for (; t1reg < t1end; t1reg++) {
00239 t1reg->ru_is_off = 0;
00240 t1reg->ru_register = DW_FRAME_SAME_VAL;
00241 t1reg->ru_offset = 0;
00242 }
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 if (cie != NULL && cie->ci_augmentation != NULL) {
00252 code_alignment_factor = cie->ci_code_alignment_factor;
00253 data_alignment_factor = cie->ci_data_alignment_factor;
00254 } else
00255 need_augmentation = !make_instr;
00256
00257 instr_ptr = start_instr_ptr;
00258 while ((instr_ptr < final_instr_ptr) && (!search_over)) {
00259
00260
00261 fp_instr_offset = instr_ptr - start_instr_ptr;
00262 instr = *(Dwarf_Small *) instr_ptr;
00263 instr_ptr += sizeof(Dwarf_Small);
00264
00265 fp_base_op = (instr & 0xc0) >> 6;
00266 if ((instr & 0xc0) == 0x00) {
00267 opcode = instr;
00268 fp_extended_op = (instr & (~(0xc0))) & 0xff;
00269 } else {
00270 opcode = instr & 0xc0;
00271 fp_extended_op = 0;
00272 }
00273
00274 fp_register = 0;
00275 fp_offset = 0;
00276 switch (opcode) {
00277
00278 case DW_CFA_advance_loc:{
00279
00280 fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
00281
00282 if (need_augmentation) {
00283
00284 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
00285 return DW_DLV_ERROR;
00286 }
00287 adv_pc = adv_pc * code_alignment_factor;
00288
00289 search_over = search_pc &&
00290 (loc + adv_pc > search_pc_val);
00291
00292 if (!search_over)
00293 loc = loc + adv_pc;
00294 break;
00295 }
00296
00297 case DW_CFA_offset:{
00298 reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
00299 if (reg_no > DW_FRAME_LAST_REG_NUM) {
00300 *returned_error = DW_DLE_DF_REG_NUM_TOO_HIGH;
00301 return DW_DLV_ERROR;
00302 }
00303
00304 factored_N_value =
00305 _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
00306 instr_ptr = instr_ptr + leb128_length;
00307
00308 fp_register = reg_no;
00309 fp_offset = factored_N_value;
00310
00311 if (need_augmentation) {
00312 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
00313 return DW_DLV_ERROR;
00314 }
00315
00316 reg[reg_no].ru_is_off = 1;
00317 reg[reg_no].ru_register = DW_FRAME_CFA_COL;
00318 reg[reg_no].ru_offset = factored_N_value *
00319 data_alignment_factor;
00320
00321 break;
00322 }
00323
00324 case DW_CFA_restore:{
00325 reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
00326 if (reg_no > DW_FRAME_LAST_REG_NUM) {
00327 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
00328 return DW_DLV_ERROR;
00329 }
00330
00331 fp_register = reg_no;
00332
00333 if (cie != NULL && cie->ci_initial_table != NULL)
00334 reg[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
00335 else if (!make_instr) {
00336 *returned_error = (DW_DLE_DF_MAKE_INSTR_NO_INIT);
00337 return DW_DLV_ERROR;
00338 }
00339
00340 break;
00341 }
00342 case DW_CFA_set_loc:{
00343 READ_UNALIGNED(dbg, new_loc, Dwarf_Addr,
00344 instr_ptr, dbg->de_pointer_size);
00345 instr_ptr += dbg->de_pointer_size;
00346 if (new_loc <= loc) {
00347 *returned_error = (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
00348 return DW_DLV_ERROR;
00349 }
00350
00351 search_over = search_pc && (new_loc > search_pc_val);
00352
00353
00354 if (!search_over)
00355 loc = new_loc;
00356 fp_offset = new_loc;
00357 break;
00358 }
00359
00360 case DW_CFA_advance_loc1:{
00361 fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr;
00362 instr_ptr += sizeof(Dwarf_Small);
00363
00364 if (need_augmentation) {
00365 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
00366 return DW_DLV_ERROR;
00367 }
00368 adv_loc *= code_alignment_factor;
00369
00370 search_over = search_pc &&
00371 (loc + adv_loc > search_pc_val);
00372
00373
00374 if (!search_over)
00375 loc = loc + adv_loc;
00376 break;
00377 }
00378
00379 case DW_CFA_advance_loc2:{
00380 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
00381 instr_ptr, sizeof(Dwarf_Half));
00382 instr_ptr += sizeof(Dwarf_Half);
00383 fp_offset = adv_loc;
00384
00385 if (need_augmentation) {
00386 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
00387 return DW_DLV_ERROR;
00388 }
00389 adv_loc *= code_alignment_factor;
00390
00391 search_over = search_pc &&
00392 (loc + adv_loc > search_pc_val);
00393
00394
00395 if (!search_over)
00396 loc = loc + adv_loc;
00397 break;
00398 }
00399
00400 case DW_CFA_advance_loc4:{
00401 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
00402 instr_ptr, sizeof(Dwarf_ufixed));
00403 instr_ptr += sizeof(Dwarf_ufixed);
00404 fp_offset = adv_loc;
00405
00406 if (need_augmentation) {
00407 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
00408 return DW_DLV_ERROR;
00409 }
00410 adv_loc *= code_alignment_factor;
00411
00412 search_over = search_pc &&
00413 (loc + adv_loc > search_pc_val);
00414
00415
00416 if (!search_over)
00417 loc = loc + adv_loc;
00418 break;
00419 }
00420
00421 case DW_CFA_offset_extended:{
00422 Dwarf_Unsigned lreg;
00423
00424 DECODE_LEB128_UWORD(instr_ptr, lreg)
00425 reg_no = (Dwarf_Small) lreg;
00426 if (reg_no > DW_FRAME_LAST_REG_NUM) {
00427 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
00428 return DW_DLV_ERROR;
00429 }
00430 factored_N_value =
00431 _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
00432 instr_ptr += leb128_length;
00433
00434 if (need_augmentation) {
00435 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
00436 return DW_DLV_ERROR;
00437 }
00438 reg[reg_no].ru_is_off = 1;
00439 reg[reg_no].ru_register = DW_FRAME_CFA_COL;
00440 reg[reg_no].ru_offset = factored_N_value *
00441 data_alignment_factor;
00442
00443 fp_register = reg_no;
00444 fp_offset = factored_N_value;
00445 break;
00446 }
00447
00448 case DW_CFA_restore_extended:{
00449 Dwarf_Unsigned lreg;
00450
00451 DECODE_LEB128_UWORD(instr_ptr, lreg)
00452 reg_no = (Dwarf_Small) lreg;
00453
00454 if (reg_no > DW_FRAME_LAST_REG_NUM) {
00455 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
00456 return DW_DLV_ERROR;
00457 }
00458
00459 if (cie != NULL && cie->ci_initial_table != NULL) {
00460 reg[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
00461 } else {
00462 if (!make_instr) {
00463 *returned_error =
00464 (DW_DLE_DF_MAKE_INSTR_NO_INIT);
00465 return DW_DLV_ERROR;
00466 }
00467 }
00468
00469 fp_register = reg_no;
00470 break;
00471 }
00472
00473 case DW_CFA_undefined:{
00474 Dwarf_Unsigned lreg;
00475
00476 DECODE_LEB128_UWORD(instr_ptr, lreg)
00477 reg_no = (Dwarf_Small) lreg;
00478 if (reg_no > DW_FRAME_LAST_REG_NUM) {
00479 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
00480 return DW_DLV_ERROR;
00481 }
00482
00483 reg[reg_no].ru_is_off = 0;
00484 reg[reg_no].ru_register = DW_FRAME_UNDEFINED_VAL;
00485 reg[reg_no].ru_offset = 0;
00486
00487 fp_register = reg_no;
00488 break;
00489 }
00490
00491 case DW_CFA_same_value:{
00492 Dwarf_Unsigned lreg;
00493
00494 DECODE_LEB128_UWORD(instr_ptr, lreg)
00495 reg_no = (Dwarf_Small) lreg;
00496 if (reg_no > DW_FRAME_LAST_REG_NUM) {
00497 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
00498 return DW_DLV_ERROR;
00499 }
00500
00501 reg[reg_no].ru_is_off = 0;
00502 reg[reg_no].ru_register = DW_FRAME_SAME_VAL;
00503 reg[reg_no].ru_offset = 0;
00504 fp_register = reg_no;
00505 break;
00506 }
00507
00508 case DW_CFA_register:{
00509 Dwarf_Unsigned lreg;
00510
00511 DECODE_LEB128_UWORD(instr_ptr, lreg)
00512 reg_noA = (Dwarf_Small) lreg;
00513
00514 if (reg_noA > DW_FRAME_LAST_REG_NUM) {
00515 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
00516 return DW_DLV_ERROR;
00517 }
00518
00519 DECODE_LEB128_UWORD(instr_ptr, lreg)
00520 reg_noB = (Dwarf_Small) lreg;
00521
00522 if (reg_noB > DW_FRAME_LAST_REG_NUM) {
00523 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
00524 return DW_DLV_ERROR;
00525 }
00526
00527
00528 reg[reg_noA].ru_is_off = 0;
00529 reg[reg_noA].ru_register = reg_noB;
00530
00531 reg[reg_noA].ru_offset = 0;
00532
00533 fp_register = reg_noA;
00534 fp_offset = reg_noB;
00535 break;
00536 }
00537
00538 case DW_CFA_remember_state:{
00539 stack_table = (Dwarf_Frame)
00540 _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
00541 if (stack_table == NULL) {
00542 *returned_error = (DW_DLE_DF_ALLOC_FAIL);
00543 return DW_DLV_ERROR;
00544 }
00545
00546 for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++)
00547 stack_table->fr_reg[i] = reg[i];
00548
00549 if (top_stack != NULL)
00550 stack_table->fr_next = top_stack;
00551 top_stack = stack_table;
00552
00553 break;
00554 }
00555
00556 case DW_CFA_restore_state:{
00557 if (top_stack == NULL) {
00558 *returned_error = (DW_DLE_DF_POP_EMPTY_STACK);
00559 return DW_DLV_ERROR;
00560 }
00561 stack_table = top_stack;
00562 top_stack = stack_table->fr_next;
00563
00564 for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++)
00565 reg[i] = stack_table->fr_reg[i];
00566
00567 dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
00568 break;
00569 }
00570
00571 case DW_CFA_def_cfa:{
00572 Dwarf_Unsigned lreg;
00573
00574 DECODE_LEB128_UWORD(instr_ptr, lreg)
00575 reg_no = (Dwarf_Small) lreg;
00576
00577 if (reg_no > DW_FRAME_LAST_REG_NUM) {
00578 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
00579 return (DW_DLV_ERROR);
00580 }
00581
00582 factored_N_value =
00583 _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
00584 instr_ptr += leb128_length;
00585
00586 if (need_augmentation) {
00587 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
00588 return DW_DLV_ERROR;
00589 }
00590 reg[DW_FRAME_CFA_COL].ru_is_off = 1;
00591 reg[DW_FRAME_CFA_COL].ru_register = reg_no;
00592 reg[DW_FRAME_CFA_COL].ru_offset = factored_N_value;
00593
00594 fp_register = reg_no;
00595 fp_offset = factored_N_value;
00596 break;
00597 }
00598
00599 case DW_CFA_def_cfa_register:{
00600 Dwarf_Unsigned lreg;
00601
00602 DECODE_LEB128_UWORD(instr_ptr, lreg)
00603 reg_no = (Dwarf_Small) lreg;
00604
00605 if (reg_no > DW_FRAME_LAST_REG_NUM) {
00606 *returned_error = (DW_DLE_DF_REG_NUM_TOO_HIGH);
00607 return DW_DLV_ERROR;
00608 }
00609
00610 reg[DW_FRAME_CFA_COL].ru_register = reg_no;
00611
00612
00613 fp_register = reg_no;
00614 break;
00615 }
00616
00617 case DW_CFA_def_cfa_offset:{
00618 factored_N_value =
00619 _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
00620 instr_ptr += leb128_length;
00621
00622 if (need_augmentation) {
00623 *returned_error = (DW_DLE_DF_NO_CIE_AUGMENTATION);
00624 return DW_DLV_ERROR;
00625 }
00626
00627
00628 reg[DW_FRAME_CFA_COL].ru_is_off = 1;
00629 reg[DW_FRAME_CFA_COL].ru_offset = factored_N_value;
00630
00631 fp_offset = factored_N_value;
00632 break;
00633 }
00634
00635 case DW_CFA_nop:{
00636 break;
00637 }
00638
00639 #ifdef DW_CFA_GNU_window_save
00640 case DW_CFA_GNU_window_save:{
00641
00642
00643
00644 break;
00645 }
00646 #endif
00647 #ifdef DW_CFA_GNU_args_size
00648
00649
00650 case DW_CFA_GNU_args_size:{
00651 Dwarf_Unsigned lreg;
00652
00653 DECODE_LEB128_UWORD(instr_ptr, lreg)
00654 reg_no = (Dwarf_Small) lreg;
00655
00656 break;
00657 }
00658 #endif
00659 }
00660
00661 if (make_instr) {
00662 instr_count++;
00663
00664 curr_instr = (Dwarf_Frame_Op *)
00665 _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
00666 if (curr_instr == NULL) {
00667 *returned_error = (DW_DLE_DF_ALLOC_FAIL);
00668 return DW_DLV_ERROR;
00669 }
00670
00671 curr_instr->fp_base_op = fp_base_op;
00672 curr_instr->fp_extended_op = fp_extended_op;
00673 curr_instr->fp_register = fp_register;
00674 curr_instr->fp_offset = fp_offset;
00675 curr_instr->fp_instr_offset = fp_instr_offset;
00676
00677 curr_instr_item = (Dwarf_Chain)
00678 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
00679 if (curr_instr_item == NULL) {
00680 *returned_error = (DW_DLE_DF_ALLOC_FAIL);
00681 return DW_DLV_ERROR;
00682 }
00683
00684 curr_instr_item->ch_item = curr_instr;
00685 if (head_instr_chain == NULL)
00686 head_instr_chain = tail_instr_chain = curr_instr_item;
00687 else {
00688 tail_instr_chain->ch_next = curr_instr_item;
00689 tail_instr_chain = curr_instr_item;
00690 }
00691 }
00692 }
00693
00694
00695
00696
00697 if (instr_ptr > final_instr_ptr) {
00698 *returned_error = (DW_DLE_DF_FRAME_DECODING_ERROR);
00699 return DW_DLV_ERROR;
00700 }
00701
00702
00703 if (table != NULL) {
00704 t1reg = reg;
00705 t1end = t1reg + DW_FRAME_LAST_REG_NUM;
00706 table->fr_loc = loc;
00707 t2reg = table->fr_reg;
00708 for (; t1reg < t1end; t1reg++, t2reg++) {
00709 *t2reg = *t1reg;
00710 }
00711 }
00712
00713
00714 for (; top_stack != NULL;) {
00715 stack_table = top_stack;
00716 top_stack = top_stack->fr_next;
00717 dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
00718 }
00719
00720 if (make_instr) {
00721
00722 head_instr_block = (Dwarf_Frame_Op *)
00723 _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
00724 if (head_instr_block == NULL) {
00725 *returned_error = DW_DLE_DF_ALLOC_FAIL;
00726 return DW_DLV_ERROR;
00727 }
00728
00729
00730
00731
00732 curr_instr_item = head_instr_chain;
00733 for (i = 0; i < instr_count; i++) {
00734 *(head_instr_block + i) =
00735 *(Dwarf_Frame_Op *) curr_instr_item->ch_item;
00736 dealloc_instr_item = curr_instr_item;
00737 curr_instr_item = curr_instr_item->ch_next;
00738 dwarf_dealloc(dbg, dealloc_instr_item->ch_item,
00739 DW_DLA_FRAME_OP);
00740 dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
00741 }
00742 *ret_frame_instr = head_instr_block;
00743
00744 *returned_count = (Dwarf_Sword) instr_count;
00745 } else {
00746 *returned_count = 0;
00747 }
00748 return DW_DLV_OK;
00749 }
00750
00751 static int
00752 qsort_compare(const void *elem1, const void *elem2)
00753 {
00754 Dwarf_Fde fde1 = *(Dwarf_Fde *) elem1;
00755 Dwarf_Fde fde2 = *(Dwarf_Fde *) elem2;
00756 Dwarf_Addr addr1 = fde1->fd_initial_location;
00757 Dwarf_Addr addr2 = fde2->fd_initial_location;
00758
00759 if (addr1 < addr2) {
00760 return -1;
00761 } else if (addr1 > addr2) {
00762 return 1;
00763 }
00764 return 0;
00765 }
00766
00767
00768
00769
00770
00771
00772 static int
00773 get_augmentation_string(Dwarf_Debug dbg,
00774 Dwarf_Small * cie_ptr,
00775 Dwarf_Unsigned cie_id_value,
00776 Dwarf_Small ** augmentation,
00777 Dwarf_Error * error)
00778 {
00779 Dwarf_Unsigned cie_id;
00780
00781 Dwarf_Small version;
00782 int local_length_size;
00783 Dwarf_Unsigned length;
00784
00785 int local_extension_size;
00786
00787
00788
00789 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
00790 cie_ptr, local_length_size, local_extension_size);
00791
00792
00793 READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
00794 cie_ptr, local_length_size);
00795 SIGN_EXTEND(cie_id, local_length_size);
00796 if (cie_id != cie_id_value) {
00797
00798
00799
00800 _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
00801 return (DW_DLV_ERROR);
00802 }
00803 cie_ptr += local_length_size;
00804
00805
00806
00807 version = *(Dwarf_Small *) cie_ptr;
00808 cie_ptr++;
00809 if (version != DW_CIE_VERSION &&
00810 version != DW_CIE_VERSION3) {
00811 _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
00812 return (DW_DLV_ERROR);
00813 }
00814
00815
00816 *augmentation = cie_ptr;
00817 return DW_DLV_OK;
00818 }
00819
00820 int
00821 dwarf_get_cie_of_fde(Dwarf_Fde fde,
00822 Dwarf_Cie * cie_returned, Dwarf_Error * error)
00823 {
00824 if (fde == NULL) {
00825 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
00826 return (DW_DLV_ERROR);
00827 }
00828
00829 *cie_returned = fde->fd_cie;
00830 return DW_DLV_OK;
00831
00832 }
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845 int
00846 dwarf_get_fde_list_eh(Dwarf_Debug dbg,
00847 Dwarf_Cie ** cie_data,
00848 Dwarf_Signed * cie_element_count,
00849 Dwarf_Fde ** fde_data,
00850 Dwarf_Signed * fde_element_count,
00851 Dwarf_Error * error)
00852 {
00853 int res;
00854
00855 res =
00856 _dwarf_load_section(dbg,
00857 dbg->de_debug_frame_eh_gnu_index,
00858 &dbg->de_debug_frame_eh_gnu,
00859 error);
00860
00861 if (res != DW_DLV_OK) {
00862 return res;
00863 }
00864
00865 res =
00866 __dwarf_get_fde_list_internal(dbg,
00867 cie_data,
00868 cie_element_count,
00869 fde_data,
00870 fde_element_count,
00871 dbg->de_debug_frame_eh_gnu,
00872 dbg->de_debug_frame_size_eh_gnu,
00873 dbg->de_debug_frame_eh_gnu_index,
00874 0,
00875 1,
00876 error);
00877 return res;
00878 }
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888 int
00889 dwarf_get_fde_list(Dwarf_Debug dbg,
00890 Dwarf_Cie ** cie_data,
00891 Dwarf_Signed * cie_element_count,
00892 Dwarf_Fde ** fde_data,
00893 Dwarf_Signed * fde_element_count,
00894 Dwarf_Error * error)
00895 {
00896 int res;
00897
00898 res =
00899 _dwarf_load_section(dbg,
00900 dbg->de_debug_frame_index,
00901 &dbg->de_debug_frame,
00902 error);
00903
00904 if (res != DW_DLV_OK) {
00905 return res;
00906 }
00907
00908 res =
00909 __dwarf_get_fde_list_internal(dbg, cie_data,
00910 cie_element_count,
00911 fde_data,
00912 fde_element_count,
00913 dbg->de_debug_frame,
00914 dbg->de_debug_frame_size,
00915 dbg->de_debug_frame_index,
00916 DW_CIE_ID,
00917 0,
00918 error);
00919
00920 return res;
00921 }
00922
00923 static int
00924 __dwarf_get_fde_list_internal(Dwarf_Debug dbg,
00925 Dwarf_Cie ** cie_data,
00926 Dwarf_Signed * cie_element_count,
00927 Dwarf_Fde ** fde_data,
00928 Dwarf_Signed * fde_element_count,
00929 Dwarf_Small * section_ptr,
00930 Dwarf_Unsigned section_length,
00931 Dwarf_Unsigned section_index,
00932 Dwarf_Unsigned cie_id_value,
00933 int use_gnu_cie_calc,
00934 Dwarf_Error * error)
00935 {
00936
00937 Dwarf_Small *frame_ptr = 0;
00938
00939
00940 Dwarf_Small *start_frame_ptr = 0;
00941
00942
00943 Dwarf_Small *saved_frame_ptr = 0;
00944
00945
00946 Dwarf_Unsigned length = 0;
00947
00948 Dwarf_Unsigned cie_base_offset = 0;
00949
00950 Dwarf_Unsigned cie_id;
00951 Dwarf_Small version = 0;
00952 Dwarf_Small *augmentation = 0;
00953 Dwarf_Word code_alignment_factor = 4;
00954 Dwarf_Sword data_alignment_factor = -1;
00955 Dwarf_Small return_address_register = 31;
00956 Dwarf_Word length_of_augmented_fields = 0;
00957
00958
00959
00960
00961 Dwarf_Cie new_cie;
00962 Dwarf_Cie head_cie_ptr = NULL;
00963 Dwarf_Cie cur_cie_ptr;
00964 Dwarf_Word cie_count = 0;
00965
00966
00967
00968
00969 Dwarf_Cie *cie_list_ptr;
00970
00971
00972 Dwarf_Addr initial_location;
00973
00974 Dwarf_Addr address_range;
00975
00976
00977
00978
00979
00980 Dwarf_Fde new_fde;
00981 Dwarf_Fde head_fde_ptr = NULL;
00982 Dwarf_Fde cur_fde_ptr;
00983 Dwarf_Word fde_count = 0;
00984
00985
00986
00987
00988 Dwarf_Fde *fde_list_ptr;
00989
00990
00991
00992
00993 Dwarf_Small *fde_cie_ptr;
00994
00995 Dwarf_Word leb128_length;
00996 Dwarf_Word i, j;
00997 int res;
00998 Dwarf_Word last_cie_index;
00999
01000
01001 Dwarf_Small *prev_augmentation_cie_ptr = 0;
01002 Dwarf_Small *prev_augmentation_ptr = 0;
01003
01004
01005 frame_ptr = section_ptr;
01006
01007 if (frame_ptr == 0) {
01008 return DW_DLV_NO_ENTRY;
01009 }
01010
01011 while (frame_ptr < section_ptr + section_length) {
01012 Dwarf_Small *cie_ptr_addr = 0;
01013 int local_extension_size = 0;
01014 int local_length_size = 0;
01015
01016 start_frame_ptr = frame_ptr;
01017
01018
01019 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
01020 frame_ptr, local_length_size,
01021 local_extension_size);
01022
01023
01024 if (length % local_length_size != 0) {
01025 _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
01026 return (DW_DLV_ERROR);
01027 }
01028
01029 if (length == 0) {
01030
01031
01032
01033
01034 break;
01035 }
01036
01037 cie_ptr_addr = frame_ptr;
01038 READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
01039 frame_ptr, local_length_size);
01040 SIGN_EXTEND(cie_id, local_length_size);
01041 cie_base_offset = cie_id;
01042
01043
01044
01045
01046
01047
01048
01049 frame_ptr += local_length_size;
01050
01051 if (cie_id == cie_id_value) {
01052
01053
01054
01055
01056
01057
01058
01059
01060 version = *(Dwarf_Small *) frame_ptr;
01061 frame_ptr++;
01062 if (version != DW_CIE_VERSION &&
01063 version != DW_CIE_VERSION3) {
01064 _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
01065 return (DW_DLV_ERROR);
01066 }
01067
01068 augmentation = frame_ptr;
01069 frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1;
01070 if ((strcmp((char *) augmentation,
01071 DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) ||
01072 (strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) {
01073
01074 Dwarf_Unsigned lreg;
01075
01076 DECODE_LEB128_UWORD(frame_ptr, lreg)
01077 code_alignment_factor = (Dwarf_Word) lreg;
01078
01079
01080 data_alignment_factor =
01081 (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
01082 &leb128_length);
01083
01084 frame_ptr = frame_ptr + leb128_length;
01085
01086 return_address_register = *(Dwarf_Small *) frame_ptr;
01087 if (return_address_register > DW_FRAME_LAST_REG_NUM) {
01088 _dwarf_error(dbg, error,
01089 DW_DLE_CIE_RET_ADDR_REG_ERROR);
01090 return (DW_DLV_ERROR);
01091 }
01092 frame_ptr++;
01093 } else if (augmentation[0] == 'z') {
01094
01095
01096
01097 Dwarf_Unsigned lreg;
01098
01099 DECODE_LEB128_UWORD(frame_ptr, lreg)
01100 code_alignment_factor = (Dwarf_Word) lreg;
01101
01102
01103 data_alignment_factor =
01104 (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
01105 &leb128_length);
01106 frame_ptr = frame_ptr + leb128_length;
01107
01108 return_address_register = *(Dwarf_Small *) frame_ptr;
01109 if (return_address_register > DW_FRAME_LAST_REG_NUM) {
01110 _dwarf_error(dbg, error,
01111 DW_DLE_CIE_RET_ADDR_REG_ERROR);
01112 return (DW_DLV_ERROR);
01113 }
01114 frame_ptr++;
01115
01116
01117 DECODE_LEB128_UWORD(frame_ptr, lreg)
01118 length_of_augmented_fields = (Dwarf_Word) lreg;
01119
01120
01121
01122
01123 frame_ptr += length_of_augmented_fields;
01124 } else if (0 == strcmp((const char *) augmentation, "eh")) {
01125
01126
01127 Dwarf_Unsigned exception_table_addr;
01128
01129
01130 READ_UNALIGNED(dbg, exception_table_addr,
01131 Dwarf_Unsigned, frame_ptr,
01132 local_length_size);
01133 frame_ptr += local_length_size;
01134
01135 code_alignment_factor =
01136 (Dwarf_Word) _dwarf_decode_s_leb128(frame_ptr,
01137 &leb128_length);
01138 frame_ptr = frame_ptr + leb128_length;
01139
01140
01141 data_alignment_factor =
01142 (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
01143 &leb128_length);
01144
01145 frame_ptr = frame_ptr + leb128_length;
01146
01147 return_address_register = *(Dwarf_Small *) frame_ptr;
01148 if (return_address_register > DW_FRAME_LAST_REG_NUM) {
01149 _dwarf_error(dbg, error,
01150 DW_DLE_CIE_RET_ADDR_REG_ERROR);
01151 return (DW_DLV_ERROR);
01152 }
01153 frame_ptr++;
01154
01155 } else {
01156
01157
01158
01159 frame_ptr = start_frame_ptr + length + local_length_size
01160 + local_extension_size;
01161
01162
01163
01164
01165
01166 }
01167
01168 new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
01169 if (new_cie == NULL) {
01170 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01171 return (DW_DLV_ERROR);
01172 }
01173
01174 new_cie->ci_cie_version_number = version;
01175 new_cie->ci_initial_table = NULL;
01176 new_cie->ci_length = (Dwarf_Word) length;
01177 new_cie->ci_length_size = local_length_size;
01178 new_cie->ci_extension_size = local_extension_size;
01179 new_cie->ci_augmentation = (char *) augmentation;
01180
01181 new_cie->ci_data_alignment_factor =
01182 (Dwarf_Sbyte) data_alignment_factor;
01183 new_cie->ci_code_alignment_factor =
01184 (Dwarf_Small) code_alignment_factor;
01185 new_cie->ci_return_address_register =
01186 return_address_register;
01187 new_cie->ci_cie_start = start_frame_ptr;
01188 new_cie->ci_cie_instr_start = frame_ptr;
01189 new_cie->ci_dbg = dbg;
01190
01191 cie_count++;
01192 if (head_cie_ptr == NULL)
01193 head_cie_ptr = cur_cie_ptr = new_cie;
01194 else {
01195 cur_cie_ptr->ci_next = new_cie;
01196 cur_cie_ptr = new_cie;
01197 }
01198 } else {
01199
01200
01201
01202
01203
01204 Dwarf_Small *cieptr;
01205
01206 Dwarf_Small *initloc = frame_ptr;
01207 Dwarf_Signed offset_into_exception_tables
01208
01209 = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET;
01210
01211 READ_UNALIGNED(dbg, initial_location, Dwarf_Addr,
01212 frame_ptr, dbg->de_pointer_size);
01213 frame_ptr += dbg->de_pointer_size;
01214
01215 READ_UNALIGNED(dbg, address_range, Dwarf_Addr,
01216 frame_ptr, dbg->de_pointer_size);
01217 frame_ptr += dbg->de_pointer_size;
01218
01219
01220 if (use_gnu_cie_calc) {
01221
01222
01223
01224
01225
01226 cieptr = cie_ptr_addr - cie_base_offset;
01227 cie_base_offset = cieptr - section_ptr;
01228 } else {
01229
01230 cieptr =
01231 (Dwarf_Small *) (section_ptr + cie_base_offset);
01232 }
01233
01234
01235 if (prev_augmentation_cie_ptr == cieptr &&
01236 prev_augmentation_ptr != NULL) {
01237 augmentation = prev_augmentation_ptr;
01238 } else {
01239 res = get_augmentation_string(dbg,
01240 cieptr,
01241 cie_id_value,
01242 &augmentation, error);
01243 if (res != DW_DLV_OK) {
01244 return res;
01245 }
01246 prev_augmentation_cie_ptr = cieptr;
01247 prev_augmentation_ptr = augmentation;
01248 }
01249 if ((strcmp((char *) augmentation,
01250 DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) ||
01251 (strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) {
01252
01253
01254 } else if (augmentation[0] == 'z') {
01255 Dwarf_Unsigned lreg;
01256
01257 DECODE_LEB128_UWORD(frame_ptr, lreg)
01258 length_of_augmented_fields = (Dwarf_Word) lreg;
01259
01260 saved_frame_ptr = frame_ptr;
01261 if (strcmp((char *) augmentation,
01262 DW_CIE_AUGMENTER_STRING_V0) == 0) {
01263
01264
01265
01266
01267 READ_UNALIGNED(dbg, offset_into_exception_tables,
01268 Dwarf_Addr, frame_ptr,
01269 sizeof(Dwarf_sfixed));
01270 SIGN_EXTEND(offset_into_exception_tables,
01271 sizeof(Dwarf_sfixed));
01272 frame_ptr += local_length_size;
01273 }
01274 frame_ptr =
01275 saved_frame_ptr + length_of_augmented_fields;
01276 } else if (strcmp((const char *) augmentation, "eh") == 0) {
01277
01278
01279 Dwarf_Unsigned exception_table_addr;
01280
01281 READ_UNALIGNED(dbg, exception_table_addr,
01282 Dwarf_Unsigned, frame_ptr,
01283 dbg->de_pointer_size);
01284 frame_ptr += dbg->de_pointer_size;
01285 } else {
01286
01287
01288
01289
01290
01291
01292 }
01293 new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
01294 if (new_fde == NULL) {
01295 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01296 return (DW_DLV_ERROR);
01297 }
01298
01299 new_fde->fd_length = (Dwarf_Word) length;
01300 new_fde->fd_length_size = local_length_size;
01301 new_fde->fd_extension_size = local_extension_size;
01302 new_fde->fd_cie_offset = cie_base_offset;
01303 new_fde->fd_initial_location = initial_location;
01304 new_fde->fd_initial_loc_pos = initloc;
01305 new_fde->fd_address_range = address_range;
01306 new_fde->fd_fde_start = start_frame_ptr;
01307 new_fde->fd_fde_instr_start = frame_ptr;
01308 new_fde->fd_dbg = dbg;
01309 new_fde->fd_offset_into_exception_tables =
01310 offset_into_exception_tables;
01311 new_fde->fd_section_ptr = section_ptr;
01312 new_fde->fd_section_length = section_length;
01313 new_fde->fd_section_index = section_index;
01314
01315 fde_count++;
01316 if (head_fde_ptr == NULL)
01317 head_fde_ptr = cur_fde_ptr = new_fde;
01318 else {
01319 cur_fde_ptr->fd_next = new_fde;
01320 cur_fde_ptr = new_fde;
01321 }
01322 }
01323
01324
01325 frame_ptr = start_frame_ptr + length + local_length_size +
01326 local_extension_size;
01327 }
01328
01329 if (cie_count > 0) {
01330 cie_list_ptr = (Dwarf_Cie *)
01331 _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count);
01332 } else {
01333 return (DW_DLV_NO_ENTRY);
01334 }
01335 if (cie_list_ptr == NULL) {
01336 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01337 return (DW_DLV_ERROR);
01338 }
01339
01340 *cie_data = cie_list_ptr;
01341 *cie_element_count = cie_count;
01342 dbg->de_cie_data = cie_list_ptr;
01343 dbg->de_cie_count = cie_count;
01344
01345 cur_cie_ptr = head_cie_ptr;
01346 for (i = 0; i < cie_count; i++) {
01347 *(cie_list_ptr + i) = cur_cie_ptr;
01348 cur_cie_ptr = cur_cie_ptr->ci_next;
01349 }
01350
01351 if (fde_count > 0) {
01352 fde_list_ptr = (Dwarf_Fde *)
01353 _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count);
01354 } else {
01355 return (DW_DLV_NO_ENTRY);
01356 }
01357 if (fde_list_ptr == NULL) {
01358 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01359 return (DW_DLV_ERROR);
01360 }
01361
01362 *fde_data = fde_list_ptr;
01363 *fde_element_count = fde_count;
01364 dbg->de_fde_data = fde_list_ptr;
01365 dbg->de_fde_count = fde_count;
01366 last_cie_index = 0;
01367
01368 cur_fde_ptr = head_fde_ptr;
01369 for (i = 0; i < fde_count; i++) {
01370 Dwarf_Sword new_cie_index = (Dwarf_Sword) cie_count;
01371
01372 *(fde_list_ptr + i) = cur_fde_ptr;
01373
01374 fde_cie_ptr = (Dwarf_Small *) (section_ptr +
01375 cur_fde_ptr->fd_cie_offset);
01376
01377
01378
01379
01380 for (j = last_cie_index; j < cie_count; j++) {
01381 Dwarf_Cie ciep = (Dwarf_Cie) * (cie_list_ptr + j);
01382
01383 if (ciep->ci_cie_start == fde_cie_ptr) {
01384 new_cie_index = (Dwarf_Sword) j;
01385 break;
01386 }
01387 }
01388
01389 if (new_cie_index == cie_count) {
01390 for (j = 0; j < last_cie_index; ++j) {
01391 Dwarf_Cie ciep = (Dwarf_Cie) * (cie_list_ptr + j);
01392
01393 if (ciep->ci_cie_start == fde_cie_ptr) {
01394 new_cie_index = (Dwarf_Sword) j;
01395 break;
01396 }
01397 }
01398 }
01399 j = new_cie_index;
01400 last_cie_index = new_cie_index;
01401 if (j == cie_count) {
01402 _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
01403 return (DW_DLV_ERROR);
01404 } else {
01405 cur_fde_ptr->fd_cie_index = (Dwarf_Sword) j;
01406 cur_fde_ptr->fd_cie = *(cie_list_ptr + j);
01407 }
01408
01409 cur_fde_ptr = cur_fde_ptr->fd_next;
01410 }
01411
01412
01413
01414 qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr),
01415 qsort_compare);
01416
01417 return (DW_DLV_OK);
01418 }
01419
01420
01421
01422
01423 int
01424 dwarf_get_fde_for_die(Dwarf_Debug dbg,
01425 Dwarf_Die die,
01426 Dwarf_Fde * ret_fde, Dwarf_Error * error)
01427 {
01428 Dwarf_Attribute attr;
01429 Dwarf_Unsigned fde_offset;
01430 Dwarf_Signed signdval;
01431 Dwarf_Unsigned length;
01432 Dwarf_Signed signed_offset;
01433 Dwarf_Addr initial_location;
01434
01435 Dwarf_Addr address_range;
01436 Dwarf_Fde new_fde;
01437 unsigned char *fde_ptr;
01438 Dwarf_Small *saved_fde_ptr;
01439 unsigned char *cie_ptr;
01440 unsigned char *start_cie_ptr;
01441 Dwarf_Cie new_cie;
01442
01443
01444 Dwarf_Small version;
01445 Dwarf_Small *augmentation;
01446 Dwarf_Word code_alignment_factor;
01447 Dwarf_Sword data_alignment_factor;
01448 Dwarf_Small return_address_register;
01449 Dwarf_Word length_of_augmented_fields;
01450 Dwarf_Signed offset_into_exception_tables =
01451 (Dwarf_Signed) DW_DLX_NO_EH_OFFSET;
01452 int res;
01453 int resattr;
01454 int sdatares;
01455 int fde_local_extension_size = 0;
01456 int fde_local_length_size = 0;
01457 int cie_local_extension_size = 0;
01458 int cie_local_length_size = 0;
01459
01460
01461 Dwarf_Word leb128_length;
01462
01463 if (die == NULL) {
01464 _dwarf_error(NULL, error, DW_DLE_DIE_NULL);
01465 return (DW_DLV_ERROR);
01466 }
01467
01468 resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error);
01469 if (resattr != DW_DLV_OK) {
01470 return resattr;
01471 }
01472
01473
01474 sdatares = dwarf_formsdata(attr, &signdval, error);
01475 if (sdatares != DW_DLV_OK) {
01476 return sdatares;
01477 }
01478
01479 res =
01480 _dwarf_load_section(dbg,
01481 dbg->de_debug_frame_index,
01482 &dbg->de_debug_frame,
01483 error);
01484 if (res != DW_DLV_OK) {
01485 return res;
01486 }
01487
01488 fde_offset = signdval;
01489 fde_ptr = (dbg->de_debug_frame + fde_offset);
01490
01491
01492 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
01493 fde_ptr, fde_local_length_size,
01494 fde_local_extension_size);
01495
01496
01497 if (length % fde_local_length_size != 0) {
01498 _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
01499 return (DW_DLV_ERROR);
01500 }
01501
01502 READ_UNALIGNED(dbg, signed_offset, Dwarf_Signed,
01503 fde_ptr, fde_local_length_size);
01504 SIGN_EXTEND(signed_offset, fde_local_length_size);
01505 fde_ptr += fde_local_length_size;
01506
01507 READ_UNALIGNED(dbg, initial_location, Dwarf_Addr,
01508 fde_ptr, dbg->de_pointer_size);
01509 fde_ptr += dbg->de_pointer_size;
01510
01511 READ_UNALIGNED(dbg, address_range, Dwarf_Addr,
01512 fde_ptr, dbg->de_pointer_size);
01513 fde_ptr += dbg->de_pointer_size;
01514
01515 res = get_augmentation_string(dbg,
01516 (Dwarf_Small *) (dbg->de_debug_frame +
01517 signed_offset),
01518 DW_CIE_ID, &augmentation, error);
01519 if (res != DW_DLV_OK) {
01520 return res;
01521 }
01522
01523 if ((strcmp((char *) augmentation, DW_DEBUG_FRAME_AUGMENTER_STRING)
01524 == 0) ||
01525 (strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) {
01526
01527
01528 } else if (augmentation[0] == 'z') {
01529
01530
01531
01532 Dwarf_Unsigned lreg;
01533
01534 DECODE_LEB128_UWORD(fde_ptr, lreg)
01535 length_of_augmented_fields = (Dwarf_Word) lreg;
01536
01537 saved_fde_ptr = fde_ptr;
01538 if (strcmp((char *) augmentation, DW_CIE_AUGMENTER_STRING_V0) ==
01539 0) {
01540
01541 READ_UNALIGNED(dbg, offset_into_exception_tables,
01542 Dwarf_Signed, fde_ptr, sizeof(Dwarf_sfixed));
01543 SIGN_EXTEND(offset_into_exception_tables,
01544 sizeof(Dwarf_sfixed));
01545 fde_ptr += sizeof(Dwarf_sfixed);
01546 }
01547 fde_ptr = saved_fde_ptr + length_of_augmented_fields;
01548 } else {
01549
01550
01551
01552
01553
01554 }
01555
01556 new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
01557 if (new_fde == NULL) {
01558 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01559 return (DW_DLV_ERROR);
01560 }
01561
01562 new_fde->fd_length = (Dwarf_Word) length;
01563 new_fde->fd_length_size = fde_local_length_size;
01564 new_fde->fd_extension_size = fde_local_extension_size;
01565 new_fde->fd_cie_offset = signed_offset;
01566 new_fde->fd_initial_location = initial_location;
01567 new_fde->fd_address_range = address_range;
01568 new_fde->fd_fde_start = dbg->de_debug_frame + fde_offset;
01569 new_fde->fd_fde_instr_start = (Dwarf_Small *) fde_ptr;
01570 new_fde->fd_dbg = dbg;
01571 new_fde->fd_offset_into_exception_tables =
01572 offset_into_exception_tables;
01573 new_fde->fd_section_ptr = dbg->de_debug_frame;
01574 new_fde->fd_section_length = dbg->de_debug_frame_size;
01575 new_fde->fd_section_index = dbg->de_debug_frame_index;
01576
01577
01578
01579 cie_ptr = (dbg->de_debug_frame + signed_offset);
01580 start_cie_ptr = cie_ptr;
01581
01582
01583 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
01584 cie_ptr, cie_local_length_size,
01585 cie_local_extension_size);
01586
01587
01588 if (length % cie_local_length_size != 0) {
01589 _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
01590 return (DW_DLV_ERROR);
01591 }
01592
01593 READ_UNALIGNED(dbg, signed_offset, Dwarf_Signed,
01594 cie_ptr, cie_local_length_size);
01595 SIGN_EXTEND(signed_offset, cie_local_length_size);
01596 cie_ptr += cie_local_length_size;
01597
01598 if (signed_offset == DW_CIE_ID) {
01599
01600 version = *(Dwarf_Small *) cie_ptr;
01601 cie_ptr++;
01602 if (version != DW_CIE_VERSION &&
01603 version != DW_CIE_VERSION3) {
01604 _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
01605 return (DW_DLV_ERROR);
01606 }
01607
01608 augmentation = cie_ptr;
01609 cie_ptr = cie_ptr + strlen((char *) cie_ptr) + 1;
01610 if ((strcmp((char *) augmentation,
01611 DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) ||
01612 (strcmp((char *) augmentation, DW_EMPTY_STRING) == 0)) {
01613
01614 Dwarf_Unsigned lreg;
01615
01616 DECODE_LEB128_UWORD(cie_ptr, lreg)
01617 code_alignment_factor = (Dwarf_Word) lreg;
01618
01619
01620 data_alignment_factor = (Dwarf_Sword)
01621 _dwarf_decode_s_leb128(cie_ptr, &leb128_length);
01622 cie_ptr = cie_ptr + leb128_length;
01623
01624 return_address_register = *(Dwarf_Small *) cie_ptr;
01625 if (return_address_register > DW_FRAME_LAST_REG_NUM) {
01626 _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
01627 return (DW_DLV_ERROR);
01628 }
01629 cie_ptr++;
01630 } else if (augmentation[0] == 'z') {
01631
01632
01633
01634
01635 Dwarf_Unsigned lreg;
01636
01637 DECODE_LEB128_UWORD(cie_ptr, lreg)
01638 code_alignment_factor = (Dwarf_Word) lreg;
01639 data_alignment_factor = (Dwarf_Sword)
01640 _dwarf_decode_s_leb128(cie_ptr, &leb128_length);
01641 cie_ptr = cie_ptr + leb128_length;
01642
01643 return_address_register = *(Dwarf_Small *) cie_ptr;
01644 if (return_address_register > DW_FRAME_LAST_REG_NUM) {
01645 _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
01646 return (DW_DLV_ERROR);
01647 }
01648 cie_ptr++;
01649
01650 DECODE_LEB128_UWORD(cie_ptr, lreg)
01651 length_of_augmented_fields = (Dwarf_Word) lreg;
01652
01653
01654 cie_ptr += length_of_augmented_fields;
01655 } else if (strcmp((const char *) augmentation, "eh") == 0) {
01656 Dwarf_Unsigned lreg;
01657
01658 DECODE_LEB128_UWORD(cie_ptr, lreg)
01659 code_alignment_factor = (Dwarf_Word) lreg;
01660
01661
01662 data_alignment_factor = (Dwarf_Sword)
01663 _dwarf_decode_s_leb128(cie_ptr, &leb128_length);
01664 cie_ptr = cie_ptr + leb128_length;
01665
01666 return_address_register = *(Dwarf_Small *) cie_ptr;
01667 if (return_address_register > DW_FRAME_LAST_REG_NUM) {
01668 _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
01669 return (DW_DLV_ERROR);
01670 }
01671 cie_ptr++;
01672
01673 } else {
01674
01675
01676
01677 cie_ptr = start_cie_ptr + length + cie_local_length_size
01678 + cie_local_extension_size;
01679
01680
01681
01682
01683
01684 }
01685
01686 new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
01687 if (new_cie == NULL) {
01688 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01689 return (DW_DLV_ERROR);
01690 }
01691
01692 new_cie->ci_cie_version_number = version;
01693 new_cie->ci_initial_table = NULL;
01694 new_cie->ci_length = (Dwarf_Word) length;
01695 new_cie->ci_length_size = cie_local_length_size;
01696 new_cie->ci_extension_size = cie_local_extension_size;
01697 new_cie->ci_augmentation = (char *) augmentation;
01698 new_cie->ci_data_alignment_factor =
01699 (Dwarf_Sbyte) data_alignment_factor;
01700 new_cie->ci_code_alignment_factor =
01701 (Dwarf_Small) code_alignment_factor;
01702 new_cie->ci_return_address_register = return_address_register;
01703 new_cie->ci_cie_start = start_cie_ptr;
01704 new_cie->ci_cie_instr_start = cie_ptr;
01705 new_cie->ci_dbg = dbg;
01706 } else {
01707 _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
01708 return (DW_DLV_ERROR);
01709 }
01710 new_fde->fd_cie = new_cie;
01711
01712 *ret_fde = new_fde;
01713 return DW_DLV_OK;
01714 }
01715
01716
01717 int
01718 dwarf_get_fde_range(Dwarf_Fde fde,
01719 Dwarf_Addr * low_pc,
01720 Dwarf_Unsigned * func_length,
01721 Dwarf_Ptr * fde_bytes,
01722 Dwarf_Unsigned * fde_byte_length,
01723 Dwarf_Off * cie_offset,
01724 Dwarf_Signed * cie_index,
01725 Dwarf_Off * fde_offset, Dwarf_Error * error)
01726 {
01727 Dwarf_Debug dbg;
01728
01729 if (fde == NULL) {
01730 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
01731 return (DW_DLV_ERROR);
01732 }
01733
01734 dbg = fde->fd_dbg;
01735 if (dbg == NULL) {
01736 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
01737 return (DW_DLV_ERROR);
01738 }
01739
01740
01741
01742
01743
01744
01745
01746
01747 if (low_pc != NULL)
01748 *low_pc = fde->fd_initial_location;
01749 if (func_length != NULL)
01750 *func_length = fde->fd_address_range;
01751 if (fde_bytes != NULL)
01752 *fde_bytes = fde->fd_fde_start;
01753 if (fde_byte_length != NULL)
01754 *fde_byte_length = fde->fd_length;
01755 if (cie_offset != NULL)
01756 *cie_offset = fde->fd_cie_offset;
01757 if (cie_index != NULL)
01758 *cie_index = fde->fd_cie_index;
01759 if (fde_offset != NULL)
01760 *fde_offset = fde->fd_fde_start - fde->fd_section_ptr;
01761
01762 return DW_DLV_OK;
01763 }
01764
01765 int
01766 dwarf_get_fde_exception_info(Dwarf_Fde fde,
01767 Dwarf_Signed *
01768 offset_into_exception_tables,
01769 Dwarf_Error * error)
01770 {
01771 Dwarf_Debug dbg;
01772
01773 dbg = fde->fd_dbg;
01774 if (dbg == NULL) {
01775 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
01776 return (DW_DLV_ERROR);
01777 }
01778 *offset_into_exception_tables =
01779 fde->fd_offset_into_exception_tables;
01780 return DW_DLV_OK;
01781 }
01782
01783
01784 int
01785 dwarf_get_cie_info(Dwarf_Cie cie,
01786 Dwarf_Unsigned * bytes_in_cie,
01787 Dwarf_Small * ptr_to_version,
01788 char **augmenter,
01789 Dwarf_Unsigned * code_alignment_factor,
01790 Dwarf_Signed * data_alignment_factor,
01791 Dwarf_Half * return_address_register,
01792 Dwarf_Ptr * initial_instructions,
01793 Dwarf_Unsigned * initial_instructions_length,
01794 Dwarf_Error * error)
01795 {
01796 Dwarf_Debug dbg;
01797
01798 if (cie == NULL) {
01799 _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
01800 return (DW_DLV_ERROR);
01801 }
01802
01803 dbg = cie->ci_dbg;
01804 if (dbg == NULL) {
01805 _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
01806 return (DW_DLV_ERROR);
01807 }
01808
01809 if (ptr_to_version != NULL)
01810 *ptr_to_version = cie->ci_cie_version_number;
01811 if (augmenter != NULL)
01812 *augmenter = cie->ci_augmentation;
01813 if (code_alignment_factor != NULL)
01814 *code_alignment_factor = cie->ci_code_alignment_factor;
01815 if (data_alignment_factor != NULL)
01816 *data_alignment_factor = cie->ci_data_alignment_factor;
01817 if (return_address_register != NULL)
01818 *return_address_register = cie->ci_return_address_register;
01819 if (initial_instructions != NULL)
01820 *initial_instructions = cie->ci_cie_instr_start;
01821 if (initial_instructions_length != NULL) {
01822 *initial_instructions_length = cie->ci_length +
01823 cie->ci_length_size +
01824 cie->ci_extension_size -
01825 (cie->ci_cie_instr_start - cie->ci_cie_start);
01826
01827 }
01828 *bytes_in_cie = (cie->ci_length);
01829 return (DW_DLV_OK);
01830 }
01831
01832 static int
01833 _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,
01834 Dwarf_Addr pc_requested,
01835 Dwarf_Frame table, Dwarf_Error * error)
01836
01837 {
01838 Dwarf_Debug dbg;
01839 Dwarf_Cie cie;
01840 Dwarf_Sword i;
01841 int dw_err;
01842 Dwarf_Sword icount;
01843 int res;
01844
01845 if (fde == NULL) {
01846 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
01847 return (DW_DLV_ERROR);
01848 }
01849
01850 dbg = fde->fd_dbg;
01851 if (dbg == NULL) {
01852 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
01853 return (DW_DLV_ERROR);
01854 }
01855
01856 if (pc_requested < fde->fd_initial_location ||
01857 pc_requested >=
01858 fde->fd_initial_location + fde->fd_address_range) {
01859 _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
01860 return (DW_DLV_ERROR);
01861 }
01862
01863 cie = fde->fd_cie;
01864 if (cie->ci_initial_table == NULL) {
01865 cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
01866 if (cie->ci_initial_table == NULL) {
01867 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01868 return (DW_DLV_ERROR);
01869 }
01870 for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++) {
01871 cie->ci_initial_table->fr_reg[i].ru_is_off = 0;
01872 cie->ci_initial_table->fr_reg[i].ru_register =
01873 DW_FRAME_SAME_VAL;
01874 cie->ci_initial_table->fr_reg[i].ru_offset = 0;
01875 }
01876
01877 res = _dwarf_exec_frame_instr( false,
01878 NULL,
01879 false,
01880 0,
01881 0,
01882 cie->ci_cie_instr_start,
01883 cie->ci_cie_instr_start +
01884 (cie->ci_length +
01885 cie->ci_length_size +
01886 cie->ci_extension_size -
01887 (cie->ci_cie_instr_start -
01888 cie->ci_cie_start)),
01889 cie->ci_initial_table, cie, dbg,
01890 &icount, &dw_err);
01891 if (res == DW_DLV_ERROR) {
01892 _dwarf_error(dbg, error, dw_err);
01893 return (res);
01894 } else if (res == DW_DLV_NO_ENTRY) {
01895 return res;
01896 }
01897 }
01898
01899 res = _dwarf_exec_frame_instr( false,
01900 NULL,
01901 true,
01902 pc_requested,
01903 fde->fd_initial_location,
01904 fde->fd_fde_instr_start,
01905 fde->fd_fde_start + fde->fd_length +
01906 fde->fd_length_size +
01907 fde->fd_extension_size,
01908 table, cie, dbg, &icount, &dw_err);
01909 if (res == DW_DLV_ERROR) {
01910 _dwarf_error(dbg, error, dw_err);
01911 return (res);
01912 } else if (res == DW_DLV_NO_ENTRY) {
01913 return res;
01914 }
01915
01916 return DW_DLV_OK;
01917 }
01918
01919 int
01920 dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,
01921 Dwarf_Addr pc_requested,
01922 Dwarf_Regtable * reg_table,
01923 Dwarf_Addr * row_pc,
01924 Dwarf_Error * error)
01925 {
01926
01927 struct Dwarf_Frame_s fde_table;
01928 Dwarf_Sword i;
01929 int res;
01930
01931
01932
01933 res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
01934 &fde_table, error);
01935 if (res != DW_DLV_OK) {
01936 return res;
01937 }
01938
01939 for (i = 0; i < DW_REG_TABLE_SIZE; i++) {
01940 reg_table->rules[i].dw_offset_relevant =
01941 fde_table.fr_reg[i].ru_is_off;
01942 reg_table->rules[i].dw_regnum = fde_table.fr_reg[i].ru_register;
01943 reg_table->rules[i].dw_offset = fde_table.fr_reg[i].ru_offset;
01944 }
01945
01946 if (row_pc != NULL)
01947 *row_pc = fde_table.fr_loc;
01948
01949 return DW_DLV_OK;
01950 }
01951
01952
01953 int
01954 dwarf_get_fde_info_for_reg(Dwarf_Fde fde,
01955 Dwarf_Half table_column,
01956 Dwarf_Addr pc_requested,
01957 Dwarf_Signed * offset_relevant,
01958 Dwarf_Signed * register_num,
01959 Dwarf_Signed * offset,
01960 Dwarf_Addr * row_pc, Dwarf_Error * error)
01961 {
01962 struct Dwarf_Frame_s fde_table;
01963 int res;
01964
01965
01966 if (table_column > DW_FRAME_LAST_REG_NUM) {
01967 _dwarf_error(NULL, error, DW_DLE_FRAME_TABLE_COL_BAD);
01968 return (DW_DLV_ERROR);
01969 }
01970
01971
01972
01973 res =
01974 _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
01975 error);
01976 if (res != DW_DLV_OK) {
01977 return res;
01978 }
01979
01980 if (register_num != NULL)
01981 *register_num = fde_table.fr_reg[table_column].ru_register;
01982 if (offset != NULL)
01983 *offset = fde_table.fr_reg[table_column].ru_offset;
01984 if (row_pc != NULL)
01985 *row_pc = fde_table.fr_loc;
01986
01987 *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
01988 return DW_DLV_OK;
01989 }
01990
01991
01992
01993
01994
01995 int
01996 dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr,
01997 Dwarf_Unsigned * outaddrlen,
01998 Dwarf_Error * error)
01999 {
02000 Dwarf_Unsigned len;
02001 unsigned char *instrs;
02002 Dwarf_Debug dbg;
02003
02004 if (inFde == NULL) {
02005 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
02006 return (DW_DLV_ERROR);
02007 }
02008
02009 dbg = inFde->fd_dbg;
02010 if (dbg == NULL) {
02011 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
02012 return (DW_DLV_ERROR);
02013 }
02014
02015 instrs = inFde->fd_fde_instr_start,
02016 len = (inFde->fd_fde_start + inFde->fd_length +
02017 inFde->fd_length_size + inFde->fd_extension_size)
02018 - instrs;
02019
02020 *outinstraddr = instrs;
02021 *outaddrlen = len;
02022 return DW_DLV_OK;
02023 }
02024
02025 int
02026 dwarf_get_fde_n(Dwarf_Fde * fde_data,
02027 Dwarf_Unsigned fde_index,
02028 Dwarf_Fde * returned_fde, Dwarf_Error * error)
02029 {
02030 Dwarf_Debug dbg;
02031
02032 if (fde_data == NULL) {
02033 _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
02034 return (DW_DLV_ERROR);
02035 }
02036
02037 if (*fde_data == NULL) {
02038 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
02039 return (DW_DLV_ERROR);
02040 }
02041
02042 dbg = (*fde_data)->fd_dbg;
02043 if (dbg == NULL) {
02044 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
02045 return (DW_DLV_ERROR);
02046 }
02047
02048 if (fde_index >= dbg->de_fde_count) {
02049 return (DW_DLV_NO_ENTRY);
02050 }
02051 *returned_fde = (*(fde_data + fde_index));
02052 return DW_DLV_OK;
02053 }
02054
02055
02056
02057
02058
02059
02060
02061 int
02062 dwarf_get_fde_at_pc(Dwarf_Fde * fde_data,
02063 Dwarf_Addr pc_of_interest,
02064 Dwarf_Fde * returned_fde,
02065 Dwarf_Addr * lopc,
02066 Dwarf_Addr * hipc, Dwarf_Error * error)
02067 {
02068 Dwarf_Debug dbg;
02069 Dwarf_Fde fde = NULL;
02070
02071 if (fde_data == NULL) {
02072 _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
02073 return (DW_DLV_ERROR);
02074 }
02075
02076 if (*fde_data == NULL) {
02077 _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
02078 return (DW_DLV_ERROR);
02079 }
02080
02081 dbg = (*fde_data)->fd_dbg;
02082 if (dbg == NULL) {
02083 _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
02084 return (DW_DLV_ERROR);
02085 }
02086 {
02087
02088
02089 int low = 0;
02090 int high = dbg->de_fde_count - 1;
02091 int middle = 0;
02092 Dwarf_Fde cur_fde;
02093
02094 while (low <= high) {
02095 middle = (low + high) / 2;
02096 cur_fde = fde_data[middle];
02097 if (pc_of_interest < cur_fde->fd_initial_location) {
02098 high = middle - 1;
02099 } else if (pc_of_interest >=
02100 (cur_fde->fd_initial_location +
02101 cur_fde->fd_address_range)) {
02102 low = middle + 1;
02103 } else {
02104 fde = fde_data[middle];
02105 break;
02106 }
02107 }
02108 }
02109
02110 if (fde) {
02111 if (lopc != NULL)
02112 *lopc = fde->fd_initial_location;
02113 if (hipc != NULL)
02114 *hipc = fde->fd_initial_location +
02115 fde->fd_address_range - 1;
02116 *returned_fde = fde;
02117 return (DW_DLV_OK);
02118 }
02119
02120 return (DW_DLV_NO_ENTRY);
02121 }
02122
02123
02124 int
02125 dwarf_expand_frame_instructions(Dwarf_Debug dbg,
02126 Dwarf_Ptr instruction,
02127 Dwarf_Unsigned i_length,
02128 Dwarf_Frame_Op ** returned_op_list,
02129 Dwarf_Signed * returned_op_count,
02130 Dwarf_Error * error)
02131 {
02132 Dwarf_Sword instr_count;
02133 int res;
02134 int dw_err;
02135
02136 if (dbg == 0) {
02137 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
02138 return (DW_DLV_ERROR);
02139 }
02140
02141 if (returned_op_list == 0 || returned_op_count == 0) {
02142 _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL);
02143 return (DW_DLV_ERROR);
02144 }
02145
02146
02147
02148
02149
02150 res = _dwarf_exec_frame_instr( true,
02151 returned_op_list,
02152 false,
02153 0,
02154 0,
02155 instruction,
02156 (Dwarf_Ptr) (instruction + i_length),
02157 NULL,
02158 NULL,
02159 dbg, &instr_count, &dw_err);
02160 if (res != DW_DLV_OK) {
02161 if (res == DW_DLV_ERROR) {
02162 _dwarf_error(dbg, error, dw_err);
02163 }
02164 return (res);
02165 }
02166
02167 *returned_op_count = instr_count;
02168 return DW_DLV_OK;
02169 }
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179 int
02180 _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
02181 Dwarf_Off ** offsetlist,
02182 Dwarf_Signed * returncount,
02183 Dwarf_Error * err)
02184 {
02185 int retval = DW_DLV_OK;
02186 int res;
02187 Dwarf_Cie *cie_data;
02188 Dwarf_Signed cie_count;
02189 Dwarf_Fde *fde_data;
02190 Dwarf_Signed fde_count;
02191 Dwarf_Signed i;
02192 Dwarf_Frame_Op *frame_inst;
02193 Dwarf_Fde fdep;
02194 Dwarf_Cie ciep;
02195 Dwarf_Chain curr_chain = 0;
02196 Dwarf_Chain head_chain = 0;
02197 Dwarf_Chain prev_chain = 0;
02198 Dwarf_Arange arange;
02199 Dwarf_Unsigned arange_count = 0;
02200 Dwarf_Addr *arange_addrs = 0;
02201 Dwarf_Off *arange_offsets = 0;
02202
02203 res = dwarf_get_fde_list(dbg, &cie_data, &cie_count,
02204 &fde_data, &fde_count, err);
02205 if (res != DW_DLV_OK) {
02206 return res;
02207 }
02208
02209 res =
02210 _dwarf_load_section(dbg,
02211 dbg->de_debug_frame_index,
02212 &dbg->de_debug_frame,
02213 err);
02214 if (res != DW_DLV_OK) {
02215 return res;
02216 }
02217
02218 for (i = 0; i < cie_count; i++) {
02219 Dwarf_Off instoff = 0;
02220 Dwarf_Signed initial_instructions_length = 0;
02221 Dwarf_Small *instr_end = 0;
02222 Dwarf_Sword icount = 0;
02223 int j;
02224 int dw_err;
02225
02226 ciep = cie_data[i];
02227 instoff = ciep->ci_cie_instr_start - dbg->de_debug_frame;
02228 initial_instructions_length = ciep->ci_length +
02229 ciep->ci_length_size + ciep->ci_extension_size -
02230 (ciep->ci_cie_instr_start - ciep->ci_cie_start);
02231 instr_end = ciep->ci_cie_instr_start +
02232 initial_instructions_length;
02233 res = _dwarf_exec_frame_instr( true,
02234 &frame_inst,
02235 false,
02236 0,
02237 0,
02238 ciep->ci_cie_instr_start,
02239 instr_end,
02240 0,
02241 0,
02242 dbg, &icount, &dw_err);
02243 if (res == DW_DLV_ERROR) {
02244 _dwarf_error(dbg, err, dw_err);
02245 return (res);
02246 } else if (res == DW_DLV_NO_ENTRY) {
02247 continue;
02248 }
02249
02250 for (j = 0; j < icount; ++j) {
02251 Dwarf_Frame_Op *finst = frame_inst + j;
02252
02253 if (finst->fp_base_op == 0 && finst->fp_extended_op == 1) {
02254
02255 Dwarf_Addr add = (Dwarf_Addr) finst->fp_offset;
02256 Dwarf_Off off = finst->fp_instr_offset + instoff;
02257
02258 arange = (Dwarf_Arange)
02259 _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
02260 if (arange == NULL) {
02261 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
02262 return (DW_DLV_ERROR);
02263 }
02264 arange->ar_address = add;
02265 arange->ar_info_offset = off;
02266 arange_count++;
02267 curr_chain = (Dwarf_Chain)
02268 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
02269 if (curr_chain == NULL) {
02270 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
02271 return (DW_DLV_ERROR);
02272 }
02273 curr_chain->ch_item = arange;
02274 if (head_chain == NULL)
02275 head_chain = prev_chain = curr_chain;
02276 else {
02277 prev_chain->ch_next = curr_chain;
02278 prev_chain = curr_chain;
02279 }
02280 }
02281 }
02282 dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK);
02283
02284 }
02285 for (i = 0; i < fde_count; i++) {
02286 Dwarf_Small *instr_end = 0;
02287 Dwarf_Sword icount = 0;
02288 Dwarf_Signed instructions_length = 0;
02289 Dwarf_Off instoff = 0;
02290 Dwarf_Off off = 0;
02291 Dwarf_Addr addr = 0;
02292 int j;
02293 int dw_err;
02294
02295 fdep = fde_data[i];
02296 off = fdep->fd_initial_loc_pos - dbg->de_debug_frame;
02297 addr = fdep->fd_initial_location;
02298 arange = (Dwarf_Arange)
02299 _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
02300 if (arange == NULL) {
02301 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
02302 return (DW_DLV_ERROR);
02303 }
02304 arange->ar_address = addr;
02305 arange->ar_info_offset = off;
02306 arange_count++;
02307 curr_chain = (Dwarf_Chain)
02308 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
02309 if (curr_chain == NULL) {
02310 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
02311 return (DW_DLV_ERROR);
02312 }
02313 curr_chain->ch_item = arange;
02314 if (head_chain == NULL)
02315 head_chain = prev_chain = curr_chain;
02316 else {
02317 prev_chain->ch_next = curr_chain;
02318 prev_chain = curr_chain;
02319 }
02320
02321
02322 instoff = fdep->fd_fde_instr_start - dbg->de_debug_frame;
02323 instructions_length = fdep->fd_length +
02324 fdep->fd_length_size + fdep->fd_extension_size -
02325 (fdep->fd_fde_instr_start - fdep->fd_fde_start);
02326 instr_end = fdep->fd_fde_instr_start + instructions_length;
02327 res = _dwarf_exec_frame_instr( true,
02328 &frame_inst,
02329 false,
02330 0,
02331 0,
02332 fdep->fd_fde_instr_start,
02333 instr_end,
02334 0,
02335 0,
02336 dbg, &icount, &dw_err);
02337 if (res == DW_DLV_ERROR) {
02338 _dwarf_error(dbg, err, dw_err);
02339 return (res);
02340 } else if (res == DW_DLV_NO_ENTRY) {
02341 continue;
02342 }
02343
02344 for (j = 0; j < icount; ++j) {
02345 Dwarf_Frame_Op *finst2 = frame_inst + j;
02346
02347 if (finst2->fp_base_op == 0 && finst2->fp_extended_op == 1) {
02348
02349 Dwarf_Addr add = (Dwarf_Addr) finst2->fp_offset;
02350 Dwarf_Off off = finst2->fp_instr_offset + instoff;
02351
02352 arange = (Dwarf_Arange)
02353 _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
02354 if (arange == NULL) {
02355 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
02356 return (DW_DLV_ERROR);
02357 }
02358 arange->ar_address = add;
02359 arange->ar_info_offset = off;
02360 arange_count++;
02361 curr_chain = (Dwarf_Chain)
02362 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
02363 if (curr_chain == NULL) {
02364 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
02365 return (DW_DLV_ERROR);
02366 }
02367 curr_chain->ch_item = arange;
02368 if (head_chain == NULL)
02369 head_chain = prev_chain = curr_chain;
02370 else {
02371 prev_chain->ch_next = curr_chain;
02372 prev_chain = curr_chain;
02373 }
02374
02375 }
02376 }
02377 dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK);
02378
02379 }
02380 dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
02381 dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
02382 arange_addrs = (Dwarf_Addr *)
02383 _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
02384 if (arange_addrs == NULL) {
02385 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
02386 return (DW_DLV_ERROR);
02387 }
02388 arange_offsets = (Dwarf_Off *)
02389 _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
02390 if (arange_offsets == NULL) {
02391 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
02392 return (DW_DLV_ERROR);
02393 }
02394
02395 curr_chain = head_chain;
02396 for (i = 0; i < arange_count; i++) {
02397 Dwarf_Arange ar = curr_chain->ch_item;
02398
02399 arange_addrs[i] = ar->ar_address;
02400 arange_offsets[i] = ar->ar_info_offset;
02401 prev_chain = curr_chain;
02402 curr_chain = curr_chain->ch_next;
02403 dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
02404 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
02405 }
02406 *returncount = arange_count;
02407 *offsetlist = arange_offsets;
02408 *addrlist = arange_addrs;
02409 return retval;
02410 }
02411
02412
02413
02414
02415
02416 int
02417 _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
02418 Dwarf_Off * fde_off, Dwarf_Off * cie_off,
02419 Dwarf_Error * err)
02420 {
02421 int res;
02422 char *start;
02423 char *loc;
02424
02425 res =
02426 _dwarf_load_section(dbg,
02427 dbg->de_debug_frame_index,
02428 &dbg->de_debug_frame,
02429 err);
02430 if (res != DW_DLV_OK) {
02431 return res;
02432 }
02433
02434 start = (char *) dbg->de_debug_frame;
02435 loc = (char *) in_fde->fd_fde_start;
02436
02437 *fde_off = (loc - start);
02438 *cie_off = in_fde->fd_cie_offset;
02439 return DW_DLV_OK;
02440 }
02441
02442
02443
02444
02445
02446 int
02447 _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
02448 Dwarf_Off * cie_off, Dwarf_Error * err)
02449 {
02450 int res;
02451 char *start;
02452 char *loc;
02453
02454 res =
02455 _dwarf_load_section(dbg,
02456 dbg->de_debug_frame_index,
02457 &dbg->de_debug_frame,
02458 err);
02459 if (res != DW_DLV_OK) {
02460 return res;
02461 }
02462
02463 start = (char *) dbg->de_debug_frame;
02464 loc = (char *) in_cie->ci_cie_start;
02465
02466 *cie_off = (loc - start);
02467 return DW_DLV_OK;
02468 }