X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=binutils%2Fdwarf.c;h=08febadf5504ed61b79c79220e8fa0e94a279e7e;hb=7a9068fe16462c35cdccd371fe588111dd1866ea;hp=102d1642dcea769fef3550ebe53427cff81caa6f;hpb=49e7b350197b0b63e4996247872da3bc86a2dc16;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 102d1642dc..08febadf55 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -63,6 +63,9 @@ int do_trace_abbrevs; int do_trace_aranges; int do_wide; +int dwarf_cutoff_level = -1; +unsigned long dwarf_start_die; + /* Values for do_debug_lines. */ #define FLAG_DEBUG_LINES_RAW 1 #define FLAG_DEBUG_LINES_DECODED 2 @@ -324,16 +327,71 @@ process_extended_line_op (unsigned char *data, int is_stmt) case DW_LNE_HP_define_proc: printf ("DW_LNE_HP_define_proc\n"); break; + case DW_LNE_HP_source_file_correlation: + { + unsigned char *edata = data + len - bytes_read - 1; + + printf ("DW_LNE_HP_source_file_correlation\n"); + + while (data < edata) + { + unsigned int opc; + + opc = read_leb128 (data, & bytes_read, 0); + data += bytes_read; + + switch (opc) + { + case DW_LNE_HP_SFC_formfeed: + printf (" DW_LNE_HP_SFC_formfeed\n"); + break; + case DW_LNE_HP_SFC_set_listing_line: + printf (" DW_LNE_HP_SFC_set_listing_line (%s)\n", + dwarf_vmatoa ("u", + read_leb128 (data, & bytes_read, 0))); + data += bytes_read; + break; + case DW_LNE_HP_SFC_associate: + printf (" DW_LNE_HP_SFC_associate "); + printf (_("(%s"), + dwarf_vmatoa ("u", + read_leb128 (data, & bytes_read, 0))); + data += bytes_read; + printf (_(",%s"), + dwarf_vmatoa ("u", + read_leb128 (data, & bytes_read, 0))); + data += bytes_read; + printf (_(",%s)\n"), + dwarf_vmatoa ("u", + read_leb128 (data, & bytes_read, 0))); + data += bytes_read; + break; + default: + printf (" UNKNOW DW_LNE_HP_SFC opcode (%u)\n", opc); + data = edata; + break; + } + } + } + break; default: - if (op_code >= DW_LNE_lo_user - /* The test against DW_LNW_hi_user is redundant due to - the limited range of the unsigned char data type used - for op_code. */ - /*&& op_code <= DW_LNE_hi_user*/) - printf (_("user defined: length %d\n"), len - bytes_read); - else - printf (_("UNKNOWN: length %d\n"), len - bytes_read); + { + unsigned int rlen = len - bytes_read - 1; + + if (op_code >= DW_LNE_lo_user + /* The test against DW_LNW_hi_user is redundant due to + the limited range of the unsigned char data type used + for op_code. */ + /*&& op_code <= DW_LNE_hi_user*/) + printf (_("user defined: ")); + else + printf (_("UNKNOWN: ")); + printf (_("length %d ["), rlen); + for (; rlen; rlen--) + printf (" %02x", *data++); + printf ("]\n"); + } break; } @@ -674,8 +732,8 @@ decode_location_expression (unsigned char * data, switch (op) { case DW_OP_addr: - printf ("DW_OP_addr: %lx", - (unsigned long) byte_get (data, pointer_size)); + printf ("DW_OP_addr: %s", + dwarf_vmatoa ("x", byte_get (data, pointer_size))); data += pointer_size; break; case DW_OP_deref: @@ -1034,17 +1092,6 @@ decode_location_expression (unsigned char * data, display_block (data, uvalue); data += uvalue; break; - case DW_OP_GNU_entry_value: - uvalue = read_leb128 (data, &bytes_read, 0); - data += bytes_read; - printf ("DW_OP_GNU_entry_value: ("); - if (decode_location_expression (data, pointer_size, offset_size, - dwarf_version, uvalue, - cu_offset, section)) - need_frame_base = 1; - putchar (')'); - data += uvalue; - break; /* GNU extensions. */ case DW_OP_GNU_push_tls_address: @@ -1093,6 +1140,58 @@ decode_location_expression (unsigned char * data, data += offset_size + bytes_read; } break; + case DW_OP_GNU_entry_value: + uvalue = read_leb128 (data, &bytes_read, 0); + data += bytes_read; + printf ("DW_OP_GNU_entry_value: ("); + if (decode_location_expression (data, pointer_size, offset_size, + dwarf_version, uvalue, + cu_offset, section)) + need_frame_base = 1; + putchar (')'); + data += uvalue; + break; + case DW_OP_GNU_const_type: + uvalue = read_leb128 (data, &bytes_read, 0); + data += bytes_read; + printf ("DW_OP_GNU_const_type: <0x%s> ", + dwarf_vmatoa ("x", cu_offset + uvalue)); + uvalue = byte_get (data++, 1); + display_block (data, uvalue); + data += uvalue; + break; + case DW_OP_GNU_regval_type: + uvalue = read_leb128 (data, &bytes_read, 0); + data += bytes_read; + printf ("DW_OP_GNU_regval_type: %s (%s)", + dwarf_vmatoa ("u", uvalue), regname (uvalue, 1)); + uvalue = read_leb128 (data, &bytes_read, 0); + data += bytes_read; + printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue)); + break; + case DW_OP_GNU_deref_type: + printf ("DW_OP_GNU_deref_type: %ld", (long) byte_get (data++, 1)); + uvalue = read_leb128 (data, &bytes_read, 0); + data += bytes_read; + printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue)); + break; + case DW_OP_GNU_convert: + uvalue = read_leb128 (data, &bytes_read, 0); + data += bytes_read; + printf ("DW_OP_GNU_convert <0x%s>", + dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0)); + break; + case DW_OP_GNU_reinterpret: + uvalue = read_leb128 (data, &bytes_read, 0); + data += bytes_read; + printf ("DW_OP_GNU_reinterpret <0x%s>", + dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0)); + break; + case DW_OP_GNU_parameter_ref: + printf ("DW_OP_GNU_parameter_ref: <0x%s>", + dwarf_vmatoa ("x", cu_offset + byte_get (data, 4))); + data += 4; + break; /* HP extensions. */ case DW_OP_HP_is_value: @@ -1367,7 +1466,8 @@ read_and_display_attr_value (unsigned long attribute, } if ((do_loc || do_debug_loc || do_debug_ranges) - && num_debug_info_entries == 0) + && num_debug_info_entries == 0 + && debug_info_p != NULL) { switch (attribute) { @@ -1926,7 +2026,7 @@ process_debug_info (struct dwarf_section *section, && num_debug_info_entries == 0 && ! do_types) { - unsigned long length; + dwarf_vma length; /* First scan the section to get the number of comp units. */ for (section_begin = start, num_units = 0; section_begin < end; @@ -1944,7 +2044,8 @@ process_debug_info (struct dwarf_section *section, } else if (length >= 0xfffffff0 && length < 0xffffffff) { - warn (_("Reserved length value (%lx) found in section %s\n"), length, section->name); + warn (_("Reserved length value (0x%s) found in section %s\n"), + dwarf_vmatoa ("x", length), section->name); return 0; } else @@ -1955,7 +2056,8 @@ process_debug_info (struct dwarf_section *section, relocations to an object file. */ if ((signed long) length <= 0) { - warn (_("Corrupt unit length (%lx) found in section %s\n"), length, section->name); + warn (_("Corrupt unit length (0x%s) found in section %s\n"), + dwarf_vmatoa ("x", length), section->name); return 0; } } @@ -1979,7 +2081,8 @@ process_debug_info (struct dwarf_section *section, if (!do_loc) { - printf (_("Contents of the %s section:\n\n"), section->name); + if (dwarf_start_die == 0) + printf (_("Contents of the %s section:\n\n"), section->name); load_debug_section (str, file); } @@ -1997,12 +2100,12 @@ process_debug_info (struct dwarf_section *section, DWARF2_Internal_CompUnit compunit; unsigned char *hdrptr; unsigned char *tags; - int level; + int level, last_level, saved_level; dwarf_vma cu_offset; int offset_size; int initial_length_size; unsigned char signature[8] = { 0 }; - unsigned long type_offset = 0; + dwarf_vma type_offset = 0; hdrptr = start; @@ -2066,7 +2169,7 @@ process_debug_info (struct dwarf_section *section, debug_information [unit].num_range_lists = 0; } - if (!do_loc) + if (!do_loc && dwarf_start_die == 0) { printf (_(" Compilation Unit @ offset 0x%s:\n"), dwarf_vmatoa ("x", cu_offset)); @@ -2084,7 +2187,8 @@ process_debug_info (struct dwarf_section *section, for (i = 0; i < 8; i++) printf ("%02x", signature[i]); printf ("\n"); - printf (_(" Type Offset: 0x%lx\n"), type_offset); + printf (_(" Type Offset: 0x%s\n"), + dwarf_vmatoa ("x", type_offset)); } } @@ -2126,6 +2230,8 @@ process_debug_info (struct dwarf_section *section, + debug_displays [abbrev_sec].section.size); level = 0; + last_level = level; + saved_level = -1; while (tags < start) { unsigned int bytes_read; @@ -2133,6 +2239,7 @@ process_debug_info (struct dwarf_section *section, unsigned long die_offset; abbrev_entry *entry; abbrev_attr *attr; + int do_printing = 1; die_offset = tags - section_begin; @@ -2169,12 +2276,30 @@ process_debug_info (struct dwarf_section *section, warn (_("Further warnings about bogus end-of-sibling markers suppressed\n")); } } + if (dwarf_start_die != 0 && level < saved_level) + return 1; continue; } if (!do_loc) - printf (_(" <%d><%lx>: Abbrev Number: %lu"), - level, die_offset, abbrev_number); + { + if (dwarf_start_die != 0 && die_offset < dwarf_start_die) + do_printing = 0; + else + { + if (dwarf_start_die != 0 && die_offset == dwarf_start_die) + saved_level = level; + do_printing = (dwarf_cutoff_level == -1 + || level < dwarf_cutoff_level); + if (do_printing) + printf (_(" <%d><%lx>: Abbrev Number: %lu"), + level, die_offset, abbrev_number); + else if (dwarf_cutoff_level == -1 + || last_level < dwarf_cutoff_level) + printf (_(" <%d><%lx>: ...\n"), level, die_offset); + last_level = level; + } + } /* Scan through the abbreviation list until we reach the correct entry. */ @@ -2185,7 +2310,7 @@ process_debug_info (struct dwarf_section *section, if (entry == NULL) { - if (!do_loc) + if (!do_loc && do_printing) { printf ("\n"); fflush (stdout); @@ -2195,7 +2320,7 @@ process_debug_info (struct dwarf_section *section, return 0; } - if (!do_loc) + if (!do_loc && do_printing) printf (" (%s)\n", get_TAG_name (entry->tag)); switch (entry->tag) @@ -2216,9 +2341,15 @@ process_debug_info (struct dwarf_section *section, for (attr = entry->first_attr; attr; attr = attr->next) { - if (! do_loc) + debug_info *arg; + + if (! do_loc && do_printing) /* Show the offset from where the tag was extracted. */ - printf (" <%2lx>", (unsigned long)(tags - section_begin)); + printf (" <%lx>", (unsigned long)(tags - section_begin)); + + arg = debug_information; + if (debug_information) + arg += unit; tags = read_and_display_attr (attr->attribute, attr->form, @@ -2226,8 +2357,8 @@ process_debug_info (struct dwarf_section *section, compunit.cu_pointer_size, offset_size, compunit.cu_version, - debug_information + unit, - do_loc, section); + arg, + do_loc || ! do_printing, section); } if (entry->children) @@ -3362,6 +3493,19 @@ display_debug_abbrev (struct dwarf_section *section, return 1; } +/* Sort array of indexes in ascending order of loc_offsets[idx]. */ + +static dwarf_vma *loc_offsets; + +static int +loc_offsets_compar (const void *ap, const void *bp) +{ + dwarf_vma a = loc_offsets[*(const unsigned int *) ap]; + dwarf_vma b = loc_offsets[*(const unsigned int *) bp]; + + return (a > b) - (b > a); +} + static int display_debug_loc (struct dwarf_section *section, void *file) { @@ -3374,9 +3518,11 @@ display_debug_loc (struct dwarf_section *section, void *file) unsigned int first = 0; unsigned int i; unsigned int j; + unsigned int k; int seen_first_offset = 0; - int use_debug_info = 1; + int locs_sorted = 1; unsigned char *next; + unsigned int *array = NULL; bytes = section->size; section_end = start + bytes; @@ -3402,10 +3548,11 @@ display_debug_loc (struct dwarf_section *section, void *file) unsigned int num; num = debug_information [i].num_loc_offsets; - num_loc_list += num; + if (num > num_loc_list) + num_loc_list = num; /* Check if we can use `debug_information' directly. */ - if (use_debug_info && num != 0) + if (locs_sorted && num != 0) { if (!seen_first_offset) { @@ -3423,7 +3570,7 @@ display_debug_loc (struct dwarf_section *section, void *file) if (last_offset > debug_information [i].loc_offsets [j]) { - use_debug_info = 0; + locs_sorted = 0; break; } last_offset = debug_information [i].loc_offsets [j]; @@ -3431,10 +3578,6 @@ display_debug_loc (struct dwarf_section *section, void *file) } } - if (!use_debug_info) - /* FIXME: Should we handle this case? */ - error (_("Location lists in .debug_info section aren't in ascending order!\n")); - if (!seen_first_offset) error (_("No location lists in .debug_info section!\n")); @@ -3445,6 +3588,8 @@ display_debug_loc (struct dwarf_section *section, void *file) section->name, dwarf_vmatoa ("x", debug_information [first].loc_offsets [0])); + if (!locs_sorted) + array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int)); printf (_("Contents of the %s section:\n\n"), section->name); printf (_(" Offset Begin End Expression\n")); @@ -3467,9 +3612,23 @@ display_debug_loc (struct dwarf_section *section, void *file) cu_offset = debug_information [i].cu_offset; offset_size = debug_information [i].offset_size; dwarf_version = debug_information [i].dwarf_version; + if (!locs_sorted) + { + for (k = 0; k < debug_information [i].num_loc_offsets; k++) + array[k] = k; + loc_offsets = debug_information [i].loc_offsets; + qsort (array, debug_information [i].num_loc_offsets, + sizeof (*array), loc_offsets_compar); + } - for (j = 0; j < debug_information [i].num_loc_offsets; j++) + for (k = 0; k < debug_information [i].num_loc_offsets; k++) { + j = locs_sorted ? k : array[k]; + if (k + && debug_information [i].loc_offsets [locs_sorted + ? k - 1 : array [k - 1]] + == 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; @@ -3583,6 +3742,7 @@ display_debug_loc (struct dwarf_section *section, void *file) warn (_("There are %ld unused bytes at the end of section %s\n"), (long) (section_end - start), section->name); putchar ('\n'); + free (array); return 1; } @@ -4073,6 +4233,7 @@ init_dwarf_regnames (unsigned int e_machine) case EM_X86_64: case EM_L1OM: + case EM_K1OM: init_dwarf_regnames_x86_64 (); break; @@ -5020,6 +5181,9 @@ display_gdb_index (struct dwarf_section *section, warn (_("The address table data in version 3 may be wrong.\n")); break; case 4: + warn (_("Version 4 does not support case insensitive lookups.\n")); + break; + case 5: break; default: warn (_("Unsupported version %lu.\n"), (unsigned long) version); @@ -5108,8 +5272,8 @@ display_gdb_index (struct dwarf_section *section, { cu = byte_get_little_endian (constant_pool + cu_vector_offset + 4 + j * 4, 4); /* Convert to TU number if it's for a type unit. */ - if (cu >= cu_list_elements) - printf (" T%lu", (unsigned long) (cu - cu_list_elements)); + if (cu >= cu_list_elements / 2) + printf (" T%lu", (unsigned long) (cu - cu_list_elements / 2)); else printf (" %lu", (unsigned long) cu); }