gdb: safety checks in skip_prologue_using_sal
[binutils-gdb.git] / gdb / symtab.c
index 0367705576c8178d11b9510077683609f934ccc7..5e1b9d91879c02d28270c555ea71096f51b943a1 100644 (file)
@@ -1,6 +1,6 @@
 /* Symbol table lookup for the GNU debugger, GDB.
 
-   Copyright (C) 1986-2022 Free Software Foundation, Inc.
+   Copyright (C) 1986-2023 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -18,6 +18,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
+#include "dwarf2/call-site.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "gdbcore.h"
@@ -77,7 +78,7 @@
 
 static void rbreak_command (const char *, int);
 
-static int find_line_common (struct linetable *, int, int *, int);
+static int find_line_common (const linetable *, int, int *, int);
 
 static struct block_symbol
   lookup_symbol_aux (const char *name,
@@ -103,16 +104,9 @@ static struct block_symbol
 
 struct main_info
 {
-  main_info () = default;
-
-  ~main_info ()
-  {
-    xfree (name_of_main);
-  }
-
   /* Name of "main".  */
 
-  char *name_of_main = nullptr;
+  std::string name_of_main;
 
   /* Language of "main".  */
 
@@ -121,7 +115,7 @@ struct main_info
 
 /* Program space key for finding name and language of "main".  */
 
-static const program_space_key<main_info> main_progspace_key;
+static const registry<program_space>::key<main_info> main_progspace_key;
 
 /* The default symbol cache size.
    There is no extra cpu cost for large N (except when flushing the cache,
@@ -251,7 +245,7 @@ struct symbol_cache
 
 /* Program space key for finding its symbol cache.  */
 
-static const program_space_key<symbol_cache> symbol_cache_key;
+static const registry<program_space>::key<symbol_cache> symbol_cache_key;
 
 /* When non-zero, print debugging messages related to symtab creation.  */
 unsigned int symtab_create_debug = 0;
@@ -335,19 +329,39 @@ search_domain_name (enum search_domain e)
 
 /* See symtab.h.  */
 
+CORE_ADDR
+linetable_entry::pc (const struct objfile *objfile) const
+{
+  return CORE_ADDR (m_pc) + objfile->text_section_offset ();
+}
+
+/* See symtab.h.  */
+
 call_site *
 compunit_symtab::find_call_site (CORE_ADDR pc) const
 {
   if (m_call_site_htab == nullptr)
     return nullptr;
 
-  CORE_ADDR delta
-    = this->objfile ()->section_offsets[this->block_line_section ()];
+  CORE_ADDR delta = this->objfile ()->text_section_offset ();
   CORE_ADDR unrelocated_pc = pc - delta;
 
   struct call_site call_site_local (unrelocated_pc, nullptr, nullptr);
   void **slot
     = htab_find_slot (m_call_site_htab, &call_site_local, NO_INSERT);
+  if (slot != nullptr)
+    return (call_site *) *slot;
+
+  /* See if the arch knows another PC we should try.  On some
+     platforms, GCC emits a DWARF call site that is offset from the
+     actual return location.  */
+  struct gdbarch *arch = objfile ()->arch ();
+  CORE_ADDR new_pc = gdbarch_update_call_site_pc (arch, pc);
+  if (pc == new_pc)
+    return nullptr;
+
+  call_site new_call_site_local (new_pc - delta, nullptr, nullptr);
+  slot = htab_find_slot (m_call_site_htab, &new_call_site_local, NO_INSERT);
   if (slot == nullptr)
     return nullptr;
 
@@ -405,12 +419,12 @@ compunit_symtab::primary_filetab () const
 /* See symtab.h.  */
 
 enum language
-compunit_language (const struct compunit_symtab *cust)
+compunit_symtab::language () const
 {
-  struct symtab *symtab = cust->primary_filetab ();
+  struct symtab *symtab = primary_filetab ();
 
-/* The language of the compunit symtab is the language of its primary
-   source file.  */
+  /* The language of the compunit symtab is the language of its
+     primary source file.  */
   return symtab->language ();
 }
 
@@ -423,7 +437,7 @@ minimal_symbol::value_address (objfile *objfile) const
   if (this->maybe_copied)
     return get_msymbol_address (objfile, this);
   else
-    return (this->value_raw_address ()
+    return (CORE_ADDR (this->unrelocated_address ())
            + objfile->section_offsets[this->section_index ()]);
 }
 
@@ -812,7 +826,7 @@ hash_demangled_name_entry (const void *data)
   const struct demangled_name_entry *e
     = (const struct demangled_name_entry *) data;
 
-  return fast_hash (e->mangled.data (), e->mangled.length ());
+  return gdb::string_view_hash () (e->mangled);
 }
 
 /* Equality function for the demangled name hash.  */
@@ -873,10 +887,7 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
   gdb::unique_xmalloc_ptr<char> demangled;
   int i;
 
-  if (gsymbol->language () == language_unknown)
-    gsymbol->m_language = language_auto;
-
-  if (gsymbol->language () != language_auto)
+  if (gsymbol->language () != language_unknown)
     {
       const struct language_defn *lang = language_def (gsymbol->language ());
 
@@ -1014,7 +1025,7 @@ general_symbol_info::compute_and_set_names (gdb::string_view linkage_name,
       (*slot)->demangled = std::move (demangled_name);
       (*slot)->language = language ();
     }
-  else if (language () == language_unknown || language () == language_auto)
+  else if (language () == language_unknown)
     m_language = (*slot)->language;
 
   m_name = (*slot)->mangled.data ();
@@ -1088,7 +1099,7 @@ struct obj_section *
 general_symbol_info::obj_section (const struct objfile *objfile) const
 {
   if (section_index () >= 0)
-    return &objfile->sections[section_index ()];
+    return &objfile->sections_start[section_index ()];
   return nullptr;
 }
 
@@ -1169,29 +1180,6 @@ matching_obj_sections (struct obj_section *obj_first,
 
   return false;
 }
-
-/* See symtab.h.  */
-
-void
-expand_symtab_containing_pc (CORE_ADDR pc, struct obj_section *section)
-{
-  struct bound_minimal_symbol msymbol;
-
-  /* If we know that this is not a text address, return failure.  This is
-     necessary because we loop based on texthigh and textlow, which do
-     not include the data ranges.  */
-  msymbol = lookup_minimal_symbol_by_pc_section (pc, section);
-  if (msymbol.minsym && msymbol.minsym->data_p ())
-    return;
-
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      struct compunit_symtab *cust
-       = objfile->find_pc_sect_compunit_symtab (msymbol, pc, section, 0);
-      if (cust)
-       return;
-    }
-}
 \f
 /* Hash function for the symbol cache.  */
 
