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