1 /* Return line number information of CU. 2 Copyright (C) 2004-2010, 2013, 2014, 2015 Red Hat, Inc. 3 This file is part of elfutils. 4 Written by Ulrich Drepper <drepper (at) redhat.com>, 2004. 5 6 This file is free software; you can redistribute it and/or modify 7 it under the terms of either 8 9 * the GNU Lesser General Public License as published by the Free 10 Software Foundation; either version 3 of the License, or (at 11 your option) any later version 12 13 or 14 15 * the GNU General Public License as published by the Free 16 Software Foundation; either version 2 of the License, or (at 17 your option) any later version 18 19 or both in parallel, as here. 20 21 elfutils is distributed in the hope that it will be useful, but 22 WITHOUT ANY WARRANTY; without even the implied warranty of 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 General Public License for more details. 25 26 You should have received copies of the GNU General Public License and 27 the GNU Lesser General Public License along with this program. If 28 not, see <http://www.gnu.org/licenses/>. */ 29 30 #ifdef HAVE_CONFIG_H 31 # include <config.h> 32 #endif 33 34 #include <assert.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <search.h> 38 39 #include "dwarf.h" 40 #include "libdwP.h" 41 42 43 struct filelist 44 { 45 Dwarf_Fileinfo info; 46 struct filelist *next; 47 }; 48 49 struct linelist 50 { 51 Dwarf_Line line; 52 struct linelist *next; 53 size_t sequence; 54 }; 55 56 57 /* Compare by Dwarf_Line.addr, given pointers into an array of pointers. */ 58 static int 59 compare_lines (const void *a, const void *b) 60 { 61 struct linelist *const *p1 = a; 62 struct linelist *const *p2 = b; 63 struct linelist *list1 = *p1; 64 struct linelist *list2 = *p2; 65 Dwarf_Line *line1 = &list1->line; 66 Dwarf_Line *line2 = &list2->line; 67 68 if (line1->addr != line2->addr) 69 return (line1->addr < line2->addr) ? -1 : 1; 70 71 /* An end_sequence marker precedes a normal record at the same address. */ 72 if (line1->end_sequence != line2->end_sequence) 73 return line2->end_sequence - line1->end_sequence; 74 75 /* Otherwise, the linelist sequence maintains a stable sort. */ 76 return (list1->sequence < list2->sequence) ? -1 77 : (list1->sequence > list2->sequence) ? 1 78 : 0; 79 } 80 81 struct line_state 82 { 83 Dwarf_Word addr; 84 unsigned int op_index; 85 unsigned int file; 86 int64_t line; 87 unsigned int column; 88 uint_fast8_t is_stmt; 89 bool basic_block; 90 bool prologue_end; 91 bool epilogue_begin; 92 unsigned int isa; 93 unsigned int discriminator; 94 struct linelist *linelist; 95 size_t nlinelist; 96 unsigned int end_sequence; 97 }; 98 99 static inline void 100 run_advance_pc (struct line_state *state, unsigned int op_advance, 101 uint_fast8_t minimum_instr_len, uint_fast8_t max_ops_per_instr) 102 { 103 state->addr += minimum_instr_len * ((state->op_index + op_advance) 104 / max_ops_per_instr); 105 state->op_index = (state->op_index + op_advance) % max_ops_per_instr; 106 } 107 108 static inline bool 109 add_new_line (struct line_state *state, struct linelist *new_line) 110 { 111 /* Set the line information. For some fields we use bitfields, 112 so we would lose information if the encoded values are too large. 113 Check just for paranoia, and call the data "invalid" if it 114 violates our assumptions on reasonable limits for the values. */ 115 new_line->next = state->linelist; 116 new_line->sequence = state->nlinelist; 117 state->linelist = new_line; 118 ++(state->nlinelist); 119 120 /* Set the line information. For some fields we use bitfields, 121 so we would lose information if the encoded values are too large. 122 Check just for paranoia, and call the data "invalid" if it 123 violates our assumptions on reasonable limits for the values. */ 124 #define SET(field) \ 125 do { \ 126 new_line->line.field = state->field; \ 127 if (unlikely (new_line->line.field != state->field)) \ 128 return true; \ 129 } while (0) 130 131 SET (addr); 132 SET (op_index); 133 SET (file); 134 SET (line); 135 SET (column); 136 SET (is_stmt); 137 SET (basic_block); 138 SET (end_sequence); 139 SET (prologue_end); 140 SET (epilogue_begin); 141 SET (isa); 142 SET (discriminator); 143 144 #undef SET 145 146 return false; 147 } 148 149 static int 150 read_srclines (Dwarf *dbg, 151 const unsigned char *linep, const unsigned char *lineendp, 152 const char *comp_dir, unsigned address_size, 153 Dwarf_Lines **linesp, Dwarf_Files **filesp) 154 { 155 int res = -1; 156 157 size_t nfilelist = 0; 158 unsigned int ndirlist = 0; 159 160 struct filelist null_file = 161 { 162 .info = 163 { 164 .name = "???", 165 .mtime = 0, 166 .length = 0 167 }, 168 .next = NULL 169 }; 170 struct filelist *filelist = &null_file; 171 172 /* If there are a large number of lines, files or dirs don't blow up 173 the stack. Stack allocate some entries, only dynamically malloc 174 when more than MAX. */ 175 #define MAX_STACK_ALLOC 4096 176 #define MAX_STACK_LINES MAX_STACK_ALLOC 177 #define MAX_STACK_FILES (MAX_STACK_ALLOC / 4) 178 #define MAX_STACK_DIRS (MAX_STACK_ALLOC / 16) 179 180 struct dirlist 181 { 182 const char *dir; 183 size_t len; 184 }; 185 struct dirlist dirstack[MAX_STACK_DIRS]; 186 struct dirlist *dirarray = dirstack; 187 188 /* We are about to process the statement program. Initialize the 189 state machine registers (see 6.2.2 in the v2.1 specification). */ 190 struct line_state state = 191 { 192 .linelist = NULL, 193 .nlinelist = 0, 194 .addr = 0, 195 .op_index = 0, 196 .file = 1, 197 /* We only store int but want to check for overflow (see SET above). */ 198 .line = 1, 199 .column = 0, 200 .basic_block = false, 201 .prologue_end = false, 202 .epilogue_begin = false, 203 .isa = 0, 204 .discriminator = 0 205 }; 206 207 if (unlikely (linep + 4 > lineendp)) 208 { 209 invalid_data: 210 __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE); 211 goto out; 212 } 213 214 Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); 215 unsigned int length = 4; 216 if (unlikely (unit_length == DWARF3_LENGTH_64_BIT)) 217 { 218 if (unlikely (linep + 8 > lineendp)) 219 goto invalid_data; 220 unit_length = read_8ubyte_unaligned_inc (dbg, linep); 221 length = 8; 222 } 223 224 /* Check whether we have enough room in the section. */ 225 if (unlikely (unit_length > (size_t) (lineendp - linep) 226 || unit_length < 2 + length + 5 * 1)) 227 goto invalid_data; 228 lineendp = linep + unit_length; 229 230 /* The next element of the header is the version identifier. */ 231 uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep); 232 if (unlikely (version < 2) || unlikely (version > 4)) 233 { 234 __libdw_seterrno (DWARF_E_VERSION); 235 goto out; 236 } 237 238 /* Next comes the header length. */ 239 Dwarf_Word header_length; 240 if (length == 4) 241 header_length = read_4ubyte_unaligned_inc (dbg, linep); 242 else 243 header_length = read_8ubyte_unaligned_inc (dbg, linep); 244 const unsigned char *header_start = linep; 245 246 /* Next the minimum instruction length. */ 247 uint_fast8_t minimum_instr_len = *linep++; 248 249 /* Next the maximum operations per instruction, in version 4 format. */ 250 uint_fast8_t max_ops_per_instr = 1; 251 if (version >= 4) 252 { 253 if (unlikely (lineendp - linep < 5)) 254 goto invalid_data; 255 max_ops_per_instr = *linep++; 256 if (unlikely (max_ops_per_instr == 0)) 257 goto invalid_data; 258 } 259 260 /* Then the flag determining the default value of the is_stmt 261 register. */ 262 uint_fast8_t default_is_stmt = *linep++; 263 264 /* Now the line base. */ 265 int_fast8_t line_base = (int8_t) *linep++; 266 267 /* And the line range. */ 268 uint_fast8_t line_range = *linep++; 269 270 /* The opcode base. */ 271 uint_fast8_t opcode_base = *linep++; 272 273 /* Remember array with the standard opcode length (-1 to account for 274 the opcode with value zero not being mentioned). */ 275 const uint8_t *standard_opcode_lengths = linep - 1; 276 if (unlikely (lineendp - linep < opcode_base - 1)) 277 goto invalid_data; 278 linep += opcode_base - 1; 279 280 /* First comes the list of directories. Add the compilation 281 directory first since the index zero is used for it. */ 282 struct dirlist comp_dir_elem = 283 { 284 .dir = comp_dir, 285 .len = comp_dir ? strlen (comp_dir) : 0, 286 }; 287 ndirlist = 1; 288 289 /* First count the entries. */ 290 const unsigned char *dirp = linep; 291 while (*dirp != 0) 292 { 293 uint8_t *endp = memchr (dirp, '\0', lineendp - dirp); 294 if (endp == NULL) 295 goto invalid_data; 296 ++ndirlist; 297 dirp = endp + 1; 298 } 299 300 /* Arrange the list in array form. */ 301 if (ndirlist >= MAX_STACK_DIRS) 302 { 303 dirarray = (struct dirlist *) malloc (ndirlist * sizeof (*dirarray)); 304 if (unlikely (dirarray == NULL)) 305 { 306 no_mem: 307 __libdw_seterrno (DWARF_E_NOMEM); 308 goto out; 309 } 310 } 311 dirarray[0] = comp_dir_elem; 312 for (unsigned int n = 1; n < ndirlist; n++) 313 { 314 dirarray[n].dir = (char *) linep; 315 uint8_t *endp = memchr (linep, '\0', lineendp - linep); 316 assert (endp != NULL); 317 dirarray[n].len = endp - linep; 318 linep = endp + 1; 319 } 320 /* Skip the final NUL byte. */ 321 ++linep; 322 323 /* Allocate memory for a new file. For the first MAX_STACK_FILES 324 entries just return a slot in the preallocated stack array. */ 325 struct filelist flstack[MAX_STACK_FILES]; 326 #define NEW_FILE() ({ \ 327 struct filelist *fl = (nfilelist < MAX_STACK_FILES \ 328 ? &flstack[nfilelist] \ 329 : malloc (sizeof (struct filelist))); \ 330 if (unlikely (fl == NULL)) \ 331 goto no_mem; \ 332 ++nfilelist; \ 333 fl->next = filelist; \ 334 filelist = fl; \ 335 fl; }) 336 337 /* Now read the files. */ 338 nfilelist = 1; 339 340 if (unlikely (linep >= lineendp)) 341 goto invalid_data; 342 while (*linep != 0) 343 { 344 struct filelist *new_file = NEW_FILE (); 345 346 /* First comes the file name. */ 347 char *fname = (char *) linep; 348 uint8_t *endp = memchr (fname, '\0', lineendp - linep); 349 if (endp == NULL) 350 goto invalid_data; 351 size_t fnamelen = endp - (uint8_t *) fname; 352 linep = endp + 1; 353 354 /* Then the index. */ 355 Dwarf_Word diridx; 356 if (unlikely (linep >= lineendp)) 357 goto invalid_data; 358 get_uleb128 (diridx, linep, lineendp); 359 if (unlikely (diridx >= ndirlist)) 360 { 361 __libdw_seterrno (DWARF_E_INVALID_DIR_IDX); 362 goto out; 363 } 364 365 if (*fname == '/') 366 /* It's an absolute path. */ 367 new_file->info.name = fname; 368 else 369 { 370 new_file->info.name = libdw_alloc (dbg, char, 1, 371 dirarray[diridx].len + 1 372 + fnamelen + 1); 373 char *cp = new_file->info.name; 374 375 if (dirarray[diridx].dir != NULL) 376 { 377 /* This value could be NULL in case the DW_AT_comp_dir 378 was not present. We cannot do much in this case. 379 The easiest thing is to convert the path in an 380 absolute path. */ 381 cp = stpcpy (cp, dirarray[diridx].dir); 382 } 383 *cp++ = '/'; 384 strcpy (cp, fname); 385 assert (strlen (new_file->info.name) 386 < dirarray[diridx].len + 1 + fnamelen + 1); 387 } 388 389 /* Next comes the modification time. */ 390 if (unlikely (linep >= lineendp)) 391 goto invalid_data; 392 get_uleb128 (new_file->info.mtime, linep, lineendp); 393 394 /* Finally the length of the file. */ 395 if (unlikely (linep >= lineendp)) 396 goto invalid_data; 397 get_uleb128 (new_file->info.length, linep, lineendp); 398 } 399 /* Skip the final NUL byte. */ 400 ++linep; 401 402 /* Consistency check. */ 403 if (unlikely (linep != header_start + header_length)) 404 { 405 __libdw_seterrno (DWARF_E_INVALID_DWARF); 406 goto out; 407 } 408 409 state.is_stmt = default_is_stmt; 410 411 /* Apply the "operation advance" from a special opcode or 412 DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */ 413 #define advance_pc(op_advance) \ 414 run_advance_pc (&state, op_advance, minimum_instr_len, max_ops_per_instr) 415 416 /* Process the instructions. */ 417 418 /* Adds a new line to the matrix. For the first MAX_STACK_LINES 419 entries just return a slot in the preallocated stack array. */ 420 struct linelist llstack[MAX_STACK_LINES]; 421 #define NEW_LINE(end_seq) \ 422 do { \ 423 struct linelist *ll = (state.nlinelist < MAX_STACK_LINES \ 424 ? &llstack[state.nlinelist] \ 425 : malloc (sizeof (struct linelist))); \ 426 if (unlikely (ll == NULL)) \ 427 goto no_mem; \ 428 state.end_sequence = end_seq; \ 429 if (unlikely (add_new_line (&state, ll))) \ 430 goto invalid_data; \ 431 } while (0) 432 433 while (linep < lineendp) 434 { 435 unsigned int opcode; 436 unsigned int u128; 437 int s128; 438 439 /* Read the opcode. */ 440 opcode = *linep++; 441 442 /* Is this a special opcode? */ 443 if (likely (opcode >= opcode_base)) 444 { 445 if (unlikely (line_range == 0)) 446 goto invalid_data; 447 448 /* Yes. Handling this is quite easy since the opcode value 449 is computed with 450 451 opcode = (desired line increment - line_base) 452 + (line_range * address advance) + opcode_base 453 */ 454 int line_increment = (line_base 455 + (opcode - opcode_base) % line_range); 456 457 /* Perform the increments. */ 458 state.line += line_increment; 459 advance_pc ((opcode - opcode_base) / line_range); 460 461 /* Add a new line with the current state machine values. */ 462 NEW_LINE (0); 463 464 /* Reset the flags. */ 465 state.basic_block = false; 466 state.prologue_end = false; 467 state.epilogue_begin = false; 468 state.discriminator = 0; 469 } 470 else if (opcode == 0) 471 { 472 /* This an extended opcode. */ 473 if (unlikely (lineendp - linep < 2)) 474 goto invalid_data; 475 476 /* The length. */ 477 uint_fast8_t len = *linep++; 478 479 if (unlikely ((size_t) (lineendp - linep) < len)) 480 goto invalid_data; 481 482 /* The sub-opcode. */ 483 opcode = *linep++; 484 485 switch (opcode) 486 { 487 case DW_LNE_end_sequence: 488 /* Add a new line with the current state machine values. 489 The is the end of the sequence. */ 490 NEW_LINE (1); 491 492 /* Reset the registers. */ 493 state.addr = 0; 494 state.op_index = 0; 495 state.file = 1; 496 state.line = 1; 497 state.column = 0; 498 state.is_stmt = default_is_stmt; 499 state.basic_block = false; 500 state.prologue_end = false; 501 state.epilogue_begin = false; 502 state.isa = 0; 503 state.discriminator = 0; 504 break; 505 506 case DW_LNE_set_address: 507 /* The value is an address. The size is defined as 508 apporiate for the target machine. We use the 509 address size field from the CU header. */ 510 state.op_index = 0; 511 if (unlikely (lineendp - linep < (uint8_t) address_size)) 512 goto invalid_data; 513 if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep, 514 address_size, &state.addr)) 515 goto out; 516 break; 517 518 case DW_LNE_define_file: 519 { 520 char *fname = (char *) linep; 521 uint8_t *endp = memchr (linep, '\0', lineendp - linep); 522 if (endp == NULL) 523 goto invalid_data; 524 size_t fnamelen = endp - linep; 525 linep = endp + 1; 526 527 unsigned int diridx; 528 if (unlikely (linep >= lineendp)) 529 goto invalid_data; 530 get_uleb128 (diridx, linep, lineendp); 531 if (unlikely (diridx >= ndirlist)) 532 { 533 __libdw_seterrno (DWARF_E_INVALID_DIR_IDX); 534 goto invalid_data; 535 } 536 Dwarf_Word mtime; 537 if (unlikely (linep >= lineendp)) 538 goto invalid_data; 539 get_uleb128 (mtime, linep, lineendp); 540 Dwarf_Word filelength; 541 if (unlikely (linep >= lineendp)) 542 goto invalid_data; 543 get_uleb128 (filelength, linep, lineendp); 544 545 struct filelist *new_file = NEW_FILE (); 546 if (fname[0] == '/') 547 new_file->info.name = fname; 548 else 549 { 550 new_file->info.name = 551 libdw_alloc (dbg, char, 1, (dirarray[diridx].len + 1 552 + fnamelen + 1)); 553 char *cp = new_file->info.name; 554 555 if (dirarray[diridx].dir != NULL) 556 /* This value could be NULL in case the 557 DW_AT_comp_dir was not present. We 558 cannot do much in this case. The easiest 559 thing is to convert the path in an 560 absolute path. */ 561 cp = stpcpy (cp, dirarray[diridx].dir); 562 *cp++ = '/'; 563 strcpy (cp, fname); 564 } 565 566 new_file->info.mtime = mtime; 567 new_file->info.length = filelength; 568 } 569 break; 570 571 case DW_LNE_set_discriminator: 572 /* Takes one ULEB128 parameter, the discriminator. */ 573 if (unlikely (standard_opcode_lengths[opcode] != 1)) 574 goto invalid_data; 575 576 if (unlikely (linep >= lineendp)) 577 goto invalid_data; 578 get_uleb128 (state.discriminator, linep, lineendp); 579 break; 580 581 default: 582 /* Unknown, ignore it. */ 583 if (unlikely ((size_t) (lineendp - (linep - 1)) < len)) 584 goto invalid_data; 585 linep += len - 1; 586 break; 587 } 588 } 589 else if (opcode <= DW_LNS_set_isa) 590 { 591 /* This is a known standard opcode. */ 592 switch (opcode) 593 { 594 case DW_LNS_copy: 595 /* Takes no argument. */ 596 if (unlikely (standard_opcode_lengths[opcode] != 0)) 597 goto invalid_data; 598 599 /* Add a new line with the current state machine values. */ 600 NEW_LINE (0); 601 602 /* Reset the flags. */ 603 state.basic_block = false; 604 state.prologue_end = false; 605 state.epilogue_begin = false; 606 state.discriminator = 0; 607 break; 608 609 case DW_LNS_advance_pc: 610 /* Takes one uleb128 parameter which is added to the 611 address. */ 612 if (unlikely (standard_opcode_lengths[opcode] != 1)) 613 goto invalid_data; 614 615 if (unlikely (linep >= lineendp)) 616 goto invalid_data; 617 get_uleb128 (u128, linep, lineendp); 618 advance_pc (u128); 619 break; 620 621 case DW_LNS_advance_line: 622 /* Takes one sleb128 parameter which is added to the 623 line. */ 624 if (unlikely (standard_opcode_lengths[opcode] != 1)) 625 goto invalid_data; 626 627 if (unlikely (linep >= lineendp)) 628 goto invalid_data; 629 get_sleb128 (s128, linep, lineendp); 630 state.line += s128; 631 break; 632 633 case DW_LNS_set_file: 634 /* Takes one uleb128 parameter which is stored in file. */ 635 if (unlikely (standard_opcode_lengths[opcode] != 1)) 636 goto invalid_data; 637 638 if (unlikely (linep >= lineendp)) 639 goto invalid_data; 640 get_uleb128 (u128, linep, lineendp); 641 state.file = u128; 642 break; 643 644 case DW_LNS_set_column: 645 /* Takes one uleb128 parameter which is stored in column. */ 646 if (unlikely (standard_opcode_lengths[opcode] != 1)) 647 goto invalid_data; 648 649 if (unlikely (linep >= lineendp)) 650 goto invalid_data; 651 get_uleb128 (u128, linep, lineendp); 652 state.column = u128; 653 break; 654 655 case DW_LNS_negate_stmt: 656 /* Takes no argument. */ 657 if (unlikely (standard_opcode_lengths[opcode] != 0)) 658 goto invalid_data; 659 660 state.is_stmt = 1 - state.is_stmt; 661 break; 662 663 case DW_LNS_set_basic_block: 664 /* Takes no argument. */ 665 if (unlikely (standard_opcode_lengths[opcode] != 0)) 666 goto invalid_data; 667 668 state.basic_block = true; 669 break; 670 671 case DW_LNS_const_add_pc: 672 /* Takes no argument. */ 673 if (unlikely (standard_opcode_lengths[opcode] != 0)) 674 goto invalid_data; 675 676 if (unlikely (line_range == 0)) 677 goto invalid_data; 678 679 advance_pc ((255 - opcode_base) / line_range); 680 break; 681 682 case DW_LNS_fixed_advance_pc: 683 /* Takes one 16 bit parameter which is added to the 684 address. */ 685 if (unlikely (standard_opcode_lengths[opcode] != 1) 686 || unlikely (lineendp - linep < 2)) 687 goto invalid_data; 688 689 state.addr += read_2ubyte_unaligned_inc (dbg, linep); 690 state.op_index = 0; 691 break; 692 693 case DW_LNS_set_prologue_end: 694 /* Takes no argument. */ 695 if (unlikely (standard_opcode_lengths[opcode] != 0)) 696 goto invalid_data; 697 698 state.prologue_end = true; 699 break; 700 701 case DW_LNS_set_epilogue_begin: 702 /* Takes no argument. */ 703 if (unlikely (standard_opcode_lengths[opcode] != 0)) 704 goto invalid_data; 705 706 state.epilogue_begin = true; 707 break; 708 709 case DW_LNS_set_isa: 710 /* Takes one uleb128 parameter which is stored in isa. */ 711 if (unlikely (standard_opcode_lengths[opcode] != 1)) 712 goto invalid_data; 713 714 if (unlikely (linep >= lineendp)) 715 goto invalid_data; 716 get_uleb128 (state.isa, linep, lineendp); 717 break; 718 } 719 } 720 else 721 { 722 /* This is a new opcode the generator but not we know about. 723 Read the parameters associated with it but then discard 724 everything. Read all the parameters for this opcode. */ 725 for (int n = standard_opcode_lengths[opcode]; n > 0; --n) 726 { 727 if (unlikely (linep >= lineendp)) 728 goto invalid_data; 729 get_uleb128 (u128, linep, lineendp); 730 } 731 732 /* Next round, ignore this opcode. */ 733 continue; 734 } 735 } 736 737 /* Put all the files in an array. */ 738 Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files, 739 sizeof (Dwarf_Files) 740 + nfilelist * sizeof (Dwarf_Fileinfo) 741 + (ndirlist + 1) * sizeof (char *), 742 1); 743 const char **dirs = (void *) &files->info[nfilelist]; 744 745 struct filelist *fileslist = filelist; 746 files->nfiles = nfilelist; 747 for (size_t n = nfilelist; n > 0; n--) 748 { 749 files->info[n - 1] = fileslist->info; 750 fileslist = fileslist->next; 751 } 752 assert (fileslist == NULL); 753 754 /* Put all the directory strings in an array. */ 755 files->ndirs = ndirlist; 756 for (unsigned int i = 0; i < ndirlist; ++i) 757 dirs[i] = dirarray[i].dir; 758 dirs[ndirlist] = NULL; 759 760 /* Pass the file data structure to the caller. */ 761 if (filesp != NULL) 762 *filesp = files; 763 764 size_t buf_size = (sizeof (Dwarf_Lines) 765 + (sizeof (Dwarf_Line) * state.nlinelist)); 766 void *buf = libdw_alloc (dbg, Dwarf_Lines, buf_size, 1); 767 768 /* First use the buffer for the pointers, and sort the entries. 769 We'll write the pointers in the end of the buffer, and then 770 copy into the buffer from the beginning so the overlap works. */ 771 assert (sizeof (Dwarf_Line) >= sizeof (struct linelist *)); 772 struct linelist **sortlines = (buf + buf_size 773 - sizeof (struct linelist **) * state.nlinelist); 774 775 /* The list is in LIFO order and usually they come in clumps with 776 ascending addresses. So fill from the back to probably start with 777 runs already in order before we sort. */ 778 struct linelist *lineslist = state.linelist; 779 for (size_t i = state.nlinelist; i-- > 0; ) 780 { 781 sortlines[i] = lineslist; 782 lineslist = lineslist->next; 783 } 784 assert (lineslist == NULL); 785 786 /* Sort by ascending address. */ 787 qsort (sortlines, state.nlinelist, sizeof sortlines[0], &compare_lines); 788 789 /* Now that they are sorted, put them in the final array. 790 The buffers overlap, so we've clobbered the early elements 791 of SORTLINES by the time we're reading the later ones. */ 792 Dwarf_Lines *lines = buf; 793 lines->nlines = state.nlinelist; 794 for (size_t i = 0; i < state.nlinelist; ++i) 795 { 796 lines->info[i] = sortlines[i]->line; 797 lines->info[i].files = files; 798 } 799 800 /* Make sure the highest address for the CU is marked as end_sequence. 801 This is required by the DWARF spec, but some compilers forget and 802 dwfl_module_getsrc depends on it. */ 803 if (state.nlinelist > 0) 804 lines->info[state.nlinelist - 1].end_sequence = 1; 805 806 /* Pass the line structure back to the caller. */ 807 if (linesp != NULL) 808 *linesp = lines; 809 810 /* Success. */ 811 res = 0; 812 813 out: 814 /* Free malloced line records, if any. */ 815 for (size_t i = MAX_STACK_LINES; i < state.nlinelist; i++) 816 { 817 struct linelist *ll = state.linelist->next; 818 free (state.linelist); 819 state.linelist = ll; 820 } 821 if (ndirlist >= MAX_STACK_DIRS) 822 free (dirarray); 823 for (size_t i = MAX_STACK_FILES; i < nfilelist; i++) 824 { 825 struct filelist *fl = filelist->next; 826 free (filelist); 827 filelist = fl; 828 } 829 830 return res; 831 } 832 833 static int 834 files_lines_compare (const void *p1, const void *p2) 835 { 836 const struct files_lines_s *t1 = p1; 837 const struct files_lines_s *t2 = p2; 838 839 if (t1->debug_line_offset < t2->debug_line_offset) 840 return -1; 841 if (t1->debug_line_offset > t2->debug_line_offset) 842 return 1; 843 844 return 0; 845 } 846 847 int 848 internal_function 849 __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, 850 const char *comp_dir, unsigned address_size, 851 Dwarf_Lines **linesp, Dwarf_Files **filesp) 852 { 853 struct files_lines_s fake = { .debug_line_offset = debug_line_offset }; 854 struct files_lines_s **found = tfind (&fake, &dbg->files_lines, 855 files_lines_compare); 856 if (found == NULL) 857 { 858 Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line); 859 if (data == NULL 860 || __libdw_offset_in_section (dbg, IDX_debug_line, 861 debug_line_offset, 1) != 0) 862 return -1; 863 864 const unsigned char *linep = data->d_buf + debug_line_offset; 865 const unsigned char *lineendp = data->d_buf + data->d_size; 866 867 struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s, 868 sizeof *node, 1); 869 870 if (read_srclines (dbg, linep, lineendp, comp_dir, address_size, 871 &node->lines, &node->files) != 0) 872 return -1; 873 874 node->debug_line_offset = debug_line_offset; 875 876 found = tsearch (node, &dbg->files_lines, files_lines_compare); 877 if (found == NULL) 878 { 879 __libdw_seterrno (DWARF_E_NOMEM); 880 return -1; 881 } 882 } 883 884 if (linesp != NULL) 885 *linesp = (*found)->lines; 886 887 if (filesp != NULL) 888 *filesp = (*found)->files; 889 890 return 0; 891 } 892 893 /* Get the compilation directory, if any is set. */ 894 const char * 895 __libdw_getcompdir (Dwarf_Die *cudie) 896 { 897 Dwarf_Attribute compdir_attr_mem; 898 Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie, 899 DW_AT_comp_dir, 900 &compdir_attr_mem); 901 return INTUSE(dwarf_formstring) (compdir_attr); 902 } 903 904 int 905 dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) 906 { 907 if (cudie == NULL) 908 return -1; 909 if (! is_cudie (cudie)) 910 { 911 __libdw_seterrno (DWARF_E_NOT_CUDIE); 912 return -1; 913 } 914 915 /* Get the information if it is not already known. */ 916 struct Dwarf_CU *const cu = cudie->cu; 917 if (cu->lines == NULL) 918 { 919 /* Failsafe mode: no data found. */ 920 cu->lines = (void *) -1l; 921 cu->files = (void *) -1l; 922 923 /* The die must have a statement list associated. */ 924 Dwarf_Attribute stmt_list_mem; 925 Dwarf_Attribute *stmt_list = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, 926 &stmt_list_mem); 927 928 /* Get the offset into the .debug_line section. NB: this call 929 also checks whether the previous dwarf_attr call failed. */ 930 Dwarf_Off debug_line_offset; 931 if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE, 932 NULL, &debug_line_offset) == NULL) 933 return -1; 934 935 if (__libdw_getsrclines (cu->dbg, debug_line_offset, 936 __libdw_getcompdir (cudie), 937 cu->address_size, &cu->lines, &cu->files) < 0) 938 return -1; 939 } 940 else if (cu->lines == (void *) -1l) 941 return -1; 942 943 *lines = cu->lines; 944 *nlines = cu->lines->nlines; 945 946 // XXX Eventually: unlocking here. 947 948 return 0; 949 } 950 INTDEF(dwarf_getsrclines) 951