X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fblock.c;h=366141c0333c7393c3835cf17f679bcc845d55a1;hb=d55e5aa6b29906346c51ad00e6a9b112590aa294;hp=2638de8f9a6e3c1b5c6ae109f43bc2c15e94a8a9;hpb=28e7fd62340426746f9c896cbc40c5d374ec47aa;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/block.c b/gdb/block.c index 2638de8f9a..366141c033 100644 --- a/gdb/block.c +++ b/gdb/block.c @@ -1,6 +1,6 @@ /* Block-related functions for the GNU debugger, GDB. - Copyright (C) 2003-2013 Free Software Foundation, Inc. + Copyright (C) 2003-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -18,28 +18,55 @@ along with this program. If not, see . */ #include "defs.h" + +/* Local non-gdb includes. */ +#include "addrmap.h" #include "block.h" -#include "symtab.h" -#include "symfile.h" -#include "gdb_obstack.h" #include "cp-support.h" -#include "addrmap.h" +#include "gdb_obstack.h" #include "gdbtypes.h" -#include "exceptions.h" +#include "objfiles.h" +#include "symfile.h" +#include "symtab.h" /* This is used by struct block to store namespace-related info for C++ files, namely using declarations and the current namespace in scope. */ -struct block_namespace_info +struct block_namespace_info : public allocate_on_obstack { - const char *scope; - struct using_direct *using; + const char *scope = nullptr; + struct using_direct *using_decl = nullptr; }; static void block_initialize_namespace (struct block *block, struct obstack *obstack); +/* See block.h. */ + +struct objfile * +block_objfile (const struct block *block) +{ + const struct global_block *global_block; + + if (BLOCK_FUNCTION (block) != NULL) + return symbol_objfile (BLOCK_FUNCTION (block)); + + global_block = (struct global_block *) block_global_block (block); + return COMPUNIT_OBJFILE (global_block->compunit_symtab); +} + +/* See block. */ + +struct gdbarch * +block_gdbarch (const struct block *block) +{ + if (BLOCK_FUNCTION (block) != NULL) + return symbol_arch (BLOCK_FUNCTION (block)); + + return get_objfile_arch (block_objfile (block)); +} + /* Return Nonzero if block a is lexically nested within block b, or if a and b have the same pc range. Return zero otherwise. */ @@ -106,16 +133,16 @@ block_inlined_p (const struct block *bl) /* A helper function that checks whether PC is in the blockvector BL. It returns the containing block if there is one, or else NULL. */ -static struct block * -find_block_in_blockvector (struct blockvector *bl, CORE_ADDR pc) +static const struct block * +find_block_in_blockvector (const struct blockvector *bl, CORE_ADDR pc) { - struct block *b; + const struct block *b; int bot, top, half; /* If we have an addrmap mapping code addresses to blocks, then use that. */ if (BLOCKVECTOR_MAP (bl)) - return addrmap_find (BLOCKVECTOR_MAP (bl), pc); + return (const struct block *) addrmap_find (BLOCKVECTOR_MAP (bl), pc); /* Otherwise, use binary search to find the last block that starts before PC. @@ -155,22 +182,23 @@ find_block_in_blockvector (struct blockvector *bl, CORE_ADDR pc) is none. PBLOCK is a pointer to the block. If PBLOCK is NULL, we don't pass this information back to the caller. */ -struct blockvector * +const struct blockvector * blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section, - struct block **pblock, struct symtab *symtab) + const struct block **pblock, + struct compunit_symtab *cust) { - struct blockvector *bl; - struct block *b; + const struct blockvector *bl; + const struct block *b; - if (symtab == 0) /* if no symtab specified by caller */ + if (cust == NULL) { /* First search all symtabs for one whose file contains our pc */ - symtab = find_pc_sect_symtab (pc, section); - if (symtab == 0) + cust = find_pc_sect_compunit_symtab (pc, section); + if (cust == NULL) return 0; } - bl = BLOCKVECTOR (symtab); + bl = COMPUNIT_BLOCKVECTOR (cust); /* Then search that symtab for the smallest block that wins. */ b = find_block_in_blockvector (bl, pc); @@ -185,7 +213,7 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section, /* Return true if the blockvector BV contains PC, false otherwise. */ int -blockvector_contains_pc (struct blockvector *bv, CORE_ADDR pc) +blockvector_contains_pc (const struct blockvector *bv, CORE_ADDR pc) { return find_block_in_blockvector (bv, pc) != NULL; } @@ -197,37 +225,38 @@ blockvector_contains_pc (struct blockvector *bv, CORE_ADDR pc) struct call_site * call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc) { - struct symtab *symtab; + struct compunit_symtab *cust; void **slot = NULL; /* -1 as tail call PC can be already after the compilation unit range. */ - symtab = find_pc_symtab (pc - 1); + cust = find_pc_compunit_symtab (pc - 1); - if (symtab != NULL && symtab->call_site_htab != NULL) - slot = htab_find_slot (symtab->call_site_htab, &pc, NO_INSERT); + if (cust != NULL && COMPUNIT_CALL_SITE_HTAB (cust) != NULL) + slot = htab_find_slot (COMPUNIT_CALL_SITE_HTAB (cust), &pc, NO_INSERT); if (slot == NULL) { - struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (pc); + struct bound_minimal_symbol msym = lookup_minimal_symbol_by_pc (pc); /* DW_TAG_gnu_call_site will be missing just if GCC could not determine the call target. */ throw_error (NO_ENTRY_VALUE_ERROR, - _("DW_OP_GNU_entry_value resolving cannot find " - "DW_TAG_GNU_call_site %s in %s"), + _("DW_OP_entry_value resolving cannot find " + "DW_TAG_call_site %s in %s"), paddress (gdbarch, pc), - msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym)); + (msym.minsym == NULL ? "???" + : MSYMBOL_PRINT_NAME (msym.minsym))); } - return *slot; + return (struct call_site *) *slot; } /* Return the blockvector immediately containing the innermost lexical block containing the specified pc value, or 0 if there is none. Backward compatibility, no section. */ -struct blockvector * -blockvector_for_pc (CORE_ADDR pc, struct block **pblock) +const struct blockvector * +blockvector_for_pc (CORE_ADDR pc, const struct block **pblock) { return blockvector_for_pc_sect (pc, find_pc_mapped_section (pc), pblock, NULL); @@ -236,11 +265,11 @@ blockvector_for_pc (CORE_ADDR pc, struct block **pblock) /* Return the innermost lexical block containing the specified pc value in the specified section, or 0 if there is none. */ -struct block * +const struct block * block_for_pc_sect (CORE_ADDR pc, struct obj_section *section) { - struct blockvector *bl; - struct block *b; + const struct blockvector *bl; + const struct block *b; bl = blockvector_for_pc_sect (pc, section, &b, NULL); if (bl) @@ -251,7 +280,7 @@ block_for_pc_sect (CORE_ADDR pc, struct obj_section *section) /* Return the innermost lexical block containing the specified pc value, or 0 if there is none. Backward compatibility, no section. */ -struct block * +const struct block * block_for_pc (CORE_ADDR pc) { return block_for_pc_sect (pc, find_pc_mapped_section (pc)); @@ -299,7 +328,7 @@ block_using (const struct block *block) if (block == NULL || BLOCK_NAMESPACE (block) == NULL) return NULL; else - return BLOCK_NAMESPACE (block)->using; + return BLOCK_NAMESPACE (block)->using_decl; } /* Set BLOCK's using member to USING; if needed, allocate memory via @@ -308,12 +337,12 @@ block_using (const struct block *block) void block_set_using (struct block *block, - struct using_direct *using, + struct using_direct *using_decl, struct obstack *obstack) { block_initialize_namespace (block, obstack); - BLOCK_NAMESPACE (block)->using = using; + BLOCK_NAMESPACE (block)->using_decl = using_decl; } /* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and @@ -323,12 +352,7 @@ static void block_initialize_namespace (struct block *block, struct obstack *obstack) { if (BLOCK_NAMESPACE (block) == NULL) - { - BLOCK_NAMESPACE (block) - = obstack_alloc (obstack, sizeof (struct block_namespace_info)); - BLOCK_NAMESPACE (block)->scope = NULL; - BLOCK_NAMESPACE (block)->using = NULL; - } + BLOCK_NAMESPACE (block) = new (obstack) struct block_namespace_info (); } /* Return the static block associated to BLOCK. Return NULL if block @@ -365,22 +389,15 @@ block_global_block (const struct block *block) zero/NULL. This is useful for creating "dummy" blocks that don't correspond to actual source files. - Warning: it sets the block's BLOCK_DICT to NULL, which isn't a + Warning: it sets the block's BLOCK_MULTIDICT to NULL, which isn't a valid value. If you really don't want the block to have a - dictionary, then you should subsequently set its BLOCK_DICT to + dictionary, then you should subsequently set its BLOCK_MULTIDICT to dict_create_linear (obstack, NULL). */ struct block * allocate_block (struct obstack *obstack) { - struct block *bl = obstack_alloc (obstack, sizeof (struct block)); - - BLOCK_START (bl) = 0; - BLOCK_END (bl) = 0; - BLOCK_FUNCTION (bl) = NULL; - BLOCK_SUPERBLOCK (bl) = NULL; - BLOCK_DICT (bl) = NULL; - BLOCK_NAMESPACE (bl) = NULL; + struct block *bl = OBSTACK_ZALLOC (obstack, struct block); return bl; } @@ -395,30 +412,45 @@ allocate_global_block (struct obstack *obstack) return &bl->block; } -/* Set the symtab of the global block. */ +/* Set the compunit of the global block. */ void -set_block_symtab (struct block *block, struct symtab *symtab) +set_block_compunit_symtab (struct block *block, struct compunit_symtab *cu) { struct global_block *gb; gdb_assert (BLOCK_SUPERBLOCK (block) == NULL); gb = (struct global_block *) block; - gdb_assert (gb->symtab == NULL); - gb->symtab = symtab; + gdb_assert (gb->compunit_symtab == NULL); + gb->compunit_symtab = cu; } -/* Return the symtab of the global block. */ +/* See block.h. */ -static struct symtab * -get_block_symtab (const struct block *block) +struct dynamic_prop * +block_static_link (const struct block *block) +{ + struct objfile *objfile = block_objfile (block); + + /* Only objfile-owned blocks that materialize top function scopes can have + static links. */ + if (objfile == NULL || BLOCK_FUNCTION (block) == NULL) + return NULL; + + return (struct dynamic_prop *) objfile_lookup_static_link (objfile, block); +} + +/* Return the compunit of the global block. */ + +static struct compunit_symtab * +get_block_compunit_symtab (const struct block *block) { struct global_block *gb; gdb_assert (BLOCK_SUPERBLOCK (block) == NULL); gb = (struct global_block *) block; - gdb_assert (gb->symtab != NULL); - return gb->symtab; + gdb_assert (gb->compunit_symtab != NULL); + return gb->compunit_symtab; } @@ -432,19 +464,19 @@ initialize_block_iterator (const struct block *block, struct block_iterator *iter) { enum block_enum which; - struct symtab *symtab; + struct compunit_symtab *cu; iter->idx = -1; if (BLOCK_SUPERBLOCK (block) == NULL) { which = GLOBAL_BLOCK; - symtab = get_block_symtab (block); + cu = get_block_compunit_symtab (block); } else if (BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL) { which = STATIC_BLOCK; - symtab = get_block_symtab (BLOCK_SUPERBLOCK (block)); + cu = get_block_compunit_symtab (BLOCK_SUPERBLOCK (block)); } else { @@ -457,14 +489,14 @@ initialize_block_iterator (const struct block *block, /* If this is an included symtab, find the canonical includer and use it instead. */ - while (symtab->user != NULL) - symtab = symtab->user; + while (cu->user != NULL) + cu = cu->user; /* Putting this check here simplifies the logic of the iterator functions. If there are no included symtabs, we only need to search a single block, so we might as well just do that directly. */ - if (symtab->includes == NULL) + if (cu->includes == NULL) { iter->d.block = block; /* A signal value meaning that we're iterating over a single @@ -473,20 +505,20 @@ initialize_block_iterator (const struct block *block, } else { - iter->d.symtab = symtab; + iter->d.compunit_symtab = cu; iter->which = which; } } -/* A helper function that finds the current symtab over whose static +/* A helper function that finds the current compunit over whose static or global block we should iterate. */ -static struct symtab * -find_iterator_symtab (struct block_iterator *iterator) +static struct compunit_symtab * +find_iterator_compunit_symtab (struct block_iterator *iterator) { if (iterator->idx == -1) - return iterator->d.symtab; - return iterator->d.symtab->includes[iterator->idx]; + return iterator->d.compunit_symtab; + return iterator->d.compunit_symtab->includes[iterator->idx]; } /* Perform a single step for a plain block iterator, iterating across @@ -504,18 +536,21 @@ block_iterator_step (struct block_iterator *iterator, int first) { if (first) { - struct symtab *symtab = find_iterator_symtab (iterator); + struct compunit_symtab *cust + = find_iterator_compunit_symtab (iterator); const struct block *block; /* Iteration is complete. */ - if (symtab == NULL) + if (cust == NULL) return NULL; - block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), iterator->which); - sym = dict_iterator_first (BLOCK_DICT (block), &iterator->dict_iter); + block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), + iterator->which); + sym = mdict_iterator_first (BLOCK_MULTIDICT (block), + &iterator->mdict_iter); } else - sym = dict_iterator_next (&iterator->dict_iter); + sym = mdict_iterator_next (&iterator->mdict_iter); if (sym != NULL) return sym; @@ -537,7 +572,7 @@ block_iterator_first (const struct block *block, initialize_block_iterator (block, iterator); if (iterator->which == FIRST_LOCAL_BLOCK) - return dict_iterator_first (block->dict, &iterator->dict_iter); + return mdict_iterator_first (block->multidict, &iterator->mdict_iter); return block_iterator_step (iterator, 1); } @@ -548,18 +583,19 @@ struct symbol * block_iterator_next (struct block_iterator *iterator) { if (iterator->which == FIRST_LOCAL_BLOCK) - return dict_iterator_next (&iterator->dict_iter); + return mdict_iterator_next (&iterator->mdict_iter); return block_iterator_step (iterator, 0); } -/* Perform a single step for a "name" block iterator, iterating across - symbol tables as needed. Returns the next symbol, or NULL when - iteration is complete. */ +/* Perform a single step for a "match" block iterator, iterating + across symbol tables as needed. Returns the next symbol, or NULL + when iteration is complete. */ static struct symbol * -block_iter_name_step (struct block_iterator *iterator, const char *name, - int first) +block_iter_match_step (struct block_iterator *iterator, + const lookup_name_info &name, + int first) { struct symbol *sym; @@ -569,19 +605,21 @@ block_iter_name_step (struct block_iterator *iterator, const char *name, { if (first) { - struct symtab *symtab = find_iterator_symtab (iterator); + struct compunit_symtab *cust + = find_iterator_compunit_symtab (iterator); const struct block *block; /* Iteration is complete. */ - if (symtab == NULL) + if (cust == NULL) return NULL; - block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), iterator->which); - sym = dict_iter_name_first (BLOCK_DICT (block), name, - &iterator->dict_iter); + block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), + iterator->which); + sym = mdict_iter_match_first (BLOCK_MULTIDICT (block), name, + &iterator->mdict_iter); } else - sym = dict_iter_name_next (name, &iterator->dict_iter); + sym = mdict_iter_match_next (name, &iterator->mdict_iter); if (sym != NULL) return sym; @@ -597,98 +635,201 @@ block_iter_name_step (struct block_iterator *iterator, const char *name, /* See block.h. */ struct symbol * -block_iter_name_first (const struct block *block, - const char *name, - struct block_iterator *iterator) +block_iter_match_first (const struct block *block, + const lookup_name_info &name, + struct block_iterator *iterator) { initialize_block_iterator (block, iterator); if (iterator->which == FIRST_LOCAL_BLOCK) - return dict_iter_name_first (block->dict, name, &iterator->dict_iter); + return mdict_iter_match_first (block->multidict, name, + &iterator->mdict_iter); - return block_iter_name_step (iterator, name, 1); + return block_iter_match_step (iterator, name, 1); } /* See block.h. */ struct symbol * -block_iter_name_next (const char *name, struct block_iterator *iterator) +block_iter_match_next (const lookup_name_info &name, + struct block_iterator *iterator) { if (iterator->which == FIRST_LOCAL_BLOCK) - return dict_iter_name_next (name, &iterator->dict_iter); + return mdict_iter_match_next (name, &iterator->mdict_iter); - return block_iter_name_step (iterator, name, 0); + return block_iter_match_step (iterator, name, 0); } -/* Perform a single step for a "match" block iterator, iterating - across symbol tables as needed. Returns the next symbol, or NULL - when iteration is complete. */ +/* See block.h. -static struct symbol * -block_iter_match_step (struct block_iterator *iterator, - const char *name, - symbol_compare_ftype *compare, - int first) + Note that if NAME is the demangled form of a C++ symbol, we will fail + to find a match during the binary search of the non-encoded names, but + for now we don't worry about the slight inefficiency of looking for + a match we'll never find, since it will go pretty quick. Once the + binary search terminates, we drop through and do a straight linear + search on the symbols. Each symbol which is marked as being a ObjC/C++ + symbol (language_cplus or language_objc set) has both the encoded and + non-encoded names tested for a match. */ + +struct symbol * +block_lookup_symbol (const struct block *block, const char *name, + symbol_name_match_type match_type, + const domain_enum domain) { + struct block_iterator iter; struct symbol *sym; - gdb_assert (iterator->which != FIRST_LOCAL_BLOCK); + lookup_name_info lookup_name (name, match_type); - while (1) + if (!BLOCK_FUNCTION (block)) { - if (first) + struct symbol *other = NULL; + + ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym) { - struct symtab *symtab = find_iterator_symtab (iterator); - const struct block *block; + if (SYMBOL_DOMAIN (sym) == domain) + return sym; + /* This is a bit of a hack, but symbol_matches_domain might ignore + STRUCT vs VAR domain symbols. So if a matching symbol is found, + make sure there is no "better" matching symbol, i.e., one with + exactly the same domain. PR 16253. */ + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), domain)) + other = sym; + } + return other; + } + else + { + /* Note that parameter symbols do not always show up last in the + list; this loop makes sure to take anything else other than + parameter symbols first; it only uses parameter symbols as a + last resort. Note that this only takes up extra computation + time on a match. + It's hard to define types in the parameter list (at least in + C/C++) so we don't do the same PR 16253 hack here that is done + for the !BLOCK_FUNCTION case. */ + + struct symbol *sym_found = NULL; + + ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym) + { + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), domain)) + { + sym_found = sym; + if (!SYMBOL_IS_ARGUMENT (sym)) + { + break; + } + } + } + return (sym_found); /* Will be NULL if not found. */ + } +} - /* Iteration is complete. */ - if (symtab == NULL) - return NULL; +/* See block.h. */ - block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), iterator->which); - sym = dict_iter_match_first (BLOCK_DICT (block), name, - compare, &iterator->dict_iter); - } - else - sym = dict_iter_match_next (name, compare, &iterator->dict_iter); +struct symbol * +block_lookup_symbol_primary (const struct block *block, const char *name, + const domain_enum domain) +{ + struct symbol *sym, *other; + struct mdict_iterator mdict_iter; - if (sym != NULL) + lookup_name_info lookup_name (name, symbol_name_match_type::FULL); + + /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */ + gdb_assert (BLOCK_SUPERBLOCK (block) == NULL + || BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL); + + other = NULL; + for (sym + = mdict_iter_match_first (block->multidict, lookup_name, &mdict_iter); + sym != NULL; + sym = mdict_iter_match_next (lookup_name, &mdict_iter)) + { + if (SYMBOL_DOMAIN (sym) == domain) return sym; - /* We have finished iterating the appropriate block of one - symtab. Now advance to the next symtab and begin iteration - there. */ - ++iterator->idx; - first = 1; + /* This is a bit of a hack, but symbol_matches_domain might ignore + STRUCT vs VAR domain symbols. So if a matching symbol is found, + make sure there is no "better" matching symbol, i.e., one with + exactly the same domain. PR 16253. */ + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), domain)) + other = sym; } + + return other; } /* See block.h. */ struct symbol * -block_iter_match_first (const struct block *block, - const char *name, - symbol_compare_ftype *compare, - struct block_iterator *iterator) +block_find_symbol (const struct block *block, const char *name, + const domain_enum domain, + block_symbol_matcher_ftype *matcher, void *data) { - initialize_block_iterator (block, iterator); + struct block_iterator iter; + struct symbol *sym; - if (iterator->which == FIRST_LOCAL_BLOCK) - return dict_iter_match_first (block->dict, name, compare, - &iterator->dict_iter); + lookup_name_info lookup_name (name, symbol_name_match_type::FULL); - return block_iter_match_step (iterator, name, compare, 1); + /* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */ + gdb_assert (BLOCK_SUPERBLOCK (block) == NULL + || BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL); + + ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym) + { + /* MATCHER is deliberately called second here so that it never sees + a non-domain-matching symbol. */ + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), domain) + && matcher (sym, data)) + return sym; + } + return NULL; } /* See block.h. */ -struct symbol * -block_iter_match_next (const char *name, - symbol_compare_ftype *compare, - struct block_iterator *iterator) +int +block_find_non_opaque_type (struct symbol *sym, void *data) { - if (iterator->which == FIRST_LOCAL_BLOCK) - return dict_iter_match_next (name, compare, &iterator->dict_iter); + return !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)); +} - return block_iter_match_step (iterator, name, compare, 0); +/* See block.h. */ + +int +block_find_non_opaque_type_preferred (struct symbol *sym, void *data) +{ + struct symbol **best = (struct symbol **) data; + + if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) + return 1; + *best = sym; + return 0; +} + +/* See block.h. */ + +struct blockranges * +make_blockranges (struct objfile *objfile, + const std::vector &rangevec) +{ + struct blockranges *blr; + size_t n = rangevec.size(); + + blr = (struct blockranges *) + obstack_alloc (&objfile->objfile_obstack, + sizeof (struct blockranges) + + (n - 1) * sizeof (struct blockrange)); + + blr->nranges = n; + for (int i = 0; i < n; i++) + blr->range[i] = rangevec[i]; + return blr; } +