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 "dwarf_loc.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 static Dwarf_Locdesc *
00060 _dwarf_get_locdesc(Dwarf_Debug dbg,
00061 Dwarf_Block * loc_block,
00062 Dwarf_Addr lowpc,
00063 Dwarf_Addr highpc, Dwarf_Error * error)
00064 {
00065
00066 Dwarf_Unsigned loc_len;
00067
00068
00069 Dwarf_Small *loc_ptr;
00070
00071
00072 Dwarf_Small atom;
00073
00074
00075 Dwarf_Unsigned offset;
00076
00077
00078 Dwarf_Unsigned operand1, operand2;
00079
00080
00081 Dwarf_Loc_Chain curr_loc, prev_loc, head_loc = NULL;
00082
00083
00084 Dwarf_Unsigned op_count;
00085
00086
00087 Dwarf_Loc *block_loc;
00088
00089
00090 Dwarf_Locdesc *locdesc;
00091
00092 Dwarf_Word leb128_length;
00093 Dwarf_Unsigned i;
00094
00095
00096
00097 loc_len = loc_block->bl_len;
00098 loc_ptr = loc_block->bl_data;
00099
00100 offset = 0;
00101 op_count = 0;
00102 while (offset < loc_len) {
00103
00104 operand1 = 0;
00105 operand2 = 0;
00106 op_count++;
00107
00108 atom = *(Dwarf_Small *) loc_ptr;
00109 loc_ptr++;
00110 offset++;
00111
00112 curr_loc =
00113 (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN,
00114 1);
00115 if (curr_loc == NULL) {
00116 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00117 return (NULL);
00118 }
00119 curr_loc->lc_offset = offset;
00120 curr_loc->lc_atom = atom;
00121 switch (atom) {
00122
00123 case DW_OP_reg0:
00124 case DW_OP_reg1:
00125 case DW_OP_reg2:
00126 case DW_OP_reg3:
00127 case DW_OP_reg4:
00128 case DW_OP_reg5:
00129 case DW_OP_reg6:
00130 case DW_OP_reg7:
00131 case DW_OP_reg8:
00132 case DW_OP_reg9:
00133 case DW_OP_reg10:
00134 case DW_OP_reg11:
00135 case DW_OP_reg12:
00136 case DW_OP_reg13:
00137 case DW_OP_reg14:
00138 case DW_OP_reg15:
00139 case DW_OP_reg16:
00140 case DW_OP_reg17:
00141 case DW_OP_reg18:
00142 case DW_OP_reg19:
00143 case DW_OP_reg20:
00144 case DW_OP_reg21:
00145 case DW_OP_reg22:
00146 case DW_OP_reg23:
00147 case DW_OP_reg24:
00148 case DW_OP_reg25:
00149 case DW_OP_reg26:
00150 case DW_OP_reg27:
00151 case DW_OP_reg28:
00152 case DW_OP_reg29:
00153 case DW_OP_reg30:
00154 case DW_OP_reg31:
00155 break;
00156
00157 case DW_OP_regx:
00158 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
00159 loc_ptr = loc_ptr + leb128_length;
00160 offset = offset + leb128_length;
00161 break;
00162
00163 case DW_OP_lit0:
00164 case DW_OP_lit1:
00165 case DW_OP_lit2:
00166 case DW_OP_lit3:
00167 case DW_OP_lit4:
00168 case DW_OP_lit5:
00169 case DW_OP_lit6:
00170 case DW_OP_lit7:
00171 case DW_OP_lit8:
00172 case DW_OP_lit9:
00173 case DW_OP_lit10:
00174 case DW_OP_lit11:
00175 case DW_OP_lit12:
00176 case DW_OP_lit13:
00177 case DW_OP_lit14:
00178 case DW_OP_lit15:
00179 case DW_OP_lit16:
00180 case DW_OP_lit17:
00181 case DW_OP_lit18:
00182 case DW_OP_lit19:
00183 case DW_OP_lit20:
00184 case DW_OP_lit21:
00185 case DW_OP_lit22:
00186 case DW_OP_lit23:
00187 case DW_OP_lit24:
00188 case DW_OP_lit25:
00189 case DW_OP_lit26:
00190 case DW_OP_lit27:
00191 case DW_OP_lit28:
00192 case DW_OP_lit29:
00193 case DW_OP_lit30:
00194 case DW_OP_lit31:
00195 operand1 = atom - DW_OP_lit0;
00196 break;
00197
00198 case DW_OP_addr:
00199 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned,
00200 loc_ptr, dbg->de_pointer_size);
00201 loc_ptr += dbg->de_pointer_size;
00202 offset += dbg->de_pointer_size;
00203 break;
00204
00205 case DW_OP_const1u:
00206 operand1 = *(Dwarf_Small *) loc_ptr;
00207 loc_ptr = loc_ptr + 1;
00208 offset = offset + 1;
00209 break;
00210
00211 case DW_OP_const1s:
00212 operand1 = *(Dwarf_Sbyte *) loc_ptr;
00213 loc_ptr = loc_ptr + 1;
00214 offset = offset + 1;
00215 break;
00216
00217 case DW_OP_const2u:
00218 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
00219 loc_ptr = loc_ptr + 2;
00220 offset = offset + 2;
00221 break;
00222
00223 case DW_OP_const2s:
00224 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
00225 loc_ptr = loc_ptr + 2;
00226 offset = offset + 2;
00227 break;
00228
00229 case DW_OP_const4u:
00230 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
00231 loc_ptr = loc_ptr + 4;
00232 offset = offset + 4;
00233 break;
00234
00235 case DW_OP_const4s:
00236 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
00237 loc_ptr = loc_ptr + 4;
00238 offset = offset + 4;
00239 break;
00240
00241 case DW_OP_const8u:
00242 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
00243 loc_ptr = loc_ptr + 8;
00244 offset = offset + 8;
00245 break;
00246
00247 case DW_OP_const8s:
00248 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
00249 loc_ptr = loc_ptr + 8;
00250 offset = offset + 8;
00251 break;
00252
00253 case DW_OP_constu:
00254 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
00255 loc_ptr = loc_ptr + leb128_length;
00256 offset = offset + leb128_length;
00257 break;
00258
00259 case DW_OP_consts:
00260 operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
00261 loc_ptr = loc_ptr + leb128_length;
00262 offset = offset + leb128_length;
00263 break;
00264
00265 case DW_OP_fbreg:
00266 operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
00267 loc_ptr = loc_ptr + leb128_length;
00268 offset = offset + leb128_length;
00269 break;
00270
00271 case DW_OP_breg0:
00272 case DW_OP_breg1:
00273 case DW_OP_breg2:
00274 case DW_OP_breg3:
00275 case DW_OP_breg4:
00276 case DW_OP_breg5:
00277 case DW_OP_breg6:
00278 case DW_OP_breg7:
00279 case DW_OP_breg8:
00280 case DW_OP_breg9:
00281 case DW_OP_breg10:
00282 case DW_OP_breg11:
00283 case DW_OP_breg12:
00284 case DW_OP_breg13:
00285 case DW_OP_breg14:
00286 case DW_OP_breg15:
00287 case DW_OP_breg16:
00288 case DW_OP_breg17:
00289 case DW_OP_breg18:
00290 case DW_OP_breg19:
00291 case DW_OP_breg20:
00292 case DW_OP_breg21:
00293 case DW_OP_breg22:
00294 case DW_OP_breg23:
00295 case DW_OP_breg24:
00296 case DW_OP_breg25:
00297 case DW_OP_breg26:
00298 case DW_OP_breg27:
00299 case DW_OP_breg28:
00300 case DW_OP_breg29:
00301 case DW_OP_breg30:
00302 case DW_OP_breg31:
00303 operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
00304 loc_ptr = loc_ptr + leb128_length;
00305 offset = offset + leb128_length;
00306 break;
00307
00308 case DW_OP_bregx:
00309
00310 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
00311 loc_ptr = loc_ptr + leb128_length;
00312 offset = offset + leb128_length;
00313
00314 operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
00315 loc_ptr = loc_ptr + leb128_length;
00316 offset = offset + leb128_length;
00317 break;
00318
00319 case DW_OP_dup:
00320 case DW_OP_drop:
00321 break;
00322
00323 case DW_OP_pick:
00324 operand1 = *(Dwarf_Small *) loc_ptr;
00325 loc_ptr = loc_ptr + 1;
00326 offset = offset + 1;
00327 break;
00328
00329 case DW_OP_over:
00330 case DW_OP_swap:
00331 case DW_OP_rot:
00332 case DW_OP_deref:
00333 break;
00334
00335 case DW_OP_deref_size:
00336 operand1 = *(Dwarf_Small *) loc_ptr;
00337 loc_ptr = loc_ptr + 1;
00338 offset = offset + 1;
00339 break;
00340
00341 case DW_OP_xderef:
00342 break;
00343
00344 case DW_OP_xderef_size:
00345 operand1 = *(Dwarf_Small *) loc_ptr;
00346 loc_ptr = loc_ptr + 1;
00347 offset = offset + 1;
00348 break;
00349
00350 case DW_OP_abs:
00351 case DW_OP_and:
00352 case DW_OP_div:
00353 case DW_OP_minus:
00354 case DW_OP_mod:
00355 case DW_OP_mul:
00356 case DW_OP_neg:
00357 case DW_OP_not:
00358 case DW_OP_or:
00359 case DW_OP_plus:
00360 break;
00361
00362 case DW_OP_plus_uconst:
00363 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
00364 loc_ptr = loc_ptr + leb128_length;
00365 offset = offset + leb128_length;
00366 break;
00367
00368 case DW_OP_shl:
00369 case DW_OP_shr:
00370 case DW_OP_shra:
00371 case DW_OP_xor:
00372 break;
00373
00374 case DW_OP_le:
00375 case DW_OP_ge:
00376 case DW_OP_eq:
00377 case DW_OP_lt:
00378 case DW_OP_gt:
00379 case DW_OP_ne:
00380 break;
00381
00382 case DW_OP_skip:
00383 case DW_OP_bra:
00384 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
00385 loc_ptr = loc_ptr + 2;
00386 offset = offset + 2;
00387 break;
00388
00389 case DW_OP_piece:
00390 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
00391 loc_ptr = loc_ptr + leb128_length;
00392 offset = offset + leb128_length;
00393 break;
00394
00395 case DW_OP_nop:
00396 break;
00397
00398 default:
00399 _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
00400 return (NULL);
00401 }
00402
00403
00404 curr_loc->lc_number = operand1;
00405 curr_loc->lc_number2 = operand2;
00406
00407 if (head_loc == NULL)
00408 head_loc = prev_loc = curr_loc;
00409 else {
00410 prev_loc->lc_next = curr_loc;
00411 prev_loc = curr_loc;
00412 }
00413 }
00414
00415 block_loc =
00416 (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count);
00417 if (block_loc == NULL) {
00418 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00419 return (NULL);
00420 }
00421
00422 curr_loc = head_loc;
00423 for (i = 0; i < op_count; i++) {
00424 (block_loc + i)->lr_atom = curr_loc->lc_atom;
00425 (block_loc + i)->lr_number = curr_loc->lc_number;
00426 (block_loc + i)->lr_number2 = curr_loc->lc_number2;
00427 (block_loc + i)->lr_offset = curr_loc->lc_offset;
00428
00429 prev_loc = curr_loc;
00430 curr_loc = curr_loc->lc_next;
00431 dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
00432 }
00433
00434 locdesc =
00435 (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
00436 if (locdesc == NULL) {
00437 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00438 return (NULL);
00439 }
00440
00441 locdesc->ld_cents = op_count;
00442 locdesc->ld_s = block_loc;
00443 locdesc->ld_from_loclist = loc_block->bl_from_loclist;
00444 locdesc->ld_section_offset = loc_block->bl_section_offset;
00445 locdesc->ld_lopc = lowpc;
00446 locdesc->ld_hipc = highpc;
00447
00448 return (locdesc);
00449 }
00450
00451
00452
00453
00454
00455
00456 #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
00457
00458 static int
00459 _dwarf_read_loc_section(Dwarf_Debug dbg,
00460 Dwarf_Block * return_block,
00461 Dwarf_Addr * lowpc, Dwarf_Addr * hipc,
00462 Dwarf_Off sec_offset, Dwarf_Error * error)
00463 {
00464 Dwarf_Small *beg = dbg->de_debug_loc + sec_offset;
00465 int address_size = dbg->de_pointer_size;
00466
00467 Dwarf_Addr start_addr = 0;
00468 Dwarf_Addr end_addr = 0;
00469 Dwarf_Half exprblock_size = 0;
00470 Dwarf_Unsigned exprblock_off =
00471 2 * address_size + sizeof(Dwarf_Half);
00472
00473 if (sec_offset >= dbg->de_debug_loc_size) {
00474
00475 return DW_DLV_NO_ENTRY;
00476 }
00477
00478
00479 if (exprblock_off > dbg->de_debug_loc_size) {
00480 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
00481 return DW_DLV_ERROR;
00482 }
00483
00484 READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size);
00485 READ_UNALIGNED(dbg, end_addr, Dwarf_Addr,
00486 beg + address_size, address_size);
00487 if (start_addr == 0 && end_addr == 0) {
00488
00489
00490 exprblock_size = 0;
00491 exprblock_off -= sizeof(Dwarf_Half);
00492 } else if (start_addr == MAX_ADDR) {
00493
00494
00495 exprblock_size = 0;
00496 exprblock_off -= sizeof(Dwarf_Half);
00497 } else {
00498
00499 READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half,
00500 beg + 2 * address_size, sizeof(Dwarf_Half));
00501
00502 if ((exprblock_off + exprblock_size) > dbg->de_debug_loc_size) {
00503 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
00504 return DW_DLV_ERROR;
00505 }
00506 }
00507 #undef MAX_ADDR
00508 *lowpc = start_addr;
00509 *hipc = end_addr;
00510
00511 return_block->bl_len = exprblock_size;
00512 return_block->bl_from_loclist = 1;
00513 return_block->bl_data = beg + exprblock_off;
00514 return_block->bl_section_offset =
00515 ((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc;
00516
00517 return DW_DLV_OK;
00518
00519 }
00520 static int
00521 _dwarf_get_loclist_count(Dwarf_Debug dbg,
00522 Dwarf_Off loclist_offset,
00523 int *loclist_count, Dwarf_Error * error)
00524 {
00525 int count = 0;
00526 Dwarf_Off offset = loclist_offset;
00527
00528
00529 for (;;) {
00530 Dwarf_Block b;
00531 Dwarf_Addr lowpc;
00532 Dwarf_Addr highpc;
00533 int res = _dwarf_read_loc_section(dbg, &b,
00534
00535 &lowpc, &highpc,
00536 offset, error);
00537
00538 if (res != DW_DLV_OK) {
00539 return res;
00540 }
00541 offset = b.bl_len + b.bl_section_offset;
00542 if (lowpc == 0 && highpc == 0) {
00543 break;
00544 }
00545 count++;
00546 }
00547 *loclist_count = count;
00548 return DW_DLV_OK;
00549 }
00550
00551
00552
00553 static int
00554 _dwarf_setup_loc(Dwarf_Attribute attr,
00555 Dwarf_Debug * dbg_ret,
00556 Dwarf_Half * form_ret, Dwarf_Error * error)
00557 {
00558 Dwarf_Debug dbg = 0;
00559 Dwarf_Half form = 0;
00560 int blkres;
00561
00562 if (attr == NULL) {
00563 _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
00564 return (DW_DLV_ERROR);
00565 }
00566 if (attr->ar_cu_context == NULL) {
00567 _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
00568 return (DW_DLV_ERROR);
00569 }
00570
00571 dbg = attr->ar_cu_context->cc_dbg;
00572 if (dbg == NULL) {
00573 _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
00574 return (DW_DLV_ERROR);
00575 }
00576 *dbg_ret = dbg;
00577 blkres = dwarf_whatform(attr, &form, error);
00578 if (blkres != DW_DLV_OK) {
00579 _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
00580 return blkres;
00581 }
00582 *form_ret = form;
00583
00584 return DW_DLV_OK;
00585 }
00586
00587
00588
00589 static int
00590 _dwarf_get_loclist_header_start(Dwarf_Debug dbg,
00591 Dwarf_Attribute attr,
00592 Dwarf_Unsigned * loclist_offset,
00593 Dwarf_Error * error)
00594 {
00595 int secload = 0;
00596 int blkres = dwarf_formudata(attr, loclist_offset, error);
00597
00598 if (blkres != DW_DLV_OK) {
00599 return (blkres);
00600 }
00601
00602 if (!dbg->de_debug_loc) {
00603 secload = _dwarf_load_section(dbg,
00604 dbg->de_debug_loc_index,
00605 &dbg->de_debug_loc, error);
00606 if (secload != DW_DLV_OK) {
00607 return secload;
00608 }
00609 }
00610 return DW_DLV_OK;
00611 }
00612
00613
00614
00615
00616
00617 static void
00618 _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count)
00619 {
00620 int i;
00621
00622 for (i = 0; i < count; ++i) {
00623 dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
00624 dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
00625 }
00626 dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
00627 }
00628
00629
00630
00631
00632
00633
00634 int
00635 dwarf_loclist_n(Dwarf_Attribute attr,
00636 Dwarf_Locdesc *** llbuf_out,
00637 Dwarf_Signed * listlen_out, Dwarf_Error * error)
00638 {
00639 Dwarf_Debug dbg;
00640
00641
00642
00643
00644 Dwarf_Attribute loc_attr = attr;
00645
00646
00647 Dwarf_Block loc_block;
00648
00649
00650 Dwarf_Locdesc *locdesc = 0;
00651
00652 Dwarf_Half form = 0;
00653 Dwarf_Addr lowpc = 0;
00654 Dwarf_Addr highpc = 0;
00655 Dwarf_Signed listlen = 0;
00656 Dwarf_Locdesc **llbuf = 0;
00657
00658 int blkres;
00659 int setup_res;
00660
00661
00662 setup_res = _dwarf_setup_loc(attr, &dbg, &form, error);
00663 if (setup_res != DW_DLV_OK) {
00664 return setup_res;
00665 }
00666
00667
00668 if (form == DW_FORM_data4 || form == DW_FORM_data8) {
00669
00670
00671
00672 Dwarf_Unsigned loclist_offset = 0;
00673 int off_res;
00674 int count_res;
00675 int loclist_count;
00676 int lli;
00677
00678 off_res = _dwarf_get_loclist_header_start(dbg,
00679 attr, &loclist_offset,
00680 error);
00681 if (off_res != DW_DLV_OK) {
00682 return off_res;
00683 }
00684 count_res = _dwarf_get_loclist_count(dbg, loclist_offset,
00685 &loclist_count, error);
00686 listlen = loclist_count;
00687 if (count_res != DW_DLV_OK) {
00688 return count_res;
00689 }
00690 if (loclist_count == 0) {
00691 return DW_DLV_NO_ENTRY;
00692 }
00693
00694 llbuf = (Dwarf_Locdesc **)
00695 _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
00696 if (!llbuf) {
00697 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00698 return (DW_DLV_ERROR);
00699 }
00700
00701 for (lli = 0; lli < loclist_count; ++lli) {
00702 blkres = _dwarf_read_loc_section(dbg, &loc_block,
00703 &lowpc,
00704 &highpc,
00705 loclist_offset, error);
00706 if (blkres != DW_DLV_OK) {
00707 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
00708 return (blkres);
00709 }
00710 locdesc = _dwarf_get_locdesc(dbg, &loc_block,
00711 lowpc, highpc, error);
00712 if (locdesc == NULL) {
00713 _dwarf_cleanup_llbuf(dbg, llbuf, lli);
00714
00715 return (DW_DLV_ERROR);
00716 }
00717 llbuf[lli] = locdesc;
00718
00719
00720 loclist_offset = loc_block.bl_section_offset +
00721 loc_block.bl_len;
00722 }
00723
00724
00725 } else {
00726 Dwarf_Block *tblock = 0;
00727
00728 blkres = dwarf_formblock(loc_attr, &tblock, error);
00729 if (blkres != DW_DLV_OK) {
00730 return (blkres);
00731 }
00732 loc_block = *tblock;
00733
00734
00735 dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
00736 listlen = 1;
00737
00738 lowpc = 0;
00739 highpc = (Dwarf_Unsigned) (-1LL);
00740
00741
00742
00743
00744
00745
00746 locdesc = _dwarf_get_locdesc(dbg, &loc_block,
00747 lowpc, highpc, error);
00748 if (locdesc == NULL) {
00749
00750 return (DW_DLV_ERROR);
00751 }
00752 llbuf = (Dwarf_Locdesc **)
00753 _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
00754 if (!llbuf) {
00755
00756 dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
00757 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00758 return (DW_DLV_ERROR);
00759 }
00760 llbuf[0] = locdesc;
00761 }
00762
00763 *llbuf_out = llbuf;
00764 *listlen_out = listlen;
00765 return (DW_DLV_OK);
00766 }
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 int
00781 dwarf_loclist(Dwarf_Attribute attr,
00782 Dwarf_Locdesc ** llbuf,
00783 Dwarf_Signed * listlen, Dwarf_Error * error)
00784 {
00785 Dwarf_Debug dbg;
00786
00787
00788
00789
00790 Dwarf_Attribute loc_attr = attr;
00791
00792
00793 Dwarf_Block loc_block;
00794
00795
00796 Dwarf_Locdesc *locdesc = 0;
00797
00798 Dwarf_Half form = 0;
00799 Dwarf_Addr lowpc = 0;
00800 Dwarf_Addr highpc = 0;
00801
00802 int blkres;
00803 int setup_res;
00804
00805
00806 setup_res = _dwarf_setup_loc(attr, &dbg, &form, error);
00807 if (setup_res != DW_DLV_OK) {
00808 return setup_res;
00809 }
00810
00811
00812 if (form == DW_FORM_data4 || form == DW_FORM_data8) {
00813
00814
00815
00816 Dwarf_Unsigned loclist_offset = 0;
00817 int off_res;
00818
00819 off_res = _dwarf_get_loclist_header_start(dbg,
00820 attr, &loclist_offset,
00821 error);
00822 if (off_res != DW_DLV_OK) {
00823 return off_res;
00824 }
00825
00826
00827 blkres = _dwarf_read_loc_section(dbg, &loc_block,
00828 &lowpc,
00829 &highpc,
00830 loclist_offset, error);
00831 if (blkres != DW_DLV_OK) {
00832 return (blkres);
00833 }
00834
00835
00836
00837
00838 } else {
00839 Dwarf_Block *tblock = 0;
00840
00841 blkres = dwarf_formblock(loc_attr, &tblock, error);
00842 if (blkres != DW_DLV_OK) {
00843 return (blkres);
00844 }
00845 loc_block = *tblock;
00846
00847
00848 dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
00849 lowpc = 0;
00850 highpc = (Dwarf_Unsigned) (-1LL);
00851 }
00852
00853
00854
00855
00856
00857
00858
00859 locdesc = _dwarf_get_locdesc(dbg, &loc_block, lowpc, highpc, error);
00860 if (locdesc == NULL) {
00861
00862 return (DW_DLV_ERROR);
00863 }
00864
00865 *llbuf = locdesc;
00866 *listlen = 1;
00867 return (DW_DLV_OK);
00868 }
00869
00870
00871
00872
00873
00874
00875 int
00876 dwarf_get_loclist_entry(Dwarf_Debug dbg,
00877 Dwarf_Unsigned offset,
00878 Dwarf_Addr * hipc_offset,
00879 Dwarf_Addr * lopc_offset,
00880 Dwarf_Ptr * data,
00881 Dwarf_Unsigned * entry_len,
00882 Dwarf_Unsigned * next_entry,
00883 Dwarf_Error * error)
00884 {
00885 Dwarf_Block b;
00886 Dwarf_Addr lowpc;
00887 Dwarf_Addr highpc;
00888 int res;
00889
00890 if (!dbg->de_debug_loc) {
00891 int secload = _dwarf_load_section(dbg,
00892 dbg->de_debug_loc_index,
00893 &dbg->de_debug_loc,
00894 error);
00895
00896 if (secload != DW_DLV_OK) {
00897 return secload;
00898 }
00899 }
00900
00901 res = _dwarf_read_loc_section(dbg,
00902 &b, &lowpc, &highpc, offset, error);
00903 if (res != DW_DLV_OK) {
00904 return res;
00905 }
00906 *hipc_offset = highpc;
00907 *lopc_offset = lowpc;
00908 *entry_len = b.bl_len;
00909 *data = b.bl_data;
00910 *next_entry = b.bl_len + b.bl_section_offset;
00911
00912 return DW_DLV_OK;
00913
00914
00915
00916 }