Constify some target_so_ops instances
[binutils-gdb.git] / gdb / solib-svr4.c
index 19d1105ae95f78c5e4b429670165e7eca2712e65..bab76e25baf6684c71374b67758df1dd273e3c0a 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle SVR4 shared libraries for GDB, the GNU Debugger.
 
-   Copyright (C) 1990-2020 Free Software Foundation, Inc.
+   Copyright (C) 1990-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -51,9 +51,9 @@ static int svr4_have_link_map_offsets (void);
 static void svr4_relocate_main_executable (void);
 static void svr4_free_library_list (void *p_list);
 static void probes_table_remove_objfile_probes (struct objfile *objfile);
-static void svr4_iterate_over_objfiles_in_search_order (
-  struct gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype *cb,
-  void *cb_data, struct objfile *objfile);
+static void svr4_iterate_over_objfiles_in_search_order
+  (gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype cb,
+   objfile *current_objfile);
 
 
 /* On SVR4 systems, a list of symbols in the dynamic linker where
@@ -292,10 +292,10 @@ lm_addr_check (const struct so_list *so, bfd *abfd)
              && (l_addr & align) == ((l_dynaddr - dynaddr) & align))
            {
              if (info_verbose)
-               printf_unfiltered (_("Using PIC (Position Independent Code) "
-                                    "prelink displacement %s for \"%s\".\n"),
-                                  paddress (target_gdbarch (), l_addr),
-                                  so->so_name);
+               gdb_printf (_("Using PIC (Position Independent Code) "
+                             "prelink displacement %s for \"%s\".\n"),
+                           paddress (target_gdbarch (), l_addr),
+                           so->so_name);
            }
          else
            {
@@ -365,7 +365,7 @@ struct svr4_info
 };
 
 /* Per-program-space data key.  */
-static const struct program_space_key<svr4_info> solib_svr4_pspace_data;
+static const registry<program_space>::key<svr4_info> solib_svr4_pspace_data;
 
 /* Free the probes table.  */
 
@@ -428,11 +428,14 @@ read_program_header (int type, int *p_arch_size, CORE_ADDR *base_addr)
   int pt_phdr_p = 0;
 
   /* Get required auxv elements from target.  */
-  if (target_auxv_search (current_top_target (), AT_PHDR, &at_phdr) <= 0)
+  if (target_auxv_search (current_inferior ()->top_target (),
+                         AT_PHDR, &at_phdr) <= 0)
     return {};
-  if (target_auxv_search (current_top_target (), AT_PHENT, &at_phent) <= 0)
+  if (target_auxv_search (current_inferior ()->top_target (),
+                         AT_PHENT, &at_phent) <= 0)
     return {};
-  if (target_auxv_search (current_top_target (), AT_PHNUM, &at_phnum) <= 0)
+  if (target_auxv_search (current_inferior ()->top_target (),
+                         AT_PHNUM, &at_phnum) <= 0)
     return {};
   if (!at_phdr || !at_phnum)
     return {};
