1 /* 2 Copyright (C) 2000,2002,2004,2006 Silicon Graphics, Inc. All Rights Reserved. 3 Portions Copyright (C) 2007-2010 David Anderson. 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., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 23 USA. 24 25 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 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 /* The address of the Free Software Foundation is 36 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 37 Boston, MA 02110-1301, USA. 38 SGI has moved from the Crittenden Lane address. 39 */ 40 41 42 /* This file was designed for SGI IRIX compiler use. 43 The static linker can rearrange the order of functions 44 in the layout in memory 45 and provided each has the right form 46 this will (when called by the SGI IRIX 47 static linker) rearrange the table so the line table 48 is arranged in the same order as the memory layout. */ 49 50 51 52 #include "config.h" 53 #include "dwarf_incl.h" 54 #include <stdio.h> 55 #include <stdlib.h> 56 #include "dwarf_line.h" 57 #ifdef HAVE_ALLOCA_H 58 #include <alloca.h> 59 #endif 60 #ifdef HAVE_STRING_H 61 #include <string.h> 62 #endif 63 64 #define MINIMUM_POSSIBLE_PROLOG_LEN 10 /* 10 is based on */ 65 /* the definition of the DWARF2/3 line table prolog. The value 66 here should be >8 (accounting for a 64 bit read) and <= the 67 length of a legal DWARF2/3 line prolog, which is at least 10 68 bytes long (but can be longer). What this constant helps 69 avoid is reading past the end of a malloc'd buffer in 70 _dwarf_update_line_sec(). */ 71 72 static int 73 _dwarf_update_line_sec(Dwarf_Small * line_ptr, 74 unsigned long remaining_bytes, 75 int *any_change, 76 int length_size, 77 int *err_code, Dwarf_Small ** new_line_ptr); 78 79 /* Used to construct 80 a linked list of so we can sort and reorder the line info. 81 */ 82 struct a_line_area { 83 Dwarf_Addr ala_address; /* from DW_LNE_set_address */ 84 Dwarf_Unsigned ala_offset; /* byte offset in buffer */ 85 Dwarf_Unsigned ala_length; /* byte length in buffer */ 86 long ala_entry_num; /* to guarantee stable sort */ 87 struct a_line_area *ala_next; 88 }; 89 90 91 /* 92 Written to support the SGI IRIX static linker. 93 It helps SGI IRIX ld 94 rearrange lines in .debug_line in a .o created with a text 95 section per function. The SGI IRIX linker option is: 96 -OPT:procedure_reorder=ON 97 where ld-cord (cord(1)ing by ld, 98 not by cord(1)) may have changed the function order. 99 100 Returns 101 DW_DLV_OK if nothing went wrong. 102 DW_DLV_ERROR if could not do anything due to 103 error. the original buffer is unchanged. 104 105 is_64_bit must be passed in by caller and tells 106 if this is a 32 or 64bit pointer object section 107 being processed. 108 109 err_code must be a non-null pointer to integer. 110 If DW_DLV_ERROR is returned that integer is set 111 to a dwarf error code so the caller may 112 print it for diagnostic purposes. 113 114 *any_change is set here 115 set 0 if no sorting (movement) done. 116 set 1 if some sorting (movement) done. 117 on all returns. On error return sets to 0. 118 119 The _dwarf name form is now obsolete, 120 the dwarf_ name for is preferred. 121 Both names supported. 122 123 */ 124 int 125 _dwarf_ld_sort_lines(void *orig_buffer, 126 unsigned long buffer_len, 127 int is_64_bit, int *any_change, int *err_code) 128 { 129 return dwarf_ld_sort_lines(orig_buffer,buffer_len, 130 is_64_bit,any_change,err_code); 131 } 132 int 133 dwarf_ld_sort_lines(void *orig_buffer, 134 unsigned long buffer_len, 135 int is_64_bit, int *any_change, int *err_code) 136 { 137 138 int length_size = 4; 139 Dwarf_Small *orig_line_ptr; /* our local copy of the user's input 140 buffer */ 141 Dwarf_Small *line_ptr; /* starts at orig_line_ptr, gets 142 incremented thru to end of our copy 143 of the input buffer */ 144 Dwarf_Small *new_line_ptr; /* output of _dwarf_update_line_sec(), 145 used to update line_ptr as we pass 146 thru compilation units in a .o 147 .debug_line */ 148 149 unsigned long remaining_bytes = buffer_len; /* total length of 150 original area left 151 to be processed. 152 Changes as we pass 153 thru compilation 154 units in a .o 155 .debug_line */ 156 157 int sec_res; 158 int lany_change = 0; 159 int did_change = 0; 160 161 if (is_64_bit) 162 length_size = 8; 163 164 *any_change = 0; 165 line_ptr = malloc(buffer_len); 166 if (!line_ptr) { 167 *err_code = DW_DLE_ALLOC_FAIL; 168 return DW_DLV_ERROR; 169 } 170 orig_line_ptr = line_ptr; 171 memcpy(line_ptr, orig_buffer, buffer_len); 172 173 174 /* 175 We must iterate thru each of a set of prologues and line data. 176 We process each set in turn. If all pass, we update the 177 passed-in buffer. */ 178 sec_res = DW_DLV_OK; 179 180 for (sec_res = _dwarf_update_line_sec(line_ptr, 181 remaining_bytes, 182 &lany_change, 183 length_size, 184 err_code, 185 &new_line_ptr); 186 (sec_res == DW_DLV_OK) && (remaining_bytes > 0); 187 sec_res = _dwarf_update_line_sec(line_ptr, 188 remaining_bytes, 189 &lany_change, 190 length_size, 191 err_code, &new_line_ptr)) { 192 long bytes_used = new_line_ptr - line_ptr; 193 194 line_ptr = new_line_ptr; 195 remaining_bytes -= bytes_used; 196 if (lany_change) { 197 did_change = 1; 198 } 199 if (remaining_bytes > 0) { 200 continue; 201 } 202 break; 203 } 204 if (sec_res == DW_DLV_ERROR) { 205 free(orig_line_ptr); 206 return sec_res; 207 } 208 209 210 /* all passed */ 211 if (did_change) { 212 /* So update the passed in buffer orig_buffer is caller's input 213 area. orig_line_ptr is our modified copy of input area. */ 214 memcpy(orig_buffer, orig_line_ptr, buffer_len); 215 *any_change = 1; 216 } 217 free(orig_line_ptr); 218 219 return sec_res; 220 } 221 222 223 /* By setting ala_entry_num we guarantee a stable sort, 224 no duplicates 225 Sorting in address order. 226 */ 227 static int 228 cmpr(const void *lin, const void *rin) 229 { 230 const struct a_line_area *l = lin; 231 const struct a_line_area *r = rin; 232 233 if (l->ala_address < r->ala_address) { 234 return -1; 235 } 236 if (l->ala_address > r->ala_address) { 237 return 1; 238 } 239 if (l->ala_entry_num < r->ala_entry_num) { 240 return -1; 241 } 242 if (l->ala_entry_num > r->ala_entry_num) { 243 return 1; 244 } 245 return 0; /* should never happen. */ 246 } 247 248 /* The list of line area records is no longer needed. 249 Free the data allocated. */ 250 static void 251 free_area_data(struct a_line_area *arp) 252 { 253 while(arp) { 254 struct a_line_area *next = arp->ala_next; 255 free(arp); 256 arp = next; 257 } 258 } 259 260 /* 261 On entry: 262 line_ptr must point to first 263 byte of a line group for one (original) .o 264 265 remaining_bytes is the size of the area pointed to 266 by line_ptr: may be larger than the 267 current original compilation unit . 268 269 length size is 4 for 32bit pointers, 8 for 64bit pointers 270 in the data pointed to. 271 272 273 On return: 274 return DW_DLV_OK if all ok. (ignore 275 *err_code in this case) 276 277 return DW_DLV_ERROR and set *err_code if an error. 278 279 If some line data was moved around, set *any_change to 1. 280 If error or no movement, set *any_change to 0; 281 282 Set *new_line_ptr to one-byte-past the end of the 283 current original compilation unit (not necessary 284 if returning DW_DLV_ERROR, but not harmful). 285 286 287 This copies the entire array to a malloc area, then 288 mallocs pieces of it (another malloc) for sorting a CU entries 289 and copying back. Then at end the whole new thing copied in. 290 The result is that on error, the input is not touched. 291 292 An alternative would be to just update a piece at a time 293 and on error stop updating but leave what was done, done. 294 This alternative would save some temporary malloc space. 295 296 297 */ 298 static int 299 _dwarf_update_line_sec(Dwarf_Small * line_ptr, 300 unsigned long remaining_bytes, 301 int *any_change, 302 int length_size, 303 int *err_code, Dwarf_Small ** new_line_ptr) 304 { 305 306 307 /* 308 This points to the last byte of the .debug_line portion for the 309 current cu. */ 310 Dwarf_Small *line_ptr_end = 0; 311 312 /* 313 This points to the end of the statement program prologue for the 314 current cu, and serves to check that the prologue was correctly 315 decoded. */ 316 317 Dwarf_Small *orig_line_ptr = 0; 318 319 /* These are the fields of the statement program header. */ 320 struct Dwarf_Debug_s dbg_data; 321 Dwarf_Debug dbg = &dbg_data; 322 323 /* These are the state machine state variables. */ 324 Dwarf_Addr address = 0; 325 Dwarf_Word line = 1; 326 Dwarf_Bool is_stmt = false; 327 328 /* Dwarf_Bool prologue_end; Dwarf_Bool epilogue_begin; */ 329 Dwarf_Small isa = 0; 330 331 332 struct a_line_area *area_base = 0; 333 struct a_line_area *area_current = 0; 334 long area_count = 0; 335 336 Dwarf_Addr last_address = 0; 337 int need_to_sort = 0; 338 339 /* 340 This is the current opcode read from the statement program. */ 341 Dwarf_Small opcode = 0; 342 343 344 /* 345 These variables are used to decode leb128 numbers. Leb128_num 346 holds the decoded number, and leb128_length is its length in 347 bytes. */ 348 Dwarf_Word leb128_num = 0; 349 Dwarf_Sword advance_line = 0; 350 351 /* 352 This is the operand of the latest fixed_advance_pc extended 353 opcode. */ 354 Dwarf_Half fixed_advance_pc = 0; 355 356 /* This is the length of an extended opcode instr. */ 357 Dwarf_Word instr_length = 0; 358 Dwarf_Small ext_opcode = 0; 359 struct Line_Table_Prefix_s prefix; 360 361 362 363 memset(dbg, 0, sizeof(struct Dwarf_Debug_s)); 364 dbg->de_copy_word = memcpy; 365 /* 366 Following is a straightforward decoding of the statement program 367 prologue information. */ 368 *any_change = 0; 369 370 371 orig_line_ptr = line_ptr; 372 if (remaining_bytes < MINIMUM_POSSIBLE_PROLOG_LEN) { 373 /* We are at the end. Remaining should be zero bytes, padding. 374 This is really just 'end of CU buffer' not an error. The is 375 no 'entry' left so report there is none. We don't want to 376 READ_UNALIGNED the total_length below and then belatedly 377 discover that we read off the end already. */ 378 return (DW_DLV_NO_ENTRY); 379 } 380 381 dwarf_init_line_table_prefix(&prefix); 382 { 383 Dwarf_Small *line_ptr_out = 0; 384 Dwarf_Error error; 385 int dres = dwarf_read_line_table_prefix(dbg, 386 line_ptr, 387 remaining_bytes, 388 &line_ptr_out, 389 &prefix, 390 NULL, NULL,&error, 391 NULL); 392 393 if (dres == DW_DLV_ERROR) { 394 dwarf_free_line_table_prefix(&prefix); 395 *err_code = dwarf_errno(error); 396 dwarf_dealloc(dbg, error, DW_DLA_ERROR); 397 free_area_data(area_base); 398 return dres; 399 } 400 if (dres == DW_DLV_NO_ENTRY) { 401 dwarf_free_line_table_prefix(&prefix); 402 return dres; 403 } 404 line_ptr_end = prefix.pf_line_ptr_end; 405 406 line_ptr = line_ptr_out; 407 } 408 409 410 /* Initialize the state machine. */ 411 /* file = 1; */ 412 /* column = 0; */ 413 is_stmt = prefix.pf_default_is_stmt; 414 /* basic_block = false; */ 415 /* end_sequence = false; */ 416 /* prologue_end = false; */ 417 /* epilogue_begin = false; */ 418 isa = 0; 419 420 421 /* Start of statement program. */ 422 while (line_ptr < line_ptr_end) { 423 int type; 424 425 Dwarf_Small *stmt_prog_entry_start = line_ptr; 426 427 opcode = *(Dwarf_Small *) line_ptr; 428 line_ptr++; 429 /* 'type' is the output */ 430 WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base, 431 prefix.pf_opcode_length_table, line_ptr, 432 prefix.pf_std_op_count); 433 434 if (type == LOP_DISCARD) { 435 int oc; 436 int opcnt = prefix.pf_opcode_length_table[opcode]; 437 438 for (oc = 0; oc < opcnt; oc++) { 439 /* 440 ** Read and discard operands we don't 441 ** understand. 442 ** arbitrary choice of unsigned read. 443 ** signed read would work as well. 444 */ 445 Dwarf_Unsigned utmp2; 446 447 DECODE_LEB128_UWORD(line_ptr, utmp2); 448 } 449 450 } else if (type == LOP_SPECIAL) { 451 opcode = opcode - prefix.pf_opcode_base; 452 address = address + prefix.pf_minimum_instruction_length * 453 (opcode / prefix.pf_line_range); 454 line = 455 line + prefix.pf_line_base + 456 opcode % prefix.pf_line_range; 457 458 /* basic_block = false; */ 459 460 461 } else if (type == LOP_STANDARD) { 462 463 464 switch (opcode) { 465 466 467 case DW_LNS_copy:{ 468 469 /* basic_block = false; */ 470 break; 471 } 472 473 case DW_LNS_advance_pc:{ 474 Dwarf_Unsigned utmp2; 475 476 477 DECODE_LEB128_UWORD(line_ptr, utmp2); 478 leb128_num = (Dwarf_Word) utmp2; 479 address = 480 address + 481 prefix.pf_minimum_instruction_length * 482 leb128_num; 483 break; 484 } 485 486 case DW_LNS_advance_line:{ 487 Dwarf_Signed stmp; 488 489 490 DECODE_LEB128_SWORD(line_ptr, stmp); 491 advance_line = (Dwarf_Sword) stmp; 492 line = line + advance_line; 493 break; 494 } 495 496 case DW_LNS_set_file:{ 497 Dwarf_Unsigned utmp2; 498 499 500 DECODE_LEB128_UWORD(line_ptr, utmp2); 501 /* file = (Dwarf_Word)utmp2; */ 502 break; 503 } 504 505 case DW_LNS_set_column:{ 506 Dwarf_Unsigned utmp2; 507 508 509 DECODE_LEB128_UWORD(line_ptr, utmp2); 510 /* column = (Dwarf_Word)utmp2; */ 511 break; 512 } 513 514 case DW_LNS_negate_stmt:{ 515 516 is_stmt = !is_stmt; 517 break; 518 } 519 520 case DW_LNS_set_basic_block:{ 521 522 /* basic_block = true; */ 523 break; 524 } 525 526 case DW_LNS_const_add_pc:{ 527 opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base; 528 address = 529 address + 530 prefix.pf_minimum_instruction_length * (opcode / 531 prefix. 532 pf_line_range); 533 534 break; 535 } 536 537 case DW_LNS_fixed_advance_pc:{ 538 539 READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half, 540 line_ptr, sizeof(Dwarf_Half)); 541 line_ptr += sizeof(Dwarf_Half); 542 address = address + fixed_advance_pc; 543 break; 544 } 545 /* New in DWARF3 */ 546 case DW_LNS_set_prologue_end:{ 547 548 /* prologue_end = true; */ 549 break; 550 551 552 } 553 /* New in DWARF3 */ 554 case DW_LNS_set_epilogue_begin:{ 555 /* epilogue_begin = true; */ 556 break; 557 } 558 559 /* New in DWARF3 */ 560 case DW_LNS_set_isa:{ 561 Dwarf_Unsigned utmp2; 562 563 DECODE_LEB128_UWORD(line_ptr, utmp2); 564 isa = utmp2; 565 if (isa != utmp2) { 566 /* The value of the isa did not fit in our 567 local so we record it wrong. declare an 568 error. */ 569 dwarf_free_line_table_prefix(&prefix); 570 *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD; 571 free_area_data(area_base); 572 return (DW_DLV_ERROR); 573 } 574 break; 575 } 576 577 } 578 } else if (type == LOP_EXTENDED) { 579 580 Dwarf_Unsigned utmp3; 581 582 DECODE_LEB128_UWORD(line_ptr, utmp3); 583 instr_length = (Dwarf_Word) utmp3; 584 ext_opcode = *(Dwarf_Small *) line_ptr; 585 line_ptr++; 586 switch (ext_opcode) { 587 588 case DW_LNE_end_sequence:{ 589 /* end_sequence = true; */ 590 591 address = 0; 592 /* file = 1; */ 593 line = 1; 594 /* column = 0; */ 595 is_stmt = prefix.pf_default_is_stmt; 596 /* basic_block = false; */ 597 /* end_sequence = false; */ 598 /* prologue_end = false; */ 599 /* epilogue_begin = false; */ 600 break; 601 } 602 603 case DW_LNE_set_address:{ 604 { 605 struct a_line_area *area; 606 607 READ_UNALIGNED(dbg, address, Dwarf_Addr, 608 line_ptr, length_size); 609 /* Here we need to remember the offset into the 610 buffer and check to see if address went 611 down. */ 612 if (address < last_address) { 613 need_to_sort = 1; 614 } 615 last_address = address; 616 617 area = malloc(sizeof(struct a_line_area)); 618 area->ala_address = address; 619 area->ala_offset = stmt_prog_entry_start - 620 orig_line_ptr; 621 area->ala_entry_num = area_count; 622 area->ala_next = 0; 623 area->ala_length = 0; 624 if (area_current) { 625 area_current->ala_next = area; 626 area_current->ala_length = 627 area->ala_offset - 628 area_current->ala_offset; 629 } 630 ++area_count; 631 area_current = area; 632 if (area_base == 0) { 633 area_base = area; 634 } 635 636 line_ptr += length_size; 637 } 638 break; 639 } 640 641 case DW_LNE_define_file:{ 642 break; 643 } 644 645 default:{ 646 Dwarf_Unsigned remaining_bytes = instr_length -1; 647 line_ptr += remaining_bytes; 648 break; 649 } 650 } 651 652 } 653 } 654 655 656 *new_line_ptr = line_ptr; 657 if (!need_to_sort) { 658 dwarf_free_line_table_prefix(&prefix); 659 free_area_data(area_base); 660 return (DW_DLV_OK); 661 } 662 663 /* So now we have something to sort. First, finish off the last 664 area record: */ 665 area_current->ala_length = (line_ptr - orig_line_ptr) 666 -area_current->ala_offset; 667 668 /* Build and sort a simple array of sections. Forcing a stable sort 669 by comparing on sequence number. We will use the sorted list to 670 move sections of this part of the line table. Each 'section' 671 starting with a DW_LNE_set_address opcode, on the assumption 672 that such only get out of order where there was an ld-cord 673 function rearrangement and that it is meaningful to restart the 674 line info there. */ 675 { 676 struct a_line_area *ala_array; 677 struct a_line_area *local; 678 long start_len; 679 Dwarf_Small *new_area; 680 long i; 681 682 ala_array = malloc(area_count * sizeof(struct a_line_area)); 683 if (!ala_array) { 684 dwarf_free_line_table_prefix(&prefix); 685 *err_code = DW_DLE_ALLOC_FAIL; 686 free_area_data(area_base); 687 return DW_DLV_ERROR; 688 } 689 690 for (local = area_base, i = 0; local; 691 local = local->ala_next, ++i) { 692 693 ala_array[i] = *local; 694 } 695 free_area_data(area_base); 696 /* Zero the stale pointers so we don't use them accidentally. */ 697 area_base = 0; 698 area_current = 0; 699 700 qsort(ala_array, area_count, sizeof(struct a_line_area), cmpr); 701 702 /* Now we must rearrange the pieces of the line table. */ 703 704 start_len = 705 (prefix.pf_line_prologue_start + 706 prefix.pf_prologue_length) - orig_line_ptr; 707 new_area = malloc(remaining_bytes); 708 if (!new_area) { 709 free(ala_array); 710 *err_code = DW_DLE_ALLOC_FAIL; 711 dwarf_free_line_table_prefix(&prefix); 712 return DW_DLV_ERROR; 713 } 714 memcpy(new_area, orig_line_ptr, start_len); 715 line_ptr = new_area + start_len; 716 for (i = 0; i < area_count; ++i) { 717 memcpy(line_ptr, orig_line_ptr + 718 ala_array[i].ala_offset, ala_array[i].ala_length); 719 line_ptr += ala_array[i].ala_length; 720 } 721 722 memcpy(orig_line_ptr, new_area, remaining_bytes); 723 724 free(new_area); 725 free(ala_array); 726 ala_array = 0; 727 new_area = 0; 728 } 729 730 *any_change = 1; 731 dwarf_free_line_table_prefix(&prefix); 732 return (DW_DLV_OK); 733 } 734