dwarf.c revision 214082
1214082Sdim/* dwarf.c -- display DWARF contents of a BFD binary file 2214082Sdim Copyright 2005, 2006 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 22214082Sdim#include <stdio.h> 23214082Sdim 24214082Sdim#include "dwarf.h" 25214082Sdim 26214082Sdim#include "bucomm.h" 27214082Sdim#include "libiberty.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"; 560214082Sdim default: 561214082Sdim { 562214082Sdim static char buffer[100]; 563214082Sdim 564214082Sdim snprintf (buffer, sizeof (buffer), _("Unknown FORM value: %lx"), form); 565214082Sdim return buffer; 566214082Sdim } 567214082Sdim } 568214082Sdim} 569214082Sdim 570214082Sdimstatic unsigned char * 571214082Sdimdisplay_block (unsigned char *data, unsigned long length) 572214082Sdim{ 573214082Sdim printf (_(" %lu byte block: "), length); 574214082Sdim 575214082Sdim while (length --) 576214082Sdim printf ("%lx ", (unsigned long) byte_get (data++, 1)); 577214082Sdim 578214082Sdim return data; 579214082Sdim} 580214082Sdim 581214082Sdimstatic int 582214082Sdimdecode_location_expression (unsigned char * data, 583214082Sdim unsigned int pointer_size, 584214082Sdim unsigned long length, 585214082Sdim unsigned long cu_offset) 586214082Sdim{ 587214082Sdim unsigned op; 588214082Sdim unsigned int bytes_read; 589214082Sdim unsigned long uvalue; 590214082Sdim unsigned char *end = data + length; 591214082Sdim int need_frame_base = 0; 592214082Sdim 593214082Sdim while (data < end) 594214082Sdim { 595214082Sdim op = *data++; 596214082Sdim 597214082Sdim switch (op) 598214082Sdim { 599214082Sdim case DW_OP_addr: 600214082Sdim printf ("DW_OP_addr: %lx", 601214082Sdim (unsigned long) byte_get (data, pointer_size)); 602214082Sdim data += pointer_size; 603214082Sdim break; 604214082Sdim case DW_OP_deref: 605214082Sdim printf ("DW_OP_deref"); 606214082Sdim break; 607214082Sdim case DW_OP_const1u: 608214082Sdim printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1)); 609214082Sdim break; 610214082Sdim case DW_OP_const1s: 611214082Sdim printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1)); 612214082Sdim break; 613214082Sdim case DW_OP_const2u: 614214082Sdim printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2)); 615214082Sdim data += 2; 616214082Sdim break; 617214082Sdim case DW_OP_const2s: 618214082Sdim printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2)); 619214082Sdim data += 2; 620214082Sdim break; 621214082Sdim case DW_OP_const4u: 622214082Sdim printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4)); 623214082Sdim data += 4; 624214082Sdim break; 625214082Sdim case DW_OP_const4s: 626214082Sdim printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4)); 627214082Sdim data += 4; 628214082Sdim break; 629214082Sdim case DW_OP_const8u: 630214082Sdim printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4), 631214082Sdim (unsigned long) byte_get (data + 4, 4)); 632214082Sdim data += 8; 633214082Sdim break; 634214082Sdim case DW_OP_const8s: 635214082Sdim printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4), 636214082Sdim (long) byte_get (data + 4, 4)); 637214082Sdim data += 8; 638214082Sdim break; 639214082Sdim case DW_OP_constu: 640214082Sdim printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0)); 641214082Sdim data += bytes_read; 642214082Sdim break; 643214082Sdim case DW_OP_consts: 644214082Sdim printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1)); 645214082Sdim data += bytes_read; 646214082Sdim break; 647214082Sdim case DW_OP_dup: 648214082Sdim printf ("DW_OP_dup"); 649214082Sdim break; 650214082Sdim case DW_OP_drop: 651214082Sdim printf ("DW_OP_drop"); 652214082Sdim break; 653214082Sdim case DW_OP_over: 654214082Sdim printf ("DW_OP_over"); 655214082Sdim break; 656214082Sdim case DW_OP_pick: 657214082Sdim printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1)); 658214082Sdim break; 659214082Sdim case DW_OP_swap: 660214082Sdim printf ("DW_OP_swap"); 661214082Sdim break; 662214082Sdim case DW_OP_rot: 663214082Sdim printf ("DW_OP_rot"); 664214082Sdim break; 665214082Sdim case DW_OP_xderef: 666214082Sdim printf ("DW_OP_xderef"); 667214082Sdim break; 668214082Sdim case DW_OP_abs: 669214082Sdim printf ("DW_OP_abs"); 670214082Sdim break; 671214082Sdim case DW_OP_and: 672214082Sdim printf ("DW_OP_and"); 673214082Sdim break; 674214082Sdim case DW_OP_div: 675214082Sdim printf ("DW_OP_div"); 676214082Sdim break; 677214082Sdim case DW_OP_minus: 678214082Sdim printf ("DW_OP_minus"); 679214082Sdim break; 680214082Sdim case DW_OP_mod: 681214082Sdim printf ("DW_OP_mod"); 682214082Sdim break; 683214082Sdim case DW_OP_mul: 684214082Sdim printf ("DW_OP_mul"); 685214082Sdim break; 686214082Sdim case DW_OP_neg: 687214082Sdim printf ("DW_OP_neg"); 688214082Sdim break; 689214082Sdim case DW_OP_not: 690214082Sdim printf ("DW_OP_not"); 691214082Sdim break; 692214082Sdim case DW_OP_or: 693214082Sdim printf ("DW_OP_or"); 694214082Sdim break; 695214082Sdim case DW_OP_plus: 696214082Sdim printf ("DW_OP_plus"); 697214082Sdim break; 698214082Sdim case DW_OP_plus_uconst: 699214082Sdim printf ("DW_OP_plus_uconst: %lu", 700214082Sdim read_leb128 (data, &bytes_read, 0)); 701214082Sdim data += bytes_read; 702214082Sdim break; 703214082Sdim case DW_OP_shl: 704214082Sdim printf ("DW_OP_shl"); 705214082Sdim break; 706214082Sdim case DW_OP_shr: 707214082Sdim printf ("DW_OP_shr"); 708214082Sdim break; 709214082Sdim case DW_OP_shra: 710214082Sdim printf ("DW_OP_shra"); 711214082Sdim break; 712214082Sdim case DW_OP_xor: 713214082Sdim printf ("DW_OP_xor"); 714214082Sdim break; 715214082Sdim case DW_OP_bra: 716214082Sdim printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2)); 717214082Sdim data += 2; 718214082Sdim break; 719214082Sdim case DW_OP_eq: 720214082Sdim printf ("DW_OP_eq"); 721214082Sdim break; 722214082Sdim case DW_OP_ge: 723214082Sdim printf ("DW_OP_ge"); 724214082Sdim break; 725214082Sdim case DW_OP_gt: 726214082Sdim printf ("DW_OP_gt"); 727214082Sdim break; 728214082Sdim case DW_OP_le: 729214082Sdim printf ("DW_OP_le"); 730214082Sdim break; 731214082Sdim case DW_OP_lt: 732214082Sdim printf ("DW_OP_lt"); 733214082Sdim break; 734214082Sdim case DW_OP_ne: 735214082Sdim printf ("DW_OP_ne"); 736214082Sdim break; 737214082Sdim case DW_OP_skip: 738214082Sdim printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2)); 739214082Sdim data += 2; 740214082Sdim break; 741214082Sdim 742214082Sdim case DW_OP_lit0: 743214082Sdim case DW_OP_lit1: 744214082Sdim case DW_OP_lit2: 745214082Sdim case DW_OP_lit3: 746214082Sdim case DW_OP_lit4: 747214082Sdim case DW_OP_lit5: 748214082Sdim case DW_OP_lit6: 749214082Sdim case DW_OP_lit7: 750214082Sdim case DW_OP_lit8: 751214082Sdim case DW_OP_lit9: 752214082Sdim case DW_OP_lit10: 753214082Sdim case DW_OP_lit11: 754214082Sdim case DW_OP_lit12: 755214082Sdim case DW_OP_lit13: 756214082Sdim case DW_OP_lit14: 757214082Sdim case DW_OP_lit15: 758214082Sdim case DW_OP_lit16: 759214082Sdim case DW_OP_lit17: 760214082Sdim case DW_OP_lit18: 761214082Sdim case DW_OP_lit19: 762214082Sdim case DW_OP_lit20: 763214082Sdim case DW_OP_lit21: 764214082Sdim case DW_OP_lit22: 765214082Sdim case DW_OP_lit23: 766214082Sdim case DW_OP_lit24: 767214082Sdim case DW_OP_lit25: 768214082Sdim case DW_OP_lit26: 769214082Sdim case DW_OP_lit27: 770214082Sdim case DW_OP_lit28: 771214082Sdim case DW_OP_lit29: 772214082Sdim case DW_OP_lit30: 773214082Sdim case DW_OP_lit31: 774214082Sdim printf ("DW_OP_lit%d", op - DW_OP_lit0); 775214082Sdim break; 776214082Sdim 777214082Sdim case DW_OP_reg0: 778214082Sdim case DW_OP_reg1: 779214082Sdim case DW_OP_reg2: 780214082Sdim case DW_OP_reg3: 781214082Sdim case DW_OP_reg4: 782214082Sdim case DW_OP_reg5: 783214082Sdim case DW_OP_reg6: 784214082Sdim case DW_OP_reg7: 785214082Sdim case DW_OP_reg8: 786214082Sdim case DW_OP_reg9: 787214082Sdim case DW_OP_reg10: 788214082Sdim case DW_OP_reg11: 789214082Sdim case DW_OP_reg12: 790214082Sdim case DW_OP_reg13: 791214082Sdim case DW_OP_reg14: 792214082Sdim case DW_OP_reg15: 793214082Sdim case DW_OP_reg16: 794214082Sdim case DW_OP_reg17: 795214082Sdim case DW_OP_reg18: 796214082Sdim case DW_OP_reg19: 797214082Sdim case DW_OP_reg20: 798214082Sdim case DW_OP_reg21: 799214082Sdim case DW_OP_reg22: 800214082Sdim case DW_OP_reg23: 801214082Sdim case DW_OP_reg24: 802214082Sdim case DW_OP_reg25: 803214082Sdim case DW_OP_reg26: 804214082Sdim case DW_OP_reg27: 805214082Sdim case DW_OP_reg28: 806214082Sdim case DW_OP_reg29: 807214082Sdim case DW_OP_reg30: 808214082Sdim case DW_OP_reg31: 809214082Sdim printf ("DW_OP_reg%d", op - DW_OP_reg0); 810214082Sdim break; 811214082Sdim 812214082Sdim case DW_OP_breg0: 813214082Sdim case DW_OP_breg1: 814214082Sdim case DW_OP_breg2: 815214082Sdim case DW_OP_breg3: 816214082Sdim case DW_OP_breg4: 817214082Sdim case DW_OP_breg5: 818214082Sdim case DW_OP_breg6: 819214082Sdim case DW_OP_breg7: 820214082Sdim case DW_OP_breg8: 821214082Sdim case DW_OP_breg9: 822214082Sdim case DW_OP_breg10: 823214082Sdim case DW_OP_breg11: 824214082Sdim case DW_OP_breg12: 825214082Sdim case DW_OP_breg13: 826214082Sdim case DW_OP_breg14: 827214082Sdim case DW_OP_breg15: 828214082Sdim case DW_OP_breg16: 829214082Sdim case DW_OP_breg17: 830214082Sdim case DW_OP_breg18: 831214082Sdim case DW_OP_breg19: 832214082Sdim case DW_OP_breg20: 833214082Sdim case DW_OP_breg21: 834214082Sdim case DW_OP_breg22: 835214082Sdim case DW_OP_breg23: 836214082Sdim case DW_OP_breg24: 837214082Sdim case DW_OP_breg25: 838214082Sdim case DW_OP_breg26: 839214082Sdim case DW_OP_breg27: 840214082Sdim case DW_OP_breg28: 841214082Sdim case DW_OP_breg29: 842214082Sdim case DW_OP_breg30: 843214082Sdim case DW_OP_breg31: 844214082Sdim printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0, 845214082Sdim read_leb128 (data, &bytes_read, 1)); 846214082Sdim data += bytes_read; 847214082Sdim break; 848214082Sdim 849214082Sdim case DW_OP_regx: 850214082Sdim printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0)); 851214082Sdim data += bytes_read; 852214082Sdim break; 853214082Sdim case DW_OP_fbreg: 854214082Sdim need_frame_base = 1; 855214082Sdim printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1)); 856214082Sdim data += bytes_read; 857214082Sdim break; 858214082Sdim case DW_OP_bregx: 859214082Sdim uvalue = read_leb128 (data, &bytes_read, 0); 860214082Sdim data += bytes_read; 861214082Sdim printf ("DW_OP_bregx: %lu %ld", uvalue, 862214082Sdim read_leb128 (data, &bytes_read, 1)); 863214082Sdim data += bytes_read; 864214082Sdim break; 865214082Sdim case DW_OP_piece: 866214082Sdim printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0)); 867214082Sdim data += bytes_read; 868214082Sdim break; 869214082Sdim case DW_OP_deref_size: 870214082Sdim printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1)); 871214082Sdim break; 872214082Sdim case DW_OP_xderef_size: 873214082Sdim printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1)); 874214082Sdim break; 875214082Sdim case DW_OP_nop: 876214082Sdim printf ("DW_OP_nop"); 877214082Sdim break; 878214082Sdim 879214082Sdim /* DWARF 3 extensions. */ 880214082Sdim case DW_OP_push_object_address: 881214082Sdim printf ("DW_OP_push_object_address"); 882214082Sdim break; 883214082Sdim case DW_OP_call2: 884214082Sdim /* XXX: Strictly speaking for 64-bit DWARF3 files 885214082Sdim this ought to be an 8-byte wide computation. */ 886214082Sdim printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2) + cu_offset); 887214082Sdim data += 2; 888214082Sdim break; 889214082Sdim case DW_OP_call4: 890214082Sdim /* XXX: Strictly speaking for 64-bit DWARF3 files 891214082Sdim this ought to be an 8-byte wide computation. */ 892214082Sdim printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4) + cu_offset); 893214082Sdim data += 4; 894214082Sdim break; 895214082Sdim case DW_OP_call_ref: 896214082Sdim printf ("DW_OP_call_ref"); 897214082Sdim break; 898214082Sdim 899214082Sdim /* GNU extensions. */ 900214082Sdim case DW_OP_GNU_push_tls_address: 901214082Sdim printf ("DW_OP_GNU_push_tls_address"); 902214082Sdim break; 903214082Sdim 904214082Sdim default: 905214082Sdim if (op >= DW_OP_lo_user 906214082Sdim && op <= DW_OP_hi_user) 907214082Sdim printf (_("(User defined location op)")); 908214082Sdim else 909214082Sdim printf (_("(Unknown location op)")); 910214082Sdim /* No way to tell where the next op is, so just bail. */ 911214082Sdim return need_frame_base; 912214082Sdim } 913214082Sdim 914214082Sdim /* Separate the ops. */ 915214082Sdim if (data < end) 916214082Sdim printf ("; "); 917214082Sdim } 918214082Sdim 919214082Sdim return need_frame_base; 920214082Sdim} 921214082Sdim 922214082Sdimstatic unsigned char * 923214082Sdimread_and_display_attr_value (unsigned long attribute, 924214082Sdim unsigned long form, 925214082Sdim unsigned char *data, 926214082Sdim unsigned long cu_offset, 927214082Sdim unsigned long pointer_size, 928214082Sdim unsigned long offset_size, 929214082Sdim int dwarf_version, 930214082Sdim debug_info *debug_info_p, 931214082Sdim int do_loc) 932214082Sdim{ 933214082Sdim unsigned long uvalue = 0; 934214082Sdim unsigned char *block_start = NULL; 935214082Sdim unsigned int bytes_read; 936214082Sdim 937214082Sdim switch (form) 938214082Sdim { 939214082Sdim default: 940214082Sdim break; 941214082Sdim 942214082Sdim case DW_FORM_ref_addr: 943214082Sdim if (dwarf_version == 2) 944214082Sdim { 945214082Sdim uvalue = byte_get (data, pointer_size); 946214082Sdim data += pointer_size; 947214082Sdim } 948214082Sdim else if (dwarf_version == 3) 949214082Sdim { 950214082Sdim uvalue = byte_get (data, offset_size); 951214082Sdim data += offset_size; 952214082Sdim } 953214082Sdim else 954214082Sdim { 955214082Sdim error (_("Internal error: DWARF version is not 2 or 3.\n")); 956214082Sdim } 957214082Sdim break; 958214082Sdim 959214082Sdim case DW_FORM_addr: 960214082Sdim uvalue = byte_get (data, pointer_size); 961214082Sdim data += pointer_size; 962214082Sdim break; 963214082Sdim 964214082Sdim case DW_FORM_strp: 965214082Sdim uvalue = byte_get (data, offset_size); 966214082Sdim data += offset_size; 967214082Sdim break; 968214082Sdim 969214082Sdim case DW_FORM_ref1: 970214082Sdim case DW_FORM_flag: 971214082Sdim case DW_FORM_data1: 972214082Sdim uvalue = byte_get (data++, 1); 973214082Sdim break; 974214082Sdim 975214082Sdim case DW_FORM_ref2: 976214082Sdim case DW_FORM_data2: 977214082Sdim uvalue = byte_get (data, 2); 978214082Sdim data += 2; 979214082Sdim break; 980214082Sdim 981214082Sdim case DW_FORM_ref4: 982214082Sdim case DW_FORM_data4: 983214082Sdim uvalue = byte_get (data, 4); 984214082Sdim data += 4; 985214082Sdim break; 986214082Sdim 987214082Sdim case DW_FORM_sdata: 988214082Sdim uvalue = read_leb128 (data, & bytes_read, 1); 989214082Sdim data += bytes_read; 990214082Sdim break; 991214082Sdim 992214082Sdim case DW_FORM_ref_udata: 993214082Sdim case DW_FORM_udata: 994214082Sdim uvalue = read_leb128 (data, & bytes_read, 0); 995214082Sdim data += bytes_read; 996214082Sdim break; 997214082Sdim 998214082Sdim case DW_FORM_indirect: 999214082Sdim form = read_leb128 (data, & bytes_read, 0); 1000214082Sdim data += bytes_read; 1001214082Sdim if (!do_loc) 1002214082Sdim printf (" %s", get_FORM_name (form)); 1003214082Sdim return read_and_display_attr_value (attribute, form, data, 1004214082Sdim cu_offset, pointer_size, 1005214082Sdim offset_size, dwarf_version, 1006214082Sdim debug_info_p, do_loc); 1007214082Sdim } 1008214082Sdim 1009214082Sdim switch (form) 1010214082Sdim { 1011214082Sdim case DW_FORM_ref_addr: 1012214082Sdim if (!do_loc) 1013214082Sdim printf (" <#%lx>", uvalue); 1014214082Sdim break; 1015214082Sdim 1016214082Sdim case DW_FORM_ref1: 1017214082Sdim case DW_FORM_ref2: 1018214082Sdim case DW_FORM_ref4: 1019214082Sdim case DW_FORM_ref_udata: 1020214082Sdim if (!do_loc) 1021214082Sdim printf (" <%lx>", uvalue + cu_offset); 1022214082Sdim break; 1023214082Sdim 1024214082Sdim case DW_FORM_data4: 1025214082Sdim case DW_FORM_addr: 1026214082Sdim if (!do_loc) 1027214082Sdim printf (" %#lx", uvalue); 1028214082Sdim break; 1029214082Sdim 1030214082Sdim case DW_FORM_flag: 1031214082Sdim case DW_FORM_data1: 1032214082Sdim case DW_FORM_data2: 1033214082Sdim case DW_FORM_sdata: 1034214082Sdim case DW_FORM_udata: 1035214082Sdim if (!do_loc) 1036214082Sdim printf (" %ld", uvalue); 1037214082Sdim break; 1038214082Sdim 1039214082Sdim case DW_FORM_ref8: 1040214082Sdim case DW_FORM_data8: 1041214082Sdim if (!do_loc) 1042214082Sdim { 1043214082Sdim uvalue = byte_get (data, 4); 1044214082Sdim printf (" %lx", uvalue); 1045214082Sdim printf (" %lx", (unsigned long) byte_get (data + 4, 4)); 1046214082Sdim } 1047214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1048214082Sdim && num_debug_info_entries == 0) 1049214082Sdim { 1050214082Sdim if (sizeof (uvalue) == 8) 1051214082Sdim uvalue = byte_get (data, 8); 1052214082Sdim else 1053214082Sdim error (_("DW_FORM_data8 is unsupported when sizeof (unsigned long) != 8\n")); 1054214082Sdim } 1055214082Sdim data += 8; 1056214082Sdim break; 1057214082Sdim 1058214082Sdim case DW_FORM_string: 1059214082Sdim if (!do_loc) 1060214082Sdim printf (" %s", data); 1061214082Sdim data += strlen ((char *) data) + 1; 1062214082Sdim break; 1063214082Sdim 1064214082Sdim case DW_FORM_block: 1065214082Sdim uvalue = read_leb128 (data, & bytes_read, 0); 1066214082Sdim block_start = data + bytes_read; 1067214082Sdim if (do_loc) 1068214082Sdim data = block_start + uvalue; 1069214082Sdim else 1070214082Sdim data = display_block (block_start, uvalue); 1071214082Sdim break; 1072214082Sdim 1073214082Sdim case DW_FORM_block1: 1074214082Sdim uvalue = byte_get (data, 1); 1075214082Sdim block_start = data + 1; 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_block2: 1083214082Sdim uvalue = byte_get (data, 2); 1084214082Sdim block_start = data + 2; 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_block4: 1092214082Sdim uvalue = byte_get (data, 4); 1093214082Sdim block_start = data + 4; 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_strp: 1101214082Sdim if (!do_loc) 1102214082Sdim printf (_(" (indirect string, offset: 0x%lx): %s"), 1103214082Sdim uvalue, fetch_indirect_string (uvalue)); 1104214082Sdim break; 1105214082Sdim 1106214082Sdim case DW_FORM_indirect: 1107214082Sdim /* Handled above. */ 1108214082Sdim break; 1109214082Sdim 1110214082Sdim default: 1111214082Sdim warn (_("Unrecognized form: %lu\n"), form); 1112214082Sdim break; 1113214082Sdim } 1114214082Sdim 1115214082Sdim /* For some attributes we can display further information. */ 1116214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1117214082Sdim && num_debug_info_entries == 0) 1118214082Sdim { 1119214082Sdim switch (attribute) 1120214082Sdim { 1121214082Sdim case DW_AT_frame_base: 1122214082Sdim have_frame_base = 1; 1123214082Sdim case DW_AT_location: 1124214082Sdim case DW_AT_data_member_location: 1125214082Sdim case DW_AT_vtable_elem_location: 1126214082Sdim case DW_AT_allocated: 1127214082Sdim case DW_AT_associated: 1128214082Sdim case DW_AT_data_location: 1129214082Sdim case DW_AT_stride: 1130214082Sdim case DW_AT_upper_bound: 1131214082Sdim case DW_AT_lower_bound: 1132214082Sdim if (form == DW_FORM_data4 || form == DW_FORM_data8) 1133214082Sdim { 1134214082Sdim /* Process location list. */ 1135214082Sdim unsigned int max = debug_info_p->max_loc_offsets; 1136214082Sdim unsigned int num = debug_info_p->num_loc_offsets; 1137214082Sdim 1138214082Sdim if (max == 0 || num >= max) 1139214082Sdim { 1140214082Sdim max += 1024; 1141214082Sdim debug_info_p->loc_offsets 1142214082Sdim = xcrealloc (debug_info_p->loc_offsets, 1143214082Sdim max, sizeof (*debug_info_p->loc_offsets)); 1144214082Sdim debug_info_p->have_frame_base 1145214082Sdim = xcrealloc (debug_info_p->have_frame_base, 1146214082Sdim max, sizeof (*debug_info_p->have_frame_base)); 1147214082Sdim debug_info_p->max_loc_offsets = max; 1148214082Sdim } 1149214082Sdim debug_info_p->loc_offsets [num] = uvalue; 1150214082Sdim debug_info_p->have_frame_base [num] = have_frame_base; 1151214082Sdim debug_info_p->num_loc_offsets++; 1152214082Sdim } 1153214082Sdim break; 1154214082Sdim 1155214082Sdim case DW_AT_low_pc: 1156214082Sdim if (need_base_address) 1157214082Sdim debug_info_p->base_address = uvalue; 1158214082Sdim break; 1159214082Sdim 1160214082Sdim case DW_AT_ranges: 1161214082Sdim if (form == DW_FORM_data4 || form == DW_FORM_data8) 1162214082Sdim { 1163214082Sdim /* Process range list. */ 1164214082Sdim unsigned int max = debug_info_p->max_range_lists; 1165214082Sdim unsigned int num = debug_info_p->num_range_lists; 1166214082Sdim 1167214082Sdim if (max == 0 || num >= max) 1168214082Sdim { 1169214082Sdim max += 1024; 1170214082Sdim debug_info_p->range_lists 1171214082Sdim = xcrealloc (debug_info_p->range_lists, 1172214082Sdim max, sizeof (*debug_info_p->range_lists)); 1173214082Sdim debug_info_p->max_range_lists = max; 1174214082Sdim } 1175214082Sdim debug_info_p->range_lists [num] = uvalue; 1176214082Sdim debug_info_p->num_range_lists++; 1177214082Sdim } 1178214082Sdim break; 1179214082Sdim 1180214082Sdim default: 1181214082Sdim break; 1182214082Sdim } 1183214082Sdim } 1184214082Sdim 1185214082Sdim if (do_loc) 1186214082Sdim return data; 1187214082Sdim 1188214082Sdim printf ("\t"); 1189214082Sdim 1190214082Sdim switch (attribute) 1191214082Sdim { 1192214082Sdim case DW_AT_inline: 1193214082Sdim switch (uvalue) 1194214082Sdim { 1195214082Sdim case DW_INL_not_inlined: 1196214082Sdim printf (_("(not inlined)")); 1197214082Sdim break; 1198214082Sdim case DW_INL_inlined: 1199214082Sdim printf (_("(inlined)")); 1200214082Sdim break; 1201214082Sdim case DW_INL_declared_not_inlined: 1202214082Sdim printf (_("(declared as inline but ignored)")); 1203214082Sdim break; 1204214082Sdim case DW_INL_declared_inlined: 1205214082Sdim printf (_("(declared as inline and inlined)")); 1206214082Sdim break; 1207214082Sdim default: 1208214082Sdim printf (_(" (Unknown inline attribute value: %lx)"), uvalue); 1209214082Sdim break; 1210214082Sdim } 1211214082Sdim break; 1212214082Sdim 1213214082Sdim case DW_AT_language: 1214214082Sdim switch (uvalue) 1215214082Sdim { 1216214082Sdim case DW_LANG_C: printf ("(non-ANSI C)"); break; 1217214082Sdim case DW_LANG_C89: printf ("(ANSI C)"); break; 1218214082Sdim case DW_LANG_C_plus_plus: printf ("(C++)"); break; 1219214082Sdim case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break; 1220214082Sdim case DW_LANG_Fortran90: printf ("(Fortran 90)"); break; 1221214082Sdim case DW_LANG_Modula2: printf ("(Modula 2)"); break; 1222214082Sdim case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break; 1223214082Sdim case DW_LANG_Ada83: printf ("(Ada)"); break; 1224214082Sdim case DW_LANG_Cobol74: printf ("(Cobol 74)"); break; 1225214082Sdim case DW_LANG_Cobol85: printf ("(Cobol 85)"); break; 1226214082Sdim /* DWARF 2.1 values. */ 1227214082Sdim case DW_LANG_C99: printf ("(ANSI C99)"); break; 1228214082Sdim case DW_LANG_Ada95: printf ("(ADA 95)"); break; 1229214082Sdim case DW_LANG_Fortran95: printf ("(Fortran 95)"); break; 1230214082Sdim /* MIPS extension. */ 1231214082Sdim case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break; 1232214082Sdim /* UPC extension. */ 1233214082Sdim case DW_LANG_Upc: printf ("(Unified Parallel C)"); break; 1234214082Sdim default: 1235214082Sdim printf ("(Unknown: %lx)", uvalue); 1236214082Sdim break; 1237214082Sdim } 1238214082Sdim break; 1239214082Sdim 1240214082Sdim case DW_AT_encoding: 1241214082Sdim switch (uvalue) 1242214082Sdim { 1243214082Sdim case DW_ATE_void: printf ("(void)"); break; 1244214082Sdim case DW_ATE_address: printf ("(machine address)"); break; 1245214082Sdim case DW_ATE_boolean: printf ("(boolean)"); break; 1246214082Sdim case DW_ATE_complex_float: printf ("(complex float)"); break; 1247214082Sdim case DW_ATE_float: printf ("(float)"); break; 1248214082Sdim case DW_ATE_signed: printf ("(signed)"); break; 1249214082Sdim case DW_ATE_signed_char: printf ("(signed char)"); break; 1250214082Sdim case DW_ATE_unsigned: printf ("(unsigned)"); break; 1251214082Sdim case DW_ATE_unsigned_char: printf ("(unsigned char)"); break; 1252214082Sdim /* DWARF 2.1 value. */ 1253214082Sdim case DW_ATE_imaginary_float: printf ("(imaginary float)"); break; 1254214082Sdim case DW_ATE_decimal_float: printf ("(decimal float)"); break; 1255214082Sdim default: 1256214082Sdim if (uvalue >= DW_ATE_lo_user 1257214082Sdim && uvalue <= DW_ATE_hi_user) 1258214082Sdim printf ("(user defined type)"); 1259214082Sdim else 1260214082Sdim printf ("(unknown type)"); 1261214082Sdim break; 1262214082Sdim } 1263214082Sdim break; 1264214082Sdim 1265214082Sdim case DW_AT_accessibility: 1266214082Sdim switch (uvalue) 1267214082Sdim { 1268214082Sdim case DW_ACCESS_public: printf ("(public)"); break; 1269214082Sdim case DW_ACCESS_protected: printf ("(protected)"); break; 1270214082Sdim case DW_ACCESS_private: printf ("(private)"); break; 1271214082Sdim default: 1272214082Sdim printf ("(unknown accessibility)"); 1273214082Sdim break; 1274214082Sdim } 1275214082Sdim break; 1276214082Sdim 1277214082Sdim case DW_AT_visibility: 1278214082Sdim switch (uvalue) 1279214082Sdim { 1280214082Sdim case DW_VIS_local: printf ("(local)"); break; 1281214082Sdim case DW_VIS_exported: printf ("(exported)"); break; 1282214082Sdim case DW_VIS_qualified: printf ("(qualified)"); break; 1283214082Sdim default: printf ("(unknown visibility)"); break; 1284214082Sdim } 1285214082Sdim break; 1286214082Sdim 1287214082Sdim case DW_AT_virtuality: 1288214082Sdim switch (uvalue) 1289214082Sdim { 1290214082Sdim case DW_VIRTUALITY_none: printf ("(none)"); break; 1291214082Sdim case DW_VIRTUALITY_virtual: printf ("(virtual)"); break; 1292214082Sdim case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break; 1293214082Sdim default: printf ("(unknown virtuality)"); break; 1294214082Sdim } 1295214082Sdim break; 1296214082Sdim 1297214082Sdim case DW_AT_identifier_case: 1298214082Sdim switch (uvalue) 1299214082Sdim { 1300214082Sdim case DW_ID_case_sensitive: printf ("(case_sensitive)"); break; 1301214082Sdim case DW_ID_up_case: printf ("(up_case)"); break; 1302214082Sdim case DW_ID_down_case: printf ("(down_case)"); break; 1303214082Sdim case DW_ID_case_insensitive: printf ("(case_insensitive)"); break; 1304214082Sdim default: printf ("(unknown case)"); break; 1305214082Sdim } 1306214082Sdim break; 1307214082Sdim 1308214082Sdim case DW_AT_calling_convention: 1309214082Sdim switch (uvalue) 1310214082Sdim { 1311214082Sdim case DW_CC_normal: printf ("(normal)"); break; 1312214082Sdim case DW_CC_program: printf ("(program)"); break; 1313214082Sdim case DW_CC_nocall: printf ("(nocall)"); break; 1314214082Sdim default: 1315214082Sdim if (uvalue >= DW_CC_lo_user 1316214082Sdim && uvalue <= DW_CC_hi_user) 1317214082Sdim printf ("(user defined)"); 1318214082Sdim else 1319214082Sdim printf ("(unknown convention)"); 1320214082Sdim } 1321214082Sdim break; 1322214082Sdim 1323214082Sdim case DW_AT_ordering: 1324214082Sdim switch (uvalue) 1325214082Sdim { 1326214082Sdim case -1: printf ("(undefined)"); break; 1327214082Sdim case 0: printf ("(row major)"); break; 1328214082Sdim case 1: printf ("(column major)"); break; 1329214082Sdim } 1330214082Sdim break; 1331214082Sdim 1332214082Sdim case DW_AT_frame_base: 1333214082Sdim have_frame_base = 1; 1334214082Sdim case DW_AT_location: 1335214082Sdim case DW_AT_data_member_location: 1336214082Sdim case DW_AT_vtable_elem_location: 1337214082Sdim case DW_AT_allocated: 1338214082Sdim case DW_AT_associated: 1339214082Sdim case DW_AT_data_location: 1340214082Sdim case DW_AT_stride: 1341214082Sdim case DW_AT_upper_bound: 1342214082Sdim case DW_AT_lower_bound: 1343214082Sdim if (block_start) 1344214082Sdim { 1345214082Sdim int need_frame_base; 1346214082Sdim 1347214082Sdim printf ("("); 1348214082Sdim need_frame_base = decode_location_expression (block_start, 1349214082Sdim pointer_size, 1350214082Sdim uvalue, 1351214082Sdim cu_offset); 1352214082Sdim printf (")"); 1353214082Sdim if (need_frame_base && !have_frame_base) 1354214082Sdim printf (_(" [without DW_AT_frame_base]")); 1355214082Sdim } 1356214082Sdim else if (form == DW_FORM_data4 || form == DW_FORM_data8) 1357214082Sdim printf (_("(location list)")); 1358214082Sdim 1359214082Sdim break; 1360214082Sdim 1361214082Sdim default: 1362214082Sdim break; 1363214082Sdim } 1364214082Sdim 1365214082Sdim return data; 1366214082Sdim} 1367214082Sdim 1368214082Sdimstatic char * 1369214082Sdimget_AT_name (unsigned long attribute) 1370214082Sdim{ 1371214082Sdim switch (attribute) 1372214082Sdim { 1373214082Sdim case DW_AT_sibling: return "DW_AT_sibling"; 1374214082Sdim case DW_AT_location: return "DW_AT_location"; 1375214082Sdim case DW_AT_name: return "DW_AT_name"; 1376214082Sdim case DW_AT_ordering: return "DW_AT_ordering"; 1377214082Sdim case DW_AT_subscr_data: return "DW_AT_subscr_data"; 1378214082Sdim case DW_AT_byte_size: return "DW_AT_byte_size"; 1379214082Sdim case DW_AT_bit_offset: return "DW_AT_bit_offset"; 1380214082Sdim case DW_AT_bit_size: return "DW_AT_bit_size"; 1381214082Sdim case DW_AT_element_list: return "DW_AT_element_list"; 1382214082Sdim case DW_AT_stmt_list: return "DW_AT_stmt_list"; 1383214082Sdim case DW_AT_low_pc: return "DW_AT_low_pc"; 1384214082Sdim case DW_AT_high_pc: return "DW_AT_high_pc"; 1385214082Sdim case DW_AT_language: return "DW_AT_language"; 1386214082Sdim case DW_AT_member: return "DW_AT_member"; 1387214082Sdim case DW_AT_discr: return "DW_AT_discr"; 1388214082Sdim case DW_AT_discr_value: return "DW_AT_discr_value"; 1389214082Sdim case DW_AT_visibility: return "DW_AT_visibility"; 1390214082Sdim case DW_AT_import: return "DW_AT_import"; 1391214082Sdim case DW_AT_string_length: return "DW_AT_string_length"; 1392214082Sdim case DW_AT_common_reference: return "DW_AT_common_reference"; 1393214082Sdim case DW_AT_comp_dir: return "DW_AT_comp_dir"; 1394214082Sdim case DW_AT_const_value: return "DW_AT_const_value"; 1395214082Sdim case DW_AT_containing_type: return "DW_AT_containing_type"; 1396214082Sdim case DW_AT_default_value: return "DW_AT_default_value"; 1397214082Sdim case DW_AT_inline: return "DW_AT_inline"; 1398214082Sdim case DW_AT_is_optional: return "DW_AT_is_optional"; 1399214082Sdim case DW_AT_lower_bound: return "DW_AT_lower_bound"; 1400214082Sdim case DW_AT_producer: return "DW_AT_producer"; 1401214082Sdim case DW_AT_prototyped: return "DW_AT_prototyped"; 1402214082Sdim case DW_AT_return_addr: return "DW_AT_return_addr"; 1403214082Sdim case DW_AT_start_scope: return "DW_AT_start_scope"; 1404214082Sdim case DW_AT_stride_size: return "DW_AT_stride_size"; 1405214082Sdim case DW_AT_upper_bound: return "DW_AT_upper_bound"; 1406214082Sdim case DW_AT_abstract_origin: return "DW_AT_abstract_origin"; 1407214082Sdim case DW_AT_accessibility: return "DW_AT_accessibility"; 1408214082Sdim case DW_AT_address_class: return "DW_AT_address_class"; 1409214082Sdim case DW_AT_artificial: return "DW_AT_artificial"; 1410214082Sdim case DW_AT_base_types: return "DW_AT_base_types"; 1411214082Sdim case DW_AT_calling_convention: return "DW_AT_calling_convention"; 1412214082Sdim case DW_AT_count: return "DW_AT_count"; 1413214082Sdim case DW_AT_data_member_location: return "DW_AT_data_member_location"; 1414214082Sdim case DW_AT_decl_column: return "DW_AT_decl_column"; 1415214082Sdim case DW_AT_decl_file: return "DW_AT_decl_file"; 1416214082Sdim case DW_AT_decl_line: return "DW_AT_decl_line"; 1417214082Sdim case DW_AT_declaration: return "DW_AT_declaration"; 1418214082Sdim case DW_AT_discr_list: return "DW_AT_discr_list"; 1419214082Sdim case DW_AT_encoding: return "DW_AT_encoding"; 1420214082Sdim case DW_AT_external: return "DW_AT_external"; 1421214082Sdim case DW_AT_frame_base: return "DW_AT_frame_base"; 1422214082Sdim case DW_AT_friend: return "DW_AT_friend"; 1423214082Sdim case DW_AT_identifier_case: return "DW_AT_identifier_case"; 1424214082Sdim case DW_AT_macro_info: return "DW_AT_macro_info"; 1425214082Sdim case DW_AT_namelist_items: return "DW_AT_namelist_items"; 1426214082Sdim case DW_AT_priority: return "DW_AT_priority"; 1427214082Sdim case DW_AT_segment: return "DW_AT_segment"; 1428214082Sdim case DW_AT_specification: return "DW_AT_specification"; 1429214082Sdim case DW_AT_static_link: return "DW_AT_static_link"; 1430214082Sdim case DW_AT_type: return "DW_AT_type"; 1431214082Sdim case DW_AT_use_location: return "DW_AT_use_location"; 1432214082Sdim case DW_AT_variable_parameter: return "DW_AT_variable_parameter"; 1433214082Sdim case DW_AT_virtuality: return "DW_AT_virtuality"; 1434214082Sdim case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location"; 1435214082Sdim /* DWARF 2.1 values. */ 1436214082Sdim case DW_AT_allocated: return "DW_AT_allocated"; 1437214082Sdim case DW_AT_associated: return "DW_AT_associated"; 1438214082Sdim case DW_AT_data_location: return "DW_AT_data_location"; 1439214082Sdim case DW_AT_stride: return "DW_AT_stride"; 1440214082Sdim case DW_AT_entry_pc: return "DW_AT_entry_pc"; 1441214082Sdim case DW_AT_use_UTF8: return "DW_AT_use_UTF8"; 1442214082Sdim case DW_AT_extension: return "DW_AT_extension"; 1443214082Sdim case DW_AT_ranges: return "DW_AT_ranges"; 1444214082Sdim case DW_AT_trampoline: return "DW_AT_trampoline"; 1445214082Sdim case DW_AT_call_column: return "DW_AT_call_column"; 1446214082Sdim case DW_AT_call_file: return "DW_AT_call_file"; 1447214082Sdim case DW_AT_call_line: return "DW_AT_call_line"; 1448214082Sdim /* SGI/MIPS extensions. */ 1449214082Sdim case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; 1450214082Sdim case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin"; 1451214082Sdim case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin"; 1452214082Sdim case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin"; 1453214082Sdim case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor"; 1454214082Sdim case DW_AT_MIPS_software_pipeline_depth: 1455214082Sdim return "DW_AT_MIPS_software_pipeline_depth"; 1456214082Sdim case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name"; 1457214082Sdim case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride"; 1458214082Sdim case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name"; 1459214082Sdim case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin"; 1460214082Sdim case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines"; 1461214082Sdim /* GNU extensions. */ 1462214082Sdim case DW_AT_sf_names: return "DW_AT_sf_names"; 1463214082Sdim case DW_AT_src_info: return "DW_AT_src_info"; 1464214082Sdim case DW_AT_mac_info: return "DW_AT_mac_info"; 1465214082Sdim case DW_AT_src_coords: return "DW_AT_src_coords"; 1466214082Sdim case DW_AT_body_begin: return "DW_AT_body_begin"; 1467214082Sdim case DW_AT_body_end: return "DW_AT_body_end"; 1468214082Sdim case DW_AT_GNU_vector: return "DW_AT_GNU_vector"; 1469214082Sdim /* UPC extension. */ 1470214082Sdim case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled"; 1471214082Sdim default: 1472214082Sdim { 1473214082Sdim static char buffer[100]; 1474214082Sdim 1475214082Sdim snprintf (buffer, sizeof (buffer), _("Unknown AT value: %lx"), 1476214082Sdim attribute); 1477214082Sdim return buffer; 1478214082Sdim } 1479214082Sdim } 1480214082Sdim} 1481214082Sdim 1482214082Sdimstatic unsigned char * 1483214082Sdimread_and_display_attr (unsigned long attribute, 1484214082Sdim unsigned long form, 1485214082Sdim unsigned char *data, 1486214082Sdim unsigned long cu_offset, 1487214082Sdim unsigned long pointer_size, 1488214082Sdim unsigned long offset_size, 1489214082Sdim int dwarf_version, 1490214082Sdim debug_info *debug_info_p, 1491214082Sdim int do_loc) 1492214082Sdim{ 1493214082Sdim if (!do_loc) 1494214082Sdim printf (" %-18s:", get_AT_name (attribute)); 1495214082Sdim data = read_and_display_attr_value (attribute, form, data, cu_offset, 1496214082Sdim pointer_size, offset_size, 1497214082Sdim dwarf_version, debug_info_p, 1498214082Sdim do_loc); 1499214082Sdim if (!do_loc) 1500214082Sdim printf ("\n"); 1501214082Sdim return data; 1502214082Sdim} 1503214082Sdim 1504214082Sdim 1505214082Sdim/* Process the contents of a .debug_info section. If do_loc is non-zero 1506214082Sdim then we are scanning for location lists and we do not want to display 1507214082Sdim anything to the user. */ 1508214082Sdim 1509214082Sdimstatic int 1510214082Sdimprocess_debug_info (struct dwarf_section *section, void *file, 1511214082Sdim int do_loc) 1512214082Sdim{ 1513214082Sdim unsigned char *start = section->start; 1514214082Sdim unsigned char *end = start + section->size; 1515214082Sdim unsigned char *section_begin; 1516214082Sdim unsigned int unit; 1517214082Sdim unsigned int num_units = 0; 1518214082Sdim 1519214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1520214082Sdim && num_debug_info_entries == 0) 1521214082Sdim { 1522214082Sdim unsigned long length; 1523214082Sdim 1524214082Sdim /* First scan the section to get the number of comp units. */ 1525214082Sdim for (section_begin = start, num_units = 0; section_begin < end; 1526214082Sdim num_units ++) 1527214082Sdim { 1528214082Sdim /* Read the first 4 bytes. For a 32-bit DWARF section, this 1529214082Sdim will be the length. For a 64-bit DWARF section, it'll be 1530214082Sdim the escape code 0xffffffff followed by an 8 byte length. */ 1531214082Sdim length = byte_get (section_begin, 4); 1532214082Sdim 1533214082Sdim if (length == 0xffffffff) 1534214082Sdim { 1535214082Sdim length = byte_get (section_begin + 4, 8); 1536214082Sdim section_begin += length + 12; 1537214082Sdim } 1538214082Sdim else 1539214082Sdim section_begin += length + 4; 1540214082Sdim } 1541214082Sdim 1542214082Sdim if (num_units == 0) 1543214082Sdim { 1544214082Sdim error (_("No comp units in %s section ?"), section->name); 1545214082Sdim return 0; 1546214082Sdim } 1547214082Sdim 1548214082Sdim /* Then allocate an array to hold the information. */ 1549214082Sdim debug_information = cmalloc (num_units, 1550214082Sdim sizeof (* debug_information)); 1551214082Sdim if (debug_information == NULL) 1552214082Sdim { 1553214082Sdim error (_("Not enough memory for a debug info array of %u entries"), 1554214082Sdim num_units); 1555214082Sdim return 0; 1556214082Sdim } 1557214082Sdim } 1558214082Sdim 1559214082Sdim if (!do_loc) 1560214082Sdim { 1561214082Sdim printf (_("The section %s contains:\n\n"), section->name); 1562214082Sdim 1563214082Sdim load_debug_section (str, file); 1564214082Sdim } 1565214082Sdim 1566214082Sdim load_debug_section (abbrev, file); 1567214082Sdim if (debug_displays [abbrev].section.start == NULL) 1568214082Sdim { 1569214082Sdim warn (_("Unable to locate %s section!\n"), 1570214082Sdim debug_displays [abbrev].section.name); 1571214082Sdim return 0; 1572214082Sdim } 1573214082Sdim 1574214082Sdim for (section_begin = start, unit = 0; start < end; unit++) 1575214082Sdim { 1576214082Sdim DWARF2_Internal_CompUnit compunit; 1577214082Sdim unsigned char *hdrptr; 1578214082Sdim unsigned char *cu_abbrev_offset_ptr; 1579214082Sdim unsigned char *tags; 1580214082Sdim int level; 1581214082Sdim unsigned long cu_offset; 1582214082Sdim int offset_size; 1583214082Sdim int initial_length_size; 1584214082Sdim 1585214082Sdim hdrptr = start; 1586214082Sdim 1587214082Sdim compunit.cu_length = byte_get (hdrptr, 4); 1588214082Sdim hdrptr += 4; 1589214082Sdim 1590214082Sdim if (compunit.cu_length == 0xffffffff) 1591214082Sdim { 1592214082Sdim compunit.cu_length = byte_get (hdrptr, 8); 1593214082Sdim hdrptr += 8; 1594214082Sdim offset_size = 8; 1595214082Sdim initial_length_size = 12; 1596214082Sdim } 1597214082Sdim else 1598214082Sdim { 1599214082Sdim offset_size = 4; 1600214082Sdim initial_length_size = 4; 1601214082Sdim } 1602214082Sdim 1603214082Sdim compunit.cu_version = byte_get (hdrptr, 2); 1604214082Sdim hdrptr += 2; 1605214082Sdim 1606214082Sdim cu_offset = start - section_begin; 1607214082Sdim start += compunit.cu_length + initial_length_size; 1608214082Sdim 1609214082Sdim cu_abbrev_offset_ptr = hdrptr; 1610214082Sdim compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size); 1611214082Sdim hdrptr += offset_size; 1612214082Sdim 1613214082Sdim compunit.cu_pointer_size = byte_get (hdrptr, 1); 1614214082Sdim hdrptr += 1; 1615214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1616214082Sdim && num_debug_info_entries == 0) 1617214082Sdim { 1618214082Sdim debug_information [unit].cu_offset = cu_offset; 1619214082Sdim debug_information [unit].pointer_size 1620214082Sdim = compunit.cu_pointer_size; 1621214082Sdim debug_information [unit].base_address = 0; 1622214082Sdim debug_information [unit].loc_offsets = NULL; 1623214082Sdim debug_information [unit].have_frame_base = NULL; 1624214082Sdim debug_information [unit].max_loc_offsets = 0; 1625214082Sdim debug_information [unit].num_loc_offsets = 0; 1626214082Sdim debug_information [unit].range_lists = NULL; 1627214082Sdim debug_information [unit].max_range_lists= 0; 1628214082Sdim debug_information [unit].num_range_lists = 0; 1629214082Sdim } 1630214082Sdim 1631214082Sdim tags = hdrptr; 1632214082Sdim 1633214082Sdim if (!do_loc) 1634214082Sdim { 1635214082Sdim printf (_(" Compilation Unit @ offset 0x%lx:\n"), cu_offset); 1636214082Sdim printf (_(" Length: %ld\n"), compunit.cu_length); 1637214082Sdim printf (_(" Version: %d\n"), compunit.cu_version); 1638214082Sdim printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset); 1639214082Sdim printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size); 1640214082Sdim } 1641214082Sdim 1642214082Sdim if (compunit.cu_version != 2 && compunit.cu_version != 3) 1643214082Sdim { 1644214082Sdim warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n")); 1645214082Sdim continue; 1646214082Sdim } 1647214082Sdim 1648214082Sdim free_abbrevs (); 1649214082Sdim 1650214082Sdim /* Process the abbrevs used by this compilation unit. DWARF 1651214082Sdim sections under Mach-O have non-zero addresses. */ 1652214082Sdim process_abbrev_section 1653214082Sdim ((unsigned char *) debug_displays [abbrev].section.start 1654214082Sdim + compunit.cu_abbrev_offset - debug_displays [abbrev].section.address, 1655214082Sdim (unsigned char *) debug_displays [abbrev].section.start 1656214082Sdim + debug_displays [abbrev].section.size); 1657214082Sdim 1658214082Sdim level = 0; 1659214082Sdim while (tags < start) 1660214082Sdim { 1661214082Sdim unsigned int bytes_read; 1662214082Sdim unsigned long abbrev_number; 1663214082Sdim abbrev_entry *entry; 1664214082Sdim abbrev_attr *attr; 1665214082Sdim 1666214082Sdim abbrev_number = read_leb128 (tags, & bytes_read, 0); 1667214082Sdim tags += bytes_read; 1668214082Sdim 1669214082Sdim /* A null DIE marks the end of a list of children. */ 1670214082Sdim if (abbrev_number == 0) 1671214082Sdim { 1672214082Sdim --level; 1673214082Sdim continue; 1674214082Sdim } 1675214082Sdim 1676214082Sdim /* Scan through the abbreviation list until we reach the 1677214082Sdim correct entry. */ 1678214082Sdim for (entry = first_abbrev; 1679214082Sdim entry && entry->entry != abbrev_number; 1680214082Sdim entry = entry->next) 1681214082Sdim continue; 1682214082Sdim 1683214082Sdim if (entry == NULL) 1684214082Sdim { 1685214082Sdim warn (_("Unable to locate entry %lu in the abbreviation table\n"), 1686214082Sdim abbrev_number); 1687214082Sdim return 0; 1688214082Sdim } 1689214082Sdim 1690214082Sdim if (!do_loc) 1691214082Sdim printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"), 1692214082Sdim level, 1693214082Sdim (unsigned long) (tags - section_begin 1694214082Sdim - bytes_read), 1695214082Sdim abbrev_number, 1696214082Sdim get_TAG_name (entry->tag)); 1697214082Sdim 1698214082Sdim switch (entry->tag) 1699214082Sdim { 1700214082Sdim default: 1701214082Sdim need_base_address = 0; 1702214082Sdim break; 1703214082Sdim case DW_TAG_compile_unit: 1704214082Sdim need_base_address = 1; 1705214082Sdim break; 1706214082Sdim case DW_TAG_entry_point: 1707214082Sdim case DW_TAG_inlined_subroutine: 1708214082Sdim case DW_TAG_subprogram: 1709214082Sdim need_base_address = 0; 1710214082Sdim /* Assuming that there is no DW_AT_frame_base. */ 1711214082Sdim have_frame_base = 0; 1712214082Sdim break; 1713214082Sdim } 1714214082Sdim 1715214082Sdim for (attr = entry->first_attr; attr; attr = attr->next) 1716214082Sdim tags = read_and_display_attr (attr->attribute, 1717214082Sdim attr->form, 1718214082Sdim tags, cu_offset, 1719214082Sdim compunit.cu_pointer_size, 1720214082Sdim offset_size, 1721214082Sdim compunit.cu_version, 1722214082Sdim &debug_information [unit], 1723214082Sdim do_loc); 1724214082Sdim 1725214082Sdim if (entry->children) 1726214082Sdim ++level; 1727214082Sdim } 1728214082Sdim } 1729214082Sdim 1730214082Sdim /* Set num_debug_info_entries here so that it can be used to check if 1731214082Sdim we need to process .debug_loc and .debug_ranges sections. */ 1732214082Sdim if ((do_loc || do_debug_loc || do_debug_ranges) 1733214082Sdim && num_debug_info_entries == 0) 1734214082Sdim num_debug_info_entries = num_units; 1735214082Sdim 1736214082Sdim if (!do_loc) 1737214082Sdim { 1738214082Sdim printf ("\n"); 1739214082Sdim } 1740214082Sdim 1741214082Sdim return 1; 1742214082Sdim} 1743214082Sdim 1744214082Sdim/* Locate and scan the .debug_info section in the file and record the pointer 1745214082Sdim sizes and offsets for the compilation units in it. Usually an executable 1746214082Sdim will have just one pointer size, but this is not guaranteed, and so we try 1747214082Sdim not to make any assumptions. Returns zero upon failure, or the number of 1748214082Sdim compilation units upon success. */ 1749214082Sdim 1750214082Sdimstatic unsigned int 1751214082Sdimload_debug_info (void * file) 1752214082Sdim{ 1753214082Sdim /* Reset the last pointer size so that we can issue correct error 1754214082Sdim messages if we are displaying the contents of more than one section. */ 1755214082Sdim last_pointer_size = 0; 1756214082Sdim warned_about_missing_comp_units = FALSE; 1757214082Sdim 1758214082Sdim /* If we already have the information there is nothing else to do. */ 1759214082Sdim if (num_debug_info_entries > 0) 1760214082Sdim return num_debug_info_entries; 1761214082Sdim 1762214082Sdim if (load_debug_section (info, file) 1763214082Sdim && process_debug_info (&debug_displays [info].section, file, 1)) 1764214082Sdim return num_debug_info_entries; 1765214082Sdim else 1766214082Sdim return 0; 1767214082Sdim} 1768214082Sdim 1769214082Sdimstatic int 1770214082Sdimdisplay_debug_lines (struct dwarf_section *section, void *file) 1771214082Sdim{ 1772214082Sdim unsigned char *start = section->start; 1773214082Sdim unsigned char *data = start; 1774214082Sdim unsigned char *end = start + section->size; 1775214082Sdim 1776214082Sdim printf (_("\nDump of debug contents of section %s:\n\n"), 1777214082Sdim section->name); 1778214082Sdim 1779214082Sdim load_debug_info (file); 1780214082Sdim 1781214082Sdim while (data < end) 1782214082Sdim { 1783214082Sdim DWARF2_Internal_LineInfo info; 1784214082Sdim unsigned char *standard_opcodes; 1785214082Sdim unsigned char *end_of_sequence; 1786214082Sdim unsigned char *hdrptr; 1787214082Sdim int initial_length_size; 1788214082Sdim int offset_size; 1789214082Sdim int i; 1790214082Sdim 1791214082Sdim hdrptr = data; 1792214082Sdim 1793214082Sdim /* Check the length of the block. */ 1794214082Sdim info.li_length = byte_get (hdrptr, 4); 1795214082Sdim hdrptr += 4; 1796214082Sdim 1797214082Sdim if (info.li_length == 0xffffffff) 1798214082Sdim { 1799214082Sdim /* This section is 64-bit DWARF 3. */ 1800214082Sdim info.li_length = byte_get (hdrptr, 8); 1801214082Sdim hdrptr += 8; 1802214082Sdim offset_size = 8; 1803214082Sdim initial_length_size = 12; 1804214082Sdim } 1805214082Sdim else 1806214082Sdim { 1807214082Sdim offset_size = 4; 1808214082Sdim initial_length_size = 4; 1809214082Sdim } 1810214082Sdim 1811214082Sdim if (info.li_length + initial_length_size > section->size) 1812214082Sdim { 1813214082Sdim warn 1814214082Sdim (_("The line info appears to be corrupt - the section is too small\n")); 1815214082Sdim return 0; 1816214082Sdim } 1817214082Sdim 1818214082Sdim /* Check its version number. */ 1819214082Sdim info.li_version = byte_get (hdrptr, 2); 1820214082Sdim hdrptr += 2; 1821214082Sdim if (info.li_version != 2 && info.li_version != 3) 1822214082Sdim { 1823214082Sdim warn (_("Only DWARF version 2 and 3 line info is currently supported.\n")); 1824214082Sdim return 0; 1825214082Sdim } 1826214082Sdim 1827214082Sdim info.li_prologue_length = byte_get (hdrptr, offset_size); 1828214082Sdim hdrptr += offset_size; 1829214082Sdim info.li_min_insn_length = byte_get (hdrptr, 1); 1830214082Sdim hdrptr++; 1831214082Sdim info.li_default_is_stmt = byte_get (hdrptr, 1); 1832214082Sdim hdrptr++; 1833214082Sdim info.li_line_base = byte_get (hdrptr, 1); 1834214082Sdim hdrptr++; 1835214082Sdim info.li_line_range = byte_get (hdrptr, 1); 1836214082Sdim hdrptr++; 1837214082Sdim info.li_opcode_base = byte_get (hdrptr, 1); 1838214082Sdim hdrptr++; 1839214082Sdim 1840214082Sdim /* Sign extend the line base field. */ 1841214082Sdim info.li_line_base <<= 24; 1842214082Sdim info.li_line_base >>= 24; 1843214082Sdim 1844214082Sdim printf (_(" Length: %ld\n"), info.li_length); 1845214082Sdim printf (_(" DWARF Version: %d\n"), info.li_version); 1846214082Sdim printf (_(" Prologue Length: %d\n"), info.li_prologue_length); 1847214082Sdim printf (_(" Minimum Instruction Length: %d\n"), info.li_min_insn_length); 1848214082Sdim printf (_(" Initial value of 'is_stmt': %d\n"), info.li_default_is_stmt); 1849214082Sdim printf (_(" Line Base: %d\n"), info.li_line_base); 1850214082Sdim printf (_(" Line Range: %d\n"), info.li_line_range); 1851214082Sdim printf (_(" Opcode Base: %d\n"), info.li_opcode_base); 1852214082Sdim 1853214082Sdim end_of_sequence = data + info.li_length + initial_length_size; 1854214082Sdim 1855214082Sdim reset_state_machine (info.li_default_is_stmt); 1856214082Sdim 1857214082Sdim /* Display the contents of the Opcodes table. */ 1858214082Sdim standard_opcodes = hdrptr; 1859214082Sdim 1860214082Sdim printf (_("\n Opcodes:\n")); 1861214082Sdim 1862214082Sdim for (i = 1; i < info.li_opcode_base; i++) 1863214082Sdim printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]); 1864214082Sdim 1865214082Sdim /* Display the contents of the Directory table. */ 1866214082Sdim data = standard_opcodes + info.li_opcode_base - 1; 1867214082Sdim 1868214082Sdim if (*data == 0) 1869214082Sdim printf (_("\n The Directory Table is empty.\n")); 1870214082Sdim else 1871214082Sdim { 1872214082Sdim printf (_("\n The Directory Table:\n")); 1873214082Sdim 1874214082Sdim while (*data != 0) 1875214082Sdim { 1876214082Sdim printf (_(" %s\n"), data); 1877214082Sdim 1878214082Sdim data += strlen ((char *) data) + 1; 1879214082Sdim } 1880214082Sdim } 1881214082Sdim 1882214082Sdim /* Skip the NUL at the end of the table. */ 1883214082Sdim data++; 1884214082Sdim 1885214082Sdim /* Display the contents of the File Name table. */ 1886214082Sdim if (*data == 0) 1887214082Sdim printf (_("\n The File Name Table is empty.\n")); 1888214082Sdim else 1889214082Sdim { 1890214082Sdim printf (_("\n The File Name Table:\n")); 1891214082Sdim printf (_(" Entry\tDir\tTime\tSize\tName\n")); 1892214082Sdim 1893214082Sdim while (*data != 0) 1894214082Sdim { 1895214082Sdim unsigned char *name; 1896214082Sdim unsigned int bytes_read; 1897214082Sdim 1898214082Sdim printf (_(" %d\t"), ++state_machine_regs.last_file_entry); 1899214082Sdim name = data; 1900214082Sdim 1901214082Sdim data += strlen ((char *) data) + 1; 1902214082Sdim 1903214082Sdim printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0)); 1904214082Sdim data += bytes_read; 1905214082Sdim printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0)); 1906214082Sdim data += bytes_read; 1907214082Sdim printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0)); 1908214082Sdim data += bytes_read; 1909214082Sdim printf (_("%s\n"), name); 1910214082Sdim } 1911214082Sdim } 1912214082Sdim 1913214082Sdim /* Skip the NUL at the end of the table. */ 1914214082Sdim data++; 1915214082Sdim 1916214082Sdim /* Now display the statements. */ 1917214082Sdim printf (_("\n Line Number Statements:\n")); 1918214082Sdim 1919214082Sdim while (data < end_of_sequence) 1920214082Sdim { 1921214082Sdim unsigned char op_code; 1922214082Sdim int adv; 1923214082Sdim unsigned long int uladv; 1924214082Sdim unsigned int bytes_read; 1925214082Sdim 1926214082Sdim op_code = *data++; 1927214082Sdim 1928214082Sdim if (op_code >= info.li_opcode_base) 1929214082Sdim { 1930214082Sdim op_code -= info.li_opcode_base; 1931214082Sdim uladv = (op_code / info.li_line_range) * info.li_min_insn_length; 1932214082Sdim state_machine_regs.address += uladv; 1933214082Sdim printf (_(" Special opcode %d: advance Address by %lu to 0x%lx"), 1934214082Sdim op_code, uladv, state_machine_regs.address); 1935214082Sdim adv = (op_code % info.li_line_range) + info.li_line_base; 1936214082Sdim state_machine_regs.line += adv; 1937214082Sdim printf (_(" and Line by %d to %d\n"), 1938214082Sdim adv, state_machine_regs.line); 1939214082Sdim } 1940214082Sdim else switch (op_code) 1941214082Sdim { 1942214082Sdim case DW_LNS_extended_op: 1943214082Sdim data += process_extended_line_op (data, info.li_default_is_stmt); 1944214082Sdim break; 1945214082Sdim 1946214082Sdim case DW_LNS_copy: 1947214082Sdim printf (_(" Copy\n")); 1948214082Sdim break; 1949214082Sdim 1950214082Sdim case DW_LNS_advance_pc: 1951214082Sdim uladv = read_leb128 (data, & bytes_read, 0); 1952214082Sdim uladv *= info.li_min_insn_length; 1953214082Sdim data += bytes_read; 1954214082Sdim state_machine_regs.address += uladv; 1955214082Sdim printf (_(" Advance PC by %lu to 0x%lx\n"), uladv, 1956214082Sdim state_machine_regs.address); 1957214082Sdim break; 1958214082Sdim 1959214082Sdim case DW_LNS_advance_line: 1960214082Sdim adv = read_leb128 (data, & bytes_read, 1); 1961214082Sdim data += bytes_read; 1962214082Sdim state_machine_regs.line += adv; 1963214082Sdim printf (_(" Advance Line by %d to %d\n"), adv, 1964214082Sdim state_machine_regs.line); 1965214082Sdim break; 1966214082Sdim 1967214082Sdim case DW_LNS_set_file: 1968214082Sdim adv = read_leb128 (data, & bytes_read, 0); 1969214082Sdim data += bytes_read; 1970214082Sdim printf (_(" Set File Name to entry %d in the File Name Table\n"), 1971214082Sdim adv); 1972214082Sdim state_machine_regs.file = adv; 1973214082Sdim break; 1974214082Sdim 1975214082Sdim case DW_LNS_set_column: 1976214082Sdim uladv = read_leb128 (data, & bytes_read, 0); 1977214082Sdim data += bytes_read; 1978214082Sdim printf (_(" Set column to %lu\n"), uladv); 1979214082Sdim state_machine_regs.column = uladv; 1980214082Sdim break; 1981214082Sdim 1982214082Sdim case DW_LNS_negate_stmt: 1983214082Sdim adv = state_machine_regs.is_stmt; 1984214082Sdim adv = ! adv; 1985214082Sdim printf (_(" Set is_stmt to %d\n"), adv); 1986214082Sdim state_machine_regs.is_stmt = adv; 1987214082Sdim break; 1988214082Sdim 1989214082Sdim case DW_LNS_set_basic_block: 1990214082Sdim printf (_(" Set basic block\n")); 1991214082Sdim state_machine_regs.basic_block = 1; 1992214082Sdim break; 1993214082Sdim 1994214082Sdim case DW_LNS_const_add_pc: 1995214082Sdim uladv = (((255 - info.li_opcode_base) / info.li_line_range) 1996214082Sdim * info.li_min_insn_length); 1997214082Sdim state_machine_regs.address += uladv; 1998214082Sdim printf (_(" Advance PC by constant %lu to 0x%lx\n"), uladv, 1999214082Sdim state_machine_regs.address); 2000214082Sdim break; 2001214082Sdim 2002214082Sdim case DW_LNS_fixed_advance_pc: 2003214082Sdim uladv = byte_get (data, 2); 2004214082Sdim data += 2; 2005214082Sdim state_machine_regs.address += uladv; 2006214082Sdim printf (_(" Advance PC by fixed size amount %lu to 0x%lx\n"), 2007214082Sdim uladv, state_machine_regs.address); 2008214082Sdim break; 2009214082Sdim 2010214082Sdim case DW_LNS_set_prologue_end: 2011214082Sdim printf (_(" Set prologue_end to true\n")); 2012214082Sdim break; 2013214082Sdim 2014214082Sdim case DW_LNS_set_epilogue_begin: 2015214082Sdim printf (_(" Set epilogue_begin to true\n")); 2016214082Sdim break; 2017214082Sdim 2018214082Sdim case DW_LNS_set_isa: 2019214082Sdim uladv = read_leb128 (data, & bytes_read, 0); 2020214082Sdim data += bytes_read; 2021214082Sdim printf (_(" Set ISA to %lu\n"), uladv); 2022214082Sdim break; 2023214082Sdim 2024214082Sdim default: 2025214082Sdim printf (_(" Unknown opcode %d with operands: "), op_code); 2026214082Sdim 2027214082Sdim for (i = standard_opcodes[op_code - 1]; i > 0 ; --i) 2028214082Sdim { 2029214082Sdim printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0), 2030214082Sdim i == 1 ? "" : ", "); 2031214082Sdim data += bytes_read; 2032214082Sdim } 2033214082Sdim putchar ('\n'); 2034214082Sdim break; 2035214082Sdim } 2036214082Sdim } 2037214082Sdim putchar ('\n'); 2038214082Sdim } 2039214082Sdim 2040214082Sdim return 1; 2041214082Sdim} 2042214082Sdim 2043214082Sdimstatic int 2044214082Sdimdisplay_debug_pubnames (struct dwarf_section *section, 2045214082Sdim void *file ATTRIBUTE_UNUSED) 2046214082Sdim{ 2047214082Sdim DWARF2_Internal_PubNames pubnames; 2048214082Sdim unsigned char *start = section->start; 2049214082Sdim unsigned char *end = start + section->size; 2050214082Sdim 2051214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2052214082Sdim 2053214082Sdim while (start < end) 2054214082Sdim { 2055214082Sdim unsigned char *data; 2056214082Sdim unsigned long offset; 2057214082Sdim int offset_size, initial_length_size; 2058214082Sdim 2059214082Sdim data = start; 2060214082Sdim 2061214082Sdim pubnames.pn_length = byte_get (data, 4); 2062214082Sdim data += 4; 2063214082Sdim if (pubnames.pn_length == 0xffffffff) 2064214082Sdim { 2065214082Sdim pubnames.pn_length = byte_get (data, 8); 2066214082Sdim data += 8; 2067214082Sdim offset_size = 8; 2068214082Sdim initial_length_size = 12; 2069214082Sdim } 2070214082Sdim else 2071214082Sdim { 2072214082Sdim offset_size = 4; 2073214082Sdim initial_length_size = 4; 2074214082Sdim } 2075214082Sdim 2076214082Sdim pubnames.pn_version = byte_get (data, 2); 2077214082Sdim data += 2; 2078214082Sdim pubnames.pn_offset = byte_get (data, offset_size); 2079214082Sdim data += offset_size; 2080214082Sdim pubnames.pn_size = byte_get (data, offset_size); 2081214082Sdim data += offset_size; 2082214082Sdim 2083214082Sdim start += pubnames.pn_length + initial_length_size; 2084214082Sdim 2085214082Sdim if (pubnames.pn_version != 2 && pubnames.pn_version != 3) 2086214082Sdim { 2087214082Sdim static int warned = 0; 2088214082Sdim 2089214082Sdim if (! warned) 2090214082Sdim { 2091214082Sdim warn (_("Only DWARF 2 and 3 pubnames are currently supported\n")); 2092214082Sdim warned = 1; 2093214082Sdim } 2094214082Sdim 2095214082Sdim continue; 2096214082Sdim } 2097214082Sdim 2098214082Sdim printf (_(" Length: %ld\n"), 2099214082Sdim pubnames.pn_length); 2100214082Sdim printf (_(" Version: %d\n"), 2101214082Sdim pubnames.pn_version); 2102214082Sdim printf (_(" Offset into .debug_info section: %ld\n"), 2103214082Sdim pubnames.pn_offset); 2104214082Sdim printf (_(" Size of area in .debug_info section: %ld\n"), 2105214082Sdim pubnames.pn_size); 2106214082Sdim 2107214082Sdim printf (_("\n Offset\tName\n")); 2108214082Sdim 2109214082Sdim do 2110214082Sdim { 2111214082Sdim offset = byte_get (data, offset_size); 2112214082Sdim 2113214082Sdim if (offset != 0) 2114214082Sdim { 2115214082Sdim data += offset_size; 2116214082Sdim printf (" %-6ld\t\t%s\n", offset, data); 2117214082Sdim data += strlen ((char *) data) + 1; 2118214082Sdim } 2119214082Sdim } 2120214082Sdim while (offset != 0); 2121214082Sdim } 2122214082Sdim 2123214082Sdim printf ("\n"); 2124214082Sdim return 1; 2125214082Sdim} 2126214082Sdim 2127214082Sdimstatic int 2128214082Sdimdisplay_debug_macinfo (struct dwarf_section *section, 2129214082Sdim void *file ATTRIBUTE_UNUSED) 2130214082Sdim{ 2131214082Sdim unsigned char *start = section->start; 2132214082Sdim unsigned char *end = start + section->size; 2133214082Sdim unsigned char *curr = start; 2134214082Sdim unsigned int bytes_read; 2135214082Sdim enum dwarf_macinfo_record_type op; 2136214082Sdim 2137214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2138214082Sdim 2139214082Sdim while (curr < end) 2140214082Sdim { 2141214082Sdim unsigned int lineno; 2142214082Sdim const char *string; 2143214082Sdim 2144214082Sdim op = *curr; 2145214082Sdim curr++; 2146214082Sdim 2147214082Sdim switch (op) 2148214082Sdim { 2149214082Sdim case DW_MACINFO_start_file: 2150214082Sdim { 2151214082Sdim unsigned int filenum; 2152214082Sdim 2153214082Sdim lineno = read_leb128 (curr, & bytes_read, 0); 2154214082Sdim curr += bytes_read; 2155214082Sdim filenum = read_leb128 (curr, & bytes_read, 0); 2156214082Sdim curr += bytes_read; 2157214082Sdim 2158214082Sdim printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"), 2159214082Sdim lineno, filenum); 2160214082Sdim } 2161214082Sdim break; 2162214082Sdim 2163214082Sdim case DW_MACINFO_end_file: 2164214082Sdim printf (_(" DW_MACINFO_end_file\n")); 2165214082Sdim break; 2166214082Sdim 2167214082Sdim case DW_MACINFO_define: 2168214082Sdim lineno = read_leb128 (curr, & bytes_read, 0); 2169214082Sdim curr += bytes_read; 2170214082Sdim string = (char *) curr; 2171214082Sdim curr += strlen (string) + 1; 2172214082Sdim printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"), 2173214082Sdim lineno, string); 2174214082Sdim break; 2175214082Sdim 2176214082Sdim case DW_MACINFO_undef: 2177214082Sdim lineno = read_leb128 (curr, & bytes_read, 0); 2178214082Sdim curr += bytes_read; 2179214082Sdim string = (char *) curr; 2180214082Sdim curr += strlen (string) + 1; 2181214082Sdim printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"), 2182214082Sdim lineno, string); 2183214082Sdim break; 2184214082Sdim 2185214082Sdim case DW_MACINFO_vendor_ext: 2186214082Sdim { 2187214082Sdim unsigned int constant; 2188214082Sdim 2189214082Sdim constant = read_leb128 (curr, & bytes_read, 0); 2190214082Sdim curr += bytes_read; 2191214082Sdim string = (char *) curr; 2192214082Sdim curr += strlen (string) + 1; 2193214082Sdim printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"), 2194214082Sdim constant, string); 2195214082Sdim } 2196214082Sdim break; 2197214082Sdim } 2198214082Sdim } 2199214082Sdim 2200214082Sdim return 1; 2201214082Sdim} 2202214082Sdim 2203214082Sdimstatic int 2204214082Sdimdisplay_debug_abbrev (struct dwarf_section *section, 2205214082Sdim void *file ATTRIBUTE_UNUSED) 2206214082Sdim{ 2207214082Sdim abbrev_entry *entry; 2208214082Sdim unsigned char *start = section->start; 2209214082Sdim unsigned char *end = start + section->size; 2210214082Sdim 2211214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2212214082Sdim 2213214082Sdim do 2214214082Sdim { 2215214082Sdim free_abbrevs (); 2216214082Sdim 2217214082Sdim start = process_abbrev_section (start, end); 2218214082Sdim 2219214082Sdim if (first_abbrev == NULL) 2220214082Sdim continue; 2221214082Sdim 2222214082Sdim printf (_(" Number TAG\n")); 2223214082Sdim 2224214082Sdim for (entry = first_abbrev; entry; entry = entry->next) 2225214082Sdim { 2226214082Sdim abbrev_attr *attr; 2227214082Sdim 2228214082Sdim printf (_(" %ld %s [%s]\n"), 2229214082Sdim entry->entry, 2230214082Sdim get_TAG_name (entry->tag), 2231214082Sdim entry->children ? _("has children") : _("no children")); 2232214082Sdim 2233214082Sdim for (attr = entry->first_attr; attr; attr = attr->next) 2234214082Sdim printf (_(" %-18s %s\n"), 2235214082Sdim get_AT_name (attr->attribute), 2236214082Sdim get_FORM_name (attr->form)); 2237214082Sdim } 2238214082Sdim } 2239214082Sdim while (start); 2240214082Sdim 2241214082Sdim printf ("\n"); 2242214082Sdim 2243214082Sdim return 1; 2244214082Sdim} 2245214082Sdim 2246214082Sdimstatic int 2247214082Sdimdisplay_debug_loc (struct dwarf_section *section, void *file) 2248214082Sdim{ 2249214082Sdim unsigned char *start = section->start; 2250214082Sdim unsigned char *section_end; 2251214082Sdim unsigned long bytes; 2252214082Sdim unsigned char *section_begin = start; 2253214082Sdim unsigned int num_loc_list = 0; 2254214082Sdim unsigned long last_offset = 0; 2255214082Sdim unsigned int first = 0; 2256214082Sdim unsigned int i; 2257214082Sdim unsigned int j; 2258214082Sdim int seen_first_offset = 0; 2259214082Sdim int use_debug_info = 1; 2260214082Sdim unsigned char *next; 2261214082Sdim 2262214082Sdim bytes = section->size; 2263214082Sdim section_end = start + bytes; 2264214082Sdim 2265214082Sdim if (bytes == 0) 2266214082Sdim { 2267214082Sdim printf (_("\nThe %s section is empty.\n"), section->name); 2268214082Sdim return 0; 2269214082Sdim } 2270214082Sdim 2271214082Sdim load_debug_info (file); 2272214082Sdim 2273214082Sdim /* Check the order of location list in .debug_info section. If 2274214082Sdim offsets of location lists are in the ascending order, we can 2275214082Sdim use `debug_information' directly. */ 2276214082Sdim for (i = 0; i < num_debug_info_entries; i++) 2277214082Sdim { 2278214082Sdim unsigned int num; 2279214082Sdim 2280214082Sdim num = debug_information [i].num_loc_offsets; 2281214082Sdim num_loc_list += num; 2282214082Sdim 2283214082Sdim /* Check if we can use `debug_information' directly. */ 2284214082Sdim if (use_debug_info && num != 0) 2285214082Sdim { 2286214082Sdim if (!seen_first_offset) 2287214082Sdim { 2288214082Sdim /* This is the first location list. */ 2289214082Sdim last_offset = debug_information [i].loc_offsets [0]; 2290214082Sdim first = i; 2291214082Sdim seen_first_offset = 1; 2292214082Sdim j = 1; 2293214082Sdim } 2294214082Sdim else 2295214082Sdim j = 0; 2296214082Sdim 2297214082Sdim for (; j < num; j++) 2298214082Sdim { 2299214082Sdim if (last_offset > 2300214082Sdim debug_information [i].loc_offsets [j]) 2301214082Sdim { 2302214082Sdim use_debug_info = 0; 2303214082Sdim break; 2304214082Sdim } 2305214082Sdim last_offset = debug_information [i].loc_offsets [j]; 2306214082Sdim } 2307214082Sdim } 2308214082Sdim } 2309214082Sdim 2310214082Sdim if (!use_debug_info) 2311214082Sdim /* FIXME: Should we handle this case? */ 2312214082Sdim error (_("Location lists in .debug_info section aren't in ascending order!\n")); 2313214082Sdim 2314214082Sdim if (!seen_first_offset) 2315214082Sdim error (_("No location lists in .debug_info section!\n")); 2316214082Sdim 2317214082Sdim /* DWARF sections under Mach-O have non-zero addresses. */ 2318214082Sdim if (debug_information [first].loc_offsets [0] != section->address) 2319214082Sdim warn (_("Location lists in %s section start at 0x%lx\n"), 2320214082Sdim section->name, debug_information [first].loc_offsets [0]); 2321214082Sdim 2322214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2323214082Sdim printf (_(" Offset Begin End Expression\n")); 2324214082Sdim 2325214082Sdim seen_first_offset = 0; 2326214082Sdim for (i = first; i < num_debug_info_entries; i++) 2327214082Sdim { 2328214082Sdim unsigned long begin; 2329214082Sdim unsigned long end; 2330214082Sdim unsigned short length; 2331214082Sdim unsigned long offset; 2332214082Sdim unsigned int pointer_size; 2333214082Sdim unsigned long cu_offset; 2334214082Sdim unsigned long base_address; 2335214082Sdim int need_frame_base; 2336214082Sdim int has_frame_base; 2337214082Sdim 2338214082Sdim pointer_size = debug_information [i].pointer_size; 2339214082Sdim cu_offset = debug_information [i].cu_offset; 2340214082Sdim 2341214082Sdim for (j = 0; j < debug_information [i].num_loc_offsets; j++) 2342214082Sdim { 2343214082Sdim has_frame_base = debug_information [i].have_frame_base [j]; 2344214082Sdim /* DWARF sections under Mach-O have non-zero addresses. */ 2345214082Sdim offset = debug_information [i].loc_offsets [j] - section->address; 2346214082Sdim next = section_begin + offset; 2347214082Sdim base_address = debug_information [i].base_address; 2348214082Sdim 2349214082Sdim if (!seen_first_offset) 2350214082Sdim seen_first_offset = 1; 2351214082Sdim else 2352214082Sdim { 2353214082Sdim if (start < next) 2354214082Sdim warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"), 2355214082Sdim (long)(start - section_begin), (long)(next - section_begin)); 2356214082Sdim else if (start > next) 2357214082Sdim warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"), 2358214082Sdim (long)(start - section_begin), (long)(next - section_begin)); 2359214082Sdim } 2360214082Sdim start = next; 2361214082Sdim 2362214082Sdim if (offset >= bytes) 2363214082Sdim { 2364214082Sdim warn (_("Offset 0x%lx is bigger than .debug_loc section size.\n"), 2365214082Sdim offset); 2366214082Sdim continue; 2367214082Sdim } 2368214082Sdim 2369214082Sdim while (1) 2370214082Sdim { 2371214082Sdim if (start + 2 * pointer_size > section_end) 2372214082Sdim { 2373214082Sdim warn (_("Location list starting at offset 0x%lx is not terminated.\n"), 2374214082Sdim offset); 2375214082Sdim break; 2376214082Sdim } 2377214082Sdim 2378214082Sdim begin = byte_get (start, pointer_size); 2379214082Sdim start += pointer_size; 2380214082Sdim end = byte_get (start, pointer_size); 2381214082Sdim start += pointer_size; 2382214082Sdim 2383214082Sdim if (begin == 0 && end == 0) 2384214082Sdim { 2385214082Sdim printf (_(" %8.8lx <End of list>\n"), offset); 2386214082Sdim break; 2387214082Sdim } 2388214082Sdim 2389214082Sdim /* Check base address specifiers. */ 2390214082Sdim if (begin == -1UL && end != -1UL) 2391214082Sdim { 2392214082Sdim base_address = end; 2393214082Sdim printf (_(" %8.8lx %8.8lx %8.8lx (base address)\n"), 2394214082Sdim offset, begin, end); 2395214082Sdim continue; 2396214082Sdim } 2397214082Sdim 2398214082Sdim if (start + 2 > section_end) 2399214082Sdim { 2400214082Sdim warn (_("Location list starting at offset 0x%lx is not terminated.\n"), 2401214082Sdim offset); 2402214082Sdim break; 2403214082Sdim } 2404214082Sdim 2405214082Sdim length = byte_get (start, 2); 2406214082Sdim start += 2; 2407214082Sdim 2408214082Sdim if (start + length > section_end) 2409214082Sdim { 2410214082Sdim warn (_("Location list starting at offset 0x%lx is not terminated.\n"), 2411214082Sdim offset); 2412214082Sdim break; 2413214082Sdim } 2414214082Sdim 2415214082Sdim printf (" %8.8lx %8.8lx %8.8lx (", 2416214082Sdim offset, begin + base_address, end + base_address); 2417214082Sdim need_frame_base = decode_location_expression (start, 2418214082Sdim pointer_size, 2419214082Sdim length, 2420214082Sdim cu_offset); 2421214082Sdim putchar (')'); 2422214082Sdim 2423214082Sdim if (need_frame_base && !has_frame_base) 2424214082Sdim printf (_(" [without DW_AT_frame_base]")); 2425214082Sdim 2426214082Sdim if (begin == end) 2427214082Sdim fputs (_(" (start == end)"), stdout); 2428214082Sdim else if (begin > end) 2429214082Sdim fputs (_(" (start > end)"), stdout); 2430214082Sdim 2431214082Sdim putchar ('\n'); 2432214082Sdim 2433214082Sdim start += length; 2434214082Sdim } 2435214082Sdim } 2436214082Sdim } 2437214082Sdim return 1; 2438214082Sdim} 2439214082Sdim 2440214082Sdimstatic int 2441214082Sdimdisplay_debug_str (struct dwarf_section *section, 2442214082Sdim void *file ATTRIBUTE_UNUSED) 2443214082Sdim{ 2444214082Sdim unsigned char *start = section->start; 2445214082Sdim unsigned long bytes = section->size; 2446214082Sdim dwarf_vma addr = section->address; 2447214082Sdim 2448214082Sdim if (bytes == 0) 2449214082Sdim { 2450214082Sdim printf (_("\nThe %s section is empty.\n"), section->name); 2451214082Sdim return 0; 2452214082Sdim } 2453214082Sdim 2454214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2455214082Sdim 2456214082Sdim while (bytes) 2457214082Sdim { 2458214082Sdim int j; 2459214082Sdim int k; 2460214082Sdim int lbytes; 2461214082Sdim 2462214082Sdim lbytes = (bytes > 16 ? 16 : bytes); 2463214082Sdim 2464214082Sdim printf (" 0x%8.8lx ", (unsigned long) addr); 2465214082Sdim 2466214082Sdim for (j = 0; j < 16; j++) 2467214082Sdim { 2468214082Sdim if (j < lbytes) 2469214082Sdim printf ("%2.2x", start[j]); 2470214082Sdim else 2471214082Sdim printf (" "); 2472214082Sdim 2473214082Sdim if ((j & 3) == 3) 2474214082Sdim printf (" "); 2475214082Sdim } 2476214082Sdim 2477214082Sdim for (j = 0; j < lbytes; j++) 2478214082Sdim { 2479214082Sdim k = start[j]; 2480214082Sdim if (k >= ' ' && k < 0x80) 2481214082Sdim printf ("%c", k); 2482214082Sdim else 2483214082Sdim printf ("."); 2484214082Sdim } 2485214082Sdim 2486214082Sdim putchar ('\n'); 2487214082Sdim 2488214082Sdim start += lbytes; 2489214082Sdim addr += lbytes; 2490214082Sdim bytes -= lbytes; 2491214082Sdim } 2492214082Sdim 2493214082Sdim putchar ('\n'); 2494214082Sdim 2495214082Sdim return 1; 2496214082Sdim} 2497214082Sdim 2498214082Sdim 2499214082Sdimstatic int 2500214082Sdimdisplay_debug_info (struct dwarf_section *section, void *file) 2501214082Sdim{ 2502214082Sdim return process_debug_info (section, file, 0); 2503214082Sdim} 2504214082Sdim 2505214082Sdim 2506214082Sdimstatic int 2507214082Sdimdisplay_debug_aranges (struct dwarf_section *section, 2508214082Sdim void *file ATTRIBUTE_UNUSED) 2509214082Sdim{ 2510214082Sdim unsigned char *start = section->start; 2511214082Sdim unsigned char *end = start + section->size; 2512214082Sdim 2513214082Sdim printf (_("The section %s contains:\n\n"), section->name); 2514214082Sdim 2515214082Sdim while (start < end) 2516214082Sdim { 2517214082Sdim unsigned char *hdrptr; 2518214082Sdim DWARF2_Internal_ARange arange; 2519214082Sdim unsigned char *ranges; 2520214082Sdim unsigned long length; 2521214082Sdim unsigned long address; 2522214082Sdim int excess; 2523214082Sdim int offset_size; 2524214082Sdim int initial_length_size; 2525214082Sdim 2526214082Sdim hdrptr = start; 2527214082Sdim 2528214082Sdim arange.ar_length = byte_get (hdrptr, 4); 2529214082Sdim hdrptr += 4; 2530214082Sdim 2531214082Sdim if (arange.ar_length == 0xffffffff) 2532214082Sdim { 2533214082Sdim arange.ar_length = byte_get (hdrptr, 8); 2534214082Sdim hdrptr += 8; 2535214082Sdim offset_size = 8; 2536214082Sdim initial_length_size = 12; 2537214082Sdim } 2538214082Sdim else 2539214082Sdim { 2540214082Sdim offset_size = 4; 2541214082Sdim initial_length_size = 4; 2542214082Sdim } 2543214082Sdim 2544214082Sdim arange.ar_version = byte_get (hdrptr, 2); 2545214082Sdim hdrptr += 2; 2546214082Sdim 2547214082Sdim arange.ar_info_offset = byte_get (hdrptr, offset_size); 2548214082Sdim hdrptr += offset_size; 2549214082Sdim 2550214082Sdim arange.ar_pointer_size = byte_get (hdrptr, 1); 2551214082Sdim hdrptr += 1; 2552214082Sdim 2553214082Sdim arange.ar_segment_size = byte_get (hdrptr, 1); 2554214082Sdim hdrptr += 1; 2555214082Sdim 2556214082Sdim if (arange.ar_version != 2 && arange.ar_version != 3) 2557214082Sdim { 2558214082Sdim warn (_("Only DWARF 2 and 3 aranges are currently supported.\n")); 2559214082Sdim break; 2560214082Sdim } 2561214082Sdim 2562214082Sdim printf (_(" Length: %ld\n"), arange.ar_length); 2563214082Sdim printf (_(" Version: %d\n"), arange.ar_version); 2564214082Sdim printf (_(" Offset into .debug_info: %lx\n"), arange.ar_info_offset); 2565214082Sdim printf (_(" Pointer Size: %d\n"), arange.ar_pointer_size); 2566214082Sdim printf (_(" Segment Size: %d\n"), arange.ar_segment_size); 2567214082Sdim 2568214082Sdim printf (_("\n Address Length\n")); 2569214082Sdim 2570214082Sdim ranges = hdrptr; 2571214082Sdim 2572214082Sdim /* Must pad to an alignment boundary that is twice the pointer size. */ 2573214082Sdim excess = (hdrptr - start) % (2 * arange.ar_pointer_size); 2574214082Sdim if (excess) 2575214082Sdim ranges += (2 * arange.ar_pointer_size) - excess; 2576214082Sdim 2577214082Sdim start += arange.ar_length + initial_length_size; 2578214082Sdim 2579214082Sdim while (ranges + 2 * arange.ar_pointer_size <= start) 2580214082Sdim { 2581214082Sdim address = byte_get (ranges, arange.ar_pointer_size); 2582214082Sdim 2583214082Sdim ranges += arange.ar_pointer_size; 2584214082Sdim 2585214082Sdim length = byte_get (ranges, arange.ar_pointer_size); 2586214082Sdim 2587214082Sdim ranges += arange.ar_pointer_size; 2588214082Sdim 2589214082Sdim printf (" %8.8lx %lu\n", address, length); 2590214082Sdim } 2591214082Sdim } 2592214082Sdim 2593214082Sdim printf ("\n"); 2594214082Sdim 2595214082Sdim return 1; 2596214082Sdim} 2597214082Sdim 2598214082Sdimstatic int 2599214082Sdimdisplay_debug_ranges (struct dwarf_section *section, 2600214082Sdim void *file ATTRIBUTE_UNUSED) 2601214082Sdim{ 2602214082Sdim unsigned char *start = section->start; 2603214082Sdim unsigned char *section_end; 2604214082Sdim unsigned long bytes; 2605214082Sdim unsigned char *section_begin = start; 2606214082Sdim unsigned int num_range_list = 0; 2607214082Sdim unsigned long last_offset = 0; 2608214082Sdim unsigned int first = 0; 2609214082Sdim unsigned int i; 2610214082Sdim unsigned int j; 2611214082Sdim int seen_first_offset = 0; 2612214082Sdim int use_debug_info = 1; 2613214082Sdim unsigned char *next; 2614214082Sdim 2615214082Sdim bytes = section->size; 2616214082Sdim section_end = start + bytes; 2617214082Sdim 2618214082Sdim if (bytes == 0) 2619214082Sdim { 2620214082Sdim printf (_("\nThe %s section is empty.\n"), section->name); 2621214082Sdim return 0; 2622214082Sdim } 2623214082Sdim 2624214082Sdim load_debug_info (file); 2625214082Sdim 2626214082Sdim /* Check the order of range list in .debug_info section. If 2627214082Sdim offsets of range lists are in the ascending order, we can 2628214082Sdim use `debug_information' directly. */ 2629214082Sdim for (i = 0; i < num_debug_info_entries; i++) 2630214082Sdim { 2631214082Sdim unsigned int num; 2632214082Sdim 2633214082Sdim num = debug_information [i].num_range_lists; 2634214082Sdim num_range_list += num; 2635214082Sdim 2636214082Sdim /* Check if we can use `debug_information' directly. */ 2637214082Sdim if (use_debug_info && num != 0) 2638214082Sdim { 2639214082Sdim if (!seen_first_offset) 2640214082Sdim { 2641214082Sdim /* This is the first range list. */ 2642214082Sdim last_offset = debug_information [i].range_lists [0]; 2643214082Sdim first = i; 2644214082Sdim seen_first_offset = 1; 2645214082Sdim j = 1; 2646214082Sdim } 2647214082Sdim else 2648214082Sdim j = 0; 2649214082Sdim 2650214082Sdim for (; j < num; j++) 2651214082Sdim { 2652214082Sdim if (last_offset > 2653214082Sdim debug_information [i].range_lists [j]) 2654214082Sdim { 2655214082Sdim use_debug_info = 0; 2656214082Sdim break; 2657214082Sdim } 2658214082Sdim last_offset = debug_information [i].range_lists [j]; 2659214082Sdim } 2660214082Sdim } 2661214082Sdim } 2662214082Sdim 2663214082Sdim if (!use_debug_info) 2664214082Sdim /* FIXME: Should we handle this case? */ 2665214082Sdim error (_("Range lists in .debug_info section aren't in ascending order!\n")); 2666214082Sdim 2667214082Sdim if (!seen_first_offset) 2668214082Sdim error (_("No range lists in .debug_info section!\n")); 2669214082Sdim 2670214082Sdim /* DWARF sections under Mach-O have non-zero addresses. */ 2671214082Sdim if (debug_information [first].range_lists [0] != section->address) 2672214082Sdim warn (_("Range lists in %s section start at 0x%lx\n"), 2673214082Sdim section->name, debug_information [first].range_lists [0]); 2674214082Sdim 2675214082Sdim printf (_("Contents of the %s section:\n\n"), section->name); 2676214082Sdim printf (_(" Offset Begin End\n")); 2677214082Sdim 2678214082Sdim seen_first_offset = 0; 2679214082Sdim for (i = first; i < num_debug_info_entries; i++) 2680214082Sdim { 2681214082Sdim unsigned long begin; 2682214082Sdim unsigned long end; 2683214082Sdim unsigned long offset; 2684214082Sdim unsigned int pointer_size; 2685214082Sdim unsigned long base_address; 2686214082Sdim 2687214082Sdim pointer_size = debug_information [i].pointer_size; 2688214082Sdim 2689214082Sdim for (j = 0; j < debug_information [i].num_range_lists; j++) 2690214082Sdim { 2691214082Sdim /* DWARF sections under Mach-O have non-zero addresses. */ 2692214082Sdim offset = debug_information [i].range_lists [j] - section->address; 2693214082Sdim next = section_begin + offset; 2694214082Sdim base_address = debug_information [i].base_address; 2695214082Sdim 2696214082Sdim if (!seen_first_offset) 2697214082Sdim seen_first_offset = 1; 2698214082Sdim else 2699214082Sdim { 2700214082Sdim if (start < next) 2701214082Sdim warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"), 2702214082Sdim (long)(start - section_begin), 2703214082Sdim (long)(next - section_begin), section->name); 2704214082Sdim else if (start > next) 2705214082Sdim warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"), 2706214082Sdim (long)(start - section_begin), 2707214082Sdim (long)(next - section_begin), section->name); 2708214082Sdim } 2709214082Sdim start = next; 2710214082Sdim 2711214082Sdim while (1) 2712214082Sdim { 2713214082Sdim begin = byte_get (start, pointer_size); 2714214082Sdim start += pointer_size; 2715214082Sdim end = byte_get (start, pointer_size); 2716214082Sdim start += pointer_size; 2717214082Sdim 2718214082Sdim if (begin == 0 && end == 0) 2719214082Sdim { 2720214082Sdim printf (_(" %8.8lx <End of list>\n"), offset); 2721214082Sdim break; 2722214082Sdim } 2723214082Sdim 2724214082Sdim /* Check base address specifiers. */ 2725214082Sdim if (begin == -1UL && end != -1UL) 2726214082Sdim { 2727214082Sdim base_address = end; 2728214082Sdim printf (" %8.8lx %8.8lx %8.8lx (base address)\n", 2729214082Sdim offset, begin, end); 2730214082Sdim continue; 2731214082Sdim } 2732214082Sdim 2733214082Sdim printf (" %8.8lx %8.8lx %8.8lx", 2734214082Sdim offset, begin + base_address, end + base_address); 2735214082Sdim 2736214082Sdim if (begin == end) 2737214082Sdim fputs (_(" (start == end)"), stdout); 2738214082Sdim else if (begin > end) 2739214082Sdim fputs (_(" (start > end)"), stdout); 2740214082Sdim 2741214082Sdim putchar ('\n'); 2742214082Sdim } 2743214082Sdim } 2744214082Sdim } 2745214082Sdim putchar ('\n'); 2746214082Sdim return 1; 2747214082Sdim} 2748214082Sdim 2749214082Sdimtypedef struct Frame_Chunk 2750214082Sdim{ 2751214082Sdim struct Frame_Chunk *next; 2752214082Sdim unsigned char *chunk_start; 2753214082Sdim int ncols; 2754214082Sdim /* DW_CFA_{undefined,same_value,offset,register,unreferenced} */ 2755214082Sdim short int *col_type; 2756214082Sdim int *col_offset; 2757214082Sdim char *augmentation; 2758214082Sdim unsigned int code_factor; 2759214082Sdim int data_factor; 2760214082Sdim unsigned long pc_begin; 2761214082Sdim unsigned long pc_range; 2762214082Sdim int cfa_reg; 2763214082Sdim int cfa_offset; 2764214082Sdim int ra; 2765214082Sdim unsigned char fde_encoding; 2766214082Sdim unsigned char cfa_exp; 2767214082Sdim} 2768214082SdimFrame_Chunk; 2769214082Sdim 2770214082Sdim/* A marker for a col_type that means this column was never referenced 2771214082Sdim in the frame info. */ 2772214082Sdim#define DW_CFA_unreferenced (-1) 2773214082Sdim 2774214082Sdimstatic void 2775214082Sdimframe_need_space (Frame_Chunk *fc, int reg) 2776214082Sdim{ 2777214082Sdim int prev = fc->ncols; 2778214082Sdim 2779214082Sdim if (reg < fc->ncols) 2780214082Sdim return; 2781214082Sdim 2782214082Sdim fc->ncols = reg + 1; 2783214082Sdim fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int)); 2784214082Sdim fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, sizeof (int)); 2785214082Sdim 2786214082Sdim while (prev < fc->ncols) 2787214082Sdim { 2788214082Sdim fc->col_type[prev] = DW_CFA_unreferenced; 2789214082Sdim fc->col_offset[prev] = 0; 2790214082Sdim prev++; 2791214082Sdim } 2792214082Sdim} 2793214082Sdim 2794214082Sdimstatic void 2795214082Sdimframe_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs) 2796214082Sdim{ 2797214082Sdim int r; 2798214082Sdim char tmp[100]; 2799214082Sdim 2800214082Sdim if (*max_regs < fc->ncols) 2801214082Sdim *max_regs = fc->ncols; 2802214082Sdim 2803214082Sdim if (*need_col_headers) 2804214082Sdim { 2805214082Sdim *need_col_headers = 0; 2806214082Sdim 2807214082Sdim printf (" LOC CFA "); 2808214082Sdim 2809214082Sdim for (r = 0; r < *max_regs; r++) 2810214082Sdim if (fc->col_type[r] != DW_CFA_unreferenced) 2811214082Sdim { 2812214082Sdim if (r == fc->ra) 2813214082Sdim printf ("ra "); 2814214082Sdim else 2815214082Sdim printf ("r%-4d", r); 2816214082Sdim } 2817214082Sdim 2818214082Sdim printf ("\n"); 2819214082Sdim } 2820214082Sdim 2821214082Sdim printf ("%08lx ", fc->pc_begin); 2822214082Sdim if (fc->cfa_exp) 2823214082Sdim strcpy (tmp, "exp"); 2824214082Sdim else 2825214082Sdim sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset); 2826214082Sdim printf ("%-8s ", tmp); 2827214082Sdim 2828214082Sdim for (r = 0; r < fc->ncols; r++) 2829214082Sdim { 2830214082Sdim if (fc->col_type[r] != DW_CFA_unreferenced) 2831214082Sdim { 2832214082Sdim switch (fc->col_type[r]) 2833214082Sdim { 2834214082Sdim case DW_CFA_undefined: 2835214082Sdim strcpy (tmp, "u"); 2836214082Sdim break; 2837214082Sdim case DW_CFA_same_value: 2838214082Sdim strcpy (tmp, "s"); 2839214082Sdim break; 2840214082Sdim case DW_CFA_offset: 2841214082Sdim sprintf (tmp, "c%+d", fc->col_offset[r]); 2842214082Sdim break; 2843214082Sdim case DW_CFA_val_offset: 2844214082Sdim sprintf (tmp, "v%+d", fc->col_offset[r]); 2845214082Sdim break; 2846214082Sdim case DW_CFA_register: 2847214082Sdim sprintf (tmp, "r%d", fc->col_offset[r]); 2848214082Sdim break; 2849214082Sdim case DW_CFA_expression: 2850214082Sdim strcpy (tmp, "exp"); 2851214082Sdim break; 2852214082Sdim case DW_CFA_val_expression: 2853214082Sdim strcpy (tmp, "vexp"); 2854214082Sdim break; 2855214082Sdim default: 2856214082Sdim strcpy (tmp, "n/a"); 2857214082Sdim break; 2858214082Sdim } 2859214082Sdim printf ("%-5s", tmp); 2860214082Sdim } 2861214082Sdim } 2862214082Sdim printf ("\n"); 2863214082Sdim} 2864214082Sdim 2865214082Sdimstatic int 2866214082Sdimsize_of_encoded_value (int encoding) 2867214082Sdim{ 2868214082Sdim switch (encoding & 0x7) 2869214082Sdim { 2870214082Sdim default: /* ??? */ 2871214082Sdim case 0: return eh_addr_size; 2872214082Sdim case 2: return 2; 2873214082Sdim case 3: return 4; 2874214082Sdim case 4: return 8; 2875214082Sdim } 2876214082Sdim} 2877214082Sdim 2878214082Sdimstatic dwarf_vma 2879214082Sdimget_encoded_value (unsigned char *data, int encoding) 2880214082Sdim{ 2881214082Sdim int size = size_of_encoded_value (encoding); 2882214082Sdim if (encoding & DW_EH_PE_signed) 2883214082Sdim return byte_get_signed (data, size); 2884214082Sdim else 2885214082Sdim return byte_get (data, size); 2886214082Sdim} 2887214082Sdim 2888214082Sdim#define GET(N) byte_get (start, N); start += N 2889214082Sdim#define LEB() read_leb128 (start, & length_return, 0); start += length_return 2890214082Sdim#define SLEB() read_leb128 (start, & length_return, 1); start += length_return 2891214082Sdim 2892214082Sdimstatic int 2893214082Sdimdisplay_debug_frames (struct dwarf_section *section, 2894214082Sdim void *file ATTRIBUTE_UNUSED) 2895214082Sdim{ 2896214082Sdim unsigned char *start = section->start; 2897214082Sdim unsigned char *end = start + section->size; 2898214082Sdim unsigned char *section_start = start; 2899214082Sdim Frame_Chunk *chunks = 0; 2900214082Sdim Frame_Chunk *remembered_state = 0; 2901214082Sdim Frame_Chunk *rs; 2902214082Sdim int is_eh = strcmp (section->name, ".eh_frame") == 0; 2903214082Sdim unsigned int length_return; 2904214082Sdim int max_regs = 0; 2905214082Sdim 2906214082Sdim printf (_("The section %s contains:\n"), section->name); 2907214082Sdim 2908214082Sdim while (start < end) 2909214082Sdim { 2910214082Sdim unsigned char *saved_start; 2911214082Sdim unsigned char *block_end; 2912214082Sdim unsigned long length; 2913214082Sdim unsigned long cie_id; 2914214082Sdim Frame_Chunk *fc; 2915214082Sdim Frame_Chunk *cie; 2916214082Sdim int need_col_headers = 1; 2917214082Sdim unsigned char *augmentation_data = NULL; 2918214082Sdim unsigned long augmentation_data_len = 0; 2919214082Sdim int encoded_ptr_size = eh_addr_size; 2920214082Sdim int offset_size; 2921214082Sdim int initial_length_size; 2922214082Sdim 2923214082Sdim saved_start = start; 2924214082Sdim length = byte_get (start, 4); start += 4; 2925214082Sdim 2926214082Sdim if (length == 0) 2927214082Sdim { 2928214082Sdim printf ("\n%08lx ZERO terminator\n\n", 2929214082Sdim (unsigned long)(saved_start - section_start)); 2930214082Sdim return 1; 2931214082Sdim } 2932214082Sdim 2933214082Sdim if (length == 0xffffffff) 2934214082Sdim { 2935214082Sdim length = byte_get (start, 8); 2936214082Sdim start += 8; 2937214082Sdim offset_size = 8; 2938214082Sdim initial_length_size = 12; 2939214082Sdim } 2940214082Sdim else 2941214082Sdim { 2942214082Sdim offset_size = 4; 2943214082Sdim initial_length_size = 4; 2944214082Sdim } 2945214082Sdim 2946214082Sdim block_end = saved_start + length + initial_length_size; 2947214082Sdim cie_id = byte_get (start, offset_size); start += offset_size; 2948214082Sdim 2949214082Sdim if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID)) 2950214082Sdim { 2951214082Sdim int version; 2952214082Sdim 2953214082Sdim fc = xmalloc (sizeof (Frame_Chunk)); 2954214082Sdim memset (fc, 0, sizeof (Frame_Chunk)); 2955214082Sdim 2956214082Sdim fc->next = chunks; 2957214082Sdim chunks = fc; 2958214082Sdim fc->chunk_start = saved_start; 2959214082Sdim fc->ncols = 0; 2960214082Sdim fc->col_type = xmalloc (sizeof (short int)); 2961214082Sdim fc->col_offset = xmalloc (sizeof (int)); 2962214082Sdim frame_need_space (fc, max_regs-1); 2963214082Sdim 2964214082Sdim version = *start++; 2965214082Sdim 2966214082Sdim fc->augmentation = (char *) start; 2967214082Sdim start = (unsigned char *) strchr ((char *) start, '\0') + 1; 2968214082Sdim 2969214082Sdim if (fc->augmentation[0] == 'z') 2970214082Sdim { 2971214082Sdim fc->code_factor = LEB (); 2972214082Sdim fc->data_factor = SLEB (); 2973214082Sdim if (version == 1) 2974214082Sdim { 2975214082Sdim fc->ra = GET (1); 2976214082Sdim } 2977214082Sdim else 2978214082Sdim { 2979214082Sdim fc->ra = LEB (); 2980214082Sdim } 2981214082Sdim augmentation_data_len = LEB (); 2982214082Sdim augmentation_data = start; 2983214082Sdim start += augmentation_data_len; 2984214082Sdim } 2985214082Sdim else if (strcmp (fc->augmentation, "eh") == 0) 2986214082Sdim { 2987214082Sdim start += eh_addr_size; 2988214082Sdim fc->code_factor = LEB (); 2989214082Sdim fc->data_factor = SLEB (); 2990214082Sdim if (version == 1) 2991214082Sdim { 2992214082Sdim fc->ra = GET (1); 2993214082Sdim } 2994214082Sdim else 2995214082Sdim { 2996214082Sdim fc->ra = LEB (); 2997214082Sdim } 2998214082Sdim } 2999214082Sdim else 3000214082Sdim { 3001214082Sdim fc->code_factor = LEB (); 3002214082Sdim fc->data_factor = SLEB (); 3003214082Sdim if (version == 1) 3004214082Sdim { 3005214082Sdim fc->ra = GET (1); 3006214082Sdim } 3007214082Sdim else 3008214082Sdim { 3009214082Sdim fc->ra = LEB (); 3010214082Sdim } 3011214082Sdim } 3012214082Sdim cie = fc; 3013214082Sdim 3014214082Sdim if (do_debug_frames_interp) 3015214082Sdim printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n", 3016214082Sdim (unsigned long)(saved_start - section_start), length, cie_id, 3017214082Sdim fc->augmentation, fc->code_factor, fc->data_factor, 3018214082Sdim fc->ra); 3019214082Sdim else 3020214082Sdim { 3021214082Sdim printf ("\n%08lx %08lx %08lx CIE\n", 3022214082Sdim (unsigned long)(saved_start - section_start), length, cie_id); 3023214082Sdim printf (" Version: %d\n", version); 3024214082Sdim printf (" Augmentation: \"%s\"\n", fc->augmentation); 3025214082Sdim printf (" Code alignment factor: %u\n", fc->code_factor); 3026214082Sdim printf (" Data alignment factor: %d\n", fc->data_factor); 3027214082Sdim printf (" Return address column: %d\n", fc->ra); 3028214082Sdim 3029214082Sdim if (augmentation_data_len) 3030214082Sdim { 3031214082Sdim unsigned long i; 3032214082Sdim printf (" Augmentation data: "); 3033214082Sdim for (i = 0; i < augmentation_data_len; ++i) 3034214082Sdim printf (" %02x", augmentation_data[i]); 3035214082Sdim putchar ('\n'); 3036214082Sdim } 3037214082Sdim putchar ('\n'); 3038214082Sdim } 3039214082Sdim 3040214082Sdim if (augmentation_data_len) 3041214082Sdim { 3042214082Sdim unsigned char *p, *q; 3043214082Sdim p = (unsigned char *) fc->augmentation + 1; 3044214082Sdim q = augmentation_data; 3045214082Sdim 3046214082Sdim while (1) 3047214082Sdim { 3048214082Sdim if (*p == 'L') 3049214082Sdim q++; 3050214082Sdim else if (*p == 'P') 3051214082Sdim q += 1 + size_of_encoded_value (*q); 3052214082Sdim else if (*p == 'R') 3053214082Sdim fc->fde_encoding = *q++; 3054214082Sdim else 3055214082Sdim break; 3056214082Sdim p++; 3057214082Sdim } 3058214082Sdim 3059214082Sdim if (fc->fde_encoding) 3060214082Sdim encoded_ptr_size = size_of_encoded_value (fc->fde_encoding); 3061214082Sdim } 3062214082Sdim 3063214082Sdim frame_need_space (fc, fc->ra); 3064214082Sdim } 3065214082Sdim else 3066214082Sdim { 3067214082Sdim unsigned char *look_for; 3068214082Sdim static Frame_Chunk fde_fc; 3069214082Sdim 3070214082Sdim fc = & fde_fc; 3071214082Sdim memset (fc, 0, sizeof (Frame_Chunk)); 3072214082Sdim 3073214082Sdim look_for = is_eh ? start - 4 - cie_id : section_start + cie_id; 3074214082Sdim 3075214082Sdim for (cie = chunks; cie ; cie = cie->next) 3076214082Sdim if (cie->chunk_start == look_for) 3077214082Sdim break; 3078214082Sdim 3079214082Sdim if (!cie) 3080214082Sdim { 3081214082Sdim warn ("Invalid CIE pointer %08lx in FDE at %08lx\n", 3082214082Sdim cie_id, (unsigned long)(saved_start - section_start)); 3083214082Sdim start = block_end; 3084214082Sdim fc->ncols = 0; 3085214082Sdim fc->col_type = xmalloc (sizeof (short int)); 3086214082Sdim fc->col_offset = xmalloc (sizeof (int)); 3087214082Sdim frame_need_space (fc, max_regs - 1); 3088214082Sdim cie = fc; 3089214082Sdim fc->augmentation = ""; 3090214082Sdim fc->fde_encoding = 0; 3091214082Sdim } 3092214082Sdim else 3093214082Sdim { 3094214082Sdim fc->ncols = cie->ncols; 3095214082Sdim fc->col_type = xcmalloc (fc->ncols, sizeof (short int)); 3096214082Sdim fc->col_offset = xcmalloc (fc->ncols, sizeof (int)); 3097214082Sdim memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int)); 3098214082Sdim memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int)); 3099214082Sdim fc->augmentation = cie->augmentation; 3100214082Sdim fc->code_factor = cie->code_factor; 3101214082Sdim fc->data_factor = cie->data_factor; 3102214082Sdim fc->cfa_reg = cie->cfa_reg; 3103214082Sdim fc->cfa_offset = cie->cfa_offset; 3104214082Sdim fc->ra = cie->ra; 3105214082Sdim frame_need_space (fc, max_regs-1); 3106214082Sdim fc->fde_encoding = cie->fde_encoding; 3107214082Sdim } 3108214082Sdim 3109214082Sdim if (fc->fde_encoding) 3110214082Sdim encoded_ptr_size = size_of_encoded_value (fc->fde_encoding); 3111214082Sdim 3112214082Sdim fc->pc_begin = get_encoded_value (start, fc->fde_encoding); 3113214082Sdim if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel 3114214082Sdim /* Don't adjust for relocatable file since there's 3115214082Sdim invariably a pcrel reloc here, which we haven't 3116214082Sdim applied. */ 3117214082Sdim && !is_relocatable) 3118214082Sdim fc->pc_begin += section->address + (start - section_start); 3119214082Sdim start += encoded_ptr_size; 3120214082Sdim fc->pc_range = byte_get (start, encoded_ptr_size); 3121214082Sdim start += encoded_ptr_size; 3122214082Sdim 3123214082Sdim if (cie->augmentation[0] == 'z') 3124214082Sdim { 3125214082Sdim augmentation_data_len = LEB (); 3126214082Sdim augmentation_data = start; 3127214082Sdim start += augmentation_data_len; 3128214082Sdim } 3129214082Sdim 3130214082Sdim printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n", 3131214082Sdim (unsigned long)(saved_start - section_start), length, cie_id, 3132214082Sdim (unsigned long)(cie->chunk_start - section_start), 3133214082Sdim fc->pc_begin, fc->pc_begin + fc->pc_range); 3134214082Sdim if (! do_debug_frames_interp && augmentation_data_len) 3135214082Sdim { 3136214082Sdim unsigned long i; 3137214082Sdim 3138214082Sdim printf (" Augmentation data: "); 3139214082Sdim for (i = 0; i < augmentation_data_len; ++i) 3140214082Sdim printf (" %02x", augmentation_data[i]); 3141214082Sdim putchar ('\n'); 3142214082Sdim putchar ('\n'); 3143214082Sdim } 3144214082Sdim } 3145214082Sdim 3146214082Sdim /* At this point, fc is the current chunk, cie (if any) is set, and 3147214082Sdim we're about to interpret instructions for the chunk. */ 3148214082Sdim /* ??? At present we need to do this always, since this sizes the 3149214082Sdim fc->col_type and fc->col_offset arrays, which we write into always. 3150214082Sdim We should probably split the interpreted and non-interpreted bits 3151214082Sdim into two different routines, since there's so much that doesn't 3152214082Sdim really overlap between them. */ 3153214082Sdim if (1 || do_debug_frames_interp) 3154214082Sdim { 3155214082Sdim /* Start by making a pass over the chunk, allocating storage 3156214082Sdim and taking note of what registers are used. */ 3157214082Sdim unsigned char *tmp = start; 3158214082Sdim 3159214082Sdim while (start < block_end) 3160214082Sdim { 3161214082Sdim unsigned op, opa; 3162214082Sdim unsigned long reg, tmp; 3163214082Sdim 3164214082Sdim op = *start++; 3165214082Sdim opa = op & 0x3f; 3166214082Sdim if (op & 0xc0) 3167214082Sdim op &= 0xc0; 3168214082Sdim 3169214082Sdim /* Warning: if you add any more cases to this switch, be 3170214082Sdim sure to add them to the corresponding switch below. */ 3171214082Sdim switch (op) 3172214082Sdim { 3173214082Sdim case DW_CFA_advance_loc: 3174214082Sdim break; 3175214082Sdim case DW_CFA_offset: 3176214082Sdim LEB (); 3177214082Sdim frame_need_space (fc, opa); 3178214082Sdim fc->col_type[opa] = DW_CFA_undefined; 3179214082Sdim break; 3180214082Sdim case DW_CFA_restore: 3181214082Sdim frame_need_space (fc, opa); 3182214082Sdim fc->col_type[opa] = DW_CFA_undefined; 3183214082Sdim break; 3184214082Sdim case DW_CFA_set_loc: 3185214082Sdim start += encoded_ptr_size; 3186214082Sdim break; 3187214082Sdim case DW_CFA_advance_loc1: 3188214082Sdim start += 1; 3189214082Sdim break; 3190214082Sdim case DW_CFA_advance_loc2: 3191214082Sdim start += 2; 3192214082Sdim break; 3193214082Sdim case DW_CFA_advance_loc4: 3194214082Sdim start += 4; 3195214082Sdim break; 3196214082Sdim case DW_CFA_offset_extended: 3197214082Sdim case DW_CFA_val_offset: 3198214082Sdim reg = LEB (); LEB (); 3199214082Sdim frame_need_space (fc, reg); 3200214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3201214082Sdim break; 3202214082Sdim case DW_CFA_restore_extended: 3203214082Sdim reg = LEB (); 3204214082Sdim frame_need_space (fc, reg); 3205214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3206214082Sdim break; 3207214082Sdim case DW_CFA_undefined: 3208214082Sdim reg = LEB (); 3209214082Sdim frame_need_space (fc, reg); 3210214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3211214082Sdim break; 3212214082Sdim case DW_CFA_same_value: 3213214082Sdim reg = LEB (); 3214214082Sdim frame_need_space (fc, reg); 3215214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3216214082Sdim break; 3217214082Sdim case DW_CFA_register: 3218214082Sdim reg = LEB (); LEB (); 3219214082Sdim frame_need_space (fc, reg); 3220214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3221214082Sdim break; 3222214082Sdim case DW_CFA_def_cfa: 3223214082Sdim LEB (); LEB (); 3224214082Sdim break; 3225214082Sdim case DW_CFA_def_cfa_register: 3226214082Sdim LEB (); 3227214082Sdim break; 3228214082Sdim case DW_CFA_def_cfa_offset: 3229214082Sdim LEB (); 3230214082Sdim break; 3231214082Sdim case DW_CFA_def_cfa_expression: 3232214082Sdim tmp = LEB (); 3233214082Sdim start += tmp; 3234214082Sdim break; 3235214082Sdim case DW_CFA_expression: 3236214082Sdim case DW_CFA_val_expression: 3237214082Sdim reg = LEB (); 3238214082Sdim tmp = LEB (); 3239214082Sdim start += tmp; 3240214082Sdim frame_need_space (fc, reg); 3241214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3242214082Sdim break; 3243214082Sdim case DW_CFA_offset_extended_sf: 3244214082Sdim case DW_CFA_val_offset_sf: 3245214082Sdim reg = LEB (); SLEB (); 3246214082Sdim frame_need_space (fc, reg); 3247214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3248214082Sdim break; 3249214082Sdim case DW_CFA_def_cfa_sf: 3250214082Sdim LEB (); SLEB (); 3251214082Sdim break; 3252214082Sdim case DW_CFA_def_cfa_offset_sf: 3253214082Sdim SLEB (); 3254214082Sdim break; 3255214082Sdim case DW_CFA_MIPS_advance_loc8: 3256214082Sdim start += 8; 3257214082Sdim break; 3258214082Sdim case DW_CFA_GNU_args_size: 3259214082Sdim LEB (); 3260214082Sdim break; 3261214082Sdim case DW_CFA_GNU_negative_offset_extended: 3262214082Sdim reg = LEB (); LEB (); 3263214082Sdim frame_need_space (fc, reg); 3264214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3265214082Sdim 3266214082Sdim default: 3267214082Sdim break; 3268214082Sdim } 3269214082Sdim } 3270214082Sdim start = tmp; 3271214082Sdim } 3272214082Sdim 3273214082Sdim /* Now we know what registers are used, make a second pass over 3274214082Sdim the chunk, this time actually printing out the info. */ 3275214082Sdim 3276214082Sdim while (start < block_end) 3277214082Sdim { 3278214082Sdim unsigned op, opa; 3279214082Sdim unsigned long ul, reg, roffs; 3280214082Sdim long l, ofs; 3281214082Sdim dwarf_vma vma; 3282214082Sdim 3283214082Sdim op = *start++; 3284214082Sdim opa = op & 0x3f; 3285214082Sdim if (op & 0xc0) 3286214082Sdim op &= 0xc0; 3287214082Sdim 3288214082Sdim /* Warning: if you add any more cases to this switch, be 3289214082Sdim sure to add them to the corresponding switch above. */ 3290214082Sdim switch (op) 3291214082Sdim { 3292214082Sdim case DW_CFA_advance_loc: 3293214082Sdim if (do_debug_frames_interp) 3294214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3295214082Sdim else 3296214082Sdim printf (" DW_CFA_advance_loc: %d to %08lx\n", 3297214082Sdim opa * fc->code_factor, 3298214082Sdim fc->pc_begin + opa * fc->code_factor); 3299214082Sdim fc->pc_begin += opa * fc->code_factor; 3300214082Sdim break; 3301214082Sdim 3302214082Sdim case DW_CFA_offset: 3303214082Sdim roffs = LEB (); 3304214082Sdim if (! do_debug_frames_interp) 3305214082Sdim printf (" DW_CFA_offset: r%d at cfa%+ld\n", 3306214082Sdim opa, roffs * fc->data_factor); 3307214082Sdim fc->col_type[opa] = DW_CFA_offset; 3308214082Sdim fc->col_offset[opa] = roffs * fc->data_factor; 3309214082Sdim break; 3310214082Sdim 3311214082Sdim case DW_CFA_restore: 3312214082Sdim if (! do_debug_frames_interp) 3313214082Sdim printf (" DW_CFA_restore: r%d\n", opa); 3314214082Sdim fc->col_type[opa] = cie->col_type[opa]; 3315214082Sdim fc->col_offset[opa] = cie->col_offset[opa]; 3316214082Sdim break; 3317214082Sdim 3318214082Sdim case DW_CFA_set_loc: 3319214082Sdim vma = get_encoded_value (start, fc->fde_encoding); 3320214082Sdim if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel 3321214082Sdim && !is_relocatable) 3322214082Sdim vma += section->address + (start - section_start); 3323214082Sdim start += encoded_ptr_size; 3324214082Sdim if (do_debug_frames_interp) 3325214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3326214082Sdim else 3327214082Sdim printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma); 3328214082Sdim fc->pc_begin = vma; 3329214082Sdim break; 3330214082Sdim 3331214082Sdim case DW_CFA_advance_loc1: 3332214082Sdim ofs = byte_get (start, 1); start += 1; 3333214082Sdim if (do_debug_frames_interp) 3334214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3335214082Sdim else 3336214082Sdim printf (" DW_CFA_advance_loc1: %ld to %08lx\n", 3337214082Sdim ofs * fc->code_factor, 3338214082Sdim fc->pc_begin + ofs * fc->code_factor); 3339214082Sdim fc->pc_begin += ofs * fc->code_factor; 3340214082Sdim break; 3341214082Sdim 3342214082Sdim case DW_CFA_advance_loc2: 3343214082Sdim ofs = byte_get (start, 2); start += 2; 3344214082Sdim if (do_debug_frames_interp) 3345214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3346214082Sdim else 3347214082Sdim printf (" DW_CFA_advance_loc2: %ld to %08lx\n", 3348214082Sdim ofs * fc->code_factor, 3349214082Sdim fc->pc_begin + ofs * fc->code_factor); 3350214082Sdim fc->pc_begin += ofs * fc->code_factor; 3351214082Sdim break; 3352214082Sdim 3353214082Sdim case DW_CFA_advance_loc4: 3354214082Sdim ofs = byte_get (start, 4); start += 4; 3355214082Sdim if (do_debug_frames_interp) 3356214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3357214082Sdim else 3358214082Sdim printf (" DW_CFA_advance_loc4: %ld to %08lx\n", 3359214082Sdim ofs * fc->code_factor, 3360214082Sdim fc->pc_begin + ofs * fc->code_factor); 3361214082Sdim fc->pc_begin += ofs * fc->code_factor; 3362214082Sdim break; 3363214082Sdim 3364214082Sdim case DW_CFA_offset_extended: 3365214082Sdim reg = LEB (); 3366214082Sdim roffs = LEB (); 3367214082Sdim if (! do_debug_frames_interp) 3368214082Sdim printf (" DW_CFA_offset_extended: r%ld at cfa%+ld\n", 3369214082Sdim reg, roffs * fc->data_factor); 3370214082Sdim fc->col_type[reg] = DW_CFA_offset; 3371214082Sdim fc->col_offset[reg] = roffs * fc->data_factor; 3372214082Sdim break; 3373214082Sdim 3374214082Sdim case DW_CFA_val_offset: 3375214082Sdim reg = LEB (); 3376214082Sdim roffs = LEB (); 3377214082Sdim if (! do_debug_frames_interp) 3378214082Sdim printf (" DW_CFA_val_offset: r%ld at cfa%+ld\n", 3379214082Sdim reg, roffs * fc->data_factor); 3380214082Sdim fc->col_type[reg] = DW_CFA_val_offset; 3381214082Sdim fc->col_offset[reg] = roffs * fc->data_factor; 3382214082Sdim break; 3383214082Sdim 3384214082Sdim case DW_CFA_restore_extended: 3385214082Sdim reg = LEB (); 3386214082Sdim if (! do_debug_frames_interp) 3387214082Sdim printf (" DW_CFA_restore_extended: r%ld\n", reg); 3388214082Sdim fc->col_type[reg] = cie->col_type[reg]; 3389214082Sdim fc->col_offset[reg] = cie->col_offset[reg]; 3390214082Sdim break; 3391214082Sdim 3392214082Sdim case DW_CFA_undefined: 3393214082Sdim reg = LEB (); 3394214082Sdim if (! do_debug_frames_interp) 3395214082Sdim printf (" DW_CFA_undefined: r%ld\n", reg); 3396214082Sdim fc->col_type[reg] = DW_CFA_undefined; 3397214082Sdim fc->col_offset[reg] = 0; 3398214082Sdim break; 3399214082Sdim 3400214082Sdim case DW_CFA_same_value: 3401214082Sdim reg = LEB (); 3402214082Sdim if (! do_debug_frames_interp) 3403214082Sdim printf (" DW_CFA_same_value: r%ld\n", reg); 3404214082Sdim fc->col_type[reg] = DW_CFA_same_value; 3405214082Sdim fc->col_offset[reg] = 0; 3406214082Sdim break; 3407214082Sdim 3408214082Sdim case DW_CFA_register: 3409214082Sdim reg = LEB (); 3410214082Sdim roffs = LEB (); 3411214082Sdim if (! do_debug_frames_interp) 3412214082Sdim printf (" DW_CFA_register: r%ld in r%ld\n", reg, roffs); 3413214082Sdim fc->col_type[reg] = DW_CFA_register; 3414214082Sdim fc->col_offset[reg] = roffs; 3415214082Sdim break; 3416214082Sdim 3417214082Sdim case DW_CFA_remember_state: 3418214082Sdim if (! do_debug_frames_interp) 3419214082Sdim printf (" DW_CFA_remember_state\n"); 3420214082Sdim rs = xmalloc (sizeof (Frame_Chunk)); 3421214082Sdim rs->ncols = fc->ncols; 3422214082Sdim rs->col_type = xcmalloc (rs->ncols, sizeof (short int)); 3423214082Sdim rs->col_offset = xcmalloc (rs->ncols, sizeof (int)); 3424214082Sdim memcpy (rs->col_type, fc->col_type, rs->ncols); 3425214082Sdim memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int)); 3426214082Sdim rs->next = remembered_state; 3427214082Sdim remembered_state = rs; 3428214082Sdim break; 3429214082Sdim 3430214082Sdim case DW_CFA_restore_state: 3431214082Sdim if (! do_debug_frames_interp) 3432214082Sdim printf (" DW_CFA_restore_state\n"); 3433214082Sdim rs = remembered_state; 3434214082Sdim if (rs) 3435214082Sdim { 3436214082Sdim remembered_state = rs->next; 3437214082Sdim frame_need_space (fc, rs->ncols-1); 3438214082Sdim memcpy (fc->col_type, rs->col_type, rs->ncols); 3439214082Sdim memcpy (fc->col_offset, rs->col_offset, 3440214082Sdim rs->ncols * sizeof (int)); 3441214082Sdim free (rs->col_type); 3442214082Sdim free (rs->col_offset); 3443214082Sdim free (rs); 3444214082Sdim } 3445214082Sdim else if (do_debug_frames_interp) 3446214082Sdim printf ("Mismatched DW_CFA_restore_state\n"); 3447214082Sdim break; 3448214082Sdim 3449214082Sdim case DW_CFA_def_cfa: 3450214082Sdim fc->cfa_reg = LEB (); 3451214082Sdim fc->cfa_offset = LEB (); 3452214082Sdim fc->cfa_exp = 0; 3453214082Sdim if (! do_debug_frames_interp) 3454214082Sdim printf (" DW_CFA_def_cfa: r%d ofs %d\n", 3455214082Sdim fc->cfa_reg, fc->cfa_offset); 3456214082Sdim break; 3457214082Sdim 3458214082Sdim case DW_CFA_def_cfa_register: 3459214082Sdim fc->cfa_reg = LEB (); 3460214082Sdim fc->cfa_exp = 0; 3461214082Sdim if (! do_debug_frames_interp) 3462214082Sdim printf (" DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg); 3463214082Sdim break; 3464214082Sdim 3465214082Sdim case DW_CFA_def_cfa_offset: 3466214082Sdim fc->cfa_offset = LEB (); 3467214082Sdim if (! do_debug_frames_interp) 3468214082Sdim printf (" DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset); 3469214082Sdim break; 3470214082Sdim 3471214082Sdim case DW_CFA_nop: 3472214082Sdim if (! do_debug_frames_interp) 3473214082Sdim printf (" DW_CFA_nop\n"); 3474214082Sdim break; 3475214082Sdim 3476214082Sdim case DW_CFA_def_cfa_expression: 3477214082Sdim ul = LEB (); 3478214082Sdim if (! do_debug_frames_interp) 3479214082Sdim { 3480214082Sdim printf (" DW_CFA_def_cfa_expression ("); 3481214082Sdim decode_location_expression (start, eh_addr_size, ul, 0); 3482214082Sdim printf (")\n"); 3483214082Sdim } 3484214082Sdim fc->cfa_exp = 1; 3485214082Sdim start += ul; 3486214082Sdim break; 3487214082Sdim 3488214082Sdim case DW_CFA_expression: 3489214082Sdim reg = LEB (); 3490214082Sdim ul = LEB (); 3491214082Sdim if (! do_debug_frames_interp) 3492214082Sdim { 3493214082Sdim printf (" DW_CFA_expression: r%ld (", reg); 3494214082Sdim decode_location_expression (start, eh_addr_size, ul, 0); 3495214082Sdim printf (")\n"); 3496214082Sdim } 3497214082Sdim fc->col_type[reg] = DW_CFA_expression; 3498214082Sdim start += ul; 3499214082Sdim break; 3500214082Sdim 3501214082Sdim case DW_CFA_val_expression: 3502214082Sdim reg = LEB (); 3503214082Sdim ul = LEB (); 3504214082Sdim if (! do_debug_frames_interp) 3505214082Sdim { 3506214082Sdim printf (" DW_CFA_val_expression: r%ld (", reg); 3507214082Sdim decode_location_expression (start, eh_addr_size, ul, 0); 3508214082Sdim printf (")\n"); 3509214082Sdim } 3510214082Sdim fc->col_type[reg] = DW_CFA_val_expression; 3511214082Sdim start += ul; 3512214082Sdim break; 3513214082Sdim 3514214082Sdim case DW_CFA_offset_extended_sf: 3515214082Sdim reg = LEB (); 3516214082Sdim l = SLEB (); 3517214082Sdim frame_need_space (fc, reg); 3518214082Sdim if (! do_debug_frames_interp) 3519214082Sdim printf (" DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n", 3520214082Sdim reg, l * fc->data_factor); 3521214082Sdim fc->col_type[reg] = DW_CFA_offset; 3522214082Sdim fc->col_offset[reg] = l * fc->data_factor; 3523214082Sdim break; 3524214082Sdim 3525214082Sdim case DW_CFA_val_offset_sf: 3526214082Sdim reg = LEB (); 3527214082Sdim l = SLEB (); 3528214082Sdim frame_need_space (fc, reg); 3529214082Sdim if (! do_debug_frames_interp) 3530214082Sdim printf (" DW_CFA_val_offset_sf: r%ld at cfa%+ld\n", 3531214082Sdim reg, l * fc->data_factor); 3532214082Sdim fc->col_type[reg] = DW_CFA_val_offset; 3533214082Sdim fc->col_offset[reg] = l * fc->data_factor; 3534214082Sdim break; 3535214082Sdim 3536214082Sdim case DW_CFA_def_cfa_sf: 3537214082Sdim fc->cfa_reg = LEB (); 3538214082Sdim fc->cfa_offset = SLEB (); 3539214082Sdim fc->cfa_offset = fc->cfa_offset * fc->data_factor; 3540214082Sdim fc->cfa_exp = 0; 3541214082Sdim if (! do_debug_frames_interp) 3542214082Sdim printf (" DW_CFA_def_cfa_sf: r%d ofs %d\n", 3543214082Sdim fc->cfa_reg, fc->cfa_offset); 3544214082Sdim break; 3545214082Sdim 3546214082Sdim case DW_CFA_def_cfa_offset_sf: 3547214082Sdim fc->cfa_offset = SLEB (); 3548214082Sdim fc->cfa_offset = fc->cfa_offset * fc->data_factor; 3549214082Sdim if (! do_debug_frames_interp) 3550214082Sdim printf (" DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset); 3551214082Sdim break; 3552214082Sdim 3553214082Sdim case DW_CFA_MIPS_advance_loc8: 3554214082Sdim ofs = byte_get (start, 8); start += 8; 3555214082Sdim if (do_debug_frames_interp) 3556214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3557214082Sdim else 3558214082Sdim printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n", 3559214082Sdim ofs * fc->code_factor, 3560214082Sdim fc->pc_begin + ofs * fc->code_factor); 3561214082Sdim fc->pc_begin += ofs * fc->code_factor; 3562214082Sdim break; 3563214082Sdim 3564214082Sdim case DW_CFA_GNU_window_save: 3565214082Sdim if (! do_debug_frames_interp) 3566214082Sdim printf (" DW_CFA_GNU_window_save\n"); 3567214082Sdim break; 3568214082Sdim 3569214082Sdim case DW_CFA_GNU_args_size: 3570214082Sdim ul = LEB (); 3571214082Sdim if (! do_debug_frames_interp) 3572214082Sdim printf (" DW_CFA_GNU_args_size: %ld\n", ul); 3573214082Sdim break; 3574214082Sdim 3575214082Sdim case DW_CFA_GNU_negative_offset_extended: 3576214082Sdim reg = LEB (); 3577214082Sdim l = - LEB (); 3578214082Sdim frame_need_space (fc, reg); 3579214082Sdim if (! do_debug_frames_interp) 3580214082Sdim printf (" DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n", 3581214082Sdim reg, l * fc->data_factor); 3582214082Sdim fc->col_type[reg] = DW_CFA_offset; 3583214082Sdim fc->col_offset[reg] = l * fc->data_factor; 3584214082Sdim break; 3585214082Sdim 3586214082Sdim default: 3587214082Sdim warn (_("unsupported or unknown DW_CFA_%d\n"), op); 3588214082Sdim start = block_end; 3589214082Sdim } 3590214082Sdim } 3591214082Sdim 3592214082Sdim if (do_debug_frames_interp) 3593214082Sdim frame_display_row (fc, &need_col_headers, &max_regs); 3594214082Sdim 3595214082Sdim start = block_end; 3596214082Sdim } 3597214082Sdim 3598214082Sdim printf ("\n"); 3599214082Sdim 3600214082Sdim return 1; 3601214082Sdim} 3602214082Sdim 3603214082Sdim#undef GET 3604214082Sdim#undef LEB 3605214082Sdim#undef SLEB 3606214082Sdim 3607214082Sdimstatic int 3608214082Sdimdisplay_debug_not_supported (struct dwarf_section *section, 3609214082Sdim void *file ATTRIBUTE_UNUSED) 3610214082Sdim{ 3611214082Sdim printf (_("Displaying the debug contents of section %s is not yet supported.\n"), 3612214082Sdim section->name); 3613214082Sdim 3614214082Sdim return 1; 3615214082Sdim} 3616214082Sdim 3617214082Sdimvoid * 3618214082Sdimcmalloc (size_t nmemb, size_t size) 3619214082Sdim{ 3620214082Sdim /* Check for overflow. */ 3621214082Sdim if (nmemb >= ~(size_t) 0 / size) 3622214082Sdim return NULL; 3623214082Sdim else 3624214082Sdim return malloc (nmemb * size); 3625214082Sdim} 3626214082Sdim 3627214082Sdimvoid * 3628214082Sdimxcmalloc (size_t nmemb, size_t size) 3629214082Sdim{ 3630214082Sdim /* Check for overflow. */ 3631214082Sdim if (nmemb >= ~(size_t) 0 / size) 3632214082Sdim return NULL; 3633214082Sdim else 3634214082Sdim return xmalloc (nmemb * size); 3635214082Sdim} 3636214082Sdim 3637214082Sdimvoid * 3638214082Sdimxcrealloc (void *ptr, size_t nmemb, size_t size) 3639214082Sdim{ 3640214082Sdim /* Check for overflow. */ 3641214082Sdim if (nmemb >= ~(size_t) 0 / size) 3642214082Sdim return NULL; 3643214082Sdim else 3644214082Sdim return xrealloc (ptr, nmemb * size); 3645214082Sdim} 3646214082Sdim 3647214082Sdimvoid 3648214082Sdimerror (const char *message, ...) 3649214082Sdim{ 3650214082Sdim va_list args; 3651214082Sdim 3652214082Sdim va_start (args, message); 3653214082Sdim fprintf (stderr, _("%s: Error: "), program_name); 3654214082Sdim vfprintf (stderr, message, args); 3655214082Sdim va_end (args); 3656214082Sdim} 3657214082Sdim 3658214082Sdimvoid 3659214082Sdimwarn (const char *message, ...) 3660214082Sdim{ 3661214082Sdim va_list args; 3662214082Sdim 3663214082Sdim va_start (args, message); 3664214082Sdim fprintf (stderr, _("%s: Warning: "), program_name); 3665214082Sdim vfprintf (stderr, message, args); 3666214082Sdim va_end (args); 3667214082Sdim} 3668214082Sdim 3669214082Sdimvoid 3670214082Sdimfree_debug_memory (void) 3671214082Sdim{ 3672214082Sdim enum dwarf_section_display_enum i; 3673214082Sdim 3674214082Sdim free_abbrevs (); 3675214082Sdim 3676214082Sdim for (i = 0; i < max; i++) 3677214082Sdim free_debug_section (i); 3678214082Sdim 3679214082Sdim if (debug_information) 3680214082Sdim { 3681214082Sdim for (i = 0; i < num_debug_info_entries; i++) 3682214082Sdim { 3683214082Sdim if (!debug_information [i].max_loc_offsets) 3684214082Sdim { 3685214082Sdim free (debug_information [i].loc_offsets); 3686214082Sdim free (debug_information [i].have_frame_base); 3687214082Sdim } 3688214082Sdim if (!debug_information [i].max_range_lists) 3689214082Sdim free (debug_information [i].range_lists); 3690214082Sdim } 3691214082Sdim free (debug_information); 3692214082Sdim debug_information = NULL; 3693214082Sdim num_debug_info_entries = 0; 3694214082Sdim } 3695214082Sdim 3696214082Sdim} 3697214082Sdim 3698214082Sdimstruct dwarf_section_display debug_displays[] = 3699214082Sdim{ 3700214082Sdim { { ".debug_abbrev", NULL, 0, 0 }, 3701214082Sdim display_debug_abbrev, 0, 0 }, 3702214082Sdim { { ".debug_aranges", NULL, 0, 0 }, 3703214082Sdim display_debug_aranges, 0, 0 }, 3704214082Sdim { { ".debug_frame", NULL, 0, 0 }, 3705214082Sdim display_debug_frames, 1, 0 }, 3706214082Sdim { { ".debug_info", NULL, 0, 0 }, 3707214082Sdim display_debug_info, 1, 0 }, 3708214082Sdim { { ".debug_line", NULL, 0, 0 }, 3709214082Sdim display_debug_lines, 0, 0 }, 3710214082Sdim { { ".debug_pubnames", NULL, 0, 0 }, 3711214082Sdim display_debug_pubnames, 0, 0 }, 3712214082Sdim { { ".eh_frame", NULL, 0, 0 }, 3713214082Sdim display_debug_frames, 1, 1 }, 3714214082Sdim { { ".debug_macinfo", NULL, 0, 0 }, 3715214082Sdim display_debug_macinfo, 0, 0 }, 3716214082Sdim { { ".debug_str", NULL, 0, 0 }, 3717214082Sdim display_debug_str, 0, 0 }, 3718214082Sdim { { ".debug_loc", NULL, 0, 0 }, 3719214082Sdim display_debug_loc, 0, 0 }, 3720214082Sdim { { ".debug_pubtypes", NULL, 0, 0 }, 3721214082Sdim display_debug_pubnames, 0, 0 }, 3722214082Sdim { { ".debug_ranges", NULL, 0, 0 }, 3723214082Sdim display_debug_ranges, 0, 0 }, 3724214082Sdim { { ".debug_static_func", NULL, 0, 0 }, 3725214082Sdim display_debug_not_supported, 0, 0 }, 3726214082Sdim { { ".debug_static_vars", NULL, 0, 0 }, 3727214082Sdim display_debug_not_supported, 0, 0 }, 3728214082Sdim { { ".debug_types", NULL, 0, 0 }, 3729214082Sdim display_debug_not_supported, 0, 0 }, 3730214082Sdim { { ".debug_weaknames", NULL, 0, 0 }, 3731214082Sdim display_debug_not_supported, 0, 0 } 3732214082Sdim}; 3733