From 60d5a603bb6cfff6ffe179ebd10271ae5d0b6287 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sat, 9 Apr 2011 11:15:29 +0000 Subject: gdb/ Fix DW_AT_accessibility compatibility with gcc-4.6+. * dwarf2read.c: Include ctype.h. (producer_is_gxx_lt_4_6, dwarf2_default_access_attribute): New functions. (dwarf2_add_field): Fix new_field->accessibility by calling dwarf2_default_access_attribute. Restructure setting accessibility vs. virtuality. (dwarf2_add_member_fn): New variable accessibility. Fix fnp is_private and is_protected by calling dwarf2_default_access_attribute. --- gdb/ChangeLog | 13 +++++++ gdb/dwarf2read.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 105 insertions(+), 18 deletions(-) (limited to 'gdb') diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2aa4b41..038c56b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2011-04-09 Jan Kratochvil + + Fix DW_AT_accessibility compatibility with gcc-4.6+. + * dwarf2read.c: Include ctype.h. + (producer_is_gxx_lt_4_6, dwarf2_default_access_attribute): New + functions. + (dwarf2_add_field): Fix new_field->accessibility by calling + dwarf2_default_access_attribute. Restructure setting accessibility + vs. virtuality. + (dwarf2_add_member_fn): New variable accessibility. Fix fnp + is_private and is_protected by calling + dwarf2_default_access_attribute. + 2011-04-08 Kevin Buettner * rx-tdep.c (rx_frame_unwind): Add default_frame_unwind_stop_reason diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 5086733..15311fe 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -57,6 +57,7 @@ #include "vec.h" #include "c-lang.h" #include "valprint.h" +#include #include #include "gdb_string.h" @@ -6236,6 +6237,81 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block, } } +/* Check for GCC PR debug/45124 fix which is not present in any G++ version up + to 4.5.any while it is present already in G++ 4.6.0 - the PR has been fixed + during 4.6.0 experimental. */ + +static int +producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu) +{ + const char *cs; + int major, minor, release; + + if (cu->producer == NULL) + { + /* For unknown compilers expect their behavior is DWARF version + compliant. + + GCC started to support .debug_types sections by -gdwarf-4 since + gcc-4.5.x. As the .debug_types sections are missing DW_AT_producer + for their space efficiency GDB cannot workaround gcc-4.5.x -gdwarf-4 + combination. gcc-4.5.x -gdwarf-4 binaries have DW_AT_accessibility + interpreted incorrectly by GDB now - GCC PR debug/48229. */ + + return 0; + } + + /* Skip any identifier after "GNU " - such as "C++" or "Java". */ + + if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0) + { + /* For non-GCC compilers expect their behavior is DWARF version + compliant. */ + + return 0; + } + cs = &cu->producer[strlen ("GNU ")]; + while (*cs && !isdigit (*cs)) + cs++; + if (sscanf (cs, "%d.%d.%d", &major, &minor, &release) != 3) + { + /* Not recognized as GCC. */ + + return 0; + } + + return major < 4 || (major == 4 && minor < 6); +} + +/* Return the default accessibility type if it is not overriden by + DW_AT_accessibility. */ + +static enum dwarf_access_attribute +dwarf2_default_access_attribute (struct die_info *die, struct dwarf2_cu *cu) +{ + if (cu->header.version < 3 || producer_is_gxx_lt_4_6 (cu)) + { + /* The default DWARF 2 accessibility for members is public, the default + accessibility for inheritance is private. */ + + if (die->tag != DW_TAG_inheritance) + return DW_ACCESS_public; + else + return DW_ACCESS_private; + } + else + { + /* DWARF 3+ defines the default accessibility a different way. The same + rules apply now for DW_TAG_inheritance as for the members and it only + depends on the container kind. */ + + if (die->parent->tag == DW_TAG_class_type) + return DW_ACCESS_private; + else + return DW_ACCESS_public; + } +} + /* Add an aggregate field to the field list. */ static void @@ -6266,23 +6342,19 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } fip->nfields++; - /* Handle accessibility and virtuality of field. - The default accessibility for members is public, the default - accessibility for inheritance is private. */ - if (die->tag != DW_TAG_inheritance) - new_field->accessibility = DW_ACCESS_public; - else - new_field->accessibility = DW_ACCESS_private; - new_field->virtuality = DW_VIRTUALITY_none; - attr = dwarf2_attr (die, DW_AT_accessibility, cu); if (attr) new_field->accessibility = DW_UNSND (attr); + else + new_field->accessibility = dwarf2_default_access_attribute (die, cu); if (new_field->accessibility != DW_ACCESS_public) fip->non_public_fields = 1; + attr = dwarf2_attr (die, DW_AT_virtuality, cu); if (attr) new_field->virtuality = DW_UNSND (attr); + else + new_field->virtuality = DW_VIRTUALITY_none; fp = &new_field->field; @@ -6598,6 +6670,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, char *fieldname; struct nextfnfield *new_fnfield; struct type *this_type; + enum dwarf_access_attribute accessibility; if (cu->language == language_ada) error (_("unexpected member function in Ada type")); @@ -6696,16 +6769,17 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, /* Get accessibility. */ attr = dwarf2_attr (die, DW_AT_accessibility, cu); if (attr) + accessibility = DW_UNSND (attr); + else + accessibility = dwarf2_default_access_attribute (die, cu); + switch (accessibility) { - switch (DW_UNSND (attr)) - { - case DW_ACCESS_private: - fnp->is_private = 1; - break; - case DW_ACCESS_protected: - fnp->is_protected = 1; - break; - } + case DW_ACCESS_private: + fnp->is_private = 1; + break; + case DW_ACCESS_protected: + fnp->is_protected = 1; + break; } /* Check for artificial methods. */ -- cgit v1.1