X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsymtab.c;h=04dd5e26481fd0cf978f516b121d1e20efbbb7a9;hb=e98ee8c458f3a8405eb93e71b00f801b4bbe3635;hp=3d5936774db49931d4e66848cc5d361ccf45361c;hpb=68e745e38edebd2a12d60ef7b5774066db3f1c40;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symtab.c b/gdb/symtab.c index 3d5936774d..04dd5e2648 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); @@ -525,7 +528,7 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) struct fn_field *method = &f[signature_id]; const char *field_name = TYPE_FN_FIELDLIST_NAME (type, method_id); const char *physname = TYPE_FN_FIELD_PHYSNAME (f, signature_id); - const char *newname = type_name_no_tag (type); + const char *newname = TYPE_NAME (type); /* Does the form of physname indicate that it is the full mangled name of a constructor (not just the args)? */ @@ -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); } @@ -1745,7 +1746,7 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile) addr = SYMBOL_VALUE_ADDRESS (sym); break; case LOC_BLOCK: - addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + addr = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)); break; default: @@ -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, @@ -2834,7 +2860,9 @@ iterate_over_symbols (const struct block *block, if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), SYMBOL_DOMAIN (sym), domain)) { - if (!callback (sym)) + struct block_symbol block_sym = {sym, block}; + + if (!callback (&block_sym)) return; } } @@ -3020,8 +3048,6 @@ find_symbol_at_address (CORE_ADDR address) 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) { @@ -3029,7 +3055,6 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) struct symtab *iter_s; struct linetable *l; int len; - int i; struct linetable_entry *item; const struct blockvector *bv; struct bound_minimal_symbol msymbol; @@ -3188,15 +3213,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 @@ -3219,10 +3246,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; } @@ -3549,46 +3576,37 @@ find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr) return sal.symtab != 0; } -/* Given a function symbol SYM, find the symtab and line for the start - of the function. - If the argument FUNFIRSTLINE is nonzero, we want the first line - of real code inside the function. - This function should return SALs matching those from minsym_found, - otherwise false multiple-locations breakpoints could be placed. */ +/* Helper for find_function_start_sal. Does most of the work, except + setting the sal's symbol. */ -struct symtab_and_line -find_function_start_sal (struct symbol *sym, int funfirstline) +static symtab_and_line +find_function_start_sal_1 (CORE_ADDR func_addr, obj_section *section, + bool funfirstline) { - fixup_symbol_section (sym, NULL); - - obj_section *section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym); - symtab_and_line sal - = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), section, 0); - sal.symbol = sym; + symtab_and_line sal = find_pc_sect_line (func_addr, section, 0); if (funfirstline && sal.symtab != NULL && (COMPUNIT_LOCATIONS_VALID (SYMTAB_COMPUNIT (sal.symtab)) || SYMTAB_LANGUAGE (sal.symtab) == language_asm)) { - struct gdbarch *gdbarch = symbol_arch (sym); + struct gdbarch *gdbarch = get_objfile_arch (SYMTAB_OBJFILE (sal.symtab)); - sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + sal.pc = func_addr; if (gdbarch_skip_entrypoint_p (gdbarch)) sal.pc = gdbarch_skip_entrypoint (gdbarch, sal.pc); return sal; } /* We always should have a line for the function start address. - If we don't, something is odd. Create a plain SAL refering + If we don't, something is odd. Create a plain SAL referring just the PC and hope that skip_prologue_sal (if requested) can find a line number for after the prologue. */ - if (sal.pc < BLOCK_START (SYMBOL_BLOCK_VALUE (sym))) + if (sal.pc < func_addr) { sal = {}; sal.pspace = current_program_space; - sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + sal.pc = func_addr; sal.section = section; - sal.symbol = sym; } if (funfirstline) @@ -3597,6 +3615,38 @@ find_function_start_sal (struct symbol *sym, int funfirstline) return sal; } +/* See symtab.h. */ + +symtab_and_line +find_function_start_sal (CORE_ADDR func_addr, obj_section *section, + bool funfirstline) +{ + symtab_and_line sal + = find_function_start_sal_1 (func_addr, section, funfirstline); + + /* find_function_start_sal_1 does a linetable search, so it finds + the symtab and linenumber, but not a symbol. Fill in the + function symbol too. */ + sal.symbol = find_pc_sect_containing_function (sal.pc, sal.section); + + return sal; +} + +/* See symtab.h. */ + +symtab_and_line +find_function_start_sal (symbol *sym, bool funfirstline) +{ + fixup_symbol_section (sym, NULL); + symtab_and_line sal + = find_function_start_sal_1 (BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)), + SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym), + funfirstline); + sal.symbol = sym; + return sal; +} + + /* Given a function start address FUNC_ADDR and SYMTAB, find the first address for that function that has an entry in SYMTAB's line info table. If such an entry cannot be found, return FUNC_ADDR @@ -3669,7 +3719,7 @@ skip_prologue_sal (struct symtab_and_line *sal) fixup_symbol_section (sym, NULL); objfile = symbol_objfile (sym); - pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + pc = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)); section = SYMBOL_OBJ_SECTION (objfile, sym); name = SYMBOL_LINKAGE_NAME (sym); } @@ -3730,7 +3780,7 @@ skip_prologue_sal (struct symtab_and_line *sal) /* Check if gdbarch_skip_prologue left us in mid-line, and the next line is still part of the same function. */ if (skip && start_sal.pc != pc - && (sym ? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end + && (sym ? (BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) : (lookup_minimal_symbol_by_pc_section (start_sal.end, section).minsym == lookup_minimal_symbol_by_pc_section (pc, section).minsym))) @@ -3927,14 +3977,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_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)) == func_addr) return sym; return NULL; @@ -4283,7 +4333,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) { @@ -4475,7 +4524,9 @@ search_symbols (const char *regexp, enum search_domain kind, /* Helper function for symtab_symbol_info, this function uses the data returned from search_symbols() to print information - regarding the match to gdb_stdout. */ + regarding the match to gdb_stdout. If LAST is not NULL, + print file and line number information for the symbol as + well. Skip printing the filename if it matches LAST. */ static void print_symbol_info (enum search_domain kind, @@ -4483,13 +4534,22 @@ print_symbol_info (enum search_domain kind, int block, const char *last) { struct symtab *s = symbol_symtab (sym); - const char *s_filename = symtab_to_filename_for_display (s); - if (last == NULL || filename_cmp (last, s_filename) != 0) + if (last != NULL) { - fputs_filtered ("\nFile ", gdb_stdout); - fputs_filtered (s_filename, gdb_stdout); - fputs_filtered (":\n", gdb_stdout); + const char *s_filename = symtab_to_filename_for_display (s); + + if (filename_cmp (last, s_filename) != 0) + { + fputs_filtered ("\nFile ", gdb_stdout); + fputs_filtered (s_filename, gdb_stdout); + fputs_filtered (":\n", gdb_stdout); + } + + if (SYMBOL_LINE (sym) != 0) + printf_filtered ("%d:\t", SYMBOL_LINE (sym)); + else + puts_filtered ("\t"); } if (kind != TYPES_DOMAIN && block == STATIC_BLOCK) @@ -4543,7 +4603,7 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty) { static const char * const classnames[] = {"variable", "function", "type"}; - const char *last_filename = NULL; + const char *last_filename = ""; int first = 1; gdb_assert (kind <= TYPES_DOMAIN); @@ -4654,10 +4714,7 @@ rbreak_command (const char *regexp, int from_tty) string = string_printf ("%s:'%s'", fullname, SYMBOL_LINKAGE_NAME (p.symbol)); break_command (&string[0], from_tty); - print_symbol_info (FUNCTIONS_DOMAIN, - p.symbol, - p.block, - symtab_to_filename_for_display (symtab)); + print_symbol_info (FUNCTIONS_DOMAIN, p.symbol, p.block, NULL); } else { @@ -4679,26 +4736,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. */ @@ -4727,31 +4770,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); } } @@ -4948,6 +4977,50 @@ symbol_is_function_or_method (minimal_symbol *msymbol) } } +/* See symtab.h. */ + +bound_minimal_symbol +find_gnu_ifunc (const symbol *sym) +{ + if (SYMBOL_CLASS (sym) != LOC_BLOCK) + return {}; + + lookup_name_info lookup_name (SYMBOL_SEARCH_NAME (sym), + symbol_name_match_type::SEARCH_NAME); + struct objfile *objfile = symbol_objfile (sym); + + CORE_ADDR address = BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym)); + minimal_symbol *ifunc = NULL; + + iterate_over_minimal_symbols (objfile, lookup_name, + [&] (minimal_symbol *minsym) + { + if (MSYMBOL_TYPE (minsym) == mst_text_gnu_ifunc + || MSYMBOL_TYPE (minsym) == mst_data_gnu_ifunc) + { + CORE_ADDR msym_addr = MSYMBOL_VALUE_ADDRESS (objfile, minsym); + if (MSYMBOL_TYPE (minsym) == mst_data_gnu_ifunc) + { + struct gdbarch *gdbarch = get_objfile_arch (objfile); + msym_addr + = gdbarch_convert_from_func_ptr_addr (gdbarch, + msym_addr, + current_top_target ()); + } + if (msym_addr == address) + { + ifunc = minsym; + return true; + } + } + return false; + }); + + if (ifunc != NULL) + return {ifunc, objfile}; + return {}; +} + /* Add matching symbols from SYMTAB to the current completion list. */ static void @@ -5158,7 +5231,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, @@ -5179,11 +5252,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); @@ -5317,30 +5387,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 @@ -5946,7 +5993,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); }