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] 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>
	    * linespec.c (minsym_found): Add new "linespec_p" argument.  Update all callers.
	    (maybe_same_source_file) New function.

Signed-off-by: Mihail-Marian Nistor <mihail.nistor@freescale.com>
---
 gdb/linespec.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 118 insertions(+), 5 deletions(-)

diff --git a/gdb/linespec.c b/gdb/linespec.c
index 8a2c8e3..e6b5ad7 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);
@@ -1582,7 +1585,7 @@ linespec_parse_basic (linespec_parser *parser)
   VEC (symbolp) *symbols, *labels;
   VEC (bound_minimal_symbol_d) *minimal_symbols;
   struct cleanup *cleanup;
-
+ 
   /* Get the next token.  */
   token = linespec_lexer_lex_one (parser);
 
@@ -1625,8 +1628,74 @@ linespec_parse_basic (linespec_parser *parser)
 
   /* Try looking it up as a function/method.  */
   find_linespec_symbols (PARSER_STATE (parser),
-			 PARSER_RESULT (parser)->file_symtabs, name,
-			 &symbols, &minimal_symbols);
+			 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)
+   {
+     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)
+      {
+        int ims;
+        bound_minimal_symbol_d *minsym;
+
+  	 VEC (symbolp) *symbols1;
+	 VEC (bound_minimal_symbol_d) *minimal_symbols1;
+
+	 find_linespec_symbols (PARSER_STATE (parser),
+                        file_symtabs,
+                        name, &symbols1, &minimal_symbols1);
+
+        /* 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 (symbols1)
+	   VEC_free(symbolp, symbols1);
+
+        /* Copy information about function/method from minimal_symbols1 to minimal_symbols vector. */
+	 if (minimal_symbols1)
+         {
+           for (ims = 0; VEC_iterate (bound_minimal_symbol_d, minimal_symbols1, ims, minsym); ++ims)
+            {
+              VEC_safe_push (bound_minimal_symbol_d, minimal_symbols, minsym);
+            }
+          
+           VEC_free (bound_minimal_symbol_d, minimal_symbols1);
+         }
+ 
+	 VEC_free (symtab_ptr, file_symtabs);
+      }
+   }
 
   if (symbols != NULL || minimal_symbols != NULL)
     {
@@ -2059,7 +2128,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 +2406,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 +3485,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. */
+  int need_filter = (ls->source_filename != NULL) ? 1 : 0;
+  if (need_filter)
+  {
+    int ix;
+    struct symtab *elt;
+    const char *name;
+    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)
+      {
+        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 +3547,7 @@ 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);
 }
 
-- 
1.9.1


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