the "ambiguous linespec" series

gdb
2011-12-06  Joel Brobecker  <brobecker@acacore.com>

        * language.h (struct language_defn): Add new component
        la_symbol_name_compare.
        * symfile.h (struct quick_symbol_functions): Update the profile
        of parameter "name_matcher" for the expand_symtabs_matching
        method.  Update the documentation accordingly.
        * ada-lang.h (ada_name_for_lookup): Add declaration.
        * ada-lang.c (ada_name_for_lookup): New function, extracted out
        from ada_iterate_over_symbols.
        (ada_iterate_over_symbols): Do not encode symbol name anymore.
        (ada_expand_partial_symbol_name): Adjust profile.
        (ada_language_defn): Add value for la_symbol_name_compare field.
        * linespec.c: #include "ada-lang.h".
        (iterate_name_matcher): Add language parameter. Replace call
        to strcmp_iw by call to language->la_symbol_name_compare.
        (decode_variable): Encode COPY if current language is Ada.
        * dwarf2read.c (dw2_expand_symtabs_matching): Adjust profile
        of name_matcher parameter.  Adjust call to name_matcher.
        * psymtab.c (expand_symtabs_matching_via_partial): Likewise.
        (expand_partial_symbol_names): Update profile of parameter "fun".
        * psymtab.h (expand_partial_symbol_names): Update profile of
        parameter "fun".
        * symtab.c (demangle_for_lookup): Update function documentation.
        (search_symbols_name_matches): Add language parameter.
        (expand_partial_symbol_name): Likewise.
        * c-lang.c (c_language_defn, cplus_language_defn)
        (asm_language_defn, minimal_language_defn): Add value for
        la_symbol_name_compare field.
        * d-lang.c (d_language_defn): Likewise.
        * f-lang.c (f_language_defn): Ditto.
        * jv-lang.c (java_language_defn): Ditto.
        * m2-lang.c (m2_language_defn): Ditto.
        * objc-lang.c (objc_language_defn): Ditto.
        * opencl-lang.c (opencl_language_defn): Ditto.
        * p-lang.c (pascal_language_defn): Ditto.
        * language.c (unknown_language_defn, auto_language_defn)
        (local_language_defn): Ditto.

2011-12-06  Tom Tromey  <tromey@redhat.com>

	* linespec.c (iterate_over_all_matching_symtabs): Use
	LA_ITERATE_OVER_SYMBOLS.
	(lookup_prefix_sym, add_matching_symbols_to_info): Likewise.
	(find_function_symbols, decode_variable): Remove Ada special
	case.
	* language.h (struct language_defn) <la_iterate_over_symbols>: New
	field.
	(LA_ITERATE_OVER_SYMBOLS): New macro.
	* language.c (unknown_language_defn, auto_language_defn)
	(local_language_defn): Update.
	* c-lang.c (c_language_defn, cplus_language_defn)
	(asm_language_defn, minimal_language_defn): Update.
	* d-lang.c (d_language_defn): Update.
	* f-lang.c (f_language_defn): Update.
	* jv-lang.c (java_language_defn): Update.
	* m2-lang.c (m2_language_defn): Update.
	* objc-lang.c (objc_language_defn): Update.
	* opencl-lang.c (opencl_language_defn): Update.
	* p-lang.c (pascal_language_defn): Update.
	* ada-lang.c (ada_iterate_over_symbols): New function.
	(ada_language_defn): Update.

