From 2b6f59972b0eac01b8f09e57ff8f2a8b89179784 Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Thu, 24 Sep 2009 20:52:07 +0000 Subject: [PATCH] include/ * dwarf2.h (DW_TAG_rvalue_reference_type, DW_TAG_template_alias): New tags. (DW_FORM_ref_sig8): New name for DW_FORM_sig8. (DW_AT_main_subprogram, DW_AT_data_bit_offset, DW_AT_const_expr, DW_AT_enum_class, DW_AT_linkage_name, DW_AT_GNU_guarded_by, DW_AT_GNU_pt_guarded_by, DW_AT_GNU_guarded, DW_AT_GNU_pt_guarded, DW_AT_GNU_locks_excluded, DW_AT_GNU_exclusive_locks_required, DW_AT_GNU_shared_locks_required, DW_AT_GNU_odr_signature): New attributes. (DW_LANG_Python): New language. binutils/ * 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. --- binutils/ChangeLog | 13 ++++++ binutils/dwarf.c | 112 +++++++++++++++++++++++++++++++++++++++------ binutils/readelf.c | 3 +- include/ChangeLog | 13 ++++++ include/dwarf2.h | 25 +++++++++- 5 files changed, 148 insertions(+), 18 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 8df97efa33..71df175bba 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,16 @@ +2009-09-24 Cary Coutant + + * 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 * readelf.c (print_dynamic_symbol): Format entries as for diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 5eeef08891..ac3753809d 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 edd5a2ed14..425161c61a 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; diff --git a/include/ChangeLog b/include/ChangeLog index b9aef7f789..1cfe59468a 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,16 @@ +2009-09-24 Cary Coutant + + * dwarf2.h (DW_TAG_rvalue_reference_type, DW_TAG_template_alias): + New tags. + (DW_FORM_ref_sig8): New name for DW_FORM_sig8. + (DW_AT_main_subprogram, DW_AT_data_bit_offset, DW_AT_const_expr, + DW_AT_enum_class, DW_AT_linkage_name, DW_AT_GNU_guarded_by, + DW_AT_GNU_pt_guarded_by, DW_AT_GNU_guarded, DW_AT_GNU_pt_guarded, + DW_AT_GNU_locks_excluded, DW_AT_GNU_exclusive_locks_required, + DW_AT_GNU_shared_locks_required, DW_AT_GNU_odr_signature): New + attributes. + (DW_LANG_Python): New language. + 2009-09-22 Dodji Seketeli * dwarf2.h (enum dwarf_tag): Add diff --git a/include/dwarf2.h b/include/dwarf2.h index 608f7b5d84..4aa10d5a87 100644 --- a/include/dwarf2.h +++ b/include/dwarf2.h @@ -196,6 +196,8 @@ enum dwarf_tag DW_TAG_shared_type = 0x40, /* DWARF 4. */ DW_TAG_type_unit = 0x41, + DW_TAG_rvalue_reference_type = 0x42, + DW_TAG_template_alias = 0x43, DW_TAG_lo_user = 0x4080, DW_TAG_hi_user = 0xffff, @@ -262,7 +264,8 @@ enum dwarf_form DW_FORM_sec_offset = 0x17, DW_FORM_exprloc = 0x18, DW_FORM_flag_present = 0x19, - DW_FORM_sig8 = 0x20 + DW_FORM_ref_sig8 = 0x20 +#define DW_FORM_sig8 DW_FORM_ref_sig8 /* Note: The use of DW_FORM_sig8 is deprecated. */ }; /* Attribute names and codes. */ @@ -361,7 +364,12 @@ enum dwarf_attribute DW_AT_pure = 0x67, DW_AT_recursive = 0x68, /* DWARF 4. */ - DW_AT_signature = 0x69, + DW_AT_signature = 0x69, + DW_AT_main_subprogram = 0x6a, + DW_AT_data_bit_offset = 0x6b, + DW_AT_const_expr = 0x6c, + DW_AT_enum_class = 0x6d, + DW_AT_linkage_name = 0x6e, DW_AT_lo_user = 0x2000, /* Implementation-defined range start. */ DW_AT_hi_user = 0x3ff0, /* Implementation-defined range end. */ @@ -401,6 +409,18 @@ enum dwarf_attribute DW_AT_body_begin = 0x2105, DW_AT_body_end = 0x2106, DW_AT_GNU_vector = 0x2107, + /* Thread-safety annotations. + See http://gcc.gnu.org/wiki/ThreadSafetyAnnotation . */ + DW_AT_GNU_guarded_by = 0x2108, + DW_AT_GNU_pt_guarded_by = 0x2109, + DW_AT_GNU_guarded = 0x210a, + DW_AT_GNU_pt_guarded = 0x210b, + DW_AT_GNU_locks_excluded = 0x210c, + DW_AT_GNU_exclusive_locks_required = 0x210d, + DW_AT_GNU_shared_locks_required = 0x210e, + /* One-definition rule violation detection. + See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo . */ + DW_AT_GNU_odr_signature = 0x210f, /* Template template argument name. See http://gcc.gnu.org/wiki/TemplateParmsDwarf . */ DW_AT_GNU_template_name = 0x2110, @@ -839,6 +859,7 @@ enum dwarf_source_language DW_LANG_ObjC_plus_plus = 0x0011, DW_LANG_UPC = 0x0012, DW_LANG_D = 0x0013, + DW_LANG_Python = 0x0014, DW_LANG_lo_user = 0x8000, /* Implementation-defined range start. */ DW_LANG_hi_user = 0xffff, /* Implementation-defined range start. */