@@ -1424,13 +1412,11 @@ symbol_cache_lookup (struct symbol_cache *cache,
 
   if (eq_symbol_entry (slot, objfile_context, name, domain))
     {
-      if (symbol_lookup_debug)
-       gdb_printf (gdb_stdlog,
-                   "%s block symbol cache hit%s for %s, %s\n",
-                   block == GLOBAL_BLOCK ? "Global" : "Static",
-                   slot->state == SYMBOL_SLOT_NOT_FOUND
-                   ? " (not found)" : "",
-                   name, domain_name (domain));
+      symbol_lookup_debug_printf ("%s block symbol cache hit%s for %s, %s",
+                                 block == GLOBAL_BLOCK ? "Global" : "Static",
+                                 slot->state == SYMBOL_SLOT_NOT_FOUND
+                                 ? " (not found)" : "", name,
+                                 domain_name (domain));
       ++bsc->hits;
       if (slot->state == SYMBOL_SLOT_NOT_FOUND)
        return SYMBOL_LOOKUP_FAILED;
@@ -1439,13 +1425,9 @@ symbol_cache_lookup (struct symbol_cache *cache,
 
   /* Symbol is not present in the cache.  */
 
-  if (symbol_lookup_debug)
-    {
-      gdb_printf (gdb_stdlog,
-                 "%s block symbol cache miss for %s, %s\n",
-                 block == GLOBAL_BLOCK ? "Global" : "Static",
-                 name, domain_name (domain));
-    }
+  symbol_lookup_debug_printf ("%s block symbol cache miss for %s, %s",
+                             block == GLOBAL_BLOCK ? "Global" : "Static",
+                             name, domain_name (domain));
   ++bsc->misses;
   return {};
 }
@@ -1707,13 +1689,39 @@ symtab_free_objfile_observer (struct objfile *objfile)
   symbol_cache_flush (objfile->pspace);
 }
 \f
-/* Debug symbols usually don't have section information.  We need to dig that
-   out of the minimal symbols and stash that in the debug symbol.  */
+/* See symtab.h.  */
 
 void
-fixup_section (struct general_symbol_info *ginfo,
-              CORE_ADDR addr, struct objfile *objfile)
+fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
 {
+  gdb_assert (sym != nullptr);
+  gdb_assert (sym->is_objfile_owned ());
+  gdb_assert (objfile != nullptr);
+  gdb_assert (sym->section_index () == -1);
+
+  /* Note that if this ends up as -1, fixup_section will handle that
+     reasonably well.  So, it's fine to use the objfile's section
+     index without doing the check that is done by the wrapper macros
+     like SECT_OFF_TEXT.  */
+  int fallback;
+  switch (sym->aclass ())
+    {
+    case LOC_STATIC:
+      fallback = objfile->sect_index_data;
+      break;
+
+    case LOC_LABEL:
+      fallback = objfile->sect_index_text;
+      break;
+
+    default:
+      /* Nothing else will be listed in the minsyms -- no use looking
+        it up.  */
+      return;
+    }
+
+  CORE_ADDR addr = sym->value_address ();
+
   struct minimal_symbol *msym;
 
   /* First, check whether a minimal symbol with the same name exists
@@ -1721,10 +1729,10 @@ fixup_section (struct general_symbol_info *ginfo,
      e.g. on PowerPC64, where the minimal symbol for a function will
      point to the function descriptor, while the debug symbol will
      point to the actual function code.  */
-  msym = lookup_minimal_symbol_by_pc_name (addr, ginfo->linkage_name (),
+  msym = lookup_minimal_symbol_by_pc_name (addr, sym->linkage_name (),
                                           objfile);
   if (msym)
-    ginfo->set_section_index (msym->section_index ());
+    sym->set_section_index (msym->section_index ());
   else
     {
       /* Static, function-local variables do appear in the linker
@@ -1762,12 +1770,12 @@ fixup_section (struct general_symbol_info *ginfo,
         this reason, we still attempt a lookup by name prior to doing
         a search of the section table.  */
 
-      struct obj_section *s;
-      int fallback = -1;
-
-      ALL_OBJFILE_OSECTIONS (objfile, s)
+      for (obj_section *s : objfile->sections ())
        {
-         int idx = s - objfile->sections;
+         if ((bfd_section_flags (s->the_bfd_section) & SEC_ALLOC) == 0)
+           continue;
+
+         int idx = s - objfile->sections_start;
          CORE_ADDR offset = objfile->section_offsets[idx];
 
          if (fallback == -1)
@@ -1775,7 +1783,7 @@ fixup_section (struct general_symbol_info *ginfo,
 
          if (s->addr () - offset <= addr && addr < s->endaddr () - offset)
            {
-             ginfo->set_section_index (idx);
+             sym->set_section_index (idx);
              return;
            }
        }
@@ -1784,55 +1792,10 @@ fixup_section (struct general_symbol_info *ginfo,
         section.  If there is no allocated section, then it hardly
         matters what we pick, so just pick zero.  */
       if (fallback == -1)
-       ginfo->set_section_index (0);
+       sym->set_section_index (0);
       else
-       ginfo->set_section_index (fallback);
-    }
-}
-
-struct symbol *
-fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
-{
-  CORE_ADDR addr;
-
-  if (!sym)
-    return NULL;
-
-  if (!sym->is_objfile_owned ())
-    return sym;
-
-  /* We either have an OBJFILE, or we can get at it from the sym's
-     symtab.  Anything else is a bug.  */
-  gdb_assert (objfile || sym->symtab ());
-
-  if (objfile == NULL)
-    objfile = sym->objfile ();
-
-  if (sym->obj_section (objfile) != nullptr)
-    return sym;
-
-  /* We should have an objfile by now.  */
-  gdb_assert (objfile);
-
-  switch (sym->aclass ())
-    {
-    case LOC_STATIC:
-    case LOC_LABEL:
-      addr = sym->value_address ();
-      break;
-    case LOC_BLOCK:
-      addr = sym->value_block ()->entry_pc ();
-      break;
-
-    default:
-      /* Nothing else will be listed in the minsyms -- no use looking
-        it up.  */
-      return sym;
+       sym->set_section_index (fallback);
     }
-
-  fixup_section (sym, addr, objfile);
-
-  return sym;
 }
 
 /* See symtab.h.  */
@@ -1956,6 +1919,8 @@ lookup_symbol_in_language (const char *name, const struct block *block,
                           const domain_enum domain, enum language lang,
                           struct field_of_this_result *is_a_field_of_this)
 {
+  SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT;
+
   demangle_result_storage storage;
   const char *modified_name = demangle_for_lookup (name, lang, storage);
 
@@ -1996,15 +1961,9 @@ lookup_language_this (const struct language_defn *lang,
   if (lang->name_of_this () == NULL || block == NULL)
     return {};
 
-  if (symbol_lookup_debug > 1)
-    {
-      struct objfile *objfile = block_objfile (block);
-
-      gdb_printf (gdb_stdlog,
-                 "lookup_language_this (%s, %s (objfile %s))",
-                 lang->name (), host_address_to_string (block),
-                 objfile_debug_name (objfile));
-    }
+  symbol_lookup_debug_printf_v ("lookup_language_this (%s, %s (objfile %s))",
+                               lang->name (), host_address_to_string (block),
+                               objfile_debug_name (block->objfile ()));
 
   while (block)
     {
@@ -2015,13 +1974,10 @@ lookup_language_this (const struct language_defn *lang,
                                 VAR_DOMAIN);
       if (sym != NULL)
        {
-         if (symbol_lookup_debug > 1)
-           {
-             gdb_printf (gdb_stdlog, " = %s (%s, block %s)\n",
-                         sym->print_name (),
-                         host_address_to_string (sym),
-                         host_address_to_string (block));
-           }
+         symbol_lookup_debug_printf_v
+           ("lookup_language_this (...) = %s (%s, block %s)",
+            sym->print_name (), host_address_to_string (sym),
+            host_address_to_string (block));
          return (struct block_symbol) {sym, block};
        }
       if (block->function ())
@@ -2029,8 +1985,7 @@ lookup_language_this (const struct language_defn *lang,
       block = block->superblock ();
     }
 
-  if (symbol_lookup_debug > 1)
-    gdb_printf (gdb_stdlog, " = NULL\n");
+  symbol_lookup_debug_printf_v ("lookup_language_this (...) = NULL");
   return {};
 }
 
@@ -2088,20 +2043,23 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
                   const domain_enum domain, enum language language,
                   struct field_of_this_result *is_a_field_of_this)
 {
+  SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT;
+
   struct block_symbol result;
   const struct language_defn *langdef;
 
   if (symbol_lookup_debug)
     {
       struct objfile *objfile = (block == nullptr
-                                ? nullptr : block_objfile (block));
+                                ? nullptr : block->objfile ());
 
-      gdb_printf (gdb_stdlog,
-                 "lookup_symbol_aux (%s, %s (objfile %s), %s, %s)\n",
-                 name, host_address_to_string (block),
-                 objfile != NULL
-                 ? objfile_debug_name (objfile) : "NULL",
-                 domain_name (domain), language_str (language));
+      symbol_lookup_debug_printf
+       ("demangled symbol name = \"%s\", block @ %s (objfile %s)",
+        name, host_address_to_string (block),
+        objfile != NULL ? objfile_debug_name (objfile) : "NULL");
+      symbol_lookup_debug_printf
+       ("domain name = \"%s\", language = \"%s\")",
+        domain_name (domain), language_str (language));
     }
 
   /* Make sure we do something sensible with is_a_field_of_this, since
@@ -2117,11 +2075,9 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
   result = lookup_local_symbol (name, match_type, block, domain, language);
   if (result.symbol != NULL)
     {
-      if (symbol_lookup_debug)
-       {
-         gdb_printf (gdb_stdlog, "lookup_symbol_aux (...) = %s\n",
-                     host_address_to_string (result.symbol));
-       }
+      symbol_lookup_debug_printf
+       ("found symbol @ %s (using lookup_local_symbol)",
+        host_address_to_string (result.symbol));
       return result;
     }
 
@@ -2145,7 +2101,7 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
             be typedefed; just be safe.  */
          t = check_typedef (t);
          if (t->is_pointer_or_reference ())
-           t = TYPE_TARGET_TYPE (t);
+           t = t->target_type ();
 
          if (t->code () != TYPE_CODE_STRUCT
              && t->code () != TYPE_CODE_UNION)
@@ -2154,11 +2110,7 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
 
          if (check_field (t, name, is_a_field_of_this))
            {
-             if (symbol_lookup_debug)
-               {
-                 gdb_printf (gdb_stdlog,
-                             "lookup_symbol_aux (...) = NULL\n");
-               }
+             symbol_lookup_debug_printf ("no symbol found");
              return {};
            }
        }
@@ -2170,11 +2122,9 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
   result = langdef->lookup_symbol_nonlocal (name, block, domain);
   if (result.symbol != NULL)
     {
-      if (symbol_lookup_debug)
-       {
-         gdb_printf (gdb_stdlog, "lookup_symbol_aux (...) = %s\n",
-                     host_address_to_string (result.symbol));
-       }
+      symbol_lookup_debug_printf
+       ("found symbol @ %s (using language lookup_symbol_nonlocal)",
+        host_address_to_string (result.symbol));
       return result;
     }
 
@@ -2182,13 +2132,9 @@ lookup_symbol_aux (const char *name, symbol_name_match_type match_type,
      but more useful than an error.  */
 
   result = lookup_static_symbol (name, domain);
-  if (symbol_lookup_debug)
-    {
-      gdb_printf (gdb_stdlog, "lookup_symbol_aux (...) = %s\n",
-                 result.symbol != NULL
-                 ? host_address_to_string (result.symbol)
-                 : "NULL");
-    }
+  symbol_lookup_debug_printf
+    ("found symbol @ %s (using lookup_static_symbol)",
+     result.symbol != NULL ? host_address_to_string (result.symbol) : "NULL");
   return result;
 }
 
@@ -2202,13 +2148,15 @@ lookup_local_symbol (const char *name,
                     const domain_enum domain,
                     enum language language)
 {
+  if (block == nullptr)
+    return {};
+
   struct symbol *sym;
-  const struct block *static_block = block_static_block (block);
-  const char *scope = block_scope (block);
+  const struct block *static_block = block->static_block ();
+  const char *scope = block->scope ();
   
-  /* Check if either no block is specified or it's a global block.  */
-
-  if (static_block == NULL)
+  /* Check if it's a global block.  */
+  if (static_block == nullptr)
     return {};
 
   while (block != static_block)
@@ -2227,7 +2175,7 @@ lookup_local_symbol (const char *name,
            return blocksym;
        }
 
-      if (block->function () != NULL && block_inlined_p (block))
+      if (block->function () != NULL && block->inlined_p ())
        break;
       block = block->superblock ();
     }
@@ -2246,31 +2194,27 @@ lookup_symbol_in_block (const char *name, symbol_name_match_type match_type,
 {
   struct symbol *sym;
 
-  if (symbol_lookup_debug > 1)
+  if (symbol_lookup_debug)
     {
-      struct objfile *objfile = (block == nullptr
-                                ? nullptr : block_objfile (block));
+      struct objfile *objfile
+       = block == nullptr ? nullptr : block->objfile ();
 
-      gdb_printf (gdb_stdlog,
-                 "lookup_symbol_in_block (%s, %s (objfile %s), %s)",
-                 name, host_address_to_string (block),
-                 objfile_debug_name (objfile),
-                 domain_name (domain));
+      symbol_lookup_debug_printf_v
+       ("lookup_symbol_in_block (%s, %s (objfile %s), %s)",
+        name, host_address_to_string (block),
+        objfile != nullptr ? objfile_debug_name (objfile) : "NULL",
+        domain_name (domain));
     }
 
   sym = block_lookup_symbol (block, name, match_type, domain);
   if (sym)
     {
-      if (symbol_lookup_debug > 1)
-       {
-         gdb_printf (gdb_stdlog, " = %s\n",
-                     host_address_to_string (sym));
-       }
-      return fixup_symbol_section (sym, NULL);
+      symbol_lookup_debug_printf_v ("lookup_symbol_in_block (...) = %s",
+                                   host_address_to_string (sym));
+      return sym;
     }
 
-  if (symbol_lookup_debug > 1)
-    gdb_printf (gdb_stdlog, " = NULL\n");
+  symbol_lookup_debug_printf_v ("lookup_symbol_in_block (...) = NULL");
   return NULL;
 }
 
@@ -2308,15 +2252,11 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
 {
   gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);
 
-  if (symbol_lookup_debug > 1)
-    {
-      gdb_printf (gdb_stdlog,
-                 "lookup_symbol_in_objfile_symtabs (%s, %s, %s, %s)",
-                 objfile_debug_name (objfile),
-                 block_index == GLOBAL_BLOCK
-                 ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
-                 name, domain_name (domain));
-    }
+  symbol_lookup_debug_printf_v
+    ("lookup_symbol_in_objfile_symtabs (%s, %s, %s, %s)",
+     objfile_debug_name (objfile),
+     block_index == GLOBAL_BLOCK ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
+     name, domain_name (domain));
 
   struct block_symbol other;
   other.symbol = NULL;
@@ -2327,7 +2267,7 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
       struct block_symbol result;
 
       bv = cust->blockvector ();
-      block = BLOCKVECTOR_BLOCK (bv, block_index);
+      block = bv->block (block_index);
       result.symbol = block_lookup_symbol_primary (block, name, domain);
       result.block = block;
       if (result.symbol == NULL)
@@ -2352,18 +2292,15 @@ lookup_symbol_in_objfile_symtabs (struct objfile *objfile,
 
   if (other.symbol != NULL)
     {
-      if (symbol_lookup_debug > 1)
-       {
-         gdb_printf (gdb_stdlog, " = %s (block %s)\n",
-                     host_address_to_string (other.symbol),
-                     host_address_to_string (other.block));
-       }
-      other.symbol = fixup_symbol_section (other.symbol, objfile);
+      symbol_lookup_debug_printf_v
+       ("lookup_symbol_in_objfile_symtabs (...) = %s (block %s)",
+        host_address_to_string (other.symbol),
+        host_address_to_string (other.block));
       return other;
     }
 
-  if (symbol_lookup_debug > 1)
-    gdb_printf (gdb_stdlog, " = NULL\n");
+  symbol_lookup_debug_printf_v
+    ("lookup_symbol_in_objfile_symtabs (...) = NULL");
   return {};
 }
 
@@ -2438,43 +2375,32 @@ lookup_symbol_via_quick_fns (struct objfile *objfile,
   const struct block *block;
   struct block_symbol result;
 
-  if (symbol_lookup_debug > 1)
-    {
-      gdb_printf (gdb_stdlog,
-                 "lookup_symbol_via_quick_fns (%s, %s, %s, %s)\n",
-                 objfile_debug_name (objfile),
-                 block_index == GLOBAL_BLOCK
-                 ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
-                 name, domain_name (domain));
-    }
+  symbol_lookup_debug_printf_v
+    ("lookup_symbol_via_quick_fns (%s, %s, %s, %s)",
+     objfile_debug_name (objfile),
+     block_index == GLOBAL_BLOCK ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
+     name, domain_name (domain));
 
   cust = objfile->lookup_symbol (block_index, name, domain);
   if (cust == NULL)
     {
-      if (symbol_lookup_debug > 1)
-       {
-         gdb_printf (gdb_stdlog,
-                     "lookup_symbol_via_quick_fns (...) = NULL\n");
-       }
+      symbol_lookup_debug_printf_v
+       ("lookup_symbol_via_quick_fns (...) = NULL");
       return {};
     }
 
   bv = cust->blockvector ();
-  block = BLOCKVECTOR_BLOCK (bv, block_index);
+  block = bv->block (block_index);
   result.symbol = block_lookup_symbol (block, name,
                                       symbol_name_match_type::FULL, domain);
   if (result.symbol == NULL)
     error_in_psymtab_expansion (block_index, name, cust);
 
-  if (symbol_lookup_debug > 1)
-    {
-      gdb_printf (gdb_stdlog,
-                 "lookup_symbol_via_quick_fns (...) = %s (block %s)\n",
-                 host_address_to_string (result.symbol),
-                 host_address_to_string (block));
-    }
+  symbol_lookup_debug_printf_v
+    ("lookup_symbol_via_quick_fns (...) = %s (block %s)",
+     host_address_to_string (result.symbol),
+     host_address_to_string (block));
 
-  result.symbol = fixup_symbol_section (result.symbol, objfile);
   result.block = block;
   return result;
 }
@@ -2509,7 +2435,7 @@ language_defn::lookup_symbol_nonlocal (const char *name,
       if (block == NULL)
        gdbarch = target_gdbarch ();
       else
-       gdbarch = block_gdbarch (block);
+       gdbarch = block->gdbarch ();
       result.symbol = language_lookup_primitive_type_as_symbol (this,
                                                                gdbarch, name);
       result.block = NULL;
@@ -2527,7 +2453,10 @@ lookup_symbol_in_static_block (const char *name,
                               const struct block *block,
                               const domain_enum domain)
 {
-  const struct block *static_block = block_static_block (block);
+  if (block == nullptr)
+    return {};
+
+  const struct block *static_block = block->static_block ();
   struct symbol *sym;
 
   if (static_block == NULL)
@@ -2536,26 +2465,21 @@ lookup_symbol_in_static_block (const char *name,
   if (symbol_lookup_debug)
     {
       struct objfile *objfile = (block == nullptr
-                                ? nullptr : block_objfile (block));
+                                ? nullptr : block->objfile ());
 
-      gdb_printf (gdb_stdlog,
-                 "lookup_symbol_in_static_block (%s, %s (objfile %s),"
-                 " %s)\n",
-                 name,
-                 host_address_to_string (block),
-                 objfile_debug_name (objfile),
-                 domain_name (domain));
+      symbol_lookup_debug_printf
+       ("lookup_symbol_in_static_block (%s, %s (objfile %s), %s)",
+        name, host_address_to_string (block),
+        objfile != nullptr ? objfile_debug_name (objfile) : "NULL",
+        domain_name (domain));
     }
 
   sym = lookup_symbol_in_block (name,
                                symbol_name_match_type::FULL,
                                static_block, domain);
-  if (symbol_lookup_debug)
-    {
-      gdb_printf (gdb_stdlog,
-                 "lookup_symbol_in_static_block (...) = %s\n",
-                 sym != NULL ? host_address_to_string (sym) : "NULL");
-    }
+  symbol_lookup_debug_printf ("lookup_symbol_in_static_block (...) = %s",
+                             sym != NULL
+                             ? host_address_to_string (sym) : "NULL");
   return (struct block_symbol) {sym, static_block};
 }
 
@@ -2572,102 +2496,33 @@ lookup_symbol_in_objfile (struct objfile *objfile, enum block_enum block_index,
 
   gdb_assert (block_index == GLOBAL_BLOCK || block_index == STATIC_BLOCK);
 
-  if (symbol_lookup_debug)
-    {
-      gdb_printf (gdb_stdlog,
-                 "lookup_symbol_in_objfile (%s, %s, %s, %s)\n",
-                 objfile_debug_name (objfile),
-                 block_index == GLOBAL_BLOCK
-                 ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
-                 name, domain_name (domain));
-    }
+  symbol_lookup_debug_printf ("lookup_symbol_in_objfile (%s, %s, %s, %s)",
+                             objfile_debug_name (objfile),
+                             block_index == GLOBAL_BLOCK
+                             ? "GLOBAL_BLOCK" : "STATIC_BLOCK",
+                             name, domain_name (domain));
 
   result = lookup_symbol_in_objfile_symtabs (objfile, block_index,
                                             name, domain);
   if (result.symbol != NULL)
     {
-      if (symbol_lookup_debug)
-       {
-         gdb_printf (gdb_stdlog,
-                     "lookup_symbol_in_objfile (...) = %s"
-                     " (in symtabs)\n",
-                     host_address_to_string (result.symbol));
-       }
+      symbol_lookup_debug_printf
+       ("lookup_symbol_in_objfile (...) = %s (in symtabs)",
+        host_address_to_string (result.symbol));
       return result;
     }
 
   result = lookup_symbol_via_quick_fns (objfile, block_index,
                                        name, domain);
-  if (symbol_lookup_debug)
-    {
-      gdb_printf (gdb_stdlog,
-                 "lookup_symbol_in_objfile (...) = %s%s\n",
-                 result.symbol != NULL
-                 ? host_address_to_string (result.symbol)
-                 : "NULL",
-                 result.symbol != NULL ? " (via quick fns)" : "");
-    }
+  symbol_lookup_debug_printf ("lookup_symbol_in_objfile (...) = %s%s",
+                             result.symbol != NULL
+                             ? host_address_to_string (result.symbol)
+                             : "NULL",
+                             result.symbol != NULL ? " (via quick fns)"
+                             : "");
   return result;
 }
 
-/* Find the language for partial symbol with NAME.  */
-
-static enum language
-find_quick_global_symbol_language (const char *name, const domain_enum domain)
-{
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      bool symbol_found_p;
-      enum language lang
-       = objfile->lookup_global_symbol_language (name, domain, &symbol_found_p);
-      if (symbol_found_p)
-       return lang;
-    }
-
-  return language_unknown;
-}
-
-/* Private data to be used with lookup_symbol_global_iterator_cb.  */
-
-struct global_or_static_sym_lookup_data
-{
-  /* The name of the symbol we are searching for.  */
-  const char *name;
-
-  /* The domain to use for our search.  */
-  domain_enum domain;
-
-  /* The block index in which to search.  */
-  enum block_enum block_index;
-
-  /* The field where the callback should store the symbol if found.
-     It should be initialized to {NULL, NULL} before the search is started.  */
-  struct block_symbol result;
-};
-
-/* A callback function for gdbarch_iterate_over_objfiles_in_search_order.
-   It searches by name for a symbol in the block given by BLOCK_INDEX of the
-   given OBJFILE.  The arguments for the search are passed via CB_DATA, which
-   in reality is a pointer to struct global_or_static_sym_lookup_data.  */
-
-static int
-lookup_symbol_global_or_static_iterator_cb (struct objfile *objfile,
-                                           void *cb_data)
-{
-  struct global_or_static_sym_lookup_data *data =
-    (struct global_or_static_sym_lookup_data *) cb_data;
-
-  gdb_assert (data->result.symbol == NULL
-             && data->result.block == NULL);
-
-  data->result = lookup_symbol_in_objfile (objfile, data->block_index,
-                                          data->name, data->domain);
-
-  /* If we found a match, tell the iterator to stop.  Otherwise,
-     keep going.  */
-  return (data->result.symbol != NULL);
-}
-
 /* This function contains the common code of lookup_{global,static}_symbol.
    OBJFILE is only used if BLOCK_INDEX is GLOBAL_SCOPE, in which case it is
    the objfile to start the lookup in.  */
@@ -2680,7 +2535,6 @@ lookup_global_or_static_symbol (const char *name,
 {
   struct symbol_cache *cache = get_symbol_cache (current_program_space);
   struct block_symbol result;
-  struct global_or_static_sym_lookup_data lookup_data;
   struct block_symbol_cache *bsc;
   struct symbol_cache_slot *slot;
 
@@ -2700,16 +2554,15 @@ lookup_global_or_static_symbol (const char *name,
 
   /* Do a global search (of global blocks, heh).  */
   if (result.symbol == NULL)
-    {
-      memset (&lookup_data, 0, sizeof (lookup_data));
-      lookup_data.name = name;
-      lookup_data.block_index = block_index;
-      lookup_data.domain = domain;
-      gdbarch_iterate_over_objfiles_in_search_order
-       (objfile != NULL ? objfile->arch () : target_gdbarch (),
-        lookup_symbol_global_or_static_iterator_cb, &lookup_data, objfile);
-      result = lookup_data.result;
-    }
+    gdbarch_iterate_over_objfiles_in_search_order
+      (objfile != NULL ? objfile->arch () : target_gdbarch (),
+       [&result, block_index, name, domain] (struct objfile *objfile_iter)
+        {
+          result = lookup_symbol_in_objfile (objfile_iter, block_index,
+                                             name, domain);
+          return result.symbol != nullptr;
+        },
+       objfile);
 
   if (result.symbol != NULL)
     symbol_cache_mark_found (bsc, slot, objfile, result.symbol, result.block);
@@ -2737,7 +2590,8 @@ lookup_global_symbol (const char *name,
   /* If a block was passed in, we want to search the corresponding
      global block first.  This yields "more expected" behavior, and is
      needed to support 'FILENAME'::VARIABLE lookups.  */
-  const struct block *global_block = block_global_block (block);
+  const struct block *global_block
+    = block == nullptr ? nullptr : block->global_block ();
   symbol *sym = NULL;
   if (global_block != nullptr)
     {
@@ -2751,7 +2605,7 @@ lookup_global_symbol (const char *name,
   struct objfile *objfile = nullptr;
   if (block != nullptr)
     {
-      objfile = block_objfile (block);
+      objfile = block->objfile ();
       if (objfile->separate_debug_objfile_backlink != nullptr)
        objfile = objfile->separate_debug_objfile_backlink;
     }
@@ -2810,7 +2664,7 @@ basic_lookup_transparent_type_quick (struct objfile *objfile,
     return NULL;
 
   bv = cust->blockvector ();
-  block = BLOCKVECTOR_BLOCK (bv, block_index);
+  block = bv->block (block_index);
   sym = block_find_symbol (block, name, STRUCT_DOMAIN,
                           block_find_non_opaque_type, NULL);
   if (sym == NULL)
@@ -2835,7 +2689,7 @@ basic_lookup_transparent_type_1 (struct objfile *objfile,
   for (compunit_symtab *cust : objfile->compunits ())
     {
       bv = cust->blockvector ();
-      block = BLOCKVECTOR_BLOCK (bv, block_index);
+      block = bv->block (block_index);
       sym = block_find_symbol (block, name, STRUCT_DOMAIN,
                               block_find_non_opaque_type, NULL);
       if (sym != NULL)
@@ -2910,10 +2764,7 @@ iterate_over_symbols (const struct block *block,
                      const domain_enum domain,
                      gdb::function_view<symbol_found_callback_ftype> callback)
 {
-  struct block_iterator iter;
-  struct symbol *sym;
-
-  ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
+  for (struct symbol *sym : block_iterator_range (block, &name))
     {
       if (symbol_matches_domain (sym->language (), sym->domain (), domain))
        {
@@ -2980,17 +2831,16 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
       for (compunit_symtab *cust : obj_file->compunits ())
        {
          const struct blockvector *bv = cust->blockvector ();
-         const struct block *global_block
-           = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+         const struct block *global_block = bv->global_block ();
          CORE_ADDR start = global_block->start ();
          CORE_ADDR end = global_block->end ();
          bool in_range_p = start <= pc && pc < end;
          if (!in_range_p)
            continue;
 
-         if (BLOCKVECTOR_MAP (bv))
+         if (bv->map () != nullptr)
            {
-             if (addrmap_find (BLOCKVECTOR_MAP (bv), pc) == nullptr)
+             if (bv->map ()->find (pc) == nullptr)
                continue;
 
              return cust;
@@ -3008,38 +2858,32 @@ find_pc_sect_compunit_symtab (CORE_ADDR pc, struct obj_section *section)
          /* In order to better support objfiles that contain both
             stabs and coff debugging info, we continue on if a psymtab
             can't be found.  */
-         if ((obj_file->flags & OBJF_REORDERED) != 0)
-           {
-             struct compunit_symtab *result;
-
-             result
-               = obj_file->find_pc_sect_compunit_symtab (msymbol,
-                                                         pc,
-                                                         section,
-                                                         0);
-             if (result != NULL)
-               return result;
-           }
+         struct compunit_symtab *result
+           = obj_file->find_pc_sect_compunit_symtab (msymbol, pc,
+                                                     section, 0);
+         if (result != nullptr)
+           return result;
 
          if (section != 0)
            {
-             struct symbol *sym = NULL;
-             struct block_iterator iter;
+             struct symbol *found_sym = nullptr;
 
              for (int b_index = GLOBAL_BLOCK;
-                  b_index <= STATIC_BLOCK && sym == NULL;
+                  b_index <= STATIC_BLOCK && found_sym == nullptr;
                   ++b_index)
                {
-                 const struct block *b = BLOCKVECTOR_BLOCK (bv, b_index);
-                 ALL_BLOCK_SYMBOLS (b, iter, sym)
+                 const struct block *b = bv->block (b_index);
+                 for (struct symbol *sym : block_iterator_range (b))
                    {
-                     fixup_symbol_section (sym, obj_file);
                      if (matching_obj_sections (sym->obj_section (obj_file),
                                                 section))
-                       break;
+                       {
+                         found_sym = sym;
+                         break;
+                       }
                    }
                }
-             if (sym == NULL)
+             if (found_sym == nullptr)
                continue;               /* No symbol in this symtab matches
                                           section.  */
            }
@@ -3089,11 +2933,9 @@ find_symbol_at_address (CORE_ADDR address)
 
       for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
        {
-         const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
-         struct block_iterator iter;
-         struct symbol *sym;
+         const struct block *b = bv->block (i);
 
-         ALL_BLOCK_SYMBOLS (b, iter, sym)
+         for (struct symbol *sym : block_iterator_range (b))
            {
              if (sym->aclass () == LOC_STATIC
                  && sym->value_address () == addr)
@@ -3153,15 +2995,15 @@ struct symtab_and_line
 find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
 {
   struct compunit_symtab *cust;
-  struct linetable *l;
+  const linetable *l;
   int len;
-  struct linetable_entry *item;
+  const linetable_entry *item;
   const struct blockvector *bv;
   struct bound_minimal_symbol msymbol;
 
   /* Info on best line seen so far, and where it starts, and its file.  */
 
-  struct linetable_entry *best = NULL;
+  const linetable_entry *best = NULL;
   CORE_ADDR best_end = 0;
   struct symtab *best_symtab = 0;
 
@@ -3170,11 +3012,11 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
      If we don't find a line whose range contains PC,
      we will use a line one less than this,
      with a range from the start of that file to the first line's pc.  */
-  struct linetable_entry *alt = NULL;
+  const linetable_entry *alt = NULL;
 
   /* Info on best line seen in this file.  */
 
-  struct linetable_entry *prev;
+  const linetable_entry *prev;
 
   /* If this pc is not from the current frame,
      it is the address of the end of a call instruction.
@@ -3272,8 +3114,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
               should occur, we'd like to know about it, so error out,
               fatally.  */
            if (mfunsym.value_address () == pc)
-             internal_error (__FILE__, __LINE__,
-               _("Infinite recursion detected in find_pc_sect_line;"
+             internal_error (_("Infinite recursion detected in find_pc_sect_line;"
                  "please file a bug report"));
 
            return find_pc_line (mfunsym.value_address (), 0);
@@ -3294,6 +3135,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
     }
 
   bv = cust->blockvector ();
+  struct objfile *objfile = cust->objfile ();
 
   /* Look at all the symtabs that share this blockvector.
      They all have the same apriori range, that we found was right;
@@ -3320,18 +3162,22 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
 
       /* Is this file's first line closer than the first lines of other files?
         If so, record this file, and its first line, as best alternate.  */
-      if (item->pc > pc && (!alt || item->pc < alt->pc))
+      if (item->pc (objfile) > pc
+         && (!alt || item->raw_pc () < alt->raw_pc ()))
        alt = item;
 
-      auto pc_compare = [](const CORE_ADDR & comp_pc,
-                          const struct linetable_entry & lhs)->bool
+      auto pc_compare = [] (const unrelocated_addr &comp_pc,
+                           const struct linetable_entry & lhs)
       {
-       return comp_pc < lhs.pc;
+       return comp_pc < lhs.raw_pc ();
       };
 
-      struct linetable_entry *first = item;
-      struct linetable_entry *last = item + len;
-      item = std::upper_bound (first, last, pc, pc_compare);
+      const linetable_entry *first = item;
+      const linetable_entry *last = item + len;
+      item = (std::upper_bound
+             (first, last,
+              unrelocated_addr (pc - objfile->text_section_offset ()),
+              pc_compare));
       if (item != first)
        prev = item - 1;                /* Found a matching item.  */
 
@@ -3345,7 +3191,7 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
         save prev if it represents the end of a function (i.e. line number
         0) instead of a real line.  */
 
-      if (prev && prev->line && (!best || prev->pc > best->pc))
+      if (prev && prev->line && (!best || prev->raw_pc () > best->raw_pc ()))
        {
          best = prev;
          best_symtab = iter_s;
@@ -3359,8 +3205,8 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
             pretty cheap.  */
          if (!best->is_stmt)
            {
-             struct linetable_entry *tmp = best;
-             while (tmp > first && (tmp - 1)->pc == tmp->pc
+             const linetable_entry *tmp = best;
+             while (tmp > first && (tmp - 1)->raw_pc () == tmp->raw_pc ()
                     && (tmp - 1)->line != 0 && !tmp->is_stmt)
                --tmp;
              if (tmp->is_stmt)
@@ -3368,16 +3214,16 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
            }
 
          /* Discard BEST_END if it's before the PC of the current BEST.  */
-         if (best_end <= best->pc)
+         if (best_end <= best->pc (objfile))
            best_end = 0;
        }
 
       /* If another line (denoted by ITEM) is in the linetable and its
         PC is after BEST's PC, but before the current BEST_END, then
         use ITEM's PC as the new best_end.  */
-      if (best && item < last && item->pc > best->pc
-         && (best_end == 0 || best_end > item->pc))
-       best_end = item->pc;
+      if (best && item < last && item->raw_pc () > best->raw_pc ()
+         && (best_end == 0 || best_end > item->pc (objfile)))
+       best_end = item->pc (objfile);
     }
 
   if (!best_symtab)
@@ -3400,13 +3246,13 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
       val.is_stmt = best->is_stmt;
       val.symtab = best_symtab;
       val.line = best->line;
-      val.pc = best->pc;
-      if (best_end && (!alt || best_end < alt->pc))
+      val.pc = best->pc (objfile);
+      if (best_end && (!alt || best_end < alt->pc (objfile)))
        val.end = best_end;
       else if (alt)
-       val.end = alt->pc;
+       val.end = alt->pc (objfile);
       else
-       val.end = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)->end ();
+       val.end = bv->global_block ()->end ();
     }
   val.section = section;
   return val;
@@ -3467,7 +3313,7 @@ find_line_symtab (struct symtab *sym_tab, int line,
      so far seen.  */
 
   int best_index;
-  struct linetable *best_linetable;
+  const struct linetable *best_linetable;
   struct symtab *best_symtab;
 
   /* First try looking it up in the given symtab.  */
@@ -3502,7 +3348,7 @@ find_line_symtab (struct symtab *sym_tab, int line,
            {
              for (symtab *s : cu->filetabs ())
                {
-                 struct linetable *l;
+                 const struct linetable *l;
                  int ind;
 
                  if (FILENAME_CMP (sym_tab->filename, s->filename) != 0)
@@ -3551,10 +3397,11 @@ done:
 
 std::vector<CORE_ADDR>
 find_pcs_for_symtab_line (struct symtab *symtab, int line,
-                         struct linetable_entry **best_item)
+                         const linetable_entry **best_item)
 {
   int start = 0;
   std::vector<CORE_ADDR> result;
+  struct objfile *objfile = symtab->compunit ()->objfile ();
 
   /* First, collect all the PCs that are at this line.  */
   while (1)
@@ -3569,7 +3416,7 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
 
       if (!was_exact)
        {
-         struct linetable_entry *item = &symtab->linetable ()->item[idx];
+         const linetable_entry *item = &symtab->linetable ()->item[idx];
 
          if (*best_item == NULL
              || (item->line < (*best_item)->line && item->is_stmt))
@@ -3578,7 +3425,7 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
          break;
        }
 
-      result.push_back (symtab->linetable ()->item[idx].pc);
+      result.push_back (symtab->linetable ()->item[idx].pc (objfile));
       start = idx + 1;
     }
 
@@ -3593,7 +3440,7 @@ find_pcs_for_symtab_line (struct symtab *symtab, int line,
 bool
 find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc)
 {
-  struct linetable *l;
+  const struct linetable *l;
   int ind;
 
   *pc = 0;
@@ -3604,7 +3451,7 @@ find_line_pc (struct symtab *symtab, int line, CORE_ADDR *pc)
   if (symtab != NULL)
     {
       l = symtab->linetable ();
-      *pc = l->item[ind].pc;
+      *pc = l->item[ind].pc (symtab->compunit ()->objfile ());
       return true;
     }
   else
@@ -3658,7 +3505,7 @@ find_line_pc_range (struct symtab_and_line sal, CORE_ADDR *startptr,
    Set *EXACT_MATCH nonzero if the value returned is an exact match.  */
 
 static int
-find_line_common (struct linetable *l, int lineno,
+find_line_common (const linetable *l, int lineno,
                  int *exact_match, int start)
 {
   int i;
@@ -3681,7 +3528,7 @@ find_line_common (struct linetable *l, int lineno,
   len = l->nitems;
   for (i = start; i < len; i++)
     {
-      struct linetable_entry *item = &(l->item[i]);
+      const linetable_entry *item = &(l->item[i]);
 
       /* Ignore non-statements.  */
       if (!item->is_stmt)
@@ -3777,7 +3624,6 @@ find_function_start_sal (CORE_ADDR func_addr, obj_section *section,
 symtab_and_line
 find_function_start_sal (symbol *sym, bool funfirstline)
 {
-  fixup_symbol_section (sym, NULL);
   symtab_and_line sal
     = find_function_start_sal_1 (sym->value_block ()->entry_pc (),
                                 sym->obj_section (sym->objfile ()),
@@ -3796,7 +3642,7 @@ static CORE_ADDR
 skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
 {
   CORE_ADDR func_start, func_end;
-  struct linetable *l;
+  const struct linetable *l;
   int i;
 
   /* Give up if this symbol has no lineinfo table.  */
@@ -3809,19 +3655,22 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab)
   if (!find_pc_partial_function (func_addr, NULL, &func_start, &func_end))
     return func_addr;
 
+  struct objfile *objfile = symtab->compunit ()->objfile ();
+
   /* Linetable entries are ordered by PC values, see the commentary in
      symtab.h where `struct linetable' is defined.  Thus, the first
      entry whose PC is in the range [FUNC_START..FUNC_END[ is the
      address we are looking for.  */
   for (i = 0; i < l->nitems; i++)
     {
-      struct linetable_entry *item = &(l->item[i]);
+      const linetable_entry *item = &(l->item[i]);
+      CORE_ADDR item_pc = item->pc (objfile);
 
       /* Don't use line numbers of zero, they mark special entries in
         the table.  See the commentary on symtab.h before the
         definition of struct linetable.  */
-      if (item->line > 0 && func_start <= item->pc && item->pc < func_end)
-       return item->pc;
+      if (item->line > 0 && func_start <= item_pc && item_pc < func_end)
+       return item_pc;
     }
 
   return func_addr;
@@ -3846,20 +3695,28 @@ skip_prologue_using_linetable (CORE_ADDR func_addr)
   if (prologue_sal.symtab != nullptr
       && prologue_sal.symtab->language () != language_asm)
     {
-      struct linetable *linetable = prologue_sal.symtab->linetable ();
+      const linetable *linetable = prologue_sal.symtab->linetable ();
+
+      struct objfile *objfile = prologue_sal.symtab->compunit ()->objfile ();
+
+      unrelocated_addr unrel_start
+       = unrelocated_addr (start_pc - objfile->text_section_offset ());
+      unrelocated_addr unrel_end
+       = unrelocated_addr (end_pc - objfile->text_section_offset ());
 
       auto it = std::lower_bound
-       (linetable->item, linetable->item + linetable->nitems, start_pc,
-        [] (const linetable_entry &lte, CORE_ADDR pc) -> bool
+       (linetable->item, linetable->item + linetable->nitems, unrel_start,
+        [] (const linetable_entry &lte, unrelocated_addr pc)
         {
-          return lte.pc < pc;
+          return lte.raw_pc () < pc;
         });
 
       for (;
-          it < linetable->item + linetable->nitems && it->pc <= end_pc;
+          (it < linetable->item + linetable->nitems
+           && it->raw_pc () < unrel_end);
           it++)
        if (it->prologue_end)
-         return {it->pc};
+         return {it->pc (objfile)};
     }
 
   return {};
@@ -3905,8 +3762,6 @@ skip_prologue_sal (struct symtab_and_line *sal)
   sym = find_pc_sect_function (sal->pc, sal->section);
   if (sym != NULL)
     {
-      fixup_symbol_section (sym, NULL);
-
       objfile = sym->objfile ();
       pc = sym->value_block ()->entry_pc ();
       section = sym->obj_section (objfile);
@@ -3949,7 +3804,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
       pc = saved_pc;
 
       /* Check if the compiler explicitly indicated where a breakpoint should
-         be placed to skip the prologue.  */
+        be placed to skip the prologue.  */
       if (!ignore_prologue_end_flag && skip)
        {
          gdb::optional<CORE_ADDR> linetable_pc
@@ -4042,7 +3897,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
   function_block = NULL;
   while (b != NULL)
     {
-      if (b->function () != NULL && block_inlined_p (b))
+      if (b->function () != NULL && b->inlined_p ())
        function_block = b;
       else if (b->function () != NULL)
        break;
@@ -4095,18 +3950,22 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
         do this.  */
       if (prologue_sal.symtab->language () != language_asm)
        {
-         struct linetable *linetable = prologue_sal.symtab->linetable ();
+         struct objfile *objfile
+           = prologue_sal.symtab->compunit ()->objfile ();
+         const linetable *linetable = prologue_sal.symtab->linetable ();
+         gdb_assert (linetable->nitems > 0);
          int idx = 0;
 
          /* Skip any earlier lines, and any end-of-sequence marker
             from a previous function.  */
-         while (linetable->item[idx].pc != prologue_sal.pc
-                || linetable->item[idx].line == 0)
+         while (idx + 1 < linetable->nitems
+                && (linetable->item[idx].pc (objfile) != prologue_sal.pc
+                    || linetable->item[idx].line == 0))
            idx++;
 
-         if (idx+1 < linetable->nitems
+         if (idx + 1 < linetable->nitems
              && linetable->item[idx+1].line != 0
-             && linetable->item[idx+1].pc == start_pc)
+             && linetable->item[idx+1].pc (objfile) == start_pc)
            return start_pc;
        }
 
@@ -4138,7 +3997,7 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
          bl = block_for_pc (prologue_sal.end);
          while (bl)
            {
-             if (block_inlined_p (bl))
+             if (bl->inlined_p ())
                break;
              if (bl->function ())
                {
@@ -4331,7 +4190,7 @@ operator_chars (const char *p, const char **end)
 /* See class declaration.  */
 
 info_sources_filter::info_sources_filter (match_on match_type,
-                                          const char *regexp)
+                                         const char *regexp)
   : m_match_type (match_type),
     m_regexp (regexp)
 {
@@ -4360,23 +4219,23 @@ info_sources_filter::matches (const char *fullname) const
       std::string dirname;
 
       switch (m_match_type)
-        {
-        case match_on::DIRNAME:
-          dirname = ldirname (fullname);
-          to_match = dirname.c_str ();
-          break;
-        case match_on::BASENAME:
-          to_match = lbasename (fullname);
-          break;
-        case match_on::FULLNAME:
-          to_match = fullname;
-          break;
+       {
+       case match_on::DIRNAME:
+         dirname = ldirname (fullname);
+         to_match = dirname.c_str ();
+         break;
+       case match_on::BASENAME:
+         to_match = lbasename (fullname);
+         break;
+       case match_on::FULLNAME:
+         to_match = fullname;
+         break;
        default:
          gdb_assert_not_reached ("bad m_match_type");
-        }
+       }
 
       if (m_c_regexp->exec (to_match, 0, NULL, 0) != 0)
-        return false;
+       return false;
     }
 
   return true;
@@ -4713,12 +4572,8 @@ treg_matches_sym_type_name (const compiled_regex &treg,
   struct type *sym_type;
   std::string printed_sym_type_name;
 
-  if (symbol_lookup_debug > 1)
-    {
-      gdb_printf (gdb_stdlog,
-                 "treg_matches_sym_type_name\n     sym %s\n",
-                 sym->natural_name ());
-    }
+  symbol_lookup_debug_printf_v ("treg_matches_sym_type_name, sym %s",
+                               sym->natural_name ());
 
   sym_type = sym->type ();
   if (sym_type == NULL)
@@ -4730,14 +4585,8 @@ treg_matches_sym_type_name (const compiled_regex &treg,
     printed_sym_type_name = type_to_string (sym_type);
   }
 
-
-  if (symbol_lookup_debug > 1)
-    {
-      gdb_printf (gdb_stdlog,
-                 "     sym_type_name %s\n",
-                 printed_sym_type_name.c_str ());
-    }
-
+  symbol_lookup_debug_printf_v ("sym_type_name %s",
+                               printed_sym_type_name.c_str ());
 
   if (printed_sym_type_name.empty ())
     return false;
@@ -4867,11 +4716,9 @@ global_symbol_searcher::add_matching_symbols
 
       for (block_enum block : { GLOBAL_BLOCK, STATIC_BLOCK })
        {
-         struct block_iterator iter;
-         struct symbol *sym;
-         const struct block *b = BLOCKVECTOR_BLOCK (bv, block);
+         const struct block *b = bv->block (block);
 
-         ALL_BLOCK_SYMBOLS (b, iter, sym)
+         for (struct symbol *sym : block_iterator_range (b))
            {
              struct symtab *real_symtab = sym->symtab ();
 
@@ -4990,6 +4837,7 @@ global_symbol_searcher::search () const
   if (m_symbol_name_regexp != NULL)
     {
       const char *symbol_name_regexp = m_symbol_name_regexp;
+      std::string symbol_name_regexp_holder;
 
       /* Make sure spacing is right for C++ operators.
         This is just a courtesy to make the matching less sensitive
@@ -5018,10 +4866,9 @@ global_symbol_searcher::search () const
          /* If wrong number of spaces, fix it.  */
          if (fix >= 0)
            {
-             char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1);
-
-             sprintf (tmp, "operator%.*s%s", fix, " ", opname);
-             symbol_name_regexp = tmp;
+             symbol_name_regexp_holder
+               = string_printf ("operator%.*s%s", fix, " ", opname);
+             symbol_name_regexp = symbol_name_regexp_holder.c_str ();
            }
        }
 
@@ -5445,6 +5292,14 @@ info_modules_command (const char *args, int from_tty)
                      from_tty);
 }
 
+/* Implement the 'info main' command.  */
+
+static void
+info_main_command (const char *args, int from_tty)
+{
+  gdb_printf ("%s\n", main_name ());
+}
+
 static void
 rbreak_command (const char *regexp, int from_tty)
 {
@@ -5831,9 +5686,6 @@ add_symtab_completions (struct compunit_symtab *cust,
                        const char *text, const char *word,
                        enum type_code code)
 {
-  struct symbol *sym;
-  const struct block *b;
-  struct block_iterator iter;
   int i;
 
   if (cust == NULL)
@@ -5842,8 +5694,9 @@ add_symtab_completions (struct compunit_symtab *cust,
   for (i = GLOBAL_BLOCK; i <= STATIC_BLOCK; i++)
     {
       QUIT;
-      b = BLOCKVECTOR_BLOCK (cust->blockvector (), i);
-      ALL_BLOCK_SYMBOLS (b, iter, sym)
+
+      const struct block *b = cust->blockvector ()->block (i);
+      for (struct symbol *sym : block_iterator_range (b))
        {
          if (completion_skip_symbol (mode, sym))
            continue;
@@ -5869,10 +5722,8 @@ default_collect_symbol_completion_matches_break_on
      frees them.  I'm not going to worry about this; hopefully there
      won't be that many.  */
 
-  struct symbol *sym;
   const struct block *b;
   const struct block *surrounding_static_block, *surrounding_global_block;
-  struct block_iterator iter;
   /* The symbol we are completing on.  Points in same buffer as text.  */
   const char *sym_text;
 
@@ -5986,14 +5837,14 @@ default_collect_symbol_completion_matches_break_on
      visible from current context.  */
 
   b = get_selected_block (0);
-  surrounding_static_block = block_static_block (b);
-  surrounding_global_block = block_global_block (b);
+  surrounding_static_block = b == nullptr ? nullptr : b->static_block ();
+  surrounding_global_block = b == nullptr ? nullptr : b->global_block ();
   if (surrounding_static_block != NULL)
     while (b != surrounding_static_block)
       {
        QUIT;
 
-       ALL_BLOCK_SYMBOLS (b, iter, sym)
+       for (struct symbol *sym : block_iterator_range (b))
          {
            if (code == TYPE_CODE_UNDEF)
              {
@@ -6011,7 +5862,7 @@ default_collect_symbol_completion_matches_break_on
        /* Stop when we encounter an enclosing function.  Do not stop for
           non-inlined functions - the locals of the enclosing function
           are in scope for a nested function.  */
-       if (b->function () != NULL && block_inlined_p (b))
+       if (b->function () != NULL && b->inlined_p ())
          break;
        b = b->superblock ();
       }
@@ -6021,12 +5872,12 @@ default_collect_symbol_completion_matches_break_on
   if (code == TYPE_CODE_UNDEF)
     {
       if (surrounding_static_block != NULL)
-       ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym)
+       for (struct symbol *sym : block_iterator_range (surrounding_static_block))
          completion_list_add_fields (tracker, sym, lookup_name,
                                      sym_text, word);
 
       if (surrounding_global_block != NULL)
-       ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym)
+       for (struct symbol *sym : block_iterator_range (surrounding_global_block))
          completion_list_add_fields (tracker, sym, lookup_name,
                                      sym_text, word);
     }
@@ -6326,15 +6177,14 @@ set_main_name (const char *name, enum language lang)
 {
   struct main_info *info = get_main_info ();
 
-  if (info->name_of_main != NULL)
+  if (!info->name_of_main.empty ())
     {
-      xfree (info->name_of_main);
-      info->name_of_main = NULL;
+      info->name_of_main.clear ();
       info->language_of_main = language_unknown;
     }
   if (name != NULL)
     {
-      info->name_of_main = xstrdup (name);
+      info->name_of_main = name;
       info->language_of_main = lang;
     }
 }
@@ -6411,13 +6261,25 @@ find_main_name (void)
      Fallback to "main".  */
 
   /* Try to find language for main in psymtabs.  */
-  enum language lang
-    = find_quick_global_symbol_language ("main", VAR_DOMAIN);
-  if (lang != language_unknown)
-    {
-      set_main_name ("main", lang);
-      return;
-    }
+  bool symbol_found_p = false;
+  gdbarch_iterate_over_objfiles_in_search_order
+    (target_gdbarch (),
+     [&symbol_found_p] (objfile *obj)
+       {
+        language lang
+          = obj->lookup_global_symbol_language ("main", VAR_DOMAIN,
+                                                &symbol_found_p);
+        if (symbol_found_p)
+          {
+            set_main_name ("main", lang);
+            return 1;
+          }
+
+        return 0;
+       }, nullptr);
+
+  if (symbol_found_p)
+    return;
 
   set_main_name ("main", language_unknown);
 }
@@ -6429,10 +6291,10 @@ main_name ()
 {
   struct main_info *info = get_main_info ();
 
-  if (info->name_of_main == NULL)
+  if (info->name_of_main.empty ())
     find_main_name ();
 
-  return info->name_of_main;
+  return info->name_of_main.c_str ();
 }
 
 /* Return the language of the main function.  If it is not known,
@@ -6443,7 +6305,7 @@ main_language (void)
 {
   struct main_info *info = get_main_info ();
 
-  if (info->name_of_main == NULL)
+  if (info->name_of_main.empty ())
     find_main_name ();
 
   return info->language_of_main;
@@ -6491,7 +6353,7 @@ static int next_aclass_value = LOC_FINAL_VALUE;
 
 /* The maximum number of "aclass" registrations we support.  This is
    constant for convenience.  */
-#define MAX_SYMBOL_IMPLS (LOC_FINAL_VALUE + 10)
+#define MAX_SYMBOL_IMPLS (LOC_FINAL_VALUE + 11)
 
 /* The objects representing the various "aclass" values.  The elements
    from 0 up to LOC_FINAL_VALUE-1 represent themselves, and subsequent
@@ -6552,7 +6414,8 @@ register_symbol_block_impl (enum address_class aclass,
 
   /* Sanity check OPS.  */
   gdb_assert (ops != NULL);
-  gdb_assert (ops->find_frame_base_location != NULL);
+  gdb_assert (ops->find_frame_base_location != nullptr
+             || ops->get_block_value != nullptr);
 
   return result;
 }
@@ -6636,17 +6499,10 @@ get_symbol_address (const struct symbol *sym)
   gdb_assert (sym->aclass () == LOC_STATIC);
 
   const char *linkage_name = sym->linkage_name ();
-
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      if (objfile->separate_debug_objfile_backlink != nullptr)
-       continue;
-
-      bound_minimal_symbol minsym
-       = lookup_minimal_symbol_linkage (linkage_name, objfile);
-      if (minsym.minsym != nullptr)
-       return minsym.value_address ();
-    }
+  bound_minimal_symbol minsym = lookup_minimal_symbol_linkage (linkage_name,
+                                                              false);
+  if (minsym.minsym != nullptr)
+    return minsym.value_address ();
   return sym->m_value.address;
 }
 
@@ -6659,18 +6515,10 @@ get_msymbol_address (struct objfile *objf, const struct minimal_symbol *minsym)
   gdb_assert ((objf->flags & OBJF_MAINLINE) == 0);
 
   const char *linkage_name = minsym->linkage_name ();
-
-  for (objfile *objfile : current_program_space->objfiles ())
-    {
-      if (objfile->separate_debug_objfile_backlink == nullptr
-         && (objfile->flags & OBJF_MAINLINE) != 0)
-       {
-         bound_minimal_symbol found
-           = lookup_minimal_symbol_linkage (linkage_name, objfile);
-         if (found.minsym != nullptr)
-           return found.value_address ();
-       }
-    }
+  bound_minimal_symbol found = lookup_minimal_symbol_linkage (linkage_name,
+                                                             true);
+  if (found.minsym != nullptr)
+    return found.value_address ();
   return (minsym->m_value.address
          + objf->section_offsets[minsym->section_index ()]);
 }
@@ -7029,6 +6877,9 @@ Options:\n\
                _("All module names, or those matching REGEXP."));
   set_cmd_completer_handle_brkchars (c, info_types_command_completer);
 
+  add_info ("main", info_main_command,
+           _("Get main symbol to identify entry point into program."));
+
   add_basic_prefix_cmd ("module", class_info, _("\
 Print information about modules."),
                        &info_module_cmdlist, 0, &infolist);