X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsymtab.c;h=2b1f9558abeba0c8b95ad60779b57792450cc840;hb=7cbe16e99d8a61a168579354487902ee50413e08;hp=eb4e30d4556371553fb2ec4e034572e99750e0b0;hpb=1b0261195e3f11932c0f5657a74028f5814168eb;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symtab.c b/gdb/symtab.c index eb4e30d455..2b1f9558ab 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1,6 +1,6 @@ /* Symbol table lookup for the GNU debugger, GDB. - Copyright (C) 1986-2017 Free Software Foundation, Inc. + Copyright (C) 1986-2018 Free Software Foundation, Inc. This file is part of GDB. @@ -54,7 +54,7 @@ #include #include "cp-abi.h" #include "cp-support.h" -#include "observer.h" +#include "observable.h" #include "solist.h" #include "macrotab.h" #include "macroscope.h" @@ -66,6 +66,7 @@ #include "filename-seen-cache.h" #include "arch-utils.h" #include +#include "common/pathstuff.h" /* Forward declarations for local functions. */ @@ -75,6 +76,7 @@ static int find_line_common (struct linetable *, int, int *, int); static struct block_symbol lookup_symbol_aux (const char *name, + symbol_name_match_type match_type, const struct block *block, const domain_enum domain, enum language language, @@ -82,6 +84,7 @@ static struct block_symbol static struct block_symbol lookup_local_symbol (const char *name, + symbol_name_match_type match_type, const struct block *block, const domain_enum domain, enum language language); @@ -729,7 +732,6 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, { char *demangled = NULL; int i; - int recognized; if (gsymbol->language == language_unknown) gsymbol->language = language_auto; @@ -954,8 +956,7 @@ symbol_matches_search_name (const struct general_symbol_info *gsymbol, const lookup_name_info &name) { symbol_name_matcher_ftype *name_match - = language_get_symbol_name_matcher (language_def (gsymbol->language), - name); + = get_symbol_name_matcher (language_def (gsymbol->language), name); return name_match (symbol_search_name (gsymbol), name, NULL); } @@ -1774,14 +1775,18 @@ demangle_for_lookup_info::demangle_for_lookup_info if (without_params != NULL) { - m_demangled_name = demangle_for_lookup (without_params.get (), - lang, storage); + if (lookup_name.match_type () != symbol_name_match_type::SEARCH_NAME) + m_demangled_name = demangle_for_lookup (without_params.get (), + lang, storage); return; } } - m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (), - lang, storage); + if (lookup_name.match_type () == symbol_name_match_type::SEARCH_NAME) + m_demangled_name = lookup_name.name (); + else + m_demangled_name = demangle_for_lookup (lookup_name.name ().c_str (), + lang, storage); } /* See symtab.h. */ @@ -1877,7 +1882,9 @@ lookup_symbol_in_language (const char *name, const struct block *block, demangle_result_storage storage; const char *modified_name = demangle_for_lookup (name, lang, storage); - return lookup_symbol_aux (modified_name, block, domain, lang, + return lookup_symbol_aux (modified_name, + symbol_name_match_type::FULL, + block, domain, lang, is_a_field_of_this); } @@ -1895,6 +1902,16 @@ lookup_symbol (const char *name, const struct block *block, /* See symtab.h. */ +struct block_symbol +lookup_symbol_search_name (const char *search_name, const struct block *block, + domain_enum domain) +{ + return lookup_symbol_aux (search_name, symbol_name_match_type::SEARCH_NAME, + block, domain, language_asm, NULL); +} + +/* See symtab.h. */ + struct block_symbol lookup_language_this (const struct language_defn *lang, const struct block *block) @@ -1916,7 +1933,9 @@ lookup_language_this (const struct language_defn *lang, { struct symbol *sym; - sym = block_lookup_symbol (block, lang->la_name_of_this, VAR_DOMAIN); + sym = block_lookup_symbol (block, lang->la_name_of_this, + symbol_name_match_type::SEARCH_NAME, + VAR_DOMAIN); if (sym != NULL) { if (symbol_lookup_debug > 1) @@ -1987,7 +2006,8 @@ check_field (struct type *type, const char *name, (e.g., demangled name) of the symbol that we're looking for. */ static struct block_symbol -lookup_symbol_aux (const char *name, const struct block *block, +lookup_symbol_aux (const char *name, symbol_name_match_type match_type, + const struct block *block, const domain_enum domain, enum language language, struct field_of_this_result *is_a_field_of_this) { @@ -2016,7 +2036,7 @@ lookup_symbol_aux (const char *name, const struct block *block, /* Search specified block and its superiors. Don't search STATIC_BLOCK or GLOBAL_BLOCK. */ - result = lookup_local_symbol (name, block, domain, language); + result = lookup_local_symbol (name, match_type, block, domain, language); if (result.symbol != NULL) { if (symbol_lookup_debug) @@ -2098,7 +2118,9 @@ lookup_symbol_aux (const char *name, const struct block *block, Don't search STATIC_BLOCK or GLOBAL_BLOCK. */ static struct block_symbol -lookup_local_symbol (const char *name, const struct block *block, +lookup_local_symbol (const char *name, + symbol_name_match_type match_type, + const struct block *block, const domain_enum domain, enum language language) { @@ -2113,7 +2135,7 @@ lookup_local_symbol (const char *name, const struct block *block, while (block != static_block) { - sym = lookup_symbol_in_block (name, block, domain); + sym = lookup_symbol_in_block (name, match_type, block, domain); if (sym != NULL) return (struct block_symbol) {sym, block}; @@ -2166,7 +2188,8 @@ lookup_objfile_from_block (const struct block *block) /* See symtab.h. */ struct symbol * -lookup_symbol_in_block (const char *name, const struct block *block, +lookup_symbol_in_block (const char *name, symbol_name_match_type match_type, + const struct block *block, const domain_enum domain) { struct symbol *sym; @@ -2182,7 +2205,7 @@ lookup_symbol_in_block (const char *name, const struct block *block, domain_name (domain)); } - sym = block_lookup_symbol (block, name, domain); + sym = block_lookup_symbol (block, name, match_type, domain); if (sym) { if (symbol_lookup_debug > 1) @@ -2371,7 +2394,8 @@ lookup_symbol_via_quick_fns (struct objfile *objfile, int block_index, bv = COMPUNIT_BLOCKVECTOR (cust); block = BLOCKVECTOR_BLOCK (bv, block_index); - result.symbol = block_lookup_symbol (block, name, domain); + result.symbol = block_lookup_symbol (block, name, + symbol_name_match_type::FULL, domain); if (result.symbol == NULL) error_in_psymtab_expansion (block_index, name, cust); @@ -2484,7 +2508,9 @@ lookup_symbol_in_static_block (const char *name, domain_name (domain)); } - sym = lookup_symbol_in_block (name, static_block, domain); + sym = lookup_symbol_in_block (name, + symbol_name_match_type::FULL, + static_block, domain); if (symbol_lookup_debug) { fprintf_unfiltered (gdb_stdlog, @@ -2964,6 +2990,45 @@ find_pc_compunit_symtab (CORE_ADDR pc) { return find_pc_sect_compunit_symtab (pc, find_pc_mapped_section (pc)); } + +/* See symtab.h. */ + +struct symbol * +find_symbol_at_address (CORE_ADDR address) +{ + struct objfile *objfile; + + ALL_OBJFILES (objfile) + { + if (objfile->sf == NULL + || objfile->sf->qf->find_compunit_symtab_by_address == NULL) + continue; + + struct compunit_symtab *symtab + = objfile->sf->qf->find_compunit_symtab_by_address (objfile, address); + if (symtab != NULL) + { + const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (symtab); + + for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i) + { + struct block *b = BLOCKVECTOR_BLOCK (bv, i); + struct block_iterator iter; + struct symbol *sym; + + ALL_BLOCK_SYMBOLS (b, iter, sym) + { + if (SYMBOL_CLASS (sym) == LOC_STATIC + && SYMBOL_VALUE_ADDRESS (sym) == address) + return sym; + } + } + } + } + + return NULL; +} + /* Find the source file and line number for a given PC value and SECTION. @@ -2981,8 +3046,6 @@ find_pc_compunit_symtab (CORE_ADDR pc) find the one whose first PC is closer than that of the next line in this symtab. */ -/* If it's worth the effort, we could be using a binary search. */ - struct symtab_and_line find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) { @@ -3149,15 +3212,17 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) if (item->pc > pc && (!alt || item->pc < alt->pc)) alt = item; - for (i = 0; i < len; i++, item++) - { - /* Leave prev pointing to the linetable entry for the last line - that started at or before PC. */ - if (item->pc > pc) - break; + auto pc_compare = [](const CORE_ADDR & pc, + const struct linetable_entry & lhs)->bool + { + return pc < lhs.pc; + }; - prev = item; - } + struct linetable_entry *first = item; + struct linetable_entry *last = item + len; + item = std::upper_bound (first, last, pc, pc_compare); + if (item != first) + prev = item - 1; /* Found a matching item. */ /* At this point, prev points at the line whose start addr is <= pc, and item points at the next line. If we ran off the end of the linetable @@ -3180,10 +3245,10 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) } /* If another line (denoted by ITEM) is in the linetable and its - PC is after BEST's PC, but before the current BEST_END, then + PC is after BEST's PC, but before the current BEST_END, then use ITEM's PC as the new best_end. */ - if (best && i < len && item->pc > best->pc - && (best_end == 0 || best_end > item->pc)) + if (best && item < last && item->pc > best->pc + && (best_end == 0 || best_end > item->pc)) best_end = item->pc; } @@ -3888,14 +3953,14 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr) symbol * find_function_alias_target (bound_minimal_symbol msymbol) { - if (!msymbol_is_text (msymbol.minsym)) + CORE_ADDR func_addr; + if (!msymbol_is_function (msymbol.objfile, msymbol.minsym, &func_addr)) return NULL; - CORE_ADDR addr = BMSYMBOL_VALUE_ADDRESS (msymbol); - symbol *sym = find_pc_function (addr); + symbol *sym = find_pc_function (func_addr); if (sym != NULL && SYMBOL_CLASS (sym) == LOC_BLOCK - && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) == addr) + && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) == func_addr) return sym; return NULL; @@ -4244,7 +4309,6 @@ search_symbols (const char *regexp, enum search_domain kind, and or . */ const char *opend; const char *opname = operator_chars (regexp, &opend); - int errcode; if (*opname) { @@ -4640,26 +4704,12 @@ compare_symbol_name (const char *symbol_name, language symbol_language, const lookup_name_info &lookup_name, completion_match_result &match_res) { - const language_defn *lang; - - /* If we're completing for an expression and the symbol doesn't have - an explicit language set, fallback to the current language. Ada - minimal symbols won't have their language set to Ada, for - example, and if we compared using the default/C-like matcher, - then when completing e.g., symbols in a package named "pck", we'd - match internal Ada symbols like "pckS", which are invalid in an - Ada expression, unless you wrap them in '<' '>' to request a - verbatim match. */ - if (symbol_language == language_auto - && lookup_name.match_type () == symbol_name_match_type::EXPRESSION) - lang = current_language; - else - lang = language_def (symbol_language); + const language_defn *lang = language_def (symbol_language); symbol_name_matcher_ftype *name_match - = language_get_symbol_name_matcher (lang, lookup_name); + = get_symbol_name_matcher (lang, lookup_name); - return name_match (symbol_name, lookup_name, &match_res.match); + return name_match (symbol_name, lookup_name, &match_res); } /* See symtab.h. */ @@ -4688,31 +4738,17 @@ completion_list_add_name (completion_tracker &tracker, of matches. Note that the name is moved to freshly malloc'd space. */ { - char *newobj; - - if (word == text) - { - newobj = (char *) xmalloc (strlen (symname) + 5); - strcpy (newobj, symname); - } - else if (word > text) - { - /* Return some portion of symname. */ - newobj = (char *) xmalloc (strlen (symname) + 5); - strcpy (newobj, symname + (word - text)); - } - else - { - /* Return some of SYM_TEXT plus symname. */ - newobj = (char *) xmalloc (strlen (symname) + (text - word) + 5); - strncpy (newobj, word, text - word); - newobj[text - word] = '\0'; - strcat (newobj, symname); - } - - gdb::unique_xmalloc_ptr completion (newobj); - - tracker.add_completion (std::move (completion)); + gdb::unique_xmalloc_ptr completion + = make_completion_match_str (symname, text, word); + + /* Here we pass the match-for-lcd object to add_completion. Some + languages match the user text against substrings of symbol + names in some cases. E.g., in C++, "b push_ba" completes to + "std::vector::push_back", "std::string::push_back", etc., and + in this case we want the completion lowest common denominator + to be "push_back" instead of "std::". */ + tracker.add_completion (std::move (completion), + &match_res.match_for_lcd, text, word); } } @@ -4877,11 +4913,44 @@ completion_list_add_fields (completion_tracker &tracker, } } +/* See symtab.h. */ + +bool +symbol_is_function_or_method (symbol *sym) +{ + switch (TYPE_CODE (SYMBOL_TYPE (sym))) + { + case TYPE_CODE_FUNC: + case TYPE_CODE_METHOD: + return true; + default: + return false; + } +} + +/* See symtab.h. */ + +bool +symbol_is_function_or_method (minimal_symbol *msymbol) +{ + switch (MSYMBOL_TYPE (msymbol)) + { + case mst_text: + case mst_text_gnu_ifunc: + case mst_solib_trampoline: + case mst_file_text: + return true; + default: + return false; + } +} + /* Add matching symbols from SYMTAB to the current completion list. */ static void add_symtab_completions (struct compunit_symtab *cust, completion_tracker &tracker, + complete_symbol_mode mode, const lookup_name_info &lookup_name, const char *text, const char *word, enum type_code code) @@ -4900,6 +4969,9 @@ add_symtab_completions (struct compunit_symtab *cust, b = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), i); ALL_BLOCK_SYMBOLS (b, iter, sym) { + if (completion_skip_symbol (mode, sym)) + continue; + if (code == TYPE_CODE_UNDEF || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN && TYPE_CODE (SYMBOL_TYPE (sym)) == code)) @@ -4998,6 +5070,9 @@ default_collect_symbol_completion_matches_break_on { QUIT; + if (completion_skip_symbol (mode, msymbol)) + continue; + completion_list_add_msymbol (tracker, msymbol, lookup_name, sym_text, word); @@ -5008,7 +5083,7 @@ default_collect_symbol_completion_matches_break_on /* Add completions for all currently loaded symbol tables. */ ALL_COMPUNITS (objfile, cust) - add_symtab_completions (cust, tracker, lookup_name, + add_symtab_completions (cust, tracker, mode, lookup_name, sym_text, word, code); /* Look through the partial symtabs for all symbols which begin by @@ -5019,7 +5094,7 @@ default_collect_symbol_completion_matches_break_on [&] (compunit_symtab *symtab) /* expansion notify */ { add_symtab_completions (symtab, - tracker, lookup_name, + tracker, mode, lookup_name, sym_text, word, code); }, ALL_DOMAIN); @@ -5080,7 +5155,7 @@ default_collect_symbol_completion_matches_break_on if (current_language->la_macro_expansion == macro_expansion_c && code == TYPE_CODE_UNDEF) { - struct macro_scope *scope; + gdb::unique_xmalloc_ptr scope; /* This adds a macro's name to the current completion list. */ auto add_macro_name = [&] (const char *macro_name, @@ -5101,11 +5176,8 @@ default_collect_symbol_completion_matches_break_on completion time. */ scope = default_macro_scope (); if (scope) - { - macro_for_each_in_scope (scope->file, scope->line, - add_macro_name); - xfree (scope); - } + macro_for_each_in_scope (scope->file, scope->line, + add_macro_name); /* User-defined macros are always visible. */ macro_for_each (macro_user_macros, add_macro_name); @@ -5225,7 +5297,7 @@ collect_file_symbol_completion_matches (completion_tracker &tracker, iterate_over_symtabs (srcfile, [&] (symtab *s) { add_symtab_completions (SYMTAB_COMPUNIT (s), - tracker, lookup_name, + tracker, mode, lookup_name, sym_text, word, TYPE_CODE_UNDEF); return false; }); @@ -5239,30 +5311,7 @@ static void add_filename_to_list (const char *fname, const char *text, const char *word, completion_list *list) { - char *newobj; - size_t fnlen = strlen (fname); - - if (word == text) - { - /* Return exactly fname. */ - newobj = (char *) xmalloc (fnlen + 5); - strcpy (newobj, fname); - } - else if (word > text) - { - /* Return some portion of fname. */ - newobj = (char *) xmalloc (fnlen + 5); - strcpy (newobj, fname + (word - text)); - } - else - { - /* Return some of TEXT plus fname. */ - newobj = (char *) xmalloc (fnlen + (text - word) + 5); - strncpy (newobj, word, text - word); - newobj[text - word] = '\0'; - strcat (newobj, fname); - } - list->emplace_back (newobj); + list->emplace_back (make_completion_match_str (fname, text, word)); } static int @@ -5722,7 +5771,7 @@ allocate_template_symbol (struct objfile *objfile) struct template_symbol *result; result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol); - initialize_objfile_symbol_1 (&result->base); + initialize_objfile_symbol_1 (result); return result; } @@ -5868,7 +5917,7 @@ If zero then the symbol cache is disabled."), _("Flush the symbol cache for each program space."), &maintenancelist); - observer_attach_executable_changed (symtab_observer_executable_changed); - observer_attach_new_objfile (symtab_new_objfile_observer); - observer_attach_free_objfile (symtab_free_objfile_observer); + gdb::observers::executable_changed.attach (symtab_observer_executable_changed); + gdb::observers::new_objfile.attach (symtab_new_objfile_observer); + gdb::observers::free_objfile.attach (symtab_free_objfile_observer); }