https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=109921 2007-01-09 Jan Kratochvil * buildsym.c (start_subfile_index): Renamed `start_subfile' now supporting the FILE_INDEX parameter. (start_subfile): Backward compatible stub for `start_subfile_index'. (end_symtab): Resolve new SYMBOL.FILE.SYMTAB from SYMBOL.FILE.INDEX. Substitute possibly missing DIRNAME from the CU's main file DIRNAME. Clear `subfiles' variable as its data have been deallocated. * buildsym.h (struct subfile): New field `file_index'. (start_subfile_index): New prototype. * dwarf2read.c (add_file_name): Ensure subfile has been founded. (dwarf_decode_lines): Specify the new FILE_INDEX parameter. (dwarf2_start_subfile): New FILE_INDEX parameter. (new_symbol): Extract `DW_AT_decl_file' DWARF 2 information entry. * symtab.c (lookup_symbol): Override by the new SYMBOL.FILE.SYMTAB. (search_symbols): Likewise. * symtab.h (struct symbol): New fields FILE.INDEX and FILE.SYMTAB. (SYMBOL_FILE_INDEX, SYMBOL_FILE_SYMTAB): New macros. 2007-01-09 Jan Kratochvil * gdb.dwarf2/dw2-included.exp, gdb.dwarf2/dw2-included.c, gdb.dwarf2/dw2-included.h: New files. Index: gdb/buildsym.c =================================================================== RCS file: /cvs/src/src/gdb/buildsym.c,v retrieving revision 1.45 diff -u -p -r1.45 buildsym.c --- gdb/buildsym.c 9 Jan 2007 17:58:50 -0000 1.45 +++ gdb/buildsym.c 11 Jan 2007 22:30:30 -0000 @@ -540,7 +540,7 @@ make_blockvector (struct objfile *objfil the directory in which it resides (or NULL if not known). */ void -start_subfile (char *name, char *dirname) +start_subfile_index (char *name, char *dirname, unsigned file_index) { struct subfile *subfile; @@ -552,6 +552,17 @@ start_subfile (char *name, char *dirname if (FILENAME_CMP (subfile->name, name) == 0) { current_subfile = subfile; + + if (subfile->file_index != 0 && file_index != 0 + && subfile->file_index != file_index) + complaint (&symfile_complaints, _("Filenames indexing conflict: " + "name \"%s\" dir \"%s\" index %u vs. " + "name \"%s\" dir \"%s\" index %u"), + subfile->name, subfile->dirname, subfile->file_index, + name, dirname, file_index); + if (subfile->file_index == 0) + subfile->file_index = file_index; + return; } } @@ -567,6 +578,7 @@ start_subfile (char *name, char *dirname current_subfile = subfile; /* Save its name and compilation directory name */ + subfile->file_index = file_index; subfile->name = (name == NULL) ? NULL : savestring (name, strlen (name)); subfile->dirname = (dirname == NULL) ? NULL : savestring (dirname, strlen (dirname)); @@ -625,6 +637,13 @@ start_subfile (char *name, char *dirname } } +/* Backward compatibility. */ +void +start_subfile (char *name, char *dirname) +{ + start_subfile_index (name, dirname, 0); +} + /* For stabs readers, the first N_SO symbol is assumed to be the source file name, and the subfile struct is initialized using that assumption. If another N_SO symbol is later seen, immediately @@ -824,9 +843,12 @@ end_symtab (CORE_ADDR end_addr, struct o { struct symtab *symtab = NULL; struct blockvector *blockvector; - struct subfile *subfile; + struct subfile *subfile, *subfile_main; struct context_stack *cstk; struct subfile *nextsub; + int subfiles_count; + struct symtab **file_index_to_symtab; + size_t file_index_to_symtab_size; /* Finish the lexical context of the last function in the file; pop the context stack. */ @@ -924,6 +946,18 @@ end_symtab (CORE_ADDR end_addr, struct o #endif PROCESS_LINENUMBER_HOOK (); /* Needed for xcoff. */ + /* Get the last subfile s SUBFILE_MAIN which is the main file of CU. + Count SUBFILES_COUNT. + Start with 1 as we do not iterate past the last item. */ + subfiles_count = 1; + for (subfile_main = subfiles; subfile_main && subfile_main->next; + subfile_main = subfile_main->next) + subfiles_count++; + + file_index_to_symtab_size = sizeof (*file_index_to_symtab) * subfiles_count; + file_index_to_symtab = xmalloc (file_index_to_symtab_size); + memset ((char *) file_index_to_symtab, 0, file_index_to_symtab_size); + /* Now create the symtab objects proper, one for each subfile. */ /* (The main file is the last one on the chain.) */ @@ -984,6 +1018,16 @@ end_symtab (CORE_ADDR end_addr, struct o strlen (subfile->dirname) + 1); strcpy (symtab->dirname, subfile->dirname); } + /* Non-primary subfiles may miss COMP_DIR resulting in NULL + DIRNAME and so default it from the CU file - SUBFILE_MAIN. */ + else if (subfile_main->dirname) + { + /* Reallocate the dirname on the symbol obstack */ + symtab->dirname = (char *) + obstack_alloc (&objfile->objfile_obstack, + strlen (subfile_main->dirname) + 1); + strcpy (symtab->dirname, subfile_main->dirname); + } else { symtab->dirname = NULL; @@ -1018,6 +1062,13 @@ end_symtab (CORE_ADDR end_addr, struct o but the main file. */ symtab->primary = 0; + + /* It may be zero for files unlisted in File Table. */ + if (subfile->file_index) + { + gdb_assert (subfile->file_index <= subfiles_count); + file_index_to_symtab[subfile->file_index - 1] = symtab; + } } if (subfile->name != NULL) { @@ -1048,9 +1099,40 @@ end_symtab (CORE_ADDR end_addr, struct o symtab->primary = 1; } + /* Resolve `struct symbol.file.index' into `struct symbol.file.symtab'. */ + if (blockvector) + { + int block_i; + + for (block_i = 0; block_i < BLOCKVECTOR_NBLOCKS (blockvector); block_i++) + { + struct symbol *sym; + struct dict_iterator iter; + + for (sym = dict_iterator_first (BLOCK_DICT + (BLOCKVECTOR_BLOCK (blockvector, block_i)), &iter); + sym != NULL; + sym = dict_iterator_next (&iter)) + { + /* Beware the ordering as `sym->file' is a union. */ + if (SYMBOL_FILE_INDEX (sym) + && file_index_to_symtab[SYMBOL_FILE_INDEX (sym) - 1]) + SYMBOL_FILE_SYMTAB (sym) = file_index_to_symtab + [SYMBOL_FILE_INDEX (sym) - 1]; + else + { + /* Default to the primary symbol table, never use NULL. */ + SYMBOL_FILE_SYMTAB (sym) = symtab; + } + } + } + } + + xfree (file_index_to_symtab); last_source_file = NULL; current_subfile = NULL; pending_macros = NULL; + subfiles = NULL; return symtab; } Index: gdb/buildsym.h =================================================================== RCS file: /cvs/src/src/gdb/buildsym.h,v retrieving revision 1.15 diff -u -p -r1.15 buildsym.h --- gdb/buildsym.h 9 Jan 2007 17:58:50 -0000 1.15 +++ gdb/buildsym.h 11 Jan 2007 22:30:30 -0000 @@ -63,6 +63,7 @@ EXTERN CORE_ADDR last_source_start_addr; struct subfile { struct subfile *next; + unsigned file_index; char *name; char *dirname; struct linetable *line_vector; @@ -241,6 +242,9 @@ extern void finish_block (struct symbol extern void really_free_pendings (void *dummy); +extern void start_subfile_index (char *name, char *dirname, + unsigned file_index); + extern void start_subfile (char *name, char *dirname); extern void patch_subfile_names (struct subfile *subfile, char *name); Index: gdb/dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.211 diff -u -p -r1.211 dwarf2read.c --- gdb/dwarf2read.c 9 Jan 2007 17:58:50 -0000 1.211 +++ gdb/dwarf2read.c 11 Jan 2007 22:30:33 -0000 @@ -854,7 +854,7 @@ static struct line_header *(dwarf_decode static void dwarf_decode_lines (struct line_header *, char *, bfd *, struct dwarf2_cu *, struct partial_symtab *); -static void dwarf2_start_subfile (char *, char *, char *); +static void dwarf2_start_subfile (char *, char *, char *, unsigned); static struct symbol *new_symbol (struct die_info *, struct type *, struct dwarf2_cu *); @@ -6435,6 +6435,7 @@ add_file_name (struct line_header *lh, unsigned int length) { struct file_entry *fe; + char *dir = NULL; /* Grow the array if necessary. */ if (lh->file_names_size == 0) @@ -6457,6 +6458,10 @@ add_file_name (struct line_header *lh, fe->mod_time = mod_time; fe->length = length; fe->included_p = 0; + + if (dir_index) + dir = lh->include_dirs[dir_index - 1]; + dwarf2_start_subfile (name, dir, NULL, lh->num_file_names); } @@ -6675,7 +6680,7 @@ dwarf_decode_lines (struct line_header * if (fe->dir_index) dir = lh->include_dirs[fe->dir_index - 1]; - dwarf2_start_subfile (fe->name, dir, comp_dir); + dwarf2_start_subfile (fe->name, dir, comp_dir, file); } /* Decode the table. */ @@ -6792,7 +6797,7 @@ dwarf_decode_lines (struct line_header * if (!decode_for_pst_p) { last_subfile = current_subfile; - dwarf2_start_subfile (fe->name, dir, comp_dir); + dwarf2_start_subfile (fe->name, dir, comp_dir, file); } } break; @@ -6896,7 +6901,8 @@ dwarf_decode_lines (struct line_header * subfile's name. */ static void -dwarf2_start_subfile (char *filename, char *dirname, char *comp_dir) +dwarf2_start_subfile (char *filename, char *dirname, char *comp_dir, + unsigned file_index) { char *fullname; @@ -6915,7 +6921,7 @@ dwarf2_start_subfile (char *filename, ch else fullname = filename; - start_subfile (fullname, comp_dir); + start_subfile_index (fullname, comp_dir, file_index); if (fullname != filename) xfree (fullname); @@ -7024,6 +7030,13 @@ new_symbol (struct die_info *die, struct { SYMBOL_LINE (sym) = DW_UNSND (attr); } + attr = dwarf2_attr (die, DW_AT_decl_file, cu); + if (attr) + { + /* Do not yet search `objfile->symtabs' here as they still do not + have filled in their FILE.INDEX fields. */ + SYMBOL_FILE_INDEX (sym) = DW_UNSND (attr); + } switch (die->tag) { case DW_TAG_label: Index: gdb/symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.152 diff -u -p -r1.152 symtab.c --- gdb/symtab.c 9 Jan 2007 22:43:08 -0000 1.152 +++ gdb/symtab.c 11 Jan 2007 22:30:35 -0000 @@ -1133,6 +1133,10 @@ lookup_symbol (const char *name, const s if (needtofreename) xfree (demangled_name); + /* Override the returned symtab with optional symbol's specific one. */ + if (returnval != NULL && symtab != NULL) + *symtab = SYMBOL_FILE_SYMTAB (returnval); + return returnval; } @@ -3088,7 +3092,7 @@ search_symbols (char *regexp, domain_enu ALL_BLOCK_SYMBOLS (b, iter, sym) { QUIT; - if (file_matches (s->filename, files, nfiles) + if (file_matches (SYMBOL_FILE_SYMTAB (sym)->filename, files, nfiles) && ((regexp == NULL || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0) && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF @@ -3101,7 +3105,7 @@ search_symbols (char *regexp, domain_enu /* match */ psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search)); psr->block = i; - psr->symtab = s; + psr->symtab = SYMBOL_FILE_SYMTAB (sym); psr->symbol = sym; psr->msymbol = NULL; psr->next = NULL; Index: gdb/symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.100 diff -u -p -r1.100 symtab.h --- gdb/symtab.h 9 Jan 2007 17:58:59 -0000 1.100 +++ gdb/symtab.h 11 Jan 2007 22:30:35 -0000 @@ -623,6 +623,18 @@ struct symbol ENUM_BITFIELD(address_class) aclass : 6; + /* File name it comes from. Use with `line' below. + FILE.INDEX is zero if the symbol's specific file is not known and in such + case we later default to the main file of the compilation unit. + FILE.SYMTAB gets resolved during end_symtab() and it is never NULL. */ + + union + { + unsigned index; + struct symtab *symtab; + } + file; + /* Line number of definition. FIXME: Should we really make the assumption that nobody will try to debug files longer than 64K lines? What about machine generated programs? */ @@ -663,6 +675,8 @@ struct symbol #define SYMBOL_DOMAIN(symbol) (symbol)->domain #define SYMBOL_CLASS(symbol) (symbol)->aclass #define SYMBOL_TYPE(symbol) (symbol)->type +#define SYMBOL_FILE_INDEX(symbol) (symbol)->file.index +#define SYMBOL_FILE_SYMTAB(symbol) (symbol)->file.symtab #define SYMBOL_LINE(symbol) (symbol)->line #define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg #define SYMBOL_OBJFILE(symbol) (symbol)->aux_value.objfile Index: gdb/testsuite/gdb.dwarf2/dw2-included.c =================================================================== RCS file: gdb/testsuite/gdb.dwarf2/dw2-included.c diff -N gdb/testsuite/gdb.dwarf2/dw2-included.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.dwarf2/dw2-included.c 11 Jan 2007 22:30:36 -0000 @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#include "dw2-included.h" + +int +main() +{ + return 0; +} Index: gdb/testsuite/gdb.dwarf2/dw2-included.exp =================================================================== RCS file: gdb/testsuite/gdb.dwarf2/dw2-included.exp diff -N gdb/testsuite/gdb.dwarf2/dw2-included.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.dwarf2/dw2-included.exp 11 Jan 2007 22:30:36 -0000 @@ -0,0 +1,47 @@ +# Copyright 2006 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Minimal DWARF-2 unit test + +# This test can only be run on targets which support DWARF-2. +# For now pick a sampling of likely targets. +if {![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*] + && ![istarget arm-*-eabi*] + && ![istarget powerpc-*-eabi*]} { + return 0 +} + +set testfile "dw2-included" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +gdb_test "set listsize 1" "" +gdb_test "list integer" "int integer;\r" +gdb_test "ptype integer" "type = int\r" +# Path varies depending on the build location. +gdb_test "info variables integer" "\r\nFile \[^\r\n\]*/gdb.dwarf2/dw2-included.h:\r\nint integer;\r" Index: gdb/testsuite/gdb.dwarf2/dw2-included.h =================================================================== RCS file: gdb/testsuite/gdb.dwarf2/dw2-included.h diff -N gdb/testsuite/gdb.dwarf2/dw2-included.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gdb/testsuite/gdb.dwarf2/dw2-included.h 11 Jan 2007 22:30:36 -0000 @@ -0,0 +1,20 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +int integer;