1/* 2 3 Copyright (C) 2000,2002,2004,2005,2006 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., 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 36 37 38#include "config.h" 39#include "dwarf_incl.h" 40#include <stdio.h> 41#include <time.h> 42#include "dwarf_line.h" 43#ifdef HAVE_ALLOCA_H 44#include <alloca.h> 45#endif 46 47/* FIXME Need to add prologue_end epilogue_begin isa fields. */ 48static void 49print_line_header(void) 50{ 51 printf 52 (" s b e\n" 53 " t l s\n" 54 " m c e\n" 55 " section op col t k q\n" 56 " offset code address file line umn ? ? ?\n"); 57} 58 59/* FIXME: print new line values: prologue_end epilogue_begin isa */ 60static void 61print_line_detail(char *prefix, 62 int opcode, 63 unsigned long long address, 64 unsigned long file, 65 unsigned long line, 66 unsigned long column, 67 int is_stmt, int basic_block, int end_sequence, 68 int prologue_end, int epilogue_begin, int isa) 69{ 70 printf("%-15s %2d 0x%08llx " 71 "%2lu %4lu %2lu %1d %1d %1d\n", 72 prefix, 73 (int) opcode, 74 (long long) address, 75 (unsigned long) file, 76 (unsigned long) line, 77 (unsigned long) column, 78 (int) is_stmt, (int) basic_block, (int) end_sequence); 79 80} 81 82 83/* 84 return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR 85*/ 86int 87_dwarf_internal_printlines(Dwarf_Die die, Dwarf_Error * error) 88{ 89 /* 90 This pointer is used to scan the portion of the .debug_line 91 section for the current cu. */ 92 Dwarf_Small *line_ptr; 93 Dwarf_Small *orig_line_ptr; 94 95 /* 96 This points to the last byte of the .debug_line portion for the 97 current cu. */ 98 Dwarf_Small *line_ptr_end = 0; 99 100 /* 101 Pointer to a DW_AT_stmt_list attribute in case it exists in the 102 die. */ 103 Dwarf_Attribute stmt_list_attr; 104 105 /* Pointer to DW_AT_comp_dir attribute in die. */ 106 Dwarf_Attribute comp_dir_attr; 107 108 /* Pointer to name of compilation directory. */ 109 Dwarf_Small *comp_dir = NULL; 110 111 /* 112 Offset into .debug_line specified by a DW_AT_stmt_list 113 attribute. */ 114 Dwarf_Unsigned line_offset; 115 116 struct Line_Table_Prefix_s prefix; 117 118 119 /* These are the state machine state variables. */ 120 Dwarf_Addr address = 0; 121 Dwarf_Word file = 1; 122 Dwarf_Word line = 1; 123 Dwarf_Word column = 0; 124 Dwarf_Bool is_stmt = false; 125 Dwarf_Bool basic_block = false; 126 Dwarf_Bool end_sequence = false; 127 Dwarf_Bool prologue_end = false; 128 Dwarf_Bool epilogue_begin = false; 129 Dwarf_Small isa = 0; 130 131 132 Dwarf_Sword i; 133 134 /* 135 This is the current opcode read from the statement program. */ 136 Dwarf_Small opcode; 137 138 139 /* 140 These variables are used to decode leb128 numbers. Leb128_num 141 holds the decoded number, and leb128_length is its length in 142 bytes. */ 143 Dwarf_Word leb128_num; 144 Dwarf_Word leb128_length; 145 Dwarf_Sword advance_line; 146 147 /* 148 This is the operand of the latest fixed_advance_pc extended 149 opcode. */ 150 Dwarf_Half fixed_advance_pc; 151 152 153 /*REFERENCED*/ /* Not used in this instance of the 154 macro */ 155 int local_extension_size; 156 157 /* The Dwarf_Debug this die belongs to. */ 158 Dwarf_Debug dbg; 159 int resattr; 160 int lres; 161 162 int res; 163 164 /* ***** BEGIN CODE ***** */ 165 166 if (error != NULL) 167 *error = NULL; 168 169 CHECK_DIE(die, DW_DLV_ERROR) 170 dbg = die->di_cu_context->cc_dbg; 171 172 res = 173 _dwarf_load_section(dbg, 174 dbg->de_debug_line_index, 175 &dbg->de_debug_line, error); 176 if (res != DW_DLV_OK) { 177 return res; 178 } 179 180 resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error); 181 if (resattr != DW_DLV_OK) { 182 return resattr; 183 } 184 185 186 187 lres = dwarf_formudata(stmt_list_attr, &line_offset, error); 188 if (lres != DW_DLV_OK) { 189 return lres; 190 } 191 192 if (line_offset >= dbg->de_debug_line_size) { 193 _dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD); 194 return (DW_DLV_ERROR); 195 } 196 orig_line_ptr = dbg->de_debug_line; 197 line_ptr = dbg->de_debug_line + line_offset; 198 dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR); 199 200 /* 201 If die has DW_AT_comp_dir attribute, get the string that names 202 the compilation directory. */ 203 resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error); 204 if (resattr == DW_DLV_ERROR) { 205 return resattr; 206 } 207 if (resattr == DW_DLV_OK) { 208 int cres; 209 char *cdir; 210 211 cres = dwarf_formstring(comp_dir_attr, &cdir, error); 212 if (cres == DW_DLV_ERROR) { 213 return cres; 214 } else if (cres == DW_DLV_OK) { 215 comp_dir = (Dwarf_Small *) cdir; 216 } 217 } 218 if (resattr == DW_DLV_OK) { 219 dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR); 220 } 221 222 dwarf_init_line_table_prefix(&prefix); 223 { 224 Dwarf_Small *line_ptr_out = 0; 225 int dres = dwarf_read_line_table_prefix(dbg, 226 line_ptr, 227 dbg-> 228 de_debug_line_size - 229 line_offset, 230 &line_ptr_out, 231 &prefix, error); 232 233 if (dres == DW_DLV_ERROR) { 234 dwarf_free_line_table_prefix(&prefix); 235 return dres; 236 } 237 if (dres == DW_DLV_NO_ENTRY) { 238 dwarf_free_line_table_prefix(&prefix); 239 return dres; 240 } 241 line_ptr_end = prefix.pf_line_ptr_end; 242 line_ptr = line_ptr_out; 243 } 244 245 246 247 printf("total line info length %ld bytes, " 248 "line offset 0x%llx %lld\n", 249 (long) prefix.pf_total_length, 250 (long long) line_offset, (long long) line_offset); 251 printf("compilation_directory %s\n", 252 comp_dir ? ((char *) comp_dir) : ""); 253 254 printf(" min instruction length %d\n", 255 (int) prefix.pf_minimum_instruction_length); 256 printf(" default is stmt %d\n", (int) 257 prefix.pf_default_is_stmt); 258 printf(" line base %d\n", (int) 259 prefix.pf_line_base); 260 printf(" line_range %d\n", (int) 261 prefix.pf_line_range); 262 263 264 for (i = 1; i < prefix.pf_opcode_base; i++) { 265 printf(" opcode[%d] length %d\n", (int) i, 266 (int) prefix.pf_opcode_length_table[i - 1]); 267 } 268 269 for (i = 0; i < prefix.pf_include_directories_count; ++i) { 270 printf(" include dir[%d] %s\n", 271 (int) i, prefix.pf_include_directories[i]); 272 } 273 274 275 for (i = 0; i < prefix.pf_files_count; ++i) { 276 struct Line_Table_File_Entry_s *lfile = 277 prefix.pf_line_table_file_entries + i; 278 279 Dwarf_Unsigned tlm2 = lfile->lte_last_modification_time; 280 Dwarf_Unsigned di = lfile->lte_directory_index; 281 Dwarf_Unsigned fl = lfile->lte_length_of_file; 282 283 printf(" file[%d] %s\n", 284 (int) i, (char *) lfile->lte_filename); 285 286 printf(" dir index %d\n", (int) di); 287 { 288 time_t tt = (time_t) tlm2; 289 290 printf(" last time 0x%x %s", /* ctime supplies 291 newline */ 292 (unsigned) tlm2, ctime(&tt)); 293 } 294 printf(" file length %ld 0x%lx\n", 295 (long) fl, (unsigned long) fl); 296 297 298 } 299 300 301 { 302 unsigned long long offset = line_ptr - orig_line_ptr; 303 304 printf(" statement prog offset in section: %llu 0x%llx\n", 305 offset, offset); 306 } 307 308 /* Initialize the part of the state machine dependent on the 309 prefix. */ 310 is_stmt = prefix.pf_default_is_stmt; 311 312 313 print_line_header(); 314 /* Start of statement program. */ 315 while (line_ptr < line_ptr_end) { 316 int type; 317 318 printf(" [0x%06llx] ", (long long) (line_ptr - orig_line_ptr)); 319 opcode = *(Dwarf_Small *) line_ptr; 320 line_ptr++; 321 /* 'type' is the output */ 322 WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base, 323 prefix.pf_opcode_length_table, line_ptr, 324 prefix.pf_std_op_count); 325 326 if (type == LOP_DISCARD) { 327 int oc; 328 int opcnt = prefix.pf_opcode_length_table[opcode]; 329 330 printf(" DISCARD standard opcode %d with %d operands: " 331 "not understood:", opcode, opcnt); 332 for (oc = 0; oc < opcnt; oc++) { 333 /* 334 * Read and discard operands we don't 335 * understand. 336 * Arbitrary choice of unsigned read. 337 * Signed read would work as well. 338 */ 339 Dwarf_Unsigned utmp2; 340 341 DECODE_LEB128_UWORD(line_ptr, utmp2) 342 printf(" %llu (0x%llx)", 343 (unsigned long long) utmp2, 344 (unsigned long long) utmp2); 345 } 346 347 printf("\n"); 348 /* do nothing, necessary ops done */ 349 } else if (type == LOP_SPECIAL) { 350 /* This op code is a special op in the object, no matter 351 that it might fall into the standard op range in this 352 compile Thatis, these are special opcodes between 353 special_opcode_base and MAX_LINE_OP_CODE. (including 354 special_opcode_base and MAX_LINE_OP_CODE) */ 355 char special[50]; 356 unsigned origop = opcode; 357 358 opcode = opcode - prefix.pf_opcode_base; 359 address = address + prefix.pf_minimum_instruction_length * 360 (opcode / prefix.pf_line_range); 361 line = 362 line + prefix.pf_line_base + 363 opcode % prefix.pf_line_range; 364 365 sprintf(special, "Specialop %3u", origop); 366 print_line_detail(special, 367 opcode, address, (int) file, line, column, 368 is_stmt, basic_block, end_sequence, 369 prologue_end, epilogue_begin, isa); 370 371 basic_block = false; 372 373 } else if (type == LOP_STANDARD) { 374 switch (opcode) { 375 376 case DW_LNS_copy:{ 377 378 print_line_detail("DW_LNS_copy", 379 opcode, address, file, line, 380 column, is_stmt, basic_block, 381 end_sequence, prologue_end, 382 epilogue_begin, isa); 383 384 basic_block = false; 385 break; 386 } 387 388 case DW_LNS_advance_pc:{ 389 Dwarf_Unsigned utmp2; 390 391 392 DECODE_LEB128_UWORD(line_ptr, utmp2) 393 printf("DW_LNS_advance_pc val %lld 0x%llx\n", 394 (long long) (Dwarf_Word) utmp2, 395 (long long) (Dwarf_Word) utmp2); 396 leb128_num = (Dwarf_Word) utmp2; 397 address = 398 address + 399 prefix.pf_minimum_instruction_length * 400 leb128_num; 401 break; 402 } 403 404 case DW_LNS_advance_line:{ 405 Dwarf_Signed stmp; 406 407 408 DECODE_LEB128_SWORD(line_ptr, stmp) 409 advance_line = (Dwarf_Sword) stmp; 410 printf("DW_LNS_advance_line val %lld 0x%llx\n", 411 (long long) advance_line, 412 (long long) advance_line); 413 line = line + advance_line; 414 break; 415 } 416 417 case DW_LNS_set_file:{ 418 Dwarf_Unsigned utmp2; 419 420 421 DECODE_LEB128_UWORD(line_ptr, utmp2) 422 file = (Dwarf_Word) utmp2; 423 printf("DW_LNS_set_file %ld\n", (long) file); 424 break; 425 } 426 427 case DW_LNS_set_column:{ 428 Dwarf_Unsigned utmp2; 429 430 431 DECODE_LEB128_UWORD(line_ptr, utmp2) 432 column = (Dwarf_Word) utmp2; 433 printf("DW_LNS_set_column val %lld 0x%llx\n", 434 (long long) column, (long long) column); 435 break; 436 } 437 438 case DW_LNS_negate_stmt:{ 439 is_stmt = !is_stmt; 440 printf("DW_LNS_negate_stmt\n"); 441 break; 442 } 443 444 case DW_LNS_set_basic_block:{ 445 446 printf("DW_LNS_set_basic_block\n"); 447 basic_block = true; 448 break; 449 } 450 451 case DW_LNS_const_add_pc:{ 452 opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base; 453 address = 454 address + 455 prefix.pf_minimum_instruction_length * (opcode / 456 prefix. 457 pf_line_range); 458 459 printf("DW_LNS_const_add_pc new address 0x%llx\n", 460 (long long) address); 461 break; 462 } 463 464 case DW_LNS_fixed_advance_pc:{ 465 466 READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half, 467 line_ptr, sizeof(Dwarf_Half)); 468 line_ptr += sizeof(Dwarf_Half); 469 address = address + fixed_advance_pc; 470 printf("DW_LNS_fixed_advance_pc val %lld 0x%llx" 471 " new address 0x%llx\n", 472 (long long) fixed_advance_pc, 473 (long long) fixed_advance_pc, 474 (long long) address); 475 break; 476 } 477 case DW_LNS_set_prologue_end:{ 478 479 prologue_end = true; 480 printf("DW_LNS_set_prologue_end set true.\n"); 481 break; 482 483 484 } 485 /* New in DWARF3 */ 486 case DW_LNS_set_epilogue_begin:{ 487 epilogue_begin = true; 488 printf("DW_LNS_set_epilogue_begin set true.\n"); 489 break; 490 } 491 492 /* New in DWARF3 */ 493 case DW_LNS_set_isa:{ 494 Dwarf_Unsigned utmp2; 495 496 DECODE_LEB128_UWORD(line_ptr, utmp2) 497 isa = utmp2; 498 printf("DW_LNS_set_isa new value 0x%llx.\n", 499 (unsigned long long) utmp2); 500 if (isa != utmp2) { 501 /* The value of the isa did not fit in our 502 local so we record it wrong. declare an 503 error. */ 504 dwarf_free_line_table_prefix(&prefix); 505 506 _dwarf_error(dbg, error, 507 DW_DLE_LINE_NUM_OPERANDS_BAD); 508 return (DW_DLV_ERROR); 509 } 510 break; 511 } 512 } 513 514 515 } else if (type == LOP_EXTENDED) { 516 Dwarf_Unsigned utmp3 = 0; 517 Dwarf_Word instr_length = 0; 518 Dwarf_Small ext_opcode = 0; 519 520 DECODE_LEB128_UWORD(line_ptr, utmp3) 521 instr_length = (Dwarf_Word) utmp3; 522 ext_opcode = *(Dwarf_Small *) line_ptr; 523 line_ptr++; 524 switch (ext_opcode) { 525 526 case DW_LNE_end_sequence:{ 527 end_sequence = true; 528 529 print_line_detail("DW_LNE_end_sequence extended", 530 opcode, address, file, line, 531 column, is_stmt, basic_block, 532 end_sequence, prologue_end, 533 epilogue_begin, isa); 534 535 address = 0; 536 file = 1; 537 line = 1; 538 column = 0; 539 is_stmt = prefix.pf_default_is_stmt; 540 basic_block = false; 541 end_sequence = false; 542 prologue_end = false; 543 epilogue_begin = false; 544 545 546 break; 547 } 548 549 case DW_LNE_set_address:{ 550 if (instr_length - 1 == dbg->de_pointer_size) { 551 READ_UNALIGNED(dbg, address, Dwarf_Addr, 552 line_ptr, dbg->de_pointer_size); 553 554 line_ptr += dbg->de_pointer_size; 555 printf("DW_LNE_set_address address 0x%llx\n", 556 (long long) address); 557 } else { 558 dwarf_free_line_table_prefix(&prefix); 559 _dwarf_error(dbg, error, 560 DW_DLE_LINE_SET_ADDR_ERROR); 561 return (DW_DLV_ERROR); 562 } 563 564 break; 565 } 566 567 case DW_LNE_define_file:{ 568 569 570 Dwarf_Small *fn; 571 Dwarf_Unsigned di; 572 Dwarf_Unsigned tlm; 573 Dwarf_Unsigned fl; 574 575 fn = (Dwarf_Small *) line_ptr; 576 line_ptr = line_ptr + strlen((char *) line_ptr) + 1; 577 578 di = _dwarf_decode_u_leb128(line_ptr, 579 &leb128_length); 580 line_ptr = line_ptr + leb128_length; 581 582 tlm = _dwarf_decode_u_leb128(line_ptr, 583 &leb128_length); 584 line_ptr = line_ptr + leb128_length; 585 586 fl = _dwarf_decode_u_leb128(line_ptr, 587 &leb128_length); 588 line_ptr = line_ptr + leb128_length; 589 590 591 printf("DW_LNE_define_file %s \n", fn); 592 printf(" dir index %d\n", (int) di); 593 { 594 time_t tt3 = (time_t) tlm; 595 596 /* ctime supplies newline */ 597 printf(" last time 0x%x %s", 598 (unsigned) tlm, ctime(&tt3)); 599 } 600 printf(" file length %ld 0x%lx\n", 601 (long) fl, (unsigned long) fl); 602 603 break; 604 } 605 606 default:{ 607 dwarf_free_line_table_prefix(&prefix); 608 _dwarf_error(dbg, error, 609 DW_DLE_LINE_EXT_OPCODE_BAD); 610 return (DW_DLV_ERROR); 611 } 612 } 613 614 } 615 } 616 617 dwarf_free_line_table_prefix(&prefix); 618 return (DW_DLV_OK); 619} 620 621/* 622 Caller passes in compilation unit DIE. 623*/ 624int 625_dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error) 626{ 627 int res; 628 629 res = _dwarf_internal_printlines(die, error); 630 if (res != DW_DLV_OK) { 631 return res; 632 } 633 return res; 634} 635