2011-12-06  Tom Tromey  <tromey@redhat.com>
	    Joel Brobecker  <brobecker@acacore.com>

	PR breakpoints/13105, PR objc/8341, PR objc/8343, PR objc/8366,
	PR objc/8535, PR breakpoints/11657, PR breakpoints/11970,
	PR breakpoints/12023, PR breakpoints/12334, PR breakpoints/12856,
	PR shlibs/8929, PR shlibs/7393:
	* python/py-type.c (compare_maybe_null_strings): Rename from
	compare_strings.
	(check_types_equal): Update.
	* utils.c (compare_strings): New function.
	* tui/tui-winsource.c (tui_update_breakpoint_info): Update for
	location changes.
	* tracepoint.c (scope_info): Update.
	(trace_find_line_command): Use DECODE_LINE_FUNFIRSTLINE.
	* symtab.h (iterate_over_minimal_symbols)
	(iterate_over_some_symtabs, iterate_over_symtabs)
	(find_pcs_for_symtab_line, iterate_over_symbols)
	(demangle_for_lookup): Declare.
	(expand_line_sal): Remove.
	* symtab.c (iterate_over_some_symtabs, iterate_over_symtabs)
	(lookup_symtab_callback): New functions.
	(lookup_symtab): Rewrite.
	(demangle_for_lookup): New function, extract from
	lookup_symbol_in_language.
	(lookup_symbol_in_language): Use it.
	(iterate_over_symbols): New function.
	(find_line_symtab): Update.
	(find_pcs_for_symtab_line): New functions.
	(find_line_common): Add 'start' argument.
	(decode_line_spec): Update.  Change argument to 'flags', change
	interpretation.
	(append_expanded_sal): Remove.
	(append_exact_match_to_sals): Remove.
	(expand_line_sal): Remove.
	* symfile.h (struct quick_symbol_functions) <lookup_symtab>:
	Remove.
	<map_symtabs_matching_filename>: New field.
	* stack.c (func_command): Only look in the current program space.
	Use DECODE_LINE_FUNFIRSTLINE.
	* source.c (line_info): Set pspace on sal.  Check program space in
	the loop.  Use DECODE_LINE_LIST_MODE.
	(select_source_symtab): Use DECODE_LINE_FUNFIRSTLINE.
	* solib-target.c: Remove DEF_VEC_I(CORE_ADDR).
	* python/python.c (gdbpy_decode_line): Update.
	* psymtab.c (partial_map_expand_apply): New function.
	(partial_map_symtabs_matching_filename): Rename from
	lookup_partial_symbol.  Update arguments.
	(lookup_symtab_via_partial_symtab): Remove.
	(psym_functions): Update.
	* objc-lang.h (parse_selector, parse_method): Don't declare.
	(find_imps): Update.
	* objc-lang.c (parse_selector, parse_method): Now static.
	(find_methods): Change arguments.  Fill in a vector of symbol
	names.
	(uniquify_strings): New function.
	(find_imps): Change arguments.
	* minsyms.c (iterate_over_minimal_symbols): New function.
	* linespec.h (enum decode_line_flags): New.
	(struct linespec_sals): New.
	(struct linespec_result) <canonical>: Remove.
	<pre_expanded, addr_string, sals>: New fields.
	(destroy_linespec_result, make_cleanup_destroy_linespec_result)
	(decode_line_full): Declare.
	(decode_line_1): Update.
	* linespec.c (struct address_entry, struct linespec_state, struct
	collect_info): New types.
	(add_sal_to_sals_basic, add_sal_to_sals, hash_address_entry)
	(eq_address_entry, maybe_add_address): New functions.
	(total_number_of_methods): Remove.
	(iterate_name_matcher, iterate_over_all_matching_symtabs): New
	functions.
	(find_methods): Change arguments.  Don't canonicalize input.
	Simplify logic.
	(add_matching_methods, add_constructors)
	(build_canonical_line_spec): Remove.
	(filter_results, convert_results_to_lsals): New functions.
	(decode_line_2): Change arguments.  Rewrite for new data
	structures.
	(decode_line_internal): Rename from decode_line_1.  Change
	arguments.  Add cleanups.  Update for new data structures.
	(linespec_state_constructor, linespec_state_destructor)
	(decode_line_full, decode_line_1): New functions.
	(decode_indirect): Change arguments.  Update.
	(locate_first_half): Use skip_spaces.
	(decode_objc): Change arguments.  Update for new data structures.
	Simplify logic.
	(decode_compound): Change arguments.  Add cleanups.  Remove
	fallback code, replace with error.
	(struct decode_compound_collector): New type.
	(collect_one_symbol): New function.
	(lookup_prefix_sym): Change arguments.  Update.
	(compare_symbol_name, add_all_symbol_names_from_pspace)
	(find_superclass_methods ): New functions.
	(find_method): Rewrite.
	(struct symtab_collector): New type.
	(add_symtabs_to_list, collect_symtabs_from_filename): New
	functions.
	(symtabs_from_filename): Change API.  Rename from
	symtab_from_filename.
	(collect_function_symbols): New function.
	(find_function_symbols): Change API.  Rename from
	find_function_symbol.  Rewrite.
	(decode_all_digits): Change arguments.  Rewrite.
	(decode_dollar): Change arguments.  Use decode_variable.
	(decode_label): Change arguments.  Rewrite.
	(collect_symbols): New function.
	(minsym_found): Change arguments.  Rewrite.
	(check_minsym, search_minsyms_for_name)
	(add_matching_symbols_to_info): New function.
	(decode_variable): Change arguments.  Iterate over all symbols.
	(symbol_found): Remove.
	(symbol_to_sal): New function.
	(init_linespec_result, destroy_linespec_result)
	(cleanup_linespec_result, make_cleanup_destroy_linespec_result):
	New functions.
	(decode_digits_list_mode, decode_digits_ordinary): New functions.
	* dwarf2read.c (dw2_map_expand_apply): New function.
	(dw2_map_symtabs_matching_filename): Rename from
	dw2_lookup_symtab.  Change arguments.
	(dwarf2_gdb_index_functions): Update.
	* dwarf2loc.c: Remove DEF_VEC_I(CORE_ADDR).
	* defs.h (compare_strings): Declare.
	* cli/cli-cmds.c (compare_strings): Move to utils.c.
	(edit_command, list_command): Use DECODE_LINE_LIST_MODE.  Call
	filter_sals.
	(compare_symtabs, filter_sals): New functions.
	* breakpoint.h (struct bp_location) <line_number, source_file>:
	New fields.
	(struct breakpoint) <line_number, source_file>: Remove.
	<filter>: New field.
	* breakpoint.c (print_breakpoint_location, init_raw_breakpoint)
	(momentary_breakpoint_from_master, add_location_to_breakpoint):
	Update for changes to locations.
	(init_breakpoint_sal): Add 'filter' argument.  Set 'filter' on
	breakpoint.
	(create_breakpoint_sal): Add 'filter' argument.
	(remove_sal, expand_line_sal_maybe): Remove.
	(create_breakpoints_sal): Remove 'sals' argument.  Handle
	pre-expanded sals and the filter.
	(parse_breakpoint_sals): Use decode_line_full.
	(check_fast_tracepoint_sals): Use get_sal_arch.
	(create_breakpoint): Create a linespec_sals.  Update.
	(break_range_command): Use decode_line_full.  Update.
	(until_break_command): Update.
	(clear_command): Update match conditions for linespec.c changes.
	Use DECODE_LINE_LIST_MODE.
	(say_where): Update for changes to locations.
	(bp_location_dtor): Free 'source_file'.
	(base_breakpoint_dtor): Free 'filter'.  Don't free 'source_file'.
	(update_static_tracepoint): Update for changes to locations.
	(update_breakpoint_locations): Disable ranged breakpoint if too
	many locations match.  Update.
	(addr_string_to_sals): Use decode_line_full.  Resolve all sal
	PCs.
	(breakpoint_re_set_default): Don't call expand_line_sal_maybe.
	(decode_line_spec_1): Update.  Change argument name to 'flags',
	change interpretation.
	* block.h (block_containing_function): Declare.
	* block.c (block_containing_function): New function.
	* skip.c (skip_function_command): Update.
	(skip_re_set): Update.
	* infcmd.c (jump_command): Use DECODE_LINE_FUNFIRSTLINE.
	* mi/mi-main.c (mi_cmd_trace_find): Use DECODE_LINE_FUNFIRSTLINE.
	* NEWS: Add entry.

2011-12-06  Tom Tromey  <tromey@redhat.com>

	* elfread.c (elf_gnu_ifunc_resolver_return_stop): Allow
	breakpoint's pspace to be NULL.
	* breakpoint.h (struct breakpoint) <pspace>: Update comment.
	* breakpoint.c (init_raw_breakpoint): Conditionally set
	breakpoint's pspace.
	(init_breakpoint_sal): Don't set breakpoint's pspace.
	(prepare_re_set_context): Conditionally switch program space.
	(addr_string_to_sals): Check executing_startup on location's
	program space.

2011-12-06  Tom Tromey  <tromey@redhat.com>

	* breakpoint.h (enum enable_state) <bp_startup_disabled>: Remove.
	* breakpoint.c (should_be_inserted): Explicitly check if program
	space is executing startup.
	(describe_other_breakpoints): Update.
	(disable_breakpoints_before_startup): Change executing_startup
	earlier.  Remove loop.
	(enable_breakpoints_after_startup): Likewise.
	(init_breakpoint_sal): Don't use bp_startup_disabled.
	(create_breakpoint): Don't use bp_startup_disabled.
	(update_global_location_list): Use should_be_inserted.
	(bkpt_re_set): Update.
gdb/testsuite
2011-12-06  Joel Brobecker  <brobecker@acacore.com>

        * gdb.ada/fullname_bp.exp: Add tests for other valid linespecs
        involving a fully qualified function name.

2011-12-06  Tom Tromey  <tromey@redhat.com>

	* gdb.ada/homonym.exp: Add three breakpoint tests.

