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:
parent
75c8c9d72c
commit
f8eba3c616
76 changed files with 3544 additions and 2145 deletions
560
gdb/symtab.c
560
gdb/symtab.c
|
@ -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). */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue