gdb: LoongArch: Define LOONGARCH_LINUX_NUM_GREGSET as 45
[binutils-gdb.git] / gdb / elfread.c
index cb98b83f74b772cf0ffae2bb89af04b2f5c03627..32cb27c8967e3053cc6e276633be4a2e9f79c436 100644 (file)
@@ -1,6 +1,6 @@
 /* Read ELF (Executable and Linking Format) object files for GDB.
 
-   Copyright (C) 1991-2019 Free Software Foundation, Inc.
+   Copyright (C) 1991-2022 Free Software Foundation, Inc.
 
    Written by Fred Fish at Cygnus Support.
 
@@ -29,8 +29,6 @@
 #include "symfile.h"
 #include "objfiles.h"
 #include "stabsread.h"
-#include "gdb-stabs.h"
-#include "complaints.h"
 #include "demangle.h"
 #include "psympriv.h"
 #include "filenames.h"
 #include "location.h"
 #include "auxv.h"
 #include "mdebugread.h"
-
-/* Forward declarations.  */
-extern const struct sym_fns elf_sym_fns_gdb_index;
-extern const struct sym_fns elf_sym_fns_debug_names;
-extern const struct sym_fns elf_sym_fns_lazy_psyms;
+#include "ctfread.h"
+#include "gdbsupport/gdb_string_view.h"
+#include "gdbsupport/scoped_fd.h"
+#include "debuginfod-support.h"
+#include "dwarf2/public.h"
 
 /* The struct elfinfo is available only during ELF symbol table and
    psymtab reading.  It is destroyed at the completion of psymtab-reading.
@@ -62,6 +60,7 @@ struct elfinfo
   {
     asection *stabsect;                /* Section pointer for .stab section */
     asection *mdebugsect;      /* Section pointer for .mdebug section */
+    asection *ctfsect;         /* Section pointer for .ctf section */
   };
 
 /* Type for per-BFD data.  */
@@ -81,14 +80,13 @@ static const struct bfd_key<elfread_data> probe_key;
 
 /* Locate the segments in ABFD.  */
 
-static struct symfile_segment_data *
+static symfile_segment_data_up
 elf_symfile_segments (bfd *abfd)
 {
   Elf_Internal_Phdr *phdrs, **segments;
   long phdrs_size;
   int num_phdrs, num_segments, num_sections, i;
   asection *sect;
-  struct symfile_segment_data *data;
 
   phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
   if (phdrs_size == -1)
@@ -108,25 +106,22 @@ elf_symfile_segments (bfd *abfd)
   if (num_segments == 0)
     return NULL;
 
-  data = XCNEW (struct symfile_segment_data);
-  data->num_segments = num_segments;
-  data->segment_bases = XCNEWVEC (CORE_ADDR, num_segments);
-  data->segment_sizes = XCNEWVEC (CORE_ADDR, num_segments);
+  symfile_segment_data_up data (new symfile_segment_data);
+  data->segments.reserve (num_segments);
 
   for (i = 0; i < num_segments; i++)
-    {
-      data->segment_bases[i] = segments[i]->p_vaddr;
-      data->segment_sizes[i] = segments[i]->p_memsz;
-    }
+    data->segments.emplace_back (segments[i]->p_vaddr, segments[i]->p_memsz);
 
   num_sections = bfd_count_sections (abfd);
-  data->segment_info = XCNEWVEC (int, num_sections);
+
+  /* All elements are initialized to 0 (map to no segment).  */
+  data->segment_info.resize (num_sections);
 
   for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
     {
       int j;
 
-      if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+      if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
        continue;
 
       Elf_Internal_Shdr *this_hdr = &elf_section_data (sect)->this_hdr;
@@ -147,10 +142,15 @@ elf_symfile_segments (bfd *abfd)
         RealView) use SHT_NOBITS for uninitialized data.  Since it is
         uninitialized, it doesn't need a program header.  Such
         binaries are not relocatable.  */
-      if (bfd_get_section_size (sect) > 0 && j == num_segments
-         && (bfd_get_section_flags (abfd, sect) & SEC_LOAD) != 0)
-       warning (_("Loadable section \"%s\" outside of ELF segments"),
-                bfd_section_name (abfd, sect));
+
+      /* Exclude debuginfo files from this warning, too, since those
+        are often not strictly compliant with the standard. See, e.g.,
+        ld/24717 for more discussion.  */
+      if (!is_debuginfo_file (abfd)
+         && bfd_section_size (sect) > 0 && j == num_segments
+         && (bfd_section_flags (sect) & SEC_LOAD) != 0)
+       warning (_("Loadable section \"%s\" outside of ELF segments\n  in %s"),
+                bfd_section_name (sect), bfd_get_filename (abfd));
     }
 
   return data;
