diff options
author | Tom Tromey <tromey@redhat.com> | 2011-12-06 18:54:43 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2011-12-06 18:54:43 +0000 |
commit | f8eba3c61629b3c03ac1f33853eab4d8507adb9c (patch) | |
tree | 5cac92f7145c1521976f16ddd0374861e0b967c4 /gdb/symtab.c | |
parent | 75c8c9d72cb6cdf4ccbaa5082bd7037afaf0fe8e (diff) | |
download | gdb-f8eba3c61629b3c03ac1f33853eab4d8507adb9c.zip gdb-f8eba3c61629b3c03ac1f33853eab4d8507adb9c.tar.gz gdb-f8eba3c61629b3c03ac1f33853eab4d8507adb9c.tar.bz2 |
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.
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r-- | gdb/symtab.c | 560 |
1 files changed, 255 insertions, 305 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c index 3d94e6b..1ea4253 100644 --- a/gdb/symtab.c +++ b/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; - } + 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; - /* 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; + *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. + + 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. */ -/* 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) +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). */ |