1 /* 2 3 Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify it 6 under the terms of version 2.1 of the GNU Lesser General Public License 7 as published by the Free Software Foundation. 8 9 This program is distributed in the hope that it would be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13 Further, this software is distributed without any warranty that it is 14 free of the rightful claim of any third person regarding infringement 15 or the like. Any license provided herein, whether implied or 16 otherwise, applies only to this software file. Patent licenses, if 17 any, provided herein do not apply to combinations of this program with 18 other software, or any other product whatsoever. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this program; if not, write the Free Software 22 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 23 USA. 24 25 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 26 Mountain View, CA 94043, or: 27 28 http://www.sgi.com 29 30 For further information regarding this notice, see: 31 32 http://oss.sgi.com/projects/GenInfo/NoticeExplan 33 34 */ 35 36 37 38 #include "config.h" 39 #include "dwarf_incl.h" 40 #include <stdio.h> 41 #include "dwarf_line.h" 42 #ifdef HAVE_ALLOCA_H 43 #include <alloca.h> 44 #endif 45 46 47 /* 48 Although source files is supposed to return the 49 source files in the compilation-unit, it does 50 not look for any in the statement program. In 51 other words, it ignores those defined using the 52 extended opcode DW_LNE_define_file. 53 */ 54 int 55 dwarf_srcfiles(Dwarf_Die die, 56 char ***srcfiles, 57 Dwarf_Signed * srcfilecount, Dwarf_Error * error) 58 { 59 /* 60 This pointer is used to scan the portion of the .debug_line 61 section for the current cu. */ 62 Dwarf_Small *line_ptr; 63 64 /* 65 This points to the last byte of the .debug_line portion for the 66 current cu. */ 67 Dwarf_Small *line_ptr_end; 68 69 /* 70 This points to the end of the statement program prologue for the 71 current cu, and serves to check that the prologue was correctly 72 decoded. */ 73 Dwarf_Small *check_line_ptr; 74 75 /* 76 Pointer to a DW_AT_stmt_list attribute in case it exists in the 77 die. */ 78 Dwarf_Attribute stmt_list_attr; 79 80 /* Pointer to DW_AT_comp_dir attribute in die. */ 81 Dwarf_Attribute comp_dir_attr; 82 83 /* Pointer to name of compilation directory. */ 84 Dwarf_Small *comp_dir = 0; 85 86 /* 87 Offset into .debug_line specified by a DW_AT_stmt_list 88 attribute. */ 89 Dwarf_Unsigned line_offset = 0; 90 91 /* Some of the fields of the statement program header. */ 92 Dwarf_Unsigned total_length = 0; 93 Dwarf_Half version = 0; 94 Dwarf_Unsigned prologue_length = 0; 95 Dwarf_Small special_opcode_base= 0; 96 97 /* File name excluding included directory. */ 98 char *file_name = 0; 99 100 /* Name of directory that the file is in. */ 101 char *dir_name = 0; 102 103 /* Name concatenating both directory and file name. */ 104 char *full_name = 0; 105 106 /* 107 This is the directory index for the file. The compilation 108 directory is 0, and the first included directory is 1. */ 109 Dwarf_Sword dir_index = 0; 110 111 Dwarf_Small *include_directories = 0; 112 113 Dwarf_Sword i = 0; 114 Dwarf_Sword file_count = 0; 115 Dwarf_Sword directories_count = 0; 116 117 /* 118 This is the current opcode read from the statement program. */ 119 120 Dwarf_Word leb128_length; 121 122 /* This is the length of an extended opcode instr. */ 123 124 /* 125 This points to a block of char *'s, each of which points to a 126 file name. */ 127 char **ret_files = 0; 128 129 /* The Dwarf_Debug this die belongs to. */ 130 Dwarf_Debug dbg; 131 132 /* Used to chain the file names. */ 133 Dwarf_Chain curr_chain, prev_chain, head_chain = NULL; 134 int resattr; 135 int lres; 136 137 int local_length_size = 0; 138 /*REFERENCED*/ /* Not used in this instance of the macro */ 139 int local_extension_size = 0; 140 141 int res; 142 143 /* ***** BEGIN CODE ***** */ 144 145 /* Reset error. */ 146 if (error != NULL) 147 *error = NULL; 148 149 CHECK_DIE(die, DW_DLV_ERROR) 150 dbg = die->di_cu_context->cc_dbg; 151 152 resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); 153 if (resattr != DW_DLV_OK) { 154 return resattr; 155 } 156 157 if (dbg->de_debug_line_index == 0) { 158 _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL); 159 return (DW_DLV_ERROR); 160 } 161 162 res = 163 _dwarf_load_section(dbg, 164 dbg->de_debug_line_index, 165 &dbg->de_debug_line, 166 error); 167 if (res != DW_DLV_OK) { 168 return res; 169 } 170 171 lres = dwarf_formudata(stmt_list_attr, &line_offset, error); 172 if (lres != DW_DLV_OK) { 173 return lres; 174 } 175 if (line_offset >= dbg->de_debug_line_size) { 176 _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); 177 return (DW_DLV_ERROR); 178 } 179 line_ptr = dbg->de_debug_line + line_offset; 180 dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); 181 182 /* 183 If die has DW_AT_comp_dir attribute, get the string that names 184 the compilation directory. */ 185 resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); 186 if (resattr == DW_DLV_ERROR) { 187 return resattr; 188 } 189 if (resattr == DW_DLV_OK) { 190 int cres; 191 char *cdir; 192 193 cres = dwarf_formstring(comp_dir_attr, &cdir, error); 194 if (cres == DW_DLV_ERROR) { 195 return cres; 196 } else if (cres == DW_DLV_OK) { 197 comp_dir = (Dwarf_Small *) cdir; 198 } 199 } 200 if (resattr == DW_DLV_OK) { 201 dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); 202 } 203 204 /* 205 Following is a straightforward decoding of the statement 206 program prologue information. */ 207 /* READ_AREA_LENGTH updates line_ptr for consumed bytes */ 208 READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned, 209 line_ptr, local_length_size, local_extension_size); 210 211 212 line_ptr_end = line_ptr + total_length; 213 if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) { 214 _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD); 215 return (DW_DLV_ERROR); 216 } 217 218 READ_UNALIGNED(dbg, version, Dwarf_Half, 219 line_ptr, sizeof(Dwarf_Half)); 220 line_ptr += sizeof(Dwarf_Half); 221 if (version != CURRENT_VERSION_STAMP) { 222 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); 223 return (DW_DLV_ERROR); 224 } 225 226 READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned, 227 line_ptr, local_length_size); 228 line_ptr += local_length_size; 229 check_line_ptr = line_ptr; 230 231 /* Skip over minimum instruction length. */ 232 line_ptr = line_ptr + sizeof(Dwarf_Small); 233 234 /* Skip over default_is_stmt. */ 235 line_ptr = line_ptr + sizeof(Dwarf_Small); 236 237 /* Skip over line_base. */ 238 line_ptr = line_ptr + sizeof(Dwarf_Sbyte); 239 240 /* Skip over line_ptr. */ 241 line_ptr = line_ptr + sizeof(Dwarf_Small); 242 243 special_opcode_base = *(Dwarf_Small *) line_ptr; 244 line_ptr = line_ptr + sizeof(Dwarf_Small); 245 246 for (i = 1; i < special_opcode_base; i++) { 247 /* Skip over opcode lengths for standard opcodes. */ 248 line_ptr = line_ptr + sizeof(Dwarf_Small); 249 } 250 251 directories_count = 0; 252 include_directories = line_ptr; 253 while ((*(char *) line_ptr) != '\0') { 254 line_ptr = line_ptr + strlen((char *) line_ptr) + 1; 255 directories_count++; 256 } 257 line_ptr++; 258 259 file_count = 0; 260 while (*(char *) line_ptr != '\0') { 261 Dwarf_Unsigned utmp; 262 263 file_name = (char *) line_ptr; 264 line_ptr = line_ptr + strlen((char *) line_ptr) + 1; 265 266 DECODE_LEB128_UWORD(line_ptr, utmp) 267 dir_index = (Dwarf_Sword) utmp; 268 if (dir_index > directories_count) { 269 _dwarf_error(dbg, error, DW_DLE_DIR_INDEX_BAD); 270 return (DW_DLV_ERROR); 271 } 272 273 if (dir_index == 0) 274 dir_name = (char *) comp_dir; 275 else { 276 dir_name = (char *) include_directories; 277 for (i = 1; i < dir_index; i++) 278 /* FIX: this is probably very slow: redoing strlen! 279 davea 9/94 */ 280 dir_name = dir_name + strlen(dir_name) + 1; 281 } 282 283 /* dir_name can be NULL if there is no DW_AT_comp_dir */ 284 if ((*file_name) == '/' || dir_name == 0) 285 full_name = file_name; 286 else { 287 full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING, 288 strlen(dir_name) + 1 + 289 strlen(file_name) + 290 1); 291 if (full_name == NULL) { 292 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 293 return (DW_DLV_ERROR); 294 } 295 296 strcpy(full_name, dir_name); 297 strcat(full_name, "/"); 298 strcat(full_name, file_name); 299 } 300 301 /* Skip over time of last modification. */ 302 _dwarf_decode_u_leb128(line_ptr, &leb128_length); 303 line_ptr = line_ptr + leb128_length; 304 305 /* Skip over file length. */ 306 _dwarf_decode_u_leb128(line_ptr, &leb128_length); 307 line_ptr = line_ptr + leb128_length; 308 309 curr_chain = 310 (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 311 if (curr_chain == NULL) { 312 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 313 return (DW_DLV_ERROR); 314 } 315 316 curr_chain->ch_item = full_name; 317 318 if (head_chain == NULL) 319 head_chain = prev_chain = curr_chain; 320 else { 321 prev_chain->ch_next = curr_chain; 322 prev_chain = curr_chain; 323 } 324 325 file_count++; 326 } 327 line_ptr++; 328 329 if (line_ptr != check_line_ptr + prologue_length) { 330 _dwarf_error(dbg, error, DW_DLE_LINE_PROLOG_LENGTH_BAD); 331 return (DW_DLV_ERROR); 332 } 333 334 if (file_count == 0) { 335 *srcfiles = NULL; 336 *srcfilecount = 0; 337 return (DW_DLV_NO_ENTRY); 338 } 339 340 ret_files = (char **) 341 _dwarf_get_alloc(dbg, DW_DLA_LIST, file_count); 342 if (ret_files == NULL) { 343 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 344 return (DW_DLV_ERROR); 345 } 346 347 curr_chain = head_chain; 348 for (i = 0; i < file_count; i++) { 349 *(ret_files + i) = curr_chain->ch_item; 350 prev_chain = curr_chain; 351 curr_chain = curr_chain->ch_next; 352 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); 353 } 354 355 *srcfiles = ret_files; 356 *srcfilecount = file_count; 357 return (DW_DLV_OK); 358 } 359 360 361 /* 362 return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR 363 */ 364 int 365 _dwarf_internal_srclines(Dwarf_Die die, 366 Dwarf_Line ** linebuf, 367 Dwarf_Signed * count, 368 Dwarf_Bool doaddrs, 369 Dwarf_Bool dolines, Dwarf_Error * error) 370 { 371 /* 372 This pointer is used to scan the portion of the .debug_line 373 section for the current cu. */ 374 Dwarf_Small *line_ptr; 375 376 /* 377 This points to the last byte of the .debug_line portion for the 378 current cu. */ 379 Dwarf_Small *line_ptr_end; 380 381 /* 382 This points to the end of the statement program prologue for the 383 current cu, and serves to check that the prologue was correctly 384 decoded. */ 385 Dwarf_Small *check_line_ptr; 386 387 /* 388 Pointer to a DW_AT_stmt_list attribute in case it exists in the 389 die. */ 390 Dwarf_Attribute stmt_list_attr; 391 392 /* Pointer to DW_AT_comp_dir attribute in die. */ 393 Dwarf_Attribute comp_dir_attr; 394 395 /* Pointer to name of compilation directory. */ 396 Dwarf_Small *comp_dir = NULL; 397 398 /* 399 Offset into .debug_line specified by a DW_AT_stmt_list 400 attribute. */ 401 Dwarf_Unsigned line_offset; 402 403 /* These are the fields of the statement program header. */ 404 Dwarf_Unsigned total_length; 405 Dwarf_Half version; 406 Dwarf_Unsigned prologue_length; 407 Dwarf_Small minimum_instruction_length; 408 Dwarf_Small default_is_stmt; 409 Dwarf_Sbyte line_base; 410 Dwarf_Small line_range; 411 Dwarf_Small special_opcode_base; 412 413 Dwarf_Small *opcode_length; 414 Dwarf_Small *include_directories; 415 Dwarf_File_Entry file_entries; 416 417 /* These are the state machine state variables. */ 418 Dwarf_Addr address; 419 Dwarf_Word file; 420 Dwarf_Word line; 421 Dwarf_Word column; 422 Dwarf_Bool is_stmt; 423 Dwarf_Bool basic_block; 424 Dwarf_Bool end_sequence; 425 426 /* 427 These pointers are used to build the list of files names by 428 this cu. cur_file_entry points to the file name being added, 429 and prev_file_entry to the previous one. */ 430 Dwarf_File_Entry cur_file_entry, prev_file_entry; 431 432 Dwarf_Sword i, file_entry_count, include_directories_count; 433 434 /* 435 This is the current opcode read from the statement program. */ 436 Dwarf_Small opcode; 437 438 /* 439 Pointer to a Dwarf_Line_Context_s structure that contains the 440 context such as file names and include directories for the set 441 of lines being generated. */ 442 Dwarf_Line_Context line_context; 443 444 /* 445 This is a pointer to the current line being added to the line 446 matrix. */ 447 Dwarf_Line curr_line; 448 449 /* 450 These variables are used to decode leb128 numbers. Leb128_num 451 holds the decoded number, and leb128_length is its length in 452 bytes. */ 453 Dwarf_Word leb128_num; 454 Dwarf_Word leb128_length; 455 Dwarf_Sword advance_line; 456 457 /* 458 This is the operand of the latest fixed_advance_pc extended 459 opcode. */ 460 Dwarf_Half fixed_advance_pc; 461 462 /* 463 Counts the number of lines in the line matrix. */ 464 Dwarf_Sword line_count = 0; 465 466 /* This is the length of an extended opcode instr. */ 467 Dwarf_Word instr_length; 468 Dwarf_Small ext_opcode; 469 470 /* 471 Used to chain together pointers to line table entries that are 472 later used to create a block of Dwarf_Line entries. */ 473 Dwarf_Chain chain_line, head_chain = NULL, curr_chain; 474 475 /* 476 This points to a block of Dwarf_Lines, a pointer to which is 477 returned in linebuf. */ 478 Dwarf_Line *block_line; 479 480 /* The Dwarf_Debug this die belongs to. */ 481 Dwarf_Debug dbg; 482 int resattr; 483 int lres; 484 int local_length_size = 0; 485 /*REFERENCED*/ /* Not used in this instance of the macro */ 486 int local_extension_size = 0; 487 488 int res; 489 490 /* ***** BEGIN CODE ***** */ 491 492 if (error != NULL) 493 *error = NULL; 494 495 CHECK_DIE(die, DW_DLV_ERROR) 496 dbg = die->di_cu_context->cc_dbg; 497 498 res = 499 _dwarf_load_section(dbg, 500 dbg->de_debug_line_index, 501 &dbg->de_debug_line, 502 error); 503 if (res != DW_DLV_OK) { 504 return res; 505 } 506 507 resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); 508 if (resattr != DW_DLV_OK) { 509 return resattr; 510 } 511 512 513 514 lres = dwarf_formudata(stmt_list_attr, &line_offset, error); 515 if (lres != DW_DLV_OK) { 516 return lres; 517 } 518 519 if (line_offset >= dbg->de_debug_line_size) { 520 _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); 521 return (DW_DLV_ERROR); 522 } 523 line_ptr = dbg->de_debug_line + line_offset; 524 dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); 525 526 /* 527 If die has DW_AT_comp_dir attribute, get the string that names 528 the compilation directory. */ 529 resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); 530 if (resattr == DW_DLV_ERROR) { 531 return resattr; 532 } 533 if (resattr == DW_DLV_OK) { 534 int cres; 535 char *cdir; 536 537 cres = dwarf_formstring(comp_dir_attr, &cdir, error); 538 if (cres == DW_DLV_ERROR) { 539 return cres; 540 } else if (cres == DW_DLV_OK) { 541 comp_dir = (Dwarf_Small *) cdir; 542 } 543 } 544 if (resattr == DW_DLV_OK) { 545 dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); 546 } 547 548 /* 549 Following is a straightforward decoding of the statement 550 program prologue information. */ 551 /* READ_AREA_LENGTH updates line_ptr for consumed bytes */ 552 READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned, 553 line_ptr, local_length_size, local_extension_size); 554 555 line_ptr_end = line_ptr + total_length; 556 if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) { 557 _dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD); 558 return (DW_DLV_ERROR); 559 } 560 561 READ_UNALIGNED(dbg, version, Dwarf_Half, 562 line_ptr, sizeof(Dwarf_Half)); 563 line_ptr += sizeof(Dwarf_Half); 564 if (version != CURRENT_VERSION_STAMP) { 565 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); 566 return (DW_DLV_ERROR); 567 } 568 569 READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned, 570 line_ptr, local_length_size); 571 line_ptr += local_length_size; 572 check_line_ptr = line_ptr; 573 574 minimum_instruction_length = *(Dwarf_Small *) line_ptr; 575 line_ptr = line_ptr + sizeof(Dwarf_Small); 576 577 default_is_stmt = *(Dwarf_Small *) line_ptr; 578 line_ptr = line_ptr + sizeof(Dwarf_Small); 579 580 line_base = *(Dwarf_Sbyte *) line_ptr; 581 line_ptr = line_ptr + sizeof(Dwarf_Sbyte); 582 583 line_range = *(Dwarf_Small *) line_ptr; 584 line_ptr = line_ptr + sizeof(Dwarf_Small); 585 586 special_opcode_base = *(Dwarf_Small *) line_ptr; 587 line_ptr = line_ptr + sizeof(Dwarf_Small); 588 589 opcode_length = (Dwarf_Small *) 590 alloca(sizeof(Dwarf_Small) * special_opcode_base); 591 for (i = 1; i < special_opcode_base; i++) { 592 opcode_length[i] = *(Dwarf_Small *) line_ptr; 593 line_ptr = line_ptr + sizeof(Dwarf_Small); 594 } 595 596 include_directories_count = 0; 597 include_directories = line_ptr; 598 while ((*(char *) line_ptr) != '\0') { 599 line_ptr = line_ptr + strlen((char *) line_ptr) + 1; 600 include_directories_count++; 601 } 602 line_ptr++; 603 604 file_entry_count = 0; 605 file_entries = prev_file_entry = NULL; 606 while (*(char *) line_ptr != '\0') { 607 608 cur_file_entry = (Dwarf_File_Entry) 609 _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1); 610 if (cur_file_entry == NULL) { 611 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 612 return (DW_DLV_ERROR); 613 } 614 615 cur_file_entry->fi_file_name = (Dwarf_Small *) line_ptr; 616 line_ptr = line_ptr + strlen((char *) line_ptr) + 1; 617 618 cur_file_entry->fi_dir_index = 619 (Dwarf_Sword) _dwarf_decode_u_leb128(line_ptr, 620 &leb128_length); 621 line_ptr = line_ptr + leb128_length; 622 623 cur_file_entry->fi_time_last_mod = 624 _dwarf_decode_u_leb128(line_ptr, &leb128_length); 625 line_ptr = line_ptr + leb128_length; 626 627 cur_file_entry->fi_file_length = 628 _dwarf_decode_u_leb128(line_ptr, &leb128_length); 629 line_ptr = line_ptr + leb128_length; 630 631 if (file_entries == NULL) 632 file_entries = cur_file_entry; 633 else 634 prev_file_entry->fi_next = cur_file_entry; 635 prev_file_entry = cur_file_entry; 636 637 file_entry_count++; 638 } 639 line_ptr++; 640 641 if (line_ptr != check_line_ptr + prologue_length) { 642 _dwarf_error(dbg, error, DW_DLE_LINE_PROLOG_LENGTH_BAD); 643 return (DW_DLV_ERROR); 644 } 645 646 /* Set up context structure for this set of lines. */ 647 line_context = (Dwarf_Line_Context) 648 _dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1); 649 if (line_context == NULL) { 650 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 651 return (DW_DLV_ERROR); 652 } 653 654 /* Initialize the state machine. */ 655 address = 0; 656 file = 1; 657 line = 1; 658 column = 0; 659 is_stmt = default_is_stmt; 660 basic_block = false; 661 end_sequence = false; 662 663 /* Start of statement program. */ 664 while (line_ptr < line_ptr_end) { 665 int type; 666 667 opcode = *(Dwarf_Small *) line_ptr; 668 line_ptr++; 669 670 671 /* 'type' is the output */ 672 WHAT_IS_OPCODE(type, opcode, special_opcode_base, 673 opcode_length, line_ptr); 674 675 676 677 if (type == LOP_DISCARD) { 678 /* do nothing, necessary ops done */ 679 } else if (type == LOP_SPECIAL) { 680 /* This op code is a special op in the object, no matter 681 that it might fall into the standard op range in this 682 compile Thatis, these are special opcodes between 683 special_opcode_base and MAX_LINE_OP_CODE. (including 684 special_opcode_base and MAX_LINE_OP_CODE) */ 685 686 opcode = opcode - special_opcode_base; 687 address = address + minimum_instruction_length * 688 (opcode / line_range); 689 line = line + line_base + opcode % line_range; 690 691 if (dolines) { 692 curr_line = 693 (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); 694 if (curr_line == NULL) { 695 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 696 return (DW_DLV_ERROR); 697 } 698 699 curr_line->li_address = address; 700 curr_line->li_addr_line.li_l_data.li_file = 701 (Dwarf_Sword) file; 702 curr_line->li_addr_line.li_l_data.li_line = 703 (Dwarf_Sword) line; 704 curr_line->li_addr_line.li_l_data.li_column = 705 (Dwarf_Half) column; 706 curr_line->li_addr_line.li_l_data.li_is_stmt = is_stmt; 707 curr_line->li_addr_line.li_l_data.li_basic_block = 708 basic_block; 709 curr_line->li_addr_line.li_l_data.li_end_sequence = 710 end_sequence; 711 curr_line->li_context = line_context; 712 line_count++; 713 714 chain_line = (Dwarf_Chain) 715 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 716 if (chain_line == NULL) { 717 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 718 return (DW_DLV_ERROR); 719 } 720 chain_line->ch_item = curr_line; 721 722 if (head_chain == NULL) 723 head_chain = curr_chain = chain_line; 724 else { 725 curr_chain->ch_next = chain_line; 726 curr_chain = chain_line; 727 } 728 } 729 730 basic_block = false; 731 } else if (type == LOP_STANDARD) { 732 switch (opcode) { 733 734 case DW_LNS_copy:{ 735 if (opcode_length[DW_LNS_copy] != 0) { 736 _dwarf_error(dbg, error, 737 DW_DLE_LINE_NUM_OPERANDS_BAD); 738 return (DW_DLV_ERROR); 739 } 740 741 if (dolines) { 742 743 curr_line = 744 (Dwarf_Line) _dwarf_get_alloc(dbg, 745 DW_DLA_LINE, 746 1); 747 if (curr_line == NULL) { 748 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 749 return (DW_DLV_ERROR); 750 } 751 752 curr_line->li_address = address; 753 curr_line->li_addr_line.li_l_data.li_file = 754 (Dwarf_Sword) file; 755 curr_line->li_addr_line.li_l_data.li_line = 756 (Dwarf_Sword) line; 757 curr_line->li_addr_line.li_l_data.li_column = 758 (Dwarf_Half) column; 759 curr_line->li_addr_line.li_l_data.li_is_stmt = 760 is_stmt; 761 curr_line->li_addr_line.li_l_data. 762 li_basic_block = basic_block; 763 curr_line->li_addr_line.li_l_data. 764 li_end_sequence = end_sequence; 765 curr_line->li_context = line_context; 766 line_count++; 767 768 chain_line = (Dwarf_Chain) 769 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 770 if (chain_line == NULL) { 771 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 772 return (DW_DLV_ERROR); 773 } 774 chain_line->ch_item = curr_line; 775 if (head_chain == NULL) 776 head_chain = curr_chain = chain_line; 777 else { 778 curr_chain->ch_next = chain_line; 779 curr_chain = chain_line; 780 } 781 } 782 783 basic_block = false; 784 break; 785 } 786 787 case DW_LNS_advance_pc:{ 788 Dwarf_Unsigned utmp2; 789 790 if (opcode_length[DW_LNS_advance_pc] != 1) { 791 _dwarf_error(dbg, error, 792 DW_DLE_LINE_NUM_OPERANDS_BAD); 793 return (DW_DLV_ERROR); 794 } 795 796 DECODE_LEB128_UWORD(line_ptr, utmp2) 797 leb128_num = (Dwarf_Word) utmp2; 798 address = 799 address + 800 minimum_instruction_length * leb128_num; 801 break; 802 } 803 804 case DW_LNS_advance_line:{ 805 Dwarf_Signed stmp; 806 807 if (opcode_length[DW_LNS_advance_line] != 1) { 808 _dwarf_error(dbg, error, 809 DW_DLE_LINE_NUM_OPERANDS_BAD); 810 return (DW_DLV_ERROR); 811 } 812 813 DECODE_LEB128_SWORD(line_ptr, stmp) 814 advance_line = (Dwarf_Sword) stmp; 815 line = line + advance_line; 816 break; 817 } 818 819 case DW_LNS_set_file:{ 820 Dwarf_Unsigned utmp2; 821 822 if (opcode_length[DW_LNS_set_file] != 1) { 823 _dwarf_error(dbg, error, 824 DW_DLE_LINE_NUM_OPERANDS_BAD); 825 return (DW_DLV_ERROR); 826 } 827 828 DECODE_LEB128_UWORD(line_ptr, utmp2) 829 file = (Dwarf_Word) utmp2; 830 break; 831 } 832 833 case DW_LNS_set_column:{ 834 Dwarf_Unsigned utmp2; 835 836 if (opcode_length[DW_LNS_set_column] != 1) { 837 _dwarf_error(dbg, error, 838 DW_DLE_LINE_NUM_OPERANDS_BAD); 839 return (DW_DLV_ERROR); 840 } 841 842 DECODE_LEB128_UWORD(line_ptr, utmp2) 843 column = (Dwarf_Word) utmp2; 844 break; 845 } 846 847 case DW_LNS_negate_stmt:{ 848 if (opcode_length[DW_LNS_negate_stmt] != 0) { 849 _dwarf_error(dbg, error, 850 DW_DLE_LINE_NUM_OPERANDS_BAD); 851 return (DW_DLV_ERROR); 852 } 853 854 is_stmt = !is_stmt; 855 break; 856 } 857 858 case DW_LNS_set_basic_block:{ 859 if (opcode_length[DW_LNS_set_basic_block] != 0) { 860 _dwarf_error(dbg, error, 861 DW_DLE_LINE_NUM_OPERANDS_BAD); 862 return (DW_DLV_ERROR); 863 } 864 865 basic_block = true; 866 break; 867 } 868 869 case DW_LNS_const_add_pc:{ 870 opcode = MAX_LINE_OP_CODE - special_opcode_base; 871 address = address + minimum_instruction_length * 872 (opcode / line_range); 873 874 break; 875 } 876 877 case DW_LNS_fixed_advance_pc:{ 878 if (opcode_length[DW_LNS_fixed_advance_pc] != 1) { 879 _dwarf_error(dbg, error, 880 DW_DLE_LINE_NUM_OPERANDS_BAD); 881 return (DW_DLV_ERROR); 882 } 883 884 READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half, 885 line_ptr, sizeof(Dwarf_Half)); 886 line_ptr += sizeof(Dwarf_Half); 887 address = address + fixed_advance_pc; 888 break; 889 } 890 } 891 892 } else if (type == LOP_EXTENDED) { 893 Dwarf_Unsigned utmp3; 894 895 DECODE_LEB128_UWORD(line_ptr, utmp3) 896 instr_length = (Dwarf_Word) utmp3; 897 /* Dwarf_Small is a ubyte and the extended opcode 898 is a ubyte, though not stated as clearly in 899 the 2.0.0 spec as one might hope. 900 */ 901 ext_opcode = *(Dwarf_Small *) line_ptr; 902 line_ptr++; 903 switch (ext_opcode) { 904 905 case DW_LNE_end_sequence:{ 906 end_sequence = true; 907 908 if (dolines) { 909 curr_line = (Dwarf_Line) 910 _dwarf_get_alloc(dbg, DW_DLA_LINE, 1); 911 if (curr_line == NULL) { 912 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 913 return (DW_DLV_ERROR); 914 } 915 916 curr_line->li_address = address; 917 curr_line->li_addr_line.li_l_data.li_file = 918 (Dwarf_Sword) file; 919 curr_line->li_addr_line.li_l_data.li_line = 920 (Dwarf_Sword) line; 921 curr_line->li_addr_line.li_l_data.li_column = 922 (Dwarf_Half) column; 923 curr_line->li_addr_line.li_l_data.li_is_stmt = 924 default_is_stmt; 925 curr_line->li_addr_line.li_l_data. 926 li_basic_block = basic_block; 927 curr_line->li_addr_line.li_l_data. 928 li_end_sequence = end_sequence; 929 curr_line->li_context = line_context; 930 line_count++; 931 932 chain_line = (Dwarf_Chain) 933 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 934 if (chain_line == NULL) { 935 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 936 return (DW_DLV_ERROR); 937 } 938 chain_line->ch_item = curr_line; 939 940 if (head_chain == NULL) 941 head_chain = curr_chain = chain_line; 942 else { 943 curr_chain->ch_next = chain_line; 944 curr_chain = chain_line; 945 } 946 } 947 948 address = 0; 949 file = 1; 950 line = 1; 951 column = 0; 952 is_stmt = default_is_stmt; 953 basic_block = false; 954 end_sequence = false; 955 956 break; 957 } 958 959 case DW_LNE_set_address:{ 960 if (instr_length - 1 == dbg->de_pointer_size) { 961 READ_UNALIGNED(dbg, address, Dwarf_Addr, 962 line_ptr, dbg->de_pointer_size); 963 if (doaddrs) { 964 curr_line = 965 (Dwarf_Line) _dwarf_get_alloc(dbg, 966 DW_DLA_LINE, 967 1); 968 if (curr_line == NULL) { 969 _dwarf_error(dbg, error, 970 DW_DLE_ALLOC_FAIL); 971 return (DW_DLV_ERROR); 972 } 973 974 curr_line->li_address = address; 975 curr_line->li_addr_line.li_offset = 976 line_ptr - dbg->de_debug_line; 977 978 line_count++; 979 980 chain_line = (Dwarf_Chain) 981 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 982 if (chain_line == NULL) { 983 _dwarf_error(dbg, error, 984 DW_DLE_ALLOC_FAIL); 985 return (DW_DLV_ERROR); 986 } 987 chain_line->ch_item = curr_line; 988 989 if (head_chain == NULL) 990 head_chain = curr_chain = chain_line; 991 else { 992 curr_chain->ch_next = chain_line; 993 curr_chain = chain_line; 994 } 995 } 996 997 line_ptr += dbg->de_pointer_size; 998 } else { 999 _dwarf_error(dbg, error, 1000 DW_DLE_LINE_SET_ADDR_ERROR); 1001 return (DW_DLV_ERROR); 1002 } 1003 1004 break; 1005 } 1006 1007 case DW_LNE_define_file:{ 1008 1009 if (dolines) { 1010 cur_file_entry = (Dwarf_File_Entry) 1011 _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1); 1012 if (cur_file_entry == NULL) { 1013 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1014 return (DW_DLV_ERROR); 1015 } 1016 1017 cur_file_entry->fi_file_name = 1018 (Dwarf_Small *) line_ptr; 1019 line_ptr = 1020 line_ptr + strlen((char *) line_ptr) + 1; 1021 1022 cur_file_entry->fi_dir_index = 1023 (Dwarf_Sword) 1024 _dwarf_decode_u_leb128(line_ptr, 1025 &leb128_length); 1026 line_ptr = line_ptr + leb128_length; 1027 1028 cur_file_entry->fi_time_last_mod = 1029 _dwarf_decode_u_leb128(line_ptr, 1030 &leb128_length); 1031 line_ptr = line_ptr + leb128_length; 1032 1033 cur_file_entry->fi_file_length = 1034 _dwarf_decode_u_leb128(line_ptr, 1035 &leb128_length); 1036 line_ptr = line_ptr + leb128_length; 1037 1038 if (file_entries == NULL) 1039 file_entries = cur_file_entry; 1040 else 1041 prev_file_entry->fi_next = cur_file_entry; 1042 prev_file_entry = cur_file_entry; 1043 1044 file_entry_count++; 1045 } 1046 break; 1047 } 1048 1049 default:{ 1050 _dwarf_error(dbg, error, 1051 DW_DLE_LINE_EXT_OPCODE_BAD); 1052 return (DW_DLV_ERROR); 1053 } 1054 } 1055 1056 } 1057 } 1058 1059 block_line = (Dwarf_Line *) 1060 _dwarf_get_alloc(dbg, DW_DLA_LIST, line_count); 1061 if (block_line == NULL) { 1062 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1063 return (DW_DLV_ERROR); 1064 } 1065 1066 curr_chain = head_chain; 1067 for (i = 0; i < line_count; i++) { 1068 *(block_line + i) = curr_chain->ch_item; 1069 head_chain = curr_chain; 1070 curr_chain = curr_chain->ch_next; 1071 dwarf_dealloc(dbg, head_chain, DW_DLA_CHAIN); 1072 } 1073 1074 line_context->lc_file_entries = file_entries; 1075 line_context->lc_file_entry_count = file_entry_count; 1076 line_context->lc_include_directories = include_directories; 1077 line_context->lc_include_directories_count = 1078 include_directories_count; 1079 line_context->lc_line_count = line_count; 1080 line_context->lc_compilation_directory = comp_dir; 1081 line_context->lc_dbg = dbg; 1082 *count = line_count; 1083 1084 *linebuf = block_line; 1085 return (DW_DLV_OK); 1086 } 1087 1088 int 1089 dwarf_srclines(Dwarf_Die die, 1090 Dwarf_Line ** linebuf, 1091 Dwarf_Signed * linecount, Dwarf_Error * error) 1092 { 1093 Dwarf_Signed count; 1094 int res; 1095 1096 res = _dwarf_internal_srclines(die, linebuf, 1097 &count, /* addrlist= */ false, 1098 /* linelist= */ true, error); 1099 if (res != DW_DLV_OK) { 1100 return res; 1101 } 1102 *linecount = count; 1103 return res; 1104 } 1105 1106 1107 1108 1109 1110 int 1111 dwarf_linebeginstatement(Dwarf_Line line, 1112 Dwarf_Bool * return_bool, Dwarf_Error * error) 1113 { 1114 if (line == NULL || return_bool == 0) { 1115 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); 1116 return (DW_DLV_ERROR); 1117 } 1118 1119 *return_bool = (line->li_addr_line.li_l_data.li_is_stmt); 1120 return DW_DLV_OK; 1121 } 1122 1123 int 1124 dwarf_lineendsequence(Dwarf_Line line, 1125 Dwarf_Bool * return_bool, Dwarf_Error * error) 1126 { 1127 if (line == NULL) { 1128 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); 1129 return (DW_DLV_ERROR); 1130 } 1131 1132 *return_bool = (line->li_addr_line.li_l_data.li_end_sequence); 1133 return DW_DLV_OK; 1134 } 1135 1136 1137 int 1138 dwarf_lineno(Dwarf_Line line, 1139 Dwarf_Unsigned * ret_lineno, Dwarf_Error * error) 1140 { 1141 if (line == NULL || ret_lineno == 0) { 1142 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); 1143 return (DW_DLV_ERROR); 1144 } 1145 1146 *ret_lineno = (line->li_addr_line.li_l_data.li_line); 1147 return DW_DLV_OK; 1148 } 1149 1150 1151 int 1152 dwarf_lineaddr(Dwarf_Line line, 1153 Dwarf_Addr * ret_lineaddr, Dwarf_Error * error) 1154 { 1155 if (line == NULL || ret_lineaddr == 0) { 1156 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); 1157 return (DW_DLV_ERROR); 1158 } 1159 1160 *ret_lineaddr = (line->li_address); 1161 return DW_DLV_OK; 1162 } 1163 1164 1165 int 1166 dwarf_lineoff(Dwarf_Line line, 1167 Dwarf_Signed * ret_lineoff, Dwarf_Error * error) 1168 { 1169 if (line == NULL || ret_lineoff == 0) { 1170 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); 1171 return (DW_DLV_ERROR); 1172 } 1173 1174 *ret_lineoff = 1175 (line->li_addr_line.li_l_data.li_column == 1176 0 ? -1 : line->li_addr_line.li_l_data.li_column); 1177 return DW_DLV_OK; 1178 } 1179 1180 1181 int 1182 dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error) 1183 { 1184 Dwarf_Signed i; 1185 Dwarf_File_Entry file_entry; 1186 Dwarf_Small *name_buffer; 1187 Dwarf_Small *include_directories; 1188 Dwarf_Debug dbg; 1189 unsigned int comp_dir_len; 1190 1191 if (line == NULL) { 1192 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); 1193 return (DW_DLV_ERROR); 1194 } 1195 1196 if (line->li_context == NULL) { 1197 _dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL); 1198 return (DW_DLV_ERROR); 1199 } 1200 dbg = line->li_context->lc_dbg; 1201 1202 if (line->li_addr_line.li_l_data.li_file > 1203 line->li_context->lc_file_entry_count) { 1204 _dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD); 1205 return (DW_DLV_ERROR); 1206 } 1207 1208 file_entry = line->li_context->lc_file_entries; 1209 for (i = line->li_addr_line.li_l_data.li_file - 1; i > 0; i--) 1210 file_entry = file_entry->fi_next; 1211 1212 if (file_entry->fi_file_name == NULL) { 1213 _dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME); 1214 return (DW_DLV_ERROR); 1215 } 1216 1217 if (*(char *) file_entry->fi_file_name == '/') { 1218 *ret_linesrc = ((char *) file_entry->fi_file_name); 1219 return DW_DLV_OK; 1220 } 1221 1222 if (file_entry->fi_dir_index == 0) { 1223 1224 /* dir_index of 0 means that the compilation was in the 1225 'current directory of compilation' */ 1226 if (line->li_context->lc_compilation_directory == NULL) { 1227 /* we don't actually *have* a current directory of 1228 compilation: DW_AT_comp_dir was not present Rather than 1229 emitting DW_DLE_NO_COMP_DIR lets just make an empty name 1230 here. In other words, do the best we can with what we do 1231 have instead of reporting an error. _dwarf_error(dbg, 1232 error, DW_DLE_NO_COMP_DIR); return(DW_DLV_ERROR); */ 1233 comp_dir_len = 0; 1234 } else { 1235 comp_dir_len = strlen((char *) 1236 (line->li_context-> 1237 lc_compilation_directory)); 1238 } 1239 1240 name_buffer = 1241 _dwarf_get_alloc(line->li_context->lc_dbg, DW_DLA_STRING, 1242 comp_dir_len + 1 + 1243 strlen((char *) file_entry->fi_file_name) + 1244 1); 1245 if (name_buffer == NULL) { 1246 _dwarf_error(line->li_context->lc_dbg, error, 1247 DW_DLE_ALLOC_FAIL); 1248 return (DW_DLV_ERROR); 1249 } 1250 1251 if (comp_dir_len > 0) { 1252 /* if comp_dir_len is 0 we do not want to put a / in front 1253 of the fi_file_name as we just don't know anything. */ 1254 strcpy((char *) name_buffer, 1255 (char *) (line->li_context-> 1256 lc_compilation_directory)); 1257 strcat((char *) name_buffer, "/"); 1258 } 1259 strcat((char *) name_buffer, (char *) file_entry->fi_file_name); 1260 *ret_linesrc = ((char *) name_buffer); 1261 return DW_DLV_OK; 1262 } 1263 1264 if (file_entry->fi_dir_index > 1265 line->li_context->lc_include_directories_count) { 1266 _dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD); 1267 return (DW_DLV_ERROR); 1268 } 1269 1270 include_directories = line->li_context->lc_include_directories; 1271 for (i = file_entry->fi_dir_index - 1; i > 0; i--) 1272 include_directories += strlen((char *) include_directories) + 1; 1273 1274 if (line->li_context->lc_compilation_directory) { 1275 comp_dir_len = strlen((char *) 1276 (line->li_context-> 1277 lc_compilation_directory)); 1278 } else { 1279 /* No DW_AT_comp_dir present. Do the best we can without it. */ 1280 comp_dir_len = 0; 1281 } 1282 1283 name_buffer = _dwarf_get_alloc(dbg, DW_DLA_STRING, 1284 (*include_directories == '/' ? 1285 0 : comp_dir_len + 1) + 1286 strlen((char *) include_directories) 1287 + 1 + 1288 strlen((char *) file_entry-> 1289 fi_file_name) + 1); 1290 if (name_buffer == NULL) { 1291 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 1292 return (DW_DLV_ERROR); 1293 } 1294 1295 if (*include_directories != '/') { 1296 if (comp_dir_len > 0) { 1297 strcpy((char *) name_buffer, 1298 (char *) line->li_context->lc_compilation_directory); 1299 /* Who provides the / needed after the compilation 1300 directory? */ 1301 if (name_buffer[comp_dir_len - 1] != '/') { 1302 /* Here we provide the / separator */ 1303 name_buffer[comp_dir_len] = '/'; /* overwrite 1304 previous nul 1305 terminator 1306 with needed 1307 / */ 1308 name_buffer[comp_dir_len + 1] = 0; 1309 } 1310 } 1311 } else { 1312 strcpy((char *) name_buffer, ""); 1313 } 1314 strcat((char *) name_buffer, (char *) include_directories); 1315 strcat((char *) name_buffer, "/"); 1316 strcat((char *) name_buffer, (char *) file_entry->fi_file_name); 1317 *ret_linesrc = ((char *) name_buffer); 1318 return DW_DLV_OK; 1319 } 1320 1321 1322 int 1323 dwarf_lineblock(Dwarf_Line line, 1324 Dwarf_Bool * return_bool, Dwarf_Error * error) 1325 { 1326 if (line == NULL) { 1327 _dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL); 1328 return (DW_DLV_ERROR); 1329 } 1330 1331 *return_bool = (line->li_addr_line.li_l_data.li_basic_block); 1332 return DW_DLV_OK; 1333 } 1334 1335 1336 #if 0 /* Ignore this. This needs major 1337 re-work. */ 1338 /* 1339 This routine works by looking for exact matches between 1340 the current line address and pc, and crossovers from 1341 from less than pc value to greater than. At each line 1342 that satisfies the above, it records a pointer to the 1343 line, and the difference between the address and pc. 1344 It then scans these pointers and picks out those with 1345 the smallest difference between pc and address. 1346 */ 1347 int 1348 dwarf_pclines(Dwarf_Debug dbg, 1349 Dwarf_Addr pc, 1350 Dwarf_Line ** linebuf, 1351 Dwarf_Signed slide, 1352 Dwarf_Signed * linecount, Dwarf_Error * error) 1353 { 1354 /* 1355 Scans the line matrix for the current cu to which a pointer 1356 exists in dbg. */ 1357 Dwarf_Line line; 1358 Dwarf_Line prev_line; 1359 1360 /* 1361 These flags are for efficiency reasons. Check_line is true 1362 initially, but set false when the address of the current line 1363 is greater than pc. It is set true only when the address of the 1364 current line falls below pc. This assumes that addresses 1365 within the same segment increase, and we are only interested in 1366 the switch from a less than pc address to a greater than. 1367 First_line is set true initially, but set false after the first 1368 line is scanned. This is to prevent looking at the address of 1369 previous line when slide is DW_DLS_BACKWARD, and the first line 1370 is being scanned. */ 1371 Dwarf_Bool check_line, first_line; 1372 1373 /* 1374 Diff tracks the smallest difference a line address and the 1375 input pc value. */ 1376 Dwarf_Signed diff, i; 1377 1378 /* 1379 For the slide = DW_DLS_BACKWARD case, pc_less is the value of 1380 the address of the line immediately preceding the first line 1381 that has value greater than pc. For the slide = DW_DLS_FORWARD 1382 case, pc_more is the values of address for the first line that 1383 is greater than pc. Diff is the difference between either of 1384 the these values and pc. */ 1385 Dwarf_Addr pc_less, pc_more; 1386 1387 /* 1388 Pc_line_buf points to a chain of pointers to lines of which 1389 those with a diff equal to the smallest difference will be 1390 returned. */ 1391 Dwarf_Line *pc_line_buf, *pc_line; 1392 1393 /* 1394 Chain_count counts the number of lines in the above chain for 1395 which the diff is equal to the smallest difference This is the 1396 number returned by this routine. */ 1397 Dwarf_Signed chain_count; 1398 1399 chain_head = NULL; 1400 1401 check_line = true; 1402 first_line = true; 1403 diff = MAX_LINE_DIFF; 1404 1405 for (i = 0; i < dbg->de_cu_line_count; i++) { 1406 1407 line = *(dbg->de_cu_line_ptr + i); 1408 prev_line = first_line ? NULL : *(dbg->de_cu_line_ptr + i - 1); 1409 1410 if (line->li_address == pc) { 1411 chain_ptr = (struct chain *) 1412 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 1413 if (chain_ptr == NULL) { 1414 _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); 1415 return (DW_DLV_ERROR); 1416 } 1417 1418 chain_ptr->line = line; 1419 chain_ptr->diff = diff = 0; 1420 chain_ptr->next = chain_head; 1421 chain_head = chain_ptr; 1422 } else 1423 /* 1424 Look for crossover from less than pc address to greater 1425 than. */ 1426 if (check_line && line->li_address > pc && 1427 (first_line ? 0 : prev_line->li_address) < pc) 1428 1429 if (slide == DW_DLS_BACKWARD && !first_line) { 1430 pc_less = prev_line->li_address; 1431 if (pc - pc_less <= diff) { 1432 chain_ptr = (struct chain *) 1433 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 1434 if (chain_ptr == NULL) { 1435 _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); 1436 return (DW_DLV_ERROR); 1437 } 1438 1439 chain_ptr->line = prev_line; 1440 chain_ptr->diff = diff = pc - pc_less; 1441 chain_ptr->next = chain_head; 1442 chain_head = chain_ptr; 1443 } 1444 check_line = false; 1445 } else if (slide == DW_DLS_FORWARD) { 1446 pc_more = line->li_address; 1447 if (pc_more - pc <= diff) { 1448 chain_ptr = (struct chain *) 1449 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 1450 if (chain_ptr == NULL) { 1451 _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); 1452 return (DW_DLV_ERROR); 1453 } 1454 1455 chain_ptr->line = line; 1456 chain_ptr->diff = diff = pc_more - pc; 1457 chain_ptr->next = chain_head; 1458 chain_head = chain_ptr; 1459 } 1460 check_line = false; 1461 } else 1462 /* Check addresses only when they go */ 1463 /* below pc. */ 1464 if (line->li_address < pc) 1465 check_line = true; 1466 1467 first_line = false; 1468 } 1469 1470 chain_count = 0; 1471 for (chain_ptr = chain_head; chain_ptr != NULL; 1472 chain_ptr = chain_ptr->next) 1473 if (chain_ptr->diff == diff) 1474 chain_count++; 1475 1476 pc_line_buf = pc_line = (Dwarf_Line) 1477 _dwarf_get_alloc(dbg, DW_DLA_LIST, chain_count); 1478 for (chain_ptr = chain_head; chain_ptr != NULL; 1479 chain_ptr = chain_ptr->next) 1480 if (chain_ptr->diff == diff) { 1481 *pc_line = chain_ptr->line; 1482 pc_line++; 1483 } 1484 1485 for (chain_ptr = chain_head; chain_ptr != NULL;) { 1486 chain_head = chain_ptr; 1487 chain_ptr = chain_ptr->next; 1488 dwarf_dealloc(dbg, chain_head, DW_DLA_CHAIN); 1489 } 1490 1491 *linebuf = pc_line_buf; 1492 return (chain_count); 1493 } 1494 #endif 1495 1496 1497 /* 1498 Return DW_DLV_OK or, if error, 1499 DW_DLV_ERROR. 1500 1501 Thru pointers, return 2 arrays and a count 1502 for rqs. 1503 */ 1504 int 1505 _dwarf_line_address_offsets(Dwarf_Debug dbg, 1506 Dwarf_Die die, 1507 Dwarf_Addr ** addrs, 1508 Dwarf_Off ** offs, 1509 Dwarf_Unsigned * returncount, 1510 Dwarf_Error * err) 1511 { 1512 Dwarf_Addr *laddrs; 1513 Dwarf_Off *loffsets; 1514 Dwarf_Signed lcount; 1515 Dwarf_Signed i; 1516 int res; 1517 Dwarf_Line *linebuf; 1518 1519 res = _dwarf_internal_srclines(die, &linebuf, 1520 &lcount, /* addrlist= */ true, 1521 /* linelist= */ false, err); 1522 if (res != DW_DLV_OK) { 1523 return res; 1524 } 1525 laddrs = (Dwarf_Addr *) 1526 _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount); 1527 if (laddrs == NULL) { 1528 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 1529 return (DW_DLV_ERROR); 1530 } 1531 loffsets = (Dwarf_Off *) 1532 _dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount); 1533 if (loffsets == NULL) { 1534 _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL); 1535 return (DW_DLV_ERROR); 1536 } 1537 1538 for (i = 0; i < lcount; i++) { 1539 laddrs[i] = linebuf[i]->li_address; 1540 loffsets[i] = linebuf[i]->li_addr_line.li_offset; 1541 dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE); 1542 } 1543 dwarf_dealloc(dbg, linebuf, DW_DLA_LIST); 1544 *returncount = lcount; 1545 *offs = loffsets; 1546 *addrs = laddrs; 1547 return DW_DLV_OK; 1548 } 1549