aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog13
-rw-r--r--binutils/dwarf.c112
-rw-r--r--binutils/readelf.c3
3 files changed, 112 insertions, 16 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 8df97ef..71df175 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,16 @@
+2009-09-24 Cary Coutant <ccoutant@google.com>
+
+ * dwarf.c (get_TAG_name): Add missing DWARF-3 and new DWARF-4 tags.
+ (get_FORM_name): Add new DWARF-4 forms.
+ (read_and_display_attr_value): Add DW_FORM_ref_sig8, DW_LANG_Python.
+ (get_AT_name): Add new DWARF-4 and GNU-specific attributes.
+ (process_debug_info): Add do_types parameter; change all callers.
+ Add support for .debug_types sections.
+ (display_debug_types): New function.
+ (debug_displays): Add .debug_types section.
+ * readelf.c (process_section_headers): Add .debug_types section.
+ (display_debug_section): Simplify call to streq.
+
2009-09-25 Alan Modra <amodra@bigpond.net.au>
* readelf.c (print_dynamic_symbol): Format entries as for
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 5eeef08..ac37538 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -628,6 +628,12 @@ get_TAG_name (unsigned long tag)
case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
+ case DW_TAG_condition: return "DW_TAG_condition";
+ case DW_TAG_shared_type: return "DW_TAG_shared_type";
+ /* DWARF 4 values. */
+ case DW_TAG_type_unit: return "DW_TAG_type_unit";
+ case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type";
+ case DW_TAG_template_alias: return "DW_TAG_template_alias";
/* UPC values. */
case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
@@ -668,6 +674,11 @@ get_FORM_name (unsigned long form)
case DW_FORM_ref8: return "DW_FORM_ref8";
case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
case DW_FORM_indirect: return "DW_FORM_indirect";
+ /* DWARF 4 values. */
+ case DW_FORM_sec_offset: return "DW_FORM_sec_offset";
+ case DW_FORM_exprloc: return "DW_FORM_exprloc";
+ case DW_FORM_flag_present: return "DW_FORM_flag_present";
+ case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8";
default:
{
static char buffer[100];
@@ -1305,6 +1316,21 @@ read_and_display_attr_value (unsigned long attribute,
/* Handled above. */
break;
+ case DW_FORM_ref_sig8:
+ if (!do_loc)
+ {
+ int i;
+ printf (" signature: ");
+ for (i = 0; i < 8; i++)
+ {
+ printf ("%02x", (unsigned) byte_get (data, 1));
+ data += 1;
+ }
+ }
+ else
+ data += 8;
+ break;
+
default:
warn (_("Unrecognized form: %lu\n"), form);
break;
@@ -1432,6 +1458,8 @@ read_and_display_attr_value (unsigned long attribute,
case DW_LANG_ObjC_plus_plus: printf ("(Objective C++)"); break;
case DW_LANG_UPC: printf ("(Unified Parallel C)"); break;
case DW_LANG_D: printf ("(D)"); break;
+ /* DWARF 4 values. */
+ case DW_LANG_Python: printf ("(Python)"); break;
/* MIPS extension. */
case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
/* UPC extension. */
@@ -1588,6 +1616,9 @@ read_and_display_attr_value (unsigned long attribute,
case DW_AT_import:
{
+ if (form == DW_FORM_ref_sig8)
+ break;
+
if (form == DW_FORM_ref1
|| form == DW_FORM_ref2
|| form == DW_FORM_ref4)
@@ -1716,6 +1747,13 @@ get_AT_name (unsigned long attribute)
case DW_AT_elemental: return "DW_AT_elemental";
case DW_AT_pure: return "DW_AT_pure";
case DW_AT_recursive: return "DW_AT_recursive";
+ /* DWARF 4 values. */
+ case DW_AT_signature: return "DW_AT_signature";
+ case DW_AT_main_subprogram: return "DW_AT_main_subprogram";
+ case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset";
+ case DW_AT_const_expr: return "DW_AT_const_expr";
+ case DW_AT_enum_class: return "DW_AT_enum_class";
+ case DW_AT_linkage_name: return "DW_AT_linkage_name";
/* HP and SGI/MIPS extensions. */
case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
@@ -1748,13 +1786,21 @@ get_AT_name (unsigned long attribute)
case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde or DW_AT_HP_unmodifiable";
/* GNU extensions. */
- case DW_AT_sf_names: return "DW_AT_sf_names";
- case DW_AT_src_info: return "DW_AT_src_info";
- case DW_AT_mac_info: return "DW_AT_mac_info";
- case DW_AT_src_coords: return "DW_AT_src_coords";
- case DW_AT_body_begin: return "DW_AT_body_begin";
- case DW_AT_body_end: return "DW_AT_body_end";
- case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
+ case DW_AT_sf_names: return "DW_AT_sf_names";
+ case DW_AT_src_info: return "DW_AT_src_info";
+ case DW_AT_mac_info: return "DW_AT_mac_info";
+ case DW_AT_src_coords: return "DW_AT_src_coords";
+ case DW_AT_body_begin: return "DW_AT_body_begin";
+ case DW_AT_body_end: return "DW_AT_body_end";
+ case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
+ case DW_AT_GNU_guarded_by: return "DW_AT_GNU_guarded_by";
+ case DW_AT_GNU_pt_guarded_by: return "DW_AT_GNU_pt_guarded_by";
+ case DW_AT_GNU_guarded: return "DW_AT_GNU_guarded";
+ case DW_AT_GNU_pt_guarded: return "DW_AT_GNU_pt_guarded";
+ case DW_AT_GNU_locks_excluded: return "DW_AT_GNU_locks_excluded";
+ case DW_AT_GNU_exclusive_locks_required: return "DW_AT_GNU_exclusive_locks_required";
+ case DW_AT_GNU_shared_locks_required: return "DW_AT_GNU_shared_locks_required";
+ case DW_AT_GNU_odr_signature: return "DW_AT_GNU_odr_signature";
/* UPC extension. */
case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
@@ -1801,12 +1847,14 @@ read_and_display_attr (unsigned long attribute,
/* Process the contents of a .debug_info section. If do_loc is non-zero
then we are scanning for location lists and we do not want to display
- anything to the user. */
+ anything to the user. If do_types is non-zero, we are processing
+ a .debug_types section instead of a .debug_info section. */
static int
process_debug_info (struct dwarf_section *section,
void *file,
- int do_loc)
+ int do_loc,
+ int do_types)
{
unsigned char *start = section->start;
unsigned char *end = start + section->size;
@@ -1815,7 +1863,8 @@ process_debug_info (struct dwarf_section *section,
unsigned int num_units = 0;
if ((do_loc || do_debug_loc || do_debug_ranges)
- && num_debug_info_entries == 0)
+ && num_debug_info_entries == 0
+ && ! do_types)
{
unsigned long length;
@@ -1893,6 +1942,8 @@ process_debug_info (struct dwarf_section *section,
unsigned long cu_offset;
int offset_size;
int initial_length_size;
+ unsigned char signature[8];
+ unsigned long type_offset = 0;
hdrptr = start;
@@ -1923,8 +1974,24 @@ process_debug_info (struct dwarf_section *section,
compunit.cu_pointer_size = byte_get (hdrptr, 1);
hdrptr += 1;
+
+ if (do_types)
+ {
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ signature[i] = byte_get (hdrptr, 1);
+ hdrptr += 1;
+ }
+
+ type_offset = byte_get (hdrptr, offset_size);
+ hdrptr += offset_size;
+ }
+
if ((do_loc || do_debug_loc || do_debug_ranges)
- && num_debug_info_entries == 0)
+ && num_debug_info_entries == 0
+ && ! do_types)
{
debug_information [unit].cu_offset = cu_offset;
debug_information [unit].pointer_size
@@ -1947,6 +2014,15 @@ process_debug_info (struct dwarf_section *section,
printf (_(" Version: %d\n"), compunit.cu_version);
printf (_(" Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
printf (_(" Pointer Size: %d\n"), compunit.cu_pointer_size);
+ if (do_types)
+ {
+ int i;
+ printf (_(" Signature: "));
+ for (i = 0; i < 8; i++)
+ printf ("%02x", signature[i]);
+ printf ("\n");
+ printf (_(" Type Offset: 0x%lx\n"), type_offset);
+ }
}
if (cu_offset + compunit.cu_length + initial_length_size
@@ -2094,7 +2170,8 @@ process_debug_info (struct dwarf_section *section,
/* Set num_debug_info_entries here so that it can be used to check if
we need to process .debug_loc and .debug_ranges sections. */
if ((do_loc || do_debug_loc || do_debug_ranges)
- && num_debug_info_entries == 0)
+ && num_debug_info_entries == 0
+ && ! do_types)
num_debug_info_entries = num_units;
if (!do_loc)
@@ -2129,7 +2206,7 @@ load_debug_info (void * file)
return num_debug_info_entries;
if (load_debug_section (info, file)
- && process_debug_info (&debug_displays [info].section, file, 1))
+ && process_debug_info (&debug_displays [info].section, file, 1, 0))
return num_debug_info_entries;
num_debug_info_entries = DEBUG_INFO_UNAVAILABLE;
@@ -3360,9 +3437,14 @@ display_debug_str (struct dwarf_section *section,
static int
display_debug_info (struct dwarf_section *section, void *file)
{
- return process_debug_info (section, file, 0);
+ return process_debug_info (section, file, 0, 0);
}
+static int
+display_debug_types (struct dwarf_section *section, void *file)
+{
+ return process_debug_info (section, file, 0, 1);
+}
static int
display_debug_aranges (struct dwarf_section *section,
@@ -4937,7 +5019,7 @@ struct dwarf_section_display debug_displays[] =
{ { ".debug_static_vars", ".zdebug_static_vars", NULL, NULL, 0, 0 },
display_debug_not_supported, NULL, 0 },
{ { ".debug_types", ".zdebug_types", NULL, NULL, 0, 0 },
- display_debug_not_supported, NULL, 0 },
+ display_debug_types, &do_debug_info, 1 },
{ { ".debug_weaknames", ".zdebug_weaknames", NULL, NULL, 0, 0 },
display_debug_not_supported, NULL, 0 }
};
diff --git a/binutils/readelf.c b/binutils/readelf.c
index edd5a2e..425161c 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -4276,6 +4276,7 @@ process_section_headers (FILE * file)
if (do_debugging
|| (do_debug_info && streq (name, "info"))
+ || (do_debug_info && streq (name, "types"))
|| (do_debug_abbrevs && streq (name, "abbrev"))
|| (do_debug_lines && streq (name, "line"))
|| (do_debug_pubnames && streq (name, "pubnames"))
@@ -8817,7 +8818,7 @@ display_debug_section (Elf_Internal_Shdr * section, FILE * file)
if (secondary)
free_debug_section ((enum dwarf_section_display_enum) i);
- if (streq (debug_displays[i].section.uncompressed_name, name))
+ if (streq (sec->uncompressed_name, name))
sec->name = sec->uncompressed_name;
else
sec->name = sec->compressed_name;