xref: /openbsd-src/gnu/usr.bin/binutils-2.17/binutils/dwarf.c (revision e309974ca263a5e8452336c36e3dd7cad43d615b)
13d8817e4Smiod /* dwarf.c -- display DWARF contents of a BFD binary file
23d8817e4Smiod    Copyright 2005, 2006
33d8817e4Smiod    Free Software Foundation, Inc.
43d8817e4Smiod 
53d8817e4Smiod    This file is part of GNU Binutils.
63d8817e4Smiod 
73d8817e4Smiod    This program is free software; you can redistribute it and/or modify
83d8817e4Smiod    it under the terms of the GNU General Public License as published by
93d8817e4Smiod    the Free Software Foundation; either version 2 of the License, or
103d8817e4Smiod    (at your option) any later version.
113d8817e4Smiod 
123d8817e4Smiod    This program is distributed in the hope that it will be useful,
133d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
143d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
153d8817e4Smiod    GNU General Public License for more details.
163d8817e4Smiod 
173d8817e4Smiod    You should have received a copy of the GNU General Public License
183d8817e4Smiod    along with this program; if not, write to the Free Software
193d8817e4Smiod    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
203d8817e4Smiod    02110-1301, USA.  */
213d8817e4Smiod 
223d8817e4Smiod #include <stdio.h>
233d8817e4Smiod 
243d8817e4Smiod #include "dwarf.h"
253d8817e4Smiod 
263d8817e4Smiod #include "bucomm.h"
273d8817e4Smiod #include "libiberty.h"
283d8817e4Smiod 
293d8817e4Smiod static int have_frame_base;
303d8817e4Smiod static int need_base_address;
313d8817e4Smiod 
323d8817e4Smiod static unsigned int last_pointer_size = 0;
333d8817e4Smiod static int warned_about_missing_comp_units = FALSE;
343d8817e4Smiod 
353d8817e4Smiod static unsigned int num_debug_info_entries = 0;
363d8817e4Smiod static debug_info *debug_information = NULL;
373d8817e4Smiod 
383d8817e4Smiod dwarf_vma eh_addr_size;
393d8817e4Smiod int is_relocatable;
403d8817e4Smiod 
413d8817e4Smiod int do_debug_info;
423d8817e4Smiod int do_debug_abbrevs;
433d8817e4Smiod int do_debug_lines;
443d8817e4Smiod int do_debug_pubnames;
453d8817e4Smiod int do_debug_aranges;
463d8817e4Smiod int do_debug_ranges;
473d8817e4Smiod int do_debug_frames;
483d8817e4Smiod int do_debug_frames_interp;
493d8817e4Smiod int do_debug_macinfo;
503d8817e4Smiod int do_debug_str;
513d8817e4Smiod int do_debug_loc;
523d8817e4Smiod 
533d8817e4Smiod dwarf_vma (*byte_get) (unsigned char *, int);
543d8817e4Smiod 
553d8817e4Smiod dwarf_vma
byte_get_little_endian(unsigned char * field,int size)563d8817e4Smiod byte_get_little_endian (unsigned char *field, int size)
573d8817e4Smiod {
583d8817e4Smiod   switch (size)
593d8817e4Smiod     {
603d8817e4Smiod     case 1:
613d8817e4Smiod       return *field;
623d8817e4Smiod 
633d8817e4Smiod     case 2:
643d8817e4Smiod       return  ((unsigned int) (field[0]))
653d8817e4Smiod 	|    (((unsigned int) (field[1])) << 8);
663d8817e4Smiod 
673d8817e4Smiod     case 4:
683d8817e4Smiod       return  ((unsigned long) (field[0]))
693d8817e4Smiod 	|    (((unsigned long) (field[1])) << 8)
703d8817e4Smiod 	|    (((unsigned long) (field[2])) << 16)
713d8817e4Smiod 	|    (((unsigned long) (field[3])) << 24);
723d8817e4Smiod 
733d8817e4Smiod     case 8:
743d8817e4Smiod       if (sizeof (dwarf_vma) == 8)
753d8817e4Smiod 	return  ((dwarf_vma) (field[0]))
763d8817e4Smiod 	  |    (((dwarf_vma) (field[1])) << 8)
773d8817e4Smiod 	  |    (((dwarf_vma) (field[2])) << 16)
783d8817e4Smiod 	  |    (((dwarf_vma) (field[3])) << 24)
793d8817e4Smiod 	  |    (((dwarf_vma) (field[4])) << 32)
803d8817e4Smiod 	  |    (((dwarf_vma) (field[5])) << 40)
813d8817e4Smiod 	  |    (((dwarf_vma) (field[6])) << 48)
823d8817e4Smiod 	  |    (((dwarf_vma) (field[7])) << 56);
833d8817e4Smiod       else if (sizeof (dwarf_vma) == 4)
843d8817e4Smiod 	/* We want to extract data from an 8 byte wide field and
853d8817e4Smiod 	   place it into a 4 byte wide field.  Since this is a little
863d8817e4Smiod 	   endian source we can just use the 4 byte extraction code.  */
873d8817e4Smiod 	return  ((unsigned long) (field[0]))
883d8817e4Smiod 	  |    (((unsigned long) (field[1])) << 8)
893d8817e4Smiod 	  |    (((unsigned long) (field[2])) << 16)
903d8817e4Smiod 	  |    (((unsigned long) (field[3])) << 24);
913d8817e4Smiod 
923d8817e4Smiod     default:
933d8817e4Smiod       error (_("Unhandled data length: %d\n"), size);
943d8817e4Smiod       abort ();
953d8817e4Smiod     }
963d8817e4Smiod }
973d8817e4Smiod 
983d8817e4Smiod dwarf_vma
byte_get_big_endian(unsigned char * field,int size)993d8817e4Smiod byte_get_big_endian (unsigned char *field, int size)
1003d8817e4Smiod {
1013d8817e4Smiod   switch (size)
1023d8817e4Smiod     {
1033d8817e4Smiod     case 1:
1043d8817e4Smiod       return *field;
1053d8817e4Smiod 
1063d8817e4Smiod     case 2:
1073d8817e4Smiod       return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
1083d8817e4Smiod 
1093d8817e4Smiod     case 4:
1103d8817e4Smiod       return ((unsigned long) (field[3]))
1113d8817e4Smiod 	|   (((unsigned long) (field[2])) << 8)
1123d8817e4Smiod 	|   (((unsigned long) (field[1])) << 16)
1133d8817e4Smiod 	|   (((unsigned long) (field[0])) << 24);
1143d8817e4Smiod 
1153d8817e4Smiod     case 8:
1163d8817e4Smiod       if (sizeof (dwarf_vma) == 8)
1173d8817e4Smiod 	return ((dwarf_vma) (field[7]))
1183d8817e4Smiod 	  |   (((dwarf_vma) (field[6])) << 8)
1193d8817e4Smiod 	  |   (((dwarf_vma) (field[5])) << 16)
1203d8817e4Smiod 	  |   (((dwarf_vma) (field[4])) << 24)
1213d8817e4Smiod 	  |   (((dwarf_vma) (field[3])) << 32)
1223d8817e4Smiod 	  |   (((dwarf_vma) (field[2])) << 40)
1233d8817e4Smiod 	  |   (((dwarf_vma) (field[1])) << 48)
1243d8817e4Smiod 	  |   (((dwarf_vma) (field[0])) << 56);
1253d8817e4Smiod       else if (sizeof (dwarf_vma) == 4)
1263d8817e4Smiod 	{
1273d8817e4Smiod 	  /* Although we are extracing data from an 8 byte wide field,
1283d8817e4Smiod 	     we are returning only 4 bytes of data.  */
1293d8817e4Smiod 	  field += 4;
1303d8817e4Smiod 	  return ((unsigned long) (field[3]))
1313d8817e4Smiod 	    |   (((unsigned long) (field[2])) << 8)
1323d8817e4Smiod 	    |   (((unsigned long) (field[1])) << 16)
1333d8817e4Smiod 	    |   (((unsigned long) (field[0])) << 24);
1343d8817e4Smiod 	}
1353d8817e4Smiod 
1363d8817e4Smiod     default:
1373d8817e4Smiod       error (_("Unhandled data length: %d\n"), size);
1383d8817e4Smiod       abort ();
1393d8817e4Smiod     }
1403d8817e4Smiod }
1413d8817e4Smiod 
1423d8817e4Smiod static dwarf_vma
byte_get_signed(unsigned char * field,int size)1433d8817e4Smiod byte_get_signed (unsigned char *field, int size)
1443d8817e4Smiod {
1453d8817e4Smiod   dwarf_vma x = byte_get (field, size);
1463d8817e4Smiod 
1473d8817e4Smiod   switch (size)
1483d8817e4Smiod     {
1493d8817e4Smiod     case 1:
1503d8817e4Smiod       return (x ^ 0x80) - 0x80;
1513d8817e4Smiod     case 2:
1523d8817e4Smiod       return (x ^ 0x8000) - 0x8000;
1533d8817e4Smiod     case 4:
1543d8817e4Smiod       return (x ^ 0x80000000) - 0x80000000;
1553d8817e4Smiod     case 8:
1563d8817e4Smiod       return x;
1573d8817e4Smiod     default:
1583d8817e4Smiod       abort ();
1593d8817e4Smiod     }
1603d8817e4Smiod }
1613d8817e4Smiod 
1623d8817e4Smiod static unsigned long int
read_leb128(unsigned char * data,unsigned int * length_return,int sign)1633d8817e4Smiod read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
1643d8817e4Smiod {
1653d8817e4Smiod   unsigned long int result = 0;
1663d8817e4Smiod   unsigned int num_read = 0;
1673d8817e4Smiod   unsigned int shift = 0;
1683d8817e4Smiod   unsigned char byte;
1693d8817e4Smiod 
1703d8817e4Smiod   do
1713d8817e4Smiod     {
1723d8817e4Smiod       byte = *data++;
1733d8817e4Smiod       num_read++;
1743d8817e4Smiod 
1753d8817e4Smiod       result |= ((unsigned long int) (byte & 0x7f)) << shift;
1763d8817e4Smiod 
1773d8817e4Smiod       shift += 7;
1783d8817e4Smiod 
1793d8817e4Smiod     }
1803d8817e4Smiod   while (byte & 0x80);
1813d8817e4Smiod 
1823d8817e4Smiod   if (length_return != NULL)
1833d8817e4Smiod     *length_return = num_read;
1843d8817e4Smiod 
1853d8817e4Smiod   if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
1863d8817e4Smiod     result |= -1L << shift;
1873d8817e4Smiod 
1883d8817e4Smiod   return result;
1893d8817e4Smiod }
1903d8817e4Smiod 
1913d8817e4Smiod typedef struct State_Machine_Registers
1923d8817e4Smiod {
1933d8817e4Smiod   unsigned long address;
1943d8817e4Smiod   unsigned int file;
1953d8817e4Smiod   unsigned int line;
1963d8817e4Smiod   unsigned int column;
1973d8817e4Smiod   int is_stmt;
1983d8817e4Smiod   int basic_block;
1993d8817e4Smiod   int end_sequence;
2003d8817e4Smiod /* This variable hold the number of the last entry seen
2013d8817e4Smiod    in the File Table.  */
2023d8817e4Smiod   unsigned int last_file_entry;
2033d8817e4Smiod } SMR;
2043d8817e4Smiod 
2053d8817e4Smiod static SMR state_machine_regs;
2063d8817e4Smiod 
2073d8817e4Smiod static void
reset_state_machine(int is_stmt)2083d8817e4Smiod reset_state_machine (int is_stmt)
2093d8817e4Smiod {
2103d8817e4Smiod   state_machine_regs.address = 0;
2113d8817e4Smiod   state_machine_regs.file = 1;
2123d8817e4Smiod   state_machine_regs.line = 1;
2133d8817e4Smiod   state_machine_regs.column = 0;
2143d8817e4Smiod   state_machine_regs.is_stmt = is_stmt;
2153d8817e4Smiod   state_machine_regs.basic_block = 0;
2163d8817e4Smiod   state_machine_regs.end_sequence = 0;
2173d8817e4Smiod   state_machine_regs.last_file_entry = 0;
2183d8817e4Smiod }
2193d8817e4Smiod 
2203d8817e4Smiod /* Handled an extend line op.
2213d8817e4Smiod    Returns the number of bytes read.  */
2223d8817e4Smiod 
2233d8817e4Smiod static int
process_extended_line_op(unsigned char * data,int is_stmt)2243d8817e4Smiod process_extended_line_op (unsigned char *data, int is_stmt)
2253d8817e4Smiod {
2263d8817e4Smiod   unsigned char op_code;
2273d8817e4Smiod   unsigned int bytes_read;
2283d8817e4Smiod   unsigned int len;
2293d8817e4Smiod   unsigned char *name;
2303d8817e4Smiod   unsigned long adr;
2313d8817e4Smiod 
2323d8817e4Smiod   len = read_leb128 (data, & bytes_read, 0);
2333d8817e4Smiod   data += bytes_read;
2343d8817e4Smiod 
2353d8817e4Smiod   if (len == 0)
2363d8817e4Smiod     {
2373d8817e4Smiod       warn (_("badly formed extended line op encountered!\n"));
2383d8817e4Smiod       return bytes_read;
2393d8817e4Smiod     }
2403d8817e4Smiod 
2413d8817e4Smiod   len += bytes_read;
2423d8817e4Smiod   op_code = *data++;
2433d8817e4Smiod 
2443d8817e4Smiod   printf (_("  Extended opcode %d: "), op_code);
2453d8817e4Smiod 
2463d8817e4Smiod   switch (op_code)
2473d8817e4Smiod     {
2483d8817e4Smiod     case DW_LNE_end_sequence:
2493d8817e4Smiod       printf (_("End of Sequence\n\n"));
2503d8817e4Smiod       reset_state_machine (is_stmt);
2513d8817e4Smiod       break;
2523d8817e4Smiod 
2533d8817e4Smiod     case DW_LNE_set_address:
2543d8817e4Smiod       adr = byte_get (data, len - bytes_read - 1);
2553d8817e4Smiod       printf (_("set Address to 0x%lx\n"), adr);
2563d8817e4Smiod       state_machine_regs.address = adr;
2573d8817e4Smiod       break;
2583d8817e4Smiod 
2593d8817e4Smiod     case DW_LNE_define_file:
2603d8817e4Smiod       printf (_("  define new File Table entry\n"));
2613d8817e4Smiod       printf (_("  Entry\tDir\tTime\tSize\tName\n"));
2623d8817e4Smiod 
2633d8817e4Smiod       printf (_("   %d\t"), ++state_machine_regs.last_file_entry);
2643d8817e4Smiod       name = data;
2653d8817e4Smiod       data += strlen ((char *) data) + 1;
2663d8817e4Smiod       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
2673d8817e4Smiod       data += bytes_read;
2683d8817e4Smiod       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
2693d8817e4Smiod       data += bytes_read;
2703d8817e4Smiod       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
2713d8817e4Smiod       printf (_("%s\n\n"), name);
2723d8817e4Smiod       break;
2733d8817e4Smiod 
2743d8817e4Smiod     default:
2753d8817e4Smiod       printf (_("UNKNOWN: length %d\n"), len - bytes_read);
2763d8817e4Smiod       break;
2773d8817e4Smiod     }
2783d8817e4Smiod 
2793d8817e4Smiod   return len;
2803d8817e4Smiod }
2813d8817e4Smiod 
2823d8817e4Smiod static const char *
fetch_indirect_string(unsigned long offset)2833d8817e4Smiod fetch_indirect_string (unsigned long offset)
2843d8817e4Smiod {
2853d8817e4Smiod   struct dwarf_section *section = &debug_displays [str].section;
2863d8817e4Smiod 
2873d8817e4Smiod   if (section->start == NULL)
2883d8817e4Smiod     return _("<no .debug_str section>");
2893d8817e4Smiod 
2903d8817e4Smiod   /* DWARF sections under Mach-O have non-zero addresses.  */
2913d8817e4Smiod   offset -= section->address;
2923d8817e4Smiod   if (offset > section->size)
2933d8817e4Smiod     {
2943d8817e4Smiod       warn (_("DW_FORM_strp offset too big: %lx\n"), offset);
2953d8817e4Smiod       return _("<offset is too big>");
2963d8817e4Smiod     }
2973d8817e4Smiod 
2983d8817e4Smiod   return (const char *) section->start + offset;
2993d8817e4Smiod }
3003d8817e4Smiod 
3013d8817e4Smiod /* FIXME:  There are better and more efficient ways to handle
3023d8817e4Smiod    these structures.  For now though, I just want something that
3033d8817e4Smiod    is simple to implement.  */
3043d8817e4Smiod typedef struct abbrev_attr
3053d8817e4Smiod {
3063d8817e4Smiod   unsigned long attribute;
3073d8817e4Smiod   unsigned long form;
3083d8817e4Smiod   struct abbrev_attr *next;
3093d8817e4Smiod }
3103d8817e4Smiod abbrev_attr;
3113d8817e4Smiod 
3123d8817e4Smiod typedef struct abbrev_entry
3133d8817e4Smiod {
3143d8817e4Smiod   unsigned long entry;
3153d8817e4Smiod   unsigned long tag;
3163d8817e4Smiod   int children;
3173d8817e4Smiod   struct abbrev_attr *first_attr;
3183d8817e4Smiod   struct abbrev_attr *last_attr;
3193d8817e4Smiod   struct abbrev_entry *next;
3203d8817e4Smiod }
3213d8817e4Smiod abbrev_entry;
3223d8817e4Smiod 
3233d8817e4Smiod static abbrev_entry *first_abbrev = NULL;
3243d8817e4Smiod static abbrev_entry *last_abbrev = NULL;
3253d8817e4Smiod 
3263d8817e4Smiod static void
free_abbrevs(void)3273d8817e4Smiod free_abbrevs (void)
3283d8817e4Smiod {
3293d8817e4Smiod   abbrev_entry *abbrev;
3303d8817e4Smiod 
3313d8817e4Smiod   for (abbrev = first_abbrev; abbrev;)
3323d8817e4Smiod     {
3333d8817e4Smiod       abbrev_entry *next = abbrev->next;
3343d8817e4Smiod       abbrev_attr *attr;
3353d8817e4Smiod 
3363d8817e4Smiod       for (attr = abbrev->first_attr; attr;)
3373d8817e4Smiod 	{
3383d8817e4Smiod 	  abbrev_attr *next = attr->next;
3393d8817e4Smiod 
3403d8817e4Smiod 	  free (attr);
3413d8817e4Smiod 	  attr = next;
3423d8817e4Smiod 	}
3433d8817e4Smiod 
3443d8817e4Smiod       free (abbrev);
3453d8817e4Smiod       abbrev = next;
3463d8817e4Smiod     }
3473d8817e4Smiod 
3483d8817e4Smiod   last_abbrev = first_abbrev = NULL;
3493d8817e4Smiod }
3503d8817e4Smiod 
3513d8817e4Smiod static void
add_abbrev(unsigned long number,unsigned long tag,int children)3523d8817e4Smiod add_abbrev (unsigned long number, unsigned long tag, int children)
3533d8817e4Smiod {
3543d8817e4Smiod   abbrev_entry *entry;
3553d8817e4Smiod 
3563d8817e4Smiod   entry = malloc (sizeof (*entry));
3573d8817e4Smiod 
3583d8817e4Smiod   if (entry == NULL)
3593d8817e4Smiod     /* ugg */
3603d8817e4Smiod     return;
3613d8817e4Smiod 
3623d8817e4Smiod   entry->entry      = number;
3633d8817e4Smiod   entry->tag        = tag;
3643d8817e4Smiod   entry->children   = children;
3653d8817e4Smiod   entry->first_attr = NULL;
3663d8817e4Smiod   entry->last_attr  = NULL;
3673d8817e4Smiod   entry->next       = NULL;
3683d8817e4Smiod 
3693d8817e4Smiod   if (first_abbrev == NULL)
3703d8817e4Smiod     first_abbrev = entry;
3713d8817e4Smiod   else
3723d8817e4Smiod     last_abbrev->next = entry;
3733d8817e4Smiod 
3743d8817e4Smiod   last_abbrev = entry;
3753d8817e4Smiod }
3763d8817e4Smiod 
3773d8817e4Smiod static void
add_abbrev_attr(unsigned long attribute,unsigned long form)3783d8817e4Smiod add_abbrev_attr (unsigned long attribute, unsigned long form)
3793d8817e4Smiod {
3803d8817e4Smiod   abbrev_attr *attr;
3813d8817e4Smiod 
3823d8817e4Smiod   attr = malloc (sizeof (*attr));
3833d8817e4Smiod 
3843d8817e4Smiod   if (attr == NULL)
3853d8817e4Smiod     /* ugg */
3863d8817e4Smiod     return;
3873d8817e4Smiod 
3883d8817e4Smiod   attr->attribute = attribute;
3893d8817e4Smiod   attr->form      = form;
3903d8817e4Smiod   attr->next      = NULL;
3913d8817e4Smiod 
3923d8817e4Smiod   if (last_abbrev->first_attr == NULL)
3933d8817e4Smiod     last_abbrev->first_attr = attr;
3943d8817e4Smiod   else
3953d8817e4Smiod     last_abbrev->last_attr->next = attr;
3963d8817e4Smiod 
3973d8817e4Smiod   last_abbrev->last_attr = attr;
3983d8817e4Smiod }
3993d8817e4Smiod 
4003d8817e4Smiod /* Processes the (partial) contents of a .debug_abbrev section.
4013d8817e4Smiod    Returns NULL if the end of the section was encountered.
4023d8817e4Smiod    Returns the address after the last byte read if the end of
4033d8817e4Smiod    an abbreviation set was found.  */
4043d8817e4Smiod 
4053d8817e4Smiod static unsigned char *
process_abbrev_section(unsigned char * start,unsigned char * end)4063d8817e4Smiod process_abbrev_section (unsigned char *start, unsigned char *end)
4073d8817e4Smiod {
4083d8817e4Smiod   if (first_abbrev != NULL)
4093d8817e4Smiod     return NULL;
4103d8817e4Smiod 
4113d8817e4Smiod   while (start < end)
4123d8817e4Smiod     {
4133d8817e4Smiod       unsigned int bytes_read;
4143d8817e4Smiod       unsigned long entry;
4153d8817e4Smiod       unsigned long tag;
4163d8817e4Smiod       unsigned long attribute;
4173d8817e4Smiod       int children;
4183d8817e4Smiod 
4193d8817e4Smiod       entry = read_leb128 (start, & bytes_read, 0);
4203d8817e4Smiod       start += bytes_read;
4213d8817e4Smiod 
4223d8817e4Smiod       /* A single zero is supposed to end the section according
4233d8817e4Smiod 	 to the standard.  If there's more, then signal that to
4243d8817e4Smiod 	 the caller.  */
4253d8817e4Smiod       if (entry == 0)
4263d8817e4Smiod 	return start == end ? NULL : start;
4273d8817e4Smiod 
4283d8817e4Smiod       tag = read_leb128 (start, & bytes_read, 0);
4293d8817e4Smiod       start += bytes_read;
4303d8817e4Smiod 
4313d8817e4Smiod       children = *start++;
4323d8817e4Smiod 
4333d8817e4Smiod       add_abbrev (entry, tag, children);
4343d8817e4Smiod 
4353d8817e4Smiod       do
4363d8817e4Smiod 	{
4373d8817e4Smiod 	  unsigned long form;
4383d8817e4Smiod 
4393d8817e4Smiod 	  attribute = read_leb128 (start, & bytes_read, 0);
4403d8817e4Smiod 	  start += bytes_read;
4413d8817e4Smiod 
4423d8817e4Smiod 	  form = read_leb128 (start, & bytes_read, 0);
4433d8817e4Smiod 	  start += bytes_read;
4443d8817e4Smiod 
4453d8817e4Smiod 	  if (attribute != 0)
4463d8817e4Smiod 	    add_abbrev_attr (attribute, form);
4473d8817e4Smiod 	}
4483d8817e4Smiod       while (attribute != 0);
4493d8817e4Smiod     }
4503d8817e4Smiod 
4513d8817e4Smiod   return NULL;
4523d8817e4Smiod }
4533d8817e4Smiod 
4543d8817e4Smiod static char *
get_TAG_name(unsigned long tag)4553d8817e4Smiod get_TAG_name (unsigned long tag)
4563d8817e4Smiod {
4573d8817e4Smiod   switch (tag)
4583d8817e4Smiod     {
4593d8817e4Smiod     case DW_TAG_padding:		return "DW_TAG_padding";
4603d8817e4Smiod     case DW_TAG_array_type:		return "DW_TAG_array_type";
4613d8817e4Smiod     case DW_TAG_class_type:		return "DW_TAG_class_type";
4623d8817e4Smiod     case DW_TAG_entry_point:		return "DW_TAG_entry_point";
4633d8817e4Smiod     case DW_TAG_enumeration_type:	return "DW_TAG_enumeration_type";
4643d8817e4Smiod     case DW_TAG_formal_parameter:	return "DW_TAG_formal_parameter";
4653d8817e4Smiod     case DW_TAG_imported_declaration:	return "DW_TAG_imported_declaration";
4663d8817e4Smiod     case DW_TAG_label:			return "DW_TAG_label";
4673d8817e4Smiod     case DW_TAG_lexical_block:		return "DW_TAG_lexical_block";
4683d8817e4Smiod     case DW_TAG_member:			return "DW_TAG_member";
4693d8817e4Smiod     case DW_TAG_pointer_type:		return "DW_TAG_pointer_type";
4703d8817e4Smiod     case DW_TAG_reference_type:		return "DW_TAG_reference_type";
4713d8817e4Smiod     case DW_TAG_compile_unit:		return "DW_TAG_compile_unit";
4723d8817e4Smiod     case DW_TAG_string_type:		return "DW_TAG_string_type";
4733d8817e4Smiod     case DW_TAG_structure_type:		return "DW_TAG_structure_type";
4743d8817e4Smiod     case DW_TAG_subroutine_type:	return "DW_TAG_subroutine_type";
4753d8817e4Smiod     case DW_TAG_typedef:		return "DW_TAG_typedef";
4763d8817e4Smiod     case DW_TAG_union_type:		return "DW_TAG_union_type";
4773d8817e4Smiod     case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
4783d8817e4Smiod     case DW_TAG_variant:		return "DW_TAG_variant";
4793d8817e4Smiod     case DW_TAG_common_block:		return "DW_TAG_common_block";
4803d8817e4Smiod     case DW_TAG_common_inclusion:	return "DW_TAG_common_inclusion";
4813d8817e4Smiod     case DW_TAG_inheritance:		return "DW_TAG_inheritance";
4823d8817e4Smiod     case DW_TAG_inlined_subroutine:	return "DW_TAG_inlined_subroutine";
4833d8817e4Smiod     case DW_TAG_module:			return "DW_TAG_module";
4843d8817e4Smiod     case DW_TAG_ptr_to_member_type:	return "DW_TAG_ptr_to_member_type";
4853d8817e4Smiod     case DW_TAG_set_type:		return "DW_TAG_set_type";
4863d8817e4Smiod     case DW_TAG_subrange_type:		return "DW_TAG_subrange_type";
4873d8817e4Smiod     case DW_TAG_with_stmt:		return "DW_TAG_with_stmt";
4883d8817e4Smiod     case DW_TAG_access_declaration:	return "DW_TAG_access_declaration";
4893d8817e4Smiod     case DW_TAG_base_type:		return "DW_TAG_base_type";
4903d8817e4Smiod     case DW_TAG_catch_block:		return "DW_TAG_catch_block";
4913d8817e4Smiod     case DW_TAG_const_type:		return "DW_TAG_const_type";
4923d8817e4Smiod     case DW_TAG_constant:		return "DW_TAG_constant";
4933d8817e4Smiod     case DW_TAG_enumerator:		return "DW_TAG_enumerator";
4943d8817e4Smiod     case DW_TAG_file_type:		return "DW_TAG_file_type";
4953d8817e4Smiod     case DW_TAG_friend:			return "DW_TAG_friend";
4963d8817e4Smiod     case DW_TAG_namelist:		return "DW_TAG_namelist";
4973d8817e4Smiod     case DW_TAG_namelist_item:		return "DW_TAG_namelist_item";
4983d8817e4Smiod     case DW_TAG_packed_type:		return "DW_TAG_packed_type";
4993d8817e4Smiod     case DW_TAG_subprogram:		return "DW_TAG_subprogram";
5003d8817e4Smiod     case DW_TAG_template_type_param:	return "DW_TAG_template_type_param";
5013d8817e4Smiod     case DW_TAG_template_value_param:	return "DW_TAG_template_value_param";
5023d8817e4Smiod     case DW_TAG_thrown_type:		return "DW_TAG_thrown_type";
5033d8817e4Smiod     case DW_TAG_try_block:		return "DW_TAG_try_block";
5043d8817e4Smiod     case DW_TAG_variant_part:		return "DW_TAG_variant_part";
5053d8817e4Smiod     case DW_TAG_variable:		return "DW_TAG_variable";
5063d8817e4Smiod     case DW_TAG_volatile_type:		return "DW_TAG_volatile_type";
5073d8817e4Smiod     case DW_TAG_MIPS_loop:		return "DW_TAG_MIPS_loop";
5083d8817e4Smiod     case DW_TAG_format_label:		return "DW_TAG_format_label";
5093d8817e4Smiod     case DW_TAG_function_template:	return "DW_TAG_function_template";
5103d8817e4Smiod     case DW_TAG_class_template:		return "DW_TAG_class_template";
5113d8817e4Smiod       /* DWARF 2.1 values.  */
5123d8817e4Smiod     case DW_TAG_dwarf_procedure:	return "DW_TAG_dwarf_procedure";
5133d8817e4Smiod     case DW_TAG_restrict_type:		return "DW_TAG_restrict_type";
5143d8817e4Smiod     case DW_TAG_interface_type:		return "DW_TAG_interface_type";
5153d8817e4Smiod     case DW_TAG_namespace:		return "DW_TAG_namespace";
5163d8817e4Smiod     case DW_TAG_imported_module:	return "DW_TAG_imported_module";
5173d8817e4Smiod     case DW_TAG_unspecified_type:	return "DW_TAG_unspecified_type";
5183d8817e4Smiod     case DW_TAG_partial_unit:		return "DW_TAG_partial_unit";
5193d8817e4Smiod     case DW_TAG_imported_unit:		return "DW_TAG_imported_unit";
5203d8817e4Smiod       /* UPC values.  */
5213d8817e4Smiod     case DW_TAG_upc_shared_type:	return "DW_TAG_upc_shared_type";
5223d8817e4Smiod     case DW_TAG_upc_strict_type:	return "DW_TAG_upc_strict_type";
5233d8817e4Smiod     case DW_TAG_upc_relaxed_type:	return "DW_TAG_upc_relaxed_type";
5243d8817e4Smiod     default:
5253d8817e4Smiod       {
5263d8817e4Smiod 	static char buffer[100];
5273d8817e4Smiod 
5283d8817e4Smiod 	snprintf (buffer, sizeof (buffer), _("Unknown TAG value: %lx"), tag);
5293d8817e4Smiod 	return buffer;
5303d8817e4Smiod       }
5313d8817e4Smiod     }
5323d8817e4Smiod }
5333d8817e4Smiod 
5343d8817e4Smiod static char *
get_FORM_name(unsigned long form)5353d8817e4Smiod get_FORM_name (unsigned long form)
5363d8817e4Smiod {
5373d8817e4Smiod   switch (form)
5383d8817e4Smiod     {
5393d8817e4Smiod     case DW_FORM_addr:		return "DW_FORM_addr";
5403d8817e4Smiod     case DW_FORM_block2:	return "DW_FORM_block2";
5413d8817e4Smiod     case DW_FORM_block4:	return "DW_FORM_block4";
5423d8817e4Smiod     case DW_FORM_data2:		return "DW_FORM_data2";
5433d8817e4Smiod     case DW_FORM_data4:		return "DW_FORM_data4";
5443d8817e4Smiod     case DW_FORM_data8:		return "DW_FORM_data8";
5453d8817e4Smiod     case DW_FORM_string:	return "DW_FORM_string";
5463d8817e4Smiod     case DW_FORM_block:		return "DW_FORM_block";
5473d8817e4Smiod     case DW_FORM_block1:	return "DW_FORM_block1";
5483d8817e4Smiod     case DW_FORM_data1:		return "DW_FORM_data1";
5493d8817e4Smiod     case DW_FORM_flag:		return "DW_FORM_flag";
5503d8817e4Smiod     case DW_FORM_sdata:		return "DW_FORM_sdata";
5513d8817e4Smiod     case DW_FORM_strp:		return "DW_FORM_strp";
5523d8817e4Smiod     case DW_FORM_udata:		return "DW_FORM_udata";
5533d8817e4Smiod     case DW_FORM_ref_addr:	return "DW_FORM_ref_addr";
5543d8817e4Smiod     case DW_FORM_ref1:		return "DW_FORM_ref1";
5553d8817e4Smiod     case DW_FORM_ref2:		return "DW_FORM_ref2";
5563d8817e4Smiod     case DW_FORM_ref4:		return "DW_FORM_ref4";
5573d8817e4Smiod     case DW_FORM_ref8:		return "DW_FORM_ref8";
5583d8817e4Smiod     case DW_FORM_ref_udata:	return "DW_FORM_ref_udata";
5593d8817e4Smiod     case DW_FORM_indirect:	return "DW_FORM_indirect";
5603d8817e4Smiod     default:
5613d8817e4Smiod       {
5623d8817e4Smiod 	static char buffer[100];
5633d8817e4Smiod 
5643d8817e4Smiod 	snprintf (buffer, sizeof (buffer), _("Unknown FORM value: %lx"), form);
5653d8817e4Smiod 	return buffer;
5663d8817e4Smiod       }
5673d8817e4Smiod     }
5683d8817e4Smiod }
5693d8817e4Smiod 
5703d8817e4Smiod static unsigned char *
display_block(unsigned char * data,unsigned long length)5713d8817e4Smiod display_block (unsigned char *data, unsigned long length)
5723d8817e4Smiod {
5733d8817e4Smiod   printf (_(" %lu byte block: "), length);
5743d8817e4Smiod 
5753d8817e4Smiod   while (length --)
5763d8817e4Smiod     printf ("%lx ", (unsigned long) byte_get (data++, 1));
5773d8817e4Smiod 
5783d8817e4Smiod   return data;
5793d8817e4Smiod }
5803d8817e4Smiod 
5813d8817e4Smiod static int
decode_location_expression(unsigned char * data,unsigned int pointer_size,unsigned long length,unsigned long cu_offset)5823d8817e4Smiod decode_location_expression (unsigned char * data,
5833d8817e4Smiod 			    unsigned int pointer_size,
5843d8817e4Smiod 			    unsigned long length,
5853d8817e4Smiod 			    unsigned long cu_offset)
5863d8817e4Smiod {
5873d8817e4Smiod   unsigned op;
5883d8817e4Smiod   unsigned int bytes_read;
5893d8817e4Smiod   unsigned long uvalue;
5903d8817e4Smiod   unsigned char *end = data + length;
5913d8817e4Smiod   int need_frame_base = 0;
5923d8817e4Smiod 
5933d8817e4Smiod   while (data < end)
5943d8817e4Smiod     {
5953d8817e4Smiod       op = *data++;
5963d8817e4Smiod 
5973d8817e4Smiod       switch (op)
5983d8817e4Smiod 	{
5993d8817e4Smiod 	case DW_OP_addr:
6003d8817e4Smiod 	  printf ("DW_OP_addr: %lx",
6013d8817e4Smiod 		  (unsigned long) byte_get (data, pointer_size));
6023d8817e4Smiod 	  data += pointer_size;
6033d8817e4Smiod 	  break;
6043d8817e4Smiod 	case DW_OP_deref:
6053d8817e4Smiod 	  printf ("DW_OP_deref");
6063d8817e4Smiod 	  break;
6073d8817e4Smiod 	case DW_OP_const1u:
6083d8817e4Smiod 	  printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
6093d8817e4Smiod 	  break;
6103d8817e4Smiod 	case DW_OP_const1s:
6113d8817e4Smiod 	  printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1));
6123d8817e4Smiod 	  break;
6133d8817e4Smiod 	case DW_OP_const2u:
6143d8817e4Smiod 	  printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
6153d8817e4Smiod 	  data += 2;
6163d8817e4Smiod 	  break;
6173d8817e4Smiod 	case DW_OP_const2s:
6183d8817e4Smiod 	  printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2));
6193d8817e4Smiod 	  data += 2;
6203d8817e4Smiod 	  break;
6213d8817e4Smiod 	case DW_OP_const4u:
6223d8817e4Smiod 	  printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
6233d8817e4Smiod 	  data += 4;
6243d8817e4Smiod 	  break;
6253d8817e4Smiod 	case DW_OP_const4s:
6263d8817e4Smiod 	  printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4));
6273d8817e4Smiod 	  data += 4;
6283d8817e4Smiod 	  break;
6293d8817e4Smiod 	case DW_OP_const8u:
6303d8817e4Smiod 	  printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
6313d8817e4Smiod 		  (unsigned long) byte_get (data + 4, 4));
6323d8817e4Smiod 	  data += 8;
6333d8817e4Smiod 	  break;
6343d8817e4Smiod 	case DW_OP_const8s:
6353d8817e4Smiod 	  printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
6363d8817e4Smiod 		  (long) byte_get (data + 4, 4));
6373d8817e4Smiod 	  data += 8;
6383d8817e4Smiod 	  break;
6393d8817e4Smiod 	case DW_OP_constu:
6403d8817e4Smiod 	  printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
6413d8817e4Smiod 	  data += bytes_read;
6423d8817e4Smiod 	  break;
6433d8817e4Smiod 	case DW_OP_consts:
6443d8817e4Smiod 	  printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
6453d8817e4Smiod 	  data += bytes_read;
6463d8817e4Smiod 	  break;
6473d8817e4Smiod 	case DW_OP_dup:
6483d8817e4Smiod 	  printf ("DW_OP_dup");
6493d8817e4Smiod 	  break;
6503d8817e4Smiod 	case DW_OP_drop:
6513d8817e4Smiod 	  printf ("DW_OP_drop");
6523d8817e4Smiod 	  break;
6533d8817e4Smiod 	case DW_OP_over:
6543d8817e4Smiod 	  printf ("DW_OP_over");
6553d8817e4Smiod 	  break;
6563d8817e4Smiod 	case DW_OP_pick:
6573d8817e4Smiod 	  printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
6583d8817e4Smiod 	  break;
6593d8817e4Smiod 	case DW_OP_swap:
6603d8817e4Smiod 	  printf ("DW_OP_swap");
6613d8817e4Smiod 	  break;
6623d8817e4Smiod 	case DW_OP_rot:
6633d8817e4Smiod 	  printf ("DW_OP_rot");
6643d8817e4Smiod 	  break;
6653d8817e4Smiod 	case DW_OP_xderef:
6663d8817e4Smiod 	  printf ("DW_OP_xderef");
6673d8817e4Smiod 	  break;
6683d8817e4Smiod 	case DW_OP_abs:
6693d8817e4Smiod 	  printf ("DW_OP_abs");
6703d8817e4Smiod 	  break;
6713d8817e4Smiod 	case DW_OP_and:
6723d8817e4Smiod 	  printf ("DW_OP_and");
6733d8817e4Smiod 	  break;
6743d8817e4Smiod 	case DW_OP_div:
6753d8817e4Smiod 	  printf ("DW_OP_div");
6763d8817e4Smiod 	  break;
6773d8817e4Smiod 	case DW_OP_minus:
6783d8817e4Smiod 	  printf ("DW_OP_minus");
6793d8817e4Smiod 	  break;
6803d8817e4Smiod 	case DW_OP_mod:
6813d8817e4Smiod 	  printf ("DW_OP_mod");
6823d8817e4Smiod 	  break;
6833d8817e4Smiod 	case DW_OP_mul:
6843d8817e4Smiod 	  printf ("DW_OP_mul");
6853d8817e4Smiod 	  break;
6863d8817e4Smiod 	case DW_OP_neg:
6873d8817e4Smiod 	  printf ("DW_OP_neg");
6883d8817e4Smiod 	  break;
6893d8817e4Smiod 	case DW_OP_not:
6903d8817e4Smiod 	  printf ("DW_OP_not");
6913d8817e4Smiod 	  break;
6923d8817e4Smiod 	case DW_OP_or:
6933d8817e4Smiod 	  printf ("DW_OP_or");
6943d8817e4Smiod 	  break;
6953d8817e4Smiod 	case DW_OP_plus:
6963d8817e4Smiod 	  printf ("DW_OP_plus");
6973d8817e4Smiod 	  break;
6983d8817e4Smiod 	case DW_OP_plus_uconst:
6993d8817e4Smiod 	  printf ("DW_OP_plus_uconst: %lu",
7003d8817e4Smiod 		  read_leb128 (data, &bytes_read, 0));
7013d8817e4Smiod 	  data += bytes_read;
7023d8817e4Smiod 	  break;
7033d8817e4Smiod 	case DW_OP_shl:
7043d8817e4Smiod 	  printf ("DW_OP_shl");
7053d8817e4Smiod 	  break;
7063d8817e4Smiod 	case DW_OP_shr:
7073d8817e4Smiod 	  printf ("DW_OP_shr");
7083d8817e4Smiod 	  break;
7093d8817e4Smiod 	case DW_OP_shra:
7103d8817e4Smiod 	  printf ("DW_OP_shra");
7113d8817e4Smiod 	  break;
7123d8817e4Smiod 	case DW_OP_xor:
7133d8817e4Smiod 	  printf ("DW_OP_xor");
7143d8817e4Smiod 	  break;
7153d8817e4Smiod 	case DW_OP_bra:
7163d8817e4Smiod 	  printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2));
7173d8817e4Smiod 	  data += 2;
7183d8817e4Smiod 	  break;
7193d8817e4Smiod 	case DW_OP_eq:
7203d8817e4Smiod 	  printf ("DW_OP_eq");
7213d8817e4Smiod 	  break;
7223d8817e4Smiod 	case DW_OP_ge:
7233d8817e4Smiod 	  printf ("DW_OP_ge");
7243d8817e4Smiod 	  break;
7253d8817e4Smiod 	case DW_OP_gt:
7263d8817e4Smiod 	  printf ("DW_OP_gt");
7273d8817e4Smiod 	  break;
7283d8817e4Smiod 	case DW_OP_le:
7293d8817e4Smiod 	  printf ("DW_OP_le");
7303d8817e4Smiod 	  break;
7313d8817e4Smiod 	case DW_OP_lt:
7323d8817e4Smiod 	  printf ("DW_OP_lt");
7333d8817e4Smiod 	  break;
7343d8817e4Smiod 	case DW_OP_ne:
7353d8817e4Smiod 	  printf ("DW_OP_ne");
7363d8817e4Smiod 	  break;
7373d8817e4Smiod 	case DW_OP_skip:
7383d8817e4Smiod 	  printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2));
7393d8817e4Smiod 	  data += 2;
7403d8817e4Smiod 	  break;
7413d8817e4Smiod 
7423d8817e4Smiod 	case DW_OP_lit0:
7433d8817e4Smiod 	case DW_OP_lit1:
7443d8817e4Smiod 	case DW_OP_lit2:
7453d8817e4Smiod 	case DW_OP_lit3:
7463d8817e4Smiod 	case DW_OP_lit4:
7473d8817e4Smiod 	case DW_OP_lit5:
7483d8817e4Smiod 	case DW_OP_lit6:
7493d8817e4Smiod 	case DW_OP_lit7:
7503d8817e4Smiod 	case DW_OP_lit8:
7513d8817e4Smiod 	case DW_OP_lit9:
7523d8817e4Smiod 	case DW_OP_lit10:
7533d8817e4Smiod 	case DW_OP_lit11:
7543d8817e4Smiod 	case DW_OP_lit12:
7553d8817e4Smiod 	case DW_OP_lit13:
7563d8817e4Smiod 	case DW_OP_lit14:
7573d8817e4Smiod 	case DW_OP_lit15:
7583d8817e4Smiod 	case DW_OP_lit16:
7593d8817e4Smiod 	case DW_OP_lit17:
7603d8817e4Smiod 	case DW_OP_lit18:
7613d8817e4Smiod 	case DW_OP_lit19:
7623d8817e4Smiod 	case DW_OP_lit20:
7633d8817e4Smiod 	case DW_OP_lit21:
7643d8817e4Smiod 	case DW_OP_lit22:
7653d8817e4Smiod 	case DW_OP_lit23:
7663d8817e4Smiod 	case DW_OP_lit24:
7673d8817e4Smiod 	case DW_OP_lit25:
7683d8817e4Smiod 	case DW_OP_lit26:
7693d8817e4Smiod 	case DW_OP_lit27:
7703d8817e4Smiod 	case DW_OP_lit28:
7713d8817e4Smiod 	case DW_OP_lit29:
7723d8817e4Smiod 	case DW_OP_lit30:
7733d8817e4Smiod 	case DW_OP_lit31:
7743d8817e4Smiod 	  printf ("DW_OP_lit%d", op - DW_OP_lit0);
7753d8817e4Smiod 	  break;
7763d8817e4Smiod 
7773d8817e4Smiod 	case DW_OP_reg0:
7783d8817e4Smiod 	case DW_OP_reg1:
7793d8817e4Smiod 	case DW_OP_reg2:
7803d8817e4Smiod 	case DW_OP_reg3:
7813d8817e4Smiod 	case DW_OP_reg4:
7823d8817e4Smiod 	case DW_OP_reg5:
7833d8817e4Smiod 	case DW_OP_reg6:
7843d8817e4Smiod 	case DW_OP_reg7:
7853d8817e4Smiod 	case DW_OP_reg8:
7863d8817e4Smiod 	case DW_OP_reg9:
7873d8817e4Smiod 	case DW_OP_reg10:
7883d8817e4Smiod 	case DW_OP_reg11:
7893d8817e4Smiod 	case DW_OP_reg12:
7903d8817e4Smiod 	case DW_OP_reg13:
7913d8817e4Smiod 	case DW_OP_reg14:
7923d8817e4Smiod 	case DW_OP_reg15:
7933d8817e4Smiod 	case DW_OP_reg16:
7943d8817e4Smiod 	case DW_OP_reg17:
7953d8817e4Smiod 	case DW_OP_reg18:
7963d8817e4Smiod 	case DW_OP_reg19:
7973d8817e4Smiod 	case DW_OP_reg20:
7983d8817e4Smiod 	case DW_OP_reg21:
7993d8817e4Smiod 	case DW_OP_reg22:
8003d8817e4Smiod 	case DW_OP_reg23:
8013d8817e4Smiod 	case DW_OP_reg24:
8023d8817e4Smiod 	case DW_OP_reg25:
8033d8817e4Smiod 	case DW_OP_reg26:
8043d8817e4Smiod 	case DW_OP_reg27:
8053d8817e4Smiod 	case DW_OP_reg28:
8063d8817e4Smiod 	case DW_OP_reg29:
8073d8817e4Smiod 	case DW_OP_reg30:
8083d8817e4Smiod 	case DW_OP_reg31:
8093d8817e4Smiod 	  printf ("DW_OP_reg%d", op - DW_OP_reg0);
8103d8817e4Smiod 	  break;
8113d8817e4Smiod 
8123d8817e4Smiod 	case DW_OP_breg0:
8133d8817e4Smiod 	case DW_OP_breg1:
8143d8817e4Smiod 	case DW_OP_breg2:
8153d8817e4Smiod 	case DW_OP_breg3:
8163d8817e4Smiod 	case DW_OP_breg4:
8173d8817e4Smiod 	case DW_OP_breg5:
8183d8817e4Smiod 	case DW_OP_breg6:
8193d8817e4Smiod 	case DW_OP_breg7:
8203d8817e4Smiod 	case DW_OP_breg8:
8213d8817e4Smiod 	case DW_OP_breg9:
8223d8817e4Smiod 	case DW_OP_breg10:
8233d8817e4Smiod 	case DW_OP_breg11:
8243d8817e4Smiod 	case DW_OP_breg12:
8253d8817e4Smiod 	case DW_OP_breg13:
8263d8817e4Smiod 	case DW_OP_breg14:
8273d8817e4Smiod 	case DW_OP_breg15:
8283d8817e4Smiod 	case DW_OP_breg16:
8293d8817e4Smiod 	case DW_OP_breg17:
8303d8817e4Smiod 	case DW_OP_breg18:
8313d8817e4Smiod 	case DW_OP_breg19:
8323d8817e4Smiod 	case DW_OP_breg20:
8333d8817e4Smiod 	case DW_OP_breg21:
8343d8817e4Smiod 	case DW_OP_breg22:
8353d8817e4Smiod 	case DW_OP_breg23:
8363d8817e4Smiod 	case DW_OP_breg24:
8373d8817e4Smiod 	case DW_OP_breg25:
8383d8817e4Smiod 	case DW_OP_breg26:
8393d8817e4Smiod 	case DW_OP_breg27:
8403d8817e4Smiod 	case DW_OP_breg28:
8413d8817e4Smiod 	case DW_OP_breg29:
8423d8817e4Smiod 	case DW_OP_breg30:
8433d8817e4Smiod 	case DW_OP_breg31:
8443d8817e4Smiod 	  printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
8453d8817e4Smiod 		  read_leb128 (data, &bytes_read, 1));
8463d8817e4Smiod 	  data += bytes_read;
8473d8817e4Smiod 	  break;
8483d8817e4Smiod 
8493d8817e4Smiod 	case DW_OP_regx:
8503d8817e4Smiod 	  printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
8513d8817e4Smiod 	  data += bytes_read;
8523d8817e4Smiod 	  break;
8533d8817e4Smiod 	case DW_OP_fbreg:
8543d8817e4Smiod 	  need_frame_base = 1;
8553d8817e4Smiod 	  printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
8563d8817e4Smiod 	  data += bytes_read;
8573d8817e4Smiod 	  break;
8583d8817e4Smiod 	case DW_OP_bregx:
8593d8817e4Smiod 	  uvalue = read_leb128 (data, &bytes_read, 0);
8603d8817e4Smiod 	  data += bytes_read;
8613d8817e4Smiod 	  printf ("DW_OP_bregx: %lu %ld", uvalue,
8623d8817e4Smiod 		  read_leb128 (data, &bytes_read, 1));
8633d8817e4Smiod 	  data += bytes_read;
8643d8817e4Smiod 	  break;
8653d8817e4Smiod 	case DW_OP_piece:
8663d8817e4Smiod 	  printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
8673d8817e4Smiod 	  data += bytes_read;
8683d8817e4Smiod 	  break;
8693d8817e4Smiod 	case DW_OP_deref_size:
8703d8817e4Smiod 	  printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
8713d8817e4Smiod 	  break;
8723d8817e4Smiod 	case DW_OP_xderef_size:
8733d8817e4Smiod 	  printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
8743d8817e4Smiod 	  break;
8753d8817e4Smiod 	case DW_OP_nop:
8763d8817e4Smiod 	  printf ("DW_OP_nop");
8773d8817e4Smiod 	  break;
8783d8817e4Smiod 
8793d8817e4Smiod 	  /* DWARF 3 extensions.  */
8803d8817e4Smiod 	case DW_OP_push_object_address:
8813d8817e4Smiod 	  printf ("DW_OP_push_object_address");
8823d8817e4Smiod 	  break;
8833d8817e4Smiod 	case DW_OP_call2:
8843d8817e4Smiod 	  /* XXX: Strictly speaking for 64-bit DWARF3 files
8853d8817e4Smiod 	     this ought to be an 8-byte wide computation.  */
8863d8817e4Smiod 	  printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2) + cu_offset);
8873d8817e4Smiod 	  data += 2;
8883d8817e4Smiod 	  break;
8893d8817e4Smiod 	case DW_OP_call4:
8903d8817e4Smiod 	  /* XXX: Strictly speaking for 64-bit DWARF3 files
8913d8817e4Smiod 	     this ought to be an 8-byte wide computation.  */
8923d8817e4Smiod 	  printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4) + cu_offset);
8933d8817e4Smiod 	  data += 4;
8943d8817e4Smiod 	  break;
8953d8817e4Smiod 	case DW_OP_call_ref:
8963d8817e4Smiod 	  printf ("DW_OP_call_ref");
8973d8817e4Smiod 	  break;
8983d8817e4Smiod 
8993d8817e4Smiod 	  /* GNU extensions.  */
9003d8817e4Smiod 	case DW_OP_GNU_push_tls_address:
9013d8817e4Smiod 	  printf ("DW_OP_GNU_push_tls_address");
9023d8817e4Smiod 	  break;
9033d8817e4Smiod 
9043d8817e4Smiod 	default:
9053d8817e4Smiod 	  if (op >= DW_OP_lo_user
9063d8817e4Smiod 	      && op <= DW_OP_hi_user)
9073d8817e4Smiod 	    printf (_("(User defined location op)"));
9083d8817e4Smiod 	  else
9093d8817e4Smiod 	    printf (_("(Unknown location op)"));
9103d8817e4Smiod 	  /* No way to tell where the next op is, so just bail.  */
9113d8817e4Smiod 	  return need_frame_base;
9123d8817e4Smiod 	}
9133d8817e4Smiod 
9143d8817e4Smiod       /* Separate the ops.  */
9153d8817e4Smiod       if (data < end)
9163d8817e4Smiod 	printf ("; ");
9173d8817e4Smiod     }
9183d8817e4Smiod 
9193d8817e4Smiod   return need_frame_base;
9203d8817e4Smiod }
9213d8817e4Smiod 
9223d8817e4Smiod static unsigned char *
read_and_display_attr_value(unsigned long attribute,unsigned long form,unsigned char * data,unsigned long cu_offset,unsigned long pointer_size,unsigned long offset_size,int dwarf_version,debug_info * debug_info_p,int do_loc)9233d8817e4Smiod read_and_display_attr_value (unsigned long attribute,
9243d8817e4Smiod 			     unsigned long form,
9253d8817e4Smiod 			     unsigned char *data,
9263d8817e4Smiod 			     unsigned long cu_offset,
9273d8817e4Smiod 			     unsigned long pointer_size,
9283d8817e4Smiod 			     unsigned long offset_size,
9293d8817e4Smiod 			     int dwarf_version,
9303d8817e4Smiod 			     debug_info *debug_info_p,
9313d8817e4Smiod 			     int do_loc)
9323d8817e4Smiod {
9333d8817e4Smiod   unsigned long uvalue = 0;
9343d8817e4Smiod   unsigned char *block_start = NULL;
9353d8817e4Smiod   unsigned int bytes_read;
9363d8817e4Smiod 
9373d8817e4Smiod   switch (form)
9383d8817e4Smiod     {
9393d8817e4Smiod     default:
9403d8817e4Smiod       break;
9413d8817e4Smiod 
9423d8817e4Smiod     case DW_FORM_ref_addr:
9433d8817e4Smiod       if (dwarf_version == 2)
9443d8817e4Smiod 	{
9453d8817e4Smiod 	  uvalue = byte_get (data, pointer_size);
9463d8817e4Smiod 	  data += pointer_size;
9473d8817e4Smiod 	}
9483d8817e4Smiod       else if (dwarf_version == 3)
9493d8817e4Smiod 	{
9503d8817e4Smiod 	  uvalue = byte_get (data, offset_size);
9513d8817e4Smiod 	  data += offset_size;
9523d8817e4Smiod 	}
9533d8817e4Smiod       else
9543d8817e4Smiod 	{
9553d8817e4Smiod 	  error (_("Internal error: DWARF version is not 2 or 3.\n"));
9563d8817e4Smiod 	}
9573d8817e4Smiod       break;
9583d8817e4Smiod 
9593d8817e4Smiod     case DW_FORM_addr:
9603d8817e4Smiod       uvalue = byte_get (data, pointer_size);
9613d8817e4Smiod       data += pointer_size;
9623d8817e4Smiod       break;
9633d8817e4Smiod 
9643d8817e4Smiod     case DW_FORM_strp:
9653d8817e4Smiod       uvalue = byte_get (data, offset_size);
9663d8817e4Smiod       data += offset_size;
9673d8817e4Smiod       break;
9683d8817e4Smiod 
9693d8817e4Smiod     case DW_FORM_ref1:
9703d8817e4Smiod     case DW_FORM_flag:
9713d8817e4Smiod     case DW_FORM_data1:
9723d8817e4Smiod       uvalue = byte_get (data++, 1);
9733d8817e4Smiod       break;
9743d8817e4Smiod 
9753d8817e4Smiod     case DW_FORM_ref2:
9763d8817e4Smiod     case DW_FORM_data2:
9773d8817e4Smiod       uvalue = byte_get (data, 2);
9783d8817e4Smiod       data += 2;
9793d8817e4Smiod       break;
9803d8817e4Smiod 
9813d8817e4Smiod     case DW_FORM_ref4:
9823d8817e4Smiod     case DW_FORM_data4:
9833d8817e4Smiod       uvalue = byte_get (data, 4);
9843d8817e4Smiod       data += 4;
9853d8817e4Smiod       break;
9863d8817e4Smiod 
9873d8817e4Smiod     case DW_FORM_sdata:
9883d8817e4Smiod       uvalue = read_leb128 (data, & bytes_read, 1);
9893d8817e4Smiod       data += bytes_read;
9903d8817e4Smiod       break;
9913d8817e4Smiod 
9923d8817e4Smiod     case DW_FORM_ref_udata:
9933d8817e4Smiod     case DW_FORM_udata:
9943d8817e4Smiod       uvalue = read_leb128 (data, & bytes_read, 0);
9953d8817e4Smiod       data += bytes_read;
9963d8817e4Smiod       break;
9973d8817e4Smiod 
9983d8817e4Smiod     case DW_FORM_indirect:
9993d8817e4Smiod       form = read_leb128 (data, & bytes_read, 0);
10003d8817e4Smiod       data += bytes_read;
10013d8817e4Smiod       if (!do_loc)
10023d8817e4Smiod 	printf (" %s", get_FORM_name (form));
10033d8817e4Smiod       return read_and_display_attr_value (attribute, form, data,
10043d8817e4Smiod 					  cu_offset, pointer_size,
10053d8817e4Smiod 					  offset_size, dwarf_version,
10063d8817e4Smiod 					  debug_info_p, do_loc);
10073d8817e4Smiod     }
10083d8817e4Smiod 
10093d8817e4Smiod   switch (form)
10103d8817e4Smiod     {
10113d8817e4Smiod     case DW_FORM_ref_addr:
10123d8817e4Smiod       if (!do_loc)
10133d8817e4Smiod 	printf (" <#%lx>", uvalue);
10143d8817e4Smiod       break;
10153d8817e4Smiod 
10163d8817e4Smiod     case DW_FORM_ref1:
10173d8817e4Smiod     case DW_FORM_ref2:
10183d8817e4Smiod     case DW_FORM_ref4:
10193d8817e4Smiod     case DW_FORM_ref_udata:
10203d8817e4Smiod       if (!do_loc)
10213d8817e4Smiod 	printf (" <%lx>", uvalue + cu_offset);
10223d8817e4Smiod       break;
10233d8817e4Smiod 
10243d8817e4Smiod     case DW_FORM_data4:
10253d8817e4Smiod     case DW_FORM_addr:
10263d8817e4Smiod       if (!do_loc)
10273d8817e4Smiod 	printf (" %#lx", uvalue);
10283d8817e4Smiod       break;
10293d8817e4Smiod 
10303d8817e4Smiod     case DW_FORM_flag:
10313d8817e4Smiod     case DW_FORM_data1:
10323d8817e4Smiod     case DW_FORM_data2:
10333d8817e4Smiod     case DW_FORM_sdata:
10343d8817e4Smiod     case DW_FORM_udata:
10353d8817e4Smiod       if (!do_loc)
10363d8817e4Smiod 	printf (" %ld", uvalue);
10373d8817e4Smiod       break;
10383d8817e4Smiod 
10393d8817e4Smiod     case DW_FORM_ref8:
10403d8817e4Smiod     case DW_FORM_data8:
10413d8817e4Smiod       if (!do_loc)
10423d8817e4Smiod 	{
10433d8817e4Smiod 	  uvalue = byte_get (data, 4);
10443d8817e4Smiod 	  printf (" %lx", uvalue);
10453d8817e4Smiod 	  printf (" %lx", (unsigned long) byte_get (data + 4, 4));
10463d8817e4Smiod 	}
10473d8817e4Smiod       if ((do_loc || do_debug_loc || do_debug_ranges)
10483d8817e4Smiod 	  && num_debug_info_entries == 0)
10493d8817e4Smiod 	{
10503d8817e4Smiod 	  if (sizeof (uvalue) == 8)
10513d8817e4Smiod 	    uvalue = byte_get (data, 8);
10523d8817e4Smiod 	  else
10533d8817e4Smiod 	    error (_("DW_FORM_data8 is unsupported when sizeof (unsigned long) != 8\n"));
10543d8817e4Smiod 	}
10553d8817e4Smiod       data += 8;
10563d8817e4Smiod       break;
10573d8817e4Smiod 
10583d8817e4Smiod     case DW_FORM_string:
10593d8817e4Smiod       if (!do_loc)
10603d8817e4Smiod 	printf (" %s", data);
10613d8817e4Smiod       data += strlen ((char *) data) + 1;
10623d8817e4Smiod       break;
10633d8817e4Smiod 
10643d8817e4Smiod     case DW_FORM_block:
10653d8817e4Smiod       uvalue = read_leb128 (data, & bytes_read, 0);
10663d8817e4Smiod       block_start = data + bytes_read;
10673d8817e4Smiod       if (do_loc)
10683d8817e4Smiod 	data = block_start + uvalue;
10693d8817e4Smiod       else
10703d8817e4Smiod 	data = display_block (block_start, uvalue);
10713d8817e4Smiod       break;
10723d8817e4Smiod 
10733d8817e4Smiod     case DW_FORM_block1:
10743d8817e4Smiod       uvalue = byte_get (data, 1);
10753d8817e4Smiod       block_start = data + 1;
10763d8817e4Smiod       if (do_loc)
10773d8817e4Smiod 	data = block_start + uvalue;
10783d8817e4Smiod       else
10793d8817e4Smiod 	data = display_block (block_start, uvalue);
10803d8817e4Smiod       break;
10813d8817e4Smiod 
10823d8817e4Smiod     case DW_FORM_block2:
10833d8817e4Smiod       uvalue = byte_get (data, 2);
10843d8817e4Smiod       block_start = data + 2;
10853d8817e4Smiod       if (do_loc)
10863d8817e4Smiod 	data = block_start + uvalue;
10873d8817e4Smiod       else
10883d8817e4Smiod 	data = display_block (block_start, uvalue);
10893d8817e4Smiod       break;
10903d8817e4Smiod 
10913d8817e4Smiod     case DW_FORM_block4:
10923d8817e4Smiod       uvalue = byte_get (data, 4);
10933d8817e4Smiod       block_start = data + 4;
10943d8817e4Smiod       if (do_loc)
10953d8817e4Smiod 	data = block_start + uvalue;
10963d8817e4Smiod       else
10973d8817e4Smiod 	data = display_block (block_start, uvalue);
10983d8817e4Smiod       break;
10993d8817e4Smiod 
11003d8817e4Smiod     case DW_FORM_strp:
11013d8817e4Smiod       if (!do_loc)
11023d8817e4Smiod 	printf (_(" (indirect string, offset: 0x%lx): %s"),
11033d8817e4Smiod 		uvalue, fetch_indirect_string (uvalue));
11043d8817e4Smiod       break;
11053d8817e4Smiod 
11063d8817e4Smiod     case DW_FORM_indirect:
11073d8817e4Smiod       /* Handled above.  */
11083d8817e4Smiod       break;
11093d8817e4Smiod 
11103d8817e4Smiod     default:
11113d8817e4Smiod       warn (_("Unrecognized form: %lu\n"), form);
11123d8817e4Smiod       break;
11133d8817e4Smiod     }
11143d8817e4Smiod 
11153d8817e4Smiod   /* For some attributes we can display further information.  */
11163d8817e4Smiod   if ((do_loc || do_debug_loc || do_debug_ranges)
11173d8817e4Smiod       && num_debug_info_entries == 0)
11183d8817e4Smiod     {
11193d8817e4Smiod       switch (attribute)
11203d8817e4Smiod 	{
11213d8817e4Smiod 	case DW_AT_frame_base:
11223d8817e4Smiod 	  have_frame_base = 1;
11233d8817e4Smiod 	case DW_AT_location:
11243d8817e4Smiod 	case DW_AT_data_member_location:
11253d8817e4Smiod 	case DW_AT_vtable_elem_location:
11263d8817e4Smiod 	case DW_AT_allocated:
11273d8817e4Smiod 	case DW_AT_associated:
11283d8817e4Smiod 	case DW_AT_data_location:
11293d8817e4Smiod 	case DW_AT_stride:
11303d8817e4Smiod 	case DW_AT_upper_bound:
11313d8817e4Smiod 	case DW_AT_lower_bound:
11323d8817e4Smiod 	  if (form == DW_FORM_data4 || form == DW_FORM_data8)
11333d8817e4Smiod 	    {
11343d8817e4Smiod 	      /* Process location list.  */
11353d8817e4Smiod 	      unsigned int max = debug_info_p->max_loc_offsets;
11363d8817e4Smiod 	      unsigned int num = debug_info_p->num_loc_offsets;
11373d8817e4Smiod 
11383d8817e4Smiod 	      if (max == 0 || num >= max)
11393d8817e4Smiod 		{
11403d8817e4Smiod 		  max += 1024;
11413d8817e4Smiod 		  debug_info_p->loc_offsets
11423d8817e4Smiod 		    = xcrealloc (debug_info_p->loc_offsets,
11433d8817e4Smiod 				 max, sizeof (*debug_info_p->loc_offsets));
11443d8817e4Smiod 		  debug_info_p->have_frame_base
11453d8817e4Smiod 		    = xcrealloc (debug_info_p->have_frame_base,
11463d8817e4Smiod 				 max, sizeof (*debug_info_p->have_frame_base));
11473d8817e4Smiod 		  debug_info_p->max_loc_offsets = max;
11483d8817e4Smiod 		}
11493d8817e4Smiod 	      debug_info_p->loc_offsets [num] = uvalue;
11503d8817e4Smiod 	      debug_info_p->have_frame_base [num] = have_frame_base;
11513d8817e4Smiod 	      debug_info_p->num_loc_offsets++;
11523d8817e4Smiod 	    }
11533d8817e4Smiod 	  break;
11543d8817e4Smiod 
11553d8817e4Smiod 	case DW_AT_low_pc:
11563d8817e4Smiod 	  if (need_base_address)
11573d8817e4Smiod 	    debug_info_p->base_address = uvalue;
11583d8817e4Smiod 	  break;
11593d8817e4Smiod 
11603d8817e4Smiod 	case DW_AT_ranges:
11613d8817e4Smiod 	  if (form == DW_FORM_data4 || form == DW_FORM_data8)
11623d8817e4Smiod 	    {
11633d8817e4Smiod 	      /* Process range list.  */
11643d8817e4Smiod 	      unsigned int max = debug_info_p->max_range_lists;
11653d8817e4Smiod 	      unsigned int num = debug_info_p->num_range_lists;
11663d8817e4Smiod 
11673d8817e4Smiod 	      if (max == 0 || num >= max)
11683d8817e4Smiod 		{
11693d8817e4Smiod 		  max += 1024;
11703d8817e4Smiod 		  debug_info_p->range_lists
11713d8817e4Smiod 		    = xcrealloc (debug_info_p->range_lists,
11723d8817e4Smiod 				 max, sizeof (*debug_info_p->range_lists));
11733d8817e4Smiod 		  debug_info_p->max_range_lists = max;
11743d8817e4Smiod 		}
11753d8817e4Smiod 	      debug_info_p->range_lists [num] = uvalue;
11763d8817e4Smiod 	      debug_info_p->num_range_lists++;
11773d8817e4Smiod 	    }
11783d8817e4Smiod 	  break;
11793d8817e4Smiod 
11803d8817e4Smiod 	default:
11813d8817e4Smiod 	  break;
11823d8817e4Smiod 	}
11833d8817e4Smiod     }
11843d8817e4Smiod 
11853d8817e4Smiod   if (do_loc)
11863d8817e4Smiod     return data;
11873d8817e4Smiod 
11883d8817e4Smiod   printf ("\t");
11893d8817e4Smiod 
11903d8817e4Smiod   switch (attribute)
11913d8817e4Smiod     {
11923d8817e4Smiod     case DW_AT_inline:
11933d8817e4Smiod       switch (uvalue)
11943d8817e4Smiod 	{
11953d8817e4Smiod 	case DW_INL_not_inlined:
11963d8817e4Smiod 	  printf (_("(not inlined)"));
11973d8817e4Smiod 	  break;
11983d8817e4Smiod 	case DW_INL_inlined:
11993d8817e4Smiod 	  printf (_("(inlined)"));
12003d8817e4Smiod 	  break;
12013d8817e4Smiod 	case DW_INL_declared_not_inlined:
12023d8817e4Smiod 	  printf (_("(declared as inline but ignored)"));
12033d8817e4Smiod 	  break;
12043d8817e4Smiod 	case DW_INL_declared_inlined:
12053d8817e4Smiod 	  printf (_("(declared as inline and inlined)"));
12063d8817e4Smiod 	  break;
12073d8817e4Smiod 	default:
12083d8817e4Smiod 	  printf (_("  (Unknown inline attribute value: %lx)"), uvalue);
12093d8817e4Smiod 	  break;
12103d8817e4Smiod 	}
12113d8817e4Smiod       break;
12123d8817e4Smiod 
12133d8817e4Smiod     case DW_AT_language:
12143d8817e4Smiod       switch (uvalue)
12153d8817e4Smiod 	{
12163d8817e4Smiod 	case DW_LANG_C:			printf ("(non-ANSI C)"); break;
12173d8817e4Smiod 	case DW_LANG_C89:		printf ("(ANSI C)"); break;
12183d8817e4Smiod 	case DW_LANG_C_plus_plus:	printf ("(C++)"); break;
12193d8817e4Smiod 	case DW_LANG_Fortran77:		printf ("(FORTRAN 77)"); break;
12203d8817e4Smiod 	case DW_LANG_Fortran90:		printf ("(Fortran 90)"); break;
12213d8817e4Smiod 	case DW_LANG_Modula2:		printf ("(Modula 2)"); break;
12223d8817e4Smiod 	case DW_LANG_Pascal83:		printf ("(ANSI Pascal)"); break;
12233d8817e4Smiod 	case DW_LANG_Ada83:		printf ("(Ada)"); break;
12243d8817e4Smiod 	case DW_LANG_Cobol74:		printf ("(Cobol 74)"); break;
12253d8817e4Smiod 	case DW_LANG_Cobol85:		printf ("(Cobol 85)"); break;
12263d8817e4Smiod 	  /* DWARF 2.1 values.	*/
12273d8817e4Smiod 	case DW_LANG_C99:		printf ("(ANSI C99)"); break;
12283d8817e4Smiod 	case DW_LANG_Ada95:		printf ("(ADA 95)"); break;
12293d8817e4Smiod 	case DW_LANG_Fortran95:		printf ("(Fortran 95)"); break;
12303d8817e4Smiod 	  /* MIPS extension.  */
12313d8817e4Smiod 	case DW_LANG_Mips_Assembler:	printf ("(MIPS assembler)"); break;
12323d8817e4Smiod 	  /* UPC extension.  */
12333d8817e4Smiod 	case DW_LANG_Upc:		printf ("(Unified Parallel C)"); break;
12343d8817e4Smiod 	default:
12353d8817e4Smiod 	  printf ("(Unknown: %lx)", uvalue);
12363d8817e4Smiod 	  break;
12373d8817e4Smiod 	}
12383d8817e4Smiod       break;
12393d8817e4Smiod 
12403d8817e4Smiod     case DW_AT_encoding:
12413d8817e4Smiod       switch (uvalue)
12423d8817e4Smiod 	{
12433d8817e4Smiod 	case DW_ATE_void:		printf ("(void)"); break;
12443d8817e4Smiod 	case DW_ATE_address:		printf ("(machine address)"); break;
12453d8817e4Smiod 	case DW_ATE_boolean:		printf ("(boolean)"); break;
12463d8817e4Smiod 	case DW_ATE_complex_float:	printf ("(complex float)"); break;
12473d8817e4Smiod 	case DW_ATE_float:		printf ("(float)"); break;
12483d8817e4Smiod 	case DW_ATE_signed:		printf ("(signed)"); break;
12493d8817e4Smiod 	case DW_ATE_signed_char:	printf ("(signed char)"); break;
12503d8817e4Smiod 	case DW_ATE_unsigned:		printf ("(unsigned)"); break;
12513d8817e4Smiod 	case DW_ATE_unsigned_char:	printf ("(unsigned char)"); break;
12523d8817e4Smiod 	  /* DWARF 2.1 value.  */
12533d8817e4Smiod 	case DW_ATE_imaginary_float:	printf ("(imaginary float)"); break;
12543d8817e4Smiod 	case DW_ATE_decimal_float:	printf ("(decimal float)"); break;
12553d8817e4Smiod 	default:
12563d8817e4Smiod 	  if (uvalue >= DW_ATE_lo_user
12573d8817e4Smiod 	      && uvalue <= DW_ATE_hi_user)
12583d8817e4Smiod 	    printf ("(user defined type)");
12593d8817e4Smiod 	  else
12603d8817e4Smiod 	    printf ("(unknown type)");
12613d8817e4Smiod 	  break;
12623d8817e4Smiod 	}
12633d8817e4Smiod       break;
12643d8817e4Smiod 
12653d8817e4Smiod     case DW_AT_accessibility:
12663d8817e4Smiod       switch (uvalue)
12673d8817e4Smiod 	{
12683d8817e4Smiod 	case DW_ACCESS_public:		printf ("(public)"); break;
12693d8817e4Smiod 	case DW_ACCESS_protected:	printf ("(protected)"); break;
12703d8817e4Smiod 	case DW_ACCESS_private:		printf ("(private)"); break;
12713d8817e4Smiod 	default:
12723d8817e4Smiod 	  printf ("(unknown accessibility)");
12733d8817e4Smiod 	  break;
12743d8817e4Smiod 	}
12753d8817e4Smiod       break;
12763d8817e4Smiod 
12773d8817e4Smiod     case DW_AT_visibility:
12783d8817e4Smiod       switch (uvalue)
12793d8817e4Smiod 	{
12803d8817e4Smiod 	case DW_VIS_local:		printf ("(local)"); break;
12813d8817e4Smiod 	case DW_VIS_exported:		printf ("(exported)"); break;
12823d8817e4Smiod 	case DW_VIS_qualified:		printf ("(qualified)"); break;
12833d8817e4Smiod 	default:			printf ("(unknown visibility)"); break;
12843d8817e4Smiod 	}
12853d8817e4Smiod       break;
12863d8817e4Smiod 
12873d8817e4Smiod     case DW_AT_virtuality:
12883d8817e4Smiod       switch (uvalue)
12893d8817e4Smiod 	{
12903d8817e4Smiod 	case DW_VIRTUALITY_none:	printf ("(none)"); break;
12913d8817e4Smiod 	case DW_VIRTUALITY_virtual:	printf ("(virtual)"); break;
12923d8817e4Smiod 	case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
12933d8817e4Smiod 	default:			printf ("(unknown virtuality)"); break;
12943d8817e4Smiod 	}
12953d8817e4Smiod       break;
12963d8817e4Smiod 
12973d8817e4Smiod     case DW_AT_identifier_case:
12983d8817e4Smiod       switch (uvalue)
12993d8817e4Smiod 	{
13003d8817e4Smiod 	case DW_ID_case_sensitive:	printf ("(case_sensitive)"); break;
13013d8817e4Smiod 	case DW_ID_up_case:		printf ("(up_case)"); break;
13023d8817e4Smiod 	case DW_ID_down_case:		printf ("(down_case)"); break;
13033d8817e4Smiod 	case DW_ID_case_insensitive:	printf ("(case_insensitive)"); break;
13043d8817e4Smiod 	default:			printf ("(unknown case)"); break;
13053d8817e4Smiod 	}
13063d8817e4Smiod       break;
13073d8817e4Smiod 
13083d8817e4Smiod     case DW_AT_calling_convention:
13093d8817e4Smiod       switch (uvalue)
13103d8817e4Smiod 	{
13113d8817e4Smiod 	case DW_CC_normal:	printf ("(normal)"); break;
13123d8817e4Smiod 	case DW_CC_program:	printf ("(program)"); break;
13133d8817e4Smiod 	case DW_CC_nocall:	printf ("(nocall)"); break;
13143d8817e4Smiod 	default:
13153d8817e4Smiod 	  if (uvalue >= DW_CC_lo_user
13163d8817e4Smiod 	      && uvalue <= DW_CC_hi_user)
13173d8817e4Smiod 	    printf ("(user defined)");
13183d8817e4Smiod 	  else
13193d8817e4Smiod 	    printf ("(unknown convention)");
13203d8817e4Smiod 	}
13213d8817e4Smiod       break;
13223d8817e4Smiod 
13233d8817e4Smiod     case DW_AT_ordering:
13243d8817e4Smiod       switch (uvalue)
13253d8817e4Smiod 	{
13263d8817e4Smiod 	case -1: printf ("(undefined)"); break;
13273d8817e4Smiod 	case 0:  printf ("(row major)"); break;
13283d8817e4Smiod 	case 1:  printf ("(column major)"); break;
13293d8817e4Smiod 	}
13303d8817e4Smiod       break;
13313d8817e4Smiod 
13323d8817e4Smiod     case DW_AT_frame_base:
13333d8817e4Smiod       have_frame_base = 1;
13343d8817e4Smiod     case DW_AT_location:
13353d8817e4Smiod     case DW_AT_data_member_location:
13363d8817e4Smiod     case DW_AT_vtable_elem_location:
13373d8817e4Smiod     case DW_AT_allocated:
13383d8817e4Smiod     case DW_AT_associated:
13393d8817e4Smiod     case DW_AT_data_location:
13403d8817e4Smiod     case DW_AT_stride:
13413d8817e4Smiod     case DW_AT_upper_bound:
13423d8817e4Smiod     case DW_AT_lower_bound:
13433d8817e4Smiod       if (block_start)
13443d8817e4Smiod 	{
13453d8817e4Smiod 	  int need_frame_base;
13463d8817e4Smiod 
13473d8817e4Smiod 	  printf ("(");
13483d8817e4Smiod 	  need_frame_base = decode_location_expression (block_start,
13493d8817e4Smiod 							pointer_size,
13503d8817e4Smiod 							uvalue,
13513d8817e4Smiod 							cu_offset);
13523d8817e4Smiod 	  printf (")");
13533d8817e4Smiod 	  if (need_frame_base && !have_frame_base)
13543d8817e4Smiod 	    printf (_(" [without DW_AT_frame_base]"));
13553d8817e4Smiod 	}
13563d8817e4Smiod       else if (form == DW_FORM_data4 || form == DW_FORM_data8)
13573d8817e4Smiod 	printf (_("(location list)"));
13583d8817e4Smiod 
13593d8817e4Smiod       break;
13603d8817e4Smiod 
13613d8817e4Smiod     default:
13623d8817e4Smiod       break;
13633d8817e4Smiod     }
13643d8817e4Smiod 
13653d8817e4Smiod   return data;
13663d8817e4Smiod }
13673d8817e4Smiod 
13683d8817e4Smiod static char *
get_AT_name(unsigned long attribute)13693d8817e4Smiod get_AT_name (unsigned long attribute)
13703d8817e4Smiod {
13713d8817e4Smiod   switch (attribute)
13723d8817e4Smiod     {
13733d8817e4Smiod     case DW_AT_sibling:			return "DW_AT_sibling";
13743d8817e4Smiod     case DW_AT_location:		return "DW_AT_location";
13753d8817e4Smiod     case DW_AT_name:			return "DW_AT_name";
13763d8817e4Smiod     case DW_AT_ordering:		return "DW_AT_ordering";
13773d8817e4Smiod     case DW_AT_subscr_data:		return "DW_AT_subscr_data";
13783d8817e4Smiod     case DW_AT_byte_size:		return "DW_AT_byte_size";
13793d8817e4Smiod     case DW_AT_bit_offset:		return "DW_AT_bit_offset";
13803d8817e4Smiod     case DW_AT_bit_size:		return "DW_AT_bit_size";
13813d8817e4Smiod     case DW_AT_element_list:		return "DW_AT_element_list";
13823d8817e4Smiod     case DW_AT_stmt_list:		return "DW_AT_stmt_list";
13833d8817e4Smiod     case DW_AT_low_pc:			return "DW_AT_low_pc";
13843d8817e4Smiod     case DW_AT_high_pc:			return "DW_AT_high_pc";
13853d8817e4Smiod     case DW_AT_language:		return "DW_AT_language";
13863d8817e4Smiod     case DW_AT_member:			return "DW_AT_member";
13873d8817e4Smiod     case DW_AT_discr:			return "DW_AT_discr";
13883d8817e4Smiod     case DW_AT_discr_value:		return "DW_AT_discr_value";
13893d8817e4Smiod     case DW_AT_visibility:		return "DW_AT_visibility";
13903d8817e4Smiod     case DW_AT_import:			return "DW_AT_import";
13913d8817e4Smiod     case DW_AT_string_length:		return "DW_AT_string_length";
13923d8817e4Smiod     case DW_AT_common_reference:	return "DW_AT_common_reference";
13933d8817e4Smiod     case DW_AT_comp_dir:		return "DW_AT_comp_dir";
13943d8817e4Smiod     case DW_AT_const_value:		return "DW_AT_const_value";
13953d8817e4Smiod     case DW_AT_containing_type:		return "DW_AT_containing_type";
13963d8817e4Smiod     case DW_AT_default_value:		return "DW_AT_default_value";
13973d8817e4Smiod     case DW_AT_inline:			return "DW_AT_inline";
13983d8817e4Smiod     case DW_AT_is_optional:		return "DW_AT_is_optional";
13993d8817e4Smiod     case DW_AT_lower_bound:		return "DW_AT_lower_bound";
14003d8817e4Smiod     case DW_AT_producer:		return "DW_AT_producer";
14013d8817e4Smiod     case DW_AT_prototyped:		return "DW_AT_prototyped";
14023d8817e4Smiod     case DW_AT_return_addr:		return "DW_AT_return_addr";
14033d8817e4Smiod     case DW_AT_start_scope:		return "DW_AT_start_scope";
14043d8817e4Smiod     case DW_AT_stride_size:		return "DW_AT_stride_size";
14053d8817e4Smiod     case DW_AT_upper_bound:		return "DW_AT_upper_bound";
14063d8817e4Smiod     case DW_AT_abstract_origin:		return "DW_AT_abstract_origin";
14073d8817e4Smiod     case DW_AT_accessibility:		return "DW_AT_accessibility";
14083d8817e4Smiod     case DW_AT_address_class:		return "DW_AT_address_class";
14093d8817e4Smiod     case DW_AT_artificial:		return "DW_AT_artificial";
14103d8817e4Smiod     case DW_AT_base_types:		return "DW_AT_base_types";
14113d8817e4Smiod     case DW_AT_calling_convention:	return "DW_AT_calling_convention";
14123d8817e4Smiod     case DW_AT_count:			return "DW_AT_count";
14133d8817e4Smiod     case DW_AT_data_member_location:	return "DW_AT_data_member_location";
14143d8817e4Smiod     case DW_AT_decl_column:		return "DW_AT_decl_column";
14153d8817e4Smiod     case DW_AT_decl_file:		return "DW_AT_decl_file";
14163d8817e4Smiod     case DW_AT_decl_line:		return "DW_AT_decl_line";
14173d8817e4Smiod     case DW_AT_declaration:		return "DW_AT_declaration";
14183d8817e4Smiod     case DW_AT_discr_list:		return "DW_AT_discr_list";
14193d8817e4Smiod     case DW_AT_encoding:		return "DW_AT_encoding";
14203d8817e4Smiod     case DW_AT_external:		return "DW_AT_external";
14213d8817e4Smiod     case DW_AT_frame_base:		return "DW_AT_frame_base";
14223d8817e4Smiod     case DW_AT_friend:			return "DW_AT_friend";
14233d8817e4Smiod     case DW_AT_identifier_case:		return "DW_AT_identifier_case";
14243d8817e4Smiod     case DW_AT_macro_info:		return "DW_AT_macro_info";
14253d8817e4Smiod     case DW_AT_namelist_items:		return "DW_AT_namelist_items";
14263d8817e4Smiod     case DW_AT_priority:		return "DW_AT_priority";
14273d8817e4Smiod     case DW_AT_segment:			return "DW_AT_segment";
14283d8817e4Smiod     case DW_AT_specification:		return "DW_AT_specification";
14293d8817e4Smiod     case DW_AT_static_link:		return "DW_AT_static_link";
14303d8817e4Smiod     case DW_AT_type:			return "DW_AT_type";
14313d8817e4Smiod     case DW_AT_use_location:		return "DW_AT_use_location";
14323d8817e4Smiod     case DW_AT_variable_parameter:	return "DW_AT_variable_parameter";
14333d8817e4Smiod     case DW_AT_virtuality:		return "DW_AT_virtuality";
14343d8817e4Smiod     case DW_AT_vtable_elem_location:	return "DW_AT_vtable_elem_location";
14353d8817e4Smiod       /* DWARF 2.1 values.  */
14363d8817e4Smiod     case DW_AT_allocated:		return "DW_AT_allocated";
14373d8817e4Smiod     case DW_AT_associated:		return "DW_AT_associated";
14383d8817e4Smiod     case DW_AT_data_location:		return "DW_AT_data_location";
14393d8817e4Smiod     case DW_AT_stride:			return "DW_AT_stride";
14403d8817e4Smiod     case DW_AT_entry_pc:		return "DW_AT_entry_pc";
14413d8817e4Smiod     case DW_AT_use_UTF8:		return "DW_AT_use_UTF8";
14423d8817e4Smiod     case DW_AT_extension:		return "DW_AT_extension";
14433d8817e4Smiod     case DW_AT_ranges:			return "DW_AT_ranges";
14443d8817e4Smiod     case DW_AT_trampoline:		return "DW_AT_trampoline";
14453d8817e4Smiod     case DW_AT_call_column:		return "DW_AT_call_column";
14463d8817e4Smiod     case DW_AT_call_file:		return "DW_AT_call_file";
14473d8817e4Smiod     case DW_AT_call_line:		return "DW_AT_call_line";
14483d8817e4Smiod       /* SGI/MIPS extensions.  */
14493d8817e4Smiod     case DW_AT_MIPS_fde:		return "DW_AT_MIPS_fde";
14503d8817e4Smiod     case DW_AT_MIPS_loop_begin:		return "DW_AT_MIPS_loop_begin";
14513d8817e4Smiod     case DW_AT_MIPS_tail_loop_begin:	return "DW_AT_MIPS_tail_loop_begin";
14523d8817e4Smiod     case DW_AT_MIPS_epilog_begin:	return "DW_AT_MIPS_epilog_begin";
14533d8817e4Smiod     case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
14543d8817e4Smiod     case DW_AT_MIPS_software_pipeline_depth:
14553d8817e4Smiod       return "DW_AT_MIPS_software_pipeline_depth";
14563d8817e4Smiod     case DW_AT_MIPS_linkage_name:	return "DW_AT_MIPS_linkage_name";
14573d8817e4Smiod     case DW_AT_MIPS_stride:		return "DW_AT_MIPS_stride";
14583d8817e4Smiod     case DW_AT_MIPS_abstract_name:	return "DW_AT_MIPS_abstract_name";
14593d8817e4Smiod     case DW_AT_MIPS_clone_origin:	return "DW_AT_MIPS_clone_origin";
14603d8817e4Smiod     case DW_AT_MIPS_has_inlines:	return "DW_AT_MIPS_has_inlines";
14613d8817e4Smiod       /* GNU extensions.  */
14623d8817e4Smiod     case DW_AT_sf_names:		return "DW_AT_sf_names";
14633d8817e4Smiod     case DW_AT_src_info:		return "DW_AT_src_info";
14643d8817e4Smiod     case DW_AT_mac_info:		return "DW_AT_mac_info";
14653d8817e4Smiod     case DW_AT_src_coords:		return "DW_AT_src_coords";
14663d8817e4Smiod     case DW_AT_body_begin:		return "DW_AT_body_begin";
14673d8817e4Smiod     case DW_AT_body_end:		return "DW_AT_body_end";
14683d8817e4Smiod     case DW_AT_GNU_vector:		return "DW_AT_GNU_vector";
14693d8817e4Smiod       /* UPC extension.  */
14703d8817e4Smiod     case DW_AT_upc_threads_scaled:	return "DW_AT_upc_threads_scaled";
14713d8817e4Smiod     default:
14723d8817e4Smiod       {
14733d8817e4Smiod 	static char buffer[100];
14743d8817e4Smiod 
14753d8817e4Smiod 	snprintf (buffer, sizeof (buffer), _("Unknown AT value: %lx"),
14763d8817e4Smiod 		  attribute);
14773d8817e4Smiod 	return buffer;
14783d8817e4Smiod       }
14793d8817e4Smiod     }
14803d8817e4Smiod }
14813d8817e4Smiod 
14823d8817e4Smiod static unsigned char *
read_and_display_attr(unsigned long attribute,unsigned long form,unsigned char * data,unsigned long cu_offset,unsigned long pointer_size,unsigned long offset_size,int dwarf_version,debug_info * debug_info_p,int do_loc)14833d8817e4Smiod read_and_display_attr (unsigned long attribute,
14843d8817e4Smiod 		       unsigned long form,
14853d8817e4Smiod 		       unsigned char *data,
14863d8817e4Smiod 		       unsigned long cu_offset,
14873d8817e4Smiod 		       unsigned long pointer_size,
14883d8817e4Smiod 		       unsigned long offset_size,
14893d8817e4Smiod 		       int dwarf_version,
14903d8817e4Smiod 		       debug_info *debug_info_p,
14913d8817e4Smiod 		       int do_loc)
14923d8817e4Smiod {
14933d8817e4Smiod   if (!do_loc)
14943d8817e4Smiod     printf ("     %-18s:", get_AT_name (attribute));
14953d8817e4Smiod   data = read_and_display_attr_value (attribute, form, data, cu_offset,
14963d8817e4Smiod 				      pointer_size, offset_size,
14973d8817e4Smiod 				      dwarf_version, debug_info_p,
14983d8817e4Smiod 				      do_loc);
14993d8817e4Smiod   if (!do_loc)
15003d8817e4Smiod     printf ("\n");
15013d8817e4Smiod   return data;
15023d8817e4Smiod }
15033d8817e4Smiod 
15043d8817e4Smiod 
15053d8817e4Smiod /* Process the contents of a .debug_info section.  If do_loc is non-zero
15063d8817e4Smiod    then we are scanning for location lists and we do not want to display
15073d8817e4Smiod    anything to the user.  */
15083d8817e4Smiod 
15093d8817e4Smiod static int
process_debug_info(struct dwarf_section * section,void * file,int do_loc)15103d8817e4Smiod process_debug_info (struct dwarf_section *section, void *file,
15113d8817e4Smiod 		    int do_loc)
15123d8817e4Smiod {
15133d8817e4Smiod   unsigned char *start = section->start;
15143d8817e4Smiod   unsigned char *end = start + section->size;
15153d8817e4Smiod   unsigned char *section_begin;
15163d8817e4Smiod   unsigned int unit;
15173d8817e4Smiod   unsigned int num_units = 0;
15183d8817e4Smiod 
15193d8817e4Smiod   if ((do_loc || do_debug_loc || do_debug_ranges)
15203d8817e4Smiod       && num_debug_info_entries == 0)
15213d8817e4Smiod     {
15223d8817e4Smiod       unsigned long length;
15233d8817e4Smiod 
15243d8817e4Smiod       /* First scan the section to get the number of comp units.  */
15253d8817e4Smiod       for (section_begin = start, num_units = 0; section_begin < end;
15263d8817e4Smiod 	   num_units ++)
15273d8817e4Smiod 	{
15283d8817e4Smiod 	  /* Read the first 4 bytes.  For a 32-bit DWARF section, this
15293d8817e4Smiod 	     will be the length.  For a 64-bit DWARF section, it'll be
15303d8817e4Smiod 	     the escape code 0xffffffff followed by an 8 byte length.  */
15313d8817e4Smiod 	  length = byte_get (section_begin, 4);
15323d8817e4Smiod 
15333d8817e4Smiod 	  if (length == 0xffffffff)
15343d8817e4Smiod 	    {
15353d8817e4Smiod 	      length = byte_get (section_begin + 4, 8);
15363d8817e4Smiod 	      section_begin += length + 12;
15373d8817e4Smiod 	    }
15383d8817e4Smiod 	  else
15393d8817e4Smiod 	    section_begin += length + 4;
15403d8817e4Smiod 	}
15413d8817e4Smiod 
15423d8817e4Smiod       if (num_units == 0)
15433d8817e4Smiod 	{
15443d8817e4Smiod 	  error (_("No comp units in %s section ?"), section->name);
15453d8817e4Smiod 	  return 0;
15463d8817e4Smiod 	}
15473d8817e4Smiod 
15483d8817e4Smiod       /* Then allocate an array to hold the information.  */
15493d8817e4Smiod       debug_information = cmalloc (num_units,
15503d8817e4Smiod 				   sizeof (* debug_information));
15513d8817e4Smiod       if (debug_information == NULL)
15523d8817e4Smiod 	{
15533d8817e4Smiod 	  error (_("Not enough memory for a debug info array of %u entries"),
15543d8817e4Smiod 		 num_units);
15553d8817e4Smiod 	  return 0;
15563d8817e4Smiod 	}
15573d8817e4Smiod     }
15583d8817e4Smiod 
15593d8817e4Smiod   if (!do_loc)
15603d8817e4Smiod     {
15613d8817e4Smiod       printf (_("The section %s contains:\n\n"), section->name);
15623d8817e4Smiod 
15633d8817e4Smiod       load_debug_section (str, file);
15643d8817e4Smiod     }
15653d8817e4Smiod 
15663d8817e4Smiod   load_debug_section (abbrev, file);
15673d8817e4Smiod   if (debug_displays [abbrev].section.start == NULL)
15683d8817e4Smiod     {
15693d8817e4Smiod       warn (_("Unable to locate %s section!\n"),
15703d8817e4Smiod 	    debug_displays [abbrev].section.name);
15713d8817e4Smiod       return 0;
15723d8817e4Smiod     }
15733d8817e4Smiod 
15743d8817e4Smiod   for (section_begin = start, unit = 0; start < end; unit++)
15753d8817e4Smiod     {
15763d8817e4Smiod       DWARF2_Internal_CompUnit compunit;
15773d8817e4Smiod       unsigned char *hdrptr;
15783d8817e4Smiod       unsigned char *cu_abbrev_offset_ptr;
15793d8817e4Smiod       unsigned char *tags;
15803d8817e4Smiod       int level;
15813d8817e4Smiod       unsigned long cu_offset;
15823d8817e4Smiod       int offset_size;
15833d8817e4Smiod       int initial_length_size;
15843d8817e4Smiod 
15853d8817e4Smiod       hdrptr = start;
15863d8817e4Smiod 
15873d8817e4Smiod       compunit.cu_length = byte_get (hdrptr, 4);
15883d8817e4Smiod       hdrptr += 4;
15893d8817e4Smiod 
15903d8817e4Smiod       if (compunit.cu_length == 0xffffffff)
15913d8817e4Smiod 	{
15923d8817e4Smiod 	  compunit.cu_length = byte_get (hdrptr, 8);
15933d8817e4Smiod 	  hdrptr += 8;
15943d8817e4Smiod 	  offset_size = 8;
15953d8817e4Smiod 	  initial_length_size = 12;
15963d8817e4Smiod 	}
15973d8817e4Smiod       else
15983d8817e4Smiod 	{
15993d8817e4Smiod 	  offset_size = 4;
16003d8817e4Smiod 	  initial_length_size = 4;
16013d8817e4Smiod 	}
16023d8817e4Smiod 
16033d8817e4Smiod       compunit.cu_version = byte_get (hdrptr, 2);
16043d8817e4Smiod       hdrptr += 2;
16053d8817e4Smiod 
16063d8817e4Smiod       cu_offset = start - section_begin;
16073d8817e4Smiod       start += compunit.cu_length + initial_length_size;
16083d8817e4Smiod 
16093d8817e4Smiod       cu_abbrev_offset_ptr = hdrptr;
16103d8817e4Smiod       compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
16113d8817e4Smiod       hdrptr += offset_size;
16123d8817e4Smiod 
16133d8817e4Smiod       compunit.cu_pointer_size = byte_get (hdrptr, 1);
16143d8817e4Smiod       hdrptr += 1;
16153d8817e4Smiod       if ((do_loc || do_debug_loc || do_debug_ranges)
16163d8817e4Smiod 	  && num_debug_info_entries == 0)
16173d8817e4Smiod 	{
16183d8817e4Smiod 	  debug_information [unit].cu_offset = cu_offset;
16193d8817e4Smiod 	  debug_information [unit].pointer_size
16203d8817e4Smiod 	    = compunit.cu_pointer_size;
16213d8817e4Smiod 	  debug_information [unit].base_address = 0;
16223d8817e4Smiod 	  debug_information [unit].loc_offsets = NULL;
16233d8817e4Smiod 	  debug_information [unit].have_frame_base = NULL;
16243d8817e4Smiod 	  debug_information [unit].max_loc_offsets = 0;
16253d8817e4Smiod 	  debug_information [unit].num_loc_offsets = 0;
16263d8817e4Smiod 	  debug_information [unit].range_lists = NULL;
16273d8817e4Smiod 	  debug_information [unit].max_range_lists= 0;
16283d8817e4Smiod 	  debug_information [unit].num_range_lists = 0;
16293d8817e4Smiod 	}
16303d8817e4Smiod 
16313d8817e4Smiod       tags = hdrptr;
16323d8817e4Smiod 
16333d8817e4Smiod       if (!do_loc)
16343d8817e4Smiod 	{
16353d8817e4Smiod 	  printf (_("  Compilation Unit @ offset 0x%lx:\n"), cu_offset);
16363d8817e4Smiod 	  printf (_("   Length:        %ld\n"), compunit.cu_length);
16373d8817e4Smiod 	  printf (_("   Version:       %d\n"), compunit.cu_version);
16383d8817e4Smiod 	  printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
16393d8817e4Smiod 	  printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
16403d8817e4Smiod 	}
16413d8817e4Smiod 
16423d8817e4Smiod       if (compunit.cu_version != 2 && compunit.cu_version != 3)
16433d8817e4Smiod 	{
16443d8817e4Smiod 	  warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
16453d8817e4Smiod 	  continue;
16463d8817e4Smiod 	}
16473d8817e4Smiod 
16483d8817e4Smiod       free_abbrevs ();
16493d8817e4Smiod 
16503d8817e4Smiod       /* Process the abbrevs used by this compilation unit. DWARF
16513d8817e4Smiod 	 sections under Mach-O have non-zero addresses.  */
16523d8817e4Smiod       process_abbrev_section
16533d8817e4Smiod 	((unsigned char *) debug_displays [abbrev].section.start
16543d8817e4Smiod 	 + compunit.cu_abbrev_offset - debug_displays [abbrev].section.address,
16553d8817e4Smiod 	 (unsigned char *) debug_displays [abbrev].section.start
16563d8817e4Smiod 	 + debug_displays [abbrev].section.size);
16573d8817e4Smiod 
16583d8817e4Smiod       level = 0;
16593d8817e4Smiod       while (tags < start)
16603d8817e4Smiod 	{
16613d8817e4Smiod 	  unsigned int bytes_read;
16623d8817e4Smiod 	  unsigned long abbrev_number;
16633d8817e4Smiod 	  abbrev_entry *entry;
16643d8817e4Smiod 	  abbrev_attr *attr;
16653d8817e4Smiod 
16663d8817e4Smiod 	  abbrev_number = read_leb128 (tags, & bytes_read, 0);
16673d8817e4Smiod 	  tags += bytes_read;
16683d8817e4Smiod 
16693d8817e4Smiod 	  /* A null DIE marks the end of a list of children.  */
16703d8817e4Smiod 	  if (abbrev_number == 0)
16713d8817e4Smiod 	    {
16723d8817e4Smiod 	      --level;
16733d8817e4Smiod 	      continue;
16743d8817e4Smiod 	    }
16753d8817e4Smiod 
16763d8817e4Smiod 	  /* Scan through the abbreviation list until we reach the
16773d8817e4Smiod 	     correct entry.  */
16783d8817e4Smiod 	  for (entry = first_abbrev;
16793d8817e4Smiod 	       entry && entry->entry != abbrev_number;
16803d8817e4Smiod 	       entry = entry->next)
16813d8817e4Smiod 	    continue;
16823d8817e4Smiod 
16833d8817e4Smiod 	  if (entry == NULL)
16843d8817e4Smiod 	    {
16853d8817e4Smiod 	      warn (_("Unable to locate entry %lu in the abbreviation table\n"),
16863d8817e4Smiod 		    abbrev_number);
16873d8817e4Smiod 	      return 0;
16883d8817e4Smiod 	    }
16893d8817e4Smiod 
16903d8817e4Smiod 	  if (!do_loc)
16913d8817e4Smiod 	    printf (_(" <%d><%lx>: Abbrev Number: %lu (%s)\n"),
16923d8817e4Smiod 		    level,
16933d8817e4Smiod 		    (unsigned long) (tags - section_begin
16943d8817e4Smiod 				     - bytes_read),
16953d8817e4Smiod 		    abbrev_number,
16963d8817e4Smiod 		    get_TAG_name (entry->tag));
16973d8817e4Smiod 
16983d8817e4Smiod 	  switch (entry->tag)
16993d8817e4Smiod 	    {
17003d8817e4Smiod 	    default:
17013d8817e4Smiod 	      need_base_address = 0;
17023d8817e4Smiod 	      break;
17033d8817e4Smiod 	    case DW_TAG_compile_unit:
17043d8817e4Smiod 	      need_base_address = 1;
17053d8817e4Smiod 	      break;
17063d8817e4Smiod 	    case DW_TAG_entry_point:
17073d8817e4Smiod 	    case DW_TAG_inlined_subroutine:
17083d8817e4Smiod 	    case DW_TAG_subprogram:
17093d8817e4Smiod 	      need_base_address = 0;
17103d8817e4Smiod 	      /* Assuming that there is no DW_AT_frame_base.  */
17113d8817e4Smiod 	      have_frame_base = 0;
17123d8817e4Smiod 	      break;
17133d8817e4Smiod 	    }
17143d8817e4Smiod 
17153d8817e4Smiod 	  for (attr = entry->first_attr; attr; attr = attr->next)
17163d8817e4Smiod 	    tags = read_and_display_attr (attr->attribute,
17173d8817e4Smiod 					  attr->form,
17183d8817e4Smiod 					  tags, cu_offset,
17193d8817e4Smiod 					  compunit.cu_pointer_size,
17203d8817e4Smiod 					  offset_size,
17213d8817e4Smiod 					  compunit.cu_version,
17223d8817e4Smiod 					  &debug_information [unit],
17233d8817e4Smiod 					  do_loc);
17243d8817e4Smiod 
17253d8817e4Smiod  	  if (entry->children)
17263d8817e4Smiod  	    ++level;
17273d8817e4Smiod  	}
17283d8817e4Smiod     }
17293d8817e4Smiod 
17303d8817e4Smiod   /* Set num_debug_info_entries here so that it can be used to check if
17313d8817e4Smiod      we need to process .debug_loc and .debug_ranges sections.  */
17323d8817e4Smiod   if ((do_loc || do_debug_loc || do_debug_ranges)
17333d8817e4Smiod       && num_debug_info_entries == 0)
17343d8817e4Smiod     num_debug_info_entries = num_units;
17353d8817e4Smiod 
17363d8817e4Smiod   if (!do_loc)
17373d8817e4Smiod     {
17383d8817e4Smiod       printf ("\n");
17393d8817e4Smiod     }
17403d8817e4Smiod 
17413d8817e4Smiod   return 1;
17423d8817e4Smiod }
17433d8817e4Smiod 
17443d8817e4Smiod /* Locate and scan the .debug_info section in the file and record the pointer
17453d8817e4Smiod    sizes and offsets for the compilation units in it.  Usually an executable
17463d8817e4Smiod    will have just one pointer size, but this is not guaranteed, and so we try
17473d8817e4Smiod    not to make any assumptions.  Returns zero upon failure, or the number of
17483d8817e4Smiod    compilation units upon success.  */
17493d8817e4Smiod 
17503d8817e4Smiod static unsigned int
load_debug_info(void * file)17513d8817e4Smiod load_debug_info (void * file)
17523d8817e4Smiod {
17533d8817e4Smiod   /* Reset the last pointer size so that we can issue correct error
17543d8817e4Smiod      messages if we are displaying the contents of more than one section.  */
17553d8817e4Smiod   last_pointer_size = 0;
17563d8817e4Smiod   warned_about_missing_comp_units = FALSE;
17573d8817e4Smiod 
17583d8817e4Smiod   /* If we already have the information there is nothing else to do.  */
17593d8817e4Smiod   if (num_debug_info_entries > 0)
17603d8817e4Smiod     return num_debug_info_entries;
17613d8817e4Smiod 
17623d8817e4Smiod   if (load_debug_section (info, file)
17633d8817e4Smiod       && process_debug_info (&debug_displays [info].section, file, 1))
17643d8817e4Smiod     return num_debug_info_entries;
17653d8817e4Smiod   else
17663d8817e4Smiod     return 0;
17673d8817e4Smiod }
17683d8817e4Smiod 
17693d8817e4Smiod static int
display_debug_lines(struct dwarf_section * section,void * file)17703d8817e4Smiod display_debug_lines (struct dwarf_section *section, void *file)
17713d8817e4Smiod {
17723d8817e4Smiod   unsigned char *start = section->start;
17733d8817e4Smiod   unsigned char *data = start;
17743d8817e4Smiod   unsigned char *end = start + section->size;
17753d8817e4Smiod 
17763d8817e4Smiod   printf (_("\nDump of debug contents of section %s:\n\n"),
17773d8817e4Smiod 	  section->name);
17783d8817e4Smiod 
17793d8817e4Smiod   load_debug_info (file);
17803d8817e4Smiod 
17813d8817e4Smiod   while (data < end)
17823d8817e4Smiod     {
17833d8817e4Smiod       DWARF2_Internal_LineInfo info;
17843d8817e4Smiod       unsigned char *standard_opcodes;
17853d8817e4Smiod       unsigned char *end_of_sequence;
17863d8817e4Smiod       unsigned char *hdrptr;
17873d8817e4Smiod       int initial_length_size;
17883d8817e4Smiod       int offset_size;
17893d8817e4Smiod       int i;
17903d8817e4Smiod 
17913d8817e4Smiod       hdrptr = data;
17923d8817e4Smiod 
17933d8817e4Smiod       /* Check the length of the block.  */
17943d8817e4Smiod       info.li_length = byte_get (hdrptr, 4);
17953d8817e4Smiod       hdrptr += 4;
17963d8817e4Smiod 
17973d8817e4Smiod       if (info.li_length == 0xffffffff)
17983d8817e4Smiod 	{
17993d8817e4Smiod 	  /* This section is 64-bit DWARF 3.  */
18003d8817e4Smiod 	  info.li_length = byte_get (hdrptr, 8);
18013d8817e4Smiod 	  hdrptr += 8;
18023d8817e4Smiod 	  offset_size = 8;
18033d8817e4Smiod 	  initial_length_size = 12;
18043d8817e4Smiod 	}
18053d8817e4Smiod       else
18063d8817e4Smiod 	{
18073d8817e4Smiod 	  offset_size = 4;
18083d8817e4Smiod 	  initial_length_size = 4;
18093d8817e4Smiod 	}
18103d8817e4Smiod 
18113d8817e4Smiod       if (info.li_length + initial_length_size > section->size)
18123d8817e4Smiod 	{
18133d8817e4Smiod 	  warn
18143d8817e4Smiod 	    (_("The line info appears to be corrupt - the section is too small\n"));
18153d8817e4Smiod 	  return 0;
18163d8817e4Smiod 	}
18173d8817e4Smiod 
18183d8817e4Smiod       /* Check its version number.  */
18193d8817e4Smiod       info.li_version = byte_get (hdrptr, 2);
18203d8817e4Smiod       hdrptr += 2;
18213d8817e4Smiod       if (info.li_version != 2 && info.li_version != 3)
18223d8817e4Smiod 	{
18233d8817e4Smiod 	  warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
18243d8817e4Smiod 	  return 0;
18253d8817e4Smiod 	}
18263d8817e4Smiod 
18273d8817e4Smiod       info.li_prologue_length = byte_get (hdrptr, offset_size);
18283d8817e4Smiod       hdrptr += offset_size;
18293d8817e4Smiod       info.li_min_insn_length = byte_get (hdrptr, 1);
18303d8817e4Smiod       hdrptr++;
18313d8817e4Smiod       info.li_default_is_stmt = byte_get (hdrptr, 1);
18323d8817e4Smiod       hdrptr++;
18333d8817e4Smiod       info.li_line_base = byte_get (hdrptr, 1);
18343d8817e4Smiod       hdrptr++;
18353d8817e4Smiod       info.li_line_range = byte_get (hdrptr, 1);
18363d8817e4Smiod       hdrptr++;
18373d8817e4Smiod       info.li_opcode_base = byte_get (hdrptr, 1);
18383d8817e4Smiod       hdrptr++;
18393d8817e4Smiod 
18403d8817e4Smiod       /* Sign extend the line base field.  */
18413d8817e4Smiod       info.li_line_base <<= 24;
18423d8817e4Smiod       info.li_line_base >>= 24;
18433d8817e4Smiod 
18443d8817e4Smiod       printf (_("  Length:                      %ld\n"), info.li_length);
18453d8817e4Smiod       printf (_("  DWARF Version:               %d\n"), info.li_version);
18463d8817e4Smiod       printf (_("  Prologue Length:             %d\n"), info.li_prologue_length);
18473d8817e4Smiod       printf (_("  Minimum Instruction Length:  %d\n"), info.li_min_insn_length);
18483d8817e4Smiod       printf (_("  Initial value of 'is_stmt':  %d\n"), info.li_default_is_stmt);
18493d8817e4Smiod       printf (_("  Line Base:                   %d\n"), info.li_line_base);
18503d8817e4Smiod       printf (_("  Line Range:                  %d\n"), info.li_line_range);
18513d8817e4Smiod       printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
18523d8817e4Smiod 
18533d8817e4Smiod       end_of_sequence = data + info.li_length + initial_length_size;
18543d8817e4Smiod 
18553d8817e4Smiod       reset_state_machine (info.li_default_is_stmt);
18563d8817e4Smiod 
18573d8817e4Smiod       /* Display the contents of the Opcodes table.  */
18583d8817e4Smiod       standard_opcodes = hdrptr;
18593d8817e4Smiod 
18603d8817e4Smiod       printf (_("\n Opcodes:\n"));
18613d8817e4Smiod 
18623d8817e4Smiod       for (i = 1; i < info.li_opcode_base; i++)
18633d8817e4Smiod 	printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
18643d8817e4Smiod 
18653d8817e4Smiod       /* Display the contents of the Directory table.  */
18663d8817e4Smiod       data = standard_opcodes + info.li_opcode_base - 1;
18673d8817e4Smiod 
18683d8817e4Smiod       if (*data == 0)
18693d8817e4Smiod 	printf (_("\n The Directory Table is empty.\n"));
18703d8817e4Smiod       else
18713d8817e4Smiod 	{
18723d8817e4Smiod 	  printf (_("\n The Directory Table:\n"));
18733d8817e4Smiod 
18743d8817e4Smiod 	  while (*data != 0)
18753d8817e4Smiod 	    {
18763d8817e4Smiod 	      printf (_("  %s\n"), data);
18773d8817e4Smiod 
18783d8817e4Smiod 	      data += strlen ((char *) data) + 1;
18793d8817e4Smiod 	    }
18803d8817e4Smiod 	}
18813d8817e4Smiod 
18823d8817e4Smiod       /* Skip the NUL at the end of the table.  */
18833d8817e4Smiod       data++;
18843d8817e4Smiod 
18853d8817e4Smiod       /* Display the contents of the File Name table.  */
18863d8817e4Smiod       if (*data == 0)
18873d8817e4Smiod 	printf (_("\n The File Name Table is empty.\n"));
18883d8817e4Smiod       else
18893d8817e4Smiod 	{
18903d8817e4Smiod 	  printf (_("\n The File Name Table:\n"));
18913d8817e4Smiod 	  printf (_("  Entry\tDir\tTime\tSize\tName\n"));
18923d8817e4Smiod 
18933d8817e4Smiod 	  while (*data != 0)
18943d8817e4Smiod 	    {
18953d8817e4Smiod 	      unsigned char *name;
18963d8817e4Smiod 	      unsigned int bytes_read;
18973d8817e4Smiod 
18983d8817e4Smiod 	      printf (_("  %d\t"), ++state_machine_regs.last_file_entry);
18993d8817e4Smiod 	      name = data;
19003d8817e4Smiod 
19013d8817e4Smiod 	      data += strlen ((char *) data) + 1;
19023d8817e4Smiod 
19033d8817e4Smiod 	      printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
19043d8817e4Smiod 	      data += bytes_read;
19053d8817e4Smiod 	      printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
19063d8817e4Smiod 	      data += bytes_read;
19073d8817e4Smiod 	      printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
19083d8817e4Smiod 	      data += bytes_read;
19093d8817e4Smiod 	      printf (_("%s\n"), name);
19103d8817e4Smiod 	    }
19113d8817e4Smiod 	}
19123d8817e4Smiod 
19133d8817e4Smiod       /* Skip the NUL at the end of the table.  */
19143d8817e4Smiod       data++;
19153d8817e4Smiod 
19163d8817e4Smiod       /* Now display the statements.  */
19173d8817e4Smiod       printf (_("\n Line Number Statements:\n"));
19183d8817e4Smiod 
19193d8817e4Smiod       while (data < end_of_sequence)
19203d8817e4Smiod 	{
19213d8817e4Smiod 	  unsigned char op_code;
19223d8817e4Smiod 	  int adv;
19233d8817e4Smiod 	  unsigned long int uladv;
19243d8817e4Smiod 	  unsigned int bytes_read;
19253d8817e4Smiod 
19263d8817e4Smiod 	  op_code = *data++;
19273d8817e4Smiod 
19283d8817e4Smiod 	  if (op_code >= info.li_opcode_base)
19293d8817e4Smiod 	    {
19303d8817e4Smiod 	      op_code -= info.li_opcode_base;
19313d8817e4Smiod 	      uladv = (op_code / info.li_line_range) * info.li_min_insn_length;
19323d8817e4Smiod 	      state_machine_regs.address += uladv;
19333d8817e4Smiod 	      printf (_("  Special opcode %d: advance Address by %lu to 0x%lx"),
19343d8817e4Smiod 		      op_code, uladv, state_machine_regs.address);
19353d8817e4Smiod 	      adv = (op_code % info.li_line_range) + info.li_line_base;
19363d8817e4Smiod 	      state_machine_regs.line += adv;
19373d8817e4Smiod 	      printf (_(" and Line by %d to %d\n"),
19383d8817e4Smiod 		      adv, state_machine_regs.line);
19393d8817e4Smiod 	    }
19403d8817e4Smiod 	  else switch (op_code)
19413d8817e4Smiod 	    {
19423d8817e4Smiod 	    case DW_LNS_extended_op:
19433d8817e4Smiod 	      data += process_extended_line_op (data, info.li_default_is_stmt);
19443d8817e4Smiod 	      break;
19453d8817e4Smiod 
19463d8817e4Smiod 	    case DW_LNS_copy:
19473d8817e4Smiod 	      printf (_("  Copy\n"));
19483d8817e4Smiod 	      break;
19493d8817e4Smiod 
19503d8817e4Smiod 	    case DW_LNS_advance_pc:
19513d8817e4Smiod 	      uladv = read_leb128 (data, & bytes_read, 0);
19523d8817e4Smiod 	      uladv *= info.li_min_insn_length;
19533d8817e4Smiod 	      data += bytes_read;
19543d8817e4Smiod 	      state_machine_regs.address += uladv;
19553d8817e4Smiod 	      printf (_("  Advance PC by %lu to 0x%lx\n"), uladv,
19563d8817e4Smiod 		      state_machine_regs.address);
19573d8817e4Smiod 	      break;
19583d8817e4Smiod 
19593d8817e4Smiod 	    case DW_LNS_advance_line:
19603d8817e4Smiod 	      adv = read_leb128 (data, & bytes_read, 1);
19613d8817e4Smiod 	      data += bytes_read;
19623d8817e4Smiod 	      state_machine_regs.line += adv;
19633d8817e4Smiod 	      printf (_("  Advance Line by %d to %d\n"), adv,
19643d8817e4Smiod 		      state_machine_regs.line);
19653d8817e4Smiod 	      break;
19663d8817e4Smiod 
19673d8817e4Smiod 	    case DW_LNS_set_file:
19683d8817e4Smiod 	      adv = read_leb128 (data, & bytes_read, 0);
19693d8817e4Smiod 	      data += bytes_read;
19703d8817e4Smiod 	      printf (_("  Set File Name to entry %d in the File Name Table\n"),
19713d8817e4Smiod 		      adv);
19723d8817e4Smiod 	      state_machine_regs.file = adv;
19733d8817e4Smiod 	      break;
19743d8817e4Smiod 
19753d8817e4Smiod 	    case DW_LNS_set_column:
19763d8817e4Smiod 	      uladv = read_leb128 (data, & bytes_read, 0);
19773d8817e4Smiod 	      data += bytes_read;
19783d8817e4Smiod 	      printf (_("  Set column to %lu\n"), uladv);
19793d8817e4Smiod 	      state_machine_regs.column = uladv;
19803d8817e4Smiod 	      break;
19813d8817e4Smiod 
19823d8817e4Smiod 	    case DW_LNS_negate_stmt:
19833d8817e4Smiod 	      adv = state_machine_regs.is_stmt;
19843d8817e4Smiod 	      adv = ! adv;
19853d8817e4Smiod 	      printf (_("  Set is_stmt to %d\n"), adv);
19863d8817e4Smiod 	      state_machine_regs.is_stmt = adv;
19873d8817e4Smiod 	      break;
19883d8817e4Smiod 
19893d8817e4Smiod 	    case DW_LNS_set_basic_block:
19903d8817e4Smiod 	      printf (_("  Set basic block\n"));
19913d8817e4Smiod 	      state_machine_regs.basic_block = 1;
19923d8817e4Smiod 	      break;
19933d8817e4Smiod 
19943d8817e4Smiod 	    case DW_LNS_const_add_pc:
19953d8817e4Smiod 	      uladv = (((255 - info.li_opcode_base) / info.li_line_range)
19963d8817e4Smiod 		      * info.li_min_insn_length);
19973d8817e4Smiod 	      state_machine_regs.address += uladv;
19983d8817e4Smiod 	      printf (_("  Advance PC by constant %lu to 0x%lx\n"), uladv,
19993d8817e4Smiod 		      state_machine_regs.address);
20003d8817e4Smiod 	      break;
20013d8817e4Smiod 
20023d8817e4Smiod 	    case DW_LNS_fixed_advance_pc:
20033d8817e4Smiod 	      uladv = byte_get (data, 2);
20043d8817e4Smiod 	      data += 2;
20053d8817e4Smiod 	      state_machine_regs.address += uladv;
20063d8817e4Smiod 	      printf (_("  Advance PC by fixed size amount %lu to 0x%lx\n"),
20073d8817e4Smiod 		      uladv, state_machine_regs.address);
20083d8817e4Smiod 	      break;
20093d8817e4Smiod 
20103d8817e4Smiod 	    case DW_LNS_set_prologue_end:
20113d8817e4Smiod 	      printf (_("  Set prologue_end to true\n"));
20123d8817e4Smiod 	      break;
20133d8817e4Smiod 
20143d8817e4Smiod 	    case DW_LNS_set_epilogue_begin:
20153d8817e4Smiod 	      printf (_("  Set epilogue_begin to true\n"));
20163d8817e4Smiod 	      break;
20173d8817e4Smiod 
20183d8817e4Smiod 	    case DW_LNS_set_isa:
20193d8817e4Smiod 	      uladv = read_leb128 (data, & bytes_read, 0);
20203d8817e4Smiod 	      data += bytes_read;
20213d8817e4Smiod 	      printf (_("  Set ISA to %lu\n"), uladv);
20223d8817e4Smiod 	      break;
20233d8817e4Smiod 
20243d8817e4Smiod 	    default:
20253d8817e4Smiod 	      printf (_("  Unknown opcode %d with operands: "), op_code);
20263d8817e4Smiod 
20273d8817e4Smiod 	      for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
20283d8817e4Smiod 		{
20293d8817e4Smiod 		  printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
20303d8817e4Smiod 			  i == 1 ? "" : ", ");
20313d8817e4Smiod 		  data += bytes_read;
20323d8817e4Smiod 		}
20333d8817e4Smiod 	      putchar ('\n');
20343d8817e4Smiod 	      break;
20353d8817e4Smiod 	    }
20363d8817e4Smiod 	}
20373d8817e4Smiod       putchar ('\n');
20383d8817e4Smiod     }
20393d8817e4Smiod 
20403d8817e4Smiod   return 1;
20413d8817e4Smiod }
20423d8817e4Smiod 
20433d8817e4Smiod static int
display_debug_pubnames(struct dwarf_section * section,void * file ATTRIBUTE_UNUSED)20443d8817e4Smiod display_debug_pubnames (struct dwarf_section *section,
20453d8817e4Smiod 			void *file ATTRIBUTE_UNUSED)
20463d8817e4Smiod {
20473d8817e4Smiod   DWARF2_Internal_PubNames pubnames;
20483d8817e4Smiod   unsigned char *start = section->start;
20493d8817e4Smiod   unsigned char *end = start + section->size;
20503d8817e4Smiod 
20513d8817e4Smiod   printf (_("Contents of the %s section:\n\n"), section->name);
20523d8817e4Smiod 
20533d8817e4Smiod   while (start < end)
20543d8817e4Smiod     {
20553d8817e4Smiod       unsigned char *data;
20563d8817e4Smiod       unsigned long offset;
20573d8817e4Smiod       int offset_size, initial_length_size;
20583d8817e4Smiod 
20593d8817e4Smiod       data = start;
20603d8817e4Smiod 
20613d8817e4Smiod       pubnames.pn_length = byte_get (data, 4);
20623d8817e4Smiod       data += 4;
20633d8817e4Smiod       if (pubnames.pn_length == 0xffffffff)
20643d8817e4Smiod 	{
20653d8817e4Smiod 	  pubnames.pn_length = byte_get (data, 8);
20663d8817e4Smiod 	  data += 8;
20673d8817e4Smiod 	  offset_size = 8;
20683d8817e4Smiod 	  initial_length_size = 12;
20693d8817e4Smiod 	}
20703d8817e4Smiod       else
20713d8817e4Smiod 	{
20723d8817e4Smiod 	  offset_size = 4;
20733d8817e4Smiod 	  initial_length_size = 4;
20743d8817e4Smiod 	}
20753d8817e4Smiod 
20763d8817e4Smiod       pubnames.pn_version = byte_get (data, 2);
20773d8817e4Smiod       data += 2;
20783d8817e4Smiod       pubnames.pn_offset = byte_get (data, offset_size);
20793d8817e4Smiod       data += offset_size;
20803d8817e4Smiod       pubnames.pn_size = byte_get (data, offset_size);
20813d8817e4Smiod       data += offset_size;
20823d8817e4Smiod 
20833d8817e4Smiod       start += pubnames.pn_length + initial_length_size;
20843d8817e4Smiod 
20853d8817e4Smiod       if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
20863d8817e4Smiod 	{
20873d8817e4Smiod 	  static int warned = 0;
20883d8817e4Smiod 
20893d8817e4Smiod 	  if (! warned)
20903d8817e4Smiod 	    {
20913d8817e4Smiod 	      warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
20923d8817e4Smiod 	      warned = 1;
20933d8817e4Smiod 	    }
20943d8817e4Smiod 
20953d8817e4Smiod 	  continue;
20963d8817e4Smiod 	}
20973d8817e4Smiod 
20983d8817e4Smiod       printf (_("  Length:                              %ld\n"),
20993d8817e4Smiod 	      pubnames.pn_length);
21003d8817e4Smiod       printf (_("  Version:                             %d\n"),
21013d8817e4Smiod 	      pubnames.pn_version);
21023d8817e4Smiod       printf (_("  Offset into .debug_info section:     %ld\n"),
21033d8817e4Smiod 	      pubnames.pn_offset);
21043d8817e4Smiod       printf (_("  Size of area in .debug_info section: %ld\n"),
21053d8817e4Smiod 	      pubnames.pn_size);
21063d8817e4Smiod 
21073d8817e4Smiod       printf (_("\n    Offset\tName\n"));
21083d8817e4Smiod 
21093d8817e4Smiod       do
21103d8817e4Smiod 	{
21113d8817e4Smiod 	  offset = byte_get (data, offset_size);
21123d8817e4Smiod 
21133d8817e4Smiod 	  if (offset != 0)
21143d8817e4Smiod 	    {
21153d8817e4Smiod 	      data += offset_size;
21163d8817e4Smiod 	      printf ("    %-6ld\t\t%s\n", offset, data);
21173d8817e4Smiod 	      data += strlen ((char *) data) + 1;
21183d8817e4Smiod 	    }
21193d8817e4Smiod 	}
21203d8817e4Smiod       while (offset != 0);
21213d8817e4Smiod     }
21223d8817e4Smiod 
21233d8817e4Smiod   printf ("\n");
21243d8817e4Smiod   return 1;
21253d8817e4Smiod }
21263d8817e4Smiod 
21273d8817e4Smiod static int
display_debug_macinfo(struct dwarf_section * section,void * file ATTRIBUTE_UNUSED)21283d8817e4Smiod display_debug_macinfo (struct dwarf_section *section,
21293d8817e4Smiod 		       void *file ATTRIBUTE_UNUSED)
21303d8817e4Smiod {
21313d8817e4Smiod   unsigned char *start = section->start;
21323d8817e4Smiod   unsigned char *end = start + section->size;
21333d8817e4Smiod   unsigned char *curr = start;
21343d8817e4Smiod   unsigned int bytes_read;
21353d8817e4Smiod   enum dwarf_macinfo_record_type op;
21363d8817e4Smiod 
21373d8817e4Smiod   printf (_("Contents of the %s section:\n\n"), section->name);
21383d8817e4Smiod 
21393d8817e4Smiod   while (curr < end)
21403d8817e4Smiod     {
21413d8817e4Smiod       unsigned int lineno;
21423d8817e4Smiod       const char *string;
21433d8817e4Smiod 
21443d8817e4Smiod       op = *curr;
21453d8817e4Smiod       curr++;
21463d8817e4Smiod 
21473d8817e4Smiod       switch (op)
21483d8817e4Smiod 	{
21493d8817e4Smiod 	case DW_MACINFO_start_file:
21503d8817e4Smiod 	  {
21513d8817e4Smiod 	    unsigned int filenum;
21523d8817e4Smiod 
21533d8817e4Smiod 	    lineno = read_leb128 (curr, & bytes_read, 0);
21543d8817e4Smiod 	    curr += bytes_read;
21553d8817e4Smiod 	    filenum = read_leb128 (curr, & bytes_read, 0);
21563d8817e4Smiod 	    curr += bytes_read;
21573d8817e4Smiod 
21583d8817e4Smiod 	    printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"),
21593d8817e4Smiod 		    lineno, filenum);
21603d8817e4Smiod 	  }
21613d8817e4Smiod 	  break;
21623d8817e4Smiod 
21633d8817e4Smiod 	case DW_MACINFO_end_file:
21643d8817e4Smiod 	  printf (_(" DW_MACINFO_end_file\n"));
21653d8817e4Smiod 	  break;
21663d8817e4Smiod 
21673d8817e4Smiod 	case DW_MACINFO_define:
21683d8817e4Smiod 	  lineno = read_leb128 (curr, & bytes_read, 0);
21693d8817e4Smiod 	  curr += bytes_read;
21703d8817e4Smiod 	  string = (char *) curr;
21713d8817e4Smiod 	  curr += strlen (string) + 1;
21723d8817e4Smiod 	  printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"),
21733d8817e4Smiod 		  lineno, string);
21743d8817e4Smiod 	  break;
21753d8817e4Smiod 
21763d8817e4Smiod 	case DW_MACINFO_undef:
21773d8817e4Smiod 	  lineno = read_leb128 (curr, & bytes_read, 0);
21783d8817e4Smiod 	  curr += bytes_read;
21793d8817e4Smiod 	  string = (char *) curr;
21803d8817e4Smiod 	  curr += strlen (string) + 1;
21813d8817e4Smiod 	  printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"),
21823d8817e4Smiod 		  lineno, string);
21833d8817e4Smiod 	  break;
21843d8817e4Smiod 
21853d8817e4Smiod 	case DW_MACINFO_vendor_ext:
21863d8817e4Smiod 	  {
21873d8817e4Smiod 	    unsigned int constant;
21883d8817e4Smiod 
21893d8817e4Smiod 	    constant = read_leb128 (curr, & bytes_read, 0);
21903d8817e4Smiod 	    curr += bytes_read;
21913d8817e4Smiod 	    string = (char *) curr;
21923d8817e4Smiod 	    curr += strlen (string) + 1;
21933d8817e4Smiod 	    printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"),
21943d8817e4Smiod 		    constant, string);
21953d8817e4Smiod 	  }
21963d8817e4Smiod 	  break;
21973d8817e4Smiod 	}
21983d8817e4Smiod     }
21993d8817e4Smiod 
22003d8817e4Smiod   return 1;
22013d8817e4Smiod }
22023d8817e4Smiod 
22033d8817e4Smiod static int
display_debug_abbrev(struct dwarf_section * section,void * file ATTRIBUTE_UNUSED)22043d8817e4Smiod display_debug_abbrev (struct dwarf_section *section,
22053d8817e4Smiod 		      void *file ATTRIBUTE_UNUSED)
22063d8817e4Smiod {
22073d8817e4Smiod   abbrev_entry *entry;
22083d8817e4Smiod   unsigned char *start = section->start;
22093d8817e4Smiod   unsigned char *end = start + section->size;
22103d8817e4Smiod 
22113d8817e4Smiod   printf (_("Contents of the %s section:\n\n"), section->name);
22123d8817e4Smiod 
22133d8817e4Smiod   do
22143d8817e4Smiod     {
22153d8817e4Smiod       free_abbrevs ();
22163d8817e4Smiod 
22173d8817e4Smiod       start = process_abbrev_section (start, end);
22183d8817e4Smiod 
22193d8817e4Smiod       if (first_abbrev == NULL)
22203d8817e4Smiod 	continue;
22213d8817e4Smiod 
22223d8817e4Smiod       printf (_("  Number TAG\n"));
22233d8817e4Smiod 
22243d8817e4Smiod       for (entry = first_abbrev; entry; entry = entry->next)
22253d8817e4Smiod 	{
22263d8817e4Smiod 	  abbrev_attr *attr;
22273d8817e4Smiod 
22283d8817e4Smiod 	  printf (_("   %ld      %s    [%s]\n"),
22293d8817e4Smiod 		  entry->entry,
22303d8817e4Smiod 		  get_TAG_name (entry->tag),
22313d8817e4Smiod 		  entry->children ? _("has children") : _("no children"));
22323d8817e4Smiod 
22333d8817e4Smiod 	  for (attr = entry->first_attr; attr; attr = attr->next)
22343d8817e4Smiod 	    printf (_("    %-18s %s\n"),
22353d8817e4Smiod 		    get_AT_name (attr->attribute),
22363d8817e4Smiod 		    get_FORM_name (attr->form));
22373d8817e4Smiod 	}
22383d8817e4Smiod     }
22393d8817e4Smiod   while (start);
22403d8817e4Smiod 
22413d8817e4Smiod   printf ("\n");
22423d8817e4Smiod 
22433d8817e4Smiod   return 1;
22443d8817e4Smiod }
22453d8817e4Smiod 
22463d8817e4Smiod static int
display_debug_loc(struct dwarf_section * section,void * file)22473d8817e4Smiod display_debug_loc (struct dwarf_section *section, void *file)
22483d8817e4Smiod {
22493d8817e4Smiod   unsigned char *start = section->start;
22503d8817e4Smiod   unsigned char *section_end;
22513d8817e4Smiod   unsigned long bytes;
22523d8817e4Smiod   unsigned char *section_begin = start;
22533d8817e4Smiod   unsigned int num_loc_list = 0;
22543d8817e4Smiod   unsigned long last_offset = 0;
22553d8817e4Smiod   unsigned int first = 0;
22563d8817e4Smiod   unsigned int i;
22573d8817e4Smiod   unsigned int j;
22583d8817e4Smiod   int seen_first_offset = 0;
22593d8817e4Smiod   int use_debug_info = 1;
22603d8817e4Smiod   unsigned char *next;
22613d8817e4Smiod 
22623d8817e4Smiod   bytes = section->size;
22633d8817e4Smiod   section_end = start + bytes;
22643d8817e4Smiod 
22653d8817e4Smiod   if (bytes == 0)
22663d8817e4Smiod     {
22673d8817e4Smiod       printf (_("\nThe %s section is empty.\n"), section->name);
22683d8817e4Smiod       return 0;
22693d8817e4Smiod     }
22703d8817e4Smiod 
22713d8817e4Smiod   load_debug_info (file);
22723d8817e4Smiod 
22733d8817e4Smiod   /* Check the order of location list in .debug_info section. If
22743d8817e4Smiod      offsets of location lists are in the ascending order, we can
22753d8817e4Smiod      use `debug_information' directly.  */
22763d8817e4Smiod   for (i = 0; i < num_debug_info_entries; i++)
22773d8817e4Smiod     {
22783d8817e4Smiod       unsigned int num;
22793d8817e4Smiod 
22803d8817e4Smiod       num = debug_information [i].num_loc_offsets;
22813d8817e4Smiod       num_loc_list += num;
22823d8817e4Smiod 
22833d8817e4Smiod       /* Check if we can use `debug_information' directly.  */
22843d8817e4Smiod       if (use_debug_info && num != 0)
22853d8817e4Smiod 	{
22863d8817e4Smiod 	  if (!seen_first_offset)
22873d8817e4Smiod 	    {
22883d8817e4Smiod 	      /* This is the first location list.  */
22893d8817e4Smiod 	      last_offset = debug_information [i].loc_offsets [0];
22903d8817e4Smiod 	      first = i;
22913d8817e4Smiod 	      seen_first_offset = 1;
22923d8817e4Smiod 	      j = 1;
22933d8817e4Smiod 	    }
22943d8817e4Smiod 	  else
22953d8817e4Smiod 	    j = 0;
22963d8817e4Smiod 
22973d8817e4Smiod 	  for (; j < num; j++)
22983d8817e4Smiod 	    {
22993d8817e4Smiod 	      if (last_offset >
23003d8817e4Smiod 		  debug_information [i].loc_offsets [j])
23013d8817e4Smiod 		{
23023d8817e4Smiod 		  use_debug_info = 0;
23033d8817e4Smiod 		  break;
23043d8817e4Smiod 		}
23053d8817e4Smiod 	      last_offset = debug_information [i].loc_offsets [j];
23063d8817e4Smiod 	    }
23073d8817e4Smiod 	}
23083d8817e4Smiod     }
23093d8817e4Smiod 
23103d8817e4Smiod   if (!use_debug_info)
23113d8817e4Smiod     /* FIXME: Should we handle this case?  */
23123d8817e4Smiod     error (_("Location lists in .debug_info section aren't in ascending order!\n"));
23133d8817e4Smiod 
23143d8817e4Smiod   if (!seen_first_offset)
23153d8817e4Smiod     error (_("No location lists in .debug_info section!\n"));
23163d8817e4Smiod 
23173d8817e4Smiod   /* DWARF sections under Mach-O have non-zero addresses.  */
23183d8817e4Smiod   if (debug_information [first].loc_offsets [0] != section->address)
23193d8817e4Smiod     warn (_("Location lists in %s section start at 0x%lx\n"),
23203d8817e4Smiod 	  section->name, debug_information [first].loc_offsets [0]);
23213d8817e4Smiod 
23223d8817e4Smiod   printf (_("Contents of the %s section:\n\n"), section->name);
23233d8817e4Smiod   printf (_("    Offset   Begin    End      Expression\n"));
23243d8817e4Smiod 
23253d8817e4Smiod   seen_first_offset = 0;
23263d8817e4Smiod   for (i = first; i < num_debug_info_entries; i++)
23273d8817e4Smiod     {
23283d8817e4Smiod       unsigned long begin;
23293d8817e4Smiod       unsigned long end;
23303d8817e4Smiod       unsigned short length;
23313d8817e4Smiod       unsigned long offset;
23323d8817e4Smiod       unsigned int pointer_size;
23333d8817e4Smiod       unsigned long cu_offset;
23343d8817e4Smiod       unsigned long base_address;
23353d8817e4Smiod       int need_frame_base;
23363d8817e4Smiod       int has_frame_base;
23373d8817e4Smiod 
23383d8817e4Smiod       pointer_size = debug_information [i].pointer_size;
23393d8817e4Smiod       cu_offset = debug_information [i].cu_offset;
23403d8817e4Smiod 
23413d8817e4Smiod       for (j = 0; j < debug_information [i].num_loc_offsets; j++)
23423d8817e4Smiod 	{
23433d8817e4Smiod 	  has_frame_base = debug_information [i].have_frame_base [j];
23443d8817e4Smiod 	  /* DWARF sections under Mach-O have non-zero addresses.  */
23453d8817e4Smiod 	  offset = debug_information [i].loc_offsets [j] - section->address;
23463d8817e4Smiod 	  next = section_begin + offset;
23473d8817e4Smiod 	  base_address = debug_information [i].base_address;
23483d8817e4Smiod 
23493d8817e4Smiod 	  if (!seen_first_offset)
23503d8817e4Smiod 	    seen_first_offset = 1;
23513d8817e4Smiod 	  else
23523d8817e4Smiod 	    {
23533d8817e4Smiod 	      if (start < next)
23543d8817e4Smiod 		warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"),
23553d8817e4Smiod 		      (long)(start - section_begin), (long)(next - section_begin));
23563d8817e4Smiod 	      else if (start > next)
23573d8817e4Smiod 		warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"),
23583d8817e4Smiod 		      (long)(start - section_begin), (long)(next - section_begin));
23593d8817e4Smiod 	    }
23603d8817e4Smiod 	  start = next;
23613d8817e4Smiod 
23623d8817e4Smiod 	  if (offset >= bytes)
23633d8817e4Smiod 	    {
23643d8817e4Smiod 	      warn (_("Offset 0x%lx is bigger than .debug_loc section size.\n"),
23653d8817e4Smiod 		    offset);
23663d8817e4Smiod 	      continue;
23673d8817e4Smiod 	    }
23683d8817e4Smiod 
23693d8817e4Smiod 	  while (1)
23703d8817e4Smiod 	    {
23713d8817e4Smiod 	      if (start + 2 * pointer_size > section_end)
23723d8817e4Smiod 		{
23733d8817e4Smiod 		  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
23743d8817e4Smiod 			offset);
23753d8817e4Smiod 		  break;
23763d8817e4Smiod 		}
23773d8817e4Smiod 
23783d8817e4Smiod 	      begin = byte_get (start, pointer_size);
23793d8817e4Smiod 	      start += pointer_size;
23803d8817e4Smiod 	      end = byte_get (start, pointer_size);
23813d8817e4Smiod 	      start += pointer_size;
23823d8817e4Smiod 
23833d8817e4Smiod 	      if (begin == 0 && end == 0)
23843d8817e4Smiod 		{
23853d8817e4Smiod 		  printf (_("    %8.8lx <End of list>\n"), offset);
23863d8817e4Smiod 		  break;
23873d8817e4Smiod 		}
23883d8817e4Smiod 
23893d8817e4Smiod 	      /* Check base address specifiers.  */
23903d8817e4Smiod 	      if (begin == -1UL && end != -1UL)
23913d8817e4Smiod 		{
23923d8817e4Smiod 		  base_address = end;
23933d8817e4Smiod 		  printf (_("    %8.8lx %8.8lx %8.8lx (base address)\n"),
23943d8817e4Smiod 			  offset, begin, end);
23953d8817e4Smiod 		  continue;
23963d8817e4Smiod 		}
23973d8817e4Smiod 
23983d8817e4Smiod 	      if (start + 2 > section_end)
23993d8817e4Smiod 		{
24003d8817e4Smiod 		  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
24013d8817e4Smiod 			offset);
24023d8817e4Smiod 		  break;
24033d8817e4Smiod 		}
24043d8817e4Smiod 
24053d8817e4Smiod 	      length = byte_get (start, 2);
24063d8817e4Smiod 	      start += 2;
24073d8817e4Smiod 
24083d8817e4Smiod 	      if (start + length > section_end)
24093d8817e4Smiod 		{
24103d8817e4Smiod 		  warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
24113d8817e4Smiod 			offset);
24123d8817e4Smiod 		  break;
24133d8817e4Smiod 		}
24143d8817e4Smiod 
24153d8817e4Smiod 	      printf ("    %8.8lx %8.8lx %8.8lx (",
24163d8817e4Smiod 		      offset, begin + base_address, end + base_address);
24173d8817e4Smiod 	      need_frame_base = decode_location_expression (start,
24183d8817e4Smiod 							    pointer_size,
24193d8817e4Smiod 							    length,
24203d8817e4Smiod 							    cu_offset);
24213d8817e4Smiod 	      putchar (')');
24223d8817e4Smiod 
24233d8817e4Smiod 	      if (need_frame_base && !has_frame_base)
24243d8817e4Smiod 		printf (_(" [without DW_AT_frame_base]"));
24253d8817e4Smiod 
24263d8817e4Smiod 	      if (begin == end)
24273d8817e4Smiod 		fputs (_(" (start == end)"), stdout);
24283d8817e4Smiod 	      else if (begin > end)
24293d8817e4Smiod 		fputs (_(" (start > end)"), stdout);
24303d8817e4Smiod 
24313d8817e4Smiod 	      putchar ('\n');
24323d8817e4Smiod 
24333d8817e4Smiod 	      start += length;
24343d8817e4Smiod 	    }
24353d8817e4Smiod 	}
24363d8817e4Smiod     }
24373d8817e4Smiod   return 1;
24383d8817e4Smiod }
24393d8817e4Smiod 
24403d8817e4Smiod static int
display_debug_str(struct dwarf_section * section,void * file ATTRIBUTE_UNUSED)24413d8817e4Smiod display_debug_str (struct dwarf_section *section,
24423d8817e4Smiod 		   void *file ATTRIBUTE_UNUSED)
24433d8817e4Smiod {
24443d8817e4Smiod   unsigned char *start = section->start;
24453d8817e4Smiod   unsigned long bytes = section->size;
24463d8817e4Smiod   dwarf_vma addr = section->address;
24473d8817e4Smiod 
24483d8817e4Smiod   if (bytes == 0)
24493d8817e4Smiod     {
24503d8817e4Smiod       printf (_("\nThe %s section is empty.\n"), section->name);
24513d8817e4Smiod       return 0;
24523d8817e4Smiod     }
24533d8817e4Smiod 
24543d8817e4Smiod   printf (_("Contents of the %s section:\n\n"), section->name);
24553d8817e4Smiod 
24563d8817e4Smiod   while (bytes)
24573d8817e4Smiod     {
24583d8817e4Smiod       int j;
24593d8817e4Smiod       int k;
24603d8817e4Smiod       int lbytes;
24613d8817e4Smiod 
24623d8817e4Smiod       lbytes = (bytes > 16 ? 16 : bytes);
24633d8817e4Smiod 
24643d8817e4Smiod       printf ("  0x%8.8lx ", (unsigned long) addr);
24653d8817e4Smiod 
24663d8817e4Smiod       for (j = 0; j < 16; j++)
24673d8817e4Smiod 	{
24683d8817e4Smiod 	  if (j < lbytes)
24693d8817e4Smiod 	    printf ("%2.2x", start[j]);
24703d8817e4Smiod 	  else
24713d8817e4Smiod 	    printf ("  ");
24723d8817e4Smiod 
24733d8817e4Smiod 	  if ((j & 3) == 3)
24743d8817e4Smiod 	    printf (" ");
24753d8817e4Smiod 	}
24763d8817e4Smiod 
24773d8817e4Smiod       for (j = 0; j < lbytes; j++)
24783d8817e4Smiod 	{
24793d8817e4Smiod 	  k = start[j];
24803d8817e4Smiod 	  if (k >= ' ' && k < 0x80)
24813d8817e4Smiod 	    printf ("%c", k);
24823d8817e4Smiod 	  else
24833d8817e4Smiod 	    printf (".");
24843d8817e4Smiod 	}
24853d8817e4Smiod 
24863d8817e4Smiod       putchar ('\n');
24873d8817e4Smiod 
24883d8817e4Smiod       start += lbytes;
24893d8817e4Smiod       addr  += lbytes;
24903d8817e4Smiod       bytes -= lbytes;
24913d8817e4Smiod     }
24923d8817e4Smiod 
24933d8817e4Smiod   putchar ('\n');
24943d8817e4Smiod 
24953d8817e4Smiod   return 1;
24963d8817e4Smiod }
24973d8817e4Smiod 
24983d8817e4Smiod 
24993d8817e4Smiod static int
display_debug_info(struct dwarf_section * section,void * file)25003d8817e4Smiod display_debug_info (struct dwarf_section *section, void *file)
25013d8817e4Smiod {
25023d8817e4Smiod   return process_debug_info (section, file, 0);
25033d8817e4Smiod }
25043d8817e4Smiod 
25053d8817e4Smiod 
25063d8817e4Smiod static int
display_debug_aranges(struct dwarf_section * section,void * file ATTRIBUTE_UNUSED)25073d8817e4Smiod display_debug_aranges (struct dwarf_section *section,
25083d8817e4Smiod 		       void *file ATTRIBUTE_UNUSED)
25093d8817e4Smiod {
25103d8817e4Smiod   unsigned char *start = section->start;
25113d8817e4Smiod   unsigned char *end = start + section->size;
25123d8817e4Smiod 
25133d8817e4Smiod   printf (_("The section %s contains:\n\n"), section->name);
25143d8817e4Smiod 
25153d8817e4Smiod   while (start < end)
25163d8817e4Smiod     {
25173d8817e4Smiod       unsigned char *hdrptr;
25183d8817e4Smiod       DWARF2_Internal_ARange arange;
25193d8817e4Smiod       unsigned char *ranges;
25203d8817e4Smiod       unsigned long length;
25213d8817e4Smiod       unsigned long address;
25223d8817e4Smiod       int excess;
25233d8817e4Smiod       int offset_size;
25243d8817e4Smiod       int initial_length_size;
25253d8817e4Smiod 
25263d8817e4Smiod       hdrptr = start;
25273d8817e4Smiod 
25283d8817e4Smiod       arange.ar_length = byte_get (hdrptr, 4);
25293d8817e4Smiod       hdrptr += 4;
25303d8817e4Smiod 
25313d8817e4Smiod       if (arange.ar_length == 0xffffffff)
25323d8817e4Smiod 	{
25333d8817e4Smiod 	  arange.ar_length = byte_get (hdrptr, 8);
25343d8817e4Smiod 	  hdrptr += 8;
25353d8817e4Smiod 	  offset_size = 8;
25363d8817e4Smiod 	  initial_length_size = 12;
25373d8817e4Smiod 	}
25383d8817e4Smiod       else
25393d8817e4Smiod 	{
25403d8817e4Smiod 	  offset_size = 4;
25413d8817e4Smiod 	  initial_length_size = 4;
25423d8817e4Smiod 	}
25433d8817e4Smiod 
25443d8817e4Smiod       arange.ar_version = byte_get (hdrptr, 2);
25453d8817e4Smiod       hdrptr += 2;
25463d8817e4Smiod 
25473d8817e4Smiod       arange.ar_info_offset = byte_get (hdrptr, offset_size);
25483d8817e4Smiod       hdrptr += offset_size;
25493d8817e4Smiod 
25503d8817e4Smiod       arange.ar_pointer_size = byte_get (hdrptr, 1);
25513d8817e4Smiod       hdrptr += 1;
25523d8817e4Smiod 
25533d8817e4Smiod       arange.ar_segment_size = byte_get (hdrptr, 1);
25543d8817e4Smiod       hdrptr += 1;
25553d8817e4Smiod 
25563d8817e4Smiod       if (arange.ar_version != 2 && arange.ar_version != 3)
25573d8817e4Smiod 	{
25583d8817e4Smiod 	  warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
25593d8817e4Smiod 	  break;
25603d8817e4Smiod 	}
25613d8817e4Smiod 
25623d8817e4Smiod       printf (_("  Length:                   %ld\n"), arange.ar_length);
25633d8817e4Smiod       printf (_("  Version:                  %d\n"), arange.ar_version);
25643d8817e4Smiod       printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
25653d8817e4Smiod       printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
25663d8817e4Smiod       printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
25673d8817e4Smiod 
25683d8817e4Smiod       printf (_("\n    Address  Length\n"));
25693d8817e4Smiod 
25703d8817e4Smiod       ranges = hdrptr;
25713d8817e4Smiod 
25723d8817e4Smiod       /* Must pad to an alignment boundary that is twice the pointer size.  */
25733d8817e4Smiod       excess = (hdrptr - start) % (2 * arange.ar_pointer_size);
25743d8817e4Smiod       if (excess)
25753d8817e4Smiod 	ranges += (2 * arange.ar_pointer_size) - excess;
25763d8817e4Smiod 
25773d8817e4Smiod       start += arange.ar_length + initial_length_size;
25783d8817e4Smiod 
25793d8817e4Smiod       while (ranges + 2 * arange.ar_pointer_size <= start)
25803d8817e4Smiod 	{
25813d8817e4Smiod 	  address = byte_get (ranges, arange.ar_pointer_size);
25823d8817e4Smiod 
25833d8817e4Smiod 	  ranges += arange.ar_pointer_size;
25843d8817e4Smiod 
25853d8817e4Smiod 	  length  = byte_get (ranges, arange.ar_pointer_size);
25863d8817e4Smiod 
25873d8817e4Smiod 	  ranges += arange.ar_pointer_size;
25883d8817e4Smiod 
25893d8817e4Smiod 	  printf ("    %8.8lx %lu\n", address, length);
25903d8817e4Smiod 	}
25913d8817e4Smiod     }
25923d8817e4Smiod 
25933d8817e4Smiod   printf ("\n");
25943d8817e4Smiod 
25953d8817e4Smiod   return 1;
25963d8817e4Smiod }
25973d8817e4Smiod 
25983d8817e4Smiod static int
display_debug_ranges(struct dwarf_section * section,void * file ATTRIBUTE_UNUSED)25993d8817e4Smiod display_debug_ranges (struct dwarf_section *section,
26003d8817e4Smiod 		      void *file ATTRIBUTE_UNUSED)
26013d8817e4Smiod {
26023d8817e4Smiod   unsigned char *start = section->start;
26033d8817e4Smiod   unsigned char *section_end;
26043d8817e4Smiod   unsigned long bytes;
26053d8817e4Smiod   unsigned char *section_begin = start;
26063d8817e4Smiod   unsigned int num_range_list = 0;
26073d8817e4Smiod   unsigned long last_offset = 0;
26083d8817e4Smiod   unsigned int first = 0;
26093d8817e4Smiod   unsigned int i;
26103d8817e4Smiod   unsigned int j;
26113d8817e4Smiod   int seen_first_offset = 0;
26123d8817e4Smiod   int use_debug_info = 1;
26133d8817e4Smiod   unsigned char *next;
26143d8817e4Smiod 
26153d8817e4Smiod   bytes = section->size;
26163d8817e4Smiod   section_end = start + bytes;
26173d8817e4Smiod 
26183d8817e4Smiod   if (bytes == 0)
26193d8817e4Smiod     {
26203d8817e4Smiod       printf (_("\nThe %s section is empty.\n"), section->name);
26213d8817e4Smiod       return 0;
26223d8817e4Smiod     }
26233d8817e4Smiod 
26243d8817e4Smiod   load_debug_info (file);
26253d8817e4Smiod 
26263d8817e4Smiod   /* Check the order of range list in .debug_info section. If
26273d8817e4Smiod      offsets of range lists are in the ascending order, we can
26283d8817e4Smiod      use `debug_information' directly.  */
26293d8817e4Smiod   for (i = 0; i < num_debug_info_entries; i++)
26303d8817e4Smiod     {
26313d8817e4Smiod       unsigned int num;
26323d8817e4Smiod 
26333d8817e4Smiod       num = debug_information [i].num_range_lists;
26343d8817e4Smiod       num_range_list += num;
26353d8817e4Smiod 
26363d8817e4Smiod       /* Check if we can use `debug_information' directly.  */
26373d8817e4Smiod       if (use_debug_info && num != 0)
26383d8817e4Smiod 	{
26393d8817e4Smiod 	  if (!seen_first_offset)
26403d8817e4Smiod 	    {
26413d8817e4Smiod 	      /* This is the first range list.  */
26423d8817e4Smiod 	      last_offset = debug_information [i].range_lists [0];
26433d8817e4Smiod 	      first = i;
26443d8817e4Smiod 	      seen_first_offset = 1;
26453d8817e4Smiod 	      j = 1;
26463d8817e4Smiod 	    }
26473d8817e4Smiod 	  else
26483d8817e4Smiod 	    j = 0;
26493d8817e4Smiod 
26503d8817e4Smiod 	  for (; j < num; j++)
26513d8817e4Smiod 	    {
26523d8817e4Smiod 	      if (last_offset >
26533d8817e4Smiod 		  debug_information [i].range_lists [j])
26543d8817e4Smiod 		{
26553d8817e4Smiod 		  use_debug_info = 0;
26563d8817e4Smiod 		  break;
26573d8817e4Smiod 		}
26583d8817e4Smiod 	      last_offset = debug_information [i].range_lists [j];
26593d8817e4Smiod 	    }
26603d8817e4Smiod 	}
26613d8817e4Smiod     }
26623d8817e4Smiod 
26633d8817e4Smiod   if (!use_debug_info)
26643d8817e4Smiod     /* FIXME: Should we handle this case?  */
26653d8817e4Smiod     error (_("Range lists in .debug_info section aren't in ascending order!\n"));
26663d8817e4Smiod 
26673d8817e4Smiod   if (!seen_first_offset)
26683d8817e4Smiod     error (_("No range lists in .debug_info section!\n"));
26693d8817e4Smiod 
26703d8817e4Smiod   /* DWARF sections under Mach-O have non-zero addresses.  */
26713d8817e4Smiod   if (debug_information [first].range_lists [0] != section->address)
26723d8817e4Smiod     warn (_("Range lists in %s section start at 0x%lx\n"),
26733d8817e4Smiod 	  section->name, debug_information [first].range_lists [0]);
26743d8817e4Smiod 
26753d8817e4Smiod   printf (_("Contents of the %s section:\n\n"), section->name);
26763d8817e4Smiod   printf (_("    Offset   Begin    End\n"));
26773d8817e4Smiod 
26783d8817e4Smiod   seen_first_offset = 0;
26793d8817e4Smiod   for (i = first; i < num_debug_info_entries; i++)
26803d8817e4Smiod     {
26813d8817e4Smiod       unsigned long begin;
26823d8817e4Smiod       unsigned long end;
26833d8817e4Smiod       unsigned long offset;
26843d8817e4Smiod       unsigned int pointer_size;
26853d8817e4Smiod       unsigned long base_address;
26863d8817e4Smiod 
26873d8817e4Smiod       pointer_size = debug_information [i].pointer_size;
26883d8817e4Smiod 
26893d8817e4Smiod       for (j = 0; j < debug_information [i].num_range_lists; j++)
26903d8817e4Smiod 	{
26913d8817e4Smiod 	  /* DWARF sections under Mach-O have non-zero addresses.  */
26923d8817e4Smiod 	  offset = debug_information [i].range_lists [j] - section->address;
26933d8817e4Smiod 	  next = section_begin + offset;
26943d8817e4Smiod 	  base_address = debug_information [i].base_address;
26953d8817e4Smiod 
26963d8817e4Smiod 	  if (!seen_first_offset)
26973d8817e4Smiod 	    seen_first_offset = 1;
26983d8817e4Smiod 	  else
26993d8817e4Smiod 	    {
27003d8817e4Smiod 	      if (start < next)
27013d8817e4Smiod 		warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"),
27023d8817e4Smiod 		      (long)(start - section_begin),
27033d8817e4Smiod 		      (long)(next - section_begin), section->name);
27043d8817e4Smiod 	      else if (start > next)
27053d8817e4Smiod 		warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"),
27063d8817e4Smiod 		      (long)(start - section_begin),
27073d8817e4Smiod 		      (long)(next - section_begin), section->name);
27083d8817e4Smiod 	    }
27093d8817e4Smiod 	  start = next;
27103d8817e4Smiod 
27113d8817e4Smiod 	  while (1)
27123d8817e4Smiod 	    {
27133d8817e4Smiod 	      begin = byte_get (start, pointer_size);
27143d8817e4Smiod 	      start += pointer_size;
27153d8817e4Smiod 	      end = byte_get (start, pointer_size);
27163d8817e4Smiod 	      start += pointer_size;
27173d8817e4Smiod 
27183d8817e4Smiod 	      if (begin == 0 && end == 0)
27193d8817e4Smiod 		{
27203d8817e4Smiod 		  printf (_("    %8.8lx <End of list>\n"), offset);
27213d8817e4Smiod 		  break;
27223d8817e4Smiod 		}
27233d8817e4Smiod 
27243d8817e4Smiod 	      /* Check base address specifiers.  */
27253d8817e4Smiod 	      if (begin == -1UL && end != -1UL)
27263d8817e4Smiod 		{
27273d8817e4Smiod 		  base_address = end;
27283d8817e4Smiod 		  printf ("    %8.8lx %8.8lx %8.8lx (base address)\n",
27293d8817e4Smiod 			  offset, begin, end);
27303d8817e4Smiod 		  continue;
27313d8817e4Smiod 		}
27323d8817e4Smiod 
27333d8817e4Smiod 	      printf ("    %8.8lx %8.8lx %8.8lx",
27343d8817e4Smiod 		      offset, begin + base_address, end + base_address);
27353d8817e4Smiod 
27363d8817e4Smiod 	      if (begin == end)
27373d8817e4Smiod 		fputs (_(" (start == end)"), stdout);
27383d8817e4Smiod 	      else if (begin > end)
27393d8817e4Smiod 		fputs (_(" (start > end)"), stdout);
27403d8817e4Smiod 
27413d8817e4Smiod 	      putchar ('\n');
27423d8817e4Smiod 	    }
27433d8817e4Smiod 	}
27443d8817e4Smiod     }
27453d8817e4Smiod   putchar ('\n');
27463d8817e4Smiod   return 1;
27473d8817e4Smiod }
27483d8817e4Smiod 
27493d8817e4Smiod typedef struct Frame_Chunk
27503d8817e4Smiod {
27513d8817e4Smiod   struct Frame_Chunk *next;
27523d8817e4Smiod   unsigned char *chunk_start;
27533d8817e4Smiod   int ncols;
27543d8817e4Smiod   /* DW_CFA_{undefined,same_value,offset,register,unreferenced}  */
27553d8817e4Smiod   short int *col_type;
27563d8817e4Smiod   int *col_offset;
27573d8817e4Smiod   char *augmentation;
27583d8817e4Smiod   unsigned int code_factor;
27593d8817e4Smiod   int data_factor;
27603d8817e4Smiod   unsigned long pc_begin;
27613d8817e4Smiod   unsigned long pc_range;
27623d8817e4Smiod   int cfa_reg;
27633d8817e4Smiod   int cfa_offset;
27643d8817e4Smiod   int ra;
27653d8817e4Smiod   unsigned char fde_encoding;
27663d8817e4Smiod   unsigned char cfa_exp;
27673d8817e4Smiod }
27683d8817e4Smiod Frame_Chunk;
27693d8817e4Smiod 
27703d8817e4Smiod /* A marker for a col_type that means this column was never referenced
27713d8817e4Smiod    in the frame info.  */
27723d8817e4Smiod #define DW_CFA_unreferenced (-1)
2773*e309974cSguenther /* Like DW_CFA_unreferenced, except indicating that it was referenced before
2774*e309974cSguenther    (and therefore needs space in the columnar output). */
2775*e309974cSguenther #define DW_CFA_placeholder  (-2)
27763d8817e4Smiod 
27773d8817e4Smiod static void
frame_need_space(Frame_Chunk * fc,int reg)27783d8817e4Smiod frame_need_space (Frame_Chunk *fc, int reg)
27793d8817e4Smiod {
27803d8817e4Smiod   int prev = fc->ncols;
27813d8817e4Smiod 
27823d8817e4Smiod   if (reg < fc->ncols)
27833d8817e4Smiod     return;
27843d8817e4Smiod 
27853d8817e4Smiod   fc->ncols = reg + 1;
27863d8817e4Smiod   fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int));
27873d8817e4Smiod   fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
27883d8817e4Smiod 
27893d8817e4Smiod   while (prev < fc->ncols)
27903d8817e4Smiod     {
27913d8817e4Smiod       fc->col_type[prev] = DW_CFA_unreferenced;
27923d8817e4Smiod       fc->col_offset[prev] = 0;
27933d8817e4Smiod       prev++;
27943d8817e4Smiod     }
27953d8817e4Smiod }
27963d8817e4Smiod 
27973d8817e4Smiod static void
frame_display_row(Frame_Chunk * fc,int * need_col_headers,int * max_regs)27983d8817e4Smiod frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
27993d8817e4Smiod {
28003d8817e4Smiod   int r;
28013d8817e4Smiod   char tmp[100];
28023d8817e4Smiod 
28033d8817e4Smiod   if (*max_regs < fc->ncols)
28043d8817e4Smiod     *max_regs = fc->ncols;
28053d8817e4Smiod 
28063d8817e4Smiod   if (*need_col_headers)
28073d8817e4Smiod     {
28083d8817e4Smiod       *need_col_headers = 0;
28093d8817e4Smiod 
28103d8817e4Smiod       printf ("   LOC   CFA      ");
28113d8817e4Smiod 
28123d8817e4Smiod       for (r = 0; r < *max_regs; r++)
28133d8817e4Smiod 	if (fc->col_type[r] != DW_CFA_unreferenced)
28143d8817e4Smiod 	  {
28153d8817e4Smiod 	    if (r == fc->ra)
28163d8817e4Smiod 	      printf ("ra   ");
28173d8817e4Smiod 	    else
28183d8817e4Smiod 	      printf ("r%-4d", r);
28193d8817e4Smiod 	  }
28203d8817e4Smiod 
28213d8817e4Smiod       printf ("\n");
28223d8817e4Smiod     }
28233d8817e4Smiod 
28243d8817e4Smiod   printf ("%08lx ", fc->pc_begin);
28253d8817e4Smiod   if (fc->cfa_exp)
28263d8817e4Smiod     strcpy (tmp, "exp");
28273d8817e4Smiod   else
28283d8817e4Smiod     sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
28293d8817e4Smiod   printf ("%-8s ", tmp);
28303d8817e4Smiod 
28313d8817e4Smiod   for (r = 0; r < fc->ncols; r++)
28323d8817e4Smiod     {
28333d8817e4Smiod       if (fc->col_type[r] != DW_CFA_unreferenced)
28343d8817e4Smiod 	{
28353d8817e4Smiod 	  switch (fc->col_type[r])
28363d8817e4Smiod 	    {
28373d8817e4Smiod 	    case DW_CFA_undefined:
28383d8817e4Smiod 	      strcpy (tmp, "u");
28393d8817e4Smiod 	      break;
28403d8817e4Smiod 	    case DW_CFA_same_value:
28413d8817e4Smiod 	      strcpy (tmp, "s");
28423d8817e4Smiod 	      break;
28433d8817e4Smiod 	    case DW_CFA_offset:
28443d8817e4Smiod 	      sprintf (tmp, "c%+d", fc->col_offset[r]);
28453d8817e4Smiod 	      break;
28463d8817e4Smiod 	    case DW_CFA_val_offset:
28473d8817e4Smiod 	      sprintf (tmp, "v%+d", fc->col_offset[r]);
28483d8817e4Smiod 	      break;
28493d8817e4Smiod 	    case DW_CFA_register:
28503d8817e4Smiod 	      sprintf (tmp, "r%d", fc->col_offset[r]);
28513d8817e4Smiod 	      break;
28523d8817e4Smiod 	    case DW_CFA_expression:
28533d8817e4Smiod 	      strcpy (tmp, "exp");
28543d8817e4Smiod 	      break;
28553d8817e4Smiod 	    case DW_CFA_val_expression:
28563d8817e4Smiod 	      strcpy (tmp, "vexp");
28573d8817e4Smiod 	      break;
2858*e309974cSguenther 	    case DW_CFA_placeholder:
2859*e309974cSguenther 	      tmp[0] = '\0';
2860*e309974cSguenther 	      break;
28613d8817e4Smiod 	    default:
28623d8817e4Smiod 	      strcpy (tmp, "n/a");
28633d8817e4Smiod 	      break;
28643d8817e4Smiod 	    }
28653d8817e4Smiod 	  printf ("%-5s", tmp);
28663d8817e4Smiod 	}
28673d8817e4Smiod     }
28683d8817e4Smiod   printf ("\n");
28693d8817e4Smiod }
28703d8817e4Smiod 
28713d8817e4Smiod static int
size_of_encoded_value(int encoding)28723d8817e4Smiod size_of_encoded_value (int encoding)
28733d8817e4Smiod {
28743d8817e4Smiod   switch (encoding & 0x7)
28753d8817e4Smiod     {
28763d8817e4Smiod     default:	/* ??? */
28773d8817e4Smiod     case 0:	return eh_addr_size;
28783d8817e4Smiod     case 2:	return 2;
28793d8817e4Smiod     case 3:	return 4;
28803d8817e4Smiod     case 4:	return 8;
28813d8817e4Smiod     }
28823d8817e4Smiod }
28833d8817e4Smiod 
28843d8817e4Smiod static dwarf_vma
get_encoded_value(unsigned char * data,int encoding)28853d8817e4Smiod get_encoded_value (unsigned char *data, int encoding)
28863d8817e4Smiod {
28873d8817e4Smiod   int size = size_of_encoded_value (encoding);
28883d8817e4Smiod   if (encoding & DW_EH_PE_signed)
28893d8817e4Smiod     return byte_get_signed (data, size);
28903d8817e4Smiod   else
28913d8817e4Smiod     return byte_get (data, size);
28923d8817e4Smiod }
28933d8817e4Smiod 
28943d8817e4Smiod #define GET(N)	byte_get (start, N); start += N
28953d8817e4Smiod #define LEB()	read_leb128 (start, & length_return, 0); start += length_return
28963d8817e4Smiod #define SLEB()	read_leb128 (start, & length_return, 1); start += length_return
28973d8817e4Smiod 
28983d8817e4Smiod static int
display_debug_frames(struct dwarf_section * section,void * file ATTRIBUTE_UNUSED)28993d8817e4Smiod display_debug_frames (struct dwarf_section *section,
29003d8817e4Smiod 		      void *file ATTRIBUTE_UNUSED)
29013d8817e4Smiod {
29023d8817e4Smiod   unsigned char *start = section->start;
29033d8817e4Smiod   unsigned char *end = start + section->size;
29043d8817e4Smiod   unsigned char *section_start = start;
29053d8817e4Smiod   Frame_Chunk *chunks = 0;
29063d8817e4Smiod   Frame_Chunk *remembered_state = 0;
29073d8817e4Smiod   Frame_Chunk *rs;
29083d8817e4Smiod   int is_eh = strcmp (section->name, ".eh_frame") == 0;
29093d8817e4Smiod   unsigned int length_return;
29103d8817e4Smiod   int max_regs = 0;
29113d8817e4Smiod 
29123d8817e4Smiod   printf (_("The section %s contains:\n"), section->name);
29133d8817e4Smiod 
29143d8817e4Smiod   while (start < end)
29153d8817e4Smiod     {
29163d8817e4Smiod       unsigned char *saved_start;
29173d8817e4Smiod       unsigned char *block_end;
29183d8817e4Smiod       unsigned long length;
29193d8817e4Smiod       unsigned long cie_id;
29203d8817e4Smiod       Frame_Chunk *fc;
29213d8817e4Smiod       Frame_Chunk *cie;
29223d8817e4Smiod       int need_col_headers = 1;
29233d8817e4Smiod       unsigned char *augmentation_data = NULL;
29243d8817e4Smiod       unsigned long augmentation_data_len = 0;
29253d8817e4Smiod       int encoded_ptr_size = eh_addr_size;
29263d8817e4Smiod       int offset_size;
29273d8817e4Smiod       int initial_length_size;
29283d8817e4Smiod 
29293d8817e4Smiod       saved_start = start;
29303d8817e4Smiod       length = byte_get (start, 4); start += 4;
29313d8817e4Smiod 
29323d8817e4Smiod       if (length == 0)
29333d8817e4Smiod 	{
29343d8817e4Smiod 	  printf ("\n%08lx ZERO terminator\n\n",
29353d8817e4Smiod 		    (unsigned long)(saved_start - section_start));
29363d8817e4Smiod 	  return 1;
29373d8817e4Smiod 	}
29383d8817e4Smiod 
29393d8817e4Smiod       if (length == 0xffffffff)
29403d8817e4Smiod 	{
29413d8817e4Smiod 	  length = byte_get (start, 8);
29423d8817e4Smiod 	  start += 8;
29433d8817e4Smiod 	  offset_size = 8;
29443d8817e4Smiod 	  initial_length_size = 12;
29453d8817e4Smiod 	}
29463d8817e4Smiod       else
29473d8817e4Smiod 	{
29483d8817e4Smiod 	  offset_size = 4;
29493d8817e4Smiod 	  initial_length_size = 4;
29503d8817e4Smiod 	}
29513d8817e4Smiod 
29523d8817e4Smiod       block_end = saved_start + length + initial_length_size;
29533d8817e4Smiod       cie_id = byte_get (start, offset_size); start += offset_size;
29543d8817e4Smiod 
29553d8817e4Smiod       if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
29563d8817e4Smiod 	{
29573d8817e4Smiod 	  int version;
29583d8817e4Smiod 
29593d8817e4Smiod 	  fc = xmalloc (sizeof (Frame_Chunk));
29603d8817e4Smiod 	  memset (fc, 0, sizeof (Frame_Chunk));
29613d8817e4Smiod 
29623d8817e4Smiod 	  fc->next = chunks;
29633d8817e4Smiod 	  chunks = fc;
29643d8817e4Smiod 	  fc->chunk_start = saved_start;
29653d8817e4Smiod 	  fc->ncols = 0;
29663d8817e4Smiod 	  fc->col_type = xmalloc (sizeof (short int));
29673d8817e4Smiod 	  fc->col_offset = xmalloc (sizeof (int));
29683d8817e4Smiod 	  frame_need_space (fc, max_regs-1);
29693d8817e4Smiod 
29703d8817e4Smiod 	  version = *start++;
29713d8817e4Smiod 
29723d8817e4Smiod 	  fc->augmentation = (char *) start;
29733d8817e4Smiod 	  start = (unsigned char *) strchr ((char *) start, '\0') + 1;
29743d8817e4Smiod 
29753d8817e4Smiod 	  if (fc->augmentation[0] == 'z')
29763d8817e4Smiod 	    {
29773d8817e4Smiod 	      fc->code_factor = LEB ();
29783d8817e4Smiod 	      fc->data_factor = SLEB ();
29793d8817e4Smiod 	      if (version == 1)
29803d8817e4Smiod 		{
29813d8817e4Smiod 		  fc->ra = GET (1);
29823d8817e4Smiod 		}
29833d8817e4Smiod 	      else
29843d8817e4Smiod 		{
29853d8817e4Smiod 		  fc->ra = LEB ();
29863d8817e4Smiod 		}
29873d8817e4Smiod 	      augmentation_data_len = LEB ();
29883d8817e4Smiod 	      augmentation_data = start;
29893d8817e4Smiod 	      start += augmentation_data_len;
29903d8817e4Smiod 	    }
29913d8817e4Smiod 	  else if (strcmp (fc->augmentation, "eh") == 0)
29923d8817e4Smiod 	    {
29933d8817e4Smiod 	      start += eh_addr_size;
29943d8817e4Smiod 	      fc->code_factor = LEB ();
29953d8817e4Smiod 	      fc->data_factor = SLEB ();
29963d8817e4Smiod 	      if (version == 1)
29973d8817e4Smiod 		{
29983d8817e4Smiod 		  fc->ra = GET (1);
29993d8817e4Smiod 		}
30003d8817e4Smiod 	      else
30013d8817e4Smiod 		{
30023d8817e4Smiod 		  fc->ra = LEB ();
30033d8817e4Smiod 		}
30043d8817e4Smiod 	    }
30053d8817e4Smiod 	  else
30063d8817e4Smiod 	    {
30073d8817e4Smiod 	      fc->code_factor = LEB ();
30083d8817e4Smiod 	      fc->data_factor = SLEB ();
30093d8817e4Smiod 	      if (version == 1)
30103d8817e4Smiod 		{
30113d8817e4Smiod 		  fc->ra = GET (1);
30123d8817e4Smiod 		}
30133d8817e4Smiod 	      else
30143d8817e4Smiod 		{
30153d8817e4Smiod 		  fc->ra = LEB ();
30163d8817e4Smiod 		}
30173d8817e4Smiod 	    }
30183d8817e4Smiod 	  cie = fc;
30193d8817e4Smiod 
30203d8817e4Smiod 	  if (do_debug_frames_interp)
30213d8817e4Smiod 	    printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
30223d8817e4Smiod 		    (unsigned long)(saved_start - section_start), length, cie_id,
30233d8817e4Smiod 		    fc->augmentation, fc->code_factor, fc->data_factor,
30243d8817e4Smiod 		    fc->ra);
30253d8817e4Smiod 	  else
30263d8817e4Smiod 	    {
30273d8817e4Smiod 	      printf ("\n%08lx %08lx %08lx CIE\n",
30283d8817e4Smiod 		      (unsigned long)(saved_start - section_start), length, cie_id);
30293d8817e4Smiod 	      printf ("  Version:               %d\n", version);
30303d8817e4Smiod 	      printf ("  Augmentation:          \"%s\"\n", fc->augmentation);
30313d8817e4Smiod 	      printf ("  Code alignment factor: %u\n", fc->code_factor);
30323d8817e4Smiod 	      printf ("  Data alignment factor: %d\n", fc->data_factor);
30333d8817e4Smiod 	      printf ("  Return address column: %d\n", fc->ra);
30343d8817e4Smiod 
30353d8817e4Smiod 	      if (augmentation_data_len)
30363d8817e4Smiod 		{
30373d8817e4Smiod 		  unsigned long i;
30383d8817e4Smiod 		  printf ("  Augmentation data:    ");
30393d8817e4Smiod 		  for (i = 0; i < augmentation_data_len; ++i)
30403d8817e4Smiod 		    printf (" %02x", augmentation_data[i]);
30413d8817e4Smiod 		  putchar ('\n');
30423d8817e4Smiod 		}
30433d8817e4Smiod 	      putchar ('\n');
30443d8817e4Smiod 	    }
30453d8817e4Smiod 
30463d8817e4Smiod 	  if (augmentation_data_len)
30473d8817e4Smiod 	    {
30483d8817e4Smiod 	      unsigned char *p, *q;
30493d8817e4Smiod 	      p = (unsigned char *) fc->augmentation + 1;
30503d8817e4Smiod 	      q = augmentation_data;
30513d8817e4Smiod 
30523d8817e4Smiod 	      while (1)
30533d8817e4Smiod 		{
30543d8817e4Smiod 		  if (*p == 'L')
30553d8817e4Smiod 		    q++;
30563d8817e4Smiod 		  else if (*p == 'P')
30573d8817e4Smiod 		    q += 1 + size_of_encoded_value (*q);
30583d8817e4Smiod 		  else if (*p == 'R')
30593d8817e4Smiod 		    fc->fde_encoding = *q++;
30603d8817e4Smiod 		  else
30613d8817e4Smiod 		    break;
30623d8817e4Smiod 		  p++;
30633d8817e4Smiod 		}
30643d8817e4Smiod 
30653d8817e4Smiod 	      if (fc->fde_encoding)
30663d8817e4Smiod 		encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
30673d8817e4Smiod 	    }
30683d8817e4Smiod 
30693d8817e4Smiod 	  frame_need_space (fc, fc->ra);
30703d8817e4Smiod 	}
30713d8817e4Smiod       else
30723d8817e4Smiod 	{
30733d8817e4Smiod 	  unsigned char *look_for;
30743d8817e4Smiod 	  static Frame_Chunk fde_fc;
30753d8817e4Smiod 
30763d8817e4Smiod 	  fc = & fde_fc;
30773d8817e4Smiod 	  memset (fc, 0, sizeof (Frame_Chunk));
30783d8817e4Smiod 
30793d8817e4Smiod 	  look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
30803d8817e4Smiod 
30813d8817e4Smiod 	  for (cie = chunks; cie ; cie = cie->next)
30823d8817e4Smiod 	    if (cie->chunk_start == look_for)
30833d8817e4Smiod 	      break;
30843d8817e4Smiod 
30853d8817e4Smiod 	  if (!cie)
30863d8817e4Smiod 	    {
30873d8817e4Smiod 	      warn ("Invalid CIE pointer %08lx in FDE at %08lx\n",
30883d8817e4Smiod 		    cie_id, (unsigned long)(saved_start - section_start));
30893d8817e4Smiod 	      start = block_end;
30903d8817e4Smiod 	      fc->ncols = 0;
30913d8817e4Smiod 	      fc->col_type = xmalloc (sizeof (short int));
30923d8817e4Smiod 	      fc->col_offset = xmalloc (sizeof (int));
30933d8817e4Smiod 	      frame_need_space (fc, max_regs - 1);
30943d8817e4Smiod 	      cie = fc;
30953d8817e4Smiod 	      fc->augmentation = "";
30963d8817e4Smiod 	      fc->fde_encoding = 0;
30973d8817e4Smiod 	    }
30983d8817e4Smiod 	  else
30993d8817e4Smiod 	    {
31003d8817e4Smiod 	      fc->ncols = cie->ncols;
31013d8817e4Smiod 	      fc->col_type = xcmalloc (fc->ncols, sizeof (short int));
31023d8817e4Smiod 	      fc->col_offset = xcmalloc (fc->ncols, sizeof (int));
31033d8817e4Smiod 	      memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
31043d8817e4Smiod 	      memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
31053d8817e4Smiod 	      fc->augmentation = cie->augmentation;
31063d8817e4Smiod 	      fc->code_factor = cie->code_factor;
31073d8817e4Smiod 	      fc->data_factor = cie->data_factor;
31083d8817e4Smiod 	      fc->cfa_reg = cie->cfa_reg;
31093d8817e4Smiod 	      fc->cfa_offset = cie->cfa_offset;
31103d8817e4Smiod 	      fc->ra = cie->ra;
31113d8817e4Smiod 	      frame_need_space (fc, max_regs-1);
31123d8817e4Smiod 	      fc->fde_encoding = cie->fde_encoding;
31133d8817e4Smiod 	    }
31143d8817e4Smiod 
31153d8817e4Smiod 	  if (fc->fde_encoding)
31163d8817e4Smiod 	    encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
31173d8817e4Smiod 
31183d8817e4Smiod 	  fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
31193d8817e4Smiod 	  if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
31203d8817e4Smiod 	      /* Don't adjust for relocatable file since there's
31213d8817e4Smiod 		 invariably a pcrel reloc here, which we haven't
31223d8817e4Smiod 		 applied.  */
31233d8817e4Smiod 	      && !is_relocatable)
31243d8817e4Smiod 	    fc->pc_begin += section->address + (start - section_start);
31253d8817e4Smiod 	  start += encoded_ptr_size;
31263d8817e4Smiod 	  fc->pc_range = byte_get (start, encoded_ptr_size);
31273d8817e4Smiod 	  start += encoded_ptr_size;
31283d8817e4Smiod 
31293d8817e4Smiod 	  if (cie->augmentation[0] == 'z')
31303d8817e4Smiod 	    {
31313d8817e4Smiod 	      augmentation_data_len = LEB ();
31323d8817e4Smiod 	      augmentation_data = start;
31333d8817e4Smiod 	      start += augmentation_data_len;
31343d8817e4Smiod 	    }
31353d8817e4Smiod 
31363d8817e4Smiod 	  printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
31373d8817e4Smiod 		  (unsigned long)(saved_start - section_start), length, cie_id,
31383d8817e4Smiod 		  (unsigned long)(cie->chunk_start - section_start),
31393d8817e4Smiod 		  fc->pc_begin, fc->pc_begin + fc->pc_range);
31403d8817e4Smiod 	  if (! do_debug_frames_interp && augmentation_data_len)
31413d8817e4Smiod 	    {
31423d8817e4Smiod 	      unsigned long i;
31433d8817e4Smiod 
31443d8817e4Smiod 	      printf ("  Augmentation data:    ");
31453d8817e4Smiod 	      for (i = 0; i < augmentation_data_len; ++i)
31463d8817e4Smiod 		printf (" %02x", augmentation_data[i]);
31473d8817e4Smiod 	      putchar ('\n');
31483d8817e4Smiod 	      putchar ('\n');
31493d8817e4Smiod 	    }
31503d8817e4Smiod 	}
31513d8817e4Smiod 
31523d8817e4Smiod       /* At this point, fc is the current chunk, cie (if any) is set, and
31533d8817e4Smiod 	 we're about to interpret instructions for the chunk.  */
31543d8817e4Smiod       /* ??? At present we need to do this always, since this sizes the
31553d8817e4Smiod 	 fc->col_type and fc->col_offset arrays, which we write into always.
31563d8817e4Smiod 	 We should probably split the interpreted and non-interpreted bits
31573d8817e4Smiod 	 into two different routines, since there's so much that doesn't
31583d8817e4Smiod 	 really overlap between them.  */
31593d8817e4Smiod       if (1 || do_debug_frames_interp)
31603d8817e4Smiod 	{
31613d8817e4Smiod 	  /* Start by making a pass over the chunk, allocating storage
31623d8817e4Smiod 	     and taking note of what registers are used.  */
31633d8817e4Smiod 	  unsigned char *tmp = start;
31643d8817e4Smiod 
31653d8817e4Smiod 	  while (start < block_end)
31663d8817e4Smiod 	    {
31673d8817e4Smiod 	      unsigned op, opa;
31683d8817e4Smiod 	      unsigned long reg, tmp;
31693d8817e4Smiod 
31703d8817e4Smiod 	      op = *start++;
31713d8817e4Smiod 	      opa = op & 0x3f;
31723d8817e4Smiod 	      if (op & 0xc0)
31733d8817e4Smiod 		op &= 0xc0;
31743d8817e4Smiod 
31753d8817e4Smiod 	      /* Warning: if you add any more cases to this switch, be
31763d8817e4Smiod 		 sure to add them to the corresponding switch below.  */
31773d8817e4Smiod 	      switch (op)
31783d8817e4Smiod 		{
31793d8817e4Smiod 		case DW_CFA_advance_loc:
31803d8817e4Smiod 		  break;
31813d8817e4Smiod 		case DW_CFA_offset:
31823d8817e4Smiod 		  LEB ();
31833d8817e4Smiod 		  frame_need_space (fc, opa);
31843d8817e4Smiod 		  fc->col_type[opa] = DW_CFA_undefined;
31853d8817e4Smiod 		  break;
31863d8817e4Smiod 		case DW_CFA_restore:
31873d8817e4Smiod 		  frame_need_space (fc, opa);
31883d8817e4Smiod 		  fc->col_type[opa] = DW_CFA_undefined;
31893d8817e4Smiod 		  break;
31903d8817e4Smiod 		case DW_CFA_set_loc:
31913d8817e4Smiod 		  start += encoded_ptr_size;
31923d8817e4Smiod 		  break;
31933d8817e4Smiod 		case DW_CFA_advance_loc1:
31943d8817e4Smiod 		  start += 1;
31953d8817e4Smiod 		  break;
31963d8817e4Smiod 		case DW_CFA_advance_loc2:
31973d8817e4Smiod 		  start += 2;
31983d8817e4Smiod 		  break;
31993d8817e4Smiod 		case DW_CFA_advance_loc4:
32003d8817e4Smiod 		  start += 4;
32013d8817e4Smiod 		  break;
32023d8817e4Smiod 		case DW_CFA_offset_extended:
32033d8817e4Smiod 		case DW_CFA_val_offset:
32043d8817e4Smiod 		  reg = LEB (); LEB ();
32053d8817e4Smiod 		  frame_need_space (fc, reg);
32063d8817e4Smiod 		  fc->col_type[reg] = DW_CFA_undefined;
32073d8817e4Smiod 		  break;
32083d8817e4Smiod 		case DW_CFA_restore_extended:
32093d8817e4Smiod 		  reg = LEB ();
32103d8817e4Smiod 		  frame_need_space (fc, reg);
32113d8817e4Smiod 		  fc->col_type[reg] = DW_CFA_undefined;
32123d8817e4Smiod 		  break;
32133d8817e4Smiod 		case DW_CFA_undefined:
32143d8817e4Smiod 		  reg = LEB ();
32153d8817e4Smiod 		  frame_need_space (fc, reg);
32163d8817e4Smiod 		  fc->col_type[reg] = DW_CFA_undefined;
32173d8817e4Smiod 		  break;
32183d8817e4Smiod 		case DW_CFA_same_value:
32193d8817e4Smiod 		  reg = LEB ();
32203d8817e4Smiod 		  frame_need_space (fc, reg);
32213d8817e4Smiod 		  fc->col_type[reg] = DW_CFA_undefined;
32223d8817e4Smiod 		  break;
32233d8817e4Smiod 		case DW_CFA_register:
32243d8817e4Smiod 		  reg = LEB (); LEB ();
32253d8817e4Smiod 		  frame_need_space (fc, reg);
32263d8817e4Smiod 		  fc->col_type[reg] = DW_CFA_undefined;
32273d8817e4Smiod 		  break;
32283d8817e4Smiod 		case DW_CFA_def_cfa:
32293d8817e4Smiod 		  LEB (); LEB ();
32303d8817e4Smiod 		  break;
32313d8817e4Smiod 		case DW_CFA_def_cfa_register:
32323d8817e4Smiod 		  LEB ();
32333d8817e4Smiod 		  break;
32343d8817e4Smiod 		case DW_CFA_def_cfa_offset:
32353d8817e4Smiod 		  LEB ();
32363d8817e4Smiod 		  break;
32373d8817e4Smiod 		case DW_CFA_def_cfa_expression:
32383d8817e4Smiod 		  tmp = LEB ();
32393d8817e4Smiod 		  start += tmp;
32403d8817e4Smiod 		  break;
32413d8817e4Smiod 		case DW_CFA_expression:
32423d8817e4Smiod 		case DW_CFA_val_expression:
32433d8817e4Smiod 		  reg = LEB ();
32443d8817e4Smiod 		  tmp = LEB ();
32453d8817e4Smiod 		  start += tmp;
32463d8817e4Smiod 		  frame_need_space (fc, reg);
32473d8817e4Smiod 		  fc->col_type[reg] = DW_CFA_undefined;
32483d8817e4Smiod 		  break;
32493d8817e4Smiod 		case DW_CFA_offset_extended_sf:
32503d8817e4Smiod 		case DW_CFA_val_offset_sf:
32513d8817e4Smiod 		  reg = LEB (); SLEB ();
32523d8817e4Smiod 		  frame_need_space (fc, reg);
32533d8817e4Smiod 		  fc->col_type[reg] = DW_CFA_undefined;
32543d8817e4Smiod 		  break;
32553d8817e4Smiod 		case DW_CFA_def_cfa_sf:
32563d8817e4Smiod 		  LEB (); SLEB ();
32573d8817e4Smiod 		  break;
32583d8817e4Smiod 		case DW_CFA_def_cfa_offset_sf:
32593d8817e4Smiod 		  SLEB ();
32603d8817e4Smiod 		  break;
32613d8817e4Smiod 		case DW_CFA_MIPS_advance_loc8:
32623d8817e4Smiod 		  start += 8;
32633d8817e4Smiod 		  break;
32643d8817e4Smiod 		case DW_CFA_GNU_args_size:
32653d8817e4Smiod 		  LEB ();
32663d8817e4Smiod 		  break;
32673d8817e4Smiod 		case DW_CFA_GNU_negative_offset_extended:
32683d8817e4Smiod 		  reg = LEB (); LEB ();
32693d8817e4Smiod 		  frame_need_space (fc, reg);
32703d8817e4Smiod 		  fc->col_type[reg] = DW_CFA_undefined;
32713d8817e4Smiod 
32723d8817e4Smiod 		default:
32733d8817e4Smiod 		  break;
32743d8817e4Smiod 		}
32753d8817e4Smiod 	    }
32763d8817e4Smiod 	  start = tmp;
32773d8817e4Smiod 	}
32783d8817e4Smiod 
32793d8817e4Smiod       /* Now we know what registers are used, make a second pass over
32803d8817e4Smiod 	 the chunk, this time actually printing out the info.  */
32813d8817e4Smiod 
32823d8817e4Smiod       while (start < block_end)
32833d8817e4Smiod 	{
32843d8817e4Smiod 	  unsigned op, opa;
32853d8817e4Smiod 	  unsigned long ul, reg, roffs;
32863d8817e4Smiod 	  long l, ofs;
32873d8817e4Smiod 	  dwarf_vma vma;
32883d8817e4Smiod 
32893d8817e4Smiod 	  op = *start++;
32903d8817e4Smiod 	  opa = op & 0x3f;
32913d8817e4Smiod 	  if (op & 0xc0)
32923d8817e4Smiod 	    op &= 0xc0;
32933d8817e4Smiod 
32943d8817e4Smiod 	  /* Warning: if you add any more cases to this switch, be
32953d8817e4Smiod 	     sure to add them to the corresponding switch above.  */
32963d8817e4Smiod 	  switch (op)
32973d8817e4Smiod 	    {
32983d8817e4Smiod 	    case DW_CFA_advance_loc:
32993d8817e4Smiod 	      if (do_debug_frames_interp)
33003d8817e4Smiod 		frame_display_row (fc, &need_col_headers, &max_regs);
33013d8817e4Smiod 	      else
33023d8817e4Smiod 		printf ("  DW_CFA_advance_loc: %d to %08lx\n",
33033d8817e4Smiod 			opa * fc->code_factor,
33043d8817e4Smiod 			fc->pc_begin + opa * fc->code_factor);
33053d8817e4Smiod 	      fc->pc_begin += opa * fc->code_factor;
33063d8817e4Smiod 	      break;
33073d8817e4Smiod 
33083d8817e4Smiod 	    case DW_CFA_offset:
33093d8817e4Smiod 	      roffs = LEB ();
33103d8817e4Smiod 	      if (! do_debug_frames_interp)
33113d8817e4Smiod 		printf ("  DW_CFA_offset: r%d at cfa%+ld\n",
33123d8817e4Smiod 			opa, roffs * fc->data_factor);
33133d8817e4Smiod 	      fc->col_type[opa] = DW_CFA_offset;
33143d8817e4Smiod 	      fc->col_offset[opa] = roffs * fc->data_factor;
33153d8817e4Smiod 	      break;
33163d8817e4Smiod 
33173d8817e4Smiod 	    case DW_CFA_restore:
33183d8817e4Smiod 	      if (! do_debug_frames_interp)
33193d8817e4Smiod 		printf ("  DW_CFA_restore: r%d\n", opa);
3320*e309974cSguenther 	      if ((fc->col_type[opa] = cie->col_type[opa]) ==
3321*e309974cSguenther 		  DW_CFA_unreferenced)
3322*e309974cSguenther 		fc->col_type[opa] = DW_CFA_placeholder;
33233d8817e4Smiod 	      fc->col_offset[opa] = cie->col_offset[opa];
33243d8817e4Smiod 	      break;
33253d8817e4Smiod 
33263d8817e4Smiod 	    case DW_CFA_set_loc:
33273d8817e4Smiod 	      vma = get_encoded_value (start, fc->fde_encoding);
33283d8817e4Smiod 	      if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
33293d8817e4Smiod 		  && !is_relocatable)
33303d8817e4Smiod 		vma += section->address + (start - section_start);
33313d8817e4Smiod 	      start += encoded_ptr_size;
33323d8817e4Smiod 	      if (do_debug_frames_interp)
33333d8817e4Smiod 		frame_display_row (fc, &need_col_headers, &max_regs);
33343d8817e4Smiod 	      else
33353d8817e4Smiod 		printf ("  DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
33363d8817e4Smiod 	      fc->pc_begin = vma;
33373d8817e4Smiod 	      break;
33383d8817e4Smiod 
33393d8817e4Smiod 	    case DW_CFA_advance_loc1:
33403d8817e4Smiod 	      ofs = byte_get (start, 1); start += 1;
33413d8817e4Smiod 	      if (do_debug_frames_interp)
33423d8817e4Smiod 		frame_display_row (fc, &need_col_headers, &max_regs);
33433d8817e4Smiod 	      else
33443d8817e4Smiod 		printf ("  DW_CFA_advance_loc1: %ld to %08lx\n",
33453d8817e4Smiod 			ofs * fc->code_factor,
33463d8817e4Smiod 			fc->pc_begin + ofs * fc->code_factor);
33473d8817e4Smiod 	      fc->pc_begin += ofs * fc->code_factor;
33483d8817e4Smiod 	      break;
33493d8817e4Smiod 
33503d8817e4Smiod 	    case DW_CFA_advance_loc2:
33513d8817e4Smiod 	      ofs = byte_get (start, 2); start += 2;
33523d8817e4Smiod 	      if (do_debug_frames_interp)
33533d8817e4Smiod 		frame_display_row (fc, &need_col_headers, &max_regs);
33543d8817e4Smiod 	      else
33553d8817e4Smiod 		printf ("  DW_CFA_advance_loc2: %ld to %08lx\n",
33563d8817e4Smiod 			ofs * fc->code_factor,
33573d8817e4Smiod 			fc->pc_begin + ofs * fc->code_factor);
33583d8817e4Smiod 	      fc->pc_begin += ofs * fc->code_factor;
33593d8817e4Smiod 	      break;
33603d8817e4Smiod 
33613d8817e4Smiod 	    case DW_CFA_advance_loc4:
33623d8817e4Smiod 	      ofs = byte_get (start, 4); start += 4;
33633d8817e4Smiod 	      if (do_debug_frames_interp)
33643d8817e4Smiod 		frame_display_row (fc, &need_col_headers, &max_regs);
33653d8817e4Smiod 	      else
33663d8817e4Smiod 		printf ("  DW_CFA_advance_loc4: %ld to %08lx\n",
33673d8817e4Smiod 			ofs * fc->code_factor,
33683d8817e4Smiod 			fc->pc_begin + ofs * fc->code_factor);
33693d8817e4Smiod 	      fc->pc_begin += ofs * fc->code_factor;
33703d8817e4Smiod 	      break;
33713d8817e4Smiod 
33723d8817e4Smiod 	    case DW_CFA_offset_extended:
33733d8817e4Smiod 	      reg = LEB ();
33743d8817e4Smiod 	      roffs = LEB ();
33753d8817e4Smiod 	      if (! do_debug_frames_interp)
33763d8817e4Smiod 		printf ("  DW_CFA_offset_extended: r%ld at cfa%+ld\n",
33773d8817e4Smiod 			reg, roffs * fc->data_factor);
33783d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_offset;
33793d8817e4Smiod 	      fc->col_offset[reg] = roffs * fc->data_factor;
33803d8817e4Smiod 	      break;
33813d8817e4Smiod 
33823d8817e4Smiod 	    case DW_CFA_val_offset:
33833d8817e4Smiod 	      reg = LEB ();
33843d8817e4Smiod 	      roffs = LEB ();
33853d8817e4Smiod 	      if (! do_debug_frames_interp)
33863d8817e4Smiod 		printf ("  DW_CFA_val_offset: r%ld at cfa%+ld\n",
33873d8817e4Smiod 			reg, roffs * fc->data_factor);
33883d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_val_offset;
33893d8817e4Smiod 	      fc->col_offset[reg] = roffs * fc->data_factor;
33903d8817e4Smiod 	      break;
33913d8817e4Smiod 
33923d8817e4Smiod 	    case DW_CFA_restore_extended:
33933d8817e4Smiod 	      reg = LEB ();
33943d8817e4Smiod 	      if (! do_debug_frames_interp)
33953d8817e4Smiod 		printf ("  DW_CFA_restore_extended: r%ld\n", reg);
3396*e309974cSguenther 	      if ((fc->col_type[opa] = cie->col_type[opa]) ==
3397*e309974cSguenther 		  DW_CFA_unreferenced)
3398*e309974cSguenther 		fc->col_type[opa] = DW_CFA_placeholder;
33993d8817e4Smiod 	      fc->col_offset[reg] = cie->col_offset[reg];
34003d8817e4Smiod 	      break;
34013d8817e4Smiod 
34023d8817e4Smiod 	    case DW_CFA_undefined:
34033d8817e4Smiod 	      reg = LEB ();
34043d8817e4Smiod 	      if (! do_debug_frames_interp)
34053d8817e4Smiod 		printf ("  DW_CFA_undefined: r%ld\n", reg);
34063d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_undefined;
34073d8817e4Smiod 	      fc->col_offset[reg] = 0;
34083d8817e4Smiod 	      break;
34093d8817e4Smiod 
34103d8817e4Smiod 	    case DW_CFA_same_value:
34113d8817e4Smiod 	      reg = LEB ();
34123d8817e4Smiod 	      if (! do_debug_frames_interp)
34133d8817e4Smiod 		printf ("  DW_CFA_same_value: r%ld\n", reg);
34143d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_same_value;
34153d8817e4Smiod 	      fc->col_offset[reg] = 0;
34163d8817e4Smiod 	      break;
34173d8817e4Smiod 
34183d8817e4Smiod 	    case DW_CFA_register:
34193d8817e4Smiod 	      reg = LEB ();
34203d8817e4Smiod 	      roffs = LEB ();
34213d8817e4Smiod 	      if (! do_debug_frames_interp)
34223d8817e4Smiod 		printf ("  DW_CFA_register: r%ld in r%ld\n", reg, roffs);
34233d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_register;
34243d8817e4Smiod 	      fc->col_offset[reg] = roffs;
34253d8817e4Smiod 	      break;
34263d8817e4Smiod 
34273d8817e4Smiod 	    case DW_CFA_remember_state:
34283d8817e4Smiod 	      if (! do_debug_frames_interp)
34293d8817e4Smiod 		printf ("  DW_CFA_remember_state\n");
34303d8817e4Smiod 	      rs = xmalloc (sizeof (Frame_Chunk));
34313d8817e4Smiod 	      rs->ncols = fc->ncols;
34323d8817e4Smiod 	      rs->col_type = xcmalloc (rs->ncols, sizeof (short int));
34333d8817e4Smiod 	      rs->col_offset = xcmalloc (rs->ncols, sizeof (int));
34343d8817e4Smiod 	      memcpy (rs->col_type, fc->col_type, rs->ncols);
34353d8817e4Smiod 	      memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
34363d8817e4Smiod 	      rs->next = remembered_state;
34373d8817e4Smiod 	      remembered_state = rs;
34383d8817e4Smiod 	      break;
34393d8817e4Smiod 
34403d8817e4Smiod 	    case DW_CFA_restore_state:
34413d8817e4Smiod 	      if (! do_debug_frames_interp)
34423d8817e4Smiod 		printf ("  DW_CFA_restore_state\n");
34433d8817e4Smiod 	      rs = remembered_state;
34443d8817e4Smiod 	      if (rs)
34453d8817e4Smiod 		{
34463d8817e4Smiod 		  remembered_state = rs->next;
34473d8817e4Smiod 		  frame_need_space (fc, rs->ncols-1);
34483d8817e4Smiod 		  memcpy (fc->col_type, rs->col_type, rs->ncols);
34493d8817e4Smiod 		  memcpy (fc->col_offset, rs->col_offset,
34503d8817e4Smiod 			  rs->ncols * sizeof (int));
34513d8817e4Smiod 		  free (rs->col_type);
34523d8817e4Smiod 		  free (rs->col_offset);
34533d8817e4Smiod 		  free (rs);
34543d8817e4Smiod 		}
34553d8817e4Smiod 	      else if (do_debug_frames_interp)
34563d8817e4Smiod 		printf ("Mismatched DW_CFA_restore_state\n");
34573d8817e4Smiod 	      break;
34583d8817e4Smiod 
34593d8817e4Smiod 	    case DW_CFA_def_cfa:
34603d8817e4Smiod 	      fc->cfa_reg = LEB ();
34613d8817e4Smiod 	      fc->cfa_offset = LEB ();
34623d8817e4Smiod 	      fc->cfa_exp = 0;
34633d8817e4Smiod 	      if (! do_debug_frames_interp)
34643d8817e4Smiod 		printf ("  DW_CFA_def_cfa: r%d ofs %d\n",
34653d8817e4Smiod 			fc->cfa_reg, fc->cfa_offset);
34663d8817e4Smiod 	      break;
34673d8817e4Smiod 
34683d8817e4Smiod 	    case DW_CFA_def_cfa_register:
34693d8817e4Smiod 	      fc->cfa_reg = LEB ();
34703d8817e4Smiod 	      fc->cfa_exp = 0;
34713d8817e4Smiod 	      if (! do_debug_frames_interp)
34723d8817e4Smiod 		printf ("  DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
34733d8817e4Smiod 	      break;
34743d8817e4Smiod 
34753d8817e4Smiod 	    case DW_CFA_def_cfa_offset:
34763d8817e4Smiod 	      fc->cfa_offset = LEB ();
34773d8817e4Smiod 	      if (! do_debug_frames_interp)
34783d8817e4Smiod 		printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
34793d8817e4Smiod 	      break;
34803d8817e4Smiod 
34813d8817e4Smiod 	    case DW_CFA_nop:
34823d8817e4Smiod 	      if (! do_debug_frames_interp)
34833d8817e4Smiod 		printf ("  DW_CFA_nop\n");
34843d8817e4Smiod 	      break;
34853d8817e4Smiod 
34863d8817e4Smiod 	    case DW_CFA_def_cfa_expression:
34873d8817e4Smiod 	      ul = LEB ();
34883d8817e4Smiod 	      if (! do_debug_frames_interp)
34893d8817e4Smiod 		{
34903d8817e4Smiod 		  printf ("  DW_CFA_def_cfa_expression (");
34913d8817e4Smiod 		  decode_location_expression (start, eh_addr_size, ul, 0);
34923d8817e4Smiod 		  printf (")\n");
34933d8817e4Smiod 		}
34943d8817e4Smiod 	      fc->cfa_exp = 1;
34953d8817e4Smiod 	      start += ul;
34963d8817e4Smiod 	      break;
34973d8817e4Smiod 
34983d8817e4Smiod 	    case DW_CFA_expression:
34993d8817e4Smiod 	      reg = LEB ();
35003d8817e4Smiod 	      ul = LEB ();
35013d8817e4Smiod 	      if (! do_debug_frames_interp)
35023d8817e4Smiod 		{
35033d8817e4Smiod 		  printf ("  DW_CFA_expression: r%ld (", reg);
35043d8817e4Smiod 		  decode_location_expression (start, eh_addr_size, ul, 0);
35053d8817e4Smiod 		  printf (")\n");
35063d8817e4Smiod 		}
35073d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_expression;
35083d8817e4Smiod 	      start += ul;
35093d8817e4Smiod 	      break;
35103d8817e4Smiod 
35113d8817e4Smiod 	    case DW_CFA_val_expression:
35123d8817e4Smiod 	      reg = LEB ();
35133d8817e4Smiod 	      ul = LEB ();
35143d8817e4Smiod 	      if (! do_debug_frames_interp)
35153d8817e4Smiod 		{
35163d8817e4Smiod 		  printf ("  DW_CFA_val_expression: r%ld (", reg);
35173d8817e4Smiod 		  decode_location_expression (start, eh_addr_size, ul, 0);
35183d8817e4Smiod 		  printf (")\n");
35193d8817e4Smiod 		}
35203d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_val_expression;
35213d8817e4Smiod 	      start += ul;
35223d8817e4Smiod 	      break;
35233d8817e4Smiod 
35243d8817e4Smiod 	    case DW_CFA_offset_extended_sf:
35253d8817e4Smiod 	      reg = LEB ();
35263d8817e4Smiod 	      l = SLEB ();
35273d8817e4Smiod 	      frame_need_space (fc, reg);
35283d8817e4Smiod 	      if (! do_debug_frames_interp)
35293d8817e4Smiod 		printf ("  DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
35303d8817e4Smiod 			reg, l * fc->data_factor);
35313d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_offset;
35323d8817e4Smiod 	      fc->col_offset[reg] = l * fc->data_factor;
35333d8817e4Smiod 	      break;
35343d8817e4Smiod 
35353d8817e4Smiod 	    case DW_CFA_val_offset_sf:
35363d8817e4Smiod 	      reg = LEB ();
35373d8817e4Smiod 	      l = SLEB ();
35383d8817e4Smiod 	      frame_need_space (fc, reg);
35393d8817e4Smiod 	      if (! do_debug_frames_interp)
35403d8817e4Smiod 		printf ("  DW_CFA_val_offset_sf: r%ld at cfa%+ld\n",
35413d8817e4Smiod 			reg, l * fc->data_factor);
35423d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_val_offset;
35433d8817e4Smiod 	      fc->col_offset[reg] = l * fc->data_factor;
35443d8817e4Smiod 	      break;
35453d8817e4Smiod 
35463d8817e4Smiod 	    case DW_CFA_def_cfa_sf:
35473d8817e4Smiod 	      fc->cfa_reg = LEB ();
35483d8817e4Smiod 	      fc->cfa_offset = SLEB ();
35493d8817e4Smiod 	      fc->cfa_offset = fc->cfa_offset * fc->data_factor;
35503d8817e4Smiod 	      fc->cfa_exp = 0;
35513d8817e4Smiod 	      if (! do_debug_frames_interp)
35523d8817e4Smiod 		printf ("  DW_CFA_def_cfa_sf: r%d ofs %d\n",
35533d8817e4Smiod 			fc->cfa_reg, fc->cfa_offset);
35543d8817e4Smiod 	      break;
35553d8817e4Smiod 
35563d8817e4Smiod 	    case DW_CFA_def_cfa_offset_sf:
35573d8817e4Smiod 	      fc->cfa_offset = SLEB ();
35583d8817e4Smiod 	      fc->cfa_offset = fc->cfa_offset * fc->data_factor;
35593d8817e4Smiod 	      if (! do_debug_frames_interp)
35603d8817e4Smiod 		printf ("  DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
35613d8817e4Smiod 	      break;
35623d8817e4Smiod 
35633d8817e4Smiod 	    case DW_CFA_MIPS_advance_loc8:
35643d8817e4Smiod 	      ofs = byte_get (start, 8); start += 8;
35653d8817e4Smiod 	      if (do_debug_frames_interp)
35663d8817e4Smiod 		frame_display_row (fc, &need_col_headers, &max_regs);
35673d8817e4Smiod 	      else
35683d8817e4Smiod 		printf ("  DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
35693d8817e4Smiod 			ofs * fc->code_factor,
35703d8817e4Smiod 			fc->pc_begin + ofs * fc->code_factor);
35713d8817e4Smiod 	      fc->pc_begin += ofs * fc->code_factor;
35723d8817e4Smiod 	      break;
35733d8817e4Smiod 
35743d8817e4Smiod 	    case DW_CFA_GNU_window_save:
35753d8817e4Smiod 	      if (! do_debug_frames_interp)
35763d8817e4Smiod 		printf ("  DW_CFA_GNU_window_save\n");
35773d8817e4Smiod 	      break;
35783d8817e4Smiod 
35793d8817e4Smiod 	    case DW_CFA_GNU_args_size:
35803d8817e4Smiod 	      ul = LEB ();
35813d8817e4Smiod 	      if (! do_debug_frames_interp)
35823d8817e4Smiod 		printf ("  DW_CFA_GNU_args_size: %ld\n", ul);
35833d8817e4Smiod 	      break;
35843d8817e4Smiod 
35853d8817e4Smiod 	    case DW_CFA_GNU_negative_offset_extended:
35863d8817e4Smiod 	      reg = LEB ();
35873d8817e4Smiod 	      l = - LEB ();
35883d8817e4Smiod 	      frame_need_space (fc, reg);
35893d8817e4Smiod 	      if (! do_debug_frames_interp)
35903d8817e4Smiod 		printf ("  DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
35913d8817e4Smiod 			reg, l * fc->data_factor);
35923d8817e4Smiod 	      fc->col_type[reg] = DW_CFA_offset;
35933d8817e4Smiod 	      fc->col_offset[reg] = l * fc->data_factor;
35943d8817e4Smiod 	      break;
35953d8817e4Smiod 
35963d8817e4Smiod 	    default:
35973d8817e4Smiod 	      warn (_("unsupported or unknown DW_CFA_%d\n"), op);
35983d8817e4Smiod 	      start = block_end;
35993d8817e4Smiod 	    }
36003d8817e4Smiod 	}
36013d8817e4Smiod 
36023d8817e4Smiod       if (do_debug_frames_interp)
36033d8817e4Smiod 	frame_display_row (fc, &need_col_headers, &max_regs);
36043d8817e4Smiod 
36053d8817e4Smiod       start = block_end;
36063d8817e4Smiod     }
36073d8817e4Smiod 
36083d8817e4Smiod   printf ("\n");
36093d8817e4Smiod 
36103d8817e4Smiod   return 1;
36113d8817e4Smiod }
36123d8817e4Smiod 
36133d8817e4Smiod #undef GET
36143d8817e4Smiod #undef LEB
36153d8817e4Smiod #undef SLEB
36163d8817e4Smiod 
36173d8817e4Smiod static int
display_debug_not_supported(struct dwarf_section * section,void * file ATTRIBUTE_UNUSED)36183d8817e4Smiod display_debug_not_supported (struct dwarf_section *section,
36193d8817e4Smiod 			     void *file ATTRIBUTE_UNUSED)
36203d8817e4Smiod {
36213d8817e4Smiod   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
36223d8817e4Smiod 	    section->name);
36233d8817e4Smiod 
36243d8817e4Smiod   return 1;
36253d8817e4Smiod }
36263d8817e4Smiod 
36273d8817e4Smiod void *
cmalloc(size_t nmemb,size_t size)36283d8817e4Smiod cmalloc (size_t nmemb, size_t size)
36293d8817e4Smiod {
36303d8817e4Smiod   /* Check for overflow.  */
36313d8817e4Smiod   if (nmemb >= ~(size_t) 0 / size)
36323d8817e4Smiod     return NULL;
36333d8817e4Smiod   else
36343d8817e4Smiod     return malloc (nmemb * size);
36353d8817e4Smiod }
36363d8817e4Smiod 
36373d8817e4Smiod void *
xcmalloc(size_t nmemb,size_t size)36383d8817e4Smiod xcmalloc (size_t nmemb, size_t size)
36393d8817e4Smiod {
36403d8817e4Smiod   /* Check for overflow.  */
36413d8817e4Smiod   if (nmemb >= ~(size_t) 0 / size)
36423d8817e4Smiod     return NULL;
36433d8817e4Smiod   else
36443d8817e4Smiod     return xmalloc (nmemb * size);
36453d8817e4Smiod }
36463d8817e4Smiod 
36473d8817e4Smiod void *
xcrealloc(void * ptr,size_t nmemb,size_t size)36483d8817e4Smiod xcrealloc (void *ptr, size_t nmemb, size_t size)
36493d8817e4Smiod {
36503d8817e4Smiod   /* Check for overflow.  */
36513d8817e4Smiod   if (nmemb >= ~(size_t) 0 / size)
36523d8817e4Smiod     return NULL;
36533d8817e4Smiod   else
36543d8817e4Smiod     return xrealloc (ptr, nmemb * size);
36553d8817e4Smiod }
36563d8817e4Smiod 
36573d8817e4Smiod void
error(const char * message,...)36583d8817e4Smiod error (const char *message, ...)
36593d8817e4Smiod {
36603d8817e4Smiod   va_list args;
36613d8817e4Smiod 
36623d8817e4Smiod   va_start (args, message);
36633d8817e4Smiod   fprintf (stderr, _("%s: Error: "), program_name);
36643d8817e4Smiod   vfprintf (stderr, message, args);
36653d8817e4Smiod   va_end (args);
36663d8817e4Smiod }
36673d8817e4Smiod 
36683d8817e4Smiod void
warn(const char * message,...)36693d8817e4Smiod warn (const char *message, ...)
36703d8817e4Smiod {
36713d8817e4Smiod   va_list args;
36723d8817e4Smiod 
36733d8817e4Smiod   va_start (args, message);
36743d8817e4Smiod   fprintf (stderr, _("%s: Warning: "), program_name);
36753d8817e4Smiod   vfprintf (stderr, message, args);
36763d8817e4Smiod   va_end (args);
36773d8817e4Smiod }
36783d8817e4Smiod 
36793d8817e4Smiod void
free_debug_memory(void)36803d8817e4Smiod free_debug_memory (void)
36813d8817e4Smiod {
36823d8817e4Smiod   enum dwarf_section_display_enum i;
36833d8817e4Smiod 
36843d8817e4Smiod   free_abbrevs ();
36853d8817e4Smiod 
36863d8817e4Smiod   for (i = 0; i < max; i++)
36873d8817e4Smiod     free_debug_section (i);
36883d8817e4Smiod 
36893d8817e4Smiod   if (debug_information)
36903d8817e4Smiod     {
36913d8817e4Smiod       for (i = 0; i < num_debug_info_entries; i++)
36923d8817e4Smiod 	{
36933d8817e4Smiod 	  if (!debug_information [i].max_loc_offsets)
36943d8817e4Smiod 	    {
36953d8817e4Smiod 	      free (debug_information [i].loc_offsets);
36963d8817e4Smiod 	      free (debug_information [i].have_frame_base);
36973d8817e4Smiod 	    }
36983d8817e4Smiod 	  if (!debug_information [i].max_range_lists)
36993d8817e4Smiod 	    free (debug_information [i].range_lists);
37003d8817e4Smiod 	}
37013d8817e4Smiod       free (debug_information);
37023d8817e4Smiod       debug_information = NULL;
37033d8817e4Smiod       num_debug_info_entries = 0;
37043d8817e4Smiod     }
37053d8817e4Smiod 
37063d8817e4Smiod }
37073d8817e4Smiod 
37083d8817e4Smiod struct dwarf_section_display debug_displays[] =
37093d8817e4Smiod {
37103d8817e4Smiod   { { ".debug_abbrev",		NULL,	0,	0 },
37113d8817e4Smiod     display_debug_abbrev,		0,	0 },
37123d8817e4Smiod   { { ".debug_aranges",		NULL,	0,	0 },
37133d8817e4Smiod     display_debug_aranges,		0,	0 },
37143d8817e4Smiod   { { ".debug_frame",		NULL,	0,	0 },
37153d8817e4Smiod     display_debug_frames,		1,	0 },
37163d8817e4Smiod   { { ".debug_info",		NULL,	0,	0 },
37173d8817e4Smiod     display_debug_info,			1,	0 },
37183d8817e4Smiod   { { ".debug_line",		NULL,	0,	0 },
37193d8817e4Smiod     display_debug_lines,		0,	0 },
37203d8817e4Smiod   { { ".debug_pubnames",	NULL,	0,	0 },
37213d8817e4Smiod     display_debug_pubnames,		0,	0 },
37223d8817e4Smiod   { { ".eh_frame",		NULL,	0,	0 },
37233d8817e4Smiod     display_debug_frames,		1,	1 },
37243d8817e4Smiod   { { ".debug_macinfo",		NULL,	0,	0 },
37253d8817e4Smiod     display_debug_macinfo,		0,	0 },
37263d8817e4Smiod   { { ".debug_str",		NULL,	0,	0 },
37273d8817e4Smiod     display_debug_str,			0,	0 },
37283d8817e4Smiod   { { ".debug_loc",		NULL,	0,	0 },
37293d8817e4Smiod     display_debug_loc,			0,	0 },
37303d8817e4Smiod   { { ".debug_pubtypes",	NULL,	0,	0 },
37313d8817e4Smiod     display_debug_pubnames,		0,	0 },
37323d8817e4Smiod   { { ".debug_ranges",		NULL,	0,	0 },
37333d8817e4Smiod     display_debug_ranges,		0,	0 },
37343d8817e4Smiod   { { ".debug_static_func",	NULL,	0,	0 },
37353d8817e4Smiod     display_debug_not_supported,	0,	0 },
37363d8817e4Smiod   { { ".debug_static_vars",	NULL,	0,	0 },
37373d8817e4Smiod     display_debug_not_supported,	0,	0 },
37383d8817e4Smiod   { { ".debug_types",		NULL,	0,	0 },
37393d8817e4Smiod     display_debug_not_supported,	0,	0 },
37403d8817e4Smiod   { { ".debug_weaknames",	NULL,	0,	0 },
37413d8817e4Smiod     display_debug_not_supported,	0,	0 }
37423d8817e4Smiod };
3743