@@ -176,11 +176,8 @@ elf_symfile_segments (bfd *abfd)
    -kingdon).  */
 
 static void
-elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip)
+elf_locate_sections (asection *sectp, struct elfinfo *ei)
 {
-  struct elfinfo *ei;
-
-  ei = (struct elfinfo *) eip;
   if (strcmp (sectp->name, ".stab") == 0)
     {
       ei->stabsect = sectp;
@@ -189,25 +186,40 @@ elf_locate_sections (bfd *ignore_abfd, asection *sectp, void *eip)
     {
       ei->mdebugsect = sectp;
     }
+  else if (strcmp (sectp->name, ".ctf") == 0)
+    {
+      ei->ctfsect = sectp;
+    }
 }
 
 static struct minimal_symbol *
 record_minimal_symbol (minimal_symbol_reader &reader,
-                      const char *name, int name_len, bool copy_name,
+                      gdb::string_view name, bool copy_name,
                       CORE_ADDR address,
                       enum minimal_symbol_type ms_type,
                       asection *bfd_section, struct objfile *objfile)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
 
   if (ms_type == mst_text || ms_type == mst_file_text
       || ms_type == mst_text_gnu_ifunc)
     address = gdbarch_addr_bits_remove (gdbarch, address);
 
-  return reader.record_full (name, name_len, copy_name, address,
-                            ms_type,
-                            gdb_bfd_section_index (objfile->obfd,
-                                                   bfd_section));
+  /* We only setup section information for allocatable sections.  Usually
+     we'd only expect to find msymbols for allocatable sections, but if the
+     ELF is malformed then this might not be the case.  In that case don't
+     create an msymbol that references an uninitialised section object.  */
+  int section_index = 0;
+  if ((bfd_section_flags (bfd_section) & SEC_ALLOC) == SEC_ALLOC)
+    section_index = gdb_bfd_section_index (objfile->obfd, bfd_section);
+
+  struct minimal_symbol *result
+    = reader.record_full (name, copy_name, address, ms_type, section_index);
+  if ((objfile->flags & OBJF_MAINLINE) == 0
+      && (ms_type == mst_data || ms_type == mst_bss))
+    result->maybe_copied = 1;
+
+  return result;
 }
 
 /* Read the symbol table of an ELF file.
@@ -232,7 +244,7 @@ elf_symtab_read (minimal_symbol_reader &reader,
                 long number_of_symbols, asymbol **symbol_table,
                 bool copy_names)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   asymbol *sym;
   long i;
   CORE_ADDR symaddr;
@@ -254,6 +266,8 @@ elf_symtab_read (minimal_symbol_reader &reader,
          continue;
        }
 
+      elf_symbol_type *elf_sym = (elf_symbol_type *) sym;
+
       /* Skip "special" symbols, e.g. ARM mapping symbols.  These are
         symbols which do not correspond to objects in the symbol table,
         but have some other target-specific meaning.  */