2011-12-06  Tom Tromey  <tromey@redhat.com>

	* gdb.base/solib-weak.exp (do_test): Remove kfail.
	* gdb.trace/tracecmd.exp: Disable pending breakpoints earlier.
	* gdb.objc/objcdecode.exp: Update for output changes.
	* gdb.linespec/linespec.exp: New file.
	* gdb.linespec/lspec.cc: New file.
	* gdb.linespec/lspec.h: New file.
	* gdb.linespec/body.h: New file.
	* gdb.linespec/base/two/thefile.cc: New file.
	* gdb.linespec/base/one/thefile.cc: New file.
	* gdb.linespec/Makefile.in: New file.
	* gdb.cp/templates.exp (test_template_breakpoints): Update for
	output changes.
	* gdb.cp/re-set-overloaded.exp: Remove kfail.
	* gdb.cp/ovldbreak.exp: Update for output changes.  "all" test now
	makes one breakpoint.
	* gdb.cp/method2.exp (test_break): Update for output changes.
	* gdb.cp/mb-templates.exp: Update for output changes.
	* gdb.cp/mb-inline.exp: Update for output changes.
	* gdb.cp/mb-ctor.exp: Update for output changes.
	* gdb.cp/ovsrch.exp: Use fully-qualified names.
	* gdb.base/solib-symbol.exp: Run to main later.  Breakpoint now
	has multiple matches.
	* gdb.base/sepdebug.exp: Disable pending breakpoints.  Update for
	error message change.
	* gdb.base/list.exp (test_list_filename_and_number): Update for
	error message change.
	* gdb.base/break.exp: Disable pending breakpoints.  Update for
	output changes.
	* configure.ac: Add gdb.linespec.
	* configure: Rebuild.
	* Makefile.in (ALL_SUBDIRS): Add gdb.linespec.
gdb/doc
2011-12-06  Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (Set Breaks): Update for new behavior.
This commit is contained in:
Tom Tromey 2011-12-06 18:54:43 +00:00
parent 75c8c9d72c
commit f8eba3c616
76 changed files with 3544 additions and 2145 deletions

View file

