From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25802 invoked by alias); 17 Oct 2008 22:54:32 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 25748 invoked by uid 9079); 17 Oct 2008 22:54:31 -0000 Date: Fri, 17 Oct 2008 22:54:00 -0000 Message-ID: <20081017225431.25733.qmail@sourceware.org> From: kseitz@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-keiths-dwarf-names-branch: Daniel's DWARF2 name patches (and miscellaneous baggage) X-Git-Refname: refs/heads/archer-keiths-dwarf-names-branch X-Git-Reftype: branch X-Git-Oldrev: 4eaa6f1cc84b9df0beda560f90a901ed36d70acf X-Git-Newrev: e56b9f4bab7f78c2749bc115cc2aa5bdd7375e8c X-SW-Source: 2008-q4/txt/msg00017.txt.bz2 List-Id: The branch, archer-keiths-dwarf-names-branch has been updated via e56b9f4bab7f78c2749bc115cc2aa5bdd7375e8c (commit) from 4eaa6f1cc84b9df0beda560f90a901ed36d70acf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit e56b9f4bab7f78c2749bc115cc2aa5bdd7375e8c Author: keiths Date: Thu Oct 2 14:41:42 2008 -0700 Daniel's DWARF2 name patches (and miscellaneous baggage) ----------------------------------------------------------------------- Summary of changes: gdb/c-typeprint.c | 32 ++- gdb/cp-support.c | 3 +- gdb/dwarf2read.c | 445 ++++++++++++++++++++--------------- gdb/eval.c | 47 +++-- gdb/gnu-v3-abi.c | 12 +- gdb/symfile.c | 5 +- gdb/symfile.h | 5 +- gdb/symtab.h | 3 - gdb/testsuite/gdb.cp/cplusfuncs.cc | 6 + gdb/testsuite/gdb.cp/cplusfuncs.exp | 195 ++++++++++++++-- gdb/testsuite/gdb.cp/member-ptr.cc | 17 ++ gdb/testsuite/gdb.cp/member-ptr.exp | 30 +++ gdb/testsuite/gdb.cp/overload.exp | 8 +- gdb/testsuite/gdb.cp/ovldbreak.exp | 46 +++-- gdb/ui-file.c | 20 ++- gdb/ui-file.h | 6 +- gdb/valops.c | 52 +++- 17 files changed, 656 insertions(+), 276 deletions(-) First 500 lines of diff: diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 56d12f9..8ec64c9 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -40,8 +40,6 @@ static void cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring, int staticp, struct ui_file *stream); -static void c_type_print_args (struct type *, struct ui_file *); - static void cp_type_print_derivation_info (struct ui_file *, struct type *); static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int, @@ -181,6 +179,23 @@ cp_type_print_method_args (struct type *mtype, char *prefix, char *varstring, fprintf_filtered (stream, "void"); fprintf_filtered (stream, ")"); + + /* For non-static methods, read qualifiers from the type of + THIS. */ + if (!staticp) + { + struct type *domain; + + gdb_assert (nargs > 0); + gdb_assert (TYPE_CODE (args[0].type) == TYPE_CODE_PTR); + domain = TYPE_TARGET_TYPE (args[0].type); + + if (TYPE_CONST (domain)) + fprintf_filtered (stream, " const"); + + if (TYPE_VOLATILE (domain)) + fprintf_filtered (stream, " volatile"); + } } @@ -336,10 +351,12 @@ c_type_print_modifier (struct type *type, struct ui_file *stream, /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD or TYPE_CODE_FUNC, to STREAM. Artificial arguments, such as "this" - in non-static methods, are displayed. */ + in non-static methods, are displayed if SHOW_ARTIFICIAL is + non-zero. */ -static void -c_type_print_args (struct type *type, struct ui_file *stream) +void +c_type_print_args (struct type *type, struct ui_file *stream, + int show_artificial) { int i, len; struct field *args; @@ -351,6 +368,9 @@ c_type_print_args (struct type *type, struct ui_file *stream) for (i = 0; i < TYPE_NFIELDS (type); i++) { + if (TYPE_FIELD_ARTIFICIAL (type, i) && !show_artificial) + continue; + if (printed_any) { fprintf_filtered (stream, ", "); @@ -574,7 +594,7 @@ c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, if (passed_a_ptr) fprintf_filtered (stream, ")"); if (!demangled_args) - c_type_print_args (type, stream); + c_type_print_args (type, stream, 1); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, passed_a_ptr, 0); break; diff --git a/gdb/cp-support.c b/gdb/cp-support.c index df48f60..1679b48 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -175,7 +175,8 @@ mangled_name_to_comp (const char *mangled_name, int options, return ret; } -/* Return the name of the class containing method PHYSNAME. */ +/* Return the name of the class or namespace containing + function, method, or variable PHYSNAME. */ char * cp_class_name_from_physname (const char *physname) diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 1b68e2a..de65a20 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -46,6 +46,7 @@ #include "command.h" #include "gdbcmd.h" #include "addrmap.h" +#include "c-lang.h" #include #include "gdb_string.h" @@ -305,9 +306,6 @@ struct dwarf2_cu /* Hash table holding all the loaded partial DIEs. */ htab_t partial_dies; - /* `.debug_ranges' offset for this `DW_TAG_compile_unit' DIE. */ - unsigned long ranges_offset; - /* Storage for things with the same lifetime as this read-in compilation unit, including partial DIEs. */ struct obstack comp_unit_obstack; @@ -355,9 +353,6 @@ struct dwarf2_cu DIEs for namespaces, we don't need to try to infer them from mangled names. */ unsigned int has_namespace_info : 1; - - /* Field `ranges_offset' is filled in; flag as the value may be zero. */ - unsigned int has_ranges_offset : 1; }; /* Persistent data held for a compilation unit, even when not @@ -455,17 +450,12 @@ struct partial_die_info /* DWARF-2 tag for this DIE. */ ENUM_BITFIELD(dwarf_tag) tag : 16; - /* Language code associated with this DIE. This is only used - for the compilation unit DIE. */ - unsigned int language : 8; - /* Assorted flags describing the data found in this DIE. */ unsigned int has_children : 1; unsigned int is_external : 1; unsigned int is_declaration : 1; unsigned int has_type : 1; unsigned int has_specification : 1; - unsigned int has_stmt_list : 1; unsigned int has_pc_info : 1; /* Flag set if the SCOPE field of this structure has been @@ -476,10 +466,12 @@ struct partial_die_info unsigned int has_byte_size : 1; /* The name of this DIE. Normally the value of DW_AT_name, but - sometimes DW_TAG_MIPS_linkage_name or a string computed in some - other fashion. */ + sometimes a default name for unnamed DIEs. */ char *name; - char *dirname; + + /* The linkage name of this DIE, from DW_AT_MIPS_linkage_name, or + NULL if no linkage name was present. */ + char *linkage_name; /* The scope to prepend to our children. This is generally allocated on the comp_unit_obstack, so will disappear @@ -502,9 +494,6 @@ struct partial_die_info DW_AT_extension). */ unsigned int spec_offset; - /* If HAS_STMT_LIST, the offset of the Line Number Information data. */ - unsigned int line_offset; - /* Pointers to this DIE's parent, first child, and next sibling, if any. */ struct partial_die_info *die_parent, *die_child, *die_sibling; @@ -746,7 +735,7 @@ static void dwarf2_create_include_psymtab (char *, struct partial_symtab *, struct objfile *); static void dwarf2_build_include_psymtabs (struct dwarf2_cu *, - struct partial_die_info *, + struct die_info *, struct partial_symtab *); static void dwarf2_build_psymtabs_hard (struct objfile *, int); @@ -906,7 +895,8 @@ static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *, struct partial_symtab *); static int dwarf2_get_pc_bounds (struct die_info *, - CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *); + CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *, + struct partial_symtab *pst); static void get_scope_pc_bounds (struct die_info *, CORE_ADDR *, CORE_ADDR *, @@ -1406,22 +1396,24 @@ dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst, /* Read the Line Number Program data and extract the list of files included by the source file represented by PST. Build an include - partial symtab for each of these included files. - - This procedure assumes that there *is* a Line Number Program in - the given CU. Callers should check that PDI->HAS_STMT_LIST is set - before calling this procedure. */ + partial symtab for each of these included files. */ static void dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, - struct partial_die_info *pdi, + struct die_info *die, struct partial_symtab *pst) { struct objfile *objfile = cu->objfile; bfd *abfd = objfile->obfd; - struct line_header *lh; + struct line_header *lh = NULL; + struct attribute *attr; - lh = dwarf_decode_line_header (pdi->line_offset, abfd, cu); + attr = dwarf2_attr (die, DW_AT_stmt_list, cu); + if (attr) + { + unsigned int line_offset = DW_UNSND (attr); + lh = dwarf_decode_line_header (line_offset, abfd, cu); + } if (lh == NULL) return; /* No linetable, so no includes. */ @@ -1430,6 +1422,36 @@ dwarf2_build_include_psymtabs (struct dwarf2_cu *cu, free_line_header (lh); } +/* Find the base address of the compilation unit for range lists and + location lists. It will normally be specified by DW_AT_low_pc. + In DWARF-3 draft 4, the base address could be overridden by + DW_AT_entry_pc. It's been removed, but GCC still uses this for + compilation units with discontinuous ranges. */ + +static void +dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu) +{ + struct attribute *attr; + + cu->header.base_known = 0; + cu->header.base_address = 0; + + attr = dwarf2_attr (die, DW_AT_entry_pc, cu); + if (attr) + { + cu->header.base_address = DW_ADDR (attr); + cu->header.base_known = 1; + } + else + { + attr = dwarf2_attr (die, DW_AT_low_pc, cu); + if (attr) + { + cu->header.base_address = DW_ADDR (attr); + cu->header.base_known = 1; + } + } +} /* Build the partial symbol table by doing a quick pass through the .debug_info and .debug_abbrev sections. */ @@ -1442,7 +1464,7 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) bfd *abfd = objfile->obfd; gdb_byte *info_ptr; gdb_byte *beg_of_comp_unit; - struct partial_die_info comp_unit_die; + struct die_info *comp_unit_die; struct partial_symtab *pst; struct cleanup *back_to; CORE_ADDR lowpc, highpc, baseaddr; @@ -1476,9 +1498,12 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) { struct cleanup *back_to_inner; struct dwarf2_cu cu; - struct abbrev_info *abbrev; unsigned int bytes_read; struct dwarf2_per_cu_data *this_cu; + int has_children, has_pc_info; + struct attribute *attr; + const char *name; + CORE_ADDR best_lowpc, best_highpc; beg_of_comp_unit = info_ptr; @@ -1505,11 +1530,10 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) this_cu = dwarf2_find_comp_unit (cu.header.offset, objfile); /* Read the compilation unit die */ - abbrev = peek_die_abbrev (info_ptr, &bytes_read, &cu); - info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, - abfd, info_ptr, &cu); + info_ptr = read_full_die (&comp_unit_die, abfd, info_ptr, &cu, + &has_children); - if (comp_unit_die.tag == DW_TAG_partial_unit) + if (comp_unit_die->tag == DW_TAG_partial_unit) { info_ptr = (beg_of_comp_unit + cu.header.length + cu.header.initial_length_size); @@ -1518,20 +1542,27 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) } /* Set the language we're debugging */ - set_cu_language (comp_unit_die.language, &cu); + attr = dwarf2_attr (comp_unit_die, DW_AT_language, &cu); + if (attr != NULL) + set_cu_language (DW_UNSND (attr), &cu); + else + set_cu_language (language_minimal, &cu); /* Allocate a new partial symbol table structure */ - pst = start_psymtab_common (objfile, objfile->section_offsets, - comp_unit_die.name ? comp_unit_die.name : "", + attr = dwarf2_attr (comp_unit_die, DW_AT_name, &cu); + if (attr != NULL) + name = DW_STRING (attr); + else + name = ""; + pst = start_psymtab_common (objfile, objfile->section_offsets, name, /* TEXTLOW and TEXTHIGH are set below. */ 0, objfile->global_psymbols.next, objfile->static_psymbols.next); - if (comp_unit_die.dirname) - pst->dirname = obsavestring (comp_unit_die.dirname, - strlen (comp_unit_die.dirname), - &objfile->objfile_obstack); + attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, &cu); + if (attr != NULL) + pst->dirname = xstrdup (DW_STRING (attr)); pst->read_symtab_private = (char *) this_cu; @@ -1561,17 +1592,17 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) /* Possibly set the default values of LOWPC and HIGHPC from `DW_AT_ranges'. */ - if (cu.has_ranges_offset) - { - if (dwarf2_ranges_read (cu.ranges_offset, &comp_unit_die.lowpc, - &comp_unit_die.highpc, &cu, pst)) - comp_unit_die.has_pc_info = 1; - } + has_pc_info = 0; + + if (dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc, &best_highpc, &cu, + pst)) + has_pc_info = 1; + dwarf2_find_base_address (comp_unit_die, &cu); /* Check if comp unit has_children. If so, read the rest of the partial symbols from this comp unit. If not, there's no more debug_info for this comp unit. */ - if (comp_unit_die.has_children) + if (has_children) { struct partial_die_info *first_die; @@ -1589,18 +1620,19 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) /* If the compilation unit didn't have an explicit address range, then use the information extracted from its child dies. */ - if (! comp_unit_die.has_pc_info) + if (! has_pc_info) { - comp_unit_die.lowpc = lowpc; - comp_unit_die.highpc = highpc; + best_lowpc = lowpc; + best_highpc = highpc; } } - pst->textlow = comp_unit_die.lowpc + baseaddr; - pst->texthigh = comp_unit_die.highpc + baseaddr; + pst->textlow = best_lowpc + baseaddr; + pst->texthigh = best_highpc + baseaddr; /* Store the contiguous range; `DW_AT_ranges' range is stored above. The range can be also empty for CUs with no code. */ - if (!cu.has_ranges_offset && pst->textlow < pst->texthigh) + if (dwarf2_attr (comp_unit_die, DW_AT_ranges, &cu) == NULL + && pst->textlow < pst->texthigh) addrmap_set_empty (objfile->psymtabs_addrmap, pst->textlow, pst->texthigh - 1, pst); @@ -1618,12 +1650,9 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline) info_ptr = beg_of_comp_unit + cu.header.length + cu.header.initial_length_size; - if (comp_unit_die.has_stmt_list) - { - /* Get the list of files included in the current compilation unit, - and build a psymtab for each of them. */ - dwarf2_build_include_psymtabs (&cu, &comp_unit_die, pst); - } + /* Get the list of files included in the current compilation unit, + and build a psymtab for each of them. */ + dwarf2_build_include_psymtabs (&cu, comp_unit_die, pst); do_cleanups (back_to_inner); } @@ -1641,11 +1670,12 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile) { bfd *abfd = objfile->obfd; gdb_byte *info_ptr, *beg_of_comp_unit; - struct partial_die_info comp_unit_die; + struct die_info *comp_unit_die; struct dwarf2_cu *cu; - struct abbrev_info *abbrev; unsigned int bytes_read; struct cleanup *back_to; + struct attribute *attr; + int has_children; info_ptr = dwarf2_per_objfile->info_buffer + this_cu->offset; beg_of_comp_unit = info_ptr; @@ -1668,12 +1698,15 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile) back_to = make_cleanup (dwarf2_free_abbrev_table, cu); /* Read the compilation unit die. */ - abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu); - info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read, - abfd, info_ptr, cu); + info_ptr = read_full_die (&comp_unit_die, abfd, info_ptr, cu, + &has_children); /* Set the language we're debugging. */ - set_cu_language (comp_unit_die.language, cu); + attr = dwarf2_attr (comp_unit_die, DW_AT_language, cu); + if (attr) + set_cu_language (DW_UNSND (attr), cu); + else + set_cu_language (language_minimal, cu); /* Link this compilation unit into the compilation unit tree. */ this_cu->cu = cu; @@ -1683,7 +1716,7 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile) /* Check if comp unit has_children. If so, read the rest of the partial symbols from this comp unit. If not, there's no more debug_info for this comp unit. */ - if (comp_unit_die.has_children) + if (has_children) load_partial_dies (abfd, info_ptr, 0, cu); do_cleanups (back_to); @@ -1910,7 +1943,7 @@ partial_die_parent_scope (struct partial_die_info *pdi, ignoring them. */ complaint (&symfile_complaints, _("unhandled containing DIE tag %d for DIE at %d"), - parent->tag, pdi->offset); + parent->tag, real_pdi->offset); parent->scope = grandparent_scope; } @@ -1925,12 +1958,37 @@ partial_die_full_name (struct partial_die_info *pdi, struct dwarf2_cu *cu) { char *parent_scope; + struct partial_die_info *real_pdi; - parent_scope = partial_die_parent_scope (pdi, cu); - if (parent_scope == NULL) - return NULL; - else + /* We need to look at our parent DIE; if we have a DW_AT_specification, + then this means the parent of the specification DIE. + partial_die_parent_scope does this loop also, but we do it here + since we need to examine real_pdi->parent ourselves. */ + + real_pdi = pdi; + while (real_pdi->has_specification) + real_pdi = find_partial_die (real_pdi->spec_offset, cu); + + parent_scope = partial_die_parent_scope (real_pdi, cu); + if (parent_scope != NULL) return typename_concat (NULL, parent_scope, pdi->name, cu); + + if (!cu->has_namespace_info && pdi->linkage_name + && !real_pdi->die_parent) + { + char *actual_scope + = language_class_name_from_physname (cu->language_defn, + pdi->linkage_name); + if (actual_scope != NULL) + { + char *actual_name = typename_concat (NULL, actual_scope, + pdi->name, cu); + xfree (actual_scope); + return actual_name; + } + } + + return NULL; } static void @@ -1946,7 +2004,9 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - if (pdi_needs_namespace (pdi->tag)) + if (pdi->linkage_name != NULL) + actual_name = pdi->linkage_name; + else if (pdi_needs_namespace (pdi->tag)) { actual_name = partial_die_full_name (pdi, cu); if (actual_name) @@ -2095,9 +2155,8 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu) if (cu->language == language_cplus && cu->has_namespace_info == 0 hooks/post-receive -- Repository for Project Archer.