@@ -290,12 +304,12 @@ elf_symtab_read (minimal_symbol_reader &reader,
             covers the stub's address.  */
          for (sect = abfd->sections; sect != NULL; sect = sect->next)
            {
-             if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+             if ((bfd_section_flags (sect) & SEC_ALLOC) == 0)
                continue;
 
-             if (symaddr >= bfd_get_section_vma (abfd, sect)
-                 && symaddr < bfd_get_section_vma (abfd, sect)
-                              + bfd_get_section_size (sect))
+             if (symaddr >= bfd_section_vma (sect)
+                 && symaddr < bfd_section_vma (sect)
+                              + bfd_section_size (sect))
                break;
            }
          if (!sect)
@@ -319,7 +333,7 @@ elf_symtab_read (minimal_symbol_reader &reader,
            continue;
 
          msym = record_minimal_symbol
-           (reader, sym->name, strlen (sym->name), copy_names,
+           (reader, sym->name, copy_names,
             symaddr, mst_solib_trampoline, sect, objfile);
          if (msym != NULL)
            {
@@ -336,11 +350,7 @@ elf_symtab_read (minimal_symbol_reader &reader,
       if (type == ST_DYNAMIC && !stripped)
        continue;
       if (sym->flags & BSF_FILE)
-       {
-         filesymname
-           = ((const char *) objfile->per_bfd->filename_cache.insert
-              (sym->name, strlen (sym->name) + 1));
-       }
+       filesymname = objfile->intern (sym->name);
       else if (sym->flags & BSF_SECTION_SYM)
        continue;
       else if (sym->flags & (BSF_GLOBAL | BSF_LOCAL | BSF_WEAK
@@ -365,7 +375,7 @@ elf_symtab_read (minimal_symbol_reader &reader,
                 NOTE: uweigand-20071112: Synthetic symbols do not
                 have an ELF-private part, so do not touch those.  */
              unsigned int shndx = type == ST_SYNTHETIC ? 0 :
-               ((elf_symbol_type *) sym)->internal_elf_sym.st_shndx;
+               elf_sym->internal_elf_sym.st_shndx;
 
              switch (shndx)
                {
@@ -463,7 +473,7 @@ elf_symtab_read (minimal_symbol_reader &reader,
              continue; /* Skip this symbol.  */
            }
          msym = record_minimal_symbol
-           (reader, sym->name, strlen (sym->name), copy_names, symaddr,
+           (reader, sym->name, copy_names, symaddr,
             ms_type, sym->section, objfile);
 
          if (msym)
@@ -473,8 +483,7 @@ elf_symtab_read (minimal_symbol_reader &reader,
              if (type != ST_SYNTHETIC)
                {
                  /* Pass symbol size field in via BFD.  FIXME!!!  */
-                 elf_symbol_type *elf_sym = (elf_symbol_type *) sym;
-                 SET_MSYMBOL_SIZE (msym, elf_sym->internal_elf_sym.st_size);
+                 msym->set_size (elf_sym->internal_elf_sym.st_size);
                }
 
              msym->filename = filesymname;
@@ -487,40 +496,39 @@ elf_symtab_read (minimal_symbol_reader &reader,
          if (msym != NULL)
            {
              const char *atsign = strchr (sym->name, '@');
-
-             if (atsign != NULL && atsign[1] == '@' && atsign > sym->name)
+             bool is_at_symbol = atsign != nullptr && atsign > sym->name;
+             bool is_plt = is_at_symbol && strcmp (atsign, "@plt") == 0;
+             int len = is_at_symbol ? atsign - sym->name : 0;
+
+             if (is_at_symbol
+                 && !is_plt
+                 && (elf_sym->version & VERSYM_HIDDEN) == 0)
+               record_minimal_symbol (reader,
+                                      gdb::string_view (sym->name, len),
+                                      true, symaddr, ms_type, sym->section,
+                                      objfile);
+             else if (is_plt)
                {
-                 int len = atsign - sym->name;
-
-                 record_minimal_symbol (reader, sym->name, len, true, symaddr,
-                                        ms_type, sym->section, objfile);
-               }
-           }
-
-         /* For @plt symbols, also record a trampoline to the
-            destination symbol.  The @plt symbol will be used in
-            disassembly, and the trampoline will be used when we are
-            trying to find the target.  */
-         if (msym && ms_type == mst_text && type == ST_SYNTHETIC)
-           {
-             int len = strlen (sym->name);
-
-             if (len > 4 && strcmp (sym->name + len - 4, "@plt") == 0)
-               {
-                 struct minimal_symbol *mtramp;
-
-                 mtramp = record_minimal_symbol (reader, sym->name, len - 4,
-                                                 true, symaddr,
-                                                 mst_solib_trampoline,
-                                                 sym->section, objfile);
-                 if (mtramp)
+                 /* For @plt symbols, also record a trampoline to the
+                    destination symbol.  The @plt symbol will be used
+                    in disassembly, and the trampoline will be used
+                    when we are trying to find the target.  */
+                 if (ms_type == mst_text && type == ST_SYNTHETIC)
                    {
-                     SET_MSYMBOL_SIZE (mtramp, MSYMBOL_SIZE (msym));
-                     mtramp->created_by_gdb = 1;
-                     mtramp->filename = filesymname;
-                     if (elf_make_msymbol_special_p)
-                       gdbarch_elf_make_msymbol_special (gdbarch,
-                                                         sym, mtramp);
+                     struct minimal_symbol *mtramp;
+
+                     mtramp = record_minimal_symbol
+                       (reader, gdb::string_view (sym->name, len), true,
+                        symaddr, mst_solib_trampoline, sym->section, objfile);
+                     if (mtramp)
+                       {
+                         mtramp->set_size (msym->size());
+                         mtramp->created_by_gdb = 1;
+                         mtramp->filename = filesymname;
+                         if (elf_make_msymbol_special_p)
+                           gdbarch_elf_make_msymbol_special (gdbarch,
+                                                             sym, mtramp);
+                       }
                    }
                }
            }
@@ -543,7 +551,7 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
   const struct elf_backend_data *bed = get_elf_backend_data (obfd);
   asection *relplt, *got_plt;
   bfd_size_type reloc_count, reloc;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
   size_t ptr_size = TYPE_LENGTH (ptr_type);
 
@@ -592,9 +600,9 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
       if (section == NULL)
        return false;
 
-      return (bfd_get_section_vma (obfd, section) <= address
-             && (address < bfd_get_section_vma (obfd, section)
-                 + bfd_get_section_size (section)));
+      return (bfd_section_vma (section) <= address
+             && (address < bfd_section_vma (section)
+                 + bfd_section_size (section)));
     };
 
   reloc_count = relplt->size / elf_section_data (relplt)->this_hdr.sh_entsize;
@@ -628,12 +636,11 @@ elf_rel_plt_read (minimal_symbol_reader &reader,
       string_buffer.assign (name);
       string_buffer.append (got_suffix, got_suffix + got_suffix_len);
 
-      msym = record_minimal_symbol (reader, string_buffer.c_str (),
-                                   string_buffer.size (),
+      msym = record_minimal_symbol (reader, string_buffer,
                                    true, address, mst_slot_got_plt,
                                    msym_section, objfile);
       if (msym)
-       SET_MSYMBOL_SIZE (msym, ptr_size);
+       msym->set_size (ptr_size);
     }
 }
 
@@ -696,13 +703,13 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr)
   msym = lookup_minimal_symbol_by_pc (addr);
   if (msym.minsym == NULL)
     return 0;
-  if (BMSYMBOL_VALUE_ADDRESS (msym) != addr)
+  if (msym.value_address () != addr)
     return 0;
   objfile = msym.objfile;
 
   /* If .plt jumps back to .plt the symbol is still deferred for later
      resolution and it has no use for GDB.  */
-  const char *target_name = MSYMBOL_LINKAGE_NAME (msym.minsym);
+  const char *target_name = msym.minsym->linkage_name ();
   size_t len = strlen (target_name);
 
   /* Note we check the symbol's name instead of checking whether the
@@ -732,7 +739,7 @@ elf_gnu_ifunc_record_cache (const char *name, CORE_ADDR addr)
     {
       struct elf_gnu_ifunc_cache *entry_found_p
        = (struct elf_gnu_ifunc_cache *) *slot;
-      struct gdbarch *gdbarch = get_objfile_arch (objfile);
+      struct gdbarch *gdbarch = objfile->arch ();
 
       if (entry_found_p->addr != addr)
        {
@@ -810,7 +817,7 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p)
   for (objfile *objfile : current_program_space->objfiles ())
     {
       bfd *obfd = objfile->obfd;
-      struct gdbarch *gdbarch = get_objfile_arch (objfile);
+      struct gdbarch *gdbarch = objfile->arch ();
       struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
       size_t ptr_size = TYPE_LENGTH (ptr_type);
       CORE_ADDR pointer_address, addr;
@@ -821,21 +828,21 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p)
       msym = lookup_minimal_symbol (name_got_plt, NULL, objfile);
       if (msym.minsym == NULL)
        continue;
-      if (MSYMBOL_TYPE (msym.minsym) != mst_slot_got_plt)
+      if (msym.minsym->type () != mst_slot_got_plt)
        continue;
-      pointer_address = BMSYMBOL_VALUE_ADDRESS (msym);
+      pointer_address = msym.value_address ();
 
       plt = bfd_get_section_by_name (obfd, ".plt");
       if (plt == NULL)
        continue;
 
-      if (MSYMBOL_SIZE (msym.minsym) != ptr_size)
+      if (msym.minsym->size () != ptr_size)
        continue;
       if (target_read_memory (pointer_address, buf, ptr_size) != 0)
        continue;
       addr = extract_typed_address (buf, ptr_type);
-      addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
-                                                current_top_target ());
+      addr = gdbarch_convert_from_func_ptr_addr
+       (gdbarch, addr, current_inferior ()->top_target ());
       addr = gdbarch_addr_bits_remove (gdbarch, addr);
 
       if (elf_gnu_ifunc_record_cache (name, addr))
@@ -851,21 +858,21 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p)
 
 /* Try to find the target resolved function entry address of a STT_GNU_IFUNC
    function NAME.  If the address is found it is stored to *ADDR_P (if ADDR_P
-   is not NULL) and the function returns 1.  It returns 0 otherwise.
+   is not NULL) and the function returns true.  It returns false otherwise.
 
    Both the elf_objfile_gnu_ifunc_cache_data hash table and
    SYMBOL_GOT_PLT_SUFFIX locations are searched by this function.  */
 
-static int
+static bool
 elf_gnu_ifunc_resolve_name (const char *name, CORE_ADDR *addr_p)
 {
   if (elf_gnu_ifunc_resolve_by_cache (name, addr_p))
-    return 1;
+    return true;
 
   if (elf_gnu_ifunc_resolve_by_got (name, addr_p))
-    return 1;
+    return true;
 
-  return 0;
+  return false;
 }
 
 /* Call STT_GNU_IFUNC - a function returning addresss of a real function to
@@ -902,12 +909,13 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc)
      parameter.  FUNCTION is the function entry address.  ADDRESS may be a
      function descriptor.  */
 
-  target_auxv_search (current_top_target (), AT_HWCAP, &hwcap);
+  target_auxv_search (current_inferior ()->top_target (), AT_HWCAP, &hwcap);
   hwcap_val = value_from_longest (builtin_type (gdbarch)
                                  ->builtin_unsigned_long, hwcap);
   address_val = call_function_by_hand (function, NULL, hwcap_val);
   address = value_as_address (address_val);
-  address = gdbarch_convert_from_func_ptr_addr (gdbarch, address, current_top_target ());
+  address = gdbarch_convert_from_func_ptr_addr
+    (gdbarch, address, current_inferior ()->top_target ());
   address = gdbarch_addr_bits_remove (gdbarch, address);
 
   if (name_at_pc)
@@ -919,7 +927,7 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc)
 /* Handle inferior hit of bp_gnu_ifunc_resolver, see its definition.  */
 
 static void
-elf_gnu_ifunc_resolver_stop (struct breakpoint *b)
+elf_gnu_ifunc_resolver_stop (code_breakpoint *b)
 {
   struct breakpoint *b_return;
   struct frame_info *prev_frame = get_prev_frame (get_current_frame ());
@@ -970,7 +978,7 @@ elf_gnu_ifunc_resolver_stop (struct breakpoint *b)
 /* Handle inferior hit of bp_gnu_ifunc_resolver_return, see its definition.  */
 
 static void
-elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
+elf_gnu_ifunc_resolver_return_stop (code_breakpoint *b)
 {
   thread_info *thread = inferior_thread ();
   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
@@ -1000,7 +1008,7 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
                            "gnu-indirect-function breakpoint type %d"),
                          (int) b->type);
        }
-      b = b_next;
+      b = (code_breakpoint *) b_next;
     }
   gdb_assert (b->type == bp_gnu_ifunc_resolver);
   gdb_assert (b->loc->next == NULL);
@@ -1011,11 +1019,10 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
 
   value = allocate_value (value_type);
   gdbarch_return_value (gdbarch, func_func, value_type, regcache,
-                       value_contents_raw (value), NULL);
+                       value_contents_raw (value).data (), NULL);
   resolved_address = value_as_address (value);
-  resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
-                                                   resolved_address,
-                                                   current_top_target ());
+  resolved_pc = gdbarch_convert_from_func_ptr_addr
+    (gdbarch, resolved_address, current_inferior ()->top_target ());
   resolved_pc = gdbarch_addr_bits_remove (gdbarch, resolved_pc);
 
   gdb_assert (current_program_space == b->pspace || b->pspace == NULL);
@@ -1039,13 +1046,12 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags,
   long symcount = 0, dynsymcount = 0, synthcount, storage_needed;
   asymbol **symbol_table = NULL, **dyn_symbol_table = NULL;
   asymbol *synthsyms;
-  struct dbx_symfile_info *dbx;
 
   if (symtab_create_debug)
     {
-      fprintf_unfiltered (gdb_stdlog,
-                         "Reading minimal symbols of objfile %s ...\n",
-                         objfile_name (objfile));
+      gdb_printf (gdb_stdlog,
+                 "Reading minimal symbols of objfile %s ...\n",
+                 objfile_name (objfile));
     }
 
   /* If we already have minsyms, then we can skip some work here.
@@ -1055,20 +1061,17 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags,
      go away once all types of symbols are in the per-BFD object.  */
   if (objfile->per_bfd->minsyms_read
       && ei->stabsect == NULL
-      && ei->mdebugsect == NULL)
+      && ei->mdebugsect == NULL
+      && ei->ctfsect == NULL)
     {
       if (symtab_create_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "... minimal symbols previously read\n");
+       gdb_printf (gdb_stdlog,
+                   "... minimal symbols previously read\n");
       return;
     }
 
   minimal_symbol_reader reader (objfile);
 
-  /* Allocate struct to keep track of the symfile.  */
-  dbx = XCNEW (struct dbx_symfile_info);
-  set_objfile_data (objfile, dbx_objfile_data_key, dbx);
-
   /* Process the normal ELF symbol table first.  */
 
   storage_needed = bfd_get_symtab_upper_bound (objfile->obfd);
@@ -1168,7 +1171,7 @@ elf_read_minimal_symbols (struct objfile *objfile, int symfile_flags,
   reader.install ();
 
   if (symtab_create_debug)
-    fprintf_unfiltered (gdb_stdlog, "Done reading minimal symbols.\n");
+    gdb_printf (gdb_stdlog, "Done reading minimal symbols.\n");
 }
 
 /* Scan and build partial symbols for a symbol file.
@@ -1200,10 +1203,14 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 {
   bfd *abfd = objfile->obfd;
   struct elfinfo ei;
+  bool has_dwarf2 = true;
 
   memset ((char *) &ei, 0, sizeof (ei));
   if (!(objfile->flags & OBJF_READNEVER))
-    bfd_map_over_sections (abfd, elf_locate_sections, (void *) & ei);
+    {
+      for (asection *sect : gdb_bfd_sections (abfd))
+       elf_locate_sections (sect, &ei);
+    }
 
   elf_read_minimal_symbols (objfile, symfile_flags, &ei);
 
@@ -1224,7 +1231,7 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
       const struct ecoff_debug_swap *swap;
 
       /* .mdebug section, presumably holding ECOFF debugging
-         information.  */
+        information.  */
       swap = get_elf_backend_data (abfd)->elf_backend_ecoff_debug_swap;
       if (swap)
        elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect);
@@ -1234,7 +1241,7 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
       asection *str_sect;
 
       /* Stab sections have an associated string table that looks like
-         a separate section.  */
+        a separate section.  */
       str_sect = bfd_get_section_by_name (abfd, ".stabstr");
 
       /* FIXME should probably warn about a stab section without a stabstr.  */
@@ -1242,51 +1249,24 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
        elfstab_build_psymtabs (objfile,
                                ei.stabsect,
                                str_sect->filepos,
-                               bfd_section_size (abfd, str_sect));
+                               bfd_section_size (str_sect));
     }
 
-  if (dwarf2_has_info (objfile, NULL))
-    {
-      dw_index_kind index_kind;
-
-      /* elf_sym_fns_gdb_index cannot handle simultaneous non-DWARF
-        debug information present in OBJFILE.  If there is such debug
-        info present never use an index.  */
-      if (!objfile_has_partial_symbols (objfile)
-         && dwarf2_initialize_objfile (objfile, &index_kind))
-       {
-         switch (index_kind)
-           {
-           case dw_index_kind::GDB_INDEX:
-             objfile_set_sym_fns (objfile, &elf_sym_fns_gdb_index);
-             break;
-           case dw_index_kind::DEBUG_NAMES:
-             objfile_set_sym_fns (objfile, &elf_sym_fns_debug_names);
-             break;
-           }
-       }
-      else
-       {
-         /* It is ok to do this even if the stabs reader made some
-            partial symbols, because OBJF_PSYMTABS_READ has not been
-            set, and so our lazy reader function will still be called
-            when needed.  */
-         objfile_set_sym_fns (objfile, &elf_sym_fns_lazy_psyms);
-       }
-    }
+  if (dwarf2_has_info (objfile, NULL, true))
+    dwarf2_initialize_objfile (objfile);
   /* If the file has its own symbol tables it has no separate debug
      info.  `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to
      SYMTABS/PSYMTABS.  `.gnu_debuglink' may no longer be present with
      `.note.gnu.build-id'.
 
-     .gnu_debugdata is !objfile_has_partial_symbols because it contains only
+     .gnu_debugdata is !objfile::has_partial_symbols because it contains only
      .symtab, not .debug_* section.  But if we already added .gnu_debugdata as
      an objfile via find_separate_debug_file_in_section there was no separate
      debug info available.  Therefore do not attempt to search for another one,
      objfile->separate_debug_objfile->separate_debug_objfile GDB guarantees to
      be NULL and we would possibly violate it.  */
 
-  else if (!objfile_has_partial_symbols (objfile)
+  else if (!objfile->has_partial_symbols ()
           && objfile->separate_debug_objfile == NULL
           && objfile->separate_debug_objfile_backlink == NULL)
     {
@@ -1302,29 +1282,52 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
          symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
                                    symfile_flags, objfile);
        }
-    }
-}
+      else
+       {
+         has_dwarf2 = false;
+         const struct bfd_build_id *build_id = build_id_bfd_get (objfile->obfd);
 
-/* Callback to lazily read psymtabs.  */
+         if (build_id != nullptr)
+           {
+             gdb::unique_xmalloc_ptr<char> symfile_path;
+             scoped_fd fd (debuginfod_debuginfo_query (build_id->data,
+                                                       build_id->size,
+                                                       objfile->original_name,
+                                                       &symfile_path));
 
-static void
-read_psyms (struct objfile *objfile)
-{
-  if (dwarf2_has_info (objfile, NULL))
-    dwarf2_build_psymtabs (objfile);
+             if (fd.get () >= 0)
+               {
+                 /* File successfully retrieved from server.  */
+                 gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (symfile_path.get ()));
+
+                 if (debug_bfd == nullptr)
+                   warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
+                            objfile->original_name);
+                 else if (build_id_verify (debug_bfd.get (), build_id->size, build_id->data))
+                   {
+                     symbol_file_add_separate (debug_bfd.get (), symfile_path.get (),
+                                               symfile_flags, objfile);
+                     has_dwarf2 = true;
+                   }
+               }
+           }
+       }
+    }
+
+  /* Read the CTF section only if there is no DWARF info.  */
+  if (!has_dwarf2 && ei.ctfsect)
+    {
+      elfctf_build_psymtabs (objfile);
+    }
 }
 
 /* Initialize anything that needs initializing when a completely new symbol
    file is specified (not just adding some symbols from another file, e.g. a
-   shared library).
-
-   We reinitialize buildsym, since we may be reading stabs from an ELF
-   file.  */
+   shared library).  */
 
 static void
 elf_new_init (struct objfile *ignore)
 {
-  stabsread_new_init ();
 }
 
 /* Perform any local cleanups required when we are done with a particular
@@ -1384,66 +1387,12 @@ static const struct sym_fns elf_sym_fns =
   elf_new_init,                        /* init anything gbl to entire symtab */
   elf_symfile_init,            /* read initial info, setup for sym_read() */
   elf_symfile_read,            /* read a symbol file into symtab */
