2007-01-21 Jan Kratochvil Daniel Jacobowitz * buildsym.c (end_symtab): Use preallocated symtab if available. Fill in SYMBOL_SYMTAB. * buildsym.h (struct subfile): Add symtab member. * dwarf2read.c (struct dwarf2_cu): Add line_header. (struct file_entry): Add symtab. (free_cu_line_header): New function. (read_file_scope): Use it. Save line_header in the cu. Process lines before DIEs. (add_file_name): Initialize new symtab member. (dwarf_decode_lines): Create symtabs for included files. (new_symbol): Set SYMBOL_SYMTAB. * symtab.c (lookup_symbol): Use SYMBOL_SYMTAB. (search_symbols): Likewise. * symtab.h (struct symbol): Add symtab member. (SYMBOL_SYMTAB): Define. 2007-01-21 Jan Kratochvil Daniel Jacobowitz * gdb.base/included.c, gdb.base/included.exp, gdb.base/included.h: New files. =================================================================== RCS file: /cvs/src/src/gdb/buildsym.c,v retrieving revision 1.45 retrieving revision 1.46 diff -u -r1.45 -r1.46 --- src/gdb/buildsym.c 2007/01/09 17:58:50 1.45 +++ src/gdb/buildsym.c 2007/01/21 16:49:40 1.46 @@ -959,7 +959,10 @@ } /* Now, allocate a symbol table. */ - symtab = allocate_symtab (subfile->name, objfile); + if (subfile->symtab == NULL) + symtab = allocate_symtab (subfile->name, objfile); + else + symtab = subfile->symtab; /* Fill in its components. */ symtab->blockvector = blockvector; @@ -1048,6 +1051,26 @@ symtab->primary = 1; } + /* Default any symbols without a specified symtab to the primary + symtab. */ + if (blockvector) + { + int block_i; + + for (block_i = 0; block_i < BLOCKVECTOR_NBLOCKS (blockvector); block_i++) + { + struct block *block = BLOCKVECTOR_BLOCK (blockvector, block_i); + struct symbol *sym; + struct dict_iterator iter; + + for (sym = dict_iterator_first (BLOCK_DICT (block), &iter); + sym != NULL; + sym = dict_iterator_next (&iter)) + if (SYMBOL_SYMTAB (sym) == NULL) + SYMBOL_SYMTAB (sym) = symtab; + } + } + last_source_file = NULL; current_subfile = NULL; pending_macros = NULL; =================================================================== RCS file: /cvs/src/src/gdb/buildsym.h,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- src/gdb/buildsym.h 2007/01/09 17:58:50 1.15 +++ src/gdb/buildsym.h 2007/01/21 16:49:40 1.16 @@ -70,6 +70,7 @@ enum language language; char *producer; char *debugformat; + struct symtab *symtab; }; EXTERN struct subfile *subfiles; =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.211 retrieving revision 1.212 diff -u -r1.211 -r1.212 --- src/gdb/dwarf2read.c 2007/01/09 17:58:50 1.211 +++ src/gdb/dwarf2read.c 2007/01/21 16:49:40 1.212 @@ -341,6 +341,9 @@ partial symbol tables do not have dependencies. */ htab_t dependencies; + /* Header data from the line table, during full symbol processing. */ + struct line_header *line_header; + /* Mark used when releasing cached dies. */ unsigned int mark : 1; @@ -432,6 +435,7 @@ unsigned int mod_time; unsigned int length; int included_p; /* Non-zero if referenced by the Line Number Program. */ + struct symtab *symtab; /* The associated symbol table, if any. */ } *file_names; /* The start and end of the statement program following this @@ -2754,6 +2758,15 @@ } static void +free_cu_line_header (void *arg) +{ + struct dwarf2_cu *cu = arg; + + free_line_header (cu->line_header); + cu->line_header = NULL; +} + +static void read_file_scope (struct die_info *die, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; @@ -2823,18 +2836,9 @@ initialize_cu_func_list (cu); - /* Process all dies in compilation unit. */ - if (die->child != NULL) - { - child_die = die->child; - while (child_die && child_die->tag) - { - process_die (child_die, cu); - child_die = sibling_die (child_die); - } - } - - /* Decode line number information if present. */ + /* Decode line number information if present. We do this before + processing child DIEs, so that the line header table is available + for DW_AT_decl_file. */ attr = dwarf2_attr (die, DW_AT_stmt_list, cu); if (attr) { @@ -2842,12 +2846,23 @@ line_header = dwarf_decode_line_header (line_offset, abfd, cu); if (line_header) { - make_cleanup ((make_cleanup_ftype *) free_line_header, - (void *) line_header); + cu->line_header = line_header; + make_cleanup (free_cu_line_header, cu); dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL); } } + /* Process all dies in compilation unit. */ + if (die->child != NULL) + { + child_die = die->child; + while (child_die && child_die->tag) + { + process_die (child_die, cu); + child_die = sibling_die (child_die); + } + } + /* Decode macro information, if present. Dwarf 2 macro information refers to information in the line number info statement program header, so we can only read it if we've read the header @@ -6457,6 +6472,7 @@ fe->mod_time = mod_time; fe->length = length; fe->included_p = 0; + fe->symtab = NULL; } @@ -6644,7 +6660,7 @@ CORE_ADDR baseaddr; struct objfile *objfile = cu->objfile; const int decode_for_pst_p = (pst != NULL); - struct subfile *last_subfile = NULL; + struct subfile *last_subfile = NULL, *first_subfile = current_subfile; baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); @@ -6869,6 +6885,35 @@ dwarf2_create_include_psymtab (include_name, pst, objfile); } } + else + { + /* Make sure a symtab is created for every file, even files + which contain only variables (i.e. no code with associated + line numbers). */ + + int i; + struct file_entry *fe; + + for (i = 0; i < lh->num_file_names; i++) + { + char *dir = NULL; + fe = &lh->file_names[i]; + if (fe->dir_index) + dir = lh->include_dirs[fe->dir_index - 1]; + dwarf2_start_subfile (fe->name, dir, comp_dir); + + /* Skip the main file; we don't need it, and it must be + allocated last, so that it will show up before the + non-primary symtabs in the objfile's symtab list. */ + if (current_subfile == first_subfile) + continue; + + if (current_subfile->symtab == NULL) + current_subfile->symtab = allocate_symtab (current_subfile->name, + cu->objfile); + fe->symtab = current_subfile->symtab; + } + } } /* Start a subfile for DWARF. FILENAME is the name of the file and @@ -7024,6 +7069,23 @@ { SYMBOL_LINE (sym) = DW_UNSND (attr); } + + attr = dwarf2_attr (die, DW_AT_decl_file, cu); + if (attr) + { + int file_index = DW_UNSND (attr); + if (cu->line_header == NULL + || file_index > cu->line_header->num_file_names) + complaint (&symfile_complaints, + _("file index out of range")); + else + { + struct file_entry *fe; + fe = &cu->line_header->file_names[file_index - 1]; + SYMBOL_SYMTAB (sym) = fe->symtab; + } + } + switch (die->tag) { case DW_TAG_label: =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.152 retrieving revision 1.153 diff -u -r1.152 -r1.153 --- src/gdb/symtab.c 2007/01/09 22:43:08 1.152 +++ src/gdb/symtab.c 2007/01/21 16:49:40 1.153 @@ -1133,6 +1133,10 @@ if (needtofreename) xfree (demangled_name); + /* Override the returned symtab with the symbol's specific one. */ + if (returnval != NULL && symtab != NULL) + *symtab = SYMBOL_SYMTAB (returnval); + return returnval; } @@ -3008,7 +3012,11 @@ QUIT; /* If it would match (logic taken from loop below) - load the file and go on to the next one */ + load the file and go on to the next one. We check the + filename here, but that's a bit bogus: we don't know + what file it really comes from until we have full + symtabs. The symbol might be in a header file included by + this psymtab. This only affects Insight. */ if (file_matches (ps->filename, files, nfiles) && ((regexp == NULL || re_exec (SYMBOL_NATURAL_NAME (*psym)) != 0) @@ -3087,8 +3095,10 @@ b = BLOCKVECTOR_BLOCK (bv, i); ALL_BLOCK_SYMBOLS (b, iter, sym) { + struct symtab *real_symtab = SYMBOL_SYMTAB (sym); QUIT; - if (file_matches (s->filename, files, nfiles) + + if (file_matches (real_symtab->filename, files, nfiles) && ((regexp == NULL || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0) && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF @@ -3101,7 +3111,7 @@ /* match */ psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search)); psr->block = i; - psr->symtab = s; + psr->symtab = real_symtab; psr->symbol = sym; psr->msymbol = NULL; psr->next = NULL; =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.100 retrieving revision 1.101 diff -u -r1.100 -r1.101 --- src/gdb/symtab.h 2007/01/09 17:58:59 1.100 +++ src/gdb/symtab.h 2007/01/21 16:49:40 1.101 @@ -609,6 +609,10 @@ struct type *type; + /* The symbol table containing this symbol. This is the file + associated with LINE. */ + struct symtab *symtab; + /* Domain code. */ ENUM_BITFIELD(domain_enum_tag) domain : 6; @@ -664,6 +668,7 @@ #define SYMBOL_CLASS(symbol) (symbol)->aclass #define SYMBOL_TYPE(symbol) (symbol)->type #define SYMBOL_LINE(symbol) (symbol)->line +#define SYMBOL_SYMTAB(symbol) (symbol)->symtab #define SYMBOL_BASEREG(symbol) (symbol)->aux_value.basereg #define SYMBOL_OBJFILE(symbol) (symbol)->aux_value.objfile #define SYMBOL_OPS(symbol) (symbol)->ops /cvs/src/src/gdb/testsuite/gdb.base/included.c,v --> standard output revision 1.1 --- src/gdb/testsuite/gdb.base/included.c +++ src/gdb/testsuite/gdb.base/included.c 2007-12-21 21:10:02.262608000 +0000 @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 "included.h" + +int +main() +{ + return 0; +} /cvs/src/src/gdb/testsuite/gdb.base/included.exp,v --> standard output revision 1.1 --- src/gdb/testsuite/gdb.base/included.exp +++ src/gdb/testsuite/gdb.base/included.exp 2007-12-21 21:10:02.521938000 +0000 @@ -0,0 +1,46 @@ +# Copyright 2007 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. + +set testfile "included" +set srcfile ${testfile}.c +set binfile ${objdir}/${subdir}/${testfile} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested included.exp + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +gdb_test "set listsize 1" "" + +gdb_test "list main" ".*" +get_debug_format +set non_dwarf [expr ! [test_debug_format "DWARF 2"]] + +# We should be able to find the source file containing the definition, +# even though it was an included header. +if { $non_dwarf } { setup_xfail *-*-* } +gdb_test "list integer" "int integer;" + +gdb_test "ptype integer" "type = int" + +# We should report that integer comes from the header file. +if { $non_dwarf } { setup_xfail *-*-* } +gdb_test "info variables integer" "\r\nFile \[^\r\n\]*/${subdir}/${testfile}.h:\r\nint integer;" /cvs/src/src/gdb/testsuite/gdb.base/included.h,v --> standard output revision 1.1 --- src/gdb/testsuite/gdb.base/included.h +++ src/gdb/testsuite/gdb.base/included.h 2007-12-21 21:10:02.732382000 +0000 @@ -0,0 +1,20 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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;