@ -81,7 +81,7 @@ static void sources_info (char *, int);
static void output_source_filename (const char *, int *);
static int find_line_common (struct linetable *, int, int *);
static int find_line_common (struct linetable *, int, int *, int);
static struct symbol *lookup_symbol_aux (const char *name,
const struct block *block,
@ -147,44 +147,38 @@ multiple_symbols_select_mode (void)
const struct block *block_found;
/* Check for a symtab of a specific name; first in symtabs, then in
psymtabs. *If* there is no '/' in the name, a match after a '/'
in the symtab filename will also work. */
/* Check for a symtab of a specific name by searching some symtabs.
This is a helper function for callbacks of iterate_over_symtabs.
struct symtab *
lookup_symtab (const char *name)
The return value, NAME, FULL_PATH, REAL_PATH, CALLBACK, and DATA
are identical to the `map_symtabs_matching_filename' method of
quick_symbol_functions.
FIRST and AFTER_LAST indicate the range of symtabs to search.
AFTER_LAST is one past the last symtab to search; NULL means to
search until the end of the list. */
int
iterate_over_some_symtabs (const char *name,
const char *full_path,
const char *real_path,
int (*callback) (struct symtab *symtab,
void *data),
void *data,
struct symtab *first,
struct symtab *after_last)
{
int found;
struct symtab *s = NULL;
struct objfile *objfile;
char *real_path = NULL;
char *full_path = NULL;
struct cleanup *cleanup;
const char* base_name = lbasename (name);
cleanup = make_cleanup (null_cleanup, NULL);
/* Here we are interested in canonicalizing an absolute path, not
absolutizing a relative path. */
if (IS_ABSOLUTE_PATH (name))
for (s = first; s != NULL && s != after_last; s = s->next)
{
full_path = xfullpath (name);
make_cleanup (xfree, full_path);
real_path = gdb_realpath (name);
make_cleanup (xfree, real_path);
}
got_symtab:
/* First, search for an exact match. */
ALL_SYMTABS (objfile, s)
{
if (FILENAME_CMP (name, s->filename) == 0)
{
do_cleanups (cleanup);
return s;
}
if (FILENAME_CMP (name, s->filename) == 0)
{
if (callback (s, data))
return 1;
}
/* Before we invoke realpath, which can get expensive when many
files are involved, do a quick comparison of the basenames. */
@ -201,8 +195,8 @@ got_symtab:
if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
{
do_cleanups (cleanup);
return s;
if (callback (s, data))
return 1;
}
}
@ -216,62 +210,114 @@ got_symtab:
make_cleanup (xfree, rp);
if (FILENAME_CMP (real_path, rp) == 0)
{
do_cleanups (cleanup);
return s;
}
{
if (callback (s, data))
return 1;
}
}
}
}
}
/* Now, search for a matching tail (only if name doesn't have any dirs). */
if (lbasename (name) == name)
ALL_SYMTABS (objfile, s)
{
if (FILENAME_CMP (lbasename (s->filename), name) == 0)
for (s = first; s != NULL && s != after_last; s = s->next)
{
do_cleanups (cleanup);
return s;
if (FILENAME_CMP (lbasename (s->filename), name) == 0)
{
if (callback (s, data))
return 1;
}
}
}
return 0;
}
/* Check for a symtab of a specific name; first in symtabs, then in
psymtabs. *If* there is no '/' in the name, a match after a '/'
in the symtab filename will also work.
Calls CALLBACK with each symtab that is found and with the supplied
DATA. If CALLBACK returns true, the search stops. */
void
iterate_over_symtabs (const char *name,
int (*callback) (struct symtab *symtab,
void *data),
void *data)
{
struct symtab *s = NULL;
struct objfile *objfile;
char *real_path = NULL;
char *full_path = NULL;
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
/* Here we are interested in canonicalizing an absolute path, not
absolutizing a relative path. */
if (IS_ABSOLUTE_PATH (name))
{
full_path = xfullpath (name);
make_cleanup (xfree, full_path);
real_path = gdb_realpath (name);
make_cleanup (xfree, real_path);
}
ALL_OBJFILES (objfile)
{
if (iterate_over_some_symtabs (name, full_path, real_path, callback, data,
objfile->symtabs, NULL))
{
do_cleanups (cleanups);
return;
}
}
/* Same search rules as above apply here, but now we look thru the
psymtabs. */
found = 0;
ALL_OBJFILES (objfile)
{
if (objfile->sf
&& objfile->sf->qf->lookup_symtab (objfile, name, full_path, real_path,
&s))
&& objfile->sf->qf->map_symtabs_matching_filename (objfile,
name,
full_path,
real_path,
callback,
data))
{
found = 1;
break;
do_cleanups (cleanups);
return;
}
}
if (s != NULL)
{
do_cleanups (cleanup);
return s;
}
if (!found)
{
do_cleanups (cleanup);
return NULL;
}
/* At this point, we have located the psymtab for this file, but
the conversion to a symtab has failed. This usually happens
when we are looking up an include file. In this case,
PSYMTAB_TO_SYMTAB doesn't return a symtab, even though one has
been created. So, we need to run through the symtabs again in
order to find the file.
XXX - This is a crock, and should be fixed inside of the
symbol parsing routines. */
goto got_symtab;
do_cleanups (cleanups);
}
/* The callback function used by lookup_symtab. */
static int
lookup_symtab_callback (struct symtab *symtab, void *data)
{
struct symtab **result_ptr = data;
*result_ptr = symtab;
return 1;
}
/* A wrapper for iterate_over_symtabs that returns the first matching
symtab, or NULL. */
struct symtab *
lookup_symtab (const char *name)
{
struct symtab *result = NULL;
iterate_over_symtabs (name, lookup_symtab_callback, &result);
return result;
}
/* Mangle a GDB method stub type. This actually reassembles the pieces of the
full method name, which consist of the class name (from T), the unadorned
@ -1006,33 +1052,30 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
return sym;
}
/* Find the definition for a specified symbol name NAME
in domain DOMAIN, visible from lexical block BLOCK.
Returns the struct symbol pointer, or zero if no symbol is found.
C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
NAME is a field of the current implied argument `this'. If so set
*IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
BLOCK_FOUND is set to the block in which NAME is found (in the case of
a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
/* Compute the demangled form of NAME as used by the various symbol
lookup functions. The result is stored in *RESULT_NAME. Returns a
cleanup which can be used to clean up the result.
/* This function has a bunch of loops in it and it would seem to be
attractive to put in some QUIT's (though I'm not really sure
whether it can run long enough to be really important). But there
are a few calls for which it would appear to be bad news to quit
out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c. (Note
that there is C++ code below which can error(), but that probably
doesn't affect these calls since they are looking for a known
variable and thus can probably assume it will never hit the C++
code). */
For Ada, this function just sets *RESULT_NAME to NAME, unmodified.
Normally, Ada symbol lookups are performed using the encoded name
rather than the demangled name, and so it might seem to make sense
for this function to return an encoded version of NAME.
Unfortunately, we cannot do this, because this function is used in
circumstances where it is not appropriate to try to encode NAME.
For instance, when displaying the frame info, we demangle the name
of each parameter, and then perform a symbol lookup inside our
function using that demangled name. In Ada, certain functions
have internally-generated parameters whose name contain uppercase
characters. Encoding those name would result in those uppercase
characters to become lowercase, and thus cause the symbol lookup
to fail. */
struct symbol *
lookup_symbol_in_language (const char *name, const struct block *block,
const domain_enum domain, enum language lang,
int *is_a_field_of_this)
struct cleanup *
demangle_for_lookup (const char *name, enum language lang,
const char **result_name)
{
char *demangled_name = NULL;
const char *modified_name = NULL;
struct symbol *returnval;
struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
modified_name = name;
@ -1079,6 +1122,38 @@ lookup_symbol_in_language (const char *name, const struct block *block,
}
}
*result_name = modified_name;
return cleanup;
}
/* Find the definition for a specified symbol name NAME
in domain DOMAIN, visible from lexical block BLOCK.
Returns the struct symbol pointer, or zero if no symbol is found.
C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
NAME is a field of the current implied argument `this'. If so set
*IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
BLOCK_FOUND is set to the block in which NAME is found (in the case of
a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
/* This function has a bunch of loops in it and it would seem to be
attractive to put in some QUIT's (though I'm not really sure
whether it can run long enough to be really important). But there
are a few calls for which it would appear to be bad news to quit
out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c. (Note
that there is C++ code below which can error(), but that probably
doesn't affect these calls since they are looking for a known
variable and thus can probably assume it will never hit the C++
code). */
struct symbol *
lookup_symbol_in_language (const char *name, const struct block *block,
const domain_enum domain, enum language lang,
int *is_a_field_of_this)
{
const char *modified_name;
struct symbol *returnval;
struct cleanup *cleanup = demangle_for_lookup (name, lang, &modified_name);
returnval = lookup_symbol_aux (modified_name, block, domain, lang,
is_a_field_of_this);
do_cleanups (cleanup);
@ -1771,6 +1846,44 @@ lookup_block_symbol (const struct block *block, const char *name,
}
}
/* Iterate over the symbols named NAME, matching DOMAIN, starting with
BLOCK.
For each symbol that matches, CALLBACK is called. The symbol and
DATA are passed to the callback.
If CALLBACK returns zero, the iteration ends. Otherwise, the
search continues. This function iterates upward through blocks.
When the outermost block has been finished, the function
returns. */
void
iterate_over_symbols (const struct block *block, const char *name,
const domain_enum domain,
int (*callback) (struct symbol *, void *),
void *data)
{
while (block)
{
struct dict_iterator iter;
struct symbol *sym;
for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
sym != NULL;
sym = dict_iter_name_next (name, &iter))
{
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
SYMBOL_DOMAIN (sym), domain))
{
if (!callback (sym, data))
return;
}
}
block = BLOCK_SUPERBLOCK (block);
}
}
/* Find the symtab associated with PC and SECTION. Look through the
psymtabs and read in another symtab if necessary. */
@ -2196,7 +2309,7 @@ find_line_symtab (struct symtab *symtab, int line,
/* First try looking it up in the given symtab. */
best_linetable = LINETABLE (symtab);
best_symtab = symtab;
best_index = find_line_common (best_linetable, line, &exact);
best_index = find_line_common (best_linetable, line, &exact, 0);
if (best_index < 0 || !exact)
{
/* Didn't find an exact match. So we better keep looking for
@ -2241,7 +2354,7 @@ find_line_symtab (struct symtab *symtab, int line,
&& FILENAME_CMP (symtab->fullname, s->fullname) != 0)
continue;
l = LINETABLE (s);
ind = find_line_common (l, line, &exact);
ind = find_line_common (l, line, &exact, 0);
if (ind >= 0)
{
if (exact)
@ -2272,6 +2385,46 @@ done:
return best_symtab;
}
/* Given SYMTAB, returns all the PCs function in the symtab that
exactly match LINE. Returns NULL if there are no exact matches,
but updates BEST_ITEM in this case. */
VEC (CORE_ADDR) *
find_pcs_for_symtab_line (struct symtab *symtab, int line,
struct linetable_entry **best_item)
{
int start = 0, ix;
struct symbol *previous_function = NULL;
VEC (CORE_ADDR) *result = NULL;
/* First, collect all the PCs that are at this line. */
while (1)
{
int was_exact;
int idx;
idx = find_line_common (LINETABLE (symtab), line, &was_exact, start);
if (idx < 0)
break;
if (!was_exact)
{
struct linetable_entry *item = &LINETABLE (symtab)->item[idx];
if (*best_item == NULL || item->line < (*best_item)->line)
*best_item = item;
break;
}
VEC_safe_push (CORE_ADDR, result, LINETABLE (symtab)->item[idx].pc);
start = idx + 1;
}
return result;
}
/* Set the PC value for a given source file and line number and return true.
Returns zero for invalid line number (and sets the PC to 0).
@ -2340,12 +2493,13 @@ find_line_pc_range (struct symtab_and_line sal, CORE_ADDR *startptr,
/* Given a line table and a line number, return the index into the line
table for the pc of the nearest line whose number is >= the specified one.
Return -1 if none is found. The value is >= 0 if it is an index.
START is the index at which to start searching the line table.
Set *EXACT_MATCH nonzero if the value returned is an exact match. */
static int
find_line_common (struct linetable *l, int lineno,
int *exact_match)
int *exact_match, int start)
{
int i;
int len;
@ -2365,7 +2519,7 @@ find_line_common (struct linetable *l, int lineno,
return -1;
len = l->nitems;
for (i = 0; i < len; i++)
for (i = start; i < len; i++)
{
struct linetable_entry *item = &(l->item[i]);
@ -3012,7 +3166,8 @@ search_symbols_file_matches (const char *filename, void *user_data)
/* A callback for expand_symtabs_matching. */
static int
search_symbols_name_matches (const char *symname, void *user_data)
search_symbols_name_matches (const struct language_defn *language,
const char *symname, void *user_data)
{
struct search_symbols_data *data = user_data;
@ -3820,7 +3975,8 @@ add_macro_name (const char *name, const struct macro_definition *ignore,
/* A callback for expand_partial_symbol_names. */
static int
expand_partial_symbol_name (const char *name, void *user_data)
expand_partial_symbol_name (const struct language_defn *language,
const char *name, void *user_data)
{
struct add_name_data *datum = (struct add_name_data *) user_data;
@ -4518,7 +4674,7 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
}
struct symtabs_and_lines
decode_line_spec (char *string, int funfirstline)
decode_line_spec (char *string, int flags)
{
struct symtabs_and_lines sals;
struct symtab_and_line cursal;
@ -4530,9 +4686,8 @@ decode_line_spec (char *string, int funfirstline)
and get a default or it will recursively call us! */
cursal = get_current_source_symtab_and_line ();
sals = decode_line_1 (&string, funfirstline,
cursal.symtab, cursal.line,
NULL);
sals = decode_line_1 (&string, flags,
cursal.symtab, cursal.line);
if (*string)
error (_("Junk at end of line specification: %s"), string);
@ -4620,211 +4775,6 @@ symtab_observer_executable_changed (void)
set_main_name (NULL);
}
/* Helper to expand_line_sal below. Appends new sal to SAL,
initializing it from SYMTAB, LINENO and PC. */
static void
append_expanded_sal (struct symtabs_and_lines *sal,
struct program_space *pspace,
struct symtab *symtab,
int lineno, CORE_ADDR pc)
{
sal->sals = xrealloc (sal->sals,
sizeof (sal->sals[0])
* (sal->nelts + 1));
init_sal (sal->sals + sal->nelts);
sal->sals[sal->nelts].pspace = pspace;
sal->sals[sal->nelts].symtab = symtab;
sal->sals[sal->nelts].section = NULL;
sal->sals[sal->nelts].end = 0;
sal->sals[sal->nelts].line = lineno;
sal->sals[sal->nelts].pc = pc;
++sal->nelts;
}
/* Helper to expand_line_sal below. Search in the symtabs for any
linetable entry that exactly matches FULLNAME and LINENO and append
them to RET. If FULLNAME is NULL or if a symtab has no full name,
use FILENAME and LINENO instead. If there is at least one match,
return 1; otherwise, return 0, and return the best choice in BEST_ITEM
and BEST_SYMTAB. */
static int
append_exact_match_to_sals (char *filename, char *fullname, int lineno,
struct symtabs_and_lines *ret,
struct linetable_entry **best_item,
struct symtab **best_symtab)
{
struct program_space *pspace;
struct objfile *objfile;
struct symtab *symtab;
int exact = 0;
int j;
*best_item = 0;
*best_symtab = 0;
ALL_PSPACES (pspace)
ALL_PSPACE_SYMTABS (pspace, objfile, symtab)
{
if (FILENAME_CMP (filename, symtab->filename) == 0)
{
struct linetable *l;
int len;
if (fullname != NULL
&& symtab_to_fullname (symtab) != NULL
&& FILENAME_CMP (fullname, symtab->fullname) != 0)
continue;
l = LINETABLE (symtab);
if (!l)
continue;
len = l->nitems;
for (j = 0; j < len; j++)
{
struct linetable_entry *item = &(l->item[j]);
if (item->line == lineno)
{
exact = 1;
append_expanded_sal (ret, objfile->pspace,
symtab, lineno, item->pc);
}
else if (!exact && item->line > lineno
&& (*best_item == NULL
|| item->line < (*best_item)->line))
{
*best_item = item;
*best_symtab = symtab;
}
}
}
}
return exact;
}
/* Compute a set of all sals in all program spaces that correspond to
same file and line as SAL and return those. If there are several
sals that belong to the same block, only one sal for the block is
included in results. */
struct symtabs_and_lines
expand_line_sal (struct symtab_and_line sal)
{
struct symtabs_and_lines ret;
int i, j;
struct objfile *objfile;
int lineno;
int deleted = 0;
struct block **blocks = NULL;
int *filter;
struct cleanup *old_chain;
ret.nelts = 0;
ret.sals = NULL;
/* Only expand sals that represent file.c:line. */
if (sal.symtab == NULL || sal.line == 0 || sal.pc != 0)
{
ret.sals = xmalloc (sizeof (struct symtab_and_line));
ret.sals[0] = sal;
ret.nelts = 1;
return ret;
}
else
{
struct program_space *pspace;
struct linetable_entry *best_item = 0;
struct symtab *best_symtab = 0;
int exact = 0;
char *match_filename;
lineno = sal.line;
match_filename = sal.symtab->filename;
/* We need to find all symtabs for a file which name
is described by sal. We cannot just directly
iterate over symtabs, since a symtab might not be
yet created. We also cannot iterate over psymtabs,
calling PSYMTAB_TO_SYMTAB and working on that symtab,
since PSYMTAB_TO_SYMTAB will return NULL for psymtab
corresponding to an included file. Therefore, we do
first pass over psymtabs, reading in those with
the right name. Then, we iterate over symtabs, knowing
that all symtabs we're interested in are loaded. */
old_chain = save_current_program_space ();
ALL_PSPACES (pspace)
{
set_current_program_space (pspace);
ALL_PSPACE_OBJFILES (pspace, objfile)
{
if (objfile->sf)
objfile->sf->qf->expand_symtabs_with_filename (objfile,
sal.symtab->filename);
}
}
do_cleanups (old_chain);
/* Now search the symtab for exact matches and append them. If
none is found, append the best_item and all its exact
matches. */
symtab_to_fullname (sal.symtab);
exact = append_exact_match_to_sals (sal.symtab->filename,
sal.symtab->fullname, lineno,
&ret, &best_item, &best_symtab);
if (!exact && best_item)
append_exact_match_to_sals (best_symtab->filename,
best_symtab->fullname, best_item->line,
&ret, &best_item, &best_symtab);
}
/* For optimized code, compiler can scatter one source line accross
disjoint ranges of PC values, even when no duplicate functions
or inline functions are involved. For example, 'for (;;)' inside
non-template non-inline non-ctor-or-dtor function can result
in two PC ranges. In this case, we don't want to set breakpoint
on first PC of each range. To filter such cases, we use containing
blocks -- for each PC found above we see if there are other PCs
that are in the same block. If yes, the other PCs are filtered out. */
old_chain = save_current_program_space ();
filter = alloca (ret.nelts * sizeof (int));
blocks = alloca (ret.nelts * sizeof (struct block *));
for (i = 0; i < ret.nelts; ++i)
{
set_current_program_space (ret.sals[i].pspace);
filter[i] = 1;
blocks[i] = block_for_pc_sect (ret.sals[i].pc, ret.sals[i].section);
}
do_cleanups (old_chain);
for (i = 0; i < ret.nelts; ++i)
if (blocks[i] != NULL)
for (j = i+1; j < ret.nelts; ++j)
if (blocks[j] == blocks[i])
{
filter[j] = 0;
++deleted;
break;
}
{
struct symtab_and_line *final =
xmalloc (sizeof (struct symtab_and_line) * (ret.nelts-deleted));
for (i = 0, j = 0; i < ret.nelts; ++i)
if (filter[i])
final[j++] = ret.sals[i];
ret.nelts -= deleted;
xfree (ret.sals);
ret.sals = final;
}
return ret;
}
/* Return 1 if the supplied producer string matches the ARM RealView
compiler (armcc). */