X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fblock.c;h=46c24ec96d510d01231be932ac8c9fd0288d701d;hb=40c75bc8b07abc5d5774ea1c439b69c96e7fd485;hp=5c6faa850457efecf76c13a3ed2bb8f2f8edc5d2;hpb=aa3b653351504e262fb455af5efb6eea6d981597;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/block.c b/gdb/block.c index 5c6faa8504..46c24ec96d 100644 --- a/gdb/block.c +++ b/gdb/block.c @@ -1,6 +1,6 @@ /* Block-related functions for the GNU debugger, GDB. - Copyright (C) 2003-2019 Free Software Foundation, Inc. + Copyright (C) 2003-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -65,25 +65,28 @@ block_gdbarch (const struct block *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. */ +/* See block.h. */ -int -contained_in (const struct block *a, const struct block *b) +bool +contained_in (const struct block *a, const struct block *b, + bool allow_nested) { if (!a || !b) - return 0; + return false; do { if (a == b) - return 1; + return true; + /* If A is a function block, then A cannot be contained in B, + except if A was inlined. */ + if (!allow_nested && BLOCK_FUNCTION (a) != NULL && !block_inlined_p (a)) + return false; a = BLOCK_SUPERBLOCK (a); } while (a != NULL); - return 0; + return false; } @@ -239,7 +242,7 @@ call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc) "DW_TAG_call_site %s in %s"), paddress (gdbarch, pc), (msym.minsym == NULL ? "???" - : MSYMBOL_PRINT_NAME (msym.minsym))); + : msym.minsym->print_name ())); } return (struct call_site *) *slot; @@ -340,7 +343,7 @@ block_set_using (struct block *block, } /* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and - ititialize its members to zero. */ + initialize its members to zero. */ static void block_initialize_namespace (struct block *block, struct obstack *obstack) @@ -654,6 +657,43 @@ block_iter_match_next (const lookup_name_info &name, return block_iter_match_step (iterator, name, 0); } +/* Return true if symbol A is the best match possible for DOMAIN. */ + +static bool +best_symbol (struct symbol *a, const domain_enum domain) +{ + return (SYMBOL_DOMAIN (a) == domain + && SYMBOL_CLASS (a) != LOC_UNRESOLVED); +} + +/* Return symbol B if it is a better match than symbol A for DOMAIN. + Otherwise return A. */ + +static struct symbol * +better_symbol (struct symbol *a, struct symbol *b, const domain_enum domain) +{ + if (a == NULL) + return b; + if (b == NULL) + return a; + + if (SYMBOL_DOMAIN (a) == domain + && SYMBOL_DOMAIN (b) != domain) + return a; + if (SYMBOL_DOMAIN (b) == domain + && SYMBOL_DOMAIN (a) != domain) + return b; + + if (SYMBOL_CLASS (a) != LOC_UNRESOLVED + && SYMBOL_CLASS (b) == LOC_UNRESOLVED) + return a; + if (SYMBOL_CLASS (b) != LOC_UNRESOLVED + && SYMBOL_CLASS (a) == LOC_UNRESOLVED) + return b; + + return a; +} + /* See block.h. Note that if NAME is the demangled form of a C++ symbol, we will fail @@ -681,15 +721,17 @@ block_lookup_symbol (const struct block *block, const char *name, ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym) { - if (SYMBOL_DOMAIN (sym) == domain) + /* See comment related to PR gcc/debug/91507 in + block_lookup_symbol_primary. */ + if (best_symbol (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), + if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain)) - other = sym; + other = better_symbol (other, sym, domain); } return other; } @@ -708,7 +750,7 @@ block_lookup_symbol (const struct block *block, const char *name, ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym) { - if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain)) { sym_found = sym; @@ -743,16 +785,42 @@ block_lookup_symbol_primary (const struct block *block, const char *name, sym != NULL; sym = mdict_iter_match_next (lookup_name, &mdict_iter)) { - if (SYMBOL_DOMAIN (sym) == domain) + /* With the fix for PR gcc/debug/91507, we get for: + ... + extern char *zzz[]; + char *zzz[ ] = { + "abc", + "cde" + }; + ... + DWARF which will result in two entries in the symbol table, a decl + with type char *[] and a def with type char *[2]. + + If we return the decl here, we don't get the value of zzz: + ... + $ gdb a.spec.out -batch -ex "p zzz" + $1 = 0x601030 + ... + because we're returning the symbol without location information, and + because the fallback that uses the address from the minimal symbols + doesn't work either because the type of the decl does not specify a + size. + + To fix this, we prefer def over decl in best_symbol and + better_symbol. + + In absence of the gcc fix, both def and decl have type char *[], so + the only option to make this work is improve the fallback to use the + size of the minimal symbol. Filed as PR exp/24989. */ + if (best_symbol (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; + if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain)) + other = better_symbol (other, sym, domain); } return other; @@ -778,8 +846,7 @@ block_find_symbol (const struct block *block, const char *name, { /* 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) + if (symbol_matches_domain (sym->language (), SYMBOL_DOMAIN (sym), domain) && matcher (sym, data)) return sym; }