X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsymtab.h;h=eac44aee15657ca7e78ed5e2ff7f242abbee86d4;hb=165f8965d770708f1dee623e308374ac108e6578;hp=0eb3a5b1987a2b66069e3aba5cdabf95595a28b1;hpb=f176c4b57f57c8965807256bad1cd487b92b5457;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symtab.h b/gdb/symtab.h index 0eb3a5b198..eac44aee15 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1,6 +1,6 @@ /* Symbol table definitions for GDB. - Copyright (C) 1986-2015 Free Software Foundation, Inc. + Copyright (C) 1986-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -20,9 +20,18 @@ #if !defined (SYMTAB_H) #define SYMTAB_H 1 -#include "vec.h" -#include "gdb_vecs.h" +#include +#include +#include +#include "gdbsupport/gdb_vecs.h" #include "gdbtypes.h" +#include "gdb_regex.h" +#include "gdbsupport/enum-flags.h" +#include "gdbsupport/function-view.h" +#include "gdbsupport/gdb_optional.h" +#include "gdbsupport/gdb_string_view.h" +#include "gdbsupport/next-iterator.h" +#include "completer.h" /* Opaque declarations. */ struct ui_file; @@ -36,8 +45,288 @@ struct axs_value; struct agent_expr; struct program_space; struct language_defn; -struct probe; struct common_block; +struct obj_section; +struct cmd_list_element; +class probe; +struct lookup_name_info; + +/* How to match a lookup name against a symbol search name. */ +enum class symbol_name_match_type +{ + /* Wild matching. Matches unqualified symbol names in all + namespace/module/packages, etc. */ + WILD, + + /* Full matching. The lookup name indicates a fully-qualified name, + and only matches symbol search names in the specified + namespace/module/package. */ + FULL, + + /* Search name matching. This is like FULL, but the search name did + not come from the user; instead it is already a search name + retrieved from a SYMBOL_SEARCH_NAME/MSYMBOL_SEARCH_NAME call. + For Ada, this avoids re-encoding an already-encoded search name + (which would potentially incorrectly lowercase letters in the + linkage/search name that should remain uppercase). For C++, it + avoids trying to demangle a name we already know is + demangled. */ + SEARCH_NAME, + + /* Expression matching. The same as FULL matching in most + languages. The same as WILD matching in Ada. */ + EXPRESSION, +}; + +/* Hash the given symbol search name according to LANGUAGE's + rules. */ +extern unsigned int search_name_hash (enum language language, + const char *search_name); + +/* Ada-specific bits of a lookup_name_info object. This is lazily + constructed on demand. */ + +class ada_lookup_name_info final +{ + public: + /* Construct. */ + explicit ada_lookup_name_info (const lookup_name_info &lookup_name); + + /* Compare SYMBOL_SEARCH_NAME with our lookup name, using MATCH_TYPE + as name match type. Returns true if there's a match, false + otherwise. If non-NULL, store the matching results in MATCH. */ + bool matches (const char *symbol_search_name, + symbol_name_match_type match_type, + completion_match_result *comp_match_res) const; + + /* The Ada-encoded lookup name. */ + const std::string &lookup_name () const + { return m_encoded_name; } + + /* Return true if we're supposed to be doing a wild match look + up. */ + bool wild_match_p () const + { return m_wild_match_p; } + + /* Return true if we're looking up a name inside package + Standard. */ + bool standard_p () const + { return m_standard_p; } + + /* Return true if doing a verbatim match. */ + bool verbatim_p () const + { return m_verbatim_p; } + +private: + /* The Ada-encoded lookup name. */ + std::string m_encoded_name; + + /* Whether the user-provided lookup name was Ada encoded. If so, + then return encoded names in the 'matches' method's 'completion + match result' output. */ + bool m_encoded_p : 1; + + /* True if really doing wild matching. Even if the user requests + wild matching, some cases require full matching. */ + bool m_wild_match_p : 1; + + /* True if doing a verbatim match. This is true if the decoded + version of the symbol name is wrapped in '<'/'>'. This is an + escape hatch users can use to look up symbols the Ada encoding + does not understand. */ + bool m_verbatim_p : 1; + + /* True if the user specified a symbol name that is inside package + Standard. Symbol names inside package Standard are handled + specially. We always do a non-wild match of the symbol name + without the "standard__" prefix, and only search static and + global symbols. This was primarily introduced in order to allow + the user to specifically access the standard exceptions using, + for instance, Standard.Constraint_Error when Constraint_Error is + ambiguous (due to the user defining its own Constraint_Error + entity inside its program). */ + bool m_standard_p : 1; +}; + +/* Language-specific bits of a lookup_name_info object, for languages + that do name searching using demangled names (C++/D/Go). This is + lazily constructed on demand. */ + +struct demangle_for_lookup_info final +{ +public: + demangle_for_lookup_info (const lookup_name_info &lookup_name, + language lang); + + /* The demangled lookup name. */ + const std::string &lookup_name () const + { return m_demangled_name; } + +private: + /* The demangled lookup name. */ + std::string m_demangled_name; +}; + +/* Object that aggregates all information related to a symbol lookup + name. I.e., the name that is matched against the symbol's search + name. Caches per-language information so that it doesn't require + recomputing it for every symbol comparison, like for example the + Ada encoded name and the symbol's name hash for a given language. + The object is conceptually immutable once constructed, and thus has + no setters. This is to prevent some code path from tweaking some + property of the lookup name for some local reason and accidentally + altering the results of any continuing search(es). + lookup_name_info objects are generally passed around as a const + reference to reinforce that. (They're not passed around by value + because they're not small.) */ +class lookup_name_info final +{ + public: + /* Create a new object. */ + lookup_name_info (std::string name, + symbol_name_match_type match_type, + bool completion_mode = false, + bool ignore_parameters = false) + : m_match_type (match_type), + m_completion_mode (completion_mode), + m_ignore_parameters (ignore_parameters), + m_name (std::move (name)) + {} + + /* Getters. See description of each corresponding field. */ + symbol_name_match_type match_type () const { return m_match_type; } + bool completion_mode () const { return m_completion_mode; } + const std::string &name () const { return m_name; } + const bool ignore_parameters () const { return m_ignore_parameters; } + + /* Return a version of this lookup name that is usable with + comparisons against symbols have no parameter info, such as + psymbols and GDB index symbols. */ + lookup_name_info make_ignore_params () const + { + return lookup_name_info (m_name, m_match_type, m_completion_mode, + true /* ignore params */); + } + + /* Get the search name hash for searches in language LANG. */ + unsigned int search_name_hash (language lang) const + { + /* Only compute each language's hash once. */ + if (!m_demangled_hashes_p[lang]) + { + m_demangled_hashes[lang] + = ::search_name_hash (lang, language_lookup_name (lang).c_str ()); + m_demangled_hashes_p[lang] = true; + } + return m_demangled_hashes[lang]; + } + + /* Get the search name for searches in language LANG. */ + const std::string &language_lookup_name (language lang) const + { + switch (lang) + { + case language_ada: + return ada ().lookup_name (); + case language_cplus: + return cplus ().lookup_name (); + case language_d: + return d ().lookup_name (); + case language_go: + return go ().lookup_name (); + default: + return m_name; + } + } + + /* Get the Ada-specific lookup info. */ + const ada_lookup_name_info &ada () const + { + maybe_init (m_ada); + return *m_ada; + } + + /* Get the C++-specific lookup info. */ + const demangle_for_lookup_info &cplus () const + { + maybe_init (m_cplus, language_cplus); + return *m_cplus; + } + + /* Get the D-specific lookup info. */ + const demangle_for_lookup_info &d () const + { + maybe_init (m_d, language_d); + return *m_d; + } + + /* Get the Go-specific lookup info. */ + const demangle_for_lookup_info &go () const + { + maybe_init (m_go, language_go); + return *m_go; + } + + /* Get a reference to a lookup_name_info object that matches any + symbol name. */ + static const lookup_name_info &match_any (); + +private: + /* Initialize FIELD, if not initialized yet. */ + template + void maybe_init (Field &field, Args&&... args) const + { + if (!field) + field.emplace (*this, std::forward (args)...); + } + + /* The lookup info as passed to the ctor. */ + symbol_name_match_type m_match_type; + bool m_completion_mode; + bool m_ignore_parameters; + std::string m_name; + + /* Language-specific info. These fields are filled lazily the first + time a lookup is done in the corresponding language. They're + mutable because lookup_name_info objects are typically passed + around by const reference (see intro), and they're conceptually + "cache" that can always be reconstructed from the non-mutable + fields. */ + mutable gdb::optional m_ada; + mutable gdb::optional m_cplus; + mutable gdb::optional m_d; + mutable gdb::optional m_go; + + /* The demangled hashes. Stored in an array with one entry for each + possible language. The second array records whether we've + already computed the each language's hash. (These are separate + arrays instead of a single array of optional to avoid + alignment padding). */ + mutable std::array m_demangled_hashes; + mutable std::array m_demangled_hashes_p {}; +}; + +/* Comparison function for completion symbol lookup. + + Returns true if the symbol name matches against LOOKUP_NAME. + + SYMBOL_SEARCH_NAME should be a symbol's "search" name. + + On success and if non-NULL, COMP_MATCH_RES->match is set to point + to the symbol name as should be presented to the user as a + completion match list element. In most languages, this is the same + as the symbol's search name, but in some, like Ada, the display + name is dynamically computed within the comparison routine. + + Also, on success and if non-NULL, COMP_MATCH_RES->match_for_lcd + points the part of SYMBOL_SEARCH_NAME that was considered to match + LOOKUP_NAME. E.g., in C++, in linespec/wild mode, if the symbol is + "foo::function()" and LOOKUP_NAME is "function(", MATCH_FOR_LCD + points to "function()" inside SYMBOL_SEARCH_NAME. */ +typedef bool (symbol_name_matcher_ftype) + (const char *symbol_search_name, + const lookup_name_info &lookup_name, + completion_match_result *comp_match_res); /* Some of the structures in this file are space critical. The space-critical structures are: @@ -134,12 +423,8 @@ struct general_symbol_info struct obstack *obstack; /* This is used by languages which wish to store a demangled name. - currently used by Ada, C++, Java, and Objective C. */ - struct mangled_lang - { - const char *demangled_name; - } - mangled_lang; + currently used by Ada, C++, and Objective C. */ + const char *demangled_name; } language_specific; @@ -147,9 +432,9 @@ struct general_symbol_info This is used to select one of the fields from the language specific union above. */ - ENUM_BITFIELD(language) language : 8; + ENUM_BITFIELD(language) language : LANGUAGE_BITS; - /* This is only used by Ada. If set, then the 'mangled_lang' field + /* This is only used by Ada. If set, then the 'demangled_name' field of language_specific is valid. Otherwise, the 'obstack' field is valid. */ unsigned int ada_mangled : 1; @@ -170,6 +455,14 @@ extern const char *symbol_get_demangled_name extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *); +/* Return the address of SYM. The MAYBE_COPIED flag must be set on + SYM. If SYM appears in the main program's minimal symbols, then + that minsym's address is returned; otherwise, SYM's address is + returned. This should generally only be used via the + SYMBOL_VALUE_ADDRESS macro. */ + +extern CORE_ADDR get_symbol_address (const struct symbol *sym); + /* Note that all the following SYMBOL_* macros are used with the SYMBOL argument being either a partial symbol or a full symbol. Both types have a ginfo field. In particular @@ -179,7 +472,11 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *); field only, instead of the SYMBOL parameter. */ #define SYMBOL_VALUE(symbol) (symbol)->ginfo.value.ivalue -#define SYMBOL_VALUE_ADDRESS(symbol) (symbol)->ginfo.value.address +#define SYMBOL_VALUE_ADDRESS(symbol) \ + (((symbol)->maybe_copied) ? get_symbol_address (symbol) \ + : ((symbol)->ginfo.value.address)) +#define SET_SYMBOL_VALUE_ADDRESS(symbol, new_value) \ + ((symbol)->ginfo.value.address = (new_value)) #define SYMBOL_VALUE_BYTES(symbol) (symbol)->ginfo.value.bytes #define SYMBOL_VALUE_COMMON_BLOCK(symbol) (symbol)->ginfo.value.common_block #define SYMBOL_BLOCK_VALUE(symbol) (symbol)->ginfo.value.block @@ -208,12 +505,14 @@ extern void symbol_set_language (struct general_symbol_info *symbol, (symbol)->ginfo.name = (linkage_name) /* Set the linkage and natural names of a symbol, by demangling - the linkage name. */ -#define SYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile) \ - symbol_set_names (&(symbol)->ginfo, linkage_name, len, copy_name, objfile) + the linkage name. If linkage_name may not be nullterminated, + copy_name must be set to true. */ +#define SYMBOL_SET_NAMES(symbol,linkage_name,copy_name,objfile) \ + symbol_set_names (&(symbol)->ginfo, linkage_name, copy_name, \ + (objfile)->per_bfd) extern void symbol_set_names (struct general_symbol_info *symbol, - const char *linkage_name, int len, int copy_name, - struct objfile *objfile); + gdb::string_view linkage_name, bool copy_name, + struct objfile_per_bfd_storage *per_bfd); /* Now come lots of name accessor macros. Short version as to when to use which: Use SYMBOL_NATURAL_NAME to refer to the name of the @@ -259,22 +558,32 @@ extern const char *symbol_demangled_name #define SYMBOL_PRINT_NAME(symbol) \ (demangle ? SYMBOL_NATURAL_NAME (symbol) : SYMBOL_LINKAGE_NAME (symbol)) -extern int demangle; +extern bool demangle; /* Macro that returns the name to be used when sorting and searching symbols. - In C++ and Java, we search for the demangled form of a name, + In C++, we search for the demangled form of a name, and so sort symbols accordingly. In Ada, however, we search by mangled name. If there is no distinct demangled name, then SYMBOL_SEARCH_NAME returns the same value (same pointer) as SYMBOL_LINKAGE_NAME. */ #define SYMBOL_SEARCH_NAME(symbol) \ (symbol_search_name (&(symbol)->ginfo)) -extern const char *symbol_search_name (const struct general_symbol_info *); +extern const char *symbol_search_name (const struct general_symbol_info *ginfo); + +/* Return true if NAME matches the "search" name of SYMBOL, according + to the symbol's language. */ +#define SYMBOL_MATCHES_SEARCH_NAME(symbol, name) \ + symbol_matches_search_name (&(symbol)->ginfo, (name)) -/* Return non-zero if NAME matches the "search" name of SYMBOL. - Whitespace and trailing parentheses are ignored. - See strcmp_iw for details about its behavior. */ -#define SYMBOL_MATCHES_SEARCH_NAME(symbol, name) \ - (strcmp_iw (SYMBOL_SEARCH_NAME (symbol), (name)) == 0) +/* Helper for SYMBOL_MATCHES_SEARCH_NAME that works with both symbols + and psymbols. */ +extern bool symbol_matches_search_name + (const struct general_symbol_info *gsymbol, + const lookup_name_info &name); + +/* Compute the hash of the given symbol search name of a symbol of + language LANGUAGE. */ +extern unsigned int search_name_hash (enum language language, + const char *search_name); /* Classification types for a minimal symbol. These should be taken as "advisory only", since if gdb can't easily figure out a @@ -288,8 +597,26 @@ enum minimal_symbol_type { mst_unknown = 0, /* Unknown type, the default */ mst_text, /* Generally executable instructions */ - mst_text_gnu_ifunc, /* Executable code returning address + + /* A GNU ifunc symbol, in the .text section. GDB uses to know + whether the user is setting a breakpoint on a GNU ifunc function, + and thus GDB needs to actually set the breakpoint on the target + function. It is also used to know whether the program stepped + into an ifunc resolver -- the resolver may get a separate + symbol/alias under a different name, but it'll have the same + address as the ifunc symbol. */ + mst_text_gnu_ifunc, /* Executable code returning address of executable code */ + + /* A GNU ifunc function descriptor symbol, in a data section + (typically ".opd"). Seen on architectures that use function + descriptors, like PPC64/ELFv1. In this case, this symbol's value + is the address of the descriptor. There'll be a corresponding + mst_text_gnu_ifunc synthetic symbol for the text/entry + address. */ + mst_data_gnu_ifunc, /* Executable code returning address + of executable code */ + mst_slot_got_plt, /* GOT entries for .plt sections */ mst_data, /* Generally initialized data */ mst_bss, /* Generally uninitialized data */ @@ -307,9 +634,15 @@ enum minimal_symbol_type within a given .o file. */ mst_file_text, /* Static version of mst_text */ mst_file_data, /* Static version of mst_data */ - mst_file_bss /* Static version of mst_bss */ + mst_file_bss, /* Static version of mst_bss */ + nr_minsym_types }; +/* The number of enum minimal_symbol_type values, with some padding for + reasonable growth. */ +#define MINSYM_TYPE_BITS 4 +gdb_static_assert (nr_minsym_types <= (1 << MINSYM_TYPE_BITS)); + /* Define a simple structure used to hold some very basic information about all defined global symbols (text, data, bss, abs, etc). The only required information is the general_symbol_info. @@ -322,17 +655,9 @@ enum minimal_symbol_type between names and addresses, and vice versa. They are also sometimes used to figure out what full symbol table entries need to be read in. */ -struct minimal_symbol +struct minimal_symbol : public general_symbol_info { - - /* The general symbol info required for all types of symbols. - - The SYMBOL_VALUE_ADDRESS contains the address that this symbol - corresponds to. */ - - struct general_symbol_info mginfo; - - /* Size of this symbol. end_psymtab in dbxread.c uses this + /* Size of this symbol. dbx_end_psymtab in dbxread.c uses this information to calculate the end of the partial symtab based on the address of the last symbol plus the size of the last symbol. */ @@ -343,7 +668,7 @@ struct minimal_symbol /* Classification type for this minimal symbol. */ - ENUM_BITFIELD(minimal_symbol_type) type : 8; + ENUM_BITFIELD(minimal_symbol_type) type : MINSYM_TYPE_BITS; /* Non-zero if this symbol was created by gdb. Such symbols do not appear in the output of "info var|fun". */ @@ -358,6 +683,14 @@ struct minimal_symbol the object file format may not carry that piece of information. */ unsigned int has_size : 1; + /* For data symbols only, if this is set, then the symbol might be + subject to copy relocation. In this case, a minimal symbol + matching the symbol's linkage name is first looked for in the + main objfile. If found, then that address is used; otherwise the + address in this symbol is used. */ + + unsigned maybe_copied : 1; + /* Minimal symbols with the same hash key are kept on a linked list. This is the link. */ @@ -367,8 +700,25 @@ struct minimal_symbol the `next' pointer for the demangled hash table. */ struct minimal_symbol *demangled_hash_next; + + /* True if this symbol is of some data type. */ + + bool data_p () const; + + /* True if MSYMBOL is of some text type. */ + + bool text_p () const; }; +/* Return the address of MINSYM, which comes from OBJF. The + MAYBE_COPIED flag must be set on MINSYM. If MINSYM appears in the + main program's minimal symbols, then that minsym's address is + returned; otherwise, MINSYM's address is returned. This should + generally only be used via the MSYMBOL_VALUE_ADDRESS macro. */ + +extern CORE_ADDR get_msymbol_address (struct objfile *objf, + const struct minimal_symbol *minsym); + #define MSYMBOL_TARGET_FLAG_1(msymbol) (msymbol)->target_flag_1 #define MSYMBOL_TARGET_FLAG_2(msymbol) (msymbol)->target_flag_2 #define MSYMBOL_SIZE(msymbol) ((msymbol)->size + 0) @@ -381,44 +731,39 @@ struct minimal_symbol #define MSYMBOL_HAS_SIZE(msymbol) ((msymbol)->has_size + 0) #define MSYMBOL_TYPE(msymbol) (msymbol)->type -#define MSYMBOL_VALUE(symbol) (symbol)->mginfo.value.ivalue +#define MSYMBOL_VALUE(symbol) (symbol)->value.ivalue /* The unrelocated address of the minimal symbol. */ -#define MSYMBOL_VALUE_RAW_ADDRESS(symbol) ((symbol)->mginfo.value.address + 0) +#define MSYMBOL_VALUE_RAW_ADDRESS(symbol) ((symbol)->value.address + 0) /* The relocated address of the minimal symbol, using the section offsets from OBJFILE. */ #define MSYMBOL_VALUE_ADDRESS(objfile, symbol) \ - ((symbol)->mginfo.value.address \ - + ANOFFSET ((objfile)->section_offsets, ((symbol)->mginfo.section))) + (((symbol)->maybe_copied) ? get_msymbol_address (objfile, symbol) \ + : ((symbol)->value.address \ + + ANOFFSET ((objfile)->section_offsets, ((symbol)->section)))) /* For a bound minsym, we can easily compute the address directly. */ #define BMSYMBOL_VALUE_ADDRESS(symbol) \ MSYMBOL_VALUE_ADDRESS ((symbol).objfile, (symbol).minsym) #define SET_MSYMBOL_VALUE_ADDRESS(symbol, new_value) \ - ((symbol)->mginfo.value.address = (new_value)) -#define MSYMBOL_VALUE_BYTES(symbol) (symbol)->mginfo.value.bytes -#define MSYMBOL_BLOCK_VALUE(symbol) (symbol)->mginfo.value.block -#define MSYMBOL_VALUE_CHAIN(symbol) (symbol)->mginfo.value.chain -#define MSYMBOL_LANGUAGE(symbol) (symbol)->mginfo.language -#define MSYMBOL_SECTION(symbol) (symbol)->mginfo.section + ((symbol)->value.address = (new_value)) +#define MSYMBOL_VALUE_BYTES(symbol) (symbol)->value.bytes +#define MSYMBOL_BLOCK_VALUE(symbol) (symbol)->value.block +#define MSYMBOL_VALUE_CHAIN(symbol) (symbol)->value.chain +#define MSYMBOL_LANGUAGE(symbol) (symbol)->language +#define MSYMBOL_SECTION(symbol) (symbol)->section #define MSYMBOL_OBJ_SECTION(objfile, symbol) \ - (((symbol)->mginfo.section >= 0) \ - ? (&(((objfile)->sections)[(symbol)->mginfo.section])) \ + (((symbol)->section >= 0) \ + ? (&(((objfile)->sections)[(symbol)->section])) \ : NULL) #define MSYMBOL_NATURAL_NAME(symbol) \ - (symbol_natural_name (&(symbol)->mginfo)) -#define MSYMBOL_LINKAGE_NAME(symbol) (symbol)->mginfo.name + (symbol_natural_name (symbol)) +#define MSYMBOL_LINKAGE_NAME(symbol) (symbol)->name #define MSYMBOL_PRINT_NAME(symbol) \ (demangle ? MSYMBOL_NATURAL_NAME (symbol) : MSYMBOL_LINKAGE_NAME (symbol)) #define MSYMBOL_DEMANGLED_NAME(symbol) \ - (symbol_demangled_name (&(symbol)->mginfo)) -#define MSYMBOL_SET_LANGUAGE(symbol,language,obstack) \ - (symbol_set_language (&(symbol)->mginfo, (language), (obstack))) + (symbol_demangled_name (symbol)) #define MSYMBOL_SEARCH_NAME(symbol) \ - (symbol_search_name (&(symbol)->mginfo)) -#define MSYMBOL_MATCHES_SEARCH_NAME(symbol, name) \ - (strcmp_iw (MSYMBOL_SEARCH_NAME (symbol), (name)) == 0) -#define MSYMBOL_SET_NAMES(symbol,linkage_name,len,copy_name,objfile) \ - symbol_set_names (&(symbol)->mginfo, linkage_name, len, copy_name, objfile) + (symbol_search_name (symbol)) #include "minsyms.h" @@ -458,12 +803,16 @@ typedef enum domain_enum_tag /* Fortran common blocks. Their naming must be separate from VAR_DOMAIN. They also always use LOC_COMMON_BLOCK. */ - COMMON_BLOCK_DOMAIN + COMMON_BLOCK_DOMAIN, + + /* This must remain last. */ + NR_DOMAINS } domain_enum; /* The number of bits in a symbol used to represent the domain. */ -#define SYMBOL_DOMAIN_BITS 4 +#define SYMBOL_DOMAIN_BITS 3 +gdb_static_assert (NR_DOMAINS <= (1 << SYMBOL_DOMAIN_BITS)); extern const char *domain_name (domain_enum); @@ -482,8 +831,11 @@ enum search_domain /* All defined types */ TYPES_DOMAIN = 2, + /* All modules. */ + MODULES_DOMAIN = 3, + /* Any type. */ - ALL_DOMAIN = 3 + ALL_DOMAIN = 4 }; extern const char *search_domain_name (enum search_domain); @@ -572,7 +924,13 @@ enum address_class not find it in the full symbol table. But a reference to an external symbol in a local block shadowing other definition requires full symbol without possibly having its address available for LOC_STATIC. Testcase - is provided as `gdb.dwarf2/dw2-unresolved.exp'. */ + is provided as `gdb.dwarf2/dw2-unresolved.exp'. + + This is also used for thread local storage (TLS) variables. In this case, + the address of the TLS variable must be determined when the variable is + referenced, from the MSYMBOL_VALUE_RAW_ADDRESS, which is the offset + of the TLS variable in the thread local storage of the shared + library/object. */ LOC_UNRESOLVED, @@ -593,6 +951,15 @@ enum address_class LOC_FINAL_VALUE }; +/* The number of bits needed for values in enum address_class, with some + padding for reasonable growth, and room for run-time registered address + classes. See symtab.c:MAX_SYMBOL_IMPLS. + This is a #define so that we can have a assertion elsewhere to + verify that we have reserved enough space for synthetic address + classes. */ +#define SYMBOL_ACLASS_BITS 5 +gdb_static_assert (LOC_FINAL_VALUE <= (1 << SYMBOL_ACLASS_BITS)); + /* The methods needed to implement LOC_COMPUTED. These methods can use the symbol's .aux_value for additional per-symbol information. @@ -605,7 +972,8 @@ struct symbol_computed_ops frame FRAME. If the variable has been optimized out, return zero. - Iff `read_needs_frame (SYMBOL)' is zero, then FRAME may be zero. */ + Iff `read_needs_frame (SYMBOL)' is not SYMBOL_NEEDS_FRAME, then + FRAME may be zero. */ struct value *(*read_variable) (struct symbol * symbol, struct frame_info * frame); @@ -616,8 +984,11 @@ struct symbol_computed_ops struct value *(*read_variable_at_entry) (struct symbol *symbol, struct frame_info *frame); - /* Return non-zero if we need a frame to find the value of the SYMBOL. */ - int (*read_needs_frame) (struct symbol * symbol); + /* Find the "symbol_needs_kind" value for the given symbol. This + value determines whether reading the symbol needs memory (e.g., a + global variable), just registers (a thread-local), or a frame (a + local variable). */ + enum symbol_needs_kind (*get_symbol_read_needs) (struct symbol * symbol); /* Write to STREAM a natural-language description of the location of SYMBOL, in the context of ADDR. */ @@ -634,8 +1005,8 @@ struct symbol_computed_ops the caller will generate the right code in the process of treating this as an lvalue or rvalue. */ - void (*tracepoint_var_ref) (struct symbol *symbol, struct gdbarch *gdbarch, - struct agent_expr *ax, struct axs_value *value); + void (*tracepoint_var_ref) (struct symbol *symbol, struct agent_expr *ax, + struct axs_value *value); /* Generate C code to compute the location of SYMBOL. The C code is emitted to STREAM. GDBARCH is the current architecture and PC is @@ -646,7 +1017,7 @@ struct symbol_computed_ops The generated C code must assign the location to a local variable; this variable's name is RESULT_NAME. */ - void (*generate_c_location) (struct symbol *symbol, struct ui_file *stream, + void (*generate_c_location) (struct symbol *symbol, string_file *stream, struct gdbarch *gdbarch, unsigned char *registers_used, CORE_ADDR pc, const char *result_name); @@ -665,6 +1036,25 @@ struct symbol_block_ops uninitialized in such case. */ void (*find_frame_base_location) (struct symbol *framefunc, CORE_ADDR pc, const gdb_byte **start, size_t *length); + + /* Return the frame base address. FRAME is the frame for which we want to + compute the base address while FRAMEFUNC is the symbol for the + corresponding function. Return 0 on failure (FRAMEFUNC may not hold the + information we need). + + This method is designed to work with static links (nested functions + handling). Static links are function properties whose evaluation returns + the frame base address for the enclosing frame. However, there are + multiple definitions for "frame base": the content of the frame base + register, the CFA as defined by DWARF unwinding information, ... + + So this specific method is supposed to compute the frame base address such + as for nested functions, the static link computes the same address. For + instance, considering DWARF debugging information, the static link is + computed with DW_AT_static_link and this method must be used to compute + the corresponding DW_AT_frame_base attribute. */ + CORE_ADDR (*get_frame_base) (struct symbol *framefunc, + struct frame_info *frame); }; /* Functions used with LOC_REGISTER and LOC_REGPARM_ADDR. */ @@ -691,12 +1081,20 @@ struct symbol_impl const struct symbol_register_ops *ops_register; }; -/* The number of bits we reserve in a symbol for the aclass index. - This is a #define so that we can have a assertion elsewhere to - verify that we have reserved enough space for synthetic address - classes. */ +/* struct symbol has some subclasses. This enum is used to + differentiate between them. */ + +enum symbol_subclass_kind +{ + /* Plain struct symbol. */ + SYMBOL_NONE, + + /* struct template_symbol. */ + SYMBOL_TEMPLATE, -#define SYMBOL_ACLASS_BITS 6 + /* struct rust_vtable_symbol. */ + SYMBOL_RUST_VTABLE +}; /* This structure is space critical. See space comments at the top. */ @@ -747,9 +1145,17 @@ struct symbol /* Whether this is an inlined function (class LOC_BLOCK only). */ unsigned is_inlined : 1; - /* True if this is a C++ function symbol with template arguments. - In this case the symbol is really a "struct template_symbol". */ - unsigned is_cplus_template_function : 1; + /* For LOC_STATIC only, if this is set, then the symbol might be + subject to copy relocation. In this case, a minimal symbol + matching the symbol's linkage name is first looked for in the + main objfile. If found, then that address is used; otherwise the + address in this symbol is used. */ + + unsigned maybe_copied : 1; + + /* The concrete type of this symbol. */ + + ENUM_BITFIELD (symbol_subclass_kind) subclass : 2; /* Line number of this symbol's definition, except for inlined functions. For an inlined function (class LOC_BLOCK and @@ -767,11 +1173,10 @@ struct symbol /* An arbitrary data pointer, allowing symbol readers to record additional information on a per-symbol basis. Note that this data must be allocated using the same obstack as the symbol itself. */ - /* So far it is only used by LOC_COMPUTED to - find the location information. For a LOC_BLOCK symbol - for a function in a compilation unit compiled with DWARF 2 - information, this is information used internally by the DWARF 2 - code --- specifically, the location expression for the frame + /* So far it is only used by: + LOC_COMPUTED: to find the location information + LOC_BLOCK (DWARF2 function): information used internally by the + DWARF 2 code --- specifically, the location expression for the frame base for this function. */ /* FIXME drow/2003-02-21: For the LOC_BLOCK case, it might be better to add a magic symbol to the block containing this information, @@ -782,6 +1187,19 @@ struct symbol struct symbol *hash_next; }; +/* Several lookup functions return both a symbol and the block in which the + symbol is found. This structure is used in these cases. */ + +struct block_symbol +{ + /* The symbol that was found, or NULL if no symbol was found. */ + struct symbol *symbol; + + /* If SYMBOL is not NULL, then this is the block in which the symbol is + defined. */ + const struct block *block; +}; + extern const struct symbol_impl *symbol_impls; /* Note: There is no accessor macro for symbol.owner because it is @@ -795,7 +1213,7 @@ extern const struct symbol_impl *symbol_impls; #define SYMBOL_IS_ARGUMENT(symbol) (symbol)->is_argument #define SYMBOL_INLINED(symbol) (symbol)->is_inlined #define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \ - (symbol)->is_cplus_template_function + (((symbol)->subclass) == SYMBOL_TEMPLATE) #define SYMBOL_TYPE(symbol) (symbol)->type #define SYMBOL_LINE(symbol) (symbol)->line #define SYMBOL_COMPUTED_OPS(symbol) (SYMBOL_IMPL (symbol).ops_computed) @@ -835,16 +1253,11 @@ extern struct symtab *symbol_symtab (const struct symbol *symbol); extern void symbol_set_symtab (struct symbol *symbol, struct symtab *symtab); /* An instance of this type is used to represent a C++ template - function. It includes a "struct symbol" as a kind of base class; - users downcast to "struct template_symbol *" when needed. A symbol - is really of this type iff SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION is - true. */ + function. A symbol is really of this type iff + SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION is true. */ -struct template_symbol +struct template_symbol : public symbol { - /* The base class. */ - struct symbol base; - /* The number of template arguments. */ int n_template_arguments; @@ -853,6 +1266,15 @@ struct template_symbol struct symbol **template_arguments; }; +/* A symbol that represents a Rust virtual table object. */ + +struct rust_vtable_symbol : public symbol +{ + /* The concrete type for which this vtable was created; that is, in + "impl Trait for Type", this is "Type". */ + struct type *concrete_type; +}; + /* Each item represents a line-->pc (or the reverse) mapping. This is somewhat more wasteful of space than one might wish, but since only @@ -924,7 +1346,8 @@ struct section_offsets struct symtab { - /* Unordered chain of all existing symtabs of this objfile. */ + /* Unordered chain of all filetabs in the compunit, with the exception + that the "main" source file is the first entry in the list. */ struct symtab *next; @@ -941,16 +1364,6 @@ struct symtab const char *filename; - /* Total number of lines found in source file. */ - - int nlines; - - /* line_charpos[N] is the position of the (N-1)th line of the - source file. "position" means something we can lseek() to; it - is not guaranteed to be useful any other way. */ - - int *line_charpos; - /* Language of this source file. */ enum language language; @@ -972,9 +1385,6 @@ struct symtab #define SYMTAB_DIRNAME(symtab) \ COMPUNIT_DIRNAME (SYMTAB_COMPUNIT (symtab)) -typedef struct symtab *symtab_ptr; -DEF_VEC_P (symtab_ptr); - /* Compunit symtabs contain the actual "symbol table", aka blockvector, as well as the list of all source files (what gdb has historically associated with the term "symtab"). @@ -1102,10 +1512,16 @@ struct compunit_symtab #define COMPUNIT_CALL_SITE_HTAB(cust) ((cust)->call_site_htab) #define COMPUNIT_MACRO_TABLE(cust) ((cust)->macro_table) -/* Iterate over all file tables (struct symtab) within a compunit. */ +/* A range adapter to allowing iterating over all the file tables + within a compunit. */ -#define ALL_COMPUNIT_FILETABS(cu, s) \ - for ((s) = (cu) -> filetabs; (s) != NULL; (s) = (s) -> next) +struct compunit_filetabs : public next_adapter +{ + compunit_filetabs (struct compunit_symtab *cu) + : next_adapter (cu->filetabs) + { + } +}; /* Return the primary symtab of CUST. */ @@ -1116,9 +1532,6 @@ extern struct symtab * extern enum language compunit_language (const struct compunit_symtab *cust); -typedef struct compunit_symtab *compunit_symtab_ptr; -DEF_VEC_P (compunit_symtab_ptr); - /* The virtual function table is now an array of structures which have the @@ -1140,10 +1553,6 @@ DEF_VEC_P (compunit_symtab_ptr); extern int currently_reading_symtab; -/* The block in which the most recently looked up symbol was found. */ - -extern const struct block *block_found; - /* symtab.c lookup functions */ extern const char multiple_symbols_ask[]; @@ -1152,9 +1561,9 @@ extern const char multiple_symbols_cancel[]; const char *multiple_symbols_select_mode (void); -int symbol_matches_domain (enum language symbol_language, - domain_enum symbol_domain, - domain_enum domain); +bool symbol_matches_domain (enum language symbol_language, + domain_enum symbol_domain, + domain_enum domain); /* lookup a symbol table by source file name. */ @@ -1189,27 +1598,41 @@ struct field_of_this_result C++: if IS_A_FIELD_OF_THIS is non-NULL on entry, check to see if NAME is a field of the current implied argument `this'. If so fill in the fields of IS_A_FIELD_OF_THIS, otherwise the fields are set to NULL. - 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). The symbol's section is fixed up if necessary. */ -extern struct symbol *lookup_symbol_in_language (const char *, - const struct block *, - const domain_enum, - enum language, - struct field_of_this_result *); +extern struct block_symbol + lookup_symbol_in_language (const char *, + const struct block *, + const domain_enum, + enum language, + struct field_of_this_result *); /* Same as lookup_symbol_in_language, but using the current language. */ -extern struct symbol *lookup_symbol (const char *, const struct block *, - const domain_enum, - struct field_of_this_result *); +extern struct block_symbol lookup_symbol (const char *, + const struct block *, + const domain_enum, + struct field_of_this_result *); + +/* Find the definition for a specified symbol search name in domain + DOMAIN, visible from lexical block BLOCK if non-NULL or from + global/static blocks if BLOCK is NULL. The passed-in search name + should not come from the user; instead it should already be a + search name as retrieved from a + SYMBOL_SEARCH_NAME/MSYMBOL_SEARCH_NAME call. See definition of + symbol_name_match_type::SEARCH_NAME. Returns the struct symbol + pointer, or NULL if no symbol is found. The symbol's section is + fixed up if necessary. */ + +extern struct block_symbol lookup_symbol_search_name (const char *search_name, + const struct block *block, + domain_enum domain); /* A default version of lookup_symbol_nonlocal for use by languages that can't think of anything better to do. This implements the C lookup rules. */ -extern struct symbol * +extern struct block_symbol basic_lookup_symbol_nonlocal (const struct language_defn *langdef, const char *, const struct block *, @@ -1220,19 +1643,18 @@ extern struct symbol * /* Lookup a symbol in the static block associated to BLOCK, if there is one; do nothing if BLOCK is NULL or a global block. - Upon success sets BLOCK_FOUND and fixes up the symbol's section - if necessary. */ + Upon success fixes up the symbol's section if necessary. */ -extern struct symbol *lookup_symbol_in_static_block (const char *name, - const struct block *block, - const domain_enum domain); +extern struct block_symbol + lookup_symbol_in_static_block (const char *name, + const struct block *block, + const domain_enum domain); /* Search all static file-level symbols for NAME from DOMAIN. - Upon success sets BLOCK_FOUND and fixes up the symbol's section - if necessary. */ + Upon success fixes up the symbol's section if necessary. */ -extern struct symbol *lookup_static_symbol (const char *name, - const domain_enum domain); +extern struct block_symbol lookup_static_symbol (const char *name, + const domain_enum domain); /* Lookup a symbol in all files' global blocks. @@ -1243,26 +1665,28 @@ extern struct symbol *lookup_static_symbol (const char *name, if the target requires it. See gdbarch_iterate_over_objfiles_in_search_order. - Upon success sets BLOCK_FOUND and fixes up the symbol's section - if necessary. */ + Upon success fixes up the symbol's section if necessary. */ -extern struct symbol *lookup_global_symbol (const char *name, - const struct block *block, - const domain_enum domain); +extern struct block_symbol + lookup_global_symbol (const char *name, + const struct block *block, + const domain_enum domain); /* Lookup a symbol in block BLOCK. - Upon success sets BLOCK_FOUND and fixes up the symbol's section - if necessary. */ + Upon success fixes up the symbol's section if necessary. */ -extern struct symbol *lookup_symbol_in_block (const char *name, - const struct block *block, - const domain_enum domain); +extern struct symbol * + lookup_symbol_in_block (const char *name, + symbol_name_match_type match_type, + const struct block *block, + const domain_enum domain); /* Look up the `this' symbol for LANG in BLOCK. Return the symbol if found, or NULL if not found. */ -extern struct symbol *lookup_language_this (const struct language_defn *lang, - const struct block *block); +extern struct block_symbol + lookup_language_this (const struct language_defn *lang, + const struct block *block); /* Lookup a [struct, union, enum] by name, within a specified block. */ @@ -1274,23 +1698,99 @@ extern struct type *lookup_enum (const char *, const struct block *); /* from blockframe.c: */ -/* lookup the function symbol corresponding to the address. */ +/* lookup the function symbol corresponding to the address. The + return value will not be an inlined function; the containing + function will be returned instead. */ extern struct symbol *find_pc_function (CORE_ADDR); -/* lookup the function corresponding to the address and section. */ +/* lookup the function corresponding to the address and section. The + return value will not be an inlined function; the containing + function will be returned instead. */ extern struct symbol *find_pc_sect_function (CORE_ADDR, struct obj_section *); -extern int find_pc_partial_function_gnu_ifunc (CORE_ADDR pc, const char **name, +/* lookup the function symbol corresponding to the address and + section. The return value will be the closest enclosing function, + which might be an inline function. */ + +extern struct symbol *find_pc_sect_containing_function + (CORE_ADDR pc, struct obj_section *section); + +/* Find the symbol at the given address. Returns NULL if no symbol + found. Only exact matches for ADDRESS are considered. */ + +extern struct symbol *find_symbol_at_address (CORE_ADDR); + +/* Finds the "function" (text symbol) that is smaller than PC but + greatest of all of the potential text symbols in SECTION. Sets + *NAME and/or *ADDRESS conditionally if that pointer is non-null. + If ENDADDR is non-null, then set *ENDADDR to be the end of the + function (exclusive). If the optional parameter BLOCK is non-null, + then set *BLOCK to the address of the block corresponding to the + function symbol, if such a symbol could be found during the lookup; + nullptr is used as a return value for *BLOCK if no block is found. + This function either succeeds or fails (not halfway succeeds). If + it succeeds, it sets *NAME, *ADDRESS, and *ENDADDR to real + information and returns true. If it fails, it sets *NAME, *ADDRESS + and *ENDADDR to zero and returns false. + + If the function in question occupies non-contiguous ranges, + *ADDRESS and *ENDADDR are (subject to the conditions noted above) set + to the start and end of the range in which PC is found. Thus + *ADDRESS <= PC < *ENDADDR with no intervening gaps (in which ranges + from other functions might be found). + + This property allows find_pc_partial_function to be used (as it had + been prior to the introduction of non-contiguous range support) by + various tdep files for finding a start address and limit address + for prologue analysis. This still isn't ideal, however, because we + probably shouldn't be doing prologue analysis (in which + instructions are scanned to determine frame size and stack layout) + for any range that doesn't contain the entry pc. Moreover, a good + argument can be made that prologue analysis ought to be performed + starting from the entry pc even when PC is within some other range. + This might suggest that *ADDRESS and *ENDADDR ought to be set to the + limits of the entry pc range, but that will cause the + *ADDRESS <= PC < *ENDADDR condition to be violated; many of the + callers of find_pc_partial_function expect this condition to hold. + + Callers which require the start and/or end addresses for the range + containing the entry pc should instead call + find_function_entry_range_from_pc. */ + +extern bool find_pc_partial_function (CORE_ADDR pc, const char **name, + CORE_ADDR *address, CORE_ADDR *endaddr, + const struct block **block = nullptr); + +/* Like find_pc_partial_function, above, but *ADDRESS and *ENDADDR are + set to start and end addresses of the range containing the entry pc. + + Note that it is not necessarily the case that (for non-NULL ADDRESS + and ENDADDR arguments) the *ADDRESS <= PC < *ENDADDR condition will + hold. + + See comment for find_pc_partial_function, above, for further + explanation. */ + +extern bool find_function_entry_range_from_pc (CORE_ADDR pc, + const char **name, CORE_ADDR *address, - CORE_ADDR *endaddr, - int *is_gnu_ifunc_p); + CORE_ADDR *endaddr); + +/* Return the type of a function with its first instruction exactly at + the PC address. Return NULL otherwise. */ -/* lookup function from address, return name, start addr and end addr. */ +extern struct type *find_function_type (CORE_ADDR pc); -extern int find_pc_partial_function (CORE_ADDR, const char **, CORE_ADDR *, - CORE_ADDR *); +/* See if we can figure out the function's actual type from the type + that the resolver returns. RESOLVER_FUNADDR is the address of the + ifunc resolver. */ + +extern struct type *find_gnu_ifunc_target_type (CORE_ADDR resolver_funaddr); + +/* Find the GNU ifunc minimal symbol that matches SYM. */ +extern bound_minimal_symbol find_gnu_ifunc (const symbol *sym); extern void clear_pc_function_cache (void); @@ -1307,7 +1807,7 @@ extern struct compunit_symtab *find_pc_compunit_symtab (CORE_ADDR); extern struct compunit_symtab * find_pc_sect_compunit_symtab (CORE_ADDR, struct obj_section *); -extern int find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *); +extern bool find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *); extern void reread_symbols (void); @@ -1329,7 +1829,7 @@ extern struct type *basic_lookup_transparent_type (const char *); #define GCC2_COMPILED_FLAG_SYMBOL "gcc2_compiled." #endif -extern int in_gnu_ifunc_stub (CORE_ADDR pc); +extern bool in_gnu_ifunc_stub (CORE_ADDR pc); /* Functions for resolving STT_GNU_IFUNC symbols which are implemented only for ELF symbol files. */ @@ -1340,7 +1840,7 @@ struct gnu_ifunc_fns CORE_ADDR (*gnu_ifunc_resolve_addr) (struct gdbarch *gdbarch, CORE_ADDR pc); /* See elf_gnu_ifunc_resolve_name for its real implementation. */ - int (*gnu_ifunc_resolve_name) (const char *function_name, + bool (*gnu_ifunc_resolve_name) (const char *function_name, CORE_ADDR *function_address_p); /* See elf_gnu_ifunc_resolver_stop for its real implementation. */ @@ -1363,34 +1863,29 @@ extern CORE_ADDR find_solib_trampoline_target (struct frame_info *, CORE_ADDR); struct symtab_and_line { /* The program space of this sal. */ - struct program_space *pspace; + struct program_space *pspace = NULL; - struct symtab *symtab; - struct obj_section *section; + struct symtab *symtab = NULL; + struct symbol *symbol = NULL; + struct obj_section *section = NULL; + struct minimal_symbol *msymbol = NULL; /* Line number. Line numbers start at 1 and proceed through symtab->nlines. 0 is never a valid line number; it is used to indicate that line number information is not available. */ - int line; + int line = 0; - CORE_ADDR pc; - CORE_ADDR end; - int explicit_pc; - int explicit_line; + CORE_ADDR pc = 0; + CORE_ADDR end = 0; + bool explicit_pc = false; + bool explicit_line = false; /* The probe associated with this symtab_and_line. */ - struct probe *probe; + probe *prob = NULL; /* If PROBE is not NULL, then this is the objfile in which the probe originated. */ - struct objfile *objfile; + struct objfile *objfile = NULL; }; -extern void init_sal (struct symtab_and_line *sal); - -struct symtabs_and_lines -{ - struct symtab_and_line *sals; - int nelts; -}; /* Given a pc value, return line number it is in. Second arg nonzero means @@ -1409,10 +1904,10 @@ extern struct symtab *find_pc_line_symtab (CORE_ADDR); /* Given a symtab and line number, return the pc there. */ -extern int find_line_pc (struct symtab *, int, CORE_ADDR *); +extern bool find_line_pc (struct symtab *, int, CORE_ADDR *); -extern int find_line_pc_range (struct symtab_and_line, CORE_ADDR *, - CORE_ADDR *); +extern bool find_line_pc_range (struct symtab_and_line, CORE_ADDR *, + CORE_ADDR *); extern void resolve_sal_pc (struct symtab_and_line *); @@ -1420,57 +1915,85 @@ extern void resolve_sal_pc (struct symtab_and_line *); extern void clear_solib (void); -/* source.c */ +/* The reason we're calling into a completion match list collector + function. */ +enum class complete_symbol_mode + { + /* Completing an expression. */ + EXPRESSION, -extern int identify_source_line (struct symtab *, int, int, CORE_ADDR); + /* Completing a linespec. */ + LINESPEC, + }; -/* Flags passed as 4th argument to print_source_lines. */ +extern void default_collect_symbol_completion_matches_break_on + (completion_tracker &tracker, + complete_symbol_mode mode, + symbol_name_match_type name_match_type, + const char *text, const char *word, const char *break_on, + enum type_code code); +extern void default_collect_symbol_completion_matches + (completion_tracker &tracker, + complete_symbol_mode, + symbol_name_match_type name_match_type, + const char *, + const char *, + enum type_code); +extern void collect_symbol_completion_matches + (completion_tracker &tracker, + complete_symbol_mode mode, + symbol_name_match_type name_match_type, + const char *, const char *); +extern void collect_symbol_completion_matches_type (completion_tracker &tracker, + const char *, const char *, + enum type_code); -enum print_source_lines_flags - { - /* Do not print an error message. */ - PRINT_SOURCE_LINES_NOERROR = (1 << 0), +extern void collect_file_symbol_completion_matches + (completion_tracker &tracker, + complete_symbol_mode, + symbol_name_match_type name_match_type, + const char *, const char *, const char *); - /* Print the filename in front of the source lines. */ - PRINT_SOURCE_LINES_FILENAME = (1 << 1) - }; +extern completion_list + make_source_files_completion_list (const char *, const char *); -extern void print_source_lines (struct symtab *, int, int, - enum print_source_lines_flags); +/* Return whether SYM is a function/method, as opposed to a data symbol. */ -extern void forget_cached_source_info_for_objfile (struct objfile *); -extern void forget_cached_source_info (void); +extern bool symbol_is_function_or_method (symbol *sym); -extern void select_source_symtab (struct symtab *); +/* Return whether MSYMBOL is a function/method, as opposed to a data + symbol */ -extern VEC (char_ptr) *default_make_symbol_completion_list_break_on - (const char *text, const char *word, const char *break_on, - enum type_code code); -extern VEC (char_ptr) *default_make_symbol_completion_list (const char *, - const char *, - enum type_code); -extern VEC (char_ptr) *make_symbol_completion_list (const char *, const char *); -extern VEC (char_ptr) *make_symbol_completion_type (const char *, const char *, - enum type_code); -extern VEC (char_ptr) *make_symbol_completion_list_fn (struct cmd_list_element *, - const char *, - const char *); +extern bool symbol_is_function_or_method (minimal_symbol *msymbol); -extern VEC (char_ptr) *make_file_symbol_completion_list (const char *, - const char *, - const char *); +/* Return whether SYM should be skipped in completion mode MODE. In + linespec mode, we're only interested in functions/methods. */ -extern VEC (char_ptr) *make_source_files_completion_list (const char *, - const char *); +template +static bool +completion_skip_symbol (complete_symbol_mode mode, Symbol *sym) +{ + return (mode == complete_symbol_mode::LINESPEC + && !symbol_is_function_or_method (sym)); +} /* symtab.c */ -int matching_obj_sections (struct obj_section *, struct obj_section *); +bool matching_obj_sections (struct obj_section *, struct obj_section *); -extern struct symtab *find_line_symtab (struct symtab *, int, int *, int *); +extern struct symtab *find_line_symtab (struct symtab *, int, int *, bool *); -extern struct symtab_and_line find_function_start_sal (struct symbol *sym, - int); +/* Given a function symbol SYM, find the symtab and line for the start + of the function. If FUNFIRSTLINE is true, we want the first line + of real code inside the function. */ +extern symtab_and_line find_function_start_sal (symbol *sym, bool + funfirstline); + +/* Same, but start with a function address/section instead of a + symbol. */ +extern symtab_and_line find_function_start_sal (CORE_ADDR func_addr, + obj_section *section, + bool funfirstline); extern void skip_prologue_sal (struct symtab_and_line *); @@ -1482,14 +2005,48 @@ extern CORE_ADDR skip_prologue_using_sal (struct gdbarch *gdbarch, extern struct symbol *fixup_symbol_section (struct symbol *, struct objfile *); +/* If MSYMBOL is an text symbol, look for a function debug symbol with + the same address. Returns NULL if not found. This is necessary in + case a function is an alias to some other function, because debug + information is only emitted for the alias target function's + definition, not for the alias. */ +extern symbol *find_function_alias_target (bound_minimal_symbol msymbol); + /* Symbol searching */ /* Note: struct symbol_search, search_symbols, et.al. are declared here, instead of making them local to symtab.c, for gdbtk's sake. */ -/* When using search_symbols, a list of the following structs is returned. - Callers must free the search list using free_search_symbols! */ +/* When using search_symbols, a vector of the following structs is + returned. */ struct symbol_search { + symbol_search (int block_, struct symbol *symbol_) + : block (block_), + symbol (symbol_) + { + msymbol.minsym = nullptr; + msymbol.objfile = nullptr; + } + + symbol_search (int block_, struct minimal_symbol *minsym, + struct objfile *objfile) + : block (block_), + symbol (nullptr) + { + msymbol.minsym = minsym; + msymbol.objfile = objfile; + } + + bool operator< (const symbol_search &other) const + { + return compare_search_syms (*this, other) < 0; + } + + bool operator== (const symbol_search &other) const + { + return compare_search_syms (*this, other) == 0; + } + /* The block in which the match was found. Could be, for example, STATIC_BLOCK or GLOBAL_BLOCK. */ int block; @@ -1503,37 +2060,57 @@ struct symbol_search which only minimal_symbols exist. */ struct bound_minimal_symbol msymbol; - /* A link to the next match, or NULL for the end. */ - struct symbol_search *next; +private: + + static int compare_search_syms (const symbol_search &sym_a, + const symbol_search &sym_b); }; -extern void search_symbols (const char *, enum search_domain, int, - const char **, struct symbol_search **); -extern void free_search_symbols (struct symbol_search *); -extern struct cleanup *make_cleanup_free_search_symbols (struct symbol_search - **); - -/* The name of the ``main'' function. - FIXME: cagney/2001-03-20: Can't make main_name() const since some - of the calling code currently assumes that the string isn't - const. */ -extern /*const */ char *main_name (void); +extern std::vector search_symbols (const char *, + enum search_domain, + const char *, + int, + const char **, + bool); + +/* When searching for Fortran symbols within modules (functions/variables) + we return a vector of this type. The first item in the pair is the + module symbol, and the second item is the symbol for the function or + variable we found. */ +typedef std::pair module_symbol_search; + +/* Searches the symbols to find function and variables symbols (depending + on KIND) within Fortran modules. The MODULE_REGEXP matches against the + name of the module, REGEXP matches against the name of the symbol within + the module, and TYPE_REGEXP matches against the type of the symbol + within the module. */ +extern std::vector search_module_symbols + (const char *module_regexp, const char *regexp, + const char *type_regexp, search_domain kind); + +extern bool treg_matches_sym_type_name (const compiled_regex &treg, + const struct symbol *sym); + +/* The name of the ``main'' function. */ +extern const char *main_name (); extern enum language main_language (void); -/* Lookup symbol NAME from DOMAIN in MAIN_OBJFILE's global blocks. +/* Lookup symbol NAME from DOMAIN in MAIN_OBJFILE's global or static blocks, + as specified by BLOCK_INDEX. This searches MAIN_OBJFILE as well as any associated separate debug info objfiles of MAIN_OBJFILE. - Upon success sets BLOCK_FOUND and fixes up the symbol's section - if necessary. */ + BLOCK_INDEX can be GLOBAL_BLOCK or STATIC_BLOCK. + Upon success fixes up the symbol's section if necessary. */ -extern struct symbol * +extern struct block_symbol lookup_global_symbol_from_objfile (struct objfile *main_objfile, + enum block_enum block_index, const char *name, const domain_enum domain); /* Return 1 if the supplied producer string matches the ARM RealView compiler (armcc). */ -int producer_is_realview (const char *producer); +bool producer_is_realview (const char *producer); void fixup_section (struct general_symbol_info *ginfo, CORE_ADDR addr, struct objfile *objfile); @@ -1546,45 +2123,95 @@ extern unsigned int symtab_create_debug; extern unsigned int symbol_lookup_debug; -extern int basenames_may_differ; +extern bool basenames_may_differ; -int compare_filenames_for_search (const char *filename, - const char *search_name); +bool compare_filenames_for_search (const char *filename, + const char *search_name); -int iterate_over_some_symtabs (const char *name, - const char *real_path, - int (*callback) (struct symtab *symtab, - void *data), - void *data, - struct compunit_symtab *first, - struct compunit_symtab *after_last); +bool compare_glob_filenames_for_search (const char *filename, + const char *search_name); + +bool iterate_over_some_symtabs (const char *name, + const char *real_path, + struct compunit_symtab *first, + struct compunit_symtab *after_last, + gdb::function_view callback); void iterate_over_symtabs (const char *name, - int (*callback) (struct symtab *symtab, - void *data), - void *data); + gdb::function_view callback); + + +std::vector find_pcs_for_symtab_line + (struct symtab *symtab, int line, struct linetable_entry **best_entry); -DEF_VEC_I (CORE_ADDR); +/* Prototype for callbacks for LA_ITERATE_OVER_SYMBOLS. The callback + is called once per matching symbol SYM. The callback should return + true to indicate that LA_ITERATE_OVER_SYMBOLS should continue + iterating, or false to indicate that the iteration should end. */ -VEC (CORE_ADDR) *find_pcs_for_symtab_line (struct symtab *symtab, int line, - struct linetable_entry **best_entry); +typedef bool (symbol_found_callback_ftype) (struct block_symbol *bsym); -/* Callback for LA_ITERATE_OVER_SYMBOLS. The callback will be called - once per matching symbol SYM, with DATA being the argument of the - same name that was passed to LA_ITERATE_OVER_SYMBOLS. The callback - should return nonzero to indicate that LA_ITERATE_OVER_SYMBOLS - should continue iterating, or zero to indicate that the iteration - should end. */ +/* Iterate over the symbols named NAME, matching DOMAIN, in BLOCK. -typedef int (symbol_found_callback_ftype) (struct symbol *sym, void *data); + For each symbol that matches, CALLBACK is called. The symbol is + passed to the callback. -void iterate_over_symbols (const struct block *block, const char *name, + If CALLBACK returns false, the iteration ends and this function + returns false. Otherwise, the search continues, and the function + eventually returns true. */ + +bool iterate_over_symbols (const struct block *block, + const lookup_name_info &name, const domain_enum domain, - symbol_found_callback_ftype *callback, - void *data); + gdb::function_view callback); + +/* Like iterate_over_symbols, but if all calls to CALLBACK return + true, then calls CALLBACK one additional time with a block_symbol + that has a valid block but a NULL symbol. */ + +bool iterate_over_symbols_terminated + (const struct block *block, + const lookup_name_info &name, + const domain_enum domain, + gdb::function_view callback); + +/* Storage type used by demangle_for_lookup. demangle_for_lookup + either returns a const char * pointer that points to either of the + fields of this type, or a pointer to the input NAME. This is done + this way because the underlying functions that demangle_for_lookup + calls either return a std::string (e.g., cp_canonicalize_string) or + a malloc'ed buffer (libiberty's demangled), and we want to avoid + unnecessary reallocation/string copying. */ +class demangle_result_storage +{ +public: -struct cleanup *demangle_for_lookup (const char *name, enum language lang, - const char **result_name); + /* Swap the std::string storage with STR, and return a pointer to + the beginning of the new string. */ + const char *swap_string (std::string &str) + { + std::swap (m_string, str); + return m_string.c_str (); + } + + /* Set the malloc storage to now point at PTR. Any previous malloc + storage is released. */ + const char *set_malloc_ptr (char *ptr) + { + m_malloc.reset (ptr); + return ptr; + } + +private: + + /* The storage. */ + std::string m_string; + gdb::unique_xmalloc_ptr m_malloc; +}; + +const char * + demangle_for_lookup (const char *name, enum language lang, + demangle_result_storage &storage); struct symbol *allocate_symbol (struct objfile *); @@ -1592,4 +2219,57 @@ void initialize_objfile_symbol (struct symbol *); struct template_symbol *allocate_template_symbol (struct objfile *); +/* Test to see if the symbol of language SYMBOL_LANGUAGE specified by + SYMNAME (which is already demangled for C++ symbols) matches + SYM_TEXT in the first SYM_TEXT_LEN characters. If so, add it to + the current completion list. */ +void completion_list_add_name (completion_tracker &tracker, + language symbol_language, + const char *symname, + const lookup_name_info &lookup_name, + const char *text, const char *word); + +/* A simple symbol searching class. */ + +class symbol_searcher +{ +public: + /* Returns the symbols found for the search. */ + const std::vector & + matching_symbols () const + { + return m_symbols; + } + + /* Returns the minimal symbols found for the search. */ + const std::vector & + matching_msymbols () const + { + return m_minimal_symbols; + } + + /* Search for all symbols named NAME in LANGUAGE with DOMAIN, restricting + search to FILE_SYMTABS and SEARCH_PSPACE, both of which may be NULL + to search all symtabs and program spaces. */ + void find_all_symbols (const std::string &name, + const struct language_defn *language, + enum search_domain search_domain, + std::vector *search_symtabs, + struct program_space *search_pspace); + + /* Reset this object to perform another search. */ + void reset () + { + m_symbols.clear (); + m_minimal_symbols.clear (); + } + +private: + /* Matching debug symbols. */ + std::vector m_symbols; + + /* Matching non-debug symbols. */ + std::vector m_minimal_symbols; +}; + #endif /* !defined(SYMTAB_H) */