@@ -554,20 +557,22 @@ read_program_header (int type, int *p_arch_size, CORE_ADDR *base_addr)
 static gdb::optional<gdb::byte_vector>
 find_program_interpreter (void)
 {
-  /* If we have an exec_bfd, use its section table.  */
-  if (exec_bfd
-      && bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
+  /* If we have a current exec_bfd, use its section table.  */
+  if (current_program_space->exec_bfd ()
+      && (bfd_get_flavour (current_program_space->exec_bfd ())
+         == bfd_target_elf_flavour))
    {
      struct bfd_section *interp_sect;
 
-     interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+     interp_sect = bfd_get_section_by_name (current_program_space->exec_bfd (),
+                                           ".interp");
      if (interp_sect != NULL)
       {
        int sect_size = bfd_section_size (interp_sect);
 
        gdb::byte_vector buf (sect_size);
-       bfd_get_section_contents (exec_bfd, interp_sect, buf.data (), 0,
-                                 sect_size);
+       bfd_get_section_contents (current_program_space->exec_bfd (),
+                                 interp_sect, buf.data (), 0, sect_size);
        return buf;
       }
    }
@@ -577,108 +582,6 @@ find_program_interpreter (void)
 }
 
 
-/* Scan for DESIRED_DYNTAG in .dynamic section of ABFD.  If DESIRED_DYNTAG is
-   found, 1 is returned and the corresponding PTR is set.  */
-
-static int
-scan_dyntag (const int desired_dyntag, bfd *abfd, CORE_ADDR *ptr,
-            CORE_ADDR *ptr_addr)
-{
-  int arch_size, step, sect_size;
-  long current_dyntag;
-  CORE_ADDR dyn_ptr, dyn_addr;
-  gdb_byte *bufend, *bufstart, *buf;
-  Elf32_External_Dyn *x_dynp_32;
-  Elf64_External_Dyn *x_dynp_64;
-  struct bfd_section *sect;
-  struct target_section *target_section;
-
-  if (abfd == NULL)
-    return 0;
-
-  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
-    return 0;
-
-  arch_size = bfd_get_arch_size (abfd);
-  if (arch_size == -1)
-    return 0;
-
-  /* Find the start address of the .dynamic section.  */
-  sect = bfd_get_section_by_name (abfd, ".dynamic");
-  if (sect == NULL)
-    return 0;
-
-  for (target_section = current_target_sections->sections;
-       target_section < current_target_sections->sections_end;
-       target_section++)
-    if (sect == target_section->the_bfd_section)
-      break;
-  if (target_section < current_target_sections->sections_end)
-    dyn_addr = target_section->addr;
-  else
-    {
-      /* ABFD may come from OBJFILE acting only as a symbol file without being
-        loaded into the target (see add_symbol_file_command).  This case is
-        such fallback to the file VMA address without the possibility of
-        having the section relocated to its actual in-memory address.  */
-
-      dyn_addr = bfd_section_vma (sect);
-    }
-
-  /* Read in .dynamic from the BFD.  We will get the actual value
-     from memory later.  */
-  sect_size = bfd_section_size (sect);
-  buf = bufstart = (gdb_byte *) alloca (sect_size);
-  if (!bfd_get_section_contents (abfd, sect,
-                                buf, 0, sect_size))
-    return 0;
-
-  /* Iterate over BUF and scan for DYNTAG.  If found, set PTR and return.  */
-  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
-                          : sizeof (Elf64_External_Dyn);
-  for (bufend = buf + sect_size;
-       buf < bufend;
-       buf += step)
-  {
-    if (arch_size == 32)
-      {
-       x_dynp_32 = (Elf32_External_Dyn *) buf;
-       current_dyntag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
-       dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
-      }
-    else
-      {
-       x_dynp_64 = (Elf64_External_Dyn *) buf;
-       current_dyntag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
-       dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
-      }
-     if (current_dyntag == DT_NULL)
-       return 0;
-     if (current_dyntag == desired_dyntag)
-       {
-        /* If requested, try to read the runtime value of this .dynamic
-           entry.  */
-        if (ptr)
-          {
-            struct type *ptr_type;
-            gdb_byte ptr_buf[8];
-            CORE_ADDR ptr_addr_1;
-
-            ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
-            ptr_addr_1 = dyn_addr + (buf - bufstart) + arch_size / 8;
-            if (target_read_memory (ptr_addr_1, ptr_buf, arch_size / 8) == 0)
-              dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
-            *ptr = dyn_ptr;
-            if (ptr_addr)
-              *ptr_addr = dyn_addr + (buf - bufstart);
-          }
-        return 1;
-       }
-  }
-
-  return 0;
-}
-
 /* Scan for DESIRED_DYNTAG in .dynamic section of the target's main executable,
    found by consulting the OS auxillary vector.  If DESIRED_DYNTAG is found, 1
    is returned and the corresponding PTR is set.  */
@@ -762,7 +665,9 @@ elf_locate_base (void)
   /* Look for DT_MIPS_RLD_MAP first.  MIPS executables use this
      instead of DT_DEBUG, although they sometimes contain an unused
      DT_DEBUG.  */
-  if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr, NULL)
+  if (gdb_bfd_scan_elf_dyntag (DT_MIPS_RLD_MAP,
+                              current_program_space->exec_bfd (),
+                              &dyn_ptr, NULL)
       || scan_dyntag_auxv (DT_MIPS_RLD_MAP, &dyn_ptr, NULL))
     {
       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
@@ -780,7 +685,9 @@ elf_locate_base (void)
   /* Then check DT_MIPS_RLD_MAP_REL.  MIPS executables now use this form
      because of needing to support PIE.  DT_MIPS_RLD_MAP will also exist
      in non-PIE.  */
-  if (scan_dyntag (DT_MIPS_RLD_MAP_REL, exec_bfd, &dyn_ptr, &dyn_ptr_addr)
+  if (gdb_bfd_scan_elf_dyntag (DT_MIPS_RLD_MAP_REL,
+                              current_program_space->exec_bfd (),
+                              &dyn_ptr, &dyn_ptr_addr)
       || scan_dyntag_auxv (DT_MIPS_RLD_MAP_REL, &dyn_ptr, &dyn_ptr_addr))
     {
       struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
@@ -796,15 +703,17 @@ elf_locate_base (void)
     }
 
   /* Find DT_DEBUG.  */
-  if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr, NULL)
+  if (gdb_bfd_scan_elf_dyntag (DT_DEBUG, current_program_space->exec_bfd (),
+                              &dyn_ptr, NULL)
       || scan_dyntag_auxv (DT_DEBUG, &dyn_ptr, NULL))
     return dyn_ptr;
 
   /* This may be a static executable.  Look for the symbol
      conventionally named _r_debug, as a last resort.  */
-  msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile);
+  msymbol = lookup_minimal_symbol ("_r_debug", NULL,
+                                  current_program_space->symfile_object_file);
   if (msymbol.minsym != NULL)
