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 v2] Bug 17394: we cannot put a break-point at a global function for ASM file


We need to cover the following test case: the user wants to do an action
only for the function that was defined into a selected file name.
An example: the user wants to put a breakpoint only for functions "func"
that was defined in the file name "file.s"
    e.i. of gdb command line: b file.s:func
Due to the limitation that the GAS doesn't generate debug info for
functions/symbols, we cannot find the function information if we look only
in file symbtabs that was collected by using the file name specified by
the user.
We need to look into a global default symtab if we want to find minimal
information about functions that were written in the ASM file.
And after that, we need to select only functions that were defined into
the file name specified by the user.

gdb/ChangeLog
      2014-09-15  Mihail-Marian Nistor  <mihail.nistor@freescale.com>
      PR gdb/17394
	    * linespec.c (minsym_found): Add new "linespec_p" argument.
      Update all callers.
	    (maybe_same_source_file) New function.

gdb/testsuite/ChangeLog
      2014-09-15  Mihail-Marian Nistor  <mihail.nistor@freescale.com>
      PR gdb/17394
	    * gdb.arch/break-asm-x86-file0.s: New file.
	    * gdb.arch/break-asm-x86-file.c: New file.
	    * gdb.arch/break-asm-x86-file.exp: New file.

Signed-off-by: Mihail-Marian Nistor <mihail.nistor@freescale.com>
---
 gdb/linespec.c                                | 126 +++++++++++++++++++++++++-
 gdb/testsuite/gdb.arch/break-asm-x86-file.c   |  16 ++++
 gdb/testsuite/gdb.arch/break-asm-x86-file.exp |  39 ++++++++
 gdb/testsuite/gdb.arch/break-asm-x86-file0.s  |  15 +++
 4 files changed, 194 insertions(+), 2 deletions(-)
 create mode 100644 gdb/testsuite/gdb.arch/break-asm-x86-file.c
 create mode 100644 gdb/testsuite/gdb.arch/break-asm-x86-file.exp
 create mode 100644 gdb/testsuite/gdb.arch/break-asm-x86-file0.s

diff --git a/gdb/linespec.c b/gdb/linespec.c
index 8a2c8e3..2592f37 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -363,8 +363,11 @@ static void decode_digits_list_mode (struct linespec_state *self,
 				     struct symtabs_and_lines *values,
 				     struct symtab_and_line val);
 
+static int maybe_same_source_file (struct symtab_and_line *sal, linespec_p ls);
+
 static void minsym_found (struct linespec_state *self, struct objfile *objfile,
 			  struct minimal_symbol *msymbol,
+			  linespec_p ls,
 			  struct symtabs_and_lines *result);
 
 static int compare_symbols (const void *a, const void *b);
@@ -1628,6 +1631,80 @@ linespec_parse_basic (linespec_parser *parser)
 			 PARSER_RESULT (parser)->file_symtabs, name,
 			 &symbols, &minimal_symbols);
 
+  /* We need to cover the following test case: the user wants
+     to do an action only for the function that was defined
+     into a selected file name.
+     An example: the user wants to put a breakpoint only for
+     functions "func" that was defined in the file name "file.s"
+         e.i. of gdb command line: b file.s:func
+     Due to the limitation that the GAS doesn't generate debug
+     info for functions/symbols,we cannot find the function
+     information if we look only in file symbtabs that was collected
+     by using the file name specified by the user. We need to look
+     into a global default symtab if we want to find minimal
+     information about functions that were written in the ASM file.
+     And after that, we need to select only functions that
+     were defined into the file name specified by the user. We do this
+     action into the mimi_found in the minsym_found function */
+
+  /* Verify if the user has specified a file name that was used
+     to build the current file symtabs. */
+  if (PARSER_RESULT (parser)->source_filename != NULL)
+    {
+      VEC (symtab_ptr) *file_symtabs = NULL;
+      int ix;
+      struct symtab *elt;
+      int global_symtabs = 0;
+
+      /* Verify if we have already used the global default symtab
+         information to find the function/method. */
+      for (ix = 0;
+	   VEC_iterate (symtab_ptr, PARSER_RESULT (parser)->file_symtabs,
+			ix, elt);
+	   ++ix)
+	{
+	  VEC_safe_push (symtab_ptr, file_symtabs, elt);
+	  if (elt == NULL)
+	    global_symtabs = 1;
+	}
+
+      if (!global_symtabs)
+	VEC_safe_push (symtab_ptr, file_symtabs, NULL);
+
+      if (file_symtabs != NULL)
+	{
+	  int ims;
+	  bound_minimal_symbol_d *minsym;
+	  VEC (symbolp) *ignore_symbols;
+	  VEC (bound_minimal_symbol_d) *minimal_syms;
+
+	  find_linespec_symbols (PARSER_STATE (parser),
+				 file_symtabs, name,
+				 &ignore_symbols, &minimal_syms);
+
+	  /* We should ignore information about function/method that
+	     were found by using .debug_info information, because this
+	     information was already stored into the symbols vector. */
+	  if (ignore_symbols)
+	    VEC_free(symbolp, ignore_symbols);
+
+	  /* Copy information about function/method from minimal_syms
+	     to minimal_symbols vector. */
+	  if (minimal_syms != NULL)
+	    {
+	      for (ims = 0;
+		   VEC_iterate (bound_minimal_symbol_d, minimal_syms,
+				ims, minsym);
+		   ++ims)
+		VEC_safe_push (bound_minimal_symbol_d,
+			       minimal_symbols, minsym);
+
+		VEC_free (bound_minimal_symbol_d, minimal_syms);
+	    }
+	  VEC_free (symtab_ptr, file_symtabs);
+	}
+    }
+
   if (symbols != NULL || minimal_symbols != NULL)
     {
       PARSER_RESULT (parser)->function_symbols = symbols;
@@ -2059,7 +2136,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
 	    {
 	      pspace = elem->objfile->pspace;
 	      set_current_program_space (pspace);
-	      minsym_found (state, elem->objfile, elem->minsym, &sals);
+	      minsym_found (state, elem->objfile, elem->minsym, ls, &sals);
 	    }
 	}
     }
