1214082Sdim/* dwarf.c -- display DWARF contents of a BFD binary file 2214634Sdim Copyright 2005, 2006, 2007 3214082Sdim Free Software Foundation, Inc. 4214082Sdim 5214082Sdim This file is part of GNU Binutils. 6214082Sdim 7214082Sdim This program is free software; you can redistribute it and/or modify 8214082Sdim it under the terms of the GNU General Public License as published by 9214082Sdim the Free Software Foundation; either version 2 of the License, or 10214082Sdim (at your option) any later version. 11214082Sdim 12214082Sdim This program is distributed in the hope that it will be useful, 13214082Sdim but WITHOUT ANY WARRANTY; without even the implied warranty of 14214082Sdim MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15214082Sdim GNU General Public License for more details. 16214082Sdim 17214082Sdim You should have received a copy of the GNU General Public License 18214082Sdim along with this program; if not, write to the Free Software 19214082Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 20214082Sdim 02110-1301, USA. */ 21214082Sdim 22214634Sdim#include "sysdep.h" 23214634Sdim#include "libiberty.h" 24214634Sdim#include "bfd.h" 25214634Sdim#include "bucomm.h" 26214634Sdim#include "elf/dwarf2.h" 27214082Sdim#include "dwarf.h" 28214082Sdim 29214082Sdimstatic int have_frame_base; 30214082Sdimstatic int need_base_address; 31214082Sdim 32214082Sdimstatic unsigned int last_pointer_size = 0; 33214082Sdimstatic int warned_about_missing_comp_units = FALSE; 34214082Sdim 35214082Sdimstatic unsigned int num_debug_info_entries = 0; 36214082Sdimstatic debug_info *debug_information = NULL; 37214082Sdim 38214082Sdimdwarf_vma eh_addr_size; 39214082Sdimint is_relocatable; 40214082Sdim 41214082Sdimint do_debug_info; 42214082Sdimint do_debug_abbrevs; 43214082Sdimint do_debug_lines; 44214082Sdimint do_debug_pubnames; 45214082Sdimint do_debug_aranges; 46214082Sdimint do_debug_ranges; 47214082Sdimint do_debug_frames; 48214082Sdimint do_debug_frames_interp; 49214082Sdimint do_debug_macinfo; 50214082Sdimint do_debug_str; 51214082Sdimint do_debug_loc; 52214082Sdim 53214082Sdimdwarf_vma (*byte_get) (unsigned char *, int); 54214082Sdim 55214082Sdimdwarf_vma 56214082Sdimbyte_get_little_endian (unsigned char *field, int size) 57214082Sdim{ 58214082Sdim switch (size) 59214082Sdim { 60214082Sdim case 1: 61214082Sdim return *field; 62214082Sdim 63214082Sdim case 2: 64214082Sdim return ((unsigned int) (field[0])) 65214082Sdim | (((unsigned int) (field[1])) << 8); 66214082Sdim 67214082Sdim case 4: 68214082Sdim return ((unsigned long) (field[0])) 69214082Sdim | (((unsigned long) (field[1])) << 8) 70214082Sdim | (((unsigned long) (field[2])) << 16) 71214082Sdim | (((unsigned long) (field[3])) << 24); 72214082Sdim 73214082Sdim case 8: 74214082Sdim if (sizeof (dwarf_vma) == 8) 75214082Sdim return ((dwarf_vma) (field[0])) 76214082Sdim | (((dwarf_vma) (field[1])) << 8) 77214082Sdim | (((dwarf_vma) (field[2])) << 16) 78214082Sdim | (((dwarf_vma) (field[3])) << 24) 79214082Sdim | (((dwarf_vma) (field[4])) << 32) 80214082Sdim | (((dwarf_vma) (field[5])) << 40) 81214082Sdim | (((dwarf_vma) (field[6])) << 48) 82214082Sdim | (((dwarf_vma) (field[7])) << 56); 83214082Sdim else if (sizeof (dwarf_vma) == 4) 84214082Sdim /* We want to extract data from an 8 byte wide field and 85214082Sdim place it into a 4 byte wide field. Since this is a little 86214082Sdim endian source we can just use the 4 byte extraction code. */ 87214082Sdim return ((unsigned long) (field[0])) 88214082Sdim | (((unsigned long) (field[1])) << 8) 89214082Sdim | (((unsigned long) (field[2])) << 16) 90214082Sdim | (((unsigned long) (field[3])) << 24); 91214082Sdim 92214082Sdim default: 93214082Sdim error (_("Unhandled data length: %d\n"), size); 94214082Sdim abort (); 95214082Sdim } 96214082Sdim} 97214082Sdim 98214082Sdimdwarf_vma 99214082Sdimbyte_get_big_endian (unsigned char *field, int size) 100214082Sdim{ 101214082Sdim switch (size) 102214082Sdim { 103214082Sdim case 1: 104214082Sdim return *field; 105214082Sdim 106214082Sdim case 2: 107214082Sdim return ((unsigned int) (field[1])) | (((int) (field[0])) << 8); 108214082Sdim 109214082Sdim case 4: 110214082Sdim return ((unsigned long) (field[3])) 111214082Sdim | (((unsigned long) (field[2])) << 8) 112214082Sdim | (((unsigned long) (field[1])) << 16) 113214082Sdim | (((unsigned long) (field[0])) << 24); 114214082Sdim 115214082Sdim case 8: 116214082Sdim if (sizeof (dwarf_vma) == 8) 117214082Sdim return ((dwarf_vma) (field[7])) 118214082Sdim | (((dwarf_vma) (field[6])) << 8) 119214082Sdim | (((dwarf_vma) (field[5])) << 16) 120214082Sdim | (((dwarf_vma) (field[4])) << 24) 121214082Sdim | (((dwarf_vma) (field[3])) << 32) 122214082Sdim | (((dwarf_vma) (field[2])) << 40) 123214082Sdim | (((dwarf_vma) (field[1])) << 48) 124214082Sdim | (((dwarf_vma) (field[0])) << 56); 125214082Sdim else if (sizeof (dwarf_vma) == 4) 126214082Sdim { 127214082Sdim /* Although we are extracing data from an 8 byte wide field, 128214082Sdim we are returning only 4 bytes of data. */ 129214082Sdim field += 4; 130214082Sdim return ((unsigned long) (field[3])) 131214082Sdim | (((unsigned long) (field[2])) << 8) 132214082Sdim | (((unsigned long) (field[1])) << 16) 133214082Sdim | (((unsigned long) (field[0])) << 24); 134214082Sdim } 135214082Sdim 136214082Sdim default: 137214082Sdim error (_("Unhandled data length: %d\n"), size); 138214082Sdim abort (); 139214082Sdim } 140214082Sdim} 141214082Sdim 142214082Sdimstatic dwarf_vma 143214082Sdimbyte_get_signed (unsigned char *field, int size) 144214082Sdim{ 145214082Sdim dwarf_vma x = byte_get (field, size); 146214082Sdim 147214082Sdim switch (size) 148214082Sdim { 149214082Sdim case 1: 150214082Sdim return (x ^ 0x80) - 0x80; 151214082Sdim case 2: 152214082Sdim return (x ^ 0x8000) - 0x8000; 153214082Sdim case 4: 154214082Sdim return (x ^ 0x80000000) - 0x80000000; 155214082Sdim case 8: 156214082Sdim return x; 157214082Sdim default: 158214082Sdim abort (); 159214082Sdim } 160214082Sdim} 161214082Sdim 162214082Sdimstatic unsigned long int 163214082Sdimread_leb128 (unsigned char *data, unsigned int *length_return, int sign) 164214082Sdim{ 165214082Sdim unsigned long int result = 0; 166214082Sdim unsigned int num_read = 0; 167214082Sdim unsigned int shift = 0; 168214082Sdim unsigned char byte; 169214082Sdim 170214082Sdim do 171214082Sdim { 172214082Sdim byte = *data++; 173214082Sdim num_read++; 174214082Sdim 175214082Sdim result |= ((unsigned long int) (byte & 0x7f)) << shift; 176214082Sdim 177214082Sdim shift += 7; 178214082Sdim 179214082Sdim } 180214082Sdim while (byte & 0x80); 181214082Sdim 182214082Sdim if (length_return != NULL) 183214082Sdim *length_return = num_read; 184214082Sdim 185214082Sdim if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40)) 186214082Sdim result |= -1L << shift; 187214082Sdim 188214082Sdim return result; 189214082Sdim} 190214082Sdim 191214082Sdimtypedef struct State_Machine_Registers 192214082Sdim{ 193214082Sdim unsigned long address; 194214082Sdim unsigned int file; 195214082Sdim unsigned int line; 196214082Sdim unsigned int column; 197214082Sdim int is_stmt; 198214082Sdim int basic_block; 199214082Sdim int end_sequence; 200214082Sdim/* This variable hold the number of the last entry seen 201214082Sdim in the File Table. */ 202214082Sdim unsigned int last_file_entry; 203214082Sdim} SMR; 204214082Sdim 205214082Sdimstatic SMR state_machine_regs; 206214082Sdim 207214082Sdimstatic void 208214082Sdimreset_state_machine (int is_stmt) 209214082Sdim{ 210214082Sdim state_machine_regs.address = 0; 211214082Sdim state_machine_regs.file = 1; 212214082Sdim state_machine_regs.line = 1; 213214082Sdim state_machine_regs.column = 0; 214214082Sdim state_machine_regs.is_stmt = is_stmt; 215214082Sdim state_machine_regs.basic_block = 0; 216214082Sdim state_machine_regs.end_sequence = 0; 217214082Sdim state_machine_regs.last_file_entry = 0; 218214082Sdim} 219214082Sdim 220214082Sdim/* Handled an extend line op. 221214082Sdim Returns the number of bytes read. */ 222214082Sdim 223214082Sdimstatic int 224214082Sdimprocess_extended_line_op (unsigned char *data, int is_stmt) 225214082Sdim{ 226214082Sdim unsigned char op_code; 227214082Sdim unsigned int bytes_read; 228214082Sdim unsigned int len; 229214082Sdim unsigned char *name; 230214082Sdim unsigned long adr; 231214082Sdim 232214082Sdim len = read_leb128 (data, & bytes_read, 0); 233214082Sdim data += bytes_read; 234214082Sdim 235214082Sdim if (len == 0) 236214082Sdim { 237214082Sdim warn (_("badly formed extended line op encountered!\n")); 238214082Sdim return bytes_read; 239214082Sdim } 240214082Sdim 241214082Sdim len += bytes_read; 242214082Sdim op_code = *data++; 243214082Sdim 244214082Sdim printf (_(" Extended opcode %d: "), op_code); 245214082Sdim 246214082Sdim switch (op_code) 247214082Sdim { 248214082Sdim case DW_LNE_end_sequence: 249214082Sdim printf (_("End of Sequence\n\n")); 250214082Sdim reset_state_machine (is_stmt); 251214082Sdim break; 252214082Sdim 253214082Sdim case DW_LNE_set_address: 254214082Sdim adr = byte_get (data, len - bytes_read - 1); 255214082Sdim printf (_("set Address to 0x%lx\n"), adr); 256214082Sdim state_machine_regs.address = adr; 257214082Sdim break; 258214082Sdim 259214082Sdim case DW_LNE_define_file: 260214082Sdim printf (_(" define new File Table entry\n")); 261214082Sdim printf (_(" Entry\tDir\tTime\tSize\tName\n")); 262214082Sdim 263214082Sdim printf (_(" %d\t"), ++state_machine_regs.last_file_entry); 264214082Sdim name = data; 265214082Sdim data += strlen ((char *) data) + 1; 266214082Sdim printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0)); 267214082Sdim data += bytes_read; 268214082Sdim printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0)); 269214082Sdim data += bytes_read; 270214082Sdim printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0)); 271214082Sdim printf (_("%s\n\n"), name); 272214082Sdim break; 273214082Sdim 274214082Sdim default: 275214082Sdim printf (_("UNKNOWN: length %d\n"), len - bytes_read); 276214082Sdim break; 277214082Sdim } 278214082Sdim 279214082Sdim return len; 280214082Sdim} 281214082Sdim 282214082Sdimstatic const char * 283214082Sdimfetch_indirect_string (unsigned long offset) 284214082Sdim{ 285214082Sdim struct dwarf_section *section = &debug_displays [str].section; 286214082Sdim 287214082Sdim if (section->start == NULL) 288214082Sdim return _("<no .debug_str section>"); 289214082Sdim 290214082Sdim /* DWARF sections under Mach-O have non-zero addresses. */ 291214082Sdim offset -= section->address; 292214082Sdim if (offset > section->size) 293214082Sdim { 294214082Sdim warn (_("DW_FORM_strp offset too big: %lx\n"), offset); 295214082Sdim return _("<offset is too big>"); 296214082Sdim } 297214082Sdim 298214082Sdim return (const char *) section->start + offset; 299214082Sdim} 300214082Sdim 301214082Sdim/* FIXME: There are better and more efficient ways to handle 302214082Sdim these structures. For now though, I just want something that 303214082Sdim is simple to implement. */ 304214082Sdimtypedef struct abbrev_attr 305214082Sdim{ 306214082Sdim unsigned long attribute; 307214082Sdim unsigned long form; 308214082Sdim struct abbrev_attr *next; 309214082Sdim} 310214082Sdimabbrev_attr; 311214082Sdim 312214082Sdimtypedef struct abbrev_entry 313214082Sdim{ 314214082Sdim unsigned long entry; 315214082Sdim unsigned long tag; 316214082Sdim int children; 317214082Sdim struct abbrev_attr *first_attr; 318214082Sdim struct abbrev_attr *last_attr; 319214082Sdim struct abbrev_entry *next; 320214082Sdim} 321214082Sdimabbrev_entry; 322214082Sdim 323214082Sdimstatic abbrev_entry *first_abbrev = NULL; 324214082Sdimstatic abbrev_entry *last_abbrev = NULL; 325214082Sdim 326214082Sdimstatic void 327214082Sdimfree_abbrevs (void) 328214082Sdim{ 329214082Sdim abbrev_entry *abbrev; 330214082Sdim 331214082Sdim for (abbrev = first_abbrev; abbrev;) 332214082Sdim { 333214082Sdim abbrev_entry *next = abbrev->next; 334214082Sdim abbrev_attr *attr; 335214082Sdim 336214082Sdim for (attr = abbrev->first_attr; attr;) 337214082Sdim { 338214082Sdim abbrev_attr *next = attr->next; 339214082Sdim 340214082Sdim free (attr); 341214082Sdim attr = next; 342214082Sdim } 343214082Sdim 344214082Sdim free (abbrev); 345214082Sdim abbrev = next; 346214082Sdim } 347214082Sdim 348214082Sdim last_abbrev = first_abbrev = NULL; 349214082Sdim} 350214082Sdim 351214082Sdimstatic void 352214082Sdimadd_abbrev (unsigned long number, unsigned long tag, int children) 353214082Sdim{ 354214082Sdim abbrev_entry *entry; 355214082Sdim 356214082Sdim entry = malloc (sizeof (*entry)); 357214082Sdim 358214082Sdim if (entry == NULL) 359214082Sdim /* ugg */ 360214082Sdim return; 361214082Sdim 362214082Sdim entry->entry = number; 363214082Sdim entry->tag = tag; 364214082Sdim entry->children = children; 365214082Sdim entry->first_attr = NULL; 366214082Sdim entry->last_attr = NULL; 367214082Sdim entry->next = NULL; 368214082Sdim 369214082Sdim if (first_abbrev == NULL) 370214082Sdim first_abbrev = entry; 371214082Sdim else 372214082Sdim last_abbrev->next = entry; 373214082Sdim 374214082Sdim last_abbrev = entry; 375214082Sdim} 376214082Sdim 377214082Sdimstatic void 378214082Sdimadd_abbrev_attr (unsigned long attribute, unsigned long form) 379214082Sdim{ 380214082Sdim abbrev_attr *attr; 381214082Sdim 382214082Sdim attr = malloc (sizeof (*attr)); 383214082Sdim 384214082Sdim if (attr == NULL) 385214082Sdim /* ugg */ 386214082Sdim return; 387214082Sdim 388214082Sdim attr->attribute = attribute; 389214082Sdim attr->form = form; 390214082Sdim attr->next = NULL; 391214082Sdim 392214082Sdim if (last_abbrev->first_attr == NULL) 393214082Sdim last_abbrev->first_attr = attr; 394214082Sdim else 395214082Sdim last_abbrev->last_attr->next = attr; 396214082Sdim 397214082Sdim last_abbrev->last_attr = attr; 398214082Sdim} 399214082Sdim 400214082Sdim/* Processes the (partial) contents of a .debug_abbrev section. 401214082Sdim Returns NULL if the end of the section was encountered. 402214082Sdim Returns the address after the last byte read if the end of 403214082Sdim an abbreviation set was found. */ 404214082Sdim 405214082Sdimstatic unsigned char * 406214082Sdimprocess_abbrev_section (unsigned char *start, unsigned char *end) 407214082Sdim{ 408214082Sdim if (first_abbrev != NULL) 409214082Sdim return NULL; 410214082Sdim 411214082Sdim while (start < end) 412214082Sdim { 413214082Sdim unsigned int bytes_read; 414214082Sdim unsigned long entry; 415214082Sdim unsigned long tag; 416214082Sdim unsigned long attribute; 417214082Sdim int children; 418214082Sdim 419214082Sdim entry = read_leb128 (start, & bytes_read, 0); 420214082Sdim start += bytes_read; 421214082Sdim 422214082Sdim /* A single zero is supposed to end the section according 423214082Sdim to the standard. If there's more, then signal that to 424214082Sdim the caller. */ 425214082Sdim if (entry == 0) 426214082Sdim return start == end ? NULL : start; 427214082Sdim 428214082Sdim tag = read_leb128 (start, & bytes_read, 0); 429214082Sdim start += bytes_read; 430214082Sdim 431214082Sdim children = *start++; 432214082Sdim 433214082Sdim add_abbrev (entry, tag, children); 434214082Sdim 435214082Sdim do 436214082Sdim { 437214082Sdim unsigned long form; 438214082Sdim 439214082Sdim attribute = read_leb128 (start, & bytes_read, 0); 440214082Sdim start += bytes_read; 441214082Sdim 442214082Sdim form = read_leb128 (start, & bytes_read, 0); 443214082Sdim start += bytes_read; 444214082Sdim 445214082Sdim if (attribute != 0) 446214082Sdim add_abbrev_attr (attribute, form); 447214082Sdim } 448214082Sdim while (attribute != 0); 449214082Sdim } 450214082Sdim 451214082Sdim return NULL; 452214082Sdim} 453214082Sdim 454214082Sdimstatic char * 455214082Sdimget_TAG_name (unsigned long tag) 456214082Sdim{ 457214082Sdim switch (tag) 458214082Sdim { 459214082Sdim case DW_TAG_padding: return "DW_TAG_padding"; 460214082Sdim case DW_TAG_array_type: return "DW_TAG_array_type"; 461214082Sdim case DW_TAG_class_type: return "DW_TAG_class_type"; 462214082Sdim case DW_TAG_entry_point: return "DW_TAG_entry_point"; 463214082Sdim case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type"; 464214082Sdim case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter"; 465214082Sdim case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration"; 466214082Sdim case DW_TAG_label: return "DW_TAG_label"; 467214082Sdim case DW_TAG_lexical_block: return "DW_TAG_lexical_block"; 468214082Sdim case DW_TAG_member: return "DW_TAG_member"; 469214082Sdim case DW_TAG_pointer_type: return "DW_TAG_pointer_type"; 470214082Sdim case DW_TAG_reference_type: return "DW_TAG_reference_type"; 471214082Sdim case DW_TAG_compile_unit: return "DW_TAG_compile_unit"; 472214082Sdim case DW_TAG_string_type: return "DW_TAG_string_type"; 473214082Sdim case DW_TAG_structure_type: return "DW_TAG_structure_type"; 474214082Sdim case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type"; 475214082Sdim case DW_TAG_typedef: return "DW_TAG_typedef"; 476214082Sdim case DW_TAG_union_type: return "DW_TAG_union_type"; 477214082Sdim case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters"; 478214082Sdim case DW_TAG_variant: return "DW_TAG_variant"; 479214082Sdim case DW_TAG_common_block: return "DW_TAG_common_block"; 480214082Sdim case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion"; 481214082Sdim case DW_TAG_inheritance: return "DW_TAG_inheritance"; 482214082Sdim case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine"; 483214082Sdim case DW_TAG_module: return "DW_TAG_module"; 484214082Sdim case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type"; 485214082Sdim case DW_TAG_set_type: return "DW_TAG_set_type"; 486214082Sdim case DW_TAG_subrange_type: return "DW_TAG_subrange_type"; 487214082Sdim case DW_TAG_with_stmt: return "DW_TAG_with_stmt"; 488214082Sdim case DW_TAG_access_declaration: return "DW_TAG_access_declaration"; 489214082Sdim case DW_TAG_base_type: return "DW_TAG_base_type"; 490214082Sdim case DW_TAG_catch_block: return "DW_TAG_catch_block"; 491214082Sdim case DW_TAG_const_type: return "DW_TAG_const_type"; 492214082Sdim case DW_TAG_constant: return "DW_TAG_constant"; 493214082Sdim case DW_TAG_enumerator: return "DW_TAG_enumerator"; 494214082Sdim case DW_TAG_file_type: return "DW_TAG_file_type"; 495214082Sdim case DW_TAG_friend: return "DW_TAG_friend"; 496214082Sdim case DW_TAG_namelist: return "DW_TAG_namelist"; 497214082Sdim case DW_TAG_namelist_item: return "DW_TAG_namelist_item"; 498214082Sdim case DW_TAG_packed_type: return "DW_TAG_packed_type"; 499214082Sdim case DW_TAG_subprogram: return "DW_TAG_subprogram"; 500214082Sdim case DW_TAG_template_type_param: return "DW_TAG_template_type_param"; 501214082Sdim case DW_TAG_template_value_param: return "DW_TAG_template_value_param"; 502214082Sdim case DW_TAG_thrown_type: return "DW_TAG_thrown_type"; 503214082Sdim case DW_TAG_try_block: return "DW_TAG_try_block"; 504214082Sdim case DW_TAG_variant_part: return "DW_TAG_variant_part"; 505214082Sdim case DW_TAG_variable: return "DW_TAG_variable"; 506214082Sdim case DW_TAG_volatile_type: return "DW_TAG_volatile_type"; 507214082Sdim case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop"; 508214082Sdim case DW_TAG_format_label: return "DW_TAG_format_label"; 509214082Sdim case DW_TAG_function_template: return "DW_TAG_function_template"; 510214082Sdim case DW_TAG_class_template: return "DW_TAG_class_template"; 511214082Sdim /* DWARF 2.1 values. */ 512214082Sdim case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure"; 513214082Sdim case DW_TAG_restrict_type: return "DW_TAG_restrict_type"; 514214082Sdim case DW_TAG_interface_type: return "DW_TAG_interface_type"; 515214082Sdim case DW_TAG_namespace: return "DW_TAG_namespace"; 516214082Sdim case DW_TAG_imported_module: return "DW_TAG_imported_module"; 517214082Sdim case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type"; 518214082Sdim case DW_TAG_partial_unit: return "DW_TAG_partial_unit"; 519214082Sdim case DW_TAG_imported_unit: return "DW_TAG_imported_unit"; 520214082Sdim /* UPC values. */ 521214082Sdim case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type"; 522214082Sdim case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type"; 523214082Sdim case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type"; 524214082Sdim default: 525214082Sdim { 526214082Sdim static char buffer[100]; 527214082Sdim 528214082Sdim snprintf (buffer, sizeof (buffer), _("Unknown TAG value: %lx"), tag); 529214082Sdim return buffer; 530214082Sdim } 531214082Sdim } 532214082Sdim} 533214082Sdim 534214082Sdimstatic char * 535214082Sdimget_FORM_name (unsigned long form) 536214082Sdim{ 537214082Sdim switch (form) 538214082Sdim { 539214082Sdim case DW_FORM_addr: return "DW_FORM_addr"; 540214082Sdim case DW_FORM_block2: return "DW_FORM_block2"; 541214082Sdim case DW_FORM_block4: return "DW_FORM_block4"; 542214082Sdim case DW_FORM_data2: return "DW_FORM_data2"; 543214082Sdim case DW_FORM_data4: return "DW_FORM_data4"; 544214082Sdim case DW_FORM_data8: return "DW_FORM_data8"; 545214082Sdim case DW_FORM_string: return "DW_FORM_string"; 546214082Sdim case DW_FORM_block: return "DW_FORM_block"; 547214082Sdim case DW_FORM_block1: return "DW_FORM_block1"; 548214082Sdim case DW_FORM_data1: return "DW_FORM_data1"; 549214082Sdim case DW_FORM_flag: return "DW_FORM_flag"; 550214082Sdim case DW_FORM_sdata: return "DW_FORM_sdata"; 551214082Sdim case DW_FORM_strp: return "DW_FORM_strp"; 552214082Sdim case DW_FORM_udata: return "DW_FORM_udata"; 553214082Sdim case DW_FORM_ref_addr: return "DW_FORM_ref_addr"; 554214082Sdim case DW_FORM_ref1: return "DW_FORM_ref1"; 555214082Sdim case DW_FORM_ref2: return "DW_FORM_ref2"; 556214082Sdim case DW_FORM_ref4: return "DW_FORM_ref4"; 557214082Sdim case DW_FORM_ref8: return "DW_FORM_ref8"; 558214082Sdim case DW_FORM_ref_udata: return "DW_FORM_ref_udata"; 559214082Sdim case DW_FORM_indirect: return "DW_FORM_indirect"; 560248802Sdim case DW_FORM_flag_present: return "DW_FORM_flag_present"; 561214082Sdim default: 562214082Sdim { 563214082Sdim static char buffer[100]; 564214082Sdim 565214082Sdim snprintf (buffer, sizeof (buffer), _("Unknown FORM value: %lx"), form); 566214082Sdim return buffer; 567214082Sdim } 568214082Sdim } 569214082Sdim} 570214082Sdim 571214082Sdimstatic unsigned char * 572214082Sdimdisplay_block (unsigned char *data, unsigned long length) 573214082Sdim{ 574214082Sdim printf (_(" %lu byte block: "), length); 575214082Sdim 576214082Sdim while (length --) 577214082Sdim printf ("%lx ", (unsigned long) byte_get (data++, 1)); 578214082Sdim 579214082Sdim return data; 580214082Sdim} 581214082Sdim 582214082Sdimstatic int 583214082Sdimdecode_location_expression (unsigned char * data, 584214082Sdim unsigned int pointer_size, 585214082Sdim unsigned long length, 586214082Sdim unsigned long cu_offset) 587214082Sdim{ 588214082Sdim unsigned op; 589214082Sdim unsigned int bytes_read; 590214082Sdim unsigned long uvalue; 591214082Sdim unsigned char *end = data + length; 592214082Sdim int need_frame_base = 0; 593214082Sdim 594214082Sdim while (data < end) 595214082Sdim { 596214082Sdim op = *data++; 597214082Sdim 598214082Sdim switch (op) 599214082Sdim { 600214082Sdim case DW_OP_addr: 601214082Sdim printf ("DW_OP_addr: %lx", 602214082Sdim (unsigned long) byte_get (data, pointer_size)); 603214082Sdim data += pointer_size; 604214082Sdim break; 605214082Sdim case DW_OP_deref: 606214082Sdim printf ("DW_OP_deref"); 607214082Sdim break; 608214082Sdim case DW_OP_const1u: 609214082Sdim printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1)); 610214082Sdim break; 611214082Sdim case DW_OP_const1s: 612214082Sdim printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1)); 613214082Sdim break; 614214082Sdim case DW_OP_const2u: 615214082Sdim printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2)); 616214082Sdim data += 2; 617214082Sdim break; 618214082Sdim case DW_OP_const2s: 619214082Sdim printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2)); 620214082Sdim data += 2; 621214082Sdim break; 622214082Sdim case DW_OP_const4u: 623214082Sdim printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4)); 624214082Sdim data += 4; 625214082Sdim break; 626214082Sdim case DW_OP_const4s: 627214082Sdim printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4)); 628214082Sdim data += 4; 629214082Sdim break; 630214082Sdim case DW_OP_const8u: 631214082Sdim printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4), 632214082Sdim (unsigned long) byte_get (data + 4, 4)); 633214082Sdim data += 8; 634214082Sdim break; 635214082Sdim case DW_OP_const8s: 636214082Sdim printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4), 637214082Sdim (long) byte_get (data + 4, 4)); 638214082Sdim data += 8; 639214082Sdim break; 640214082Sdim case DW_OP_constu: 641214082Sdim printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0)); 642214082Sdim data += bytes_read; 643214082Sdim break; 644214082Sdim case DW_OP_consts: 645214082Sdim printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1)); 646214082Sdim data += bytes_read; 647214082Sdim break; 648214082Sdim case DW_OP_dup: 649214082Sdim printf ("DW_OP_dup"); 650214082Sdim break; 651214082Sdim case DW_OP_drop: 652214082Sdim printf ("DW_OP_drop"); 653214082Sdim break; 654214082Sdim case DW_OP_over: 655214082Sdim printf ("DW_OP_over"); 656214082Sdim break; 657214082Sdim case DW_OP_pick: 658214082Sdim printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1)); 659214082Sdim break; 660214082Sdim case DW_OP_swap: 661214082Sdim printf ("DW_OP_swap"); 662214082Sdim break; 663214082Sdim case DW_OP_rot: 664214082Sdim printf ("DW_OP_rot"); 665214082Sdim break; 666214082Sdim case DW_OP_xderef: 667214082Sdim printf ("DW_OP_xderef"); 668214082Sdim break; 669214082Sdim case DW_OP_abs: 670214082Sdim printf ("DW_OP_abs"); 671214082Sdim break; 672214082Sdim case DW_OP_and: 673214082Sdim printf ("DW_OP_and"); 674214082Sdim break; 675214082Sdim case DW_OP_div: 676214082Sdim printf ("DW_OP_div"); 677214082Sdim break; 678214082Sdim case DW_OP_minus: 679214082Sdim printf ("DW_OP_minus"); 680214082Sdim break; 681214082Sdim case DW_OP_mod: 682214082Sdim printf ("DW_OP_mod"); 683214082Sdim break; 684214082Sdim case DW_OP_mul: 685214082Sdim printf ("DW_OP_mul"); 686214082Sdim break; 687214082Sdim case DW_OP_neg: 688214082Sdim printf ("DW_OP_neg"); 689214082Sdim break; 690214082Sdim case DW_OP_not: 691214082Sdim printf ("DW_OP_not"); 692214082Sdim break; 693214082Sdim case DW_OP_or: 694214082Sdim printf ("DW_OP_or"); 695214082Sdim break; 696214082Sdim case DW_OP_plus: 697214082Sdim printf ("DW_OP_plus"); 698214082Sdim break; 699214082Sdim case DW_OP_plus_uconst: 700214082Sdim printf ("DW_OP_plus_uconst: %lu", 701214082Sdim read_leb128 (data, &bytes_read, 0)); 702214082Sdim data += bytes_read; 703214082Sdim break; 704214082Sdim case DW_OP_shl: 705214082Sdim printf ("DW_OP_shl"); 706214082Sdim break; 707214082Sdim case DW_OP_shr: 708214082Sdim printf ("DW_OP_shr"); 709214082Sdim break; 710214082Sdim case DW_OP_shra: 711214082Sdim printf ("DW_OP_shra"); 712214082Sdim break; 713214082Sdim case DW_OP_xor: 714214082Sdim printf ("DW_OP_xor"); 715214082Sdim break; 716214082Sdim case DW_OP_bra: 717214082Sdim printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2)); 718214082Sdim data += 2; 719214082Sdim break; 720214082Sdim case DW_OP_eq: 721214082Sdim printf ("DW_OP_eq"); 722214082Sdim break; 723214082Sdim case DW_OP_ge: 724214082Sdim printf ("DW_OP_ge"); 725214082Sdim break; 726214082Sdim case DW_OP_gt: 727214082Sdim printf ("DW_OP_gt"); 728214082Sdim break; 729214082Sdim case DW_OP_le: 730214082Sdim printf ("DW_OP_le"); 731214082Sdim break; 732214082Sdim case DW_OP_lt: 733214082Sdim printf ("DW_OP_lt"); 734214082Sdim break; 735214082Sdim case DW_OP_ne: 736214082Sdim printf ("DW_OP_ne"); 737214082Sdim break; 738214082Sdim case DW_OP_skip: 739214082Sdim printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2)); 740214082Sdim data += 2; 741214082Sdim break; 742214082Sdim 743214082Sdim case DW_OP_lit0: 744214082Sdim case DW_OP_lit1: 745214082Sdim case DW_OP_lit2: 746214082Sdim case DW_OP_lit3: 747214082Sdim case DW_OP_lit4: 748214082Sdim case DW_OP_lit5: 749214082Sdim case DW_OP_lit6: 750214082Sdim case DW_OP_lit7: 751214082Sdim case DW_OP_lit8: 752214082Sdim case DW_OP_lit9: 753214082Sdim case DW_OP_lit10: 754214082Sdim case DW_OP_lit11: 755214082Sdim case DW_OP_lit12: 756214082Sdim case DW_OP_lit13: 757214082Sdim case DW_OP_lit14: 758214082Sdim case DW_OP_lit15: 759214082Sdim case DW_OP_lit16: 760214082Sdim case DW_OP_lit17: 761214082Sdim case DW_OP_lit18: 762214082Sdim case DW_OP_lit19: 763214082Sdim case DW_OP_lit20: 764214082Sdim case DW_OP_lit21: 765214082Sdim case DW_OP_lit22: 766214082Sdim case DW_OP_lit23: 767214082Sdim case DW_OP_lit24: 768214082Sdim case DW_OP_lit25: 769214082Sdim case DW_OP_lit26: 770214082Sdim case DW_OP_lit27: 771214082Sdim case DW_OP_lit28: 772214082Sdim case DW_OP_lit29: 773214082Sdim case DW_OP_lit30: 774214082Sdim case DW_OP_lit31: 775214082Sdim printf ("DW_OP_lit%d", op - DW_OP_lit0); 776214082Sdim break; 777214082Sdim 778214082Sdim case DW_OP_reg0: 779214082Sdim case DW_OP_reg1: 780214082Sdim case DW_OP_reg2: 781214082Sdim case DW_OP_reg3: 782214082Sdim case DW_OP_reg4: 783214082Sdim case DW_OP_reg5: 784214082Sdim case DW_OP_reg6: 785214082Sdim case DW_OP_reg7: 786214082Sdim case DW_OP_reg8: 787214082Sdim case DW_OP_reg9: 788214082Sdim case DW_OP_reg10: 789214082Sdim case DW_OP_reg11: 790214082Sdim case DW_OP_reg12: 791214082Sdim case DW_OP_reg13: 792214082Sdim case DW_OP_reg14: 793214082Sdim case DW_OP_reg15: 794214082Sdim case DW_OP_reg16: 795214082Sdim case DW_OP_reg17: 796214082Sdim case DW_OP_reg18: 797214082Sdim case DW_OP_reg19: 798214082Sdim case DW_OP_reg20: 799214082Sdim case DW_OP_reg21: 800214082Sdim case DW_OP_reg22: 801214082Sdim case DW_OP_reg23: 802214082Sdim case DW_OP_reg24: 803214082Sdim case DW_OP_reg25: 804214082Sdim case DW_OP_reg26: 805214082Sdim case DW_OP_reg27: 806214082Sdim case DW_OP_reg28: 807214082Sdim case DW_OP_reg29: 808214082Sdim case DW_OP_reg30: 809214082Sdim case DW_OP_reg31: 810214082Sdim printf ("DW_OP_reg%d", op - DW_OP_reg0); 811214082Sdim break; 812214082Sdim 813214082Sdim case DW_OP_breg0: 814214082Sdim case DW_OP_breg1: 815214082Sdim case DW_OP_breg2: 816214082Sdim case DW_OP_breg3: 817214082Sdim case DW_OP_breg4: 818214082Sdim case DW_OP_breg5: 819214082Sdim case DW_OP_breg6: 820214082Sdim case DW_OP_breg7: 821214082Sdim case DW_OP_breg8: 822214082Sdim case DW_OP_breg9: 823214082Sdim case DW_OP_breg10: 824214082Sdim case DW_OP_breg11: 825214082Sdim case DW_OP_breg12: 826214082Sdim case DW_OP_breg13: 827214082Sdim case DW_OP_breg14: 828214082Sdim case DW_OP_breg15: 829214082Sdim case DW_OP_breg16: 830214082Sdim case DW_OP_breg17: 831214082Sdim case DW_OP_breg18: 832214082Sdim case DW_OP_breg19: 833214082Sdim case DW_OP_breg20: 834214082Sdim case DW_OP_breg21: 835214082Sdim case DW_OP_breg22: 836214082Sdim case DW_OP_breg23: 837214082Sdim case DW_OP_breg24: 838214082Sdim case DW_OP_breg25: 839214082Sdim case DW_OP_breg26: 840214082Sdim case DW_OP_breg27: 841214082Sdim case DW_OP_breg28: 842214082Sdim case DW_OP_breg29: 843214082Sdim case DW_OP_breg30: 844214082Sdim case DW_OP_breg31: 845214082Sdim printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0, 846214082Sdim read_leb128 (data, &bytes_read, 1)); 847214082Sdim data += bytes_read; 848214082Sdim break; 849214082Sdim 850214082Sdim case DW_OP_regx: 851214082Sdim printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0)); 852214082Sdim data += bytes_read; 853214082Sdim break; 854214082Sdim case DW_OP_fbreg: 855214082Sdim need_frame_base = 1; 856214082Sdim printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1)); 857214082Sdim data += bytes_read; 858214082Sdim break; 859214082Sdim case DW_OP_bregx: 860214082Sdim uvalue = read_leb128 (data, &bytes_read, 0); 861214082Sdim data += bytes_read; 862214082Sdim printf ("DW_OP_bregx: %lu %ld", uvalue, 863214082Sdim read_leb128 (data, &bytes_read, 1)); 864214082Sdim data += bytes_read; 865214082Sdim break; 866214082Sdim case DW_OP_piece: 867214082Sdim printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0)); 868214082Sdim data += bytes_read; 869214082Sdim break; 870214082Sdim case DW_OP_deref_size: 871214082Sdim printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1)); 872214082Sdim break; 873214082Sdim case DW_OP_xderef_size: 874214082Sdim printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1)); 875214082Sdim break; 876214082Sdim case DW_OP_nop: 877214082Sdim printf ("DW_OP_nop"); 878214082Sdim break; 879214082Sdim 880214082Sdim /* DWARF 3 extensions. */ 881214082Sdim case DW_OP_push_object_address: 882214082Sdim printf ("DW_OP_push_object_address"); 883214082Sdim break; 884214082Sdim case DW_OP_call2: 885214082Sdim /* XXX: Strictly speaking for 64-bit DWARF3 files 886214082Sdim this ought to be an 8-byte wide computation. */ 887214082Sdim printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2) + cu_offset); 888214082Sdim data += 2; 889214082Sdim break; 890214082Sdim case DW_OP_call4: 891214082Sdim /* XXX: Strictly speaking for 64-bit DWARF3 files 892214082Sdim this ought to be an 8-byte wide computation. */ 893214082Sdim printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4) + cu_offset); 894214082Sdim data += 4; 895214082Sdim break; 896214082Sdim case DW_OP_call_ref: 897214082Sdim printf ("DW_OP_call_ref"); 898214082Sdim break; 899214634Sdim case DW_OP_form_tls_address: 900214634Sdim printf ("DW_OP_form_tls_address"); 901214634Sdim break; 902214082Sdim 903214082Sdim /* GNU extensions. */ 904214082Sdim case DW_OP_GNU_push_tls_address: 905214082Sdim printf ("DW_OP_GNU_push_tls_address"); 906214082Sdim break; 907214082Sdim 908214082Sdim default: 909214082Sdim if (op >= DW_OP_lo_user 910214082Sdim && op <= DW_OP_hi_user) 911214082Sdim printf (_("(User defined location op)")); 912214082Sdim else 913214082Sdim printf (_("(Unknown location op)")); 914214082Sdim /* No way to tell where the next op is, so just bail. */ 915214082Sdim return need_frame_base; 916214082Sdim } 917214082Sdim 918214082Sdim /* Separate the ops. */ 919214082Sdim if (data < end) 920214082Sdim printf ("; "); 921214082Sdim } 922214082Sdim 923214082Sdim return need_frame_base; 924214082Sdim} 925214082Sdim 926214082Sdimstatic unsigned char * 927214082Sdimread_and_display_attr_value (unsigned long attribute, 928214082Sdim unsigned long form, 929214082Sdim unsigned char *data, 930214082Sdim unsigned long cu_offset, 931214082Sdim unsigned long pointer_size, 932214082Sdim unsigned long offset_size, 933214082Sdim int dwarf_version, 934214082Sdim debug_info *debug_info_p, 935214082Sdim int do_loc) 936214082Sdim{ 937214082Sdim unsigned long uvalue = 0; 938214082Sdim unsigned char *block_start = NULL; 939214082Sdim unsigned int bytes_read; 940214082Sdim 941214082Sdim switch (form) 942214082Sdim { 943214082Sdim default: 944214082Sdim break; 945214082Sdim 946214082Sdim case DW_FORM_ref_addr: 947214082Sdim if (dwarf_version == 2) 948214082Sdim { 949214082Sdim uvalue = byte_get (data, pointer_size); 950214082Sdim data += pointer_size; 951214082Sdim } 952214082Sdim else if (dwarf_version == 3) 953214082Sdim { 954214082Sdim uvalue = byte_get (data, offset_size); 955214082Sdim data += offset_size; 956214082Sdim } 957214082Sdim else 958214082Sdim { 959214082Sdim error (_("Internal error: DWARF version is not 2 or 3.\n")); 960214082Sdim } 961214082Sdim break; 962214082Sdim 963214082Sdim case DW_FORM_addr: 964214082Sdim uvalue = byte_get (data, pointer_size); 965214082Sdim data += pointer_size; 966214082Sdim break; 967214082Sdim 968214082Sdim case DW_FORM_strp: 969214082Sdim uvalue = byte_get (data, offset_size); 970214082Sdim data += offset_size; 971214082Sdim break; 972214082Sdim 973248802Sdim case DW_FORM_flag_present: 974248802Sdim uvalue = 1; 975248802Sdim break; 976248802Sdim 977214082Sdim case DW_FORM_ref1: 978214082Sdim case DW_FORM_flag: 979214082Sdim case DW_FORM_data1: 980214082Sdim uvalue = byte_get (data++, 1); 981214082Sdim break; 982214082Sdim 983214082Sdim case DW_FORM_ref2: 984214082Sdim case DW_FORM_data2: 985214082Sdim uvalue = byte_get (data, 2); 986214082Sdim data += 2; 987214082Sdim break; 988214082Sdim 989214082Sdim case DW_FORM_ref4: 990214082Sdim case DW_FORM_data4: 991214082Sdim uvalue = byte_get (data, 4); 992214082Sdim data += 4; 993214082Sdim break; 994214082Sdim 995214082Sdim case DW_FORM_sdata: 996214082Sdim uvalue = read_leb128 (data, & bytes_read, 1); 997214082Sdim data += bytes_read; 998214082Sdim break; 999214082Sdim 1000214082Sdim case DW_FORM_ref_udata: 1001214082Sdim case DW_FORM_udata: 1002214082Sdim uvalue = read_leb128 (data, & bytes_read, 0); 1003214082Sdim data += bytes_read; 1004214082Sdim break; 1005214082Sdim 1006214082Sdim case DW_FORM_indirect: 1007214082Sdim form = read_leb128 (data, & bytes_read, 0); 1008214082Sdim data += bytes_read; 1009214082Sdim if (!do_loc) 1010214082Sdim printf (" %s", get_FORM_name (form)); 1011214082Sdim return read_and_display_attr_value (attribute, form, data, 1012214082Sdim cu_offset, pointer_size, 1013214082Sdim offset_size, dwarf_version, 1014214082Sdim debug_info_p, do_loc); 1015214082Sdim } 1016214082Sdim 1017214082Sdim switch (form) 1018214082Sdim { 1019214082Sdim case DW_FORM_ref_addr: 1020214082Sdim if (!do_loc) 1021214082Sdim printf (" <#%lx>", uvalue); 1022214082Sdim break; 1023214082Sdim 1024214082Sdim case DW_FORM_ref1: 1025214082Sdim case DW_FORM_ref2: 1026214082Sdim case DW_FORM_ref4: 1027214082Sdim case DW_FORM_ref_udata: 1028214082Sdim if (!do_loc) 1029214082Sdim printf (" <%lx>", uvalue + cu_offset); 1030214082Sdim break; 1031214082Sdim 1032214082Sdim case DW_FORM_data4: 1033214082Sdim case DW_FORM_addr: 1034214082Sdim if (!do_loc) 1035214082Sdim printf (" %#lx", uvalue); 1036214082Sdim break; 1037214082Sdim 1038248802Sdim case DW_FORM_flag_present: 1039214082Sdim case DW_FORM_flag: 1040214082Sdim case DW_FORM_data1: 1041214082Sdim case DW_FORM_data2: 1042214082Sdim case DW_FORM_sdata: 1043214082Sdim case DW_FORM_udata: 1044214082Sdim if (!do_loc) 1045214082Sdim printf (" %ld", uvalue); 1046214082Sdim break; 1047214082Sdim 1048214082Sdim case DW_FORM_ref8: 1049214082Sdim case DW_FORM_data8: 1050214082Sdim if (!do_loc) 1051214082Sdim { 1052214082Sdim uvalue = byte_get (data, 4); 1053214082Sdim printf (" %lx", uvalue); 1054214082Sdim printf (" %lx", (unsigned long) byte_get (data + 4, 4)); 1055214082Sdim } 1056214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1057214082Sdim && num_debug_info_entries == 0) 1058214082Sdim { 1059214082Sdim if (sizeof (uvalue) == 8) 1060214082Sdim uvalue = byte_get (data, 8); 1061214082Sdim else 1062214082Sdim error (_("DW_FORM_data8 is unsupported when sizeof (unsigned long) != 8\n")); 1063214082Sdim } 1064214082Sdim data += 8; 1065214082Sdim break; 1066214082Sdim 1067214082Sdim case DW_FORM_string: 1068214082Sdim if (!do_loc) 1069214082Sdim printf (" %s", data); 1070214082Sdim data += strlen ((char *) data) + 1; 1071214082Sdim break; 1072214082Sdim 1073214082Sdim case DW_FORM_block: 1074214082Sdim uvalue = read_leb128 (data, & bytes_read, 0); 1075214082Sdim block_start = data + bytes_read; 1076214082Sdim if (do_loc) 1077214082Sdim data = block_start + uvalue; 1078214082Sdim else 1079214082Sdim data = display_block (block_start, uvalue); 1080214082Sdim break; 1081214082Sdim 1082214082Sdim case DW_FORM_block1: 1083214082Sdim uvalue = byte_get (data, 1); 1084214082Sdim block_start = data + 1; 1085214082Sdim if (do_loc) 1086214082Sdim data = block_start + uvalue; 1087214082Sdim else 1088214082Sdim data = display_block (block_start, uvalue); 1089214082Sdim break; 1090214082Sdim 1091214082Sdim case DW_FORM_block2: 1092214082Sdim uvalue = byte_get (data, 2); 1093214082Sdim block_start = data + 2; 1094214082Sdim if (do_loc) 1095214082Sdim data = block_start + uvalue; 1096214082Sdim else 1097214082Sdim data = display_block (block_start, uvalue); 1098214082Sdim break; 1099214082Sdim 1100214082Sdim case DW_FORM_block4: 1101214082Sdim uvalue = byte_get (data, 4); 1102214082Sdim block_start = data + 4; 1103214082Sdim if (do_loc) 1104214082Sdim data = block_start + uvalue; 1105214082Sdim else 1106214082Sdim data = display_block (block_start, uvalue); 1107214082Sdim break; 1108214082Sdim 1109214082Sdim case DW_FORM_strp: 1110214082Sdim if (!do_loc) 1111214082Sdim printf (_(" (indirect string, offset: 0x%lx): %s"), 1112214082Sdim uvalue, fetch_indirect_string (uvalue)); 1113214082Sdim break; 1114214082Sdim 1115214082Sdim case DW_FORM_indirect: 1116214082Sdim /* Handled above. */ 1117214082Sdim break; 1118214082Sdim 1119214082Sdim default: 1120214082Sdim warn (_("Unrecognized form: %lu\n"), form); 1121214082Sdim break; 1122214082Sdim } 1123214082Sdim 1124214082Sdim /* For some attributes we can display further information. */ 1125214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1126214082Sdim && num_debug_info_entries == 0) 1127214082Sdim { 1128214082Sdim switch (attribute) 1129214082Sdim { 1130214082Sdim case DW_AT_frame_base: 1131214082Sdim have_frame_base = 1; 1132214082Sdim case DW_AT_location: 1133214082Sdim case DW_AT_data_member_location: 1134214082Sdim case DW_AT_vtable_elem_location: 1135214082Sdim case DW_AT_allocated: 1136214082Sdim case DW_AT_associated: 1137214082Sdim case DW_AT_data_location: 1138214082Sdim case DW_AT_stride: 1139214082Sdim case DW_AT_upper_bound: 1140214082Sdim case DW_AT_lower_bound: 1141214082Sdim if (form == DW_FORM_data4 || form == DW_FORM_data8) 1142214082Sdim { 1143214082Sdim /* Process location list. */ 1144214082Sdim unsigned int max = debug_info_p->max_loc_offsets; 1145214082Sdim unsigned int num = debug_info_p->num_loc_offsets; 1146214082Sdim 1147214082Sdim if (max == 0 || num >= max) 1148214082Sdim { 1149214082Sdim max += 1024; 1150214082Sdim debug_info_p->loc_offsets 1151214082Sdim = xcrealloc (debug_info_p->loc_offsets, 1152214082Sdim max, sizeof (*debug_info_p->loc_offsets)); 1153214082Sdim debug_info_p->have_frame_base 1154214082Sdim = xcrealloc (debug_info_p->have_frame_base, 1155214082Sdim max, sizeof (*debug_info_p->have_frame_base)); 1156214082Sdim debug_info_p->max_loc_offsets = max; 1157214082Sdim } 1158214082Sdim debug_info_p->loc_offsets [num] = uvalue; 1159214082Sdim debug_info_p->have_frame_base [num] = have_frame_base; 1160214082Sdim debug_info_p->num_loc_offsets++; 1161214082Sdim } 1162214082Sdim break; 1163214082Sdim 1164214082Sdim case DW_AT_low_pc: 1165214082Sdim if (need_base_address) 1166214082Sdim debug_info_p->base_address = uvalue; 1167214082Sdim break; 1168214082Sdim 1169214082Sdim case DW_AT_ranges: 1170214082Sdim if (form == DW_FORM_data4 || form == DW_FORM_data8) 1171214082Sdim { 1172214082Sdim /* Process range list. */ 1173214082Sdim unsigned int max = debug_info_p->max_range_lists; 1174214082Sdim unsigned int num = debug_info_p->num_range_lists; 1175214082Sdim 1176214082Sdim if (max == 0 || num >= max) 1177214082Sdim { 1178214082Sdim max += 1024; 1179214082Sdim debug_info_p->range_lists 1180214082Sdim = xcrealloc (debug_info_p->range_lists, 1181214082Sdim max, sizeof (*debug_info_p->range_lists)); 1182214082Sdim debug_info_p->max_range_lists = max; 1183214082Sdim } 1184214082Sdim debug_info_p->range_lists [num] = uvalue; 1185214082Sdim debug_info_p->num_range_lists++; 1186214082Sdim } 1187214082Sdim break; 1188214082Sdim 1189214082Sdim default: 1190214082Sdim break; 1191214082Sdim } 1192214082Sdim } 1193214082Sdim 1194214082Sdim if (do_loc) 1195214082Sdim return data; 1196214082Sdim 1197214082Sdim printf ("\t"); 1198214082Sdim 1199214082Sdim switch (attribute) 1200214082Sdim { 1201214082Sdim case DW_AT_inline: 1202214082Sdim switch (uvalue) 1203214082Sdim { 1204214082Sdim case DW_INL_not_inlined: 1205214082Sdim printf (_("(not inlined)")); 1206214082Sdim break; 1207214082Sdim case DW_INL_inlined: 1208214082Sdim printf (_("(inlined)")); 1209214082Sdim break; 1210214082Sdim case DW_INL_declared_not_inlined: 1211214082Sdim printf (_("(declared as inline but ignored)")); 1212214082Sdim break; 1213214082Sdim case DW_INL_declared_inlined: 1214214082Sdim printf (_("(declared as inline and inlined)")); 1215214082Sdim break; 1216214082Sdim default: 1217214082Sdim printf (_(" (Unknown inline attribute value: %lx)"), uvalue); 1218214082Sdim break; 1219214082Sdim } 1220214082Sdim break; 1221214082Sdim 1222214082Sdim case DW_AT_language: 1223214082Sdim switch (uvalue) 1224214082Sdim { 1225214634Sdim /* Ordered by the numeric value of these constants. */ 1226214634Sdim case DW_LANG_C89: printf ("(ANSI C)"); break; 1227214082Sdim case DW_LANG_C: printf ("(non-ANSI C)"); break; 1228214634Sdim case DW_LANG_Ada83: printf ("(Ada)"); break; 1229214082Sdim case DW_LANG_C_plus_plus: printf ("(C++)"); break; 1230214634Sdim case DW_LANG_Cobol74: printf ("(Cobol 74)"); break; 1231214634Sdim case DW_LANG_Cobol85: printf ("(Cobol 85)"); break; 1232214082Sdim case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break; 1233214082Sdim case DW_LANG_Fortran90: printf ("(Fortran 90)"); break; 1234214634Sdim case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break; 1235214082Sdim case DW_LANG_Modula2: printf ("(Modula 2)"); break; 1236214082Sdim /* DWARF 2.1 values. */ 1237214634Sdim case DW_LANG_Java: printf ("(Java)"); break; 1238214082Sdim case DW_LANG_C99: printf ("(ANSI C99)"); break; 1239214082Sdim case DW_LANG_Ada95: printf ("(ADA 95)"); break; 1240214082Sdim case DW_LANG_Fortran95: printf ("(Fortran 95)"); break; 1241214634Sdim /* DWARF 3 values. */ 1242214634Sdim case DW_LANG_PLI: printf ("(PLI)"); break; 1243214634Sdim case DW_LANG_ObjC: printf ("(Objective C)"); break; 1244214634Sdim case DW_LANG_ObjC_plus_plus: printf ("(Objective C++)"); break; 1245214634Sdim case DW_LANG_UPC: printf ("(Unified Parallel C)"); break; 1246214634Sdim case DW_LANG_D: printf ("(D)"); break; 1247214082Sdim /* MIPS extension. */ 1248214082Sdim case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break; 1249214082Sdim /* UPC extension. */ 1250214082Sdim case DW_LANG_Upc: printf ("(Unified Parallel C)"); break; 1251214082Sdim default: 1252214634Sdim if (uvalue >= DW_LANG_lo_user && uvalue <= DW_LANG_hi_user) 1253214634Sdim printf ("(implementation defined: %lx)", uvalue); 1254214634Sdim else 1255214634Sdim printf ("(Unknown: %lx)", uvalue); 1256214082Sdim break; 1257214082Sdim } 1258214082Sdim break; 1259214082Sdim 1260214082Sdim case DW_AT_encoding: 1261214082Sdim switch (uvalue) 1262214082Sdim { 1263214082Sdim case DW_ATE_void: printf ("(void)"); break; 1264214082Sdim case DW_ATE_address: printf ("(machine address)"); break; 1265214082Sdim case DW_ATE_boolean: printf ("(boolean)"); break; 1266214082Sdim case DW_ATE_complex_float: printf ("(complex float)"); break; 1267214082Sdim case DW_ATE_float: printf ("(float)"); break; 1268214082Sdim case DW_ATE_signed: printf ("(signed)"); break; 1269214082Sdim case DW_ATE_signed_char: printf ("(signed char)"); break; 1270214082Sdim case DW_ATE_unsigned: printf ("(unsigned)"); break; 1271214082Sdim case DW_ATE_unsigned_char: printf ("(unsigned char)"); break; 1272214082Sdim /* DWARF 2.1 value. */ 1273214082Sdim case DW_ATE_imaginary_float: printf ("(imaginary float)"); break; 1274214082Sdim case DW_ATE_decimal_float: printf ("(decimal float)"); break; 1275214082Sdim default: 1276214082Sdim if (uvalue >= DW_ATE_lo_user 1277214082Sdim && uvalue <= DW_ATE_hi_user) 1278214082Sdim printf ("(user defined type)"); 1279214082Sdim else 1280214082Sdim printf ("(unknown type)"); 1281214082Sdim break; 1282214082Sdim } 1283214082Sdim break; 1284214082Sdim 1285214082Sdim case DW_AT_accessibility: 1286214082Sdim switch (uvalue) 1287214082Sdim { 1288214082Sdim case DW_ACCESS_public: printf ("(public)"); break; 1289214082Sdim case DW_ACCESS_protected: printf ("(protected)"); break; 1290214082Sdim case DW_ACCESS_private: printf ("(private)"); break; 1291214082Sdim default: 1292214082Sdim printf ("(unknown accessibility)"); 1293214082Sdim break; 1294214082Sdim } 1295214082Sdim break; 1296214082Sdim 1297214082Sdim case DW_AT_visibility: 1298214082Sdim switch (uvalue) 1299214082Sdim { 1300214082Sdim case DW_VIS_local: printf ("(local)"); break; 1301214082Sdim case DW_VIS_exported: printf ("(exported)"); break; 1302214082Sdim case DW_VIS_qualified: printf ("(qualified)"); break; 1303214082Sdim default: printf ("(unknown visibility)"); break; 1304214082Sdim } 1305214082Sdim break; 1306214082Sdim 1307214082Sdim case DW_AT_virtuality: 1308214082Sdim switch (uvalue) 1309214082Sdim { 1310214082Sdim case DW_VIRTUALITY_none: printf ("(none)"); break; 1311214082Sdim case DW_VIRTUALITY_virtual: printf ("(virtual)"); break; 1312214082Sdim case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break; 1313214082Sdim default: printf ("(unknown virtuality)"); break; 1314214082Sdim } 1315214082Sdim break; 1316214082Sdim 1317214082Sdim case DW_AT_identifier_case: 1318214082Sdim switch (uvalue) 1319214082Sdim { 1320214082Sdim case DW_ID_case_sensitive: printf ("(case_sensitive)"); break; 1321214082Sdim case DW_ID_up_case: printf ("(up_case)"); break; 1322214082Sdim case DW_ID_down_case: printf ("(down_case)"); break; 1323214082Sdim case DW_ID_case_insensitive: printf ("(case_insensitive)"); break; 1324214082Sdim default: printf ("(unknown case)"); break; 1325214082Sdim } 1326214082Sdim break; 1327214082Sdim 1328214082Sdim case DW_AT_calling_convention: 1329214082Sdim switch (uvalue) 1330214082Sdim { 1331214082Sdim case DW_CC_normal: printf ("(normal)"); break; 1332214082Sdim case DW_CC_program: printf ("(program)"); break; 1333214082Sdim case DW_CC_nocall: printf ("(nocall)"); break; 1334214082Sdim default: 1335214082Sdim if (uvalue >= DW_CC_lo_user 1336214082Sdim && uvalue <= DW_CC_hi_user) 1337214082Sdim printf ("(user defined)"); 1338214082Sdim else 1339214082Sdim printf ("(unknown convention)"); 1340214082Sdim } 1341214082Sdim break; 1342214082Sdim 1343214082Sdim case DW_AT_ordering: 1344214082Sdim switch (uvalue) 1345214082Sdim { 1346214082Sdim case -1: printf ("(undefined)"); break; 1347214082Sdim case 0: printf ("(row major)"); break; 1348214082Sdim case 1: printf ("(column major)"); break; 1349214082Sdim } 1350214082Sdim break; 1351214082Sdim 1352214082Sdim case DW_AT_frame_base: 1353214082Sdim have_frame_base = 1; 1354214082Sdim case DW_AT_location: 1355214082Sdim case DW_AT_data_member_location: 1356214082Sdim case DW_AT_vtable_elem_location: 1357214082Sdim case DW_AT_allocated: 1358214082Sdim case DW_AT_associated: 1359214082Sdim case DW_AT_data_location: 1360214082Sdim case DW_AT_stride: 1361214082Sdim case DW_AT_upper_bound: 1362214082Sdim case DW_AT_lower_bound: 1363214082Sdim if (block_start) 1364214082Sdim { 1365214082Sdim int need_frame_base; 1366214082Sdim 1367214082Sdim printf ("("); 1368214082Sdim need_frame_base = decode_location_expression (block_start, 1369214082Sdim pointer_size, 1370214082Sdim uvalue, 1371214082Sdim cu_offset); 1372214082Sdim printf (")"); 1373214082Sdim if (need_frame_base && !have_frame_base) 1374214082Sdim printf (_(" [without DW_AT_frame_base]")); 1375214082Sdim } 1376214082Sdim else if (form == DW_FORM_data4 || form == DW_FORM_data8) 1377214082Sdim printf (_("(location list)")); 1378214082Sdim 1379214082Sdim break; 1380214082Sdim 1381214082Sdim default: 1382214082Sdim break; 1383214082Sdim } 1384214082Sdim 1385214082Sdim return data; 1386214082Sdim} 1387214082Sdim 1388214082Sdimstatic char * 1389214082Sdimget_AT_name (unsigned long attribute) 1390214082Sdim{ 1391214082Sdim switch (attribute) 1392214082Sdim { 1393214082Sdim case DW_AT_sibling: return "DW_AT_sibling"; 1394214082Sdim case DW_AT_location: return "DW_AT_location"; 1395214082Sdim case DW_AT_name: return "DW_AT_name"; 1396214082Sdim case DW_AT_ordering: return "DW_AT_ordering"; 1397214082Sdim case DW_AT_subscr_data: return "DW_AT_subscr_data"; 1398214082Sdim case DW_AT_byte_size: return "DW_AT_byte_size"; 1399214082Sdim case DW_AT_bit_offset: return "DW_AT_bit_offset"; 1400214082Sdim case DW_AT_bit_size: return "DW_AT_bit_size"; 1401214082Sdim case DW_AT_element_list: return "DW_AT_element_list"; 1402214082Sdim case DW_AT_stmt_list: return "DW_AT_stmt_list"; 1403214082Sdim case DW_AT_low_pc: return "DW_AT_low_pc"; 1404214082Sdim case DW_AT_high_pc: return "DW_AT_high_pc"; 1405214082Sdim case DW_AT_language: return "DW_AT_language"; 1406214082Sdim case DW_AT_member: return "DW_AT_member"; 1407214082Sdim case DW_AT_discr: return "DW_AT_discr"; 1408214082Sdim case DW_AT_discr_value: return "DW_AT_discr_value"; 1409214082Sdim case DW_AT_visibility: return "DW_AT_visibility"; 1410214082Sdim case DW_AT_import: return "DW_AT_import"; 1411214082Sdim case DW_AT_string_length: return "DW_AT_string_length"; 1412214082Sdim case DW_AT_common_reference: return "DW_AT_common_reference"; 1413214082Sdim case DW_AT_comp_dir: return "DW_AT_comp_dir"; 1414214082Sdim case DW_AT_const_value: return "DW_AT_const_value"; 1415214082Sdim case DW_AT_containing_type: return "DW_AT_containing_type"; 1416214082Sdim case DW_AT_default_value: return "DW_AT_default_value"; 1417214082Sdim case DW_AT_inline: return "DW_AT_inline"; 1418214082Sdim case DW_AT_is_optional: return "DW_AT_is_optional"; 1419214082Sdim case DW_AT_lower_bound: return "DW_AT_lower_bound"; 1420214082Sdim case DW_AT_producer: return "DW_AT_producer"; 1421214082Sdim case DW_AT_prototyped: return "DW_AT_prototyped"; 1422214082Sdim case DW_AT_return_addr: return "DW_AT_return_addr"; 1423214082Sdim case DW_AT_start_scope: return "DW_AT_start_scope"; 1424214082Sdim case DW_AT_stride_size: return "DW_AT_stride_size"; 1425214082Sdim case DW_AT_upper_bound: return "DW_AT_upper_bound"; 1426214082Sdim case DW_AT_abstract_origin: return "DW_AT_abstract_origin"; 1427214082Sdim case DW_AT_accessibility: return "DW_AT_accessibility"; 1428214082Sdim case DW_AT_address_class: return "DW_AT_address_class"; 1429214082Sdim case DW_AT_artificial: return "DW_AT_artificial"; 1430214082Sdim case DW_AT_base_types: return "DW_AT_base_types"; 1431214082Sdim case DW_AT_calling_convention: return "DW_AT_calling_convention"; 1432214082Sdim case DW_AT_count: return "DW_AT_count"; 1433214082Sdim case DW_AT_data_member_location: return "DW_AT_data_member_location"; 1434214082Sdim case DW_AT_decl_column: return "DW_AT_decl_column"; 1435214082Sdim case DW_AT_decl_file: return "DW_AT_decl_file"; 1436214082Sdim case DW_AT_decl_line: return "DW_AT_decl_line"; 1437214082Sdim case DW_AT_declaration: return "DW_AT_declaration"; 1438214082Sdim case DW_AT_discr_list: return "DW_AT_discr_list"; 1439214082Sdim case DW_AT_encoding: return "DW_AT_encoding"; 1440214082Sdim case DW_AT_external: return "DW_AT_external"; 1441214082Sdim case DW_AT_frame_base: return "DW_AT_frame_base"; 1442214082Sdim case DW_AT_friend: return "DW_AT_friend"; 1443214082Sdim case DW_AT_identifier_case: return "DW_AT_identifier_case"; 1444214082Sdim case DW_AT_macro_info: return "DW_AT_macro_info"; 1445214082Sdim case DW_AT_namelist_items: return "DW_AT_namelist_items"; 1446214082Sdim case DW_AT_priority: return "DW_AT_priority"; 1447214082Sdim case DW_AT_segment: return "DW_AT_segment"; 1448214082Sdim case DW_AT_specification: return "DW_AT_specification"; 1449214082Sdim case DW_AT_static_link: return "DW_AT_static_link"; 1450214082Sdim case DW_AT_type: return "DW_AT_type"; 1451214082Sdim case DW_AT_use_location: return "DW_AT_use_location"; 1452214082Sdim case DW_AT_variable_parameter: return "DW_AT_variable_parameter"; 1453214082Sdim case DW_AT_virtuality: return "DW_AT_virtuality"; 1454214082Sdim case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location"; 1455214082Sdim /* DWARF 2.1 values. */ 1456214082Sdim case DW_AT_allocated: return "DW_AT_allocated"; 1457214082Sdim case DW_AT_associated: return "DW_AT_associated"; 1458214082Sdim case DW_AT_data_location: return "DW_AT_data_location"; 1459214082Sdim case DW_AT_stride: return "DW_AT_stride"; 1460214082Sdim case DW_AT_entry_pc: return "DW_AT_entry_pc"; 1461214082Sdim case DW_AT_use_UTF8: return "DW_AT_use_UTF8"; 1462214082Sdim case DW_AT_extension: return "DW_AT_extension"; 1463214082Sdim case DW_AT_ranges: return "DW_AT_ranges"; 1464214082Sdim case DW_AT_trampoline: return "DW_AT_trampoline"; 1465214082Sdim case DW_AT_call_column: return "DW_AT_call_column"; 1466214082Sdim case DW_AT_call_file: return "DW_AT_call_file"; 1467214082Sdim case DW_AT_call_line: return "DW_AT_call_line"; 1468214082Sdim /* SGI/MIPS extensions. */ 1469214082Sdim case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; 1470214082Sdim case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin"; 1471214082Sdim case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin"; 1472214082Sdim case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin"; 1473214082Sdim case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor"; 1474214082Sdim case DW_AT_MIPS_software_pipeline_depth: 1475214082Sdim return "DW_AT_MIPS_software_pipeline_depth"; 1476214082Sdim case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name"; 1477214082Sdim case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride"; 1478214082Sdim case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name"; 1479214082Sdim case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin"; 1480214082Sdim case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines"; 1481214082Sdim /* GNU extensions. */ 1482214082Sdim case DW_AT_sf_names: return "DW_AT_sf_names"; 1483214082Sdim case DW_AT_src_info: return "DW_AT_src_info"; 1484214082Sdim case DW_AT_mac_info: return "DW_AT_mac_info"; 1485214082Sdim case DW_AT_src_coords: return "DW_AT_src_coords"; 1486214082Sdim case DW_AT_body_begin: return "DW_AT_body_begin"; 1487214082Sdim case DW_AT_body_end: return "DW_AT_body_end"; 1488214082Sdim case DW_AT_GNU_vector: return "DW_AT_GNU_vector"; 1489214082Sdim /* UPC extension. */ 1490214082Sdim case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled"; 1491214082Sdim default: 1492214082Sdim { 1493214082Sdim static char buffer[100]; 1494214082Sdim 1495214082Sdim snprintf (buffer, sizeof (buffer), _("Unknown AT value: %lx"), 1496214082Sdim attribute); 1497214082Sdim return buffer; 1498214082Sdim } 1499214082Sdim } 1500214082Sdim} 1501214082Sdim 1502214082Sdimstatic unsigned char * 1503214082Sdimread_and_display_attr (unsigned long attribute, 1504214082Sdim unsigned long form, 1505214082Sdim unsigned char *data, 1506214082Sdim unsigned long cu_offset, 1507214082Sdim unsigned long pointer_size, 1508214082Sdim unsigned long offset_size, 1509214082Sdim int dwarf_version, 1510214082Sdim debug_info *debug_info_p, 1511214082Sdim int do_loc) 1512214082Sdim{ 1513214082Sdim if (!do_loc) 1514214082Sdim printf (" %-18s:", get_AT_name (attribute)); 1515214082Sdim data = read_and_display_attr_value (attribute, form, data, cu_offset, 1516214082Sdim pointer_size, offset_size, 1517214082Sdim dwarf_version, debug_info_p, 1518214082Sdim do_loc); 1519214082Sdim if (!do_loc) 1520214082Sdim printf ("\n"); 1521214082Sdim return data; 1522214082Sdim} 1523214082Sdim 1524214082Sdim 1525214082Sdim/* Process the contents of a .debug_info section. If do_loc is non-zero 1526214082Sdim then we are scanning for location lists and we do not want to display 1527214082Sdim anything to the user. */ 1528214082Sdim 1529214082Sdimstatic int 1530214082Sdimprocess_debug_info (struct dwarf_section *section, void *file, 1531214082Sdim int do_loc) 1532214082Sdim{ 1533214082Sdim unsigned char *start = section->start; 1534214082Sdim unsigned char *end = start + section->size; 1535214082Sdim unsigned char *section_begin; 1536214082Sdim unsigned int unit; 1537214082Sdim unsigned int num_units = 0; 1538214082Sdim 1539214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1540214082Sdim && num_debug_info_entries == 0) 1541214082Sdim { 1542214082Sdim unsigned long length; 1543214082Sdim 1544214082Sdim /* First scan the section to get the number of comp units. */ 1545214082Sdim for (section_begin = start, num_units = 0; section_begin < end; 1546214082Sdim num_units ++) 1547214082Sdim { 1548214082Sdim /* Read the first 4 bytes. For a 32-bit DWARF section, this 1549214082Sdim will be the length. For a 64-bit DWARF section, it'll be 1550214082Sdim the escape code 0xffffffff followed by an 8 byte length. */ 1551214082Sdim length = byte_get (section_begin, 4); 1552214082Sdim 1553214082Sdim if (length == 0xffffffff) 1554214082Sdim { 1555214082Sdim length = byte_get (section_begin + 4, 8); 1556214082Sdim section_begin += length + 12; 1557214082Sdim } 1558214082Sdim else 1559214082Sdim section_begin += length + 4; 1560214082Sdim } 1561214082Sdim 1562214082Sdim if (num_units == 0) 1563214082Sdim { 1564214082Sdim error (_("No comp units in %s section ?"), section->name); 1565214082Sdim return 0; 1566214082Sdim } 1567214082Sdim 1568214082Sdim /* Then allocate an array to hold the information. */ 1569214082Sdim debug_information = cmalloc (num_units, 1570214082Sdim sizeof (* debug_information)); 1571214082Sdim if (debug_information == NULL) 1572214082Sdim { 1573214082Sdim error (_("Not enough memory for a debug info array of %u entries"), 1574214082Sdim num_units); 1575214082Sdim return 0; 1576214082Sdim } 1577214082Sdim } 1578214082Sdim 1579214082Sdim if (!do_loc) 1580214082Sdim { 1581214082Sdim printf (_("The section %s contains:\n\n"), section->name); 1582214082Sdim 1583214082Sdim load_debug_section (str, file); 1584214082Sdim } 1585214082Sdim 1586214082Sdim load_debug_section (abbrev, file); 1587214082Sdim if (debug_displays [abbrev].section.start == NULL) 1588214082Sdim { 1589214082Sdim warn (_("Unable to locate %s section!\n"), 1590214082Sdim debug_displays [abbrev].section.name); 1591214082Sdim return 0; 1592214082Sdim } 1593214082Sdim 1594214082Sdim for (section_begin = start, unit = 0; start < end; unit++) 1595214082Sdim { 1596214082Sdim DWARF2_Internal_CompUnit compunit; 1597214082Sdim unsigned char *hdrptr; 1598214082Sdim unsigned char *cu_abbrev_offset_ptr; 1599214082Sdim unsigned char *tags; 1600214082Sdim int level; 1601214082Sdim unsigned long cu_offset; 1602214082Sdim int offset_size; 1603214082Sdim int initial_length_size; 1604214082Sdim 1605214082Sdim hdrptr = start; 1606214082Sdim 1607214082Sdim compunit.cu_length = byte_get (hdrptr, 4); 1608214082Sdim hdrptr += 4; 1609214082Sdim 1610214082Sdim if (compunit.cu_length == 0xffffffff) 1611214082Sdim { 1612214082Sdim compunit.cu_length = byte_get (hdrptr, 8); 1613214082Sdim hdrptr += 8; 1614214082Sdim offset_size = 8; 1615214082Sdim initial_length_size = 12; 1616214082Sdim } 1617214082Sdim else 1618214082Sdim { 1619214082Sdim offset_size = 4; 1620214082Sdim initial_length_size = 4; 1621214082Sdim } 1622214082Sdim 1623214082Sdim compunit.cu_version = byte_get (hdrptr, 2); 1624214082Sdim hdrptr += 2; 1625214082Sdim 1626214082Sdim cu_offset = start - section_begin; 1627214082Sdim 1628214082Sdim cu_abbrev_offset_ptr = hdrptr; 1629214082Sdim compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size); 1630214082Sdim hdrptr += offset_size; 1631214082Sdim 1632214082Sdim compunit.cu_pointer_size = byte_get (hdrptr, 1); 1633214082Sdim hdrptr += 1; 1634214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1635214082Sdim && num_debug_info_entries == 0) 1636214082Sdim { 1637214082Sdim debug_information [unit].cu_offset = cu_offset; 1638214082Sdim debug_information [unit].pointer_size 1639214082Sdim = compunit.cu_pointer_size; 1640214082Sdim debug_information [unit].base_address = 0; 1641214082Sdim debug_information [unit].loc_offsets = NULL; 1642214082Sdim debug_information [unit].have_frame_base = NULL; 1643214082Sdim debug_information [unit].max_loc_offsets = 0; 1644214082Sdim debug_information [unit].num_loc_offsets = 0; 1645214082Sdim debug_information [unit].range_lists = NULL; 1646214082Sdim debug_information [unit].max_range_lists= 0; 1647214082Sdim debug_information [unit].num_range_lists = 0; 1648214082Sdim } 1649214082Sdim 1650214082Sdim if (!do_loc) 1651214082Sdim { 1652214082Sdim printf (_(" Compilation Unit @ offset 0x%lx:\n"), cu_offset); 1653214082Sdim printf (_(" Length: %ld\n"), compunit.cu_length); 1654214082Sdim printf (_(" Version: %d\n"), compunit.cu_version); 1655214082Sdim printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset); 1656214082Sdim printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size); 1657214082Sdim } 1658214082Sdim 1659214634Sdim if (cu_offset + compunit.cu_length + initial_length_size 1660214634Sdim > section->size) 1661214634Sdim { 1662214634Sdim warn (_("Debug info is corrupted, length is invalid (section is %lu bytes)\n"), 1663214634Sdim (unsigned long)section->size); 1664214634Sdim break; 1665214634Sdim } 1666214634Sdim tags = hdrptr; 1667214634Sdim start += compunit.cu_length + initial_length_size; 1668214634Sdim 1669214082Sdim if (compunit.cu_version != 2 && compunit.cu_version != 3) 1670214082Sdim { 1671214082Sdim warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n")); 1672214082Sdim continue; 1673214082Sdim } 1674214082Sdim 1675214082Sdim free_abbrevs (); 1676214082Sdim 1677214082Sdim /* Process the abbrevs used by this compilation unit. DWARF 1678214082Sdim sections under Mach-O have non-zero addresses. */ 1679214634Sdim if (compunit.cu_abbrev_offset >= debug_displays [abbrev].section.size) 1680214634Sdim warn (_("Debug info is corrupted, abbrev offset is invalid (section is %lu bytes)\n"), 1681214634Sdim (unsigned long)debug_displays [abbrev].section.size); 1682214634Sdim else 1683214634Sdim process_abbrev_section 1684214634Sdim ((unsigned char *) debug_displays [abbrev].section.start 1685214634Sdim + compunit.cu_abbrev_offset - debug_displays [abbrev].section.address, 1686214634Sdim (unsigned char *) debug_displays [abbrev].section.start 1687214634Sdim + debug_displays [abbrev].section.size); 1688214082Sdim 1689214082Sdim level = 0; 1690214082Sdim while (tags < start) 1691214082Sdim { 1692214082Sdim unsigned int bytes_read; 1693214082Sdim unsigned long abbrev_number; 1694214082Sdim abbrev_entry *entry; 1695214082Sdim abbrev_attr *attr; 1696214082Sdim 1697214082Sdim abbrev_number = read_leb128 (tags, & bytes_read, 0); 1698214082Sdim tags += bytes_read; 1699214082Sdim 1700214082Sdim /* A null DIE marks the end of a list of children. */ 1701214082Sdim if (abbrev_number == 0) 1702214082Sdim { 1703214082Sdim --level; 1704214082Sdim continue; 1705214082Sdim } 1706214082Sdim 1707214634Sdim if (!do_loc) 1708214634Sdim printf (_(" <%d><%lx>: Abbrev Number: %lu"), 1709214634Sdim level, 1710214634Sdim (unsigned long) (tags - section_begin 1711214634Sdim - bytes_read), 1712214634Sdim abbrev_number); 1713214634Sdim 1714214082Sdim /* Scan through the abbreviation list until we reach the 1715214082Sdim correct entry. */ 1716214082Sdim for (entry = first_abbrev; 1717214082Sdim entry && entry->entry != abbrev_number; 1718214082Sdim entry = entry->next) 1719214082Sdim continue; 1720214082Sdim 1721214082Sdim if (entry == NULL) 1722214082Sdim { 1723214634Sdim if (!do_loc) 1724214634Sdim { 1725214634Sdim printf ("\n"); 1726214634Sdim fflush (stdout); 1727214634Sdim } 1728214082Sdim warn (_("Unable to locate entry %lu in the abbreviation table\n"), 1729214082Sdim abbrev_number); 1730214082Sdim return 0; 1731214082Sdim } 1732214082Sdim 1733214082Sdim if (!do_loc) 1734214634Sdim printf (_(" (%s)\n"), get_TAG_name (entry->tag)); 1735214082Sdim 1736214082Sdim switch (entry->tag) 1737214082Sdim { 1738214082Sdim default: 1739214082Sdim need_base_address = 0; 1740214082Sdim break; 1741214082Sdim case DW_TAG_compile_unit: 1742214082Sdim need_base_address = 1; 1743214082Sdim break; 1744214082Sdim case DW_TAG_entry_point: 1745214082Sdim case DW_TAG_subprogram: 1746214082Sdim need_base_address = 0; 1747214082Sdim /* Assuming that there is no DW_AT_frame_base. */ 1748214082Sdim have_frame_base = 0; 1749214082Sdim break; 1750214082Sdim } 1751214082Sdim 1752214082Sdim for (attr = entry->first_attr; attr; attr = attr->next) 1753214634Sdim { 1754214634Sdim if (! do_loc) 1755214634Sdim /* Show the offset from where the tag was extracted. */ 1756214634Sdim printf (" <%2lx>", (unsigned long)(tags - section_begin)); 1757214634Sdim 1758214634Sdim tags = read_and_display_attr (attr->attribute, 1759214634Sdim attr->form, 1760214634Sdim tags, cu_offset, 1761214634Sdim compunit.cu_pointer_size, 1762214634Sdim offset_size, 1763214634Sdim compunit.cu_version, 1764214634Sdim &debug_information [unit], 1765214634Sdim do_loc); 1766214634Sdim } 1767214082Sdim 1768214082Sdim if (entry->children) 1769214082Sdim ++level; 1770214082Sdim } 1771214082Sdim } 1772214082Sdim 1773214082Sdim /* Set num_debug_info_entries here so that it can be used to check if 1774214082Sdim we need to process .debug_loc and .debug_ranges sections. */ 1775214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1776214082Sdim && num_debug_info_entries == 0) 1777214082Sdim num_debug_info_entries = num_units; 1778214082Sdim 1779214082Sdim if (!do_loc) 1780214082Sdim { 1781214082Sdim printf ("\n"); 1782214082Sdim } 1783214082Sdim 1784214082Sdim return 1; 1785214082Sdim} 1786214082Sdim 1787214082Sdim/* Locate and scan the .debug_info section in the file and record the pointer 1788214082Sdim sizes and offsets for the compilation units in it. Usually an executable 1789214082Sdim will have just one pointer size, but this is not guaranteed, and so we try 1790214082Sdim not to make any assumptions. Returns zero upon failure, or the number of 1791214082Sdim compilation units upon success. */ 1792214082Sdim 1793214082Sdimstatic unsigned int 1794214082Sdimload_debug_info (void * file) 1795214082Sdim{ 1796214082Sdim /* Reset the last pointer size so that we can issue correct error 1797214082Sdim messages if we are displaying the contents of more than one section. */ 1798214082Sdim last_pointer_size = 0; 1799214082Sdim warned_about_missing_comp_units = FALSE; 1800214082Sdim 1801214082Sdim /* If we already have the information there is nothing else to do. */ 1802214082Sdim if (num_debug_info_entries > 0) 1803214082Sdim return num_debug_info_entries; 1804214082Sdim 1805214082Sdim if (load_debug_section (info, file) 1806214082Sdim && process_debug_info (&debug_displays [info].section, file, 1)) 1807214082Sdim return num_debug_info_entries; 1808214082Sdim else 1809214082Sdim return 0; 1810214082Sdim} 1811214082Sdim 1812214082Sdimstatic int 1813214082Sdimdisplay_debug_lines (struct dwarf_section *section, void *file) 1814214082Sdim{ 1815214082Sdim unsigned char *start = section->start; 1816214082Sdim unsigned char *data = start; 1817214082Sdim unsigned char *end = start + section->size; 1818214082Sdim 1819214082Sdim printf (_("\nDump of debug contents of section %s:\n\n"), 1820214082Sdim section->name); 1821214082Sdim 1822214082Sdim load_debug_info (file); 1823214082Sdim 1824214082Sdim while (data < end) 1825214082Sdim { 1826214082Sdim DWARF2_Internal_LineInfo info; 1827214082Sdim unsigned char *standard_opcodes; 1828214082Sdim unsigned char *end_of_sequence; 1829214082Sdim unsigned char *hdrptr; 1830214082Sdim int initial_length_size; 1831214082Sdim int offset_size; 1832214082Sdim int i; 1833214082Sdim 1834214082Sdim hdrptr = data; 1835214082Sdim 1836214082Sdim /* Check the length of the block. */ 1837214082Sdim info.li_length = byte_get (hdrptr, 4); 1838214082Sdim hdrptr += 4; 1839214082Sdim 1840214082Sdim if (info.li_length == 0xffffffff) 1841214082Sdim { 1842214082Sdim /* This section is 64-bit DWARF 3. */ 1843214082Sdim info.li_length = byte_get (hdrptr, 8); 1844214082Sdim hdrptr += 8; 1845214082Sdim offset_size = 8; 1846214082Sdim initial_length_size = 12; 1847214082Sdim } 1848214082Sdim else 1849214082Sdim { 1850214082Sdim offset_size = 4; 1851214082Sdim initial_length_size = 4; 1852214082Sdim } 1853214082Sdim 1854214082Sdim if (info.li_length + initial_length_size > section->size) 1855214082Sdim { 1856214082Sdim warn 1857214082Sdim (_("The line info appears to be corrupt - the section is too small\n")); 1858214082Sdim return 0; 1859214082Sdim } 1860214082Sdim 1861214082Sdim /* Check its version number. */ 1862214082Sdim info.li_version = byte_get (hdrptr, 2); 1863214082Sdim hdrptr += 2; 1864214082Sdim if (info.li_version != 2 && info.li_version != 3) 1865214082Sdim { 1866214082Sdim warn (_("Only DWARF version 2 and 3 line info is currently supported.\n")); 1867214082Sdim return 0; 1868214082Sdim } 1869214082Sdim 1870214082Sdim info.li_prologue_length = byte_get (hdrptr, offset_size); 1871214082Sdim hdrptr += offset_size; 1872214082Sdim info.li_min_insn_length = byte_get (hdrptr, 1); 1873214082Sdim hdrptr++; 1874214082Sdim info.li_default_is_stmt = byte_get (hdrptr, 1); 1875214082Sdim hdrptr++; 1876214082Sdim info.li_line_base = byte_get (hdrptr, 1); 1877214082Sdim hdrptr++; 1878214082Sdim info.li_line_range = byte_get (hdrptr, 1); 1879214082Sdim hdrptr++; 1880214082Sdim info.li_opcode_base = byte_get (hdrptr, 1); 1881214082Sdim hdrptr++; 1882214082Sdim 1883214082Sdim /* Sign extend the line base field. */ 1884214082Sdim info.li_line_base <<= 24; 1885214082Sdim info.li_line_base >>= 24; 1886214082Sdim 1887214082Sdim printf (_(" Length: %ld\n"), info.li_length); 1888214082Sdim printf (_(" DWARF Version: %d\n"), info.li_version); 1889214082Sdim printf (_(" Prologue Length: %d\n"), info.li_prologue_length); 1890214082Sdim printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length); 1891214082Sdim printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt); 1892214082Sdim printf (_(" Line Base: %d\n"), info.li_line_base); 1893214082Sdim printf (_(" Line Range: %d\n"), info.li_line_range); 1894214082Sdim printf (_(" Opcode Base: %d\n"), info.li_opcode_base); 1895214082Sdim 1896214082Sdim end_of_sequence = data + info.li_length + initial_length_size; 1897214082Sdim 1898214082Sdim reset_state_machine (info.li_default_is_stmt); 1899214082Sdim 1900214082Sdim /* Display the contents of the Opcodes table. */ 1901214082Sdim standard_opcodes = hdrptr; 1902214082Sdim 1903214082Sdim printf (_("\n Opcodes:\n")); 1904214082Sdim 1905214082Sdim for (i = 1; i < info.li_opcode_base; i++) 1906214082Sdim printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]); 1907214082Sdim 1908214082Sdim /* Display the contents of the Directory table. */ 1909214082Sdim data = standard_opcodes + info.li_opcode_base - 1; 1910214082Sdim 1911214082Sdim if (*data == 0) 1912214082Sdim printf (_("\n The Directory Table is empty.\n")); 1913214082Sdim else 1914214082Sdim { 1915214082Sdim printf (_("\n The Directory Table:\n")); 1916214082Sdim 1917214082Sdim while (*data != 0) 1918214082Sdim { 1919214082Sdim printf (_(" %s\n"), data); 1920214082Sdim 1921214082Sdim data += strlen ((char *) data) + 1; 1922214082Sdim } 1923214082Sdim } 1924214082Sdim 1925214082Sdim /* Skip the NUL at the end of the table. */ 1926214082Sdim data++; 1927214082Sdim 1928214082Sdim /* Display the contents of the File Name table. */ 1929214082Sdim if (*data == 0) 1930214082Sdim printf (_("\n The File Name Table is empty.\n")); 1931214082Sdim else 1932214082Sdim { 1933214082Sdim printf (_("\n The File Name Table:\n")); 1934214082Sdim printf (_(" Entry\tDir\tTime\tSize\tName\n")); 1935214082Sdim 1936214082Sdim while (*data != 0) 1937214082Sdim { 1938214082Sdim unsigned char *name; 1939214082Sdim unsigned int bytes_read; 1940214082Sdim 1941214082Sdim printf (_(" %d\t"), ++state_machine_regs.last_file_entry); 1942214082Sdim name = data; 1943214082Sdim 1944214082Sdim data += strlen ((char *) data) + 1; 1945214082Sdim 1946214082Sdim printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0)); 1947214082Sdim data += bytes_read; 1948214082Sdim printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0)); 1949214082Sdim data += bytes_read; 1950214082Sdim printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0)); 1951214082Sdim data += bytes_read; 1952214082Sdim printf (_("%s\n"), name); 1953214082Sdim } 1954214082Sdim } 1955214082Sdim 1956214082Sdim /* Skip the NUL at the end of the table. */ 1957214082Sdim data++; 1958214082Sdim 1959214082Sdim /* Now display the statements. */ 1960214082Sdim printf (_("\n Line Number Statements:\n")); 1961214082Sdim 1962214082Sdim while (data < end_of_sequence) 1963214082Sdim { 1964214082Sdim unsigned char op_code; 1965214082Sdim int adv; 1966214082Sdim unsigned long int uladv; 1967214082Sdim unsigned int bytes_read; 1968214082Sdim 1969214082Sdim op_code = *data++; 1970214082Sdim 1971214082Sdim if (op_code >= info.li_opcode_base) 1972214082Sdim { 1973214082Sdim op_code -= info.li_opcode_base; 1974214082Sdim uladv = (op_code / info.li_line_range) * info.li_min_insn_length; 1975214082Sdim state_machine_regs.address += uladv; 1976214082Sdim printf (_(" Special opcode %d: advance Address by %lu to 0x%lx"), 1977214082Sdim op_code, uladv, state_machine_regs.address); 1978214082Sdim adv = (op_code % info.li_line_range) + info.li_line_base; 1979214082Sdim state_machine_regs.line += adv; 1980214082Sdim printf (_(" and Line by %d to %d\n"), 1981214082Sdim adv, state_machine_regs.line); 1982214082Sdim } 1983214082Sdim else switch (op_code) 1984214082Sdim { 1985214082Sdim case DW_LNS_extended_op: 1986214082Sdim data += process_extended_line_op (data, info.li_default_is_stmt); 1987214082Sdim break; 1988214082Sdim 1989214082Sdim case DW_LNS_copy: 1990214082Sdim printf (_(" Copy\n")); 1991214082Sdim break; 1992214082Sdim 1993214082Sdim case DW_LNS_advance_pc: 1994214082Sdim uladv = read_leb128 (data, & bytes_read, 0); 1995214082Sdim uladv *= info.li_min_insn_length; 1996214082Sdim data += bytes_read; 1997214082Sdim state_machine_regs.address += uladv; 1998214082Sdim printf (_(" Advance PC by %lu to 0x%lx\n"), uladv, 1999214082Sdim state_machine_regs.address); 2000214082Sdim break; 2001214082Sdim 2002214082Sdim case DW_LNS_advance_line: 2003214082Sdim adv = read_leb128 (data, & bytes_read, 1); 2004214082Sdim data += bytes_read; 2005214082Sdim state_machine_regs.line += adv; 2006214082Sdim printf (_(" Advance Line by %d to %d\n"), adv, 2007214082Sdim state_machine_regs.line); 2008214082Sdim break; 2009214082Sdim 2010214082Sdim case DW_LNS_set_file: 2011214082Sdim adv = read_leb128 (data, & bytes_read, 0); 2012214082Sdim data += bytes_read; 2013214082Sdim printf (_(" Set File Name to entry %d in the File Name Table\n"), 2014214082Sdim adv); 2015214082Sdim state_machine_regs.file = adv; 2016214082Sdim break; 2017214082Sdim 2018214082Sdim case DW_LNS_set_column: 2019214082Sdim uladv = read_leb128 (data, & bytes_read, 0); 2020214082Sdim data += bytes_read; 2021214082Sdim printf (_(" Set column to %lu\n"), uladv); 2022214082Sdim state_machine_regs.column = uladv; 2023214082Sdim break; 2024214082Sdim 2025214082Sdim case DW_LNS_negate_stmt: 2026214082Sdim adv = state_machine_regs.is_stmt; 2027214082Sdim adv = ! adv; 2028214082Sdim printf (_(" Set is_stmt to %d\n"), adv); 2029214082Sdim state_machine_regs.is_stmt = adv; 2030214082Sdim break; 2031214082Sdim 2032214082Sdim case DW_LNS_set_basic_block: 2033214082Sdim printf (_(" Set basic block\n")); 2034214082Sdim state_machine_regs.basic_block = 1; 2035214082Sdim break; 2036214082Sdim 2037214082Sdim case DW_LNS_const_add_pc: 2038214082Sdim uladv = (((255 - info.li_opcode_base) / info.li_line_range) 2039214082Sdim * info.li_min_insn_length); 2040214082Sdim state_machine_regs.address += uladv; 2041214082Sdim printf (_(" Advance PC by constant %lu to 0x%lx\n"), uladv, 2042214082Sdim state_machine_regs.address); 2043214082Sdim break; 2044214082Sdim 2045214082Sdim case DW_LNS_fixed_advance_pc: 2046214082Sdim uladv = byte_get (data, 2); 2047214082Sdim data += 2; 2048214082Sdim state_machine_regs.address += uladv; 2049214082Sdim printf (_(" Advance PC by fixed size amount %lu to 0x%lx\n"), 2050214082Sdim uladv, state_machine_regs.address); 2051214082Sdim break; 2052214082Sdim 2053214082Sdim case DW_LNS_set_prologue_end: 2054214082Sdim printf (_(" Set prologue_end to true\n")); 2055214082Sdim break; 2056214082Sdim 2057214082Sdim case DW_LNS_set_epilogue_begin: 2058214082Sdim printf (_(" Set epilogue_begin to true\n")); 2059214082Sdim break; 2060214082Sdim 2061214082Sdim case DW_LNS_set_isa: 2062214082Sdim uladv = read_leb128 (data, & bytes_read, 0); 2063214082Sdim data += bytes_read; 2064214082Sdim printf (_(" Set ISA to %lu\n"), uladv); 2065214082Sdim break; 2066214082Sdim 2067214082Sdim default: 2068214082Sdim printf (_(" Unknown opcode %d with operands: "), op_code); 2069214082Sdim 2070214082Sdim for (i = standard_opcodes[op_code - 1]; i > 0 ; --i) 2071214082Sdim { 2072214082Sdim printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0), 2073214082Sdim i == 1 ? "" : ", "); 2074214082Sdim data += bytes_read; 2075214082Sdim } 2076214082Sdim putchar ('\n'); 2077214082Sdim break; 2078214082Sdim } 2079214082Sdim } 2080214082Sdim putchar ('\n'); 2081214082Sdim } 2082214082Sdim 2083214082Sdim return 1; 2084214082Sdim} 2085214082Sdim 2086214082Sdimstatic int 2087214082Sdimdisplay_debug_pubnames (struct dwarf_section *section, 2088214082Sdim void *file ATTRIBUTE_UNUSED) 2089214082Sdim{ 2090214082Sdim DWARF2_Internal_PubNames pubnames; 2091214082Sdim unsigned char *start = section->start; 2092214082Sdim unsigned char *end = start + section->size; 2093214082Sdim 2094214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2095214082Sdim 2096214082Sdim while (start < end) 2097214082Sdim { 2098214082Sdim unsigned char *data; 2099214082Sdim unsigned long offset; 2100214082Sdim int offset_size, initial_length_size; 2101214082Sdim 2102214082Sdim data = start; 2103214082Sdim 2104214082Sdim pubnames.pn_length = byte_get (data, 4); 2105214082Sdim data += 4; 2106214082Sdim if (pubnames.pn_length == 0xffffffff) 2107214082Sdim { 2108214082Sdim pubnames.pn_length = byte_get (data, 8); 2109214082Sdim data += 8; 2110214082Sdim offset_size = 8; 2111214082Sdim initial_length_size = 12; 2112214082Sdim } 2113214082Sdim else 2114214082Sdim { 2115214082Sdim offset_size = 4; 2116214082Sdim initial_length_size = 4; 2117214082Sdim } 2118214082Sdim 2119214082Sdim pubnames.pn_version = byte_get (data, 2); 2120214082Sdim data += 2; 2121214082Sdim pubnames.pn_offset = byte_get (data, offset_size); 2122214082Sdim data += offset_size; 2123214082Sdim pubnames.pn_size = byte_get (data, offset_size); 2124214082Sdim data += offset_size; 2125214082Sdim 2126214082Sdim start += pubnames.pn_length + initial_length_size; 2127214082Sdim 2128214082Sdim if (pubnames.pn_version != 2 && pubnames.pn_version != 3) 2129214082Sdim { 2130214082Sdim static int warned = 0; 2131214082Sdim 2132214082Sdim if (! warned) 2133214082Sdim { 2134214082Sdim warn (_("Only DWARF 2 and 3 pubnames are currently supported\n")); 2135214082Sdim warned = 1; 2136214082Sdim } 2137214082Sdim 2138214082Sdim continue; 2139214082Sdim } 2140214082Sdim 2141214082Sdim printf (_(" Length: %ld\n"), 2142214082Sdim pubnames.pn_length); 2143214082Sdim printf (_(" Version: %d\n"), 2144214082Sdim pubnames.pn_version); 2145214082Sdim printf (_(" Offset into .debug_info section: %ld\n"), 2146214082Sdim pubnames.pn_offset); 2147214082Sdim printf (_(" Size of area in .debug_info section: %ld\n"), 2148214082Sdim pubnames.pn_size); 2149214082Sdim 2150214082Sdim printf (_("\n Offset\tName\n")); 2151214082Sdim 2152214082Sdim do 2153214082Sdim { 2154214082Sdim offset = byte_get (data, offset_size); 2155214082Sdim 2156214082Sdim if (offset != 0) 2157214082Sdim { 2158214082Sdim data += offset_size; 2159214082Sdim printf (" %-6ld\t\t%s\n", offset, data); 2160214082Sdim data += strlen ((char *) data) + 1; 2161214082Sdim } 2162214082Sdim } 2163214082Sdim while (offset != 0); 2164214082Sdim } 2165214082Sdim 2166214082Sdim printf ("\n"); 2167214082Sdim return 1; 2168214082Sdim} 2169214082Sdim 2170214082Sdimstatic int 2171214082Sdimdisplay_debug_macinfo (struct dwarf_section *section, 2172214082Sdim void *file ATTRIBUTE_UNUSED) 2173214082Sdim{ 2174214082Sdim unsigned char *start = section->start; 2175214082Sdim unsigned char *end = start + section->size; 2176214082Sdim unsigned char *curr = start; 2177214082Sdim unsigned int bytes_read; 2178214082Sdim enum dwarf_macinfo_record_type op; 2179214082Sdim 2180214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2181214082Sdim 2182214082Sdim while (curr < end) 2183214082Sdim { 2184214082Sdim unsigned int lineno; 2185214082Sdim const char *string; 2186214082Sdim 2187214082Sdim op = *curr; 2188214082Sdim curr++; 2189214082Sdim 2190214082Sdim switch (op) 2191214082Sdim { 2192214082Sdim case DW_MACINFO_start_file: 2193214082Sdim { 2194214082Sdim unsigned int filenum; 2195214082Sdim 2196214082Sdim lineno = read_leb128 (curr, & bytes_read, 0); 2197214082Sdim curr += bytes_read; 2198214082Sdim filenum = read_leb128 (curr, & bytes_read, 0); 2199214082Sdim curr += bytes_read; 2200214082Sdim 2201214082Sdim printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), 2202214082Sdim lineno, filenum); 2203214082Sdim } 2204214082Sdim break; 2205214082Sdim 2206214082Sdim case DW_MACINFO_end_file: 2207214082Sdim printf (_(" DW_MACINFO_end_file\n")); 2208214082Sdim break; 2209214082Sdim 2210214082Sdim case DW_MACINFO_define: 2211214082Sdim lineno = read_leb128 (curr, & bytes_read, 0); 2212214082Sdim curr += bytes_read; 2213214082Sdim string = (char *) curr; 2214214082Sdim curr += strlen (string) + 1; 2215214082Sdim printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), 2216214082Sdim lineno, string); 2217214082Sdim break; 2218214082Sdim 2219214082Sdim case DW_MACINFO_undef: 2220214082Sdim lineno = read_leb128 (curr, & bytes_read, 0); 2221214082Sdim curr += bytes_read; 2222214082Sdim string = (char *) curr; 2223214082Sdim curr += strlen (string) + 1; 2224214082Sdim printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), 2225214082Sdim lineno, string); 2226214082Sdim break; 2227214082Sdim 2228214082Sdim case DW_MACINFO_vendor_ext: 2229214082Sdim { 2230214082Sdim unsigned int constant; 2231214082Sdim 2232214082Sdim constant = read_leb128 (curr, & bytes_read, 0); 2233214082Sdim curr += bytes_read; 2234214082Sdim string = (char *) curr; 2235214082Sdim curr += strlen (string) + 1; 2236214082Sdim printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), 2237214082Sdim constant, string); 2238214082Sdim } 2239214082Sdim break; 2240214082Sdim } 2241214082Sdim } 2242214082Sdim 2243214082Sdim return 1; 2244214082Sdim} 2245214082Sdim 2246214082Sdimstatic int 2247214082Sdimdisplay_debug_abbrev (struct dwarf_section *section, 2248214082Sdim void *file ATTRIBUTE_UNUSED) 2249214082Sdim{ 2250214082Sdim abbrev_entry *entry; 2251214082Sdim unsigned char *start = section->start; 2252214082Sdim unsigned char *end = start + section->size; 2253214082Sdim 2254214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2255214082Sdim 2256214082Sdim do 2257214082Sdim { 2258214082Sdim free_abbrevs (); 2259214082Sdim 2260214082Sdim start = process_abbrev_section (start, end); 2261214082Sdim 2262214082Sdim if (first_abbrev == NULL) 2263214082Sdim continue; 2264214082Sdim 2265214082Sdim printf (_(" Number TAG\n")); 2266214082Sdim 2267214082Sdim for (entry = first_abbrev; entry; entry = entry->next) 2268214082Sdim { 2269214082Sdim abbrev_attr *attr; 2270214082Sdim 2271214082Sdim printf (_(" %ld %s [%s]\n"), 2272214082Sdim entry->entry, 2273214082Sdim get_TAG_name (entry->tag), 2274214082Sdim entry->children ? _("has children") : _("no children")); 2275214082Sdim 2276214082Sdim for (attr = entry->first_attr; attr; attr = attr->next) 2277214082Sdim printf (_(" %-18s %s\n"), 2278214082Sdim get_AT_name (attr->attribute), 2279214082Sdim get_FORM_name (attr->form)); 2280214082Sdim } 2281214082Sdim } 2282214082Sdim while (start); 2283214082Sdim 2284214082Sdim printf ("\n"); 2285214082Sdim 2286214082Sdim return 1; 2287214082Sdim} 2288214082Sdim 2289214082Sdimstatic int 2290214082Sdimdisplay_debug_loc (struct dwarf_section *section, void *file) 2291214082Sdim{ 2292214082Sdim unsigned char *start = section->start; 2293214082Sdim unsigned char *section_end; 2294214082Sdim unsigned long bytes; 2295214082Sdim unsigned char *section_begin = start; 2296214082Sdim unsigned int num_loc_list = 0; 2297214082Sdim unsigned long last_offset = 0; 2298214082Sdim unsigned int first = 0; 2299214082Sdim unsigned int i; 2300214082Sdim unsigned int j; 2301214082Sdim int seen_first_offset = 0; 2302214082Sdim int use_debug_info = 1; 2303214082Sdim unsigned char *next; 2304214082Sdim 2305214082Sdim bytes = section->size; 2306214082Sdim section_end = start + bytes; 2307214082Sdim 2308214082Sdim if (bytes == 0) 2309214082Sdim { 2310214082Sdim printf (_("\nThe %s section is empty.\n"), section->name); 2311214082Sdim return 0; 2312214082Sdim } 2313214082Sdim 2314214082Sdim load_debug_info (file); 2315214082Sdim 2316214082Sdim /* Check the order of location list in .debug_info section. If 2317214082Sdim offsets of location lists are in the ascending order, we can 2318214082Sdim use `debug_information' directly. */ 2319214082Sdim for (i = 0; i < num_debug_info_entries; i++) 2320214082Sdim { 2321214082Sdim unsigned int num; 2322214082Sdim 2323214082Sdim num = debug_information [i].num_loc_offsets; 2324214082Sdim num_loc_list += num; 2325214082Sdim 2326214082Sdim /* Check if we can use `debug_information' directly. */ 2327214082Sdim if (use_debug_info && num != 0) 2328214082Sdim { 2329214082Sdim if (!seen_first_offset) 2330214082Sdim { 2331214082Sdim /* This is the first location list. */ 2332214082Sdim last_offset = debug_information [i].loc_offsets [0]; 2333214082Sdim first = i; 2334214082Sdim seen_first_offset = 1; 2335214082Sdim j = 1; 2336214082Sdim } 2337214082Sdim else 2338214082Sdim j = 0; 2339214082Sdim 2340214082Sdim for (; j < num; j++) 2341214082Sdim { 2342214082Sdim if (last_offset > 2343214082Sdim debug_information [i].loc_offsets [j]) 2344214082Sdim { 2345214082Sdim use_debug_info = 0; 2346214082Sdim break; 2347214082Sdim } 2348214082Sdim last_offset = debug_information [i].loc_offsets [j]; 2349214082Sdim } 2350214082Sdim } 2351214082Sdim } 2352214082Sdim 2353214082Sdim if (!use_debug_info) 2354214082Sdim /* FIXME: Should we handle this case? */ 2355214082Sdim error (_("Location lists in .debug_info section aren't in ascending order!\n")); 2356214082Sdim 2357214082Sdim if (!seen_first_offset) 2358214082Sdim error (_("No location lists in .debug_info section!\n")); 2359214082Sdim 2360214082Sdim /* DWARF sections under Mach-O have non-zero addresses. */ 2361214634Sdim if (debug_information [first].num_loc_offsets > 0 2362214634Sdim && debug_information [first].loc_offsets [0] != section->address) 2363214082Sdim warn (_("Location lists in %s section start at 0x%lx\n"), 2364214082Sdim section->name, debug_information [first].loc_offsets [0]); 2365214082Sdim 2366214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2367214082Sdim printf (_(" Offset Begin End Expression\n")); 2368214082Sdim 2369214082Sdim seen_first_offset = 0; 2370214082Sdim for (i = first; i < num_debug_info_entries; i++) 2371214082Sdim { 2372214082Sdim unsigned long begin; 2373214082Sdim unsigned long end; 2374214082Sdim unsigned short length; 2375214082Sdim unsigned long offset; 2376214082Sdim unsigned int pointer_size; 2377214082Sdim unsigned long cu_offset; 2378214082Sdim unsigned long base_address; 2379214082Sdim int need_frame_base; 2380214082Sdim int has_frame_base; 2381214082Sdim 2382214082Sdim pointer_size = debug_information [i].pointer_size; 2383214082Sdim cu_offset = debug_information [i].cu_offset; 2384214082Sdim 2385214082Sdim for (j = 0; j < debug_information [i].num_loc_offsets; j++) 2386214082Sdim { 2387214082Sdim has_frame_base = debug_information [i].have_frame_base [j]; 2388214082Sdim /* DWARF sections under Mach-O have non-zero addresses. */ 2389214082Sdim offset = debug_information [i].loc_offsets [j] - section->address; 2390214082Sdim next = section_begin + offset; 2391214082Sdim base_address = debug_information [i].base_address; 2392214082Sdim 2393214082Sdim if (!seen_first_offset) 2394214082Sdim seen_first_offset = 1; 2395214082Sdim else 2396214082Sdim { 2397214082Sdim if (start < next) 2398214082Sdim warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"), 2399214082Sdim (long)(start - section_begin), (long)(next - section_begin)); 2400214082Sdim else if (start > next) 2401214082Sdim warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"), 2402214082Sdim (long)(start - section_begin), (long)(next - section_begin)); 2403214082Sdim } 2404214082Sdim start = next; 2405214082Sdim 2406214082Sdim if (offset >= bytes) 2407214082Sdim { 2408214082Sdim warn (_("Offset 0x%lx is bigger than .debug_loc section size.\n"), 2409214082Sdim offset); 2410214082Sdim continue; 2411214082Sdim } 2412214082Sdim 2413214082Sdim while (1) 2414214082Sdim { 2415214082Sdim if (start + 2 * pointer_size > section_end) 2416214082Sdim { 2417214082Sdim warn (_("Location list starting at offset 0x%lx is not terminated.\n"), 2418214082Sdim offset); 2419214082Sdim break; 2420214082Sdim } 2421214082Sdim 2422214082Sdim begin = byte_get (start, pointer_size); 2423214082Sdim start += pointer_size; 2424214082Sdim end = byte_get (start, pointer_size); 2425214082Sdim start += pointer_size; 2426214082Sdim 2427214082Sdim if (begin == 0 && end == 0) 2428214082Sdim { 2429214082Sdim printf (_(" %8.8lx <End of list>\n"), offset); 2430214082Sdim break; 2431214082Sdim } 2432214082Sdim 2433214082Sdim /* Check base address specifiers. */ 2434214082Sdim if (begin == -1UL && end != -1UL) 2435214082Sdim { 2436214082Sdim base_address = end; 2437214082Sdim printf (_(" %8.8lx %8.8lx %8.8lx (base address)\n"), 2438214082Sdim offset, begin, end); 2439214082Sdim continue; 2440214082Sdim } 2441214082Sdim 2442214082Sdim if (start + 2 > section_end) 2443214082Sdim { 2444214082Sdim warn (_("Location list starting at offset 0x%lx is not terminated.\n"), 2445214082Sdim offset); 2446214082Sdim break; 2447214082Sdim } 2448214082Sdim 2449214082Sdim length = byte_get (start, 2); 2450214082Sdim start += 2; 2451214082Sdim 2452214082Sdim if (start + length > section_end) 2453214082Sdim { 2454214082Sdim warn (_("Location list starting at offset 0x%lx is not terminated.\n"), 2455214082Sdim offset); 2456214082Sdim break; 2457214082Sdim } 2458214082Sdim 2459214082Sdim printf (" %8.8lx %8.8lx %8.8lx (", 2460214082Sdim offset, begin + base_address, end + base_address); 2461214082Sdim need_frame_base = decode_location_expression (start, 2462214082Sdim pointer_size, 2463214082Sdim length, 2464214082Sdim cu_offset); 2465214082Sdim putchar (')'); 2466214082Sdim 2467214082Sdim if (need_frame_base && !has_frame_base) 2468214082Sdim printf (_(" [without DW_AT_frame_base]")); 2469214082Sdim 2470214082Sdim if (begin == end) 2471214082Sdim fputs (_(" (start == end)"), stdout); 2472214082Sdim else if (begin > end) 2473214082Sdim fputs (_(" (start > end)"), stdout); 2474214082Sdim 2475214082Sdim putchar ('\n'); 2476214082Sdim 2477214082Sdim start += length; 2478214082Sdim } 2479214082Sdim } 2480214082Sdim } 2481214082Sdim return 1; 2482214082Sdim} 2483214082Sdim 2484214082Sdimstatic int 2485214082Sdimdisplay_debug_str (struct dwarf_section *section, 2486214082Sdim void *file ATTRIBUTE_UNUSED) 2487214082Sdim{ 2488214082Sdim unsigned char *start = section->start; 2489214082Sdim unsigned long bytes = section->size; 2490214082Sdim dwarf_vma addr = section->address; 2491214082Sdim 2492214082Sdim if (bytes == 0) 2493214082Sdim { 2494214082Sdim printf (_("\nThe %s section is empty.\n"), section->name); 2495214082Sdim return 0; 2496214082Sdim } 2497214082Sdim 2498214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2499214082Sdim 2500214082Sdim while (bytes) 2501214082Sdim { 2502214082Sdim int j; 2503214082Sdim int k; 2504214082Sdim int lbytes; 2505214082Sdim 2506214082Sdim lbytes = (bytes > 16 ? 16 : bytes); 2507214082Sdim 2508214082Sdim printf (" 0x%8.8lx ", (unsigned long) addr); 2509214082Sdim 2510214082Sdim for (j = 0; j < 16; j++) 2511214082Sdim { 2512214082Sdim if (j < lbytes) 2513214082Sdim printf ("%2.2x", start[j]); 2514214082Sdim else 2515214082Sdim printf (" "); 2516214082Sdim 2517214082Sdim if ((j & 3) == 3) 2518214082Sdim printf (" "); 2519214082Sdim } 2520214082Sdim 2521214082Sdim for (j = 0; j < lbytes; j++) 2522214082Sdim { 2523214082Sdim k = start[j]; 2524214082Sdim if (k >= ' ' && k < 0x80) 2525214082Sdim printf ("%c", k); 2526214082Sdim else 2527214082Sdim printf ("."); 2528214082Sdim } 2529214082Sdim 2530214082Sdim putchar ('\n'); 2531214082Sdim 2532214082Sdim start += lbytes; 2533214082Sdim addr += lbytes; 2534214082Sdim bytes -= lbytes; 2535214082Sdim } 2536214082Sdim 2537214082Sdim putchar ('\n'); 2538214082Sdim 2539214082Sdim return 1; 2540214082Sdim} 2541214082Sdim 2542214082Sdimstatic int 2543214082Sdimdisplay_debug_info (struct dwarf_section *section, void *file) 2544214082Sdim{ 2545214082Sdim return process_debug_info (section, file, 0); 2546214082Sdim} 2547214082Sdim 2548214082Sdim 2549214082Sdimstatic int 2550214082Sdimdisplay_debug_aranges (struct dwarf_section *section, 2551214082Sdim void *file ATTRIBUTE_UNUSED) 2552214082Sdim{ 2553214082Sdim unsigned char *start = section->start; 2554214082Sdim unsigned char *end = start + section->size; 2555214082Sdim 2556214082Sdim printf (_("The section %s contains:\n\n"), section->name); 2557214082Sdim 2558214082Sdim while (start < end) 2559214082Sdim { 2560214082Sdim unsigned char *hdrptr; 2561214082Sdim DWARF2_Internal_ARange arange; 2562214082Sdim unsigned char *ranges; 2563214082Sdim unsigned long length; 2564214082Sdim unsigned long address; 2565214634Sdim unsigned char address_size; 2566214082Sdim int excess; 2567214082Sdim int offset_size; 2568214082Sdim int initial_length_size; 2569214082Sdim 2570214082Sdim hdrptr = start; 2571214082Sdim 2572214082Sdim arange.ar_length = byte_get (hdrptr, 4); 2573214082Sdim hdrptr += 4; 2574214082Sdim 2575214082Sdim if (arange.ar_length == 0xffffffff) 2576214082Sdim { 2577214082Sdim arange.ar_length = byte_get (hdrptr, 8); 2578214082Sdim hdrptr += 8; 2579214082Sdim offset_size = 8; 2580214082Sdim initial_length_size = 12; 2581214082Sdim } 2582214082Sdim else 2583214082Sdim { 2584214082Sdim offset_size = 4; 2585214082Sdim initial_length_size = 4; 2586214082Sdim } 2587214082Sdim 2588214082Sdim arange.ar_version = byte_get (hdrptr, 2); 2589214082Sdim hdrptr += 2; 2590214082Sdim 2591214082Sdim arange.ar_info_offset = byte_get (hdrptr, offset_size); 2592214082Sdim hdrptr += offset_size; 2593214082Sdim 2594214082Sdim arange.ar_pointer_size = byte_get (hdrptr, 1); 2595214082Sdim hdrptr += 1; 2596214082Sdim 2597214082Sdim arange.ar_segment_size = byte_get (hdrptr, 1); 2598214082Sdim hdrptr += 1; 2599214082Sdim 2600214082Sdim if (arange.ar_version != 2 && arange.ar_version != 3) 2601214082Sdim { 2602214082Sdim warn (_("Only DWARF 2 and 3 aranges are currently supported.\n")); 2603214082Sdim break; 2604214082Sdim } 2605214082Sdim 2606214082Sdim printf (_(" Length: %ld\n"), arange.ar_length); 2607214082Sdim printf (_(" Version: %d\n"), arange.ar_version); 2608214082Sdim printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset); 2609214082Sdim printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size); 2610214082Sdim printf (_(" Segment Size: %d\n"), arange.ar_segment_size); 2611214082Sdim 2612214634Sdim address_size = arange.ar_pointer_size + arange.ar_segment_size; 2613214082Sdim 2614214634Sdim /* The DWARF spec does not require that the address size be a power 2615214634Sdim of two, but we do. This will have to change if we ever encounter 2616214634Sdim an uneven architecture. */ 2617214634Sdim if ((address_size & (address_size - 1)) != 0) 2618214634Sdim { 2619214634Sdim warn (_("Pointer size + Segment size is not a power of two.\n")); 2620214634Sdim break; 2621214634Sdim } 2622214634Sdim 2623214634Sdim if (address_size > 4) 2624214634Sdim printf (_("\n Address Length\n")); 2625214634Sdim else 2626214634Sdim printf (_("\n Address Length\n")); 2627214634Sdim 2628214082Sdim ranges = hdrptr; 2629214082Sdim 2630214634Sdim /* Must pad to an alignment boundary that is twice the address size. */ 2631214634Sdim excess = (hdrptr - start) % (2 * address_size); 2632214082Sdim if (excess) 2633214634Sdim ranges += (2 * address_size) - excess; 2634214082Sdim 2635214082Sdim start += arange.ar_length + initial_length_size; 2636214082Sdim 2637214634Sdim while (ranges + 2 * address_size <= start) 2638214082Sdim { 2639214634Sdim address = byte_get (ranges, address_size); 2640214082Sdim 2641214634Sdim ranges += address_size; 2642214082Sdim 2643214634Sdim length = byte_get (ranges, address_size); 2644214082Sdim 2645214634Sdim ranges += address_size; 2646214082Sdim 2647214634Sdim if (address_size > 4) 2648214634Sdim printf (" 0x%16.16lx 0x%lx\n", address, length); 2649214634Sdim else 2650214634Sdim printf (" 0x%8.8lx 0x%lx\n", address, length); 2651214082Sdim } 2652214082Sdim } 2653214082Sdim 2654214082Sdim printf ("\n"); 2655214082Sdim 2656214082Sdim return 1; 2657214082Sdim} 2658214082Sdim 2659214082Sdimstatic int 2660214082Sdimdisplay_debug_ranges (struct dwarf_section *section, 2661214082Sdim void *file ATTRIBUTE_UNUSED) 2662214082Sdim{ 2663214082Sdim unsigned char *start = section->start; 2664214082Sdim unsigned char *section_end; 2665214082Sdim unsigned long bytes; 2666214082Sdim unsigned char *section_begin = start; 2667214082Sdim unsigned int num_range_list = 0; 2668214082Sdim unsigned long last_offset = 0; 2669214082Sdim unsigned int first = 0; 2670214082Sdim unsigned int i; 2671214082Sdim unsigned int j; 2672214082Sdim int seen_first_offset = 0; 2673214082Sdim int use_debug_info = 1; 2674214082Sdim unsigned char *next; 2675214082Sdim 2676214082Sdim bytes = section->size; 2677214082Sdim section_end = start + bytes; 2678214082Sdim 2679214082Sdim if (bytes == 0) 2680214082Sdim { 2681214082Sdim printf (_("\nThe %s section is empty.\n"), section->name); 2682214082Sdim return 0; 2683214082Sdim } 2684214082Sdim 2685214082Sdim load_debug_info (file); 2686214082Sdim 2687214082Sdim /* Check the order of range list in .debug_info section. If 2688214082Sdim offsets of range lists are in the ascending order, we can 2689214082Sdim use `debug_information' directly. */ 2690214082Sdim for (i = 0; i < num_debug_info_entries; i++) 2691214082Sdim { 2692214082Sdim unsigned int num; 2693214082Sdim 2694214082Sdim num = debug_information [i].num_range_lists; 2695214082Sdim num_range_list += num; 2696214082Sdim 2697214082Sdim /* Check if we can use `debug_information' directly. */ 2698214082Sdim if (use_debug_info && num != 0) 2699214082Sdim { 2700214082Sdim if (!seen_first_offset) 2701214082Sdim { 2702214082Sdim /* This is the first range list. */ 2703214082Sdim last_offset = debug_information [i].range_lists [0]; 2704214082Sdim first = i; 2705214082Sdim seen_first_offset = 1; 2706214082Sdim j = 1; 2707214082Sdim } 2708214082Sdim else 2709214082Sdim j = 0; 2710214082Sdim 2711214082Sdim for (; j < num; j++) 2712214082Sdim { 2713214082Sdim if (last_offset > 2714214082Sdim debug_information [i].range_lists [j]) 2715214082Sdim { 2716214082Sdim use_debug_info = 0; 2717214082Sdim break; 2718214082Sdim } 2719214082Sdim last_offset = debug_information [i].range_lists [j]; 2720214082Sdim } 2721214082Sdim } 2722214082Sdim } 2723214082Sdim 2724214082Sdim if (!use_debug_info) 2725214082Sdim /* FIXME: Should we handle this case? */ 2726214082Sdim error (_("Range lists in .debug_info section aren't in ascending order!\n")); 2727214082Sdim 2728214082Sdim if (!seen_first_offset) 2729214082Sdim error (_("No range lists in .debug_info section!\n")); 2730214082Sdim 2731214082Sdim /* DWARF sections under Mach-O have non-zero addresses. */ 2732214634Sdim if (debug_information [first].num_range_lists > 0 2733214634Sdim && debug_information [first].range_lists [0] != section->address) 2734214082Sdim warn (_("Range lists in %s section start at 0x%lx\n"), 2735214082Sdim section->name, debug_information [first].range_lists [0]); 2736214082Sdim 2737214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2738214082Sdim printf (_(" Offset Begin End\n")); 2739214082Sdim 2740214082Sdim seen_first_offset = 0; 2741214082Sdim for (i = first; i < num_debug_info_entries; i++) 2742214082Sdim { 2743214082Sdim unsigned long begin; 2744214082Sdim unsigned long end; 2745214082Sdim unsigned long offset; 2746214082Sdim unsigned int pointer_size; 2747214082Sdim unsigned long base_address; 2748214082Sdim 2749214082Sdim pointer_size = debug_information [i].pointer_size; 2750214082Sdim 2751214082Sdim for (j = 0; j < debug_information [i].num_range_lists; j++) 2752214082Sdim { 2753214082Sdim /* DWARF sections under Mach-O have non-zero addresses. */ 2754214082Sdim offset = debug_information [i].range_lists [j] - section->address; 2755214082Sdim next = section_begin + offset; 2756214082Sdim base_address = debug_information [i].base_address; 2757214082Sdim 2758214082Sdim if (!seen_first_offset) 2759214082Sdim seen_first_offset = 1; 2760214082Sdim else 2761214082Sdim { 2762214082Sdim if (start < next) 2763214082Sdim warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"), 2764214082Sdim (long)(start - section_begin), 2765214082Sdim (long)(next - section_begin), section->name); 2766214082Sdim else if (start > next) 2767214082Sdim warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"), 2768214082Sdim (long)(start - section_begin), 2769214082Sdim (long)(next - section_begin), section->name); 2770214082Sdim } 2771214082Sdim start = next; 2772214082Sdim 2773214082Sdim while (1) 2774214082Sdim { 2775214082Sdim begin = byte_get (start, pointer_size); 2776214082Sdim start += pointer_size; 2777214082Sdim end = byte_get (start, pointer_size); 2778214082Sdim start += pointer_size; 2779214082Sdim 2780214082Sdim if (begin == 0 && end == 0) 2781214082Sdim { 2782214082Sdim printf (_(" %8.8lx <End of list>\n"), offset); 2783214082Sdim break; 2784214082Sdim } 2785214082Sdim 2786214082Sdim /* Check base address specifiers. */ 2787214082Sdim if (begin == -1UL && end != -1UL) 2788214082Sdim { 2789214082Sdim base_address = end; 2790214082Sdim printf (" %8.8lx %8.8lx %8.8lx (base address)\n", 2791214082Sdim offset, begin, end); 2792214082Sdim continue; 2793214082Sdim } 2794214082Sdim 2795214082Sdim printf (" %8.8lx %8.8lx %8.8lx", 2796214082Sdim offset, begin + base_address, end + base_address); 2797214082Sdim 2798214082Sdim if (begin == end) 2799214082Sdim fputs (_(" (start == end)"), stdout); 2800214082Sdim else if (begin > end) 2801214082Sdim fputs (_(" (start > end)"), stdout); 2802214082Sdim 2803214082Sdim putchar ('\n'); 2804214082Sdim } 2805214082Sdim } 2806214082Sdim } 2807214082Sdim putchar ('\n'); 2808214082Sdim return 1; 2809214082Sdim} 2810214082Sdim 2811214082Sdimtypedef struct Frame_Chunk 2812214082Sdim{ 2813214082Sdim struct Frame_Chunk *next; 2814214082Sdim unsigned char *chunk_start; 2815214082Sdim int ncols; 2816214082Sdim /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */ 2817214082Sdim short int *col_type; 2818214082Sdim int *col_offset; 2819214082Sdim char *augmentation; 2820214082Sdim unsigned int code_factor; 2821214082Sdim int data_factor; 2822214082Sdim unsigned long pc_begin; 2823214082Sdim unsigned long pc_range; 2824214082Sdim int cfa_reg; 2825214082Sdim int cfa_offset; 2826214082Sdim int ra; 2827214082Sdim unsigned char fde_encoding; 2828214082Sdim unsigned char cfa_exp; 2829214082Sdim} 2830214082SdimFrame_Chunk; 2831214082Sdim 2832214082Sdim/* A marker for a col_type that means this column was never referenced 2833214082Sdim in the frame info. */ 2834214082Sdim#define DW_CFA_unreferenced (-1) 2835214082Sdim 2836214082Sdimstatic void 2837214082Sdimframe_need_space (Frame_Chunk *fc, int reg) 2838214082Sdim{ 2839214082Sdim int prev = fc->ncols; 2840214082Sdim 2841214082Sdim if (reg < fc->ncols) 2842214082Sdim return; 2843214082Sdim 2844214082Sdim fc->ncols = reg + 1; 2845214082Sdim fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int)); 2846214082Sdim fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, sizeof (int)); 2847214082Sdim 2848214082Sdim while (prev < fc->ncols) 2849214082Sdim { 2850214082Sdim fc->col_type[prev] = DW_CFA_unreferenced; 2851214082Sdim fc->col_offset[prev] = 0; 2852214082Sdim prev++; 2853214082Sdim } 2854214082Sdim} 2855214082Sdim 2856214082Sdimstatic void 2857214082Sdimframe_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs) 2858214082Sdim{ 2859214082Sdim int r; 2860214082Sdim char tmp[100]; 2861214082Sdim 2862214082Sdim if (*max_regs < fc->ncols) 2863214082Sdim *max_regs = fc->ncols; 2864214082Sdim 2865214082Sdim if (*need_col_headers) 2866214082Sdim { 2867214082Sdim *need_col_headers = 0; 2868214082Sdim 2869214082Sdim printf (" LOC CFA "); 2870214082Sdim 2871214082Sdim for (r = 0; r < *max_regs; r++) 2872214082Sdim if (fc->col_type[r] != DW_CFA_unreferenced) 2873214082Sdim { 2874214082Sdim if (r == fc->ra) 2875214082Sdim printf ("ra "); 2876214082Sdim else 2877214082Sdim printf ("r%-4d", r); 2878214082Sdim } 2879214082Sdim 2880214082Sdim printf ("\n"); 2881214082Sdim } 2882214082Sdim 2883214082Sdim printf ("%08lx ", fc->pc_begin); 2884214082Sdim if (fc->cfa_exp) 2885214082Sdim strcpy (tmp, "exp"); 2886214082Sdim else 2887214082Sdim sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset); 2888214082Sdim printf ("%-8s ", tmp); 2889214082Sdim 2890214082Sdim for (r = 0; r < fc->ncols; r++) 2891214082Sdim { 2892214082Sdim if (fc->col_type[r] != DW_CFA_unreferenced) 2893214082Sdim { 2894214082Sdim switch (fc->col_type[r]) 2895214082Sdim { 2896214082Sdim case DW_CFA_undefined: 2897214082Sdim strcpy (tmp, "u"); 2898214082Sdim break; 2899214082Sdim case DW_CFA_same_value: 2900214082Sdim strcpy (tmp, "s"); 2901214082Sdim break; 2902214082Sdim case DW_CFA_offset: 2903214082Sdim sprintf (tmp, "c%+d", fc->col_offset[r]); 2904214082Sdim break; 2905214082Sdim case DW_CFA_val_offset: 2906214082Sdim sprintf (tmp, "v%+d", fc->col_offset[r]); 2907214082Sdim break; 2908214082Sdim case DW_CFA_register: 2909214082Sdim sprintf (tmp, "r%d", fc->col_offset[r]); 2910214082Sdim break; 2911214082Sdim case DW_CFA_expression: 2912214082Sdim strcpy (tmp, "exp"); 2913214082Sdim break; 2914214082Sdim case DW_CFA_val_expression: 2915214082Sdim strcpy (tmp, "vexp"); 2916214082Sdim break; 2917214082Sdim default: 2918214082Sdim strcpy (tmp, "n/a"); 2919214082Sdim break; 2920214082Sdim } 2921214082Sdim printf ("%-5s", tmp); 2922214082Sdim } 2923214082Sdim } 2924214082Sdim printf ("\n"); 2925214082Sdim} 2926214082Sdim 2927214082Sdimstatic int 2928214082Sdimsize_of_encoded_value (int encoding) 2929214082Sdim{ 2930214082Sdim switch (encoding & 0x7) 2931214082Sdim { 2932214082Sdim default: /* ??? */ 2933214082Sdim case 0: return eh_addr_size; 2934214082Sdim case 2: return 2; 2935214082Sdim case 3: return 4; 2936214082Sdim case 4: return 8; 2937214082Sdim } 2938214082Sdim} 2939214082Sdim 2940214082Sdimstatic dwarf_vma 2941214082Sdimget_encoded_value (unsigned char *data, int encoding) 2942214082Sdim{ 2943214082Sdim int size = size_of_encoded_value (encoding); 2944214634Sdim 2945214082Sdim if (encoding & DW_EH_PE_signed) 2946214082Sdim return byte_get_signed (data, size); 2947214082Sdim else 2948214082Sdim return byte_get (data, size); 2949214082Sdim} 2950214082Sdim 2951214082Sdim#define GET(N) byte_get (start, N); start += N 2952214082Sdim#define LEB() read_leb128 (start, & length_return, 0); start += length_return 2953214082Sdim#define SLEB() read_leb128 (start, & length_return, 1); start += length_return 2954214082Sdim 2955214082Sdimstatic int 2956214082Sdimdisplay_debug_frames (struct dwarf_section *section, 2957214082Sdim void *file ATTRIBUTE_UNUSED) 2958214082Sdim{ 2959214082Sdim unsigned char *start = section->start; 2960214082Sdim unsigned char *end = start + section->size; 2961214082Sdim unsigned char *section_start = start; 2962214082Sdim Frame_Chunk *chunks = 0; 2963214082Sdim Frame_Chunk *remembered_state = 0; 2964214082Sdim Frame_Chunk *rs; 2965214082Sdim int is_eh = strcmp (section->name, ".eh_frame") == 0; 2966214082Sdim unsigned int length_return; 2967214082Sdim int max_regs = 0; 2968214082Sdim 2969214082Sdim printf (_("The section %s contains:\n"), section->name); 2970214082Sdim 2971214082Sdim while (start < end) 2972214082Sdim { 2973214082Sdim unsigned char *saved_start; 2974214082Sdim unsigned char *block_end; 2975214082Sdim unsigned long length; 2976214082Sdim unsigned long cie_id; 2977214082Sdim Frame_Chunk *fc; 2978214082Sdim Frame_Chunk *cie; 2979214082Sdim int need_col_headers = 1; 2980214082Sdim unsigned char *augmentation_data = NULL; 2981214082Sdim unsigned long augmentation_data_len = 0; 2982214082Sdim int encoded_ptr_size = eh_addr_size; 2983214082Sdim int offset_size; 2984214082Sdim int initial_length_size; 2985214082Sdim 2986214082Sdim saved_start = start; 2987214082Sdim length = byte_get (start, 4); start += 4; 2988214082Sdim 2989214082Sdim if (length == 0) 2990214082Sdim { 2991214082Sdim printf ("\n%08lx ZERO terminator\n\n", 2992214082Sdim (unsigned long)(saved_start - section_start)); 2993214634Sdim continue; 2994214082Sdim } 2995214082Sdim 2996214082Sdim if (length == 0xffffffff) 2997214082Sdim { 2998214082Sdim length = byte_get (start, 8); 2999214082Sdim start += 8; 3000214082Sdim offset_size = 8; 3001214082Sdim initial_length_size = 12; 3002214082Sdim } 3003214082Sdim else 3004214082Sdim { 3005214082Sdim offset_size = 4; 3006214082Sdim initial_length_size = 4; 3007214082Sdim } 3008214082Sdim 3009214082Sdim block_end = saved_start + length + initial_length_size; 3010214634Sdim if (block_end > end) 3011214634Sdim { 3012214634Sdim warn ("Invalid length %#08lx in FDE at %#08lx\n", 3013214634Sdim length, (unsigned long)(saved_start - section_start)); 3014214634Sdim block_end = end; 3015214634Sdim } 3016214082Sdim cie_id = byte_get (start, offset_size); start += offset_size; 3017214082Sdim 3018214082Sdim if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID)) 3019214082Sdim { 3020214082Sdim int version; 3021214082Sdim 3022214082Sdim fc = xmalloc (sizeof (Frame_Chunk)); 3023214082Sdim memset (fc, 0, sizeof (Frame_Chunk)); 3024214082Sdim 3025214082Sdim fc->next = chunks; 3026214082Sdim chunks = fc; 3027214082Sdim fc->chunk_start = saved_start; 3028214082Sdim fc->ncols = 0; 3029214082Sdim fc->col_type = xmalloc (sizeof (short int)); 3030214082Sdim fc->col_offset = xmalloc (sizeof (int)); 3031214082Sdim frame_need_space (fc, max_regs-1); 3032214082Sdim 3033214082Sdim version = *start++; 3034214082Sdim 3035214082Sdim fc->augmentation = (char *) start; 3036214082Sdim start = (unsigned char *) strchr ((char *) start, '\0') + 1; 3037214082Sdim 3038214082Sdim if (fc->augmentation[0] == 'z') 3039214082Sdim { 3040214082Sdim fc->code_factor = LEB (); 3041214082Sdim fc->data_factor = SLEB (); 3042214082Sdim if (version == 1) 3043214082Sdim { 3044214082Sdim fc->ra = GET (1); 3045214082Sdim } 3046214082Sdim else 3047214082Sdim { 3048214082Sdim fc->ra = LEB (); 3049214082Sdim } 3050214082Sdim augmentation_data_len = LEB (); 3051214082Sdim augmentation_data = start; 3052214082Sdim start += augmentation_data_len; 3053214082Sdim } 3054214082Sdim else if (strcmp (fc->augmentation, "eh") == 0) 3055214082Sdim { 3056214082Sdim start += eh_addr_size; 3057214082Sdim fc->code_factor = LEB (); 3058214082Sdim fc->data_factor = SLEB (); 3059214082Sdim if (version == 1) 3060214082Sdim { 3061214082Sdim fc->ra = GET (1); 3062214082Sdim } 3063214082Sdim else 3064214082Sdim { 3065214082Sdim fc->ra = LEB (); 3066214082Sdim } 3067214082Sdim } 3068214082Sdim else 3069214082Sdim { 3070214082Sdim fc->code_factor = LEB (); 3071214082Sdim fc->data_factor = SLEB (); 3072214082Sdim if (version == 1) 3073214082Sdim { 3074214082Sdim fc->ra = GET (1); 3075214082Sdim } 3076214082Sdim else 3077214082Sdim { 3078214082Sdim fc->ra = LEB (); 3079214082Sdim } 3080214082Sdim } 3081214082Sdim cie = fc; 3082214082Sdim 3083214082Sdim if (do_debug_frames_interp) 3084214082Sdim printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n", 3085214082Sdim (unsigned long)(saved_start - section_start), length, cie_id, 3086214082Sdim fc->augmentation, fc->code_factor, fc->data_factor, 3087214082Sdim fc->ra); 3088214082Sdim else 3089214082Sdim { 3090214082Sdim printf ("\n%08lx %08lx %08lx CIE\n", 3091214082Sdim (unsigned long)(saved_start - section_start), length, cie_id); 3092214082Sdim printf (" Version: %d\n", version); 3093214082Sdim printf (" Augmentation: \"%s\"\n", fc->augmentation); 3094214082Sdim printf (" Code alignment factor: %u\n", fc->code_factor); 3095214082Sdim printf (" Data alignment factor: %d\n", fc->data_factor); 3096214082Sdim printf (" Return address column: %d\n", fc->ra); 3097214082Sdim 3098214082Sdim if (augmentation_data_len) 3099214082Sdim { 3100214082Sdim unsigned long i; 3101214082Sdim printf (" Augmentation data: "); 3102214082Sdim for (i = 0; i < augmentation_data_len; ++i) 3103214082Sdim printf (" %02x", augmentation_data[i]); 3104214082Sdim putchar ('\n'); 3105214082Sdim } 3106214082Sdim putchar ('\n'); 3107214082Sdim } 3108214082Sdim 3109214082Sdim if (augmentation_data_len) 3110214082Sdim { 3111214082Sdim unsigned char *p, *q; 3112214082Sdim p = (unsigned char *) fc->augmentation + 1; 3113214082Sdim q = augmentation_data; 3114214082Sdim 3115214082Sdim while (1) 3116214082Sdim { 3117214082Sdim if (*p == 'L') 3118214082Sdim q++; 3119214082Sdim else if (*p == 'P') 3120214082Sdim q += 1 + size_of_encoded_value (*q); 3121214082Sdim else if (*p == 'R') 3122214082Sdim fc->fde_encoding = *q++; 3123214082Sdim else 3124214082Sdim break; 3125214082Sdim p++; 3126214082Sdim } 3127214082Sdim 3128214082Sdim if (fc->fde_encoding) 3129214082Sdim encoded_ptr_size = size_of_encoded_value (fc->fde_encoding); 3130214082Sdim } 3131214082Sdim 3132214082Sdim frame_need_space (fc, fc->ra); 3133214082Sdim } 3134214082Sdim else 3135214082Sdim { 3136214082Sdim unsigned char *look_for; 3137214082Sdim static Frame_Chunk fde_fc; 3138214082Sdim 3139214082Sdim fc = & fde_fc; 3140214082Sdim memset (fc, 0, sizeof (Frame_Chunk)); 3141214082Sdim 3142214082Sdim look_for = is_eh ? start - 4 - cie_id : section_start + cie_id; 3143214082Sdim 3144214082Sdim for (cie = chunks; cie ; cie = cie->next) 3145214082Sdim if (cie->chunk_start == look_for) 3146214082Sdim break; 3147214082Sdim 3148214082Sdim if (!cie) 3149214082Sdim { 3150214634Sdim warn ("Invalid CIE pointer %#08lx in FDE at %#08lx\n", 3151214082Sdim cie_id, (unsigned long)(saved_start - section_start)); 3152214082Sdim fc->ncols = 0; 3153214082Sdim fc->col_type = xmalloc (sizeof (short int)); 3154214082Sdim fc->col_offset = xmalloc (sizeof (int)); 3155214082Sdim frame_need_space (fc, max_regs - 1); 3156214082Sdim cie = fc; 3157214082Sdim fc->augmentation = ""; 3158214082Sdim fc->fde_encoding = 0; 3159214082Sdim } 3160214082Sdim else 3161214082Sdim { 3162214082Sdim fc->ncols = cie->ncols; 3163214082Sdim fc->col_type = xcmalloc (fc->ncols, sizeof (short int)); 3164214082Sdim fc->col_offset = xcmalloc (fc->ncols, sizeof (int)); 3165214082Sdim memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int)); 3166214082Sdim memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int)); 3167214082Sdim fc->augmentation = cie->augmentation; 3168214082Sdim fc->code_factor = cie->code_factor; 3169214082Sdim fc->data_factor = cie->data_factor; 3170214082Sdim fc->cfa_reg = cie->cfa_reg; 3171214082Sdim fc->cfa_offset = cie->cfa_offset; 3172214082Sdim fc->ra = cie->ra; 3173214082Sdim frame_need_space (fc, max_regs-1); 3174214082Sdim fc->fde_encoding = cie->fde_encoding; 3175214082Sdim } 3176214082Sdim 3177214082Sdim if (fc->fde_encoding) 3178214082Sdim encoded_ptr_size = size_of_encoded_value (fc->fde_encoding); 3179214082Sdim 3180214082Sdim fc->pc_begin = get_encoded_value (start, fc->fde_encoding); 3181214082Sdim if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel 3182214082Sdim /* Don't adjust for relocatable file since there's 3183214082Sdim invariably a pcrel reloc here, which we haven't 3184214082Sdim applied. */ 3185214082Sdim && !is_relocatable) 3186214082Sdim fc->pc_begin += section->address + (start - section_start); 3187214082Sdim start += encoded_ptr_size; 3188214082Sdim fc->pc_range = byte_get (start, encoded_ptr_size); 3189214082Sdim start += encoded_ptr_size; 3190214082Sdim 3191214082Sdim if (cie->augmentation[0] == 'z') 3192214082Sdim { 3193214082Sdim augmentation_data_len = LEB (); 3194214082Sdim augmentation_data = start; 3195214082Sdim start += augmentation_data_len; 3196214082Sdim } 3197214082Sdim 3198214082Sdim printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n", 3199214082Sdim (unsigned long)(saved_start - section_start), length, cie_id, 3200214082Sdim (unsigned long)(cie->chunk_start - section_start), 3201214082Sdim fc->pc_begin, fc->pc_begin + fc->pc_range); 3202214082Sdim if (! do_debug_frames_interp && augmentation_data_len) 3203214082Sdim { 3204214082Sdim unsigned long i; 3205214082Sdim 3206214082Sdim printf (" Augmentation data: "); 3207214082Sdim for (i = 0; i < augmentation_data_len; ++i) 3208214082Sdim printf (" %02x", augmentation_data[i]); 3209214082Sdim putchar ('\n'); 3210214082Sdim putchar ('\n'); 3211214082Sdim } 3212214082Sdim } 3213214082Sdim 3214214082Sdim /* At this point, fc is the current chunk, cie (if any) is set, and 3215214082Sdim we're about to interpret instructions for the chunk. */ 3216214082Sdim /* ??? At present we need to do this always, since this sizes the 3217214082Sdim fc->col_type and fc->col_offset arrays, which we write into always. 3218214082Sdim We should probably split the interpreted and non-interpreted bits 3219214082Sdim into two different routines, since there's so much that doesn't 3220214082Sdim really overlap between them. */ 3221214082Sdim if (1 || do_debug_frames_interp) 3222214082Sdim { 3223214082Sdim /* Start by making a pass over the chunk, allocating storage 3224214082Sdim and taking note of what registers are used. */ 3225214082Sdim unsigned char *tmp = start; 3226214082Sdim 3227214082Sdim while (start < block_end) 3228214082Sdim { 3229214082Sdim unsigned op, opa; 3230214082Sdim unsigned long reg, tmp; 3231214082Sdim 3232214082Sdim op = *start++; 3233214082Sdim opa = op & 0x3f; 3234214082Sdim if (op & 0xc0) 3235214082Sdim op &= 0xc0; 3236214082Sdim 3237214082Sdim /* Warning: if you add any more cases to this switch, be 3238214082Sdim sure to add them to the corresponding switch below. */ 3239214082Sdim switch (op) 3240214082Sdim { 3241214082Sdim case DW_CFA_advance_loc: 3242214082Sdim break; 3243214082Sdim case DW_CFA_offset: 3244214082Sdim LEB (); 3245214082Sdim frame_need_space (fc, opa); 3246214082Sdim fc->col_type[opa] = DW_CFA_undefined; 3247214082Sdim break; 3248214082Sdim case DW_CFA_restore: 3249214082Sdim frame_need_space (fc, opa); 3250214082Sdim fc->col_type[opa] = DW_CFA_undefined; 3251214082Sdim break; 3252214082Sdim case DW_CFA_set_loc: 3253214082Sdim start += encoded_ptr_size; 3254214082Sdim break; 3255214082Sdim case DW_CFA_advance_loc1: 3256214082Sdim start += 1; 3257214082Sdim break; 3258214082Sdim case DW_CFA_advance_loc2: 3259214082Sdim start += 2; 3260214082Sdim break; 3261214082Sdim case DW_CFA_advance_loc4: 3262214082Sdim start += 4; 3263214082Sdim break; 3264214082Sdim case DW_CFA_offset_extended: 3265214082Sdim case DW_CFA_val_offset: 3266214082Sdim reg = LEB (); LEB (); 3267214082Sdim frame_need_space (fc, reg); 3268214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3269214082Sdim break; 3270214082Sdim case DW_CFA_restore_extended: 3271214082Sdim reg = LEB (); 3272214082Sdim frame_need_space (fc, reg); 3273214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3274214082Sdim break; 3275214082Sdim case DW_CFA_undefined: 3276214082Sdim reg = LEB (); 3277214082Sdim frame_need_space (fc, reg); 3278214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3279214082Sdim break; 3280214082Sdim case DW_CFA_same_value: 3281214082Sdim reg = LEB (); 3282214082Sdim frame_need_space (fc, reg); 3283214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3284214082Sdim break; 3285214082Sdim case DW_CFA_register: 3286214082Sdim reg = LEB (); LEB (); 3287214082Sdim frame_need_space (fc, reg); 3288214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3289214082Sdim break; 3290214082Sdim case DW_CFA_def_cfa: 3291214082Sdim LEB (); LEB (); 3292214082Sdim break; 3293214082Sdim case DW_CFA_def_cfa_register: 3294214082Sdim LEB (); 3295214082Sdim break; 3296214082Sdim case DW_CFA_def_cfa_offset: 3297214082Sdim LEB (); 3298214082Sdim break; 3299214082Sdim case DW_CFA_def_cfa_expression: 3300214082Sdim tmp = LEB (); 3301214082Sdim start += tmp; 3302214082Sdim break; 3303214082Sdim case DW_CFA_expression: 3304214082Sdim case DW_CFA_val_expression: 3305214082Sdim reg = LEB (); 3306214082Sdim tmp = LEB (); 3307214082Sdim start += tmp; 3308214082Sdim frame_need_space (fc, reg); 3309214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3310214082Sdim break; 3311214082Sdim case DW_CFA_offset_extended_sf: 3312214082Sdim case DW_CFA_val_offset_sf: 3313214082Sdim reg = LEB (); SLEB (); 3314214082Sdim frame_need_space (fc, reg); 3315214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3316214082Sdim break; 3317214082Sdim case DW_CFA_def_cfa_sf: 3318214082Sdim LEB (); SLEB (); 3319214082Sdim break; 3320214082Sdim case DW_CFA_def_cfa_offset_sf: 3321214082Sdim SLEB (); 3322214082Sdim break; 3323214082Sdim case DW_CFA_MIPS_advance_loc8: 3324214082Sdim start += 8; 3325214082Sdim break; 3326214082Sdim case DW_CFA_GNU_args_size: 3327214082Sdim LEB (); 3328214082Sdim break; 3329214082Sdim case DW_CFA_GNU_negative_offset_extended: 3330214082Sdim reg = LEB (); LEB (); 3331214082Sdim frame_need_space (fc, reg); 3332214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3333214082Sdim 3334214082Sdim default: 3335214082Sdim break; 3336214082Sdim } 3337214082Sdim } 3338214082Sdim start = tmp; 3339214082Sdim } 3340214082Sdim 3341214082Sdim /* Now we know what registers are used, make a second pass over 3342214082Sdim the chunk, this time actually printing out the info. */ 3343214082Sdim 3344214082Sdim while (start < block_end) 3345214082Sdim { 3346214082Sdim unsigned op, opa; 3347214082Sdim unsigned long ul, reg, roffs; 3348214082Sdim long l, ofs; 3349214082Sdim dwarf_vma vma; 3350214082Sdim 3351214082Sdim op = *start++; 3352214082Sdim opa = op & 0x3f; 3353214082Sdim if (op & 0xc0) 3354214082Sdim op &= 0xc0; 3355214082Sdim 3356214082Sdim /* Warning: if you add any more cases to this switch, be 3357214082Sdim sure to add them to the corresponding switch above. */ 3358214082Sdim switch (op) 3359214082Sdim { 3360214082Sdim case DW_CFA_advance_loc: 3361214082Sdim if (do_debug_frames_interp) 3362214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3363214082Sdim else 3364214082Sdim printf (" DW_CFA_advance_loc: %d to %08lx\n", 3365214082Sdim opa * fc->code_factor, 3366214082Sdim fc->pc_begin + opa * fc->code_factor); 3367214082Sdim fc->pc_begin += opa * fc->code_factor; 3368214082Sdim break; 3369214082Sdim 3370214082Sdim case DW_CFA_offset: 3371214082Sdim roffs = LEB (); 3372214082Sdim if (! do_debug_frames_interp) 3373214082Sdim printf (" DW_CFA_offset: r%d at cfa%+ld\n", 3374214082Sdim opa, roffs * fc->data_factor); 3375214082Sdim fc->col_type[opa] = DW_CFA_offset; 3376214082Sdim fc->col_offset[opa] = roffs * fc->data_factor; 3377214082Sdim break; 3378214082Sdim 3379214082Sdim case DW_CFA_restore: 3380214082Sdim if (! do_debug_frames_interp) 3381214082Sdim printf (" DW_CFA_restore: r%d\n", opa); 3382214082Sdim fc->col_type[opa] = cie->col_type[opa]; 3383214082Sdim fc->col_offset[opa] = cie->col_offset[opa]; 3384214082Sdim break; 3385214082Sdim 3386214082Sdim case DW_CFA_set_loc: 3387214082Sdim vma = get_encoded_value (start, fc->fde_encoding); 3388214082Sdim if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel 3389214082Sdim && !is_relocatable) 3390214082Sdim vma += section->address + (start - section_start); 3391214082Sdim start += encoded_ptr_size; 3392214082Sdim if (do_debug_frames_interp) 3393214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3394214082Sdim else 3395214082Sdim printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma); 3396214082Sdim fc->pc_begin = vma; 3397214082Sdim break; 3398214082Sdim 3399214082Sdim case DW_CFA_advance_loc1: 3400214082Sdim ofs = byte_get (start, 1); start += 1; 3401214082Sdim if (do_debug_frames_interp) 3402214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3403214082Sdim else 3404214082Sdim printf (" DW_CFA_advance_loc1: %ld to %08lx\n", 3405214082Sdim ofs * fc->code_factor, 3406214082Sdim fc->pc_begin + ofs * fc->code_factor); 3407214082Sdim fc->pc_begin += ofs * fc->code_factor; 3408214082Sdim break; 3409214082Sdim 3410214082Sdim case DW_CFA_advance_loc2: 3411214082Sdim ofs = byte_get (start, 2); start += 2; 3412214082Sdim if (do_debug_frames_interp) 3413214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3414214082Sdim else 3415214082Sdim printf (" DW_CFA_advance_loc2: %ld to %08lx\n", 3416214082Sdim ofs * fc->code_factor, 3417214082Sdim fc->pc_begin + ofs * fc->code_factor); 3418214082Sdim fc->pc_begin += ofs * fc->code_factor; 3419214082Sdim break; 3420214082Sdim 3421214082Sdim case DW_CFA_advance_loc4: 3422214082Sdim ofs = byte_get (start, 4); start += 4; 3423214082Sdim if (do_debug_frames_interp) 3424214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3425214082Sdim else 3426214082Sdim printf (" DW_CFA_advance_loc4: %ld to %08lx\n", 3427214082Sdim ofs * fc->code_factor, 3428214082Sdim fc->pc_begin + ofs * fc->code_factor); 3429214082Sdim fc->pc_begin += ofs * fc->code_factor; 3430214082Sdim break; 3431214082Sdim 3432214082Sdim case DW_CFA_offset_extended: 3433214082Sdim reg = LEB (); 3434214082Sdim roffs = LEB (); 3435214082Sdim if (! do_debug_frames_interp) 3436214082Sdim printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n", 3437214082Sdim reg, roffs * fc->data_factor); 3438214082Sdim fc->col_type[reg] = DW_CFA_offset; 3439214082Sdim fc->col_offset[reg] = roffs * fc->data_factor; 3440214082Sdim break; 3441214082Sdim 3442214082Sdim case DW_CFA_val_offset: 3443214082Sdim reg = LEB (); 3444214082Sdim roffs = LEB (); 3445214082Sdim if (! do_debug_frames_interp) 3446214082Sdim printf (" DW_CFA_val_offset: r%ld at cfa%+ld\n", 3447214082Sdim reg, roffs * fc->data_factor); 3448214082Sdim fc->col_type[reg] = DW_CFA_val_offset; 3449214082Sdim fc->col_offset[reg] = roffs * fc->data_factor; 3450214082Sdim break; 3451214082Sdim 3452214082Sdim case DW_CFA_restore_extended: 3453214082Sdim reg = LEB (); 3454214082Sdim if (! do_debug_frames_interp) 3455214082Sdim printf (" DW_CFA_restore_extended: r%ld\n", reg); 3456214082Sdim fc->col_type[reg] = cie->col_type[reg]; 3457214082Sdim fc->col_offset[reg] = cie->col_offset[reg]; 3458214082Sdim break; 3459214082Sdim 3460214082Sdim case DW_CFA_undefined: 3461214082Sdim reg = LEB (); 3462214082Sdim if (! do_debug_frames_interp) 3463214082Sdim printf (" DW_CFA_undefined: r%ld\n", reg); 3464214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3465214082Sdim fc->col_offset[reg] = 0; 3466214082Sdim break; 3467214082Sdim 3468214082Sdim case DW_CFA_same_value: 3469214082Sdim reg = LEB (); 3470214082Sdim if (! do_debug_frames_interp) 3471214082Sdim printf (" DW_CFA_same_value: r%ld\n", reg); 3472214082Sdim fc->col_type[reg] = DW_CFA_same_value; 3473214082Sdim fc->col_offset[reg] = 0; 3474214082Sdim break; 3475214082Sdim 3476214082Sdim case DW_CFA_register: 3477214082Sdim reg = LEB (); 3478214082Sdim roffs = LEB (); 3479214082Sdim if (! do_debug_frames_interp) 3480214082Sdim printf (" DW_CFA_register: r%ld in r%ld\n", reg, roffs); 3481214082Sdim fc->col_type[reg] = DW_CFA_register; 3482214082Sdim fc->col_offset[reg] = roffs; 3483214082Sdim break; 3484214082Sdim 3485214082Sdim case DW_CFA_remember_state: 3486214082Sdim if (! do_debug_frames_interp) 3487214082Sdim printf (" DW_CFA_remember_state\n"); 3488214082Sdim rs = xmalloc (sizeof (Frame_Chunk)); 3489214082Sdim rs->ncols = fc->ncols; 3490214082Sdim rs->col_type = xcmalloc (rs->ncols, sizeof (short int)); 3491214082Sdim rs->col_offset = xcmalloc (rs->ncols, sizeof (int)); 3492214082Sdim memcpy (rs->col_type, fc->col_type, rs->ncols); 3493214082Sdim memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int)); 3494214082Sdim rs->next = remembered_state; 3495214082Sdim remembered_state = rs; 3496214082Sdim break; 3497214082Sdim 3498214082Sdim case DW_CFA_restore_state: 3499214082Sdim if (! do_debug_frames_interp) 3500214082Sdim printf (" DW_CFA_restore_state\n"); 3501214082Sdim rs = remembered_state; 3502214082Sdim if (rs) 3503214082Sdim { 3504214082Sdim remembered_state = rs->next; 3505214082Sdim frame_need_space (fc, rs->ncols-1); 3506214082Sdim memcpy (fc->col_type, rs->col_type, rs->ncols); 3507214082Sdim memcpy (fc->col_offset, rs->col_offset, 3508214082Sdim rs->ncols * sizeof (int)); 3509214082Sdim free (rs->col_type); 3510214082Sdim free (rs->col_offset); 3511214082Sdim free (rs); 3512214082Sdim } 3513214082Sdim else if (do_debug_frames_interp) 3514214082Sdim printf ("Mismatched DW_CFA_restore_state\n"); 3515214082Sdim break; 3516214082Sdim 3517214082Sdim case DW_CFA_def_cfa: 3518214082Sdim fc->cfa_reg = LEB (); 3519214082Sdim fc->cfa_offset = LEB (); 3520214082Sdim fc->cfa_exp = 0; 3521214082Sdim if (! do_debug_frames_interp) 3522214082Sdim printf (" DW_CFA_def_cfa: r%d ofs %d\n", 3523214082Sdim fc->cfa_reg, fc->cfa_offset); 3524214082Sdim break; 3525214082Sdim 3526214082Sdim case DW_CFA_def_cfa_register: 3527214082Sdim fc->cfa_reg = LEB (); 3528214082Sdim fc->cfa_exp = 0; 3529214082Sdim if (! do_debug_frames_interp) 3530214082Sdim printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg); 3531214082Sdim break; 3532214082Sdim 3533214082Sdim case DW_CFA_def_cfa_offset: 3534214082Sdim fc->cfa_offset = LEB (); 3535214082Sdim if (! do_debug_frames_interp) 3536214082Sdim printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset); 3537214082Sdim break; 3538214082Sdim 3539214082Sdim case DW_CFA_nop: 3540214082Sdim if (! do_debug_frames_interp) 3541214082Sdim printf (" DW_CFA_nop\n"); 3542214082Sdim break; 3543214082Sdim 3544214082Sdim case DW_CFA_def_cfa_expression: 3545214082Sdim ul = LEB (); 3546214082Sdim if (! do_debug_frames_interp) 3547214082Sdim { 3548214082Sdim printf (" DW_CFA_def_cfa_expression ("); 3549214082Sdim decode_location_expression (start, eh_addr_size, ul, 0); 3550214082Sdim printf (")\n"); 3551214082Sdim } 3552214082Sdim fc->cfa_exp = 1; 3553214082Sdim start += ul; 3554214082Sdim break; 3555214082Sdim 3556214082Sdim case DW_CFA_expression: 3557214082Sdim reg = LEB (); 3558214082Sdim ul = LEB (); 3559214082Sdim if (! do_debug_frames_interp) 3560214082Sdim { 3561214082Sdim printf (" DW_CFA_expression: r%ld (", reg); 3562214082Sdim decode_location_expression (start, eh_addr_size, ul, 0); 3563214082Sdim printf (")\n"); 3564214082Sdim } 3565214082Sdim fc->col_type[reg] = DW_CFA_expression; 3566214082Sdim start += ul; 3567214082Sdim break; 3568214082Sdim 3569214082Sdim case DW_CFA_val_expression: 3570214082Sdim reg = LEB (); 3571214082Sdim ul = LEB (); 3572214082Sdim if (! do_debug_frames_interp) 3573214082Sdim { 3574214082Sdim printf (" DW_CFA_val_expression: r%ld (", reg); 3575214082Sdim decode_location_expression (start, eh_addr_size, ul, 0); 3576214082Sdim printf (")\n"); 3577214082Sdim } 3578214082Sdim fc->col_type[reg] = DW_CFA_val_expression; 3579214082Sdim start += ul; 3580214082Sdim break; 3581214082Sdim 3582214082Sdim case DW_CFA_offset_extended_sf: 3583214082Sdim reg = LEB (); 3584214082Sdim l = SLEB (); 3585214082Sdim frame_need_space (fc, reg); 3586214082Sdim if (! do_debug_frames_interp) 3587214082Sdim printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n", 3588214082Sdim reg, l * fc->data_factor); 3589214082Sdim fc->col_type[reg] = DW_CFA_offset; 3590214082Sdim fc->col_offset[reg] = l * fc->data_factor; 3591214082Sdim break; 3592214082Sdim 3593214082Sdim case DW_CFA_val_offset_sf: 3594214082Sdim reg = LEB (); 3595214082Sdim l = SLEB (); 3596214082Sdim frame_need_space (fc, reg); 3597214082Sdim if (! do_debug_frames_interp) 3598214082Sdim printf (" DW_CFA_val_offset_sf: r%ld at cfa%+ld\n", 3599214082Sdim reg, l * fc->data_factor); 3600214082Sdim fc->col_type[reg] = DW_CFA_val_offset; 3601214082Sdim fc->col_offset[reg] = l * fc->data_factor; 3602214082Sdim break; 3603214082Sdim 3604214082Sdim case DW_CFA_def_cfa_sf: 3605214082Sdim fc->cfa_reg = LEB (); 3606214082Sdim fc->cfa_offset = SLEB (); 3607214082Sdim fc->cfa_offset = fc->cfa_offset * fc->data_factor; 3608214082Sdim fc->cfa_exp = 0; 3609214082Sdim if (! do_debug_frames_interp) 3610214082Sdim printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n", 3611214082Sdim fc->cfa_reg, fc->cfa_offset); 3612214082Sdim break; 3613214082Sdim 3614214082Sdim case DW_CFA_def_cfa_offset_sf: 3615214082Sdim fc->cfa_offset = SLEB (); 3616214082Sdim fc->cfa_offset = fc->cfa_offset * fc->data_factor; 3617214082Sdim if (! do_debug_frames_interp) 3618214082Sdim printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset); 3619214082Sdim break; 3620214082Sdim 3621214082Sdim case DW_CFA_MIPS_advance_loc8: 3622214082Sdim ofs = byte_get (start, 8); start += 8; 3623214082Sdim if (do_debug_frames_interp) 3624214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3625214082Sdim else 3626214082Sdim printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n", 3627214082Sdim ofs * fc->code_factor, 3628214082Sdim fc->pc_begin + ofs * fc->code_factor); 3629214082Sdim fc->pc_begin += ofs * fc->code_factor; 3630214082Sdim break; 3631214082Sdim 3632214082Sdim case DW_CFA_GNU_window_save: 3633214082Sdim if (! do_debug_frames_interp) 3634214082Sdim printf (" DW_CFA_GNU_window_save\n"); 3635214082Sdim break; 3636214082Sdim 3637214082Sdim case DW_CFA_GNU_args_size: 3638214082Sdim ul = LEB (); 3639214082Sdim if (! do_debug_frames_interp) 3640214082Sdim printf (" DW_CFA_GNU_args_size: %ld\n", ul); 3641214082Sdim break; 3642214082Sdim 3643214082Sdim case DW_CFA_GNU_negative_offset_extended: 3644214082Sdim reg = LEB (); 3645214082Sdim l = - LEB (); 3646214082Sdim frame_need_space (fc, reg); 3647214082Sdim if (! do_debug_frames_interp) 3648214082Sdim printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n", 3649214082Sdim reg, l * fc->data_factor); 3650214082Sdim fc->col_type[reg] = DW_CFA_offset; 3651214082Sdim fc->col_offset[reg] = l * fc->data_factor; 3652214082Sdim break; 3653214082Sdim 3654214082Sdim default: 3655214634Sdim if (op >= DW_CFA_lo_user && op <= DW_CFA_hi_user) 3656214634Sdim printf (_(" DW_CFA_??? (User defined call frame op: %#x)\n"), op); 3657214634Sdim else 3658214634Sdim warn (_("unsupported or unknown Dwarf Call Frame Instruction number: %#x\n"), op); 3659214082Sdim start = block_end; 3660214082Sdim } 3661214082Sdim } 3662214082Sdim 3663214082Sdim if (do_debug_frames_interp) 3664214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3665214082Sdim 3666214082Sdim start = block_end; 3667214082Sdim } 3668214082Sdim 3669214082Sdim printf ("\n"); 3670214082Sdim 3671214082Sdim return 1; 3672214082Sdim} 3673214082Sdim 3674214082Sdim#undef GET 3675214082Sdim#undef LEB 3676214082Sdim#undef SLEB 3677214082Sdim 3678214082Sdimstatic int 3679214082Sdimdisplay_debug_not_supported (struct dwarf_section *section, 3680214082Sdim void *file ATTRIBUTE_UNUSED) 3681214082Sdim{ 3682214082Sdim printf (_("Displaying the debug contents of section %s is not yet supported.\n"), 3683214082Sdim section->name); 3684214082Sdim 3685214082Sdim return 1; 3686214082Sdim} 3687214082Sdim 3688214082Sdimvoid * 3689214082Sdimcmalloc (size_t nmemb, size_t size) 3690214082Sdim{ 3691214082Sdim /* Check for overflow. */ 3692214082Sdim if (nmemb >= ~(size_t) 0 / size) 3693214082Sdim return NULL; 3694214082Sdim else 3695214082Sdim return malloc (nmemb * size); 3696214082Sdim} 3697214082Sdim 3698214082Sdimvoid * 3699214082Sdimxcmalloc (size_t nmemb, size_t size) 3700214082Sdim{ 3701214082Sdim /* Check for overflow. */ 3702214082Sdim if (nmemb >= ~(size_t) 0 / size) 3703214082Sdim return NULL; 3704214082Sdim else 3705214082Sdim return xmalloc (nmemb * size); 3706214082Sdim} 3707214082Sdim 3708214082Sdimvoid * 3709214082Sdimxcrealloc (void *ptr, size_t nmemb, size_t size) 3710214082Sdim{ 3711214082Sdim /* Check for overflow. */ 3712214082Sdim if (nmemb >= ~(size_t) 0 / size) 3713214082Sdim return NULL; 3714214082Sdim else 3715214082Sdim return xrealloc (ptr, nmemb * size); 3716214082Sdim} 3717214082Sdim 3718214082Sdimvoid 3719214082Sdimerror (const char *message, ...) 3720214082Sdim{ 3721214082Sdim va_list args; 3722214082Sdim 3723214082Sdim va_start (args, message); 3724214082Sdim fprintf (stderr, _("%s: Error: "), program_name); 3725214082Sdim vfprintf (stderr, message, args); 3726214082Sdim va_end (args); 3727214082Sdim} 3728214082Sdim 3729214082Sdimvoid 3730214082Sdimwarn (const char *message, ...) 3731214082Sdim{ 3732214082Sdim va_list args; 3733214082Sdim 3734214082Sdim va_start (args, message); 3735214082Sdim fprintf (stderr, _("%s: Warning: "), program_name); 3736214082Sdim vfprintf (stderr, message, args); 3737214082Sdim va_end (args); 3738214082Sdim} 3739214082Sdim 3740214082Sdimvoid 3741214082Sdimfree_debug_memory (void) 3742214082Sdim{ 3743214082Sdim enum dwarf_section_display_enum i; 3744214082Sdim 3745214082Sdim free_abbrevs (); 3746214082Sdim 3747214082Sdim for (i = 0; i < max; i++) 3748214082Sdim free_debug_section (i); 3749214082Sdim 3750214082Sdim if (debug_information) 3751214082Sdim { 3752214082Sdim for (i = 0; i < num_debug_info_entries; i++) 3753214082Sdim { 3754214082Sdim if (!debug_information [i].max_loc_offsets) 3755214082Sdim { 3756214082Sdim free (debug_information [i].loc_offsets); 3757214082Sdim free (debug_information [i].have_frame_base); 3758214082Sdim } 3759214082Sdim if (!debug_information [i].max_range_lists) 3760214082Sdim free (debug_information [i].range_lists); 3761214082Sdim } 3762214082Sdim free (debug_information); 3763214082Sdim debug_information = NULL; 3764214082Sdim num_debug_info_entries = 0; 3765214082Sdim } 3766214082Sdim 3767214082Sdim} 3768214082Sdim 3769214082Sdimstruct dwarf_section_display debug_displays[] = 3770214082Sdim{ 3771214082Sdim { { ".debug_abbrev", NULL, 0, 0 }, 3772214082Sdim display_debug_abbrev, 0, 0 }, 3773214082Sdim { { ".debug_aranges", NULL, 0, 0 }, 3774214082Sdim display_debug_aranges, 0, 0 }, 3775214082Sdim { { ".debug_frame", NULL, 0, 0 }, 3776214082Sdim display_debug_frames, 1, 0 }, 3777214082Sdim { { ".debug_info", NULL, 0, 0 }, 3778214082Sdim display_debug_info, 1, 0 }, 3779214082Sdim { { ".debug_line", NULL, 0, 0 }, 3780214082Sdim display_debug_lines, 0, 0 }, 3781214082Sdim { { ".debug_pubnames", NULL, 0, 0 }, 3782214082Sdim display_debug_pubnames, 0, 0 }, 3783214082Sdim { { ".eh_frame", NULL, 0, 0 }, 3784214082Sdim display_debug_frames, 1, 1 }, 3785214082Sdim { { ".debug_macinfo", NULL, 0, 0 }, 3786214082Sdim display_debug_macinfo, 0, 0 }, 3787214082Sdim { { ".debug_str", NULL, 0, 0 }, 3788214082Sdim display_debug_str, 0, 0 }, 3789214082Sdim { { ".debug_loc", NULL, 0, 0 }, 3790214082Sdim display_debug_loc, 0, 0 }, 3791214082Sdim { { ".debug_pubtypes", NULL, 0, 0 }, 3792214082Sdim display_debug_pubnames, 0, 0 }, 3793214082Sdim { { ".debug_ranges", NULL, 0, 0 }, 3794214082Sdim display_debug_ranges, 0, 0 }, 3795214082Sdim { { ".debug_static_func", NULL, 0, 0 }, 3796214082Sdim display_debug_not_supported, 0, 0 }, 3797214082Sdim { { ".debug_static_vars", NULL, 0, 0 }, 3798214082Sdim display_debug_not_supported, 0, 0 }, 3799214082Sdim { { ".debug_types", NULL, 0, 0 }, 3800214082Sdim display_debug_not_supported, 0, 0 }, 3801214082Sdim { { ".debug_weaknames", NULL, 0, 0 }, 3802214082Sdim display_debug_not_supported, 0, 0 } 3803214082Sdim}; 3804