-    return BMSYMBOL_VALUE_ADDRESS (msymbol);
+    return msymbol.value_address ();
 
   /* DT_DEBUG entry not found.  */
   return 0;
@@ -867,7 +776,7 @@ solib_svr4_r_map (struct svr4_info *info)
   try
     {
       addr = read_memory_typed_address (info->debug_base + lmo->r_map_offset,
-                                        ptr_type);
+                                       ptr_type);
     }
   catch (const gdb_exception_error &ex)
     {
@@ -957,8 +866,6 @@ static int
 open_symbol_file_object (int from_tty)
 {
   CORE_ADDR lm, l_name;
-  gdb::unique_xmalloc_ptr<char> filename;
-  int errcode;
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
   struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
   int l_name_size = TYPE_LENGTH (ptr_type);
@@ -969,7 +876,7 @@ open_symbol_file_object (int from_tty)
   if (from_tty)
     add_flags |= SYMFILE_VERBOSE;
 
-  if (symfile_objfile)
+  if (current_program_space->symfile_object_file)
     if (!query (_("Attempt to reload symbols from process? ")))
       return 0;
 
@@ -993,12 +900,12 @@ open_symbol_file_object (int from_tty)
     return 0;          /* No filename.  */
 
   /* Now fetch the filename from target memory.  */
-  target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+  gdb::unique_xmalloc_ptr<char> filename
+    = target_read_string (l_name, SO_NAME_MAX_PATH_SIZE - 1);
 
-  if (errcode)
+  if (filename == nullptr)
     {
-      warning (_("failed to read exec filename from attached file: %s"),
-              safe_strerror (errcode));
+      warning (_("failed to read exec filename from attached file"));
       return 0;
     }
 
@@ -1235,7 +1142,8 @@ svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list,
 
   /* Fetch the list of shared libraries.  */
   gdb::optional<gdb::char_vector> svr4_library_document
-    = target_read_stralloc (current_top_target (), TARGET_OBJECT_LIBRARIES_SVR4,
+    = target_read_stralloc (current_inferior ()->top_target (),
+                           TARGET_OBJECT_LIBRARIES_SVR4,
                            annex);
   if (!svr4_library_document)
     return 0;
@@ -1297,9 +1205,6 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
 
   for (; lm != 0; prev_lm = lm, lm = next_lm)
     {
-      int errcode;
-      gdb::unique_xmalloc_ptr<char> buffer;
-
       so_list_up newobj (XCNEW (struct so_list));
 
       lm_info_svr4 *li = lm_info_read (lm).release ();
@@ -1318,10 +1223,10 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
        }
 
       /* For SVR4 versions, the first entry in the link map is for the
-         inferior executable, so we must ignore it.  For some versions of
-         SVR4, it has no name.  For others (Solaris 2.3 for example), it
-         does have a name, so we can no longer use a missing name to
-         decide when to ignore it.  */
+        inferior executable, so we must ignore it.  For some versions of
+        SVR4, it has no name.  For others (Solaris 2.3 for example), it
+        does have a name, so we can no longer use a missing name to
+        decide when to ignore it.  */
       if (ignore_first && li->l_prev == 0)
        {
          first_l_name = li->l_name;
@@ -1330,17 +1235,16 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
        }
 
       /* Extract this shared object's name.  */
-      target_read_string (li->l_name, &buffer, SO_NAME_MAX_PATH_SIZE - 1,
-                         &errcode);
-      if (errcode != 0)
+      gdb::unique_xmalloc_ptr<char> buffer
+       = target_read_string (li->l_name, SO_NAME_MAX_PATH_SIZE - 1);
+      if (buffer == nullptr)
        {
          /* If this entry's l_name address matches that of the
             inferior executable, then this is not a normal shared
             object, but (most likely) a vDSO.  In this case, silently
             skip it; otherwise emit a warning. */
          if (first_l_name == 0 || li->l_name != first_l_name)
-           warning (_("Can't read pathname for load map: %s."),
-                    safe_strerror (errcode));
+           warning (_("Can't read pathname for load map."));
          continue;
        }
 
@@ -1405,7 +1309,9 @@ svr4_current_sos_direct (struct svr4_info *info)
 
   /* Assume that everything is a library if the dynamic loader was loaded
      late by a static executable.  */
-  if (exec_bfd && bfd_get_section_by_name (exec_bfd, ".dynamic") == NULL)
+  if (current_program_space->exec_bfd ()
+      && bfd_get_section_by_name (current_program_space->exec_bfd (),
+                                 ".dynamic") == NULL)
     ignore_first = 0;
   else
     ignore_first = 1;
@@ -1544,14 +1450,9 @@ svr4_fetch_objfile_link_map (struct objfile *objfile)
     solib_add (NULL, 0, auto_solib_add);
 
   /* svr4_current_sos() will set main_lm_addr for the main executable.  */
-  if (objfile == symfile_objfile)
+  if (objfile == current_program_space->symfile_object_file)
     return info->main_lm_addr;
 
-  /* If OBJFILE is a separate debug object file, look for the
-     original object file.  */
-  if (objfile->separate_debug_objfile_backlink != NULL)
-    objfile = objfile->separate_debug_objfile_backlink;
-
   /* The other link map addresses may be found by examining the list
      of shared libraries.  */
   for (struct so_list *so : current_program_space->solibs ())
@@ -2013,15 +1914,13 @@ svr4_handle_solib_event (void)
 static bool
 svr4_update_solib_event_breakpoint (struct breakpoint *b)
 {
-  struct bp_location *loc;
-
   if (b->type != bp_shlib_event)
     {
       /* Continue iterating.  */
       return false;
     }
 
-  for (loc = b->loc; loc != NULL; loc = loc->next)
+  for (bp_location *loc : b->locations ())
     {
       struct svr4_info *info;
       struct probe_and_action *pa;
@@ -2055,7 +1954,8 @@ svr4_update_solib_event_breakpoint (struct breakpoint *b)
 static void
 svr4_update_solib_event_breakpoints (void)
 {
-  iterate_over_breakpoints (svr4_update_solib_event_breakpoint);
+  for (breakpoint *bp : all_breakpoints_safe ())
+    svr4_update_solib_event_breakpoint (bp);
 }
 
 /* Create and register solib event breakpoints.  PROBES is an array
@@ -2240,9 +2140,8 @@ enable_break (struct svr4_info *info, int from_tty)
 
       sym_addr = gdbarch_addr_bits_remove
        (target_gdbarch (),
-        gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
-                                            sym_addr,
-                                            current_top_target ()));
+        gdbarch_convert_from_func_ptr_addr
+          (target_gdbarch (), sym_addr, current_inferior ()->top_target ()));
 
       /* On at least some versions of Solaris there's a dynamic relocation
         on _r_debug.r_brk and SYM_ADDR may not be relocated yet, e.g., if
@@ -2271,7 +2170,7 @@ enable_break (struct svr4_info *info, int from_tty)
          bfd *tmp_bfd;
          CORE_ADDR load_addr;
 
-         tmp_bfd = os->objfile->obfd;
+         tmp_bfd = os->objfile->obfd.get ();
          load_addr = os->objfile->text_section_offset ();
 
          interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
@@ -2311,17 +2210,17 @@ enable_break (struct svr4_info *info, int from_tty)
       sym_addr = 0;
 
       /* Now we need to figure out where the dynamic linker was
-         loaded so that we can load its symbols and place a breakpoint
-         in the dynamic linker itself.
+        loaded so that we can load its symbols and place a breakpoint
+        in the dynamic linker itself.
 
-         This address is stored on the stack.  However, I've been unable
-         to find any magic formula to find it for Solaris (appears to
-         be trivial on GNU/Linux).  Therefore, we have to try an alternate
-         mechanism to find the dynamic linker's base address.  */
+        This address is stored on the stack.  However, I've been unable
+        to find any magic formula to find it for Solaris (appears to
+        be trivial on GNU/Linux).  Therefore, we have to try an alternate
+        mechanism to find the dynamic linker's base address.  */
 
       gdb_bfd_ref_ptr tmp_bfd;
       try
-        {
+       {
          tmp_bfd = solib_bfd_open (interp_name);
        }
       catch (const gdb_exception &ex)
@@ -2332,12 +2231,11 @@ enable_break (struct svr4_info *info, int from_tty)
        goto bkpt_at_symbol;
 
       /* Now convert the TMP_BFD into a target.  That way target, as
-         well as BFD operations can be used.  target_bfd_reopen
-         acquires its own reference.  */
-      tmp_bfd_target = target_bfd_reopen (tmp_bfd.get ());
+        well as BFD operations can be used.  */
+      tmp_bfd_target = target_bfd_reopen (tmp_bfd);
 
       /* On a running target, we can get the dynamic linker's base
-         address from the shared library table.  */
+        address from the shared library table.  */
       for (struct so_list *so : current_program_space->solibs ())
        {
          if (svr4_same_1 (interp_name, so->so_original_name))
@@ -2350,9 +2248,10 @@ enable_break (struct svr4_info *info, int from_tty)
        }
 
       /* If we were not able to find the base address of the loader
-         from our so_list, then try using the AT_BASE auxilliary entry.  */
+        from our so_list, then try using the AT_BASE auxilliary entry.  */
       if (!load_addr_found)
-       if (target_auxv_search (current_top_target (), AT_BASE, &load_addr) > 0)
+       if (target_auxv_search (current_inferior ()->top_target (),
+                               AT_BASE, &load_addr) > 0)
          {
            int addr_bit = gdbarch_addr_bit (target_gdbarch ());
 
@@ -2384,9 +2283,9 @@ enable_break (struct svr4_info *info, int from_tty)
         the current pc (which should point at the entry point for the
         dynamic linker) and subtracting the offset of the entry point.
 
-         This is more fragile than the previous approaches, but is a good
-         fallback method because it has actually been working well in
-         most cases.  */
+        This is more fragile than the previous approaches, but is a good
+        fallback method because it has actually been working well in
+        most cases.  */
       if (!load_addr_found)
        {
          struct regcache *regcache
@@ -2406,7 +2305,7 @@ enable_break (struct svr4_info *info, int from_tty)
        }
 
       /* Record the relocated start and end address of the dynamic linker
-         text and plt section for svr4_in_dynsym_resolve_code.  */
+        text and plt section for svr4_in_dynsym_resolve_code.  */
       interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text");
       if (interp_sect)
        {
@@ -2443,8 +2342,8 @@ enable_break (struct svr4_info *info, int from_tty)
                                                       tmp_bfd_target);
 
       /* We're done with both the temporary bfd and target.  Closing
-         the target closes the underlying bfd, because it holds the
-         only remaining reference.  */
+        the target closes the underlying bfd, because it holds the
+        only remaining reference.  */
       target_close (tmp_bfd_target);
 
       if (sym_addr != 0)
@@ -2455,26 +2354,26 @@ enable_break (struct svr4_info *info, int from_tty)
        }
 
       /* For whatever reason we couldn't set a breakpoint in the dynamic
-         linker.  Warn and drop into the old code.  */
+        linker.  Warn and drop into the old code.  */
     bkpt_at_symbol:
       warning (_("Unable to find dynamic linker breakpoint function.\n"
-               "GDB will be unable to debug shared library initializers\n"
-               "and track explicitly loaded dynamic code."));
+              "GDB will be unable to debug shared library initializers\n"
+              "and track explicitly loaded dynamic code."));
     }
 
   /* Scan through the lists of symbols, trying to look up the symbol and
      set a breakpoint there.  Terminate loop when we/if we succeed.  */
 
+  objfile *objf = current_program_space->symfile_object_file;
   for (bkpt_namep = solib_break_names; *bkpt_namep != NULL; bkpt_namep++)
     {
-      msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
+      msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, objf);
       if ((msymbol.minsym != NULL)
-         && (BMSYMBOL_VALUE_ADDRESS (msymbol) != 0))
+         && (msymbol.value_address () != 0))
        {
-         sym_addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
-         sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
-                                                        sym_addr,
-                                                        current_top_target ());
+         sym_addr = msymbol.value_address ();
+         sym_addr = gdbarch_convert_from_func_ptr_addr
+           (target_gdbarch (), sym_addr, current_inferior ()->top_target ());
          svr4_create_solib_event_breakpoints (info, target_gdbarch (),
                                               sym_addr);
          return 1;
@@ -2485,14 +2384,14 @@ enable_break (struct svr4_info *info, int from_tty)
     {
       for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++)
        {
-         msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, symfile_objfile);
+         msymbol = lookup_minimal_symbol (*bkpt_namep, NULL, objf);
          if ((msymbol.minsym != NULL)
-             && (BMSYMBOL_VALUE_ADDRESS (msymbol) != 0))
+             && (msymbol.value_address () != 0))
            {
-             sym_addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
-             sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
-                                                            sym_addr,
-                                                            current_top_target ());
+             sym_addr = msymbol.value_address ();
+             sym_addr = gdbarch_convert_from_func_ptr_addr
+               (target_gdbarch (), sym_addr,
+                current_inferior ()->top_target ());
              svr4_create_solib_event_breakpoints (info, target_gdbarch (),
                                                   sym_addr);
              return 1;
@@ -2570,27 +2469,31 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
      a call to gdbarch_convert_from_func_ptr_addr.  */
   CORE_ADDR entry_point, exec_displacement;
 
-  if (exec_bfd == NULL)
+  if (current_program_space->exec_bfd () == NULL)
     return 0;
 
   /* Therefore for ELF it is ET_EXEC and not ET_DYN.  Both shared libraries
      being executed themselves and PIE (Position Independent Executable)
      executables are ET_DYN.  */
 
-  if ((bfd_get_file_flags (exec_bfd) & DYNAMIC) == 0)
+  if ((bfd_get_file_flags (current_program_space->exec_bfd ()) & DYNAMIC) == 0)
     return 0;
 
-  if (target_auxv_search (current_top_target (), AT_ENTRY, &entry_point) <= 0)
+  if (target_auxv_search (current_inferior ()->top_target (),
+                         AT_ENTRY, &entry_point) <= 0)
     return 0;
 
-  exec_displacement = entry_point - bfd_get_start_address (exec_bfd);
+  exec_displacement
+    = entry_point - bfd_get_start_address (current_program_space->exec_bfd ());
 
   /* Verify the EXEC_DISPLACEMENT candidate complies with the required page
      alignment.  It is cheaper than the program headers comparison below.  */
 
-  if (bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
+  if (bfd_get_flavour (current_program_space->exec_bfd ())
+      == bfd_target_elf_flavour)
     {
-      const struct elf_backend_data *elf = get_elf_backend_data (exec_bfd);
+      const struct elf_backend_data *elf
+       = get_elf_backend_data (current_program_space->exec_bfd ());
 
       /* p_align of PT_LOAD segments does not specify any alignment but
         only congruency of addresses:
@@ -2607,7 +2510,8 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
      looking at a different file than the one used by the kernel - for
      instance, "gdb program" connected to "gdbserver :PORT ld.so program".  */
 
-  if (bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
+  if (bfd_get_flavour (current_program_space->exec_bfd ())
+      == bfd_target_elf_flavour)
     {
       /* Be optimistic and return 0 only if GDB was able to verify the headers
         really do not match.  */
@@ -2616,7 +2520,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
       gdb::optional<gdb::byte_vector> phdrs_target
        = read_program_header (-1, &arch_size, NULL);
       gdb::optional<gdb::byte_vector> phdrs_binary
-       = read_program_headers_from_bfd (exec_bfd);
+       = read_program_headers_from_bfd (current_program_space->exec_bfd ());
       if (phdrs_target && phdrs_binary)
        {
          enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
@@ -2635,14 +2539,16 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
             content offset for the verification purpose.  */
 
          if (phdrs_target->size () != phdrs_binary->size ()
-             || bfd_get_arch_size (exec_bfd) != arch_size)
+             || bfd_get_arch_size (current_program_space->exec_bfd ()) != arch_size)
            return 0;
          else if (arch_size == 32
                   && phdrs_target->size () >= sizeof (Elf32_External_Phdr)
-                  && phdrs_target->size () % sizeof (Elf32_External_Phdr) == 0)
+                  && phdrs_target->size () % sizeof (Elf32_External_Phdr) == 0)
            {
-             Elf_Internal_Ehdr *ehdr2 = elf_tdata (exec_bfd)->elf_header;
-             Elf_Internal_Phdr *phdr2 = elf_tdata (exec_bfd)->phdr;
+             Elf_Internal_Ehdr *ehdr2
+               = elf_tdata (current_program_space->exec_bfd ())->elf_header;
+             Elf_Internal_Phdr *phdr2
+               = elf_tdata (current_program_space->exec_bfd ())->phdr;
              CORE_ADDR displacement = 0;
              int i;
 
@@ -2679,7 +2585,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
                  }
 
              /* Now compare program headers from the target and the binary
-                with optional DISPLACEMENT.  */
+                with optional DISPLACEMENT.  */
 
              for (i = 0;
                   i < phdrs_target->size () / sizeof (Elf32_External_Phdr);
@@ -2742,6 +2648,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
                    }
 
                  /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS.  */
+                 bfd *exec_bfd = current_program_space->exec_bfd ();
                  plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
                  if (plt2_asect)
                    {
@@ -2774,10 +2681,12 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
            }
          else if (arch_size == 64
                   && phdrs_target->size () >= sizeof (Elf64_External_Phdr)
-                  && phdrs_target->size () % sizeof (Elf64_External_Phdr) == 0)
+                  && phdrs_target->size () % sizeof (Elf64_External_Phdr) == 0)
            {
-             Elf_Internal_Ehdr *ehdr2 = elf_tdata (exec_bfd)->elf_header;
-             Elf_Internal_Phdr *phdr2 = elf_tdata (exec_bfd)->phdr;
+             Elf_Internal_Ehdr *ehdr2
+               = elf_tdata (current_program_space->exec_bfd ())->elf_header;
+             Elf_Internal_Phdr *phdr2
+               = elf_tdata (current_program_space->exec_bfd ())->phdr;
              CORE_ADDR displacement = 0;
              int i;
 
@@ -2876,7 +2785,9 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
                    }
 
                  /* prelink can convert .plt SHT_NOBITS to SHT_PROGBITS.  */
-                 plt2_asect = bfd_get_section_by_name (exec_bfd, ".plt");
+                 plt2_asect
+                   = bfd_get_section_by_name (current_program_space->exec_bfd (),
+                                              ".plt");
                  if (plt2_asect)
                    {
                      int content2;
@@ -2889,8 +2800,9 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
                      filesz = extract_unsigned_integer (buf_filesz_p, 8,
                                                         byte_order);
 
-                     /* PLT2_ASECT is from on-disk file (exec_bfd) while
-                        FILESZ is from the in-memory image.  */
+                     /* PLT2_ASECT is from on-disk file (current
+                        exec_bfd) while FILESZ is from the in-memory
+                        image.  */
                      if (content2)
                        filesz += bfd_section_size (plt2_asect);
                      else
@@ -2917,10 +2829,10 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
         the executable symbols/file has been already relocated to
         displacement.  */
 
-      printf_unfiltered (_("Using PIE (Position Independent Executable) "
-                          "displacement %s for \"%s\".\n"),
-                        paddress (target_gdbarch (), exec_displacement),
-                        bfd_get_filename (exec_bfd));
+      gdb_printf (_("Using PIE (Position Independent Executable) "
+                   "displacement %s for \"%s\".\n"),
+                 paddress (target_gdbarch (), exec_displacement),
+                 bfd_get_filename (current_program_space->exec_bfd ()));
     }
 
   *displacementp = exec_displacement;
@@ -2969,16 +2881,18 @@ svr4_relocate_main_executable (void)
   /* Even DISPLACEMENT 0 is a valid new difference of in-memory vs. in-file
      addresses.  */
 
-  if (symfile_objfile)
+  objfile *objf = current_program_space->symfile_object_file;
+  if (objf)
     {
-      section_offsets new_offsets (symfile_objfile->section_offsets.size (),
+      section_offsets new_offsets (objf->section_offsets.size (),
                                   displacement);
-      objfile_relocate (symfile_objfile, new_offsets);
+      objfile_relocate (objf, new_offsets);
     }
-  else if (exec_bfd)
+  else if (current_program_space->exec_bfd ())
     {
       asection *asect;
 
+      bfd *exec_bfd = current_program_space->exec_bfd ();
       for (asect = exec_bfd->sections; asect != NULL; asect = asect->next)
        exec_set_section_address (bfd_get_filename (exec_bfd), asect->index,
                                  bfd_section_vma (asect) + displacement);
@@ -3020,7 +2934,7 @@ svr4_solib_create_inferior_hook (int from_tty)
 
   /* No point setting a breakpoint in the dynamic linker if we can't
      hit it (e.g., a core file, or a trace file).  */
-  if (!target_has_execution)
+  if (!target_has_execution ())
     return;
 
   if (!svr4_have_link_map_offsets ())
@@ -3070,7 +2984,7 @@ svr4_truncate_ptr (CORE_ADDR addr)
 
 static void
 svr4_relocate_section_addresses (struct so_list *so,
-                                 struct target_section *sec)
+                                struct target_section *sec)
 {
   bfd *abfd = sec->the_bfd_section->owner;
 
@@ -3081,24 +2995,23 @@ svr4_relocate_section_addresses (struct so_list *so,
 
 /* Architecture-specific operations.  */
 
-/* Per-architecture data key.  */
-static struct gdbarch_data *solib_svr4_data;
-
 struct solib_svr4_ops
 {
   /* Return a description of the layout of `struct link_map'.  */
-  struct link_map_offsets *(*fetch_link_map_offsets)(void);
+  struct link_map_offsets *(*fetch_link_map_offsets)(void) = nullptr;
 };
 
+/* Per-architecture data key.  */
+static const registry<gdbarch>::key<struct solib_svr4_ops> solib_svr4_data;
+
 /* Return a default for the architecture-specific operations.  */
 
-static void *
-solib_svr4_init (struct obstack *obstack)
+static struct solib_svr4_ops *
+get_ops (struct gdbarch *gdbarch)
 {
-  struct solib_svr4_ops *ops;
-
-  ops = OBSTACK_ZALLOC (obstack, struct solib_svr4_ops);
-  ops->fetch_link_map_offsets = NULL;
+  struct solib_svr4_ops *ops = solib_svr4_data.get (gdbarch);
+  if (ops == nullptr)
+    ops = solib_svr4_data.emplace (gdbarch);
   return ops;
 }
 
@@ -3107,14 +3020,13 @@ solib_svr4_init (struct obstack *obstack)
 
 void
 set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
-                                       struct link_map_offsets *(*flmo) (void))
+                                      struct link_map_offsets *(*flmo) (void))
 {
-  struct solib_svr4_ops *ops
-    = (struct solib_svr4_ops *) gdbarch_data (gdbarch, solib_svr4_data);
+  struct solib_svr4_ops *ops = get_ops (gdbarch);
 
   ops->fetch_link_map_offsets = flmo;
 
-  set_solib_ops (gdbarch, &svr4_so_ops);
+  set_gdbarch_so_ops (gdbarch, &svr4_so_ops);
   set_gdbarch_iterate_over_objfiles_in_search_order
     (gdbarch, svr4_iterate_over_objfiles_in_search_order);
 }
@@ -3125,9 +3037,7 @@ set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
 static struct link_map_offsets *
 svr4_fetch_link_map_offsets (void)
 {
-  struct solib_svr4_ops *ops
-    = (struct solib_svr4_ops *) gdbarch_data (target_gdbarch (),
-                                             solib_svr4_data);
+  struct solib_svr4_ops *ops = get_ops (target_gdbarch ());
 
   gdb_assert (ops->fetch_link_map_offsets);
   return ops->fetch_link_map_offsets ();
@@ -3138,9 +3048,7 @@ svr4_fetch_link_map_offsets (void)
 static int
 svr4_have_link_map_offsets (void)
 {
-  struct solib_svr4_ops *ops
-    = (struct solib_svr4_ops *) gdbarch_data (target_gdbarch (),
-                                             solib_svr4_data);
+  struct solib_svr4_ops *ops = get_ops (target_gdbarch ());
 
   return (ops->fetch_link_map_offsets != NULL);
 }
@@ -3213,17 +3121,14 @@ svr4_lp64_fetch_link_map_offsets (void)
 }
 \f
 
-struct target_so_ops svr4_so_ops;
-
 /* Search order for ELF DSOs linked with -Bsymbolic.  Those DSOs have a
    different rule for symbol lookup.  The lookup begins here in the DSO, not in
    the main executable.  */
 
 static void
 svr4_iterate_over_objfiles_in_search_order
-  (struct gdbarch *gdbarch,
-   iterate_over_objfiles_in_search_order_cb_ftype *cb,
-   void *cb_data, struct objfile *current_objfile)
+  (gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype cb,
+   objfile *current_objfile)
 {
   bool checked_current_objfile = false;
   if (current_objfile != nullptr)
@@ -3231,18 +3136,18 @@ svr4_iterate_over_objfiles_in_search_order
       bfd *abfd;
 
       if (current_objfile->separate_debug_objfile_backlink != nullptr)
-        current_objfile = current_objfile->separate_debug_objfile_backlink;
+       current_objfile = current_objfile->separate_debug_objfile_backlink;
 
-      if (current_objfile == symfile_objfile)
-       abfd = exec_bfd;
+      if (current_objfile == current_program_space->symfile_object_file)
+       abfd = current_program_space->exec_bfd ();
       else
-       abfd = current_objfile->obfd;
+       abfd = current_objfile->obfd.get ();
 
       if (abfd != nullptr
-         && scan_dyntag (DT_SYMBOLIC, abfd, nullptr, nullptr) == 1)
+         && gdb_bfd_scan_elf_dyntag (DT_SYMBOLIC, abfd, nullptr, nullptr) == 1)
        {
          checked_current_objfile = true;
-         if (cb (current_objfile, cb_data) != 0)
+         if (cb (current_objfile))
            return;
        }
     }
@@ -3251,30 +3156,33 @@ svr4_iterate_over_objfiles_in_search_order
     {
       if (checked_current_objfile && objfile == current_objfile)
        continue;
-      if (cb (objfile, cb_data) != 0)
+      if (cb (objfile))
        return;
     }
 }
 
+const struct target_so_ops svr4_so_ops =
+{
+  svr4_relocate_section_addresses,
+  svr4_free_so,
+  svr4_clear_so,
+  svr4_clear_solib,
+  svr4_solib_create_inferior_hook,
+  svr4_current_sos,
+  open_symbol_file_object,
+  svr4_in_dynsym_resolve_code,
+  solib_bfd_open,
+  nullptr,
+  svr4_same,
+  svr4_keep_data_in_core,
+  svr4_update_solib_event_breakpoints,
+  svr4_handle_solib_event,
+};
+
 void _initialize_svr4_solib ();
 void
 _initialize_svr4_solib ()
 {
-  solib_svr4_data = gdbarch_data_register_pre_init (solib_svr4_init);
-
-  svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses;
-  svr4_so_ops.free_so = svr4_free_so;
-  svr4_so_ops.clear_so = svr4_clear_so;
-  svr4_so_ops.clear_solib = svr4_clear_solib;
-  svr4_so_ops.solib_create_inferior_hook = svr4_solib_create_inferior_hook;
-  svr4_so_ops.current_sos = svr4_current_sos;
-  svr4_so_ops.open_symbol_file_object = open_symbol_file_object;
-  svr4_so_ops.in_dynsym_resolve_code = svr4_in_dynsym_resolve_code;
-  svr4_so_ops.bfd_open = solib_bfd_open;
-  svr4_so_ops.same = svr4_same;
-  svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core;
-  svr4_so_ops.update_breakpoints = svr4_update_solib_event_breakpoints;
-  svr4_so_ops.handle_event = svr4_handle_solib_event;
-
-  gdb::observers::free_objfile.attach (svr4_free_objfile_observer);
+  gdb::observers::free_objfile.attach (svr4_free_objfile_observer,
+                                      "solib-svr4");
 }