-  NULL,                                /* sym_read_psymbols */
   elf_symfile_finish,          /* finished with file, cleanup */
   default_symfile_offsets,     /* Translate ext. to int. relocation */
   elf_symfile_segments,                /* Get segment information from a file.  */
   NULL,
   default_symfile_relocate,    /* Relocate a debug section.  */
   &elf_probe_fns,              /* sym_probe_fns */
-  &psym_functions
-};
-
-/* The same as elf_sym_fns, but not registered and lazily reads
-   psymbols.  */
-
-const struct sym_fns elf_sym_fns_lazy_psyms =
-{
-  elf_new_init,                        /* init anything gbl to entire symtab */
-  elf_symfile_init,            /* read initial info, setup for sym_read() */
-  elf_symfile_read,            /* read a symbol file into symtab */
-  read_psyms,                  /* sym_read_psymbols */
-  elf_symfile_finish,          /* finished with file, cleanup */
-  default_symfile_offsets,     /* Translate ext. to int. relocation */
-  elf_symfile_segments,                /* Get segment information from a file.  */
-  NULL,
-  default_symfile_relocate,    /* Relocate a debug section.  */
-  &elf_probe_fns,              /* sym_probe_fns */
-  &psym_functions
-};
-
-/* The same as elf_sym_fns, but not registered and uses the
-   DWARF-specific GNU index rather than psymtab.  */
-const struct sym_fns elf_sym_fns_gdb_index =
-{
-  elf_new_init,                        /* init anything gbl to entire symab */
-  elf_symfile_init,            /* read initial info, setup for sym_red() */
-  elf_symfile_read,            /* read a symbol file into symtab */
-  NULL,                                /* sym_read_psymbols */
-  elf_symfile_finish,          /* finished with file, cleanup */
-  default_symfile_offsets,     /* Translate ext. to int. relocatin */
-  elf_symfile_segments,                /* Get segment information from a file.  */
-  NULL,
-  default_symfile_relocate,    /* Relocate a debug section.  */
-  &elf_probe_fns,              /* sym_probe_fns */
-  &dwarf2_gdb_index_functions
-};
-
-/* The same as elf_sym_fns, but not registered and uses the
-   DWARF-specific .debug_names index rather than psymtab.  */
-const struct sym_fns elf_sym_fns_debug_names =
-{
-  elf_new_init,                        /* init anything gbl to entire symab */
-  elf_symfile_init,            /* read initial info, setup for sym_red() */
-  elf_symfile_read,            /* read a symbol file into symtab */
-  NULL,                                /* sym_read_psymbols */
-  elf_symfile_finish,          /* finished with file, cleanup */
-  default_symfile_offsets,     /* Translate ext. to int. relocatin */
-  elf_symfile_segments,                /* Get segment information from a file.  */
-  NULL,
-  default_symfile_relocate,    /* Relocate a debug section.  */
-  &elf_probe_fns,              /* sym_probe_fns */
-  &dwarf2_debug_names_functions
 };
 
 /* STT_GNU_IFUNC resolver vector to be installed to gnu_ifunc_fns_p.  */
@@ -1456,8 +1405,9 @@ static const struct gnu_ifunc_fns elf_gnu_ifunc_fns =
   elf_gnu_ifunc_resolver_return_stop
 };
 
+void _initialize_elfread ();
 void
-_initialize_elfread (void)
+_initialize_elfread ()
 {
   add_symtab_fns (bfd_target_elf_flavour, &elf_sym_fns);