X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=binutils%2Fdwarf.c;h=a6986ad4045d8ef9cecb30808e8d637cc840d637;hb=d0ae9fbda7513c1cab463bf1a9b21fdef40e7c56;hp=24a5906f8468d9d1c40f3b0821dbb082cd3b74ef;hpb=0c5882475c48596b92ed08a7ccfa6347d44f8f65;p=binutils-gdb.git diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 24a5906f846..a6986ad4045 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -1,5 +1,5 @@ /* dwarf.c -- display DWARF contents of a BFD binary file - Copyright 2005-2013 Free Software Foundation, Inc. + Copyright (C) 2005-2014 Free Software Foundation, Inc. This file is part of GNU Binutils. @@ -135,52 +135,27 @@ get_encoded_value (unsigned char *data, return val; } -/* Print a dwarf_vma value (typically an address, offset or length) in - hexadecimal format, followed by a space. The length of the value (and - hence the precision displayed) is determined by the byte_size parameter. */ - -static void -print_dwarf_vma (dwarf_vma val, unsigned byte_size) -{ - static char buff[18]; - int offset = 0; - - /* Printf does not have a way of specifiying a maximum field width for an - integer value, so we print the full value into a buffer and then select - the precision we need. */ #if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) #ifndef __MINGW32__ - snprintf (buff, sizeof (buff), "%16.16llx ", val); +#define DWARF_VMA_FMT "ll" +#define DWARF_VMA_FMT_LONG "%16.16llx" #else - snprintf (buff, sizeof (buff), "%016I64x ", val); +#define DWARF_VMA_FMT "I64" +#define DWARF_VMA_FMT_LONG "%016I64x" #endif #else - snprintf (buff, sizeof (buff), "%16.16lx ", val); +#define DWARF_VMA_FMT "l" +#define DWARF_VMA_FMT_LONG "%16.16lx" #endif - if (byte_size != 0) - { - if (byte_size > 0 && byte_size <= 8) - offset = 16 - 2 * byte_size; - else - error (_("Wrong size in print_dwarf_vma")); - } - - fputs (buff + offset, stdout); -} - -#if __STDC_VERSION__ >= 199901L || (defined(__GNUC__) && __GNUC__ >= 2) -#ifndef __MINGW32__ -#define DWARF_VMA_FMT "ll" -#else -#define DWARF_VMA_FMT "I64" -#endif -#else -#define DWARF_VMA_FMT "l" -#endif +/* Convert a dwarf vma value into a string. Returns a pointer to a static + buffer containing the converted VALUE. The value is converted according + to the printf formating character FMTCH. If NUM_BYTES is non-zero then + it specifies the maximum number of bytes to be displayed in the converted + value and FMTCH is ignored - hex is always used. */ static const char * -dwarf_vmatoa (const char *fmtch, dwarf_vma value) +dwarf_vmatoa_1 (const char *fmtch, dwarf_vma value, unsigned num_bytes) { /* As dwarf_vmatoa is used more then once in a printf call for output, we are cycling through an fixed array of pointers @@ -190,17 +165,45 @@ dwarf_vmatoa (const char *fmtch, dwarf_vma value) { char place[64]; } buf[16]; - char fmt[32]; char *ret; - sprintf (fmt, "%%%s%s", DWARF_VMA_FMT, fmtch); - ret = buf[buf_pos++].place; buf_pos %= ARRAY_SIZE (buf); - snprintf (ret, sizeof (buf[0].place), fmt, value); + if (num_bytes) + { + /* Printf does not have a way of specifiying a maximum field width for an + integer value, so we print the full value into a buffer and then select + the precision we need. */ + snprintf (ret, sizeof (buf[0].place), DWARF_VMA_FMT_LONG, value); + if (num_bytes > 8) + num_bytes = 8; + return ret + (16 - 2 * num_bytes); + } + else + { + char fmt[32]; + + sprintf (fmt, "%%%s%s", DWARF_VMA_FMT, fmtch); + snprintf (ret, sizeof (buf[0].place), fmt, value); + return ret; + } +} + +static inline const char * +dwarf_vmatoa (const char * fmtch, dwarf_vma value) +{ + return dwarf_vmatoa_1 (fmtch, value, 0); +} + +/* Print a dwarf_vma value (typically an address, offset or length) in + hexadecimal format, followed by a space. The length of the VALUE (and + hence the precision displayed) is determined by the NUM_BYTES parameter. */ - return ret; +static void +print_dwarf_vma (dwarf_vma value, unsigned num_bytes) +{ + printf ("%s ", dwarf_vmatoa_1 (NULL, value, num_bytes)); } /* Format a 64-bit value, given as two 32-bit values, in hex. @@ -281,6 +284,7 @@ read_uleb128 (unsigned char * data, #define SAFE_BYTE_GET(VAL, PTR, AMOUNT, END) \ do \ { \ + int dummy [sizeof (VAL) < (AMOUNT) ? -1 : 1] ATTRIBUTE_UNUSED ; \ unsigned int amount = (AMOUNT); \ if (((PTR) + amount) >= (END)) \ { \ @@ -333,13 +337,12 @@ read_uleb128 (unsigned char * data, #define SAFE_BYTE_GET64(PTR, HIGH, LOW, END) \ do \ { \ - if (((PTR) + 8) < (END)) \ + if (((PTR) + 8) <= (END)) \ { \ byte_get_64 ((PTR), (HIGH), (LOW)); \ } \ else \ { \ - PTR = END; \ * (LOW) = * (HIGH) = 0; \ } \ } \ @@ -553,8 +556,6 @@ fetch_indirect_string (dwarf_vma offset) if (section->start == NULL) return (const unsigned char *) _(""); - /* DWARF sections under Mach-O have non-zero addresses. */ - offset -= section->address; if (offset > section->size) { warn (_("DW_FORM_strp offset too big: %s\n"), @@ -580,8 +581,6 @@ fetch_indexed_string (dwarf_vma idx, struct cu_tu_set *this_set, return (dwo ? _("") : _("")); - /* DWARF sections under Mach-O have non-zero addresses. */ - index_offset -= index_section->address; if (this_set != NULL) index_offset += this_set->section_offsets [DW_SECT_STR_OFFSETS]; if (index_offset > index_section->size) @@ -807,7 +806,7 @@ static const char * get_FORM_name (unsigned long form) { const char *name; - + if (form == 0) return "DW_FORM value: 0"; @@ -879,7 +878,7 @@ decode_location_expression (unsigned char * data, printf ("DW_OP_const1s: %ld", (long) svalue); break; case DW_OP_const2u: - SAFE_BYTE_GET_AND_INC (uvalue, data, 1, end); + SAFE_BYTE_GET_AND_INC (uvalue, data, 2, end); printf ("DW_OP_const2u: %lu", (unsigned long) uvalue); break; case DW_OP_const2s: @@ -1418,6 +1417,34 @@ find_cu_tu_set_v2 (dwarf_vma cu_offset, int do_types) return NULL; } +/* Add INC to HIGH_BITS:LOW_BITS. */ +static void +add64 (dwarf_vma * high_bits, dwarf_vma * low_bits, dwarf_vma inc) +{ + dwarf_vma tmp = * low_bits; + + tmp += inc; + + /* FIXME: There is probably a better way of handling this: + + We need to cope with dwarf_vma being a 32-bit or 64-bit + type. Plus regardless of its size LOW_BITS is meant to + only hold 32-bits, so if there is overflow or wrap around + we must propagate into HIGH_BITS. */ + if (tmp < * low_bits) + { + ++ * high_bits; + } + else if (sizeof (tmp) > 8 + && (tmp >> 31) > 1) + { + ++ * high_bits; + tmp &= 0xFFFFFFFF; + } + + * low_bits = tmp; +} + static unsigned char * read_and_display_attr_value (unsigned long attribute, unsigned long form, @@ -1437,7 +1464,7 @@ read_and_display_attr_value (unsigned long attribute, unsigned char * orig_data = data; unsigned int bytes_read; - if (data == end) + if (data == end && form != DW_FORM_flag_present) { warn (_("corrupt attribute\n")); return data; @@ -1563,12 +1590,15 @@ read_and_display_attr_value (unsigned long attribute, if (!do_loc) { dwarf_vma high_bits; + dwarf_vma utmp; char buf[64]; SAFE_BYTE_GET64 (data, &high_bits, &uvalue, end); - + utmp = uvalue; + if (form == DW_FORM_ref8) + add64 (& high_bits, & utmp, cu_offset); printf (" 0x%s", - dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf))); + dwarf_vmatoa64 (high_bits, utmp, buf, sizeof (buf))); } if ((do_loc || do_debug_loc || do_debug_ranges) @@ -1585,7 +1615,7 @@ read_and_display_attr_value (unsigned long attribute, case DW_FORM_string: if (!do_loc) - printf (" %.*s", end - data, data); + printf (" %.*s", (int) (end - data), data); data += strnlen ((char *) data, end - data) + 1; break; @@ -1771,11 +1801,10 @@ read_and_display_attr_value (unsigned long attribute, return data; /* For some attributes we can display further information. */ - printf ("\t"); - switch (attribute) { case DW_AT_inline: + printf ("\t"); switch (uvalue) { case DW_INL_not_inlined: @@ -1798,6 +1827,7 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_language: + printf ("\t"); switch (uvalue) { /* Ordered by the numeric value of these constants. */ @@ -1841,6 +1871,7 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_encoding: + printf ("\t"); switch (uvalue) { case DW_ATE_void: printf ("(void)"); break; @@ -1881,6 +1912,7 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_accessibility: + printf ("\t"); switch (uvalue) { case DW_ACCESS_public: printf ("(public)"); break; @@ -1893,6 +1925,7 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_visibility: + printf ("\t"); switch (uvalue) { case DW_VIS_local: printf ("(local)"); break; @@ -1903,6 +1936,7 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_virtuality: + printf ("\t"); switch (uvalue) { case DW_VIRTUALITY_none: printf ("(none)"); break; @@ -1913,6 +1947,7 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_identifier_case: + printf ("\t"); switch (uvalue) { case DW_ID_case_sensitive: printf ("(case_sensitive)"); break; @@ -1924,6 +1959,7 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_calling_convention: + printf ("\t"); switch (uvalue) { case DW_CC_normal: printf ("(normal)"); break; @@ -1939,6 +1975,7 @@ read_and_display_attr_value (unsigned long attribute, break; case DW_AT_ordering: + printf ("\t"); switch (uvalue) { case -1: printf (_("(undefined)")); break; @@ -1964,7 +2001,7 @@ read_and_display_attr_value (unsigned long attribute, if ((dwarf_version < 4 && (form == DW_FORM_data4 || form == DW_FORM_data8)) || form == DW_FORM_sec_offset) - printf (_("(location list)")); + printf (_(" (location list)")); /* Fall through. */ case DW_AT_allocated: case DW_AT_associated: @@ -1976,7 +2013,7 @@ read_and_display_attr_value (unsigned long attribute, { int need_frame_base; - printf ("("); + printf ("\t("); need_frame_base = decode_location_expression (block_start, pointer_size, offset_size, @@ -2012,7 +2049,7 @@ read_and_display_attr_value (unsigned long attribute, abbrev_number = read_uleb128 (section->start + uvalue, NULL, end); - printf (_("[Abbrev Number: %ld"), abbrev_number); + printf (_("\t[Abbrev Number: %ld"), abbrev_number); /* Don't look up abbrev for DW_FORM_ref_addr, as it very often will use different abbrev table, and we don't track .debug_info chunks yet. */ @@ -2189,7 +2226,7 @@ process_debug_info (struct dwarf_section *section, unsigned char *tags; int level, last_level, saved_level; dwarf_vma cu_offset; - int offset_size; + unsigned int offset_size; int initial_length_size; dwarf_vma signature_high = 0; dwarf_vma signature_low = 0; @@ -2238,6 +2275,7 @@ process_debug_info (struct dwarf_section *section, if (do_types) { SAFE_BYTE_GET64 (hdrptr, &signature_high, &signature_low, end); + hdrptr += 8; SAFE_BYTE_GET_AND_INC (type_offset, hdrptr, offset_size, end); } @@ -2328,8 +2366,7 @@ process_debug_info (struct dwarf_section *section, free_abbrevs (); - /* Process the abbrevs used by this compilation unit. DWARF - sections under Mach-O have non-zero addresses. */ + /* Process the abbrevs used by this compilation unit. */ if (compunit.cu_abbrev_offset >= abbrev_size) warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than abbrev section size (%lx)\n"), (unsigned long) compunit.cu_abbrev_offset, @@ -2374,7 +2411,9 @@ process_debug_info (struct dwarf_section *section, break; } - if (!do_loc && die_offset >= dwarf_start_die) + if (!do_loc && die_offset >= dwarf_start_die + && (dwarf_cutoff_level == -1 + || level < dwarf_cutoff_level)) printf (_(" <%d><%lx>: Abbrev Number: 0\n"), level, die_offset); @@ -2539,37 +2578,33 @@ load_debug_info (void * file) return 0; } -static int -display_debug_lines_raw (struct dwarf_section *section, - unsigned char *data, - unsigned char *end) -{ - unsigned char *start = section->start; - - printf (_("Raw dump of debug contents of section %s:\n\n"), - section->name); +/* Read a DWARF .debug_line section header starting at DATA. + Upon success returns an updated DATA pointer and the LINFO + structure and the END_OF_SEQUENCE pointer will be filled in. + Otherwise returns NULL. */ - while (data < end) - { - DWARF2_Internal_LineInfo linfo; - unsigned char *standard_opcodes; - unsigned char *end_of_sequence; - unsigned char *hdrptr; - unsigned long hdroff; - int initial_length_size; - int offset_size; - int i; +static unsigned char * +read_debug_line_header (struct dwarf_section * section, + unsigned char * data, + unsigned char * end, + DWARF2_Internal_LineInfo * linfo, + unsigned char ** end_of_sequence) +{ + unsigned char *hdrptr; + unsigned int offset_size; + unsigned int initial_length_size; + /* Extract information from the Line Number Program Header. + (section 6.2.4 in the Dwarf3 doc). */ hdrptr = data; - hdroff = hdrptr - start; - /* Check the length of the block. */ - SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 4, end); + /* Get and check the length of the block. */ + SAFE_BYTE_GET_AND_INC (linfo->li_length, hdrptr, 4, end); - if (linfo.li_length == 0xffffffff) + if (linfo->li_length == 0xffffffff) { /* This section is 64-bit DWARF 3. */ - SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 8, end); + SAFE_BYTE_GET_AND_INC (linfo->li_length, hdrptr, 8, end); offset_size = 8; initial_length_size = 12; } @@ -2579,315 +2614,389 @@ display_debug_lines_raw (struct dwarf_section *section, initial_length_size = 4; } - if (linfo.li_length + initial_length_size > section->size) + if (linfo->li_length + initial_length_size > section->size) { - warn - (_("The information in section %s appears to be corrupt - the section is too small\n"), - section->name); - return 0; + /* If the length is just a bias against the initial_length_size then + this means that the field has a relocation against it which has not + been applied. (Ie we are dealing with an object file, not a linked + binary). Do not complain but instead assume that the rest of the + section applies to this particular header. */ + if (linfo->li_length == - initial_length_size) + { + linfo->li_length = section->size - initial_length_size; + } + else + { + warn (_("The line info appears to be corrupt - " + "the section is too small\n")); + return NULL; + } } - /* Check its version number. */ - SAFE_BYTE_GET_AND_INC (linfo.li_version, hdrptr, 2, end); - if (linfo.li_version != 2 - && linfo.li_version != 3 - && linfo.li_version != 4) + /* Get and check the version number. */ + SAFE_BYTE_GET_AND_INC (linfo->li_version, hdrptr, 2, end); + + if (linfo->li_version != 2 + && linfo->li_version != 3 + && linfo->li_version != 4) { warn (_("Only DWARF version 2, 3 and 4 line info is currently supported.\n")); - return 0; + return NULL; } - SAFE_BYTE_GET_AND_INC (linfo.li_prologue_length, hdrptr, offset_size, end); - SAFE_BYTE_GET_AND_INC (linfo.li_min_insn_length, hdrptr, 1, end); + SAFE_BYTE_GET_AND_INC (linfo->li_prologue_length, hdrptr, offset_size, end); + SAFE_BYTE_GET_AND_INC (linfo->li_min_insn_length, hdrptr, 1, end); - if (linfo.li_version >= 4) + if (linfo->li_version >= 4) { - SAFE_BYTE_GET_AND_INC (linfo.li_max_ops_per_insn, hdrptr, 1, end); + SAFE_BYTE_GET_AND_INC (linfo->li_max_ops_per_insn, hdrptr, 1, end); - if (linfo.li_max_ops_per_insn == 0) + if (linfo->li_max_ops_per_insn == 0) { warn (_("Invalid maximum operations per insn.\n")); - return 0; + return NULL; } } else - linfo.li_max_ops_per_insn = 1; + linfo->li_max_ops_per_insn = 1; - SAFE_BYTE_GET_AND_INC (linfo.li_default_is_stmt, hdrptr, 1, end); - SAFE_BYTE_GET_AND_INC (linfo.li_line_base, hdrptr, 1, end); - SAFE_BYTE_GET_AND_INC (linfo.li_line_range, hdrptr, 1, end); - SAFE_BYTE_GET_AND_INC (linfo.li_opcode_base, hdrptr, 1, end); + SAFE_BYTE_GET_AND_INC (linfo->li_default_is_stmt, hdrptr, 1, end); + SAFE_BYTE_GET_AND_INC (linfo->li_line_base, hdrptr, 1, end); + SAFE_BYTE_GET_AND_INC (linfo->li_line_range, hdrptr, 1, end); + SAFE_BYTE_GET_AND_INC (linfo->li_opcode_base, hdrptr, 1, end); /* Sign extend the line base field. */ - linfo.li_line_base <<= 24; - linfo.li_line_base >>= 24; - - printf (_(" Offset: 0x%lx\n"), hdroff); - printf (_(" Length: %ld\n"), (long) linfo.li_length); - printf (_(" DWARF Version: %d\n"), linfo.li_version); - printf (_(" Prologue Length: %d\n"), linfo.li_prologue_length); - printf (_(" Minimum Instruction Length: %d\n"), linfo.li_min_insn_length); - if (linfo.li_version >= 4) - printf (_(" Maximum Ops per Instruction: %d\n"), linfo.li_max_ops_per_insn); - printf (_(" Initial value of 'is_stmt': %d\n"), linfo.li_default_is_stmt); - printf (_(" Line Base: %d\n"), linfo.li_line_base); - printf (_(" Line Range: %d\n"), linfo.li_line_range); - printf (_(" Opcode Base: %d\n"), linfo.li_opcode_base); - - end_of_sequence = data + linfo.li_length + initial_length_size; - - reset_state_machine (linfo.li_default_is_stmt); + linfo->li_line_base <<= 24; + linfo->li_line_base >>= 24; - /* Display the contents of the Opcodes table. */ - standard_opcodes = hdrptr; + * end_of_sequence = data + linfo->li_length + initial_length_size; + return hdrptr; +} - printf (_("\n Opcodes:\n")); +static int +display_debug_lines_raw (struct dwarf_section *section, + unsigned char *data, + unsigned char *end) +{ + unsigned char *start = section->start; - for (i = 1; i < linfo.li_opcode_base; i++) - printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]); + printf (_("Raw dump of debug contents of section %s:\n\n"), + section->name); - /* Display the contents of the Directory table. */ - data = standard_opcodes + linfo.li_opcode_base - 1; + while (data < end) + { + static DWARF2_Internal_LineInfo saved_linfo; + DWARF2_Internal_LineInfo linfo; + unsigned char *standard_opcodes; + unsigned char *end_of_sequence; + unsigned int last_dir_entry = 0; + int i; - if (*data == 0) - printf (_("\n The Directory Table is empty.\n")); - else + if (const_strneq (section->name, ".debug_line.") + /* Note: the following does not apply to .debug_line.dwo sections. + These are full debug_line sections. */ + && strcmp (section->name, ".debug_line.dwo") != 0) { - printf (_("\n The Directory Table:\n")); - - while (*data != 0) - { - printf (" %s\n", data); - - data += strnlen ((char *) data, end - data) + 1; - } + /* Sections named .debug_line. are fragments of a .debug_line + section containing just the Line Number Statements. They are + created by the assembler and intended to be used alongside gcc's + -ffunction-sections command line option. When the linker's + garbage collection decides to discard a .text. section it + can then also discard the line number information in .debug_line.. + + Since the section is a fragment it does not have the details + needed to fill out a LineInfo structure, so instead we use the + details from the last full debug_line section that we processed. */ + end_of_sequence = end; + standard_opcodes = NULL; + linfo = saved_linfo; + reset_state_machine (linfo.li_default_is_stmt); } - - /* Skip the NUL at the end of the table. */ - data++; - - /* Display the contents of the File Name table. */ - if (*data == 0) - printf (_("\n The File Name Table is empty.\n")); else { - printf (_("\n The File Name Table:\n")); - printf (_(" Entry\tDir\tTime\tSize\tName\n")); + unsigned char * hdrptr; - while (*data != 0) - { - unsigned char *name; - unsigned int bytes_read; + if ((hdrptr = read_debug_line_header (section, data, end, & linfo, + & end_of_sequence)) == NULL) + return 0; - printf (" %d\t", ++state_machine_regs.last_file_entry); - name = data; - data += strnlen ((char *) data, end - data) + 1; + printf (_(" Offset: 0x%lx\n"), (long)(data - start)); + printf (_(" Length: %ld\n"), (long) linfo.li_length); + printf (_(" DWARF Version: %d\n"), linfo.li_version); + printf (_(" Prologue Length: %d\n"), linfo.li_prologue_length); + printf (_(" Minimum Instruction Length: %d\n"), linfo.li_min_insn_length); + if (linfo.li_version >= 4) + printf (_(" Maximum Ops per Instruction: %d\n"), linfo.li_max_ops_per_insn); + printf (_(" Initial value of 'is_stmt': %d\n"), linfo.li_default_is_stmt); + printf (_(" Line Base: %d\n"), linfo.li_line_base); + printf (_(" Line Range: %d\n"), linfo.li_line_range); + printf (_(" Opcode Base: %d\n"), linfo.li_opcode_base); - printf ("%s\t", - dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); - data += bytes_read; - printf ("%s\t", - dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); - data += bytes_read; - printf ("%s\t", - dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); - data += bytes_read; - printf ("%s\n", name); - - if (data == end) - { - warn (_("Corrupt file name table entry\n")); - break; - } - } - } + reset_state_machine (linfo.li_default_is_stmt); - /* Skip the NUL at the end of the table. */ - data++; + /* Display the contents of the Opcodes table. */ + standard_opcodes = hdrptr; - /* Now display the statements. */ - printf (_("\n Line Number Statements:\n")); + printf (_("\n Opcodes:\n")); - while (data < end_of_sequence) - { - unsigned char op_code; - dwarf_signed_vma adv; - dwarf_vma uladv; - unsigned int bytes_read; + for (i = 1; i < linfo.li_opcode_base; i++) + printf (_(" Opcode %d has %d args\n"), i, standard_opcodes[i - 1]); - op_code = *data++; + /* Display the contents of the Directory table. */ + data = standard_opcodes + linfo.li_opcode_base - 1; - if (op_code >= linfo.li_opcode_base) - { - op_code -= linfo.li_opcode_base; - uladv = (op_code / linfo.li_line_range); - if (linfo.li_max_ops_per_insn == 1) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - printf (_(" Special opcode %d: " - "advance Address by %s to 0x%s"), - op_code, dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address)); - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - printf (_(" Special opcode %d: " - "advance Address by %s to 0x%s[%d]"), - op_code, dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address), - state_machine_regs.op_index); - } - adv = (op_code % linfo.li_line_range) + linfo.li_line_base; - state_machine_regs.line += adv; - printf (_(" and Line by %s to %d\n"), - dwarf_vmatoa ("d", adv), state_machine_regs.line); - } - else switch (op_code) + if (*data == 0) + printf (_("\n The Directory Table is empty.\n")); + else { - case DW_LNS_extended_op: - data += process_extended_line_op (data, linfo.li_default_is_stmt, end); - break; - - case DW_LNS_copy: - printf (_(" Copy\n")); - break; + printf (_("\n The Directory Table (offset 0x%lx):\n"), + (long)(data - start)); - case DW_LNS_advance_pc: - uladv = read_uleb128 (data, & bytes_read, end); - data += bytes_read; - if (linfo.li_max_ops_per_insn == 1) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - printf (_(" Advance PC by %s to 0x%s\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address)); - } - else + while (*data != 0) { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - printf (_(" Advance PC by %s to 0x%s[%d]\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address), - state_machine_regs.op_index); + printf (" %d\t%s\n", ++last_dir_entry, data); + + data += strnlen ((char *) data, end - data) + 1; } - break; + } - case DW_LNS_advance_line: - adv = read_sleb128 (data, & bytes_read, end); - data += bytes_read; - state_machine_regs.line += adv; - printf (_(" Advance Line by %s to %d\n"), - dwarf_vmatoa ("d", adv), - state_machine_regs.line); - break; + /* Skip the NUL at the end of the table. */ + data++; - case DW_LNS_set_file: - adv = read_uleb128 (data, & bytes_read, end); - data += bytes_read; - printf (_(" Set File Name to entry %s in the File Name Table\n"), - dwarf_vmatoa ("d", adv)); - state_machine_regs.file = adv; - break; + /* Display the contents of the File Name table. */ + if (*data == 0) + printf (_("\n The File Name Table is empty.\n")); + else + { + printf (_("\n The File Name Table (offset 0x%lx):\n"), + (long)(data - start)); + printf (_(" Entry\tDir\tTime\tSize\tName\n")); - case DW_LNS_set_column: - uladv = read_uleb128 (data, & bytes_read, end); - data += bytes_read; - printf (_(" Set column to %s\n"), - dwarf_vmatoa ("u", uladv)); - state_machine_regs.column = uladv; - break; + while (*data != 0) + { + unsigned char *name; + unsigned int bytes_read; - case DW_LNS_negate_stmt: - adv = state_machine_regs.is_stmt; - adv = ! adv; - printf (_(" Set is_stmt to %s\n"), dwarf_vmatoa ("d", adv)); - state_machine_regs.is_stmt = adv; - break; + printf (" %d\t", ++state_machine_regs.last_file_entry); + name = data; + data += strnlen ((char *) data, end - data) + 1; - case DW_LNS_set_basic_block: - printf (_(" Set basic block\n")); - state_machine_regs.basic_block = 1; - break; + printf ("%s\t", + dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); + data += bytes_read; + printf ("%s\t", + dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); + data += bytes_read; + printf ("%s\t", + dwarf_vmatoa ("u", read_uleb128 (data, & bytes_read, end))); + data += bytes_read; + printf ("%s\n", name); - case DW_LNS_const_add_pc: - uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range); - if (linfo.li_max_ops_per_insn) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - printf (_(" Advance PC by constant %s to 0x%s\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address)); - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - printf (_(" Advance PC by constant %s to 0x%s[%d]\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address), - state_machine_regs.op_index); + if (data == end) + { + warn (_("Corrupt file name table entry\n")); + break; + } } - break; + } - case DW_LNS_fixed_advance_pc: - SAFE_BYTE_GET_AND_INC (uladv, data, 2, end); - state_machine_regs.address += uladv; - state_machine_regs.op_index = 0; - printf (_(" Advance PC by fixed size amount %s to 0x%s\n"), - dwarf_vmatoa ("u", uladv), - dwarf_vmatoa ("x", state_machine_regs.address)); - break; + /* Skip the NUL at the end of the table. */ + data++; + putchar ('\n'); + saved_linfo = linfo; + } - case DW_LNS_set_prologue_end: - printf (_(" Set prologue_end to true\n")); - break; + /* Now display the statements. */ + if (data >= end_of_sequence) + printf (_(" No Line Number Statements.\n")); + else + { + printf (_(" Line Number Statements:\n")); - case DW_LNS_set_epilogue_begin: - printf (_(" Set epilogue_begin to true\n")); - break; + while (data < end_of_sequence) + { + unsigned char op_code; + dwarf_signed_vma adv; + dwarf_vma uladv; + unsigned int bytes_read; - case DW_LNS_set_isa: - uladv = read_uleb128 (data, & bytes_read, end); - data += bytes_read; - printf (_(" Set ISA to %s\n"), dwarf_vmatoa ("u", uladv)); - break; + printf (" [0x%08lx]", (long)(data - start)); - default: - printf (_(" Unknown opcode %d with operands: "), op_code); + op_code = *data++; - for (i = standard_opcodes[op_code - 1]; i > 0 ; --i) + if (op_code >= linfo.li_opcode_base) { - printf ("0x%s%s", dwarf_vmatoa ("x", read_uleb128 (data, - &bytes_read, end)), - i == 1 ? "" : ", "); - data += bytes_read; + op_code -= linfo.li_opcode_base; + uladv = (op_code / linfo.li_line_range); + if (linfo.li_max_ops_per_insn == 1) + { + uladv *= linfo.li_min_insn_length; + state_machine_regs.address += uladv; + printf (_(" Special opcode %d: " + "advance Address by %s to 0x%s"), + op_code, dwarf_vmatoa ("u", uladv), + dwarf_vmatoa ("x", state_machine_regs.address)); + } + else + { + state_machine_regs.address + += ((state_machine_regs.op_index + uladv) + / linfo.li_max_ops_per_insn) + * linfo.li_min_insn_length; + state_machine_regs.op_index + = (state_machine_regs.op_index + uladv) + % linfo.li_max_ops_per_insn; + printf (_(" Special opcode %d: " + "advance Address by %s to 0x%s[%d]"), + op_code, dwarf_vmatoa ("u", uladv), + dwarf_vmatoa ("x", state_machine_regs.address), + state_machine_regs.op_index); + } + adv = (op_code % linfo.li_line_range) + linfo.li_line_base; + state_machine_regs.line += adv; + printf (_(" and Line by %s to %d\n"), + dwarf_vmatoa ("d", adv), state_machine_regs.line); } - putchar ('\n'); - break; + else switch (op_code) + { + case DW_LNS_extended_op: + data += process_extended_line_op (data, linfo.li_default_is_stmt, end); + break; + + case DW_LNS_copy: + printf (_(" Copy\n")); + break; + + case DW_LNS_advance_pc: + uladv = read_uleb128 (data, & bytes_read, end); + data += bytes_read; + if (linfo.li_max_ops_per_insn == 1) + { + uladv *= linfo.li_min_insn_length; + state_machine_regs.address += uladv; + printf (_(" Advance PC by %s to 0x%s\n"), + dwarf_vmatoa ("u", uladv), + dwarf_vmatoa ("x", state_machine_regs.address)); + } + else + { + state_machine_regs.address + += ((state_machine_regs.op_index + uladv) + / linfo.li_max_ops_per_insn) + * linfo.li_min_insn_length; + state_machine_regs.op_index + = (state_machine_regs.op_index + uladv) + % linfo.li_max_ops_per_insn; + printf (_(" Advance PC by %s to 0x%s[%d]\n"), + dwarf_vmatoa ("u", uladv), + dwarf_vmatoa ("x", state_machine_regs.address), + state_machine_regs.op_index); + } + break; + + case DW_LNS_advance_line: + adv = read_sleb128 (data, & bytes_read, end); + data += bytes_read; + state_machine_regs.line += adv; + printf (_(" Advance Line by %s to %d\n"), + dwarf_vmatoa ("d", adv), + state_machine_regs.line); + break; + + case DW_LNS_set_file: + adv = read_uleb128 (data, & bytes_read, end); + data += bytes_read; + printf (_(" Set File Name to entry %s in the File Name Table\n"), + dwarf_vmatoa ("d", adv)); + state_machine_regs.file = adv; + break; + + case DW_LNS_set_column: + uladv = read_uleb128 (data, & bytes_read, end); + data += bytes_read; + printf (_(" Set column to %s\n"), + dwarf_vmatoa ("u", uladv)); + state_machine_regs.column = uladv; + break; + + case DW_LNS_negate_stmt: + adv = state_machine_regs.is_stmt; + adv = ! adv; + printf (_(" Set is_stmt to %s\n"), dwarf_vmatoa ("d", adv)); + state_machine_regs.is_stmt = adv; + break; + + case DW_LNS_set_basic_block: + printf (_(" Set basic block\n")); + state_machine_regs.basic_block = 1; + break; + + case DW_LNS_const_add_pc: + uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range); + if (linfo.li_max_ops_per_insn) + { + uladv *= linfo.li_min_insn_length; + state_machine_regs.address += uladv; + printf (_(" Advance PC by constant %s to 0x%s\n"), + dwarf_vmatoa ("u", uladv), + dwarf_vmatoa ("x", state_machine_regs.address)); + } + else + { + state_machine_regs.address + += ((state_machine_regs.op_index + uladv) + / linfo.li_max_ops_per_insn) + * linfo.li_min_insn_length; + state_machine_regs.op_index + = (state_machine_regs.op_index + uladv) + % linfo.li_max_ops_per_insn; + printf (_(" Advance PC by constant %s to 0x%s[%d]\n"), + dwarf_vmatoa ("u", uladv), + dwarf_vmatoa ("x", state_machine_regs.address), + state_machine_regs.op_index); + } + break; + + case DW_LNS_fixed_advance_pc: + SAFE_BYTE_GET_AND_INC (uladv, data, 2, end); + state_machine_regs.address += uladv; + state_machine_regs.op_index = 0; + printf (_(" Advance PC by fixed size amount %s to 0x%s\n"), + dwarf_vmatoa ("u", uladv), + dwarf_vmatoa ("x", state_machine_regs.address)); + break; + + case DW_LNS_set_prologue_end: + printf (_(" Set prologue_end to true\n")); + break; + + case DW_LNS_set_epilogue_begin: + printf (_(" Set epilogue_begin to true\n")); + break; + + case DW_LNS_set_isa: + uladv = read_uleb128 (data, & bytes_read, end); + data += bytes_read; + printf (_(" Set ISA to %s\n"), dwarf_vmatoa ("u", uladv)); + break; + + default: + printf (_(" Unknown opcode %d with operands: "), op_code); + + if (standard_opcodes != NULL) + for (i = standard_opcodes[op_code - 1]; i > 0 ; --i) + { + printf ("0x%s%s", dwarf_vmatoa ("x", read_uleb128 (data, + &bytes_read, end)), + i == 1 ? "" : ", "); + data += bytes_read; + } + putchar ('\n'); + break; + } } + putchar ('\n'); } - putchar ('\n'); } return 1; @@ -2908,6 +3017,8 @@ display_debug_lines_decoded (struct dwarf_section *section, unsigned char *data, unsigned char *end) { + static DWARF2_Internal_LineInfo saved_linfo; + printf (_("Decoded dump of debug contents of section %s:\n\n"), section->name); @@ -2917,183 +3028,136 @@ display_debug_lines_decoded (struct dwarf_section *section, DWARF2_Internal_LineInfo linfo; unsigned char *standard_opcodes; unsigned char *end_of_sequence; - unsigned char *hdrptr; - int initial_length_size; - int offset_size; int i; File_Entry *file_table = NULL; unsigned int n_files = 0; unsigned char **directory_table = NULL; unsigned int n_directories = 0; - hdrptr = data; - - /* Extract information from the Line Number Program Header. - (section 6.2.4 in the Dwarf3 doc). */ - - /* Get the length of this CU's line number information block. */ - SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 4, end); - - if (linfo.li_length == 0xffffffff) + if (const_strneq (section->name, ".debug_line.") + /* Note: the following does not apply to .debug_line.dwo sections. + These are full debug_line sections. */ + && strcmp (section->name, ".debug_line.dwo") != 0) { - /* This section is 64-bit DWARF 3. */ - SAFE_BYTE_GET_AND_INC (linfo.li_length, hdrptr, 8, end); - offset_size = 8; - initial_length_size = 12; + /* See comment in display_debug_lines_raw(). */ + end_of_sequence = end; + standard_opcodes = NULL; + linfo = saved_linfo; + reset_state_machine (linfo.li_default_is_stmt); } else { - offset_size = 4; - initial_length_size = 4; - } - - if (linfo.li_length + initial_length_size > section->size) - { - warn (_("The line info appears to be corrupt - " - "the section is too small\n")); - return 0; - } - - /* Get this CU's Line Number Block version number. */ - SAFE_BYTE_GET_AND_INC (linfo.li_version, hdrptr, 2, end); - if (linfo.li_version != 2 - && linfo.li_version != 3 - && linfo.li_version != 4) - { - warn (_("Only DWARF version 2, 3 and 4 line info is currently " - "supported.\n")); - return 0; - } - - SAFE_BYTE_GET_AND_INC (linfo.li_prologue_length, hdrptr, offset_size, end); - SAFE_BYTE_GET_AND_INC (linfo.li_min_insn_length, hdrptr, 1, end); + unsigned char *hdrptr; - if (linfo.li_version >= 4) - { - SAFE_BYTE_GET_AND_INC (linfo.li_max_ops_per_insn, hdrptr, 1, end); - if (linfo.li_max_ops_per_insn == 0) - { - warn (_("Invalid maximum operations per insn.\n")); + if ((hdrptr = read_debug_line_header (section, data, end, & linfo, + & end_of_sequence)) == NULL) return 0; - } - } - else - linfo.li_max_ops_per_insn = 1; - SAFE_BYTE_GET_AND_INC (linfo.li_default_is_stmt, hdrptr, 1, end); - SAFE_BYTE_GET_AND_INC (linfo.li_line_base, hdrptr, 1, end); - SAFE_BYTE_GET_AND_INC (linfo.li_line_range, hdrptr, 1, end); - SAFE_BYTE_GET_AND_INC (linfo.li_opcode_base, hdrptr, 1, end); + reset_state_machine (linfo.li_default_is_stmt); - /* Sign extend the line base field. */ - linfo.li_line_base <<= 24; - linfo.li_line_base >>= 24; + /* Save a pointer to the contents of the Opcodes table. */ + standard_opcodes = hdrptr; - /* Find the end of this CU's Line Number Information Block. */ - end_of_sequence = data + linfo.li_length + initial_length_size; - - reset_state_machine (linfo.li_default_is_stmt); + /* Traverse the Directory table just to count entries. */ + data = standard_opcodes + linfo.li_opcode_base - 1; + if (*data != 0) + { + unsigned char *ptr_directory_table = data; - /* Save a pointer to the contents of the Opcodes table. */ - standard_opcodes = hdrptr; + while (*data != 0) + { + data += strnlen ((char *) data, end - data) + 1; + n_directories++; + } - /* Traverse the Directory table just to count entries. */ - data = standard_opcodes + linfo.li_opcode_base - 1; - if (*data != 0) - { - unsigned char *ptr_directory_table = data; + /* Go through the directory table again to save the directories. */ + directory_table = (unsigned char **) + xmalloc (n_directories * sizeof (unsigned char *)); - while (*data != 0) - { - data += strnlen ((char *) data, end - data) + 1; - n_directories++; + i = 0; + while (*ptr_directory_table != 0) + { + directory_table[i] = ptr_directory_table; + ptr_directory_table += strnlen ((char *) ptr_directory_table, + ptr_directory_table - end) + 1; + i++; + } } + /* Skip the NUL at the end of the table. */ + data++; - /* Go through the directory table again to save the directories. */ - directory_table = (unsigned char **) - xmalloc (n_directories * sizeof (unsigned char *)); + /* Traverse the File Name table just to count the entries. */ + if (*data != 0) + { + unsigned char *ptr_file_name_table = data; - i = 0; - while (*ptr_directory_table != 0) - { - directory_table[i] = ptr_directory_table; - ptr_directory_table += strnlen ((char *) ptr_directory_table, - ptr_directory_table - end) + 1; - i++; - } - } - /* Skip the NUL at the end of the table. */ - data++; + while (*data != 0) + { + unsigned int bytes_read; - /* Traverse the File Name table just to count the entries. */ - if (*data != 0) - { - unsigned char *ptr_file_name_table = data; + /* Skip Name, directory index, last modification time and length + of file. */ + data += strnlen ((char *) data, end - data) + 1; + read_uleb128 (data, & bytes_read, end); + data += bytes_read; + read_uleb128 (data, & bytes_read, end); + data += bytes_read; + read_uleb128 (data, & bytes_read, end); + data += bytes_read; - while (*data != 0) - { - unsigned int bytes_read; + n_files++; + } - /* Skip Name, directory index, last modification time and length - of file. */ - data += strnlen ((char *) data, end - data) + 1; - read_uleb128 (data, & bytes_read, end); - data += bytes_read; - read_uleb128 (data, & bytes_read, end); - data += bytes_read; - read_uleb128 (data, & bytes_read, end); - data += bytes_read; - - n_files++; - } + /* Go through the file table again to save the strings. */ + file_table = (File_Entry *) xmalloc (n_files * sizeof (File_Entry)); - /* Go through the file table again to save the strings. */ - file_table = (File_Entry *) xmalloc (n_files * sizeof (File_Entry)); + i = 0; + while (*ptr_file_name_table != 0) + { + unsigned int bytes_read; + + file_table[i].name = ptr_file_name_table; + ptr_file_name_table += strnlen ((char *) ptr_file_name_table, + end - ptr_file_name_table) + 1; + + /* We are not interested in directory, time or size. */ + file_table[i].directory_index = read_uleb128 (ptr_file_name_table, + & bytes_read, end); + ptr_file_name_table += bytes_read; + file_table[i].modification_date = read_uleb128 (ptr_file_name_table, + & bytes_read, end); + ptr_file_name_table += bytes_read; + file_table[i].length = read_uleb128 (ptr_file_name_table, & bytes_read, end); + ptr_file_name_table += bytes_read; + i++; + } + i = 0; - i = 0; - while (*ptr_file_name_table != 0) - { - unsigned int bytes_read; - - file_table[i].name = ptr_file_name_table; - ptr_file_name_table += strnlen ((char *) ptr_file_name_table, - end - ptr_file_name_table) + 1; - - /* We are not interested in directory, time or size. */ - file_table[i].directory_index = read_uleb128 (ptr_file_name_table, - & bytes_read, end); - ptr_file_name_table += bytes_read; - file_table[i].modification_date = read_uleb128 (ptr_file_name_table, - & bytes_read, end); - ptr_file_name_table += bytes_read; - file_table[i].length = read_uleb128 (ptr_file_name_table, & bytes_read, end); - ptr_file_name_table += bytes_read; - i++; - } - i = 0; + /* Print the Compilation Unit's name and a header. */ + if (directory_table == NULL) + { + printf (_("CU: %s:\n"), file_table[0].name); + printf (_("File name Line number Starting address\n")); + } + else + { + unsigned int ix = file_table[0].directory_index; + const char *directory = ix ? (char *)directory_table[ix - 1] : "."; - /* Print the Compilation Unit's name and a header. */ - if (directory_table == NULL) - { - printf (_("CU: %s:\n"), file_table[0].name); - printf (_("File name Line number Starting address\n")); - } - else - { - unsigned int ix = file_table[0].directory_index; - const char *directory = ix ? (char *)directory_table[ix - 1] : "."; + if (do_wide || strlen (directory) < 76) + printf (_("CU: %s/%s:\n"), directory, file_table[0].name); + else + printf ("%s:\n", file_table[0].name); - if (do_wide || strlen (directory) < 76) - printf (_("CU: %s/%s:\n"), directory, file_table[0].name); - else - printf ("%s:\n", file_table[0].name); + printf (_("File name Line number Starting address\n")); + } + } - printf (_("File name Line number Starting address\n")); - } - } + /* Skip the NUL at the end of the table. */ + data++; - /* Skip the NUL at the end of the table. */ - data++; + saved_linfo = linfo; + } /* This loop iterates through the Dwarf Line Number Program. */ while (data < end_of_sequence) @@ -3120,10 +3184,10 @@ display_debug_lines_decoded (struct dwarf_section *section, state_machine_regs.address += ((state_machine_regs.op_index + uladv) / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; + * linfo.li_min_insn_length; state_machine_regs.op_index = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; + % linfo.li_max_ops_per_insn; } adv = (op_code % linfo.li_line_range) + linfo.li_line_base; @@ -3131,190 +3195,194 @@ display_debug_lines_decoded (struct dwarf_section *section, is_special_opcode = 1; } else switch (op_code) - { - case DW_LNS_extended_op: - { - unsigned int ext_op_code_len; - unsigned char ext_op_code; - unsigned char *op_code_data = data; - - ext_op_code_len = read_uleb128 (op_code_data, &bytes_read, - end_of_sequence); - op_code_data += bytes_read; - - if (ext_op_code_len == 0) - { - warn (_("badly formed extended line op encountered!\n")); - break; - } - ext_op_code_len += bytes_read; - ext_op_code = *op_code_data++; - - switch (ext_op_code) - { - case DW_LNE_end_sequence: - reset_state_machine (linfo.li_default_is_stmt); - break; - case DW_LNE_set_address: - SAFE_BYTE_GET_AND_INC (state_machine_regs.address, - op_code_data, ext_op_code_len - bytes_read - 1, - end); - state_machine_regs.op_index = 0; - break; - case DW_LNE_define_file: - { - file_table = (File_Entry *) xrealloc - (file_table, (n_files + 1) * sizeof (File_Entry)); - - ++state_machine_regs.last_file_entry; - /* Source file name. */ - file_table[n_files].name = op_code_data; - op_code_data += strlen ((char *) op_code_data) + 1; - /* Directory index. */ - file_table[n_files].directory_index = - read_uleb128 (op_code_data, & bytes_read, - end_of_sequence); - op_code_data += bytes_read; - /* Last modification time. */ - file_table[n_files].modification_date = - read_uleb128 (op_code_data, & bytes_read, - end_of_sequence); - op_code_data += bytes_read; - /* File length. */ - file_table[n_files].length = - read_uleb128 (op_code_data, & bytes_read, - end_of_sequence); - - n_files++; - break; - } - case DW_LNE_set_discriminator: - case DW_LNE_HP_set_sequence: - /* Simply ignored. */ - break; - - default: - printf (_("UNKNOWN (%u): length %d\n"), - ext_op_code, ext_op_code_len - bytes_read); - break; - } - data += ext_op_code_len; - break; - } - case DW_LNS_copy: - break; - - case DW_LNS_advance_pc: - uladv = read_uleb128 (data, & bytes_read, end); - data += bytes_read; - if (linfo.li_max_ops_per_insn == 1) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - } - break; - - case DW_LNS_advance_line: - adv = read_sleb128 (data, & bytes_read, end); - data += bytes_read; - state_machine_regs.line += adv; - break; - - case DW_LNS_set_file: - adv = read_uleb128 (data, & bytes_read, end); - data += bytes_read; - state_machine_regs.file = adv; - if (file_table[state_machine_regs.file - 1].directory_index == 0) - { - /* If directory index is 0, that means current directory. */ - printf ("\n./%s:[++]\n", - file_table[state_machine_regs.file - 1].name); - } - else - { - /* The directory index starts counting at 1. */ - printf ("\n%s/%s:\n", - directory_table[file_table[state_machine_regs.file - 1].directory_index - 1], - file_table[state_machine_regs.file - 1].name); - } - break; - - case DW_LNS_set_column: - uladv = read_uleb128 (data, & bytes_read, end); - data += bytes_read; - state_machine_regs.column = uladv; - break; - - case DW_LNS_negate_stmt: - adv = state_machine_regs.is_stmt; - adv = ! adv; - state_machine_regs.is_stmt = adv; - break; - - case DW_LNS_set_basic_block: - state_machine_regs.basic_block = 1; - break; - - case DW_LNS_const_add_pc: - uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range); - if (linfo.li_max_ops_per_insn == 1) - { - uladv *= linfo.li_min_insn_length; - state_machine_regs.address += uladv; - } - else - { - state_machine_regs.address - += ((state_machine_regs.op_index + uladv) - / linfo.li_max_ops_per_insn) - * linfo.li_min_insn_length; - state_machine_regs.op_index - = (state_machine_regs.op_index + uladv) - % linfo.li_max_ops_per_insn; - } - break; - - case DW_LNS_fixed_advance_pc: - SAFE_BYTE_GET_AND_INC (uladv, data, 2, end); - state_machine_regs.address += uladv; - state_machine_regs.op_index = 0; - break; - - case DW_LNS_set_prologue_end: - break; - - case DW_LNS_set_epilogue_begin: - break; - - case DW_LNS_set_isa: - uladv = read_uleb128 (data, & bytes_read, end); - data += bytes_read; - printf (_(" Set ISA to %lu\n"), uladv); - break; - - default: - printf (_(" Unknown opcode %d with operands: "), op_code); - - for (i = standard_opcodes[op_code - 1]; i > 0 ; --i) - { - printf ("0x%s%s", dwarf_vmatoa ("x", read_uleb128 (data, - &bytes_read, end)), - i == 1 ? "" : ", "); - data += bytes_read; - } - putchar ('\n'); - break; - } + { + case DW_LNS_extended_op: + { + unsigned int ext_op_code_len; + unsigned char ext_op_code; + unsigned char *op_code_data = data; + + ext_op_code_len = read_uleb128 (op_code_data, &bytes_read, + end_of_sequence); + op_code_data += bytes_read; + + if (ext_op_code_len == 0) + { + warn (_("badly formed extended line op encountered!\n")); + break; + } + ext_op_code_len += bytes_read; + ext_op_code = *op_code_data++; + + switch (ext_op_code) + { + case DW_LNE_end_sequence: + reset_state_machine (linfo.li_default_is_stmt); + break; + case DW_LNE_set_address: + SAFE_BYTE_GET_AND_INC (state_machine_regs.address, + op_code_data, + ext_op_code_len - bytes_read - 1, + end); + state_machine_regs.op_index = 0; + break; + case DW_LNE_define_file: + { + file_table = (File_Entry *) xrealloc + (file_table, (n_files + 1) * sizeof (File_Entry)); + + ++state_machine_regs.last_file_entry; + /* Source file name. */ + file_table[n_files].name = op_code_data; + op_code_data += strlen ((char *) op_code_data) + 1; + /* Directory index. */ + file_table[n_files].directory_index = + read_uleb128 (op_code_data, & bytes_read, + end_of_sequence); + op_code_data += bytes_read; + /* Last modification time. */ + file_table[n_files].modification_date = + read_uleb128 (op_code_data, & bytes_read, + end_of_sequence); + op_code_data += bytes_read; + /* File length. */ + file_table[n_files].length = + read_uleb128 (op_code_data, & bytes_read, + end_of_sequence); + + n_files++; + break; + } + case DW_LNE_set_discriminator: + case DW_LNE_HP_set_sequence: + /* Simply ignored. */ + break; + + default: + printf (_("UNKNOWN (%u): length %d\n"), + ext_op_code, ext_op_code_len - bytes_read); + break; + } + data += ext_op_code_len; + break; + } + case DW_LNS_copy: + break; + + case DW_LNS_advance_pc: + uladv = read_uleb128 (data, & bytes_read, end); + data += bytes_read; + if (linfo.li_max_ops_per_insn == 1) + { + uladv *= linfo.li_min_insn_length; + state_machine_regs.address += uladv; + } + else + { + state_machine_regs.address + += ((state_machine_regs.op_index + uladv) + / linfo.li_max_ops_per_insn) + * linfo.li_min_insn_length; + state_machine_regs.op_index + = (state_machine_regs.op_index + uladv) + % linfo.li_max_ops_per_insn; + } + break; + + case DW_LNS_advance_line: + adv = read_sleb128 (data, & bytes_read, end); + data += bytes_read; + state_machine_regs.line += adv; + break; + + case DW_LNS_set_file: + adv = read_uleb128 (data, & bytes_read, end); + data += bytes_read; + state_machine_regs.file = adv; + + if (file_table == NULL) + printf (_("\n [Use file table entry %d]\n"), state_machine_regs.file - 1); + else if (file_table[state_machine_regs.file - 1].directory_index == 0) + /* If directory index is 0, that means current directory. */ + printf ("\n./%s:[++]\n", + file_table[state_machine_regs.file - 1].name); + else if (directory_table == NULL) + printf (_("\n [Use directory table entry %d]\n"), + file_table[state_machine_regs.file - 1].directory_index - 1); + else + /* The directory index starts counting at 1. */ + printf ("\n%s/%s:\n", + directory_table[file_table[state_machine_regs.file - 1].directory_index - 1], + file_table[state_machine_regs.file - 1].name); + break; + + case DW_LNS_set_column: + uladv = read_uleb128 (data, & bytes_read, end); + data += bytes_read; + state_machine_regs.column = uladv; + break; + + case DW_LNS_negate_stmt: + adv = state_machine_regs.is_stmt; + adv = ! adv; + state_machine_regs.is_stmt = adv; + break; + + case DW_LNS_set_basic_block: + state_machine_regs.basic_block = 1; + break; + + case DW_LNS_const_add_pc: + uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range); + if (linfo.li_max_ops_per_insn == 1) + { + uladv *= linfo.li_min_insn_length; + state_machine_regs.address += uladv; + } + else + { + state_machine_regs.address + += ((state_machine_regs.op_index + uladv) + / linfo.li_max_ops_per_insn) + * linfo.li_min_insn_length; + state_machine_regs.op_index + = (state_machine_regs.op_index + uladv) + % linfo.li_max_ops_per_insn; + } + break; + + case DW_LNS_fixed_advance_pc: + SAFE_BYTE_GET_AND_INC (uladv, data, 2, end); + state_machine_regs.address += uladv; + state_machine_regs.op_index = 0; + break; + + case DW_LNS_set_prologue_end: + break; + + case DW_LNS_set_epilogue_begin: + break; + + case DW_LNS_set_isa: + uladv = read_uleb128 (data, & bytes_read, end); + data += bytes_read; + printf (_(" Set ISA to %lu\n"), uladv); + break; + + default: + printf (_(" Unknown opcode %d with operands: "), op_code); + + if (standard_opcodes != NULL) + for (i = standard_opcodes[op_code - 1]; i > 0 ; --i) + { + printf ("0x%s%s", dwarf_vmatoa ("x", read_uleb128 (data, + &bytes_read, end)), + i == 1 ? "" : ", "); + data += bytes_read; + } + putchar ('\n'); + break; + } /* Only Special opcodes, DW_LNS_copy and DW_LNE_end_sequence adds a row to the DWARF address/line matrix. */ @@ -3322,9 +3390,16 @@ display_debug_lines_decoded (struct dwarf_section *section, || (op_code == DW_LNS_copy)) { const unsigned int MAX_FILENAME_LENGTH = 35; - char *fileName = (char *)file_table[state_machine_regs.file - 1].name; + char *fileName; char *newFileName = NULL; - size_t fileNameLength = strlen (fileName); + size_t fileNameLength; + + if (file_table) + fileName = (char *) file_table[state_machine_regs.file - 1].name; + else + fileName = ""; + + fileNameLength = strlen (fileName); if ((fileNameLength > MAX_FILENAME_LENGTH) && (!do_wide)) { @@ -3371,10 +3446,21 @@ display_debug_lines_decoded (struct dwarf_section *section, free (newFileName); } } - free (file_table); - file_table = NULL; - free (directory_table); - directory_table = NULL; + + if (file_table) + { + free (file_table); + file_table = NULL; + n_files = 0; + } + + if (directory_table) + { + free (directory_table); + directory_table = NULL; + n_directories = 0; + } + putchar ('\n'); } @@ -3419,9 +3505,29 @@ find_debug_info_for_offset (unsigned long offset) return NULL; } +static const char * +get_gdb_index_symbol_kind_name (gdb_index_symbol_kind kind) +{ + /* See gdb/gdb-index.h. */ + static const char * const kinds[] = + { + N_ ("no info"), + N_ ("type"), + N_ ("variable"), + N_ ("function"), + N_ ("other"), + N_ ("unused5"), + N_ ("unused6"), + N_ ("unused7") + }; + + return _ (kinds[kind]); +} + static int -display_debug_pubnames (struct dwarf_section *section, - void *file ATTRIBUTE_UNUSED) +display_debug_pubnames_worker (struct dwarf_section *section, + void *file ATTRIBUTE_UNUSED, + int is_gnu) { DWARF2_Internal_PubNames names; unsigned char *start = section->start; @@ -3437,7 +3543,7 @@ display_debug_pubnames (struct dwarf_section *section, { unsigned char *data; unsigned long offset; - int offset_size, initial_length_size; + unsigned int offset_size, initial_length_size; data = start; @@ -3489,7 +3595,10 @@ display_debug_pubnames (struct dwarf_section *section, printf (_(" Size of area in .debug_info section: %ld\n"), (long) names.pn_size); - printf (_("\n Offset\tName\n")); + if (is_gnu) + printf (_("\n Offset Kind Name\n")); + else + printf (_("\n Offset\tName\n")); do { @@ -3498,7 +3607,29 @@ display_debug_pubnames (struct dwarf_section *section, if (offset != 0) { data += offset_size; - printf (" %-6lx\t%s\n", offset, data); + if (is_gnu) + { + unsigned int kind_data; + gdb_index_symbol_kind kind; + const char *kind_name; + int is_static; + + SAFE_BYTE_GET (kind_data, data, 1, end); + data++; + /* GCC computes the kind as the upper byte in the CU index + word, and then right shifts it by the CU index size. + Left shift KIND to where the gdb-index.h accessor macros + can use it. */ + kind_data <<= GDB_INDEX_CU_BITSIZE; + kind = GDB_INDEX_SYMBOL_KIND_VALUE (kind_data); + kind_name = get_gdb_index_symbol_kind_name (kind); + is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (kind_data); + printf (" %-6lx %s,%-10s %s\n", + offset, is_static ? _("s") : _("g"), + kind_name, data); + } + else + printf (" %-6lx\t%s\n", offset, data); data += strnlen ((char *) data, end - data) + 1; } } @@ -3509,6 +3640,18 @@ display_debug_pubnames (struct dwarf_section *section, return 1; } +static int +display_debug_pubnames (struct dwarf_section *section, void *file) +{ + return display_debug_pubnames_worker (section, file, 0); +} + +static int +display_debug_gnu_pubnames (struct dwarf_section *section, void *file) +{ + return display_debug_pubnames_worker (section, file, 1); +} + static int display_debug_macinfo (struct dwarf_section *section, void *file ATTRIBUTE_UNUSED) @@ -3720,7 +3863,7 @@ display_debug_macro (struct dwarf_section *section, dwarf_vma nargs, n; SAFE_BYTE_GET_AND_INC (count, curr, 1, end); - + memset (extended_op_buf, 0, sizeof (extended_op_buf)); extended_ops = extended_op_buf; if (count) @@ -4286,9 +4429,8 @@ display_debug_loc (struct dwarf_section *section, void *file) if (!seen_first_offset) error (_("No location lists in .debug_info section!\n")); - /* DWARF sections under Mach-O have non-zero addresses. */ if (debug_information [first].num_loc_offsets > 0 - && debug_information [first].loc_offsets [0] != section->address) + && debug_information [first].loc_offsets [0] != 0) warn (_("Location lists in %s section start at 0x%s\n"), section->name, dwarf_vmatoa ("x", debug_information [first].loc_offsets [0])); @@ -4323,8 +4465,7 @@ display_debug_loc (struct dwarf_section *section, void *file) == debug_information [i].loc_offsets [j]) continue; has_frame_base = debug_information [i].have_frame_base [j]; - /* DWARF sections under Mach-O have non-zero addresses. */ - offset = debug_information [i].loc_offsets [j] - section->address; + offset = debug_information [i].loc_offsets [j]; next = section_begin + offset; base_address = debug_information [i].base_address; @@ -4464,8 +4605,8 @@ display_debug_aranges (struct dwarf_section *section, dwarf_vma address; unsigned char address_size; int excess; - int offset_size; - int initial_length_size; + unsigned int offset_size; + unsigned int initial_length_size; hdrptr = start; @@ -4732,8 +4873,7 @@ display_debug_ranges (struct dwarf_section *section, qsort (range_entries, num_range_list, sizeof (*range_entries), range_entry_compar); - /* DWARF sections under Mach-O have non-zero addresses. */ - if (dwarf_check != 0 && range_entries[0].ranges_offset != section->address) + if (dwarf_check != 0 && range_entries[0].ranges_offset != 0) warn (_("Range lists in %s section start at 0x%lx\n"), section->name, range_entries[0].ranges_offset); @@ -4751,8 +4891,7 @@ display_debug_ranges (struct dwarf_section *section, pointer_size = debug_info_p->pointer_size; - /* DWARF sections under Mach-O have non-zero addresses. */ - offset = range_entry->ranges_offset - section->address; + offset = range_entry->ranges_offset; next = section_begin + offset; base_address = debug_info_p->base_address; @@ -4836,8 +4975,8 @@ typedef struct Frame_Chunk char *augmentation; unsigned int code_factor; int data_factor; - unsigned long pc_begin; - unsigned long pc_range; + dwarf_vma pc_begin; + dwarf_vma pc_range; int cfa_reg; int cfa_offset; int ra; @@ -4886,19 +5025,26 @@ frame_need_space (Frame_Chunk *fc, unsigned int reg) static const char *const dwarf_regnames_i386[] = { - "eax", "ecx", "edx", "ebx", - "esp", "ebp", "esi", "edi", - "eip", "eflags", NULL, - "st0", "st1", "st2", "st3", - "st4", "st5", "st6", "st7", - NULL, NULL, - "xmm0", "xmm1", "xmm2", "xmm3", - "xmm4", "xmm5", "xmm6", "xmm7", - "mm0", "mm1", "mm2", "mm3", - "mm4", "mm5", "mm6", "mm7", - "fcw", "fsw", "mxcsr", - "es", "cs", "ss", "ds", "fs", "gs", NULL, NULL, - "tr", "ldtr" + "eax", "ecx", "edx", "ebx", /* 0 - 3 */ + "esp", "ebp", "esi", "edi", /* 4 - 7 */ + "eip", "eflags", NULL, /* 8 - 10 */ + "st0", "st1", "st2", "st3", /* 11 - 14 */ + "st4", "st5", "st6", "st7", /* 15 - 18 */ + NULL, NULL, /* 19 - 20 */ + "xmm0", "xmm1", "xmm2", "xmm3", /* 21 - 24 */ + "xmm4", "xmm5", "xmm6", "xmm7", /* 25 - 28 */ + "mm0", "mm1", "mm2", "mm3", /* 29 - 32 */ + "mm4", "mm5", "mm6", "mm7", /* 33 - 36 */ + "fcw", "fsw", "mxcsr", /* 37 - 39 */ + "es", "cs", "ss", "ds", "fs", "gs", NULL, NULL, /* 40 - 47 */ + "tr", "ldtr", /* 48 - 49 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 50 - 57 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 58 - 65 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 66 - 73 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 74 - 81 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 82 - 89 */ + NULL, NULL, NULL, /* 90 - 92 */ + "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7" /* 93 - 100 */ }; void @@ -4927,7 +5073,17 @@ static const char *const dwarf_regnames_x86_64[] = "es", "cs", "ss", "ds", "fs", "gs", NULL, NULL, "fs.base", "gs.base", NULL, NULL, "tr", "ldtr", - "mxcsr", "fcw", "fsw" + "mxcsr", "fcw", "fsw", + "xmm16", "xmm17", "xmm18", "xmm19", + "xmm20", "xmm21", "xmm22", "xmm23", + "xmm24", "xmm25", "xmm26", "xmm27", + "xmm28", "xmm29", "xmm30", "xmm31", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 83 - 90 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 91 - 98 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 99 - 106 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 107 - 114 */ + NULL, NULL, NULL, /* 115 - 117 */ + "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7" }; void @@ -5005,7 +5161,7 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs) printf ("\n"); } - printf ("%0*lx ", eh_addr_size * 2, fc->pc_begin); + print_dwarf_vma (fc->pc_begin, eh_addr_size); if (fc->cfa_exp) strcpy (tmp, "exp"); else @@ -5075,16 +5231,16 @@ display_debug_frames (struct dwarf_section *section, { unsigned char *saved_start; unsigned char *block_end; - unsigned long length; - unsigned long cie_id; + dwarf_vma length; + dwarf_vma cie_id; Frame_Chunk *fc; Frame_Chunk *cie; int need_col_headers = 1; unsigned char *augmentation_data = NULL; unsigned long augmentation_data_len = 0; - int encoded_ptr_size = saved_eh_addr_size; - int offset_size; - int initial_length_size; + unsigned int encoded_ptr_size = saved_eh_addr_size; + unsigned int offset_size; + unsigned int initial_length_size; saved_start = start; @@ -5111,14 +5267,16 @@ display_debug_frames (struct dwarf_section *section, block_end = saved_start + length + initial_length_size; if (block_end > end) { - warn ("Invalid length %#08lx in FDE at %#08lx\n", - length, (unsigned long)(saved_start - section_start)); + warn ("Invalid length 0x%s in FDE at %#08lx\n", + dwarf_vmatoa_1 (NULL, length, offset_size), + (unsigned long) (saved_start - section_start)); block_end = end; } SAFE_BYTE_GET_AND_INC (cie_id, start, offset_size, end); - if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID)) + if (is_eh ? (cie_id == 0) : ((offset_size == 4 && cie_id == DW_CIE_ID) + || (offset_size == 8 && cie_id == DW64_CIE_ID))) { int version; @@ -5171,15 +5329,18 @@ display_debug_frames (struct dwarf_section *section, } cie = fc; + printf ("\n%08lx ", (unsigned long) (saved_start - section_start)); + print_dwarf_vma (length, fc->ptr_size); + print_dwarf_vma (cie_id, offset_size); + if (do_debug_frames_interp) - printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n", - (unsigned long)(saved_start - section_start), length, cie_id, - fc->augmentation, fc->code_factor, fc->data_factor, - fc->ra); + { + printf ("CIE \"%s\" cf=%d df=%d ra=%d\n", fc->augmentation, + fc->code_factor, fc->data_factor, fc->ra); + } else { - printf ("\n%08lx %08lx %08lx CIE\n", - (unsigned long)(saved_start - section_start), length, cie_id); + printf ("CIE\n"); printf (" Version: %d\n", version); printf (" Augmentation: \"%s\"\n", fc->augmentation); if (version >= 4) @@ -5246,8 +5407,9 @@ display_debug_frames (struct dwarf_section *section, if (!cie) { - warn ("Invalid CIE pointer %#08lx in FDE at %#08lx\n", - cie_id, (unsigned long)(saved_start - section_start)); + warn ("Invalid CIE pointer 0x%s in FDE at %#08lx\n", + dwarf_vmatoa_1 (NULL, cie_id, offset_size), + (unsigned long) (saved_start - section_start)); fc->ncols = 0; fc->col_type = (short int *) xmalloc (sizeof (short int)); fc->col_offset = (int *) xmalloc (sizeof (int)); @@ -5294,7 +5456,7 @@ display_debug_frames (struct dwarf_section *section, run of the "objcopy on compressed debug sections" test for an example of this. */ SAFE_BYTE_GET_AND_INC (fc->pc_range, start, encoded_ptr_size, end); - + if (cie->augmentation[0] == 'z') { augmentation_data_len = LEB (); @@ -5302,12 +5464,19 @@ display_debug_frames (struct dwarf_section *section, start += augmentation_data_len; } - printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=", - (unsigned long)(saved_start - section_start), length, cie_id, + printf ("\n%08lx %s %s FDE cie=%08lx pc=", + (unsigned long)(saved_start - section_start), + dwarf_vmatoa_1 (NULL, length, fc->ptr_size), + dwarf_vmatoa_1 (NULL, cie_id, offset_size), (unsigned long)(cie->chunk_start - section_start)); + if (fc->segment_size) printf ("%04lx:", segment_selector); - printf ("%08lx..%08lx\n", fc->pc_begin, fc->pc_begin + fc->pc_range); + + printf ("%s..%s\n", + dwarf_vmatoa_1 (NULL, fc->pc_begin, fc->ptr_size), + dwarf_vmatoa_1 (NULL, fc->pc_begin + fc->pc_range, fc->ptr_size)); + if (! do_debug_frames_interp && augmentation_data_len) { unsigned long i; @@ -5455,7 +5624,8 @@ display_debug_frames (struct dwarf_section *section, { unsigned op, opa; unsigned long ul, reg, roffs; - long l, ofs; + long l; + dwarf_vma ofs; dwarf_vma vma; const char *reg_prefix = ""; @@ -5472,9 +5642,11 @@ display_debug_frames (struct dwarf_section *section, if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_advance_loc: %d to %08lx\n", + printf (" DW_CFA_advance_loc: %d to %s\n", opa * fc->code_factor, - fc->pc_begin + opa * fc->code_factor); + dwarf_vmatoa_1 (NULL, + fc->pc_begin + opa * fc->code_factor, + fc->ptr_size)); fc->pc_begin += opa * fc->code_factor; break; @@ -5516,7 +5688,8 @@ display_debug_frames (struct dwarf_section *section, if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_set_loc: %08lx\n", (unsigned long)vma); + printf (" DW_CFA_set_loc: %s\n", + dwarf_vmatoa_1 (NULL, vma, fc->ptr_size)); fc->pc_begin = vma; break; @@ -5525,9 +5698,11 @@ display_debug_frames (struct dwarf_section *section, if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_advance_loc1: %ld to %08lx\n", - ofs * fc->code_factor, - fc->pc_begin + ofs * fc->code_factor); + printf (" DW_CFA_advance_loc1: %ld to %s\n", + (unsigned long) (ofs * fc->code_factor), + dwarf_vmatoa_1 (NULL, + fc->pc_begin + ofs * fc->code_factor, + fc->ptr_size)); fc->pc_begin += ofs * fc->code_factor; break; @@ -5536,9 +5711,11 @@ display_debug_frames (struct dwarf_section *section, if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_advance_loc2: %ld to %08lx\n", - ofs * fc->code_factor, - fc->pc_begin + ofs * fc->code_factor); + printf (" DW_CFA_advance_loc2: %ld to %s\n", + (unsigned long) (ofs * fc->code_factor), + dwarf_vmatoa_1 (NULL, + fc->pc_begin + ofs * fc->code_factor, + fc->ptr_size)); fc->pc_begin += ofs * fc->code_factor; break; @@ -5547,9 +5724,11 @@ display_debug_frames (struct dwarf_section *section, if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_advance_loc4: %ld to %08lx\n", - ofs * fc->code_factor, - fc->pc_begin + ofs * fc->code_factor); + printf (" DW_CFA_advance_loc4: %ld to %s\n", + (unsigned long) (ofs * fc->code_factor), + dwarf_vmatoa_1 (NULL, + fc->pc_begin + ofs * fc->code_factor, + fc->ptr_size)); fc->pc_begin += ofs * fc->code_factor; break; @@ -5650,12 +5829,16 @@ display_debug_frames (struct dwarf_section *section, if (! do_debug_frames_interp) printf (" DW_CFA_remember_state\n"); rs = (Frame_Chunk *) xmalloc (sizeof (Frame_Chunk)); + rs->cfa_offset = fc->cfa_offset; + rs->cfa_reg = fc->cfa_reg; + rs->ra = fc->ra; + rs->cfa_exp = fc->cfa_exp; rs->ncols = fc->ncols; rs->col_type = (short int *) xcmalloc (rs->ncols, - sizeof (short int)); - rs->col_offset = (int *) xcmalloc (rs->ncols, sizeof (int)); - memcpy (rs->col_type, fc->col_type, rs->ncols); - memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int)); + sizeof (* rs->col_type)); + rs->col_offset = (int *) xcmalloc (rs->ncols, sizeof (* rs->col_offset)); + memcpy (rs->col_type, fc->col_type, rs->ncols * sizeof (* fc->col_type)); + memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (* fc->col_offset)); rs->next = remembered_state; remembered_state = rs; break; @@ -5667,10 +5850,14 @@ display_debug_frames (struct dwarf_section *section, if (rs) { remembered_state = rs->next; + fc->cfa_offset = rs->cfa_offset; + fc->cfa_reg = rs->cfa_reg; + fc->ra = rs->ra; + fc->cfa_exp = rs->cfa_exp; frame_need_space (fc, rs->ncols - 1); - memcpy (fc->col_type, rs->col_type, rs->ncols); + memcpy (fc->col_type, rs->col_type, rs->ncols * sizeof (* rs->col_type)); memcpy (fc->col_offset, rs->col_offset, - rs->ncols * sizeof (int)); + rs->ncols * sizeof (* rs->col_offset)); free (rs->col_type); free (rs->col_offset); free (rs); @@ -5810,9 +5997,11 @@ display_debug_frames (struct dwarf_section *section, if (do_debug_frames_interp) frame_display_row (fc, &need_col_headers, &max_regs); else - printf (" DW_CFA_MIPS_advance_loc8: %ld to %08lx\n", - ofs * fc->code_factor, - fc->pc_begin + ofs * fc->code_factor); + printf (" DW_CFA_MIPS_advance_loc8: %ld to %s\n", + (unsigned long) (ofs * fc->code_factor), + dwarf_vmatoa_1 (NULL, + fc->pc_begin + ofs * fc->code_factor, + fc->ptr_size)); fc->pc_begin += ofs * fc->code_factor; break; @@ -6011,38 +6200,9 @@ display_gdb_index (struct dwarf_section *section, else printf ("%c%lu", num_cus > 1 ? '\t' : ' ', (unsigned long) cu); - switch (kind) - { - case GDB_INDEX_SYMBOL_KIND_NONE: - printf (_(" [no symbol information]")); - break; - case GDB_INDEX_SYMBOL_KIND_TYPE: - printf (is_static - ? _(" [static type]") - : _(" [global type]")); - break; - case GDB_INDEX_SYMBOL_KIND_VARIABLE: - printf (is_static - ? _(" [static variable]") - : _(" [global variable]")); - break; - case GDB_INDEX_SYMBOL_KIND_FUNCTION: - printf (is_static - ? _(" [static function]") - : _(" [global function]")); - break; - case GDB_INDEX_SYMBOL_KIND_OTHER: - printf (is_static - ? _(" [static other]") - : _(" [global other]")); - break; - default: - printf (is_static - ? _(" [static unknown: %d]") - : _(" [global unknown: %d]"), - kind); - break; - } + printf (" [%s, %s]", + is_static ? _("static") : _("global"), + get_gdb_index_symbol_kind_name (kind)); if (num_cus > 1) printf ("\n"); } @@ -6666,6 +6826,8 @@ struct dwarf_section_display debug_displays[] = display_debug_lines, &do_debug_lines, 1 }, { { ".debug_pubnames", ".zdebug_pubnames", NULL, NULL, 0, 0, 0 }, display_debug_pubnames, &do_debug_pubnames, 0 }, + { { ".debug_gnu_pubnames", ".zdebug_gnu_pubnames", NULL, NULL, 0, 0, 0 }, + display_debug_gnu_pubnames, &do_debug_pubnames, 0 }, { { ".eh_frame", "", NULL, NULL, 0, 0, 0 }, display_debug_frames, &do_debug_frames, 1 }, { { ".debug_macinfo", ".zdebug_macinfo", NULL, NULL, 0, 0, 0 }, @@ -6678,6 +6840,8 @@ struct dwarf_section_display debug_displays[] = display_debug_loc, &do_debug_loc, 1 }, { { ".debug_pubtypes", ".zdebug_pubtypes", NULL, NULL, 0, 0, 0 }, display_debug_pubnames, &do_debug_pubtypes, 0 }, + { { ".debug_gnu_pubtypes", ".zdebug_gnu_pubtypes", NULL, NULL, 0, 0, 0 }, + display_debug_gnu_pubnames, &do_debug_pubtypes, 0 }, { { ".debug_ranges", ".zdebug_ranges", NULL, NULL, 0, 0, 0 }, display_debug_ranges, &do_debug_ranges, 1 }, { { ".debug_static_func", ".zdebug_static_func", NULL, NULL, 0, 0, 0 },