2007-01-21 Jan Kratochvil <jan.kratochvil@redhat.com>
authorDaniel Jacobowitz <drow@false.org>
Sun, 21 Jan 2007 16:49:40 +0000 (16:49 +0000)
committerDaniel Jacobowitz <drow@false.org>
Sun, 21 Jan 2007 16:49:40 +0000 (16:49 +0000)
    Daniel Jacobowitz  <dan@codesourcery.com>

* 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.

* gdb.base/included.c, gdb.base/included.exp,
gdb.base/included.h: New files.

gdb/ChangeLog
gdb/buildsym.c
gdb/buildsym.h
gdb/dwarf2read.c
gdb/symtab.c
gdb/symtab.h
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/included.c [new file with mode: 0644]
gdb/testsuite/gdb.base/included.exp [new file with mode: 0644]
gdb/testsuite/gdb.base/included.h [new file with mode: 0644]

index c9d7091..66cd6c7 100644 (file)
@@ -1,3 +1,22 @@
+2007-01-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
+           Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * 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-20  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * symfile.c (allocate_symtab): Remove INIT_EXTRA_SYMTAB_INFO.
index e0e2d4d..ae0750a 100644 (file)
@@ -959,7 +959,10 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
            }
 
          /* 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 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
       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;
index 876b103..9b96fe8 100644 (file)
@@ -70,6 +70,7 @@ struct subfile
     enum language language;
     char *producer;
     char *debugformat;
+    struct symtab *symtab;
   };
 
 EXTERN struct subfile *subfiles;
index 37075f6..010b0bc 100644 (file)
@@ -341,6 +341,9 @@ struct dwarf2_cu
      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 @@ struct line_header
     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 @@ initialize_cu_func_list (struct dwarf2_cu *cu)
 }
 
 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 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   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 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
       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 @@ add_file_name (struct line_header *lh,
   fe->mod_time = mod_time;
   fe->length = length;
   fe->included_p = 0;
+  fe->symtab = NULL;
 }
  
 
@@ -6644,7 +6660,7 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
   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 @@ dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
               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 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
        {
          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:
index 4a5b1e2..e00edf7 100644 (file)
@@ -1133,6 +1133,10 @@ lookup_symbol (const char *name, const struct block *block,
   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 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
            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 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
          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 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
                  /* 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;
index 4e4061c..da637cb 100644 (file)
@@ -609,6 +609,10 @@ struct symbol
 
   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 @@ struct symbol
 #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
index c876e51..e45b6c3 100644 (file)
@@ -1,3 +1,9 @@
+2007-01-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
+           Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gdb.base/included.c, gdb.base/included.exp,
+       gdb.base/included.h: New files.
+
 2007-01-20  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * gdb.base/bigcore.c (RLIMIT_CAP): Define.
diff --git a/gdb/testsuite/gdb.base/included.c b/gdb/testsuite/gdb.base/included.c
new file mode 100644 (file)
index 0000000..677290b
--- /dev/null
@@ -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;
+}
diff --git a/gdb/testsuite/gdb.base/included.exp b/gdb/testsuite/gdb.base/included.exp
new file mode 100644 (file)
index 0000000..c3ed857
--- /dev/null
@@ -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;"
diff --git a/gdb/testsuite/gdb.base/included.h b/gdb/testsuite/gdb.base/included.h
new file mode 100644 (file)
index 0000000..130fc7f
--- /dev/null
@@ -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;