@@ -2337,6 +2414,13 @@ parse_linespec (linespec_parser *parser, const char **argptr)
   values = convert_linespec_to_sals (PARSER_STATE (parser),
 				     PARSER_RESULT (parser));
 
+  if (values.nelts == 0)
+    {
+      /* The symbol is not found. */
+      symbol_not_found_error (PARSER_RESULT (parser)->function_name,
+			      PARSER_RESULT (parser)->source_filename);
+    }
+
   return values;
 }
 
@@ -3409,12 +3493,49 @@ collect_symbols (struct symbol *sym, void *data)
   return 1; /* Continue iterating.  */
 }
 
+/* Check whether the user source file is the same as the source
+   file from SAL. If so, return 1.  Otherwise, return  0.  */
+static int
+maybe_same_source_file (struct symtab_and_line *sal, linespec_p ls)
+{
+  /* We know if the user has specified a source file name
+     by using the source_filename field from linespec. */
+  if (ls->source_filename != NULL)
+    {
+      int ix;
+      struct symtab *elt;
+      const char *fullname;
+
+      if (sal->symtab == NULL)
+	return 0;
+
+      fullname = symtab_to_fullname (sal->symtab);
+
+      for (ix = 0;
+	   VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt);
+	   ++ix)
+	{
+	  if (elt != NULL)
+	    {
+	      const char *name = symtab_to_fullname (elt);
+	      if (strcmp (fullname, name) == 0)
+		return 1;
+	    }
+	}
+
+      return 0;
+    }
+
+  return 1;
+}
+
 /* We've found a minimal symbol MSYMBOL in OBJFILE to associate with our
    linespec; return the SAL in RESULT.  */
 
 static void
 minsym_found (struct linespec_state *self, struct objfile *objfile,
 	      struct minimal_symbol *msymbol,
+	      linespec_p ls,
 	      struct symtabs_and_lines *result)
 {
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
@@ -3434,7 +3555,8 @@ minsym_found (struct linespec_state *self, struct objfile *objfile,
   if (self->funfirstline)
     skip_prologue_sal (&sal);
 
-  if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc))
+  if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc)
+    && maybe_same_source_file (&sal, ls))
     add_sal_to_sals (self, result, &sal, MSYMBOL_NATURAL_NAME (msymbol), 0);
 }
 
diff --git a/gdb/testsuite/gdb.arch/break-asm-x86-file.c b/gdb/testsuite/gdb.arch/break-asm-x86-file.c
new file mode 100644
index 0000000..ebaaa72
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/break-asm-x86-file.c
@@ -0,0 +1,16 @@
+void func2();
+
+static func()
+{
+}
+
+void func1()
+{
+  func2();
+  func();
+}
+
+int main()
+{
+  func1();
+}
diff --git a/gdb/testsuite/gdb.arch/break-asm-x86-file.exp b/gdb/testsuite/gdb.arch/break-asm-x86-file.exp
new file mode 100644
index 0000000..db304c5
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/break-asm-x86-file.exp
@@ -0,0 +1,39 @@
+# Copyright 2012-2014 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 3 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, see <http://www.gnu.org/licenses/>.
+
+# Bug 17394
+# Test for break-point at a global function only for a selected ASM file.
+
+standard_testfile .c
+set execfile $testfile
+set asm_file break-asm-x86-file0.s
+
+if { ![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] } then {
+    verbose "Skipping ${testfile}."
+    return
+}
+
+if {[prepare_for_testing ${testfile}.exp $execfile \
+	 [list $asm_file $srcfile ] \
+	 {debug nowarnings optimize=-O0}]} {
+    untested "Skipping ${testfile}."
+    return
+}
+
+clean_restart $execfile
+
+gdb_test "break $asm_file:func" \
+    "Breakpoint 1 at 0x\[0-9a-fA-F\]+: file .*$asm_file, line 15\\\." \
+    "set a break-point at a global function only for a selected ASM file."
diff --git a/gdb/testsuite/gdb.arch/break-asm-x86-file0.s b/gdb/testsuite/gdb.arch/break-asm-x86-file0.s
new file mode 100644
index 0000000..f6dd0c0
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/break-asm-x86-file0.s
@@ -0,0 +1,15 @@
+	.section .text
+
+	.global _func2
+_func2:
+	.global func2
+	.type   func2, @function
+func2:
+	ret
+
+	.global _func
+_func:
+	.global func
+       .type   func, @function
+func:
+	ret
-- 
1.9.1


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