This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Follow specific symbol's DW_AT_decl_file


Hi,

Debby Townsend <dstownse(at)us.ibm.com>:
------------------------------------------------------------------------------
Both the "info variable" and the "list" command, when given the name 
of an external variable which is defined in an #include'd file,  list 
the incorrect file-name.  In the case of "list" the line number is 
extrapolated correctly; but the wrong source file is listed. 

The problem does not occur for functions defined in the same 
#include'd file. 
------------------------------------------------------------------------------


The regression-smelling parts of the patch are about the file located in
various directories, currently the patch fills in `symtab->dirname' from the
main file of CU (Compilation Unit) - the non-primary filenames were not (much
or at all?) used so far.

I could not find any regression but maybe some more directory-intensive
testcase would be useful.  Request if you feel so.


Regarsd,
Jan
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=109921


2007-01-09  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* 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  <jan.kratochvil@redhat.com>

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]