@@ -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);
}
new file mode 100644
@@ -0,0 +1,16 @@
+void func2();
+
+static func()
+{
+}
+
+void func1()
+{
+ func2();
+ func();
+}
+
+int main()
+{
+ func1();
+}
new file mode 100644
@@ -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."
new file mode 100644
@@ -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