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 "dwarf_line.h"
00046 #ifdef HAVE_ALLOCA_H
00047 #include <alloca.h>
00048 #endif
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 int
00059 dwarf_srcfiles(Dwarf_Die die,
00060 char ***srcfiles,
00061 Dwarf_Signed * srcfilecount, Dwarf_Error * error)
00062 {
00063
00064
00065
00066 Dwarf_Small *line_ptr;
00067
00068
00069
00070
00071 Dwarf_Small *line_ptr_end;
00072
00073
00074
00075
00076
00077 Dwarf_Small *check_line_ptr;
00078
00079
00080
00081
00082 Dwarf_Attribute stmt_list_attr;
00083
00084
00085 Dwarf_Attribute comp_dir_attr;
00086
00087
00088 Dwarf_Small *comp_dir = 0;
00089
00090
00091
00092
00093 Dwarf_Unsigned line_offset = 0;
00094
00095
00096 Dwarf_Unsigned total_length = 0;
00097 Dwarf_Half version = 0;
00098 Dwarf_Unsigned prologue_length = 0;
00099 Dwarf_Small special_opcode_base= 0;
00100
00101
00102 char *file_name = 0;
00103
00104
00105 char *dir_name = 0;
00106
00107
00108 char *full_name = 0;
00109
00110
00111
00112
00113 Dwarf_Sword dir_index = 0;
00114
00115 Dwarf_Small *include_directories = 0;
00116
00117 Dwarf_Sword i = 0;
00118 Dwarf_Sword file_count = 0;
00119 Dwarf_Sword directories_count = 0;
00120
00121
00122
00123
00124 Dwarf_Word leb128_length;
00125
00126
00127
00128
00129
00130
00131 char **ret_files = 0;
00132
00133
00134 Dwarf_Debug dbg;
00135
00136
00137 Dwarf_Chain curr_chain, prev_chain, head_chain = NULL;
00138 int resattr;
00139 int lres;
00140
00141 int local_length_size = 0;
00142
00143 int local_extension_size = 0;
00144
00145 int res;
00146
00147
00148
00149
00150 if (error != NULL)
00151 *error = NULL;
00152
00153 CHECK_DIE(die, DW_DLV_ERROR)
00154 dbg = die->di_cu_context->cc_dbg;
00155
00156 resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
00157 if (resattr != DW_DLV_OK) {
00158 return resattr;
00159 }
00160
00161 if (dbg->de_debug_line_index == 0) {
00162 _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
00163 return (DW_DLV_ERROR);
00164 }
00165
00166 res =
00167 _dwarf_load_section(dbg,
00168 dbg->de_debug_line_index,
00169 &dbg->de_debug_line,
00170 error);
00171 if (res != DW_DLV_OK) {
00172 return res;
00173 }
00174
00175 lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
00176 if (lres != DW_DLV_OK) {
00177 return lres;
00178 }
00179 if (line_offset >= dbg->de_debug_line_size) {
00180 _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
00181 return (DW_DLV_ERROR);
00182 }
00183 line_ptr = dbg->de_debug_line + line_offset;
00184 dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
00185
00186
00187
00188
00189 resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
00190 if (resattr == DW_DLV_ERROR) {
00191 return resattr;
00192 }
00193 if (resattr == DW_DLV_OK) {
00194 int cres;
00195 char *cdir;
00196
00197 cres = dwarf_formstring(comp_dir_attr, &cdir, error);
00198 if (cres == DW_DLV_ERROR) {
00199 return cres;
00200 } else if (cres == DW_DLV_OK) {
00201 comp_dir = (Dwarf_Small *) cdir;
00202 }
00203 }
00204 if (resattr == DW_DLV_OK) {
00205 dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
00206 }
00207
00208
00209
00210
00211
00212 READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
00213 line_ptr, local_length_size, local_extension_size);
00214
00215
00216 line_ptr_end = line_ptr + total_length;
00217 if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) {
00218 _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD);
00219 return (DW_DLV_ERROR);
00220 }
00221
00222 READ_UNALIGNED(dbg, version, Dwarf_Half,
00223 line_ptr, sizeof(Dwarf_Half));
00224 line_ptr += sizeof(Dwarf_Half);
00225 if (version != CURRENT_VERSION_STAMP &&
00226 version != CURRENT_VERSION_STAMP3) {
00227 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
00228 return (DW_DLV_ERROR);
00229 }
00230
00231 READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
00232 line_ptr, local_length_size);
00233 line_ptr += local_length_size;
00234 check_line_ptr = line_ptr;
00235
00236
00237 line_ptr = line_ptr + sizeof(Dwarf_Small);
00238
00239
00240 line_ptr = line_ptr + sizeof(Dwarf_Small);
00241
00242
00243 line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
00244
00245
00246 line_ptr = line_ptr + sizeof(Dwarf_Small);
00247
00248 special_opcode_base = *(Dwarf_Small *) line_ptr;
00249 line_ptr = line_ptr + sizeof(Dwarf_Small);
00250
00251 for (i = 1; i < special_opcode_base; i++) {
00252
00253 line_ptr = line_ptr + sizeof(Dwarf_Small);
00254 }
00255
00256 directories_count = 0;
00257 include_directories = line_ptr;
00258 while ((*(char *) line_ptr) != '\0') {
00259 line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
00260 directories_count++;
00261 }
00262 line_ptr++;
00263
00264 file_count = 0;
00265 while (*(char *) line_ptr != '\0') {
00266 Dwarf_Unsigned utmp;
00267
00268 file_name = (char *) line_ptr;
00269 line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
00270
00271 DECODE_LEB128_UWORD(line_ptr, utmp)
00272 dir_index = (Dwarf_Sword) utmp;
00273 if (dir_index > directories_count) {
00274 _dwarf_error(dbg, error, DW_DLE_DIR_INDEX_BAD);
00275 return (DW_DLV_ERROR);
00276 }
00277
00278 if (dir_index == 0)
00279 dir_name = (char *) comp_dir;
00280 else {
00281 dir_name = (char *) include_directories;
00282 for (i = 1; i < dir_index; i++)
00283
00284
00285 dir_name = dir_name + strlen(dir_name) + 1;
00286 }
00287
00288
00289 if ((*file_name) == '/' || dir_name == 0)
00290 full_name = file_name;
00291 else {
00292 full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
00293 strlen(dir_name) + 1 +
00294 strlen(file_name) +
00295 1);
00296 if (full_name == NULL) {
00297 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00298 return (DW_DLV_ERROR);
00299 }
00300
00301 strcpy(full_name, dir_name);
00302 strcat(full_name, "/");
00303 strcat(full_name, file_name);
00304 }
00305
00306
00307 _dwarf_decode_u_leb128(line_ptr, &leb128_length);
00308 line_ptr = line_ptr + leb128_length;
00309
00310
00311 _dwarf_decode_u_leb128(line_ptr, &leb128_length);
00312 line_ptr = line_ptr + leb128_length;
00313
00314 curr_chain =
00315 (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
00316 if (curr_chain == NULL) {
00317 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00318 return (DW_DLV_ERROR);
00319 }
00320
00321 curr_chain->ch_item = full_name;
00322
00323 if (head_chain == NULL)
00324 head_chain = prev_chain = curr_chain;
00325 else {
00326 prev_chain->ch_next = curr_chain;
00327 prev_chain = curr_chain;
00328 }
00329
00330 file_count++;
00331 }
00332 line_ptr++;
00333
00334 if (line_ptr != check_line_ptr + prologue_length) {
00335 _dwarf_error(dbg, error, DW_DLE_LINE_PROLOG_LENGTH_BAD);
00336 return (DW_DLV_ERROR);
00337 }
00338
00339 if (file_count == 0) {
00340 *srcfiles = NULL;
00341 *srcfilecount = 0;
00342 return (DW_DLV_NO_ENTRY);
00343 }
00344
00345 ret_files = (char **)
00346 _dwarf_get_alloc(dbg, DW_DLA_LIST, file_count);
00347 if (ret_files == NULL) {
00348 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00349 return (DW_DLV_ERROR);
00350 }
00351
00352 curr_chain = head_chain;
00353 for (i = 0; i < file_count; i++) {
00354 *(ret_files + i) = curr_chain->ch_item;
00355 prev_chain = curr_chain;
00356 curr_chain = curr_chain->ch_next;
00357 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
00358 }
00359
00360 *srcfiles = ret_files;
00361 *srcfilecount = file_count;
00362 return (DW_DLV_OK);
00363 }
00364
00365
00366
00367
00368
00369 int
00370 _dwarf_internal_srclines(Dwarf_Die die,
00371 Dwarf_Line ** linebuf,
00372 Dwarf_Signed * count,
00373 Dwarf_Bool doaddrs,
00374 Dwarf_Bool dolines, Dwarf_Error * error)
00375 {
00376
00377
00378
00379 Dwarf_Small *line_ptr;
00380
00381
00382
00383
00384 Dwarf_Small *line_ptr_end;
00385
00386
00387
00388
00389
00390 Dwarf_Small *check_line_ptr;
00391
00392
00393
00394
00395 Dwarf_Attribute stmt_list_attr;
00396
00397
00398 Dwarf_Attribute comp_dir_attr;
00399
00400
00401 Dwarf_Small *comp_dir = NULL;
00402
00403
00404
00405
00406 Dwarf_Unsigned line_offset;
00407
00408
00409 Dwarf_Unsigned total_length;
00410 Dwarf_Half version;
00411 Dwarf_Unsigned prologue_length;
00412 Dwarf_Small minimum_instruction_length;
00413 Dwarf_Small default_is_stmt;
00414 Dwarf_Sbyte line_base;
00415 Dwarf_Small line_range;
00416 Dwarf_Small special_opcode_base;
00417
00418 Dwarf_Small *opcode_length;
00419 Dwarf_Small *include_directories;
00420 Dwarf_File_Entry file_entries;
00421
00422
00423 Dwarf_Addr address;
00424 Dwarf_Word file;
00425 Dwarf_Word line;
00426 Dwarf_Word column;
00427 Dwarf_Bool is_stmt;
00428 Dwarf_Bool basic_block;
00429 Dwarf_Bool end_sequence;
00430
00431
00432
00433
00434
00435 Dwarf_File_Entry cur_file_entry, prev_file_entry;
00436
00437 Dwarf_Sword i, file_entry_count, include_directories_count;
00438
00439
00440
00441 Dwarf_Small opcode;
00442
00443
00444
00445
00446
00447 Dwarf_Line_Context line_context;
00448
00449
00450
00451
00452 Dwarf_Line curr_line;
00453
00454
00455
00456
00457
00458 Dwarf_Word leb128_num;
00459 Dwarf_Word leb128_length;
00460 Dwarf_Sword advance_line;
00461
00462
00463
00464
00465 Dwarf_Half fixed_advance_pc;
00466
00467
00468
00469 Dwarf_Sword line_count = 0;
00470
00471
00472 Dwarf_Word instr_length;
00473 Dwarf_Small ext_opcode;
00474
00475
00476
00477
00478 Dwarf_Chain chain_line, head_chain = NULL, curr_chain;
00479
00480
00481
00482
00483 Dwarf_Line *block_line;
00484
00485
00486 Dwarf_Debug dbg;
00487 int resattr;
00488 int lres;
00489 int local_length_size = 0;
00490
00491 int local_extension_size = 0;
00492
00493 int res;
00494
00495
00496
00497 if (error != NULL)
00498 *error = NULL;
00499
00500 CHECK_DIE(die, DW_DLV_ERROR)
00501 dbg = die->di_cu_context->cc_dbg;
00502
00503 res =
00504 _dwarf_load_section(dbg,
00505 dbg->de_debug_line_index,
00506 &dbg->de_debug_line,
00507 error);
00508 if (res != DW_DLV_OK) {
00509 return res;
00510 }
00511
00512 resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
00513 if (resattr != DW_DLV_OK) {
00514 return resattr;
00515 }
00516
00517
00518
00519 lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
00520 if (lres != DW_DLV_OK) {
00521 return lres;
00522 }
00523
00524 if (line_offset >= dbg->de_debug_line_size) {
00525 _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
00526 return (DW_DLV_ERROR);
00527 }
00528 line_ptr = dbg->de_debug_line + line_offset;
00529 dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
00530
00531
00532
00533
00534 resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
00535 if (resattr == DW_DLV_ERROR) {
00536 return resattr;
00537 }
00538 if (resattr == DW_DLV_OK) {
00539 int cres;
00540 char *cdir;
00541
00542 cres = dwarf_formstring(comp_dir_attr, &cdir, error);
00543 if (cres == DW_DLV_ERROR) {
00544 return cres;
00545 } else if (cres == DW_DLV_OK) {
00546 comp_dir = (Dwarf_Small *) cdir;
00547 }
00548 }
00549 if (resattr == DW_DLV_OK) {
00550 dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
00551 }
00552
00553
00554
00555
00556
00557 READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
00558 line_ptr, local_length_size, local_extension_size);
00559
00560 line_ptr_end = line_ptr + total_length;
00561 if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) {
00562 _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD);
00563 return (DW_DLV_ERROR);
00564 }
00565
00566 READ_UNALIGNED(dbg, version, Dwarf_Half,
00567 line_ptr, sizeof(Dwarf_Half));
00568 line_ptr += sizeof(Dwarf_Half);
00569 if (version != CURRENT_VERSION_STAMP &&
00570 version != CURRENT_VERSION_STAMP3) {
00571 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
00572 return (DW_DLV_ERROR);
00573 }
00574
00575 READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
00576 line_ptr, local_length_size);
00577 line_ptr += local_length_size;
00578 check_line_ptr = line_ptr;
00579
00580 minimum_instruction_length = *(Dwarf_Small *) line_ptr;
00581 line_ptr = line_ptr + sizeof(Dwarf_Small);
00582
00583 default_is_stmt = *(Dwarf_Small *) line_ptr;
00584 line_ptr = line_ptr + sizeof(Dwarf_Small);
00585
00586 line_base = *(Dwarf_Sbyte *) line_ptr;
00587 line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
00588
00589 line_range = *(Dwarf_Small *) line_ptr;
00590 line_ptr = line_ptr + sizeof(Dwarf_Small);
00591
00592 special_opcode_base = *(Dwarf_Small *) line_ptr;
00593 line_ptr = line_ptr + sizeof(Dwarf_Small);
00594
00595 opcode_length = (Dwarf_Small *)
00596 alloca(sizeof(Dwarf_Small) * special_opcode_base);
00597 for (i = 1; i < special_opcode_base; i++) {
00598 opcode_length[i] = *(Dwarf_Small *) line_ptr;
00599 line_ptr = line_ptr + sizeof(Dwarf_Small);
00600 }
00601
00602 include_directories_count = 0;
00603 include_directories = line_ptr;
00604 while ((*(char *) line_ptr) != '\0') {
00605 line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
00606 include_directories_count++;
00607 }
00608 line_ptr++;
00609
00610 file_entry_count = 0;
00611 file_entries = prev_file_entry = NULL;
00612 while (*(char *) line_ptr != '\0') {
00613
00614 cur_file_entry = (Dwarf_File_Entry)
00615 _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
00616 if (cur_file_entry == NULL) {
00617 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00618 return (DW_DLV_ERROR);
00619 }
00620
00621 cur_file_entry->fi_file_name = (Dwarf_Small *) line_ptr;
00622 line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
00623
00624 cur_file_entry->fi_dir_index =
00625 (Dwarf_Sword) _dwarf_decode_u_leb128(line_ptr,
00626 &leb128_length);
00627 line_ptr = line_ptr + leb128_length;
00628
00629 cur_file_entry->fi_time_last_mod =
00630 _dwarf_decode_u_leb128(line_ptr, &leb128_length);
00631 line_ptr = line_ptr + leb128_length;
00632
00633 cur_file_entry->fi_file_length =
00634 _dwarf_decode_u_leb128(line_ptr, &leb128_length);
00635 line_ptr = line_ptr + leb128_length;
00636
00637 if (file_entries == NULL)
00638 file_entries = cur_file_entry;
00639 else
00640 prev_file_entry->fi_next = cur_file_entry;
00641 prev_file_entry = cur_file_entry;
00642
00643 file_entry_count++;
00644 }
00645 line_ptr++;
00646
00647 if (line_ptr != check_line_ptr + prologue_length) {
00648 _dwarf_error(dbg, error, DW_DLE_LINE_PROLOG_LENGTH_BAD);
00649 return (DW_DLV_ERROR);
00650 }
00651
00652
00653 line_context = (Dwarf_Line_Context)
00654 _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
00655 if (line_context == NULL) {
00656 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00657 return (DW_DLV_ERROR);
00658 }
00659
00660
00661 address = 0;
00662 file = 1;
00663 line = 1;
00664 column = 0;
00665 is_stmt = default_is_stmt;
00666 basic_block = false;
00667 end_sequence = false;
00668
00669
00670 while (line_ptr < line_ptr_end) {
00671 int type;
00672
00673 opcode = *(Dwarf_Small *) line_ptr;
00674 line_ptr++;
00675
00676
00677
00678 WHAT_IS_OPCODE(type, opcode, special_opcode_base,
00679 opcode_length, line_ptr);
00680
00681
00682
00683 if (type == LOP_DISCARD) {
00684
00685 } else if (type == LOP_SPECIAL) {
00686
00687
00688
00689
00690
00691
00692 opcode = opcode - special_opcode_base;
00693 address = address + minimum_instruction_length *
00694 (opcode / line_range);
00695 line = line + line_base + opcode % line_range;
00696
00697 if (dolines) {
00698 curr_line =
00699 (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
00700 if (curr_line == NULL) {
00701 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00702 return (DW_DLV_ERROR);
00703 }
00704
00705 curr_line->li_address = address;
00706 curr_line->li_addr_line.li_l_data.li_file =
00707 (Dwarf_Sword) file;
00708 curr_line->li_addr_line.li_l_data.li_line =
00709 (Dwarf_Sword) line;
00710 curr_line->li_addr_line.li_l_data.li_column =
00711 (Dwarf_Half) column;
00712 curr_line->li_addr_line.li_l_data.li_is_stmt = is_stmt;
00713 curr_line->li_addr_line.li_l_data.li_basic_block =
00714 basic_block;
00715 curr_line->li_addr_line.li_l_data.li_end_sequence =
00716 end_sequence;
00717 curr_line->li_context = line_context;
00718 line_count++;
00719
00720 chain_line = (Dwarf_Chain)
00721 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
00722 if (chain_line == NULL) {
00723 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00724 return (DW_DLV_ERROR);
00725 }
00726 chain_line->ch_item = curr_line;
00727
00728 if (head_chain == NULL)
00729 head_chain = curr_chain = chain_line;
00730 else {
00731 curr_chain->ch_next = chain_line;
00732 curr_chain = chain_line;
00733 }
00734 }
00735
00736 basic_block = false;
00737 } else if (type == LOP_STANDARD) {
00738 switch (opcode) {
00739
00740 case DW_LNS_copy:{
00741 if (opcode_length[DW_LNS_copy] != 0) {
00742 _dwarf_error(dbg, error,
00743 DW_DLE_LINE_NUM_OPERANDS_BAD);
00744 return (DW_DLV_ERROR);
00745 }
00746
00747 if (dolines) {
00748
00749 curr_line =
00750 (Dwarf_Line) _dwarf_get_alloc(dbg,
00751 DW_DLA_LINE,
00752 1);
00753 if (curr_line == NULL) {
00754 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00755 return (DW_DLV_ERROR);
00756 }
00757
00758 curr_line->li_address = address;
00759 curr_line->li_addr_line.li_l_data.li_file =
00760 (Dwarf_Sword) file;
00761 curr_line->li_addr_line.li_l_data.li_line =
00762 (Dwarf_Sword) line;
00763 curr_line->li_addr_line.li_l_data.li_column =
00764 (Dwarf_Half) column;
00765 curr_line->li_addr_line.li_l_data.li_is_stmt =
00766 is_stmt;
00767 curr_line->li_addr_line.li_l_data.
00768 li_basic_block = basic_block;
00769 curr_line->li_addr_line.li_l_data.
00770 li_end_sequence = end_sequence;
00771 curr_line->li_context = line_context;
00772 line_count++;
00773
00774 chain_line = (Dwarf_Chain)
00775 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
00776 if (chain_line == NULL) {
00777 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00778 return (DW_DLV_ERROR);
00779 }
00780 chain_line->ch_item = curr_line;
00781 if (head_chain == NULL)
00782 head_chain = curr_chain = chain_line;
00783 else {
00784 curr_chain->ch_next = chain_line;
00785 curr_chain = chain_line;
00786 }
00787 }
00788
00789 basic_block = false;
00790 break;
00791 }
00792
00793 case DW_LNS_advance_pc:{
00794 Dwarf_Unsigned utmp2;
00795
00796 if (opcode_length[DW_LNS_advance_pc] != 1) {
00797 _dwarf_error(dbg, error,
00798 DW_DLE_LINE_NUM_OPERANDS_BAD);
00799 return (DW_DLV_ERROR);
00800 }
00801
00802 DECODE_LEB128_UWORD(line_ptr, utmp2)
00803 leb128_num = (Dwarf_Word) utmp2;
00804 address =
00805 address +
00806 minimum_instruction_length * leb128_num;
00807 break;
00808 }
00809
00810 case DW_LNS_advance_line:{
00811 Dwarf_Signed stmp;
00812
00813 if (opcode_length[DW_LNS_advance_line] != 1) {
00814 _dwarf_error(dbg, error,
00815 DW_DLE_LINE_NUM_OPERANDS_BAD);
00816 return (DW_DLV_ERROR);
00817 }
00818
00819 DECODE_LEB128_SWORD(line_ptr, stmp)
00820 advance_line = (Dwarf_Sword) stmp;
00821 line = line + advance_line;
00822 break;
00823 }
00824
00825 case DW_LNS_set_file:{
00826 Dwarf_Unsigned utmp2;
00827
00828 if (opcode_length[DW_LNS_set_file] != 1) {
00829 _dwarf_error(dbg, error,
00830 DW_DLE_LINE_NUM_OPERANDS_BAD);
00831 return (DW_DLV_ERROR);
00832 }
00833
00834 DECODE_LEB128_UWORD(line_ptr, utmp2)
00835 file = (Dwarf_Word) utmp2;
00836 break;
00837 }
00838
00839 case DW_LNS_set_column:{
00840 Dwarf_Unsigned utmp2;
00841
00842 if (opcode_length[DW_LNS_set_column] != 1) {
00843 _dwarf_error(dbg, error,
00844 DW_DLE_LINE_NUM_OPERANDS_BAD);
00845 return (DW_DLV_ERROR);
00846 }
00847
00848 DECODE_LEB128_UWORD(line_ptr, utmp2)
00849 column = (Dwarf_Word) utmp2;
00850 break;
00851 }
00852
00853 case DW_LNS_negate_stmt:{
00854 if (opcode_length[DW_LNS_negate_stmt] != 0) {
00855 _dwarf_error(dbg, error,
00856 DW_DLE_LINE_NUM_OPERANDS_BAD);
00857 return (DW_DLV_ERROR);
00858 }
00859
00860 is_stmt = !is_stmt;
00861 break;
00862 }
00863
00864 case DW_LNS_set_basic_block:{
00865 if (opcode_length[DW_LNS_set_basic_block] != 0) {
00866 _dwarf_error(dbg, error,
00867 DW_DLE_LINE_NUM_OPERANDS_BAD);
00868 return (DW_DLV_ERROR);
00869 }
00870
00871 basic_block = true;
00872 break;
00873 }
00874
00875 case DW_LNS_const_add_pc:{
00876 opcode = MAX_LINE_OP_CODE - special_opcode_base;
00877 address = address + minimum_instruction_length *
00878 (opcode / line_range);
00879
00880 break;
00881 }
00882
00883 case DW_LNS_fixed_advance_pc:{
00884 if (opcode_length[DW_LNS_fixed_advance_pc] != 1) {
00885 _dwarf_error(dbg, error,
00886 DW_DLE_LINE_NUM_OPERANDS_BAD);
00887 return (DW_DLV_ERROR);
00888 }
00889
00890 READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
00891 line_ptr, sizeof(Dwarf_Half));
00892 line_ptr += sizeof(Dwarf_Half);
00893 address = address + fixed_advance_pc;
00894 break;
00895 }
00896 }
00897
00898 } else if (type == LOP_EXTENDED) {
00899 Dwarf_Unsigned utmp3;
00900
00901 DECODE_LEB128_UWORD(line_ptr, utmp3)
00902 instr_length = (Dwarf_Word) utmp3;
00903
00904
00905
00906
00907 ext_opcode = *(Dwarf_Small *) line_ptr;
00908 line_ptr++;
00909 switch (ext_opcode) {
00910
00911 case DW_LNE_end_sequence:{
00912 end_sequence = true;
00913
00914 if (dolines) {
00915 curr_line = (Dwarf_Line)
00916 _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
00917 if (curr_line == NULL) {
00918 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00919 return (DW_DLV_ERROR);
00920 }
00921
00922 curr_line->li_address = address;
00923 curr_line->li_addr_line.li_l_data.li_file =
00924 (Dwarf_Sword) file;
00925 curr_line->li_addr_line.li_l_data.li_line =
00926 (Dwarf_Sword) line;
00927 curr_line->li_addr_line.li_l_data.li_column =
00928 (Dwarf_Half) column;
00929 curr_line->li_addr_line.li_l_data.li_is_stmt =
00930 default_is_stmt;
00931 curr_line->li_addr_line.li_l_data.
00932 li_basic_block = basic_block;
00933 curr_line->li_addr_line.li_l_data.
00934 li_end_sequence = end_sequence;
00935 curr_line->li_context = line_context;
00936 line_count++;
00937
00938 chain_line = (Dwarf_Chain)
00939 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
00940 if (chain_line == NULL) {
00941 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
00942 return (DW_DLV_ERROR);
00943 }
00944 chain_line->ch_item = curr_line;
00945
00946 if (head_chain == NULL)
00947 head_chain = curr_chain = chain_line;
00948 else {
00949 curr_chain->ch_next = chain_line;
00950 curr_chain = chain_line;
00951 }
00952 }
00953
00954 address = 0;
00955 file = 1;
00956 line = 1;
00957 column = 0;
00958 is_stmt = default_is_stmt;
00959 basic_block = false;
00960 end_sequence = false;
00961
00962 break;
00963 }
00964
00965 case DW_LNE_set_address:{
00966 if (instr_length - 1 == dbg->de_pointer_size) {
00967 READ_UNALIGNED(dbg, address, Dwarf_Addr,
00968 line_ptr, dbg->de_pointer_size);
00969 if (doaddrs) {
00970 curr_line =
00971 (Dwarf_Line) _dwarf_get_alloc(dbg,
00972 DW_DLA_LINE,
00973 1);
00974 if (curr_line == NULL) {
00975 _dwarf_error(dbg, error,
00976 DW_DLE_ALLOC_FAIL);
00977 return (DW_DLV_ERROR);
00978 }
00979
00980 curr_line->li_address = address;
00981 curr_line->li_addr_line.li_offset =
00982 line_ptr - dbg->de_debug_line;
00983
00984 line_count++;
00985
00986 chain_line = (Dwarf_Chain)
00987 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
00988 if (chain_line == NULL) {
00989 _dwarf_error(dbg, error,
00990 DW_DLE_ALLOC_FAIL);
00991 return (DW_DLV_ERROR);
00992 }
00993 chain_line->ch_item = curr_line;
00994
00995 if (head_chain == NULL)
00996 head_chain = curr_chain = chain_line;
00997 else {
00998 curr_chain->ch_next = chain_line;
00999 curr_chain = chain_line;
01000 }
01001 }
01002
01003 line_ptr += dbg->de_pointer_size;
01004 } else {
01005 _dwarf_error(dbg, error,
01006 DW_DLE_LINE_SET_ADDR_ERROR);
01007 return (DW_DLV_ERROR);
01008 }
01009
01010 break;
01011 }
01012
01013 case DW_LNE_define_file:{
01014
01015 if (dolines) {
01016 cur_file_entry = (Dwarf_File_Entry)
01017 _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
01018 if (cur_file_entry == NULL) {
01019 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01020 return (DW_DLV_ERROR);
01021 }
01022
01023 cur_file_entry->fi_file_name =
01024 (Dwarf_Small *) line_ptr;
01025 line_ptr =
01026 line_ptr + strlen((char *) line_ptr) + 1;
01027
01028 cur_file_entry->fi_dir_index =
01029 (Dwarf_Sword)
01030 _dwarf_decode_u_leb128(line_ptr,
01031 &leb128_length);
01032 line_ptr = line_ptr + leb128_length;
01033
01034 cur_file_entry->fi_time_last_mod =
01035 _dwarf_decode_u_leb128(line_ptr,
01036 &leb128_length);
01037 line_ptr = line_ptr + leb128_length;
01038
01039 cur_file_entry->fi_file_length =
01040 _dwarf_decode_u_leb128(line_ptr,
01041 &leb128_length);
01042 line_ptr = line_ptr + leb128_length;
01043
01044 if (file_entries == NULL)
01045 file_entries = cur_file_entry;
01046 else
01047 prev_file_entry->fi_next = cur_file_entry;
01048 prev_file_entry = cur_file_entry;
01049
01050 file_entry_count++;
01051 }
01052 break;
01053 }
01054
01055 default:{
01056 _dwarf_error(dbg, error,
01057 DW_DLE_LINE_EXT_OPCODE_BAD);
01058 return (DW_DLV_ERROR);
01059 }
01060 }
01061
01062 }
01063 }
01064
01065 block_line = (Dwarf_Line *)
01066 _dwarf_get_alloc(dbg, DW_DLA_LIST, line_count);
01067 if (block_line == NULL) {
01068 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01069 return (DW_DLV_ERROR);
01070 }
01071
01072 curr_chain = head_chain;
01073 for (i = 0; i < line_count; i++) {
01074 *(block_line + i) = curr_chain->ch_item;
01075 head_chain = curr_chain;
01076 curr_chain = curr_chain->ch_next;
01077 dwarf_dealloc(dbg, head_chain, DW_DLA_CHAIN);
01078 }
01079
01080 line_context->lc_file_entries = file_entries;
01081 line_context->lc_file_entry_count = file_entry_count;
01082 line_context->lc_include_directories = include_directories;
01083 line_context->lc_include_directories_count =
01084 include_directories_count;
01085 line_context->lc_line_count = line_count;
01086 line_context->lc_compilation_directory = comp_dir;
01087 line_context->lc_version_number = version;
01088 line_context->lc_dbg = dbg;
01089 *count = line_count;
01090
01091 *linebuf = block_line;
01092 return (DW_DLV_OK);
01093 }
01094
01095 int
01096 dwarf_srclines(Dwarf_Die die,
01097 Dwarf_Line ** linebuf,
01098 Dwarf_Signed * linecount, Dwarf_Error * error)
01099 {
01100 Dwarf_Signed count;
01101 int res;
01102
01103 res = _dwarf_internal_srclines(die, linebuf,
01104 &count, false,
01105 true, error);
01106 if (res != DW_DLV_OK) {
01107 return res;
01108 }
01109 *linecount = count;
01110 return res;
01111 }
01112
01113
01114
01115
01116
01117 int
01118 dwarf_linebeginstatement(Dwarf_Line line,
01119 Dwarf_Bool * return_bool, Dwarf_Error * error)
01120 {
01121 if (line == NULL || return_bool == 0) {
01122 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
01123 return (DW_DLV_ERROR);
01124 }
01125
01126 *return_bool = (line->li_addr_line.li_l_data.li_is_stmt);
01127 return DW_DLV_OK;
01128 }
01129
01130 int
01131 dwarf_lineendsequence(Dwarf_Line line,
01132 Dwarf_Bool * return_bool, Dwarf_Error * error)
01133 {
01134 if (line == NULL) {
01135 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
01136 return (DW_DLV_ERROR);
01137 }
01138
01139 *return_bool = (line->li_addr_line.li_l_data.li_end_sequence);
01140 return DW_DLV_OK;
01141 }
01142
01143
01144 int
01145 dwarf_lineno(Dwarf_Line line,
01146 Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
01147 {
01148 if (line == NULL || ret_lineno == 0) {
01149 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
01150 return (DW_DLV_ERROR);
01151 }
01152
01153 *ret_lineno = (line->li_addr_line.li_l_data.li_line);
01154 return DW_DLV_OK;
01155 }
01156
01157
01158 int
01159 dwarf_lineaddr(Dwarf_Line line,
01160 Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
01161 {
01162 if (line == NULL || ret_lineaddr == 0) {
01163 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
01164 return (DW_DLV_ERROR);
01165 }
01166
01167 *ret_lineaddr = (line->li_address);
01168 return DW_DLV_OK;
01169 }
01170
01171
01172 int
01173 dwarf_lineoff(Dwarf_Line line,
01174 Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
01175 {
01176 if (line == NULL || ret_lineoff == 0) {
01177 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
01178 return (DW_DLV_ERROR);
01179 }
01180
01181 *ret_lineoff =
01182 (line->li_addr_line.li_l_data.li_column ==
01183 0 ? -1 : line->li_addr_line.li_l_data.li_column);
01184 return DW_DLV_OK;
01185 }
01186
01187
01188 int
01189 dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error)
01190 {
01191 Dwarf_Signed i;
01192 Dwarf_File_Entry file_entry;
01193 Dwarf_Small *name_buffer;
01194 Dwarf_Small *include_directories;
01195 Dwarf_Debug dbg;
01196 unsigned int comp_dir_len;
01197
01198 if (line == NULL) {
01199 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
01200 return (DW_DLV_ERROR);
01201 }
01202
01203 if (line->li_context == NULL) {
01204 _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
01205 return (DW_DLV_ERROR);
01206 }
01207 dbg = line->li_context->lc_dbg;
01208
01209 if (line->li_addr_line.li_l_data.li_file >
01210 line->li_context->lc_file_entry_count) {
01211 _dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD);
01212 return (DW_DLV_ERROR);
01213 }
01214
01215 file_entry = line->li_context->lc_file_entries;
01216 for (i = line->li_addr_line.li_l_data.li_file - 1; i > 0; i--)
01217 file_entry = file_entry->fi_next;
01218
01219 if (file_entry->fi_file_name == NULL) {
01220 _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
01221 return (DW_DLV_ERROR);
01222 }
01223
01224 if (*(char *) file_entry->fi_file_name == '/') {
01225 *ret_linesrc = ((char *) file_entry->fi_file_name);
01226 return DW_DLV_OK;
01227 }
01228
01229 if (file_entry->fi_dir_index == 0) {
01230
01231
01232
01233 if (line->li_context->lc_compilation_directory == NULL) {
01234
01235
01236
01237
01238
01239
01240 comp_dir_len = 0;
01241 } else {
01242 comp_dir_len = strlen((char *)
01243 (line->li_context->
01244 lc_compilation_directory));
01245 }
01246
01247 name_buffer =
01248 _dwarf_get_alloc(line->li_context->lc_dbg, DW_DLA_STRING,
01249 comp_dir_len + 1 +
01250 strlen((char *) file_entry->fi_file_name) +
01251 1);
01252 if (name_buffer == NULL) {
01253 _dwarf_error(line->li_context->lc_dbg, error,
01254 DW_DLE_ALLOC_FAIL);
01255 return (DW_DLV_ERROR);
01256 }
01257
01258 if (comp_dir_len > 0) {
01259
01260
01261 strcpy((char *) name_buffer,
01262 (char *) (line->li_context->
01263 lc_compilation_directory));
01264 strcat((char *) name_buffer, "/");
01265 }
01266 strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
01267 *ret_linesrc = ((char *) name_buffer);
01268 return DW_DLV_OK;
01269 }
01270
01271 if (file_entry->fi_dir_index >
01272 line->li_context->lc_include_directories_count) {
01273 _dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
01274 return (DW_DLV_ERROR);
01275 }
01276
01277 include_directories = line->li_context->lc_include_directories;
01278 for (i = file_entry->fi_dir_index - 1; i > 0; i--)
01279 include_directories += strlen((char *) include_directories) + 1;
01280
01281 if (line->li_context->lc_compilation_directory) {
01282 comp_dir_len = strlen((char *)
01283 (line->li_context->
01284 lc_compilation_directory));
01285 } else {
01286
01287 comp_dir_len = 0;
01288 }
01289
01290 name_buffer = _dwarf_get_alloc(dbg, DW_DLA_STRING,
01291 (*include_directories == '/' ?
01292 0 : comp_dir_len + 1) +
01293 strlen((char *) include_directories)
01294 + 1 +
01295 strlen((char *) file_entry->
01296 fi_file_name) + 1);
01297 if (name_buffer == NULL) {
01298 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
01299 return (DW_DLV_ERROR);
01300 }
01301
01302 if (*include_directories != '/') {
01303 if (comp_dir_len > 0) {
01304 strcpy((char *) name_buffer,
01305 (char *) line->li_context->lc_compilation_directory);
01306
01307
01308 if (name_buffer[comp_dir_len - 1] != '/') {
01309
01310 name_buffer[comp_dir_len] = '/';
01311
01312
01313
01314
01315 name_buffer[comp_dir_len + 1] = 0;
01316 }
01317 }
01318 } else {
01319 strcpy((char *) name_buffer, "");
01320 }
01321 strcat((char *) name_buffer, (char *) include_directories);
01322 strcat((char *) name_buffer, "/");
01323 strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
01324 *ret_linesrc = ((char *) name_buffer);
01325 return DW_DLV_OK;
01326 }
01327
01328
01329 int
01330 dwarf_lineblock(Dwarf_Line line,
01331 Dwarf_Bool * return_bool, Dwarf_Error * error)
01332 {
01333 if (line == NULL) {
01334 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
01335 return (DW_DLV_ERROR);
01336 }
01337
01338 *return_bool = (line->li_addr_line.li_l_data.li_basic_block);
01339 return DW_DLV_OK;
01340 }
01341
01342
01343 #if 0
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354 int
01355 dwarf_pclines(Dwarf_Debug dbg,
01356 Dwarf_Addr pc,
01357 Dwarf_Line ** linebuf,
01358 Dwarf_Signed slide,
01359 Dwarf_Signed * linecount, Dwarf_Error * error)
01360 {
01361
01362
01363
01364 Dwarf_Line line;
01365 Dwarf_Line prev_line;
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 Dwarf_Bool check_line, first_line;
01379
01380
01381
01382
01383 Dwarf_Signed diff, i;
01384
01385
01386
01387
01388
01389
01390
01391
01392 Dwarf_Addr pc_less, pc_more;
01393
01394
01395
01396
01397
01398 Dwarf_Line *pc_line_buf, *pc_line;
01399
01400
01401
01402
01403
01404 Dwarf_Signed chain_count;
01405
01406 chain_head = NULL;
01407
01408 check_line = true;
01409 first_line = true;
01410 diff = MAX_LINE_DIFF;
01411
01412 for (i = 0; i < dbg->de_cu_line_count; i++) {
01413
01414 line = *(dbg->de_cu_line_ptr + i);
01415 prev_line = first_line ? NULL : *(dbg->de_cu_line_ptr + i - 1);
01416
01417 if (line->li_address == pc) {
01418 chain_ptr = (struct chain *)
01419 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
01420 if (chain_ptr == NULL) {
01421 _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
01422 return (DW_DLV_ERROR);
01423 }
01424
01425 chain_ptr->line = line;
01426 chain_ptr->diff = diff = 0;
01427 chain_ptr->next = chain_head;
01428 chain_head = chain_ptr;
01429 } else
01430
01431
01432
01433 if (check_line && line->li_address > pc &&
01434 (first_line ? 0 : prev_line->li_address) < pc)
01435
01436 if (slide == DW_DLS_BACKWARD && !first_line) {
01437 pc_less = prev_line->li_address;
01438 if (pc - pc_less <= diff) {
01439 chain_ptr = (struct chain *)
01440 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
01441 if (chain_ptr == NULL) {
01442 _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
01443 return (DW_DLV_ERROR);
01444 }
01445
01446 chain_ptr->line = prev_line;
01447 chain_ptr->diff = diff = pc - pc_less;
01448 chain_ptr->next = chain_head;
01449 chain_head = chain_ptr;
01450 }
01451 check_line = false;
01452 } else if (slide == DW_DLS_FORWARD) {
01453 pc_more = line->li_address;
01454 if (pc_more - pc <= diff) {
01455 chain_ptr = (struct chain *)
01456 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
01457 if (chain_ptr == NULL) {
01458 _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
01459 return (DW_DLV_ERROR);
01460 }
01461
01462 chain_ptr->line = line;
01463 chain_ptr->diff = diff = pc_more - pc;
01464 chain_ptr->next = chain_head;
01465 chain_head = chain_ptr;
01466 }
01467 check_line = false;
01468 } else
01469
01470
01471 if (line->li_address < pc)
01472 check_line = true;
01473
01474 first_line = false;
01475 }
01476
01477 chain_count = 0;
01478 for (chain_ptr = chain_head; chain_ptr != NULL;
01479 chain_ptr = chain_ptr->next)
01480 if (chain_ptr->diff == diff)
01481 chain_count++;
01482
01483 pc_line_buf = pc_line = (Dwarf_Line)
01484 _dwarf_get_alloc(dbg, DW_DLA_LIST, chain_count);
01485 for (chain_ptr = chain_head; chain_ptr != NULL;
01486 chain_ptr = chain_ptr->next)
01487 if (chain_ptr->diff == diff) {
01488 *pc_line = chain_ptr->line;
01489 pc_line++;
01490 }
01491
01492 for (chain_ptr = chain_head; chain_ptr != NULL;) {
01493 chain_head = chain_ptr;
01494 chain_ptr = chain_ptr->next;
01495 dwarf_dealloc(dbg, chain_head, DW_DLA_CHAIN);
01496 }
01497
01498 *linebuf = pc_line_buf;
01499 return (chain_count);
01500 }
01501 #endif
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511 int
01512 _dwarf_line_address_offsets(Dwarf_Debug dbg,
01513 Dwarf_Die die,
01514 Dwarf_Addr ** addrs,
01515 Dwarf_Off ** offs,
01516 Dwarf_Unsigned * returncount,
01517 Dwarf_Error * err)
01518 {
01519 Dwarf_Addr *laddrs;
01520 Dwarf_Off *loffsets;
01521 Dwarf_Signed lcount;
01522 Dwarf_Signed i;
01523 int res;
01524 Dwarf_Line *linebuf;
01525
01526 res = _dwarf_internal_srclines(die, &linebuf,
01527 &lcount, true,
01528 false, err);
01529 if (res != DW_DLV_OK) {
01530 return res;
01531 }
01532 laddrs = (Dwarf_Addr *)
01533 _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
01534 if (laddrs == NULL) {
01535 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
01536 return (DW_DLV_ERROR);
01537 }
01538 loffsets = (Dwarf_Off *)
01539 _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
01540 if (loffsets == NULL) {
01541 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
01542 return (DW_DLV_ERROR);
01543 }
01544
01545 for (i = 0; i < lcount; i++) {
01546 laddrs[i] = linebuf[i]->li_address;
01547 loffsets[i] = linebuf[i]->li_addr_line.li_offset;
01548 dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
01549 }
01550 dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
01551 *returncount = lcount;
01552 *offs = loffsets;
01553 *addrs = laddrs;
01554 return DW_DLV_OK;
01555 }