gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / block.c
index 5c6faa850457efecf76c13a3ed2bb8f2f8edc5d2..597d6d5d875a9b7a12af20d9e9780b42deef4ef3 100644 (file)
@@ -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.
 
@@ -62,28 +62,31 @@ 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 block_objfile (block)->arch ();
 }
 
-/* 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,42 @@ block_iter_match_next (const lookup_name_info &name,
   return block_iter_match_step (iterator, name, 0);
 }
 
+/* See block.h.  */
+
+bool
+best_symbol (struct symbol *a, const domain_enum domain)
+{
+  return (SYMBOL_DOMAIN (a) == domain
+         && SYMBOL_CLASS (a) != LOC_UNRESOLVED);
+}
+
+/* See block.h.  */
+
+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 +720,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 +749,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 +784,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 <zzz>
+        ...
+        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 +845,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;
     }
This page took 0.031638 seconds and 4 git commands to generate.