]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/solib-frv.c
Remove unnecessary block from execute_fn_to_ui_file
[thirdparty/binutils-gdb.git] / gdb / solib-frv.c
index d2594403adbf62e0d18dcc9328a6e27176422846..39508fab4c8310c96332e06cec2910e3baa08bd2 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger.
-   Copyright (C) 2004, 2007-2012 Free Software Foundation, Inc.
+   Copyright (C) 2004-2024 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
-#include "defs.h"
-#include "gdb_string.h"
-#include "inferior.h"
+#include "extract-store-integer.h"
 #include "gdbcore.h"
 #include "solib.h"
 #include "solist.h"
 #include "frv-tdep.h"
 #include "objfiles.h"
 #include "symtab.h"
-#include "language.h"
-#include "command.h"
-#include "gdbcmd.h"
 #include "elf/frv.h"
-#include "exceptions.h"
 #include "gdb_bfd.h"
-
-/* Flag which indicates whether internal debug messages should be printed.  */
-static unsigned int solib_frv_debug;
+#include "inferior.h"
 
 /* FR-V pointers are four bytes wide.  */
 enum { FRV_PTR_SIZE = 4 };
@@ -98,7 +90,7 @@ struct int_elf32_fdpic_loadmap {
 static struct int_elf32_fdpic_loadmap *
 fetch_loadmap (CORE_ADDR ldmaddr)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+  bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   struct ext_elf32_fdpic_loadmap ext_ldmbuf_partial;
   struct ext_elf32_fdpic_loadmap *ext_ldmbuf;
   struct int_elf32_fdpic_loadmap *int_ldmbuf;
@@ -107,7 +99,7 @@ fetch_loadmap (CORE_ADDR ldmaddr)
 
   /* Fetch initial portion of the loadmap.  */
   if (target_read_memory (ldmaddr, (gdb_byte *) &ext_ldmbuf_partial,
-                          sizeof ext_ldmbuf_partial))
+                         sizeof ext_ldmbuf_partial))
     {
       /* Problem reading the target's memory.  */
       return NULL;
@@ -115,7 +107,7 @@ fetch_loadmap (CORE_ADDR ldmaddr)
 
   /* Extract the version.  */
   version = extract_unsigned_integer (ext_ldmbuf_partial.version,
-                                      sizeof ext_ldmbuf_partial.version,
+                                     sizeof ext_ldmbuf_partial.version,
                                      byte_order);
   if (version != 0)
     {
@@ -125,7 +117,7 @@ fetch_loadmap (CORE_ADDR ldmaddr)
 
   /* Extract the number of segments.  */
   nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs,
-                                    sizeof ext_ldmbuf_partial.nsegs,
+                                   sizeof ext_ldmbuf_partial.nsegs,
                                    byte_order);
 
   if (nsegs <= 0)
@@ -133,16 +125,16 @@ fetch_loadmap (CORE_ADDR ldmaddr)
 
   /* Allocate space for the complete (external) loadmap.  */
   ext_ldmbuf_size = sizeof (struct ext_elf32_fdpic_loadmap)
-               + (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg);
-  ext_ldmbuf = xmalloc (ext_ldmbuf_size);
+              + (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg);
+  ext_ldmbuf = (struct ext_elf32_fdpic_loadmap *) xmalloc (ext_ldmbuf_size);
 
   /* Copy over the portion of the loadmap that's already been read.  */
   memcpy (ext_ldmbuf, &ext_ldmbuf_partial, sizeof ext_ldmbuf_partial);
 
   /* Read the rest of the loadmap from the target.  */
   if (target_read_memory (ldmaddr + sizeof ext_ldmbuf_partial,
-                          (gdb_byte *) ext_ldmbuf + sizeof ext_ldmbuf_partial,
-                          ext_ldmbuf_size - sizeof ext_ldmbuf_partial))
+                         (gdb_byte *) ext_ldmbuf + sizeof ext_ldmbuf_partial,
+                         ext_ldmbuf_size - sizeof ext_ldmbuf_partial))
     {
       /* Couldn't read rest of the loadmap.  */
       xfree (ext_ldmbuf);
@@ -152,8 +144,8 @@ fetch_loadmap (CORE_ADDR ldmaddr)
   /* Allocate space into which to put information extract from the
      external loadsegs.  I.e, allocate the internal loadsegs.  */
   int_ldmbuf_size = sizeof (struct int_elf32_fdpic_loadmap)
-               + (nsegs - 1) * sizeof (struct int_elf32_fdpic_loadseg);
-  int_ldmbuf = xmalloc (int_ldmbuf_size);
+              + (nsegs - 1) * sizeof (struct int_elf32_fdpic_loadseg);
+  int_ldmbuf = (struct int_elf32_fdpic_loadmap *) xmalloc (int_ldmbuf_size);
 
   /* Place extracted information in internal structs.  */
   int_ldmbuf->version = version;
@@ -162,15 +154,15 @@ fetch_loadmap (CORE_ADDR ldmaddr)
     {
       int_ldmbuf->segs[seg].addr
        = extract_unsigned_integer (ext_ldmbuf->segs[seg].addr,
-                                   sizeof (ext_ldmbuf->segs[seg].addr),
+                                   sizeof (ext_ldmbuf->segs[seg].addr),
                                    byte_order);
       int_ldmbuf->segs[seg].p_vaddr
        = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_vaddr,
-                                   sizeof (ext_ldmbuf->segs[seg].p_vaddr),
+                                   sizeof (ext_ldmbuf->segs[seg].p_vaddr),
                                    byte_order);
       int_ldmbuf->segs[seg].p_memsz
        = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz,
-                                   sizeof (ext_ldmbuf->segs[seg].p_memsz),
+                                   sizeof (ext_ldmbuf->segs[seg].p_memsz),
                                    byte_order);
     }
 
@@ -204,45 +196,51 @@ struct ext_link_map
 
 /* Link map info to include in an allocated so_list entry.  */
 
-struct lm_info
+struct lm_info_frv final : public lm_info
+{
+  ~lm_info_frv ()
   {
-    /* The loadmap, digested into an easier to use form.  */
-    struct int_elf32_fdpic_loadmap *map;
-    /* The GOT address for this link map entry.  */
-    CORE_ADDR got_value;
-    /* The link map address, needed for frv_fetch_objfile_link_map().  */
-    CORE_ADDR lm_addr;
-
-    /* Cached dynamic symbol table and dynamic relocs initialized and
-       used only by find_canonical_descriptor_in_load_object().
-
-       Note: kevinb/2004-02-26: It appears that calls to
-       bfd_canonicalize_dynamic_reloc() will use the same symbols as
-       those supplied to the first call to this function.  Therefore,
-       it's important to NOT free the asymbol ** data structure
-       supplied to the first call.  Thus the caching of the dynamic
-       symbols (dyn_syms) is critical for correct operation.  The
-       caching of the dynamic relocations could be dispensed with.  */
-    asymbol **dyn_syms;
-    arelent **dyn_relocs;
-    int dyn_reloc_count;       /* Number of dynamic relocs.  */
-
-  };
+    xfree (this->map);
+    xfree (this->dyn_syms);
+    xfree (this->dyn_relocs);
+  }
+
+  /* The loadmap, digested into an easier to use form.  */
+  int_elf32_fdpic_loadmap *map = NULL;
+  /* The GOT address for this link map entry.  */
+  CORE_ADDR got_value = 0;
+  /* The link map address, needed for frv_fetch_objfile_link_map().  */
+  CORE_ADDR lm_addr = 0;
+
+  /* Cached dynamic symbol table and dynamic relocs initialized and
+     used only by find_canonical_descriptor_in_load_object().
+
+     Note: kevinb/2004-02-26: It appears that calls to
+     bfd_canonicalize_dynamic_reloc() will use the same symbols as
+     those supplied to the first call to this function.  Therefore,
+     it's important to NOT free the asymbol ** data structure
+     supplied to the first call.  Thus the caching of the dynamic
+     symbols (dyn_syms) is critical for correct operation.  The
+     caching of the dynamic relocations could be dispensed with.  */
+  asymbol **dyn_syms = NULL;
+  arelent **dyn_relocs = NULL;
+  int dyn_reloc_count = 0;     /* Number of dynamic relocs.  */
+};
 
 /* The load map, got value, etc. are not available from the chain
    of loaded shared objects.  ``main_executable_lm_info'' provides
    a way to get at this information so that it doesn't need to be
    frequently recomputed.  Initialized by frv_relocate_main_executable().  */
-static struct lm_info *main_executable_lm_info;
+static lm_info_frv *main_executable_lm_info;
 
 static void frv_relocate_main_executable (void);
 static CORE_ADDR main_got (void);
 static int enable_break2 (void);
 
-/* Implement the "open_symbol_file_object" target_so_ops method.  */
+/* Implement the "open_symbol_file_object" solib_ops method.  */
 
 static int
-open_symbol_file_object (void *from_ttyp)
+open_symbol_file_object (int from_tty)
 {
   /* Unimplemented.  */
   return 0;
@@ -265,8 +263,8 @@ static CORE_ADDR main_lm_addr = 0;
 static CORE_ADDR
 lm_base (void)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
-  struct minimal_symbol *got_sym;
+  bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
+  struct bound_minimal_symbol got_sym;
   CORE_ADDR addr;
   gdb_byte buf[FRV_PTR_SIZE];
 
@@ -283,44 +281,37 @@ lm_base (void)
     return lm_base_cache;
 
   got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL,
-                                   symfile_objfile);
-  if (got_sym == 0)
+                                  current_program_space->symfile_object_file);
+  if (got_sym.minsym == 0)
     {
-      if (solib_frv_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "lm_base: _GLOBAL_OFFSET_TABLE_ not found.\n");
+      solib_debug_printf ("_GLOBAL_OFFSET_TABLE_ not found.");
       return 0;
     }
 
-  addr = SYMBOL_VALUE_ADDRESS (got_sym) + 8;
+  addr = got_sym.value_address () + 8;
 
-  if (solib_frv_debug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "lm_base: _GLOBAL_OFFSET_TABLE_ + 8 = %s\n",
-                       hex_string_custom (addr, 8));
+  solib_debug_printf ("_GLOBAL_OFFSET_TABLE_ + 8 = %s",
+                     hex_string_custom (addr, 8));
 
   if (target_read_memory (addr, buf, sizeof buf) != 0)
     return 0;
   lm_base_cache = extract_unsigned_integer (buf, sizeof buf, byte_order);
 
-  if (solib_frv_debug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "lm_base: lm_base_cache = %s\n",
-                       hex_string_custom (lm_base_cache, 8));
+  solib_debug_printf ("lm_base_cache = %s",
+                     hex_string_custom (lm_base_cache, 8));
 
   return lm_base_cache;
 }
 
 
-/* Implement the "current_sos" target_so_ops method.  */
+/* Implement the "current_sos" solib_ops method.  */
 
-static struct so_list *
-frv_current_sos (void)
+static intrusive_list<solib>
+frv_current_sos ()
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+  bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   CORE_ADDR lm_addr, mgot;
-  struct so_list *sos_head = NULL;
-  struct so_list **sos_next_ptr = &sos_head;
+  intrusive_list<solib> sos;
 
   /* Make sure that the main executable has been relocated.  This is
      required in order to find the address of the global offset table,
@@ -328,13 +319,14 @@ frv_current_sos (void)
      for details.)
 
      Note that the relocation of the main executable is also performed
-     by SOLIB_CREATE_INFERIOR_HOOK(), however, in the case of core
+     by solib_create_inferior_hook(), however, in the case of core
      files, this hook is called too late in order to be of benefit to
-     SOLIB_ADD.  SOLIB_ADD eventually calls this this function,
+     solib_add.  solib_add eventually calls this this function,
      frv_current_sos, and also precedes the call to
-     SOLIB_CREATE_INFERIOR_HOOK().   (See post_create_inferior() in
+     solib_create_inferior_hook().   (See post_create_inferior() in
      infcmd.c.)  */
-  if (main_executable_lm_info == 0 && core_bfd != NULL)
+  if (main_executable_lm_info == 0
+      && current_program_space->core_bfd () != nullptr)
     frv_relocate_main_executable ();
 
   /* Fetch the GOT corresponding to the main executable.  */
@@ -350,10 +342,8 @@ frv_current_sos (void)
       struct ext_link_map lm_buf;
       CORE_ADDR got_addr;
 
-      if (solib_frv_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "current_sos: reading link_map entry at %s\n",
-                           hex_string_custom (lm_addr, 8));
+      solib_debug_printf ("reading link_map entry at %s",
+                         hex_string_custom (lm_addr, 8));
 
       if (target_read_memory (lm_addr, (gdb_byte *) &lm_buf,
                              sizeof (lm_buf)) != 0)
@@ -372,10 +362,7 @@ frv_current_sos (void)
         this in the list of shared objects.  */
       if (got_addr != mgot)
        {
-         int errcode;
-         char *name_buf;
          struct int_elf32_fdpic_loadmap *loadmap;
-         struct so_list *sop;
          CORE_ADDR addr;
 
          /* Fetch the load map address.  */
@@ -390,35 +377,29 @@ frv_current_sos (void)
              break;
            }
 
-         sop = xcalloc (1, sizeof (struct so_list));
-         sop->lm_info = xcalloc (1, sizeof (struct lm_info));
-         sop->lm_info->map = loadmap;
-         sop->lm_info->got_value = got_addr;
-         sop->lm_info->lm_addr = lm_addr;
+         solib *sop = new solib;
+         auto li = std::make_unique<lm_info_frv> ();
+         li->map = loadmap;
+         li->got_value = got_addr;
+         li->lm_addr = lm_addr;
          /* Fetch the name.  */
          addr = extract_unsigned_integer (lm_buf.l_name,
                                           sizeof (lm_buf.l_name),
                                           byte_order);
-         target_read_string (addr, &name_buf, SO_NAME_MAX_PATH_SIZE - 1,
-                             &errcode);
-
-         if (solib_frv_debug)
-           fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n",
-                               name_buf);
-         
-         if (errcode != 0)
-           warning (_("Can't read pathname for link map entry: %s."),
-                    safe_strerror (errcode));
+         gdb::unique_xmalloc_ptr<char> name_buf
+           = target_read_string (addr, SO_NAME_MAX_PATH_SIZE - 1);
+
+         solib_debug_printf ("name = %s", name_buf.get ());
+
+         if (name_buf == nullptr)
+           warning (_("Can't read pathname for link map entry."));
          else
            {
-             strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1);
-             sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
-             xfree (name_buf);
-             strcpy (sop->so_original_name, sop->so_name);
+             sop->so_name = name_buf.get ();
+             sop->so_original_name = sop->so_name;
            }
 
-         *sos_next_ptr = sop;
-         sos_next_ptr = &sop->next;
+         sos.push_back (*sop);
        }
       else
        {
@@ -431,7 +412,7 @@ frv_current_sos (void)
 
   enable_break2 ();
 
-  return sos_head;
+  return sos;
 }
 
 
@@ -448,7 +429,7 @@ frv_in_dynsym_resolve_code (CORE_ADDR pc)
 {
   return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
          || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
-         || in_plt_section (pc, NULL));
+         || in_plt_section (pc));
 }
 
 /* Given a loadmap and an address, return the displacement needed
@@ -456,14 +437,14 @@ frv_in_dynsym_resolve_code (CORE_ADDR pc)
 
 static CORE_ADDR
 displacement_from_map (struct int_elf32_fdpic_loadmap *map,
-                       CORE_ADDR addr)
+                      CORE_ADDR addr)
 {
   int seg;
 
   for (seg = 0; seg < map->nsegs; seg++)
     {
       if (map->segs[seg].p_vaddr <= addr
-          && addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
+         && addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
        {
          return map->segs[seg].addr - map->segs[seg].p_vaddr;
        }
@@ -479,18 +460,10 @@ static void
 enable_break_failure_warning (void)
 {
   warning (_("Unable to find dynamic linker breakpoint function.\n"
-           "GDB will be unable to debug shared library initializers\n"
+          "GDB will be unable to debug shared library initializers\n"
           "and track explicitly loaded dynamic code."));
 }
 
-/* Helper function for gdb_bfd_lookup_symbol.  */
-
-static int
-cmp_name (asymbol *sym, void *data)
-{
-  return (strcmp (sym->name, (const char *) data) == 0);
-}
-
 /* Arrange for dynamic linker to hit breakpoint.
 
    The dynamic linkers has, as part of its debugger interface, support
@@ -518,9 +491,7 @@ static int enable_break2_done = 0;
 static int
 enable_break2 (void)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
-  int success = 0;
-  char **bkpt_namep;
+  bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   asection *interp_sect;
 
   if (enable_break2_done)
@@ -531,151 +502,142 @@ enable_break2 (void)
 
   /* Find the .interp section; if not found, warn the user and drop
      into the old breakpoint at symbol code.  */
-  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)
     {
       unsigned int interp_sect_size;
-      gdb_byte *buf;
-      bfd *tmp_bfd = NULL;
+      char *buf;
       int status;
       CORE_ADDR addr, interp_loadmap_addr;
       gdb_byte addr_buf[FRV_PTR_SIZE];
       struct int_elf32_fdpic_loadmap *ldm;
-      volatile struct gdb_exception ex;
 
       /* Read the contents of the .interp section into a local buffer;
-         the contents specify the dynamic linker this program uses.  */
-      interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
-      buf = alloca (interp_sect_size);
-      bfd_get_section_contents (exec_bfd, interp_sect,
-                               buf, 0, interp_sect_size);
+        the contents specify the dynamic linker this program uses.  */
+      interp_sect_size = bfd_section_size (interp_sect);
+      buf = (char *) alloca (interp_sect_size);
+      bfd_get_section_contents (current_program_space->exec_bfd (),
+                               interp_sect, buf, 0, interp_sect_size);
 
       /* 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.
-
-         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.  */
-
-      TRY_CATCH (ex, RETURN_MASK_ALL)
-        {
-          tmp_bfd = solib_bfd_open (buf);
-        }
+        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.  */
+
+      gdb_bfd_ref_ptr tmp_bfd;
+      try
+       {
+         tmp_bfd = solib_bfd_open (buf);
+       }
+      catch (const gdb_exception &ex)
+       {
+       }
+
       if (tmp_bfd == NULL)
        {
          enable_break_failure_warning ();
          return 0;
        }
 
-      status = frv_fdpic_loadmap_addresses (target_gdbarch (),
-                                            &interp_loadmap_addr, 0);
+      status = frv_fdpic_loadmap_addresses (current_inferior ()->arch (),
+                                           &interp_loadmap_addr, 0);
       if (status < 0)
        {
          warning (_("Unable to determine dynamic linker loadmap address."));
          enable_break_failure_warning ();
-         gdb_bfd_unref (tmp_bfd);
          return 0;
        }
 
-      if (solib_frv_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "enable_break: interp_loadmap_addr = %s\n",
-                           hex_string_custom (interp_loadmap_addr, 8));
+      solib_debug_printf ("interp_loadmap_addr = %s",
+                         hex_string_custom (interp_loadmap_addr, 8));
 
       ldm = fetch_loadmap (interp_loadmap_addr);
       if (ldm == NULL)
        {
          warning (_("Unable to load dynamic linker loadmap at address %s."),
-                  hex_string_custom (interp_loadmap_addr, 8));
+                  hex_string_custom (interp_loadmap_addr, 8));
          enable_break_failure_warning ();
-         gdb_bfd_unref (tmp_bfd);
          return 0;
        }
 
       /* Record the relocated start and end address of the dynamic linker
-         text and plt section for svr4_in_dynsym_resolve_code.  */
-      interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
+        text and plt section for svr4_in_dynsym_resolve_code.  */
+      interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".text");
       if (interp_sect)
        {
-         interp_text_sect_low
-           = bfd_section_vma (tmp_bfd, interp_sect);
+         interp_text_sect_low = bfd_section_vma (interp_sect);
          interp_text_sect_low
            += displacement_from_map (ldm, interp_text_sect_low);
          interp_text_sect_high
-           = interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+           = interp_text_sect_low + bfd_section_size (interp_sect);
        }
-      interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
+      interp_sect = bfd_get_section_by_name (tmp_bfd.get (), ".plt");
       if (interp_sect)
        {
-         interp_plt_sect_low =
-           bfd_section_vma (tmp_bfd, interp_sect);
+         interp_plt_sect_low = bfd_section_vma (interp_sect);
          interp_plt_sect_low
            += displacement_from_map (ldm, interp_plt_sect_low);
          interp_plt_sect_high =
-           interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
+           interp_plt_sect_low + bfd_section_size (interp_sect);
        }
 
-      addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_addr");
+      addr = (gdb_bfd_lookup_symbol
+             (tmp_bfd.get (),
+              [] (const asymbol *sym)
+              {
+                return strcmp (sym->name, "_dl_debug_addr") == 0;
+              }));
 
       if (addr == 0)
        {
          warning (_("Could not find symbol _dl_debug_addr "
                     "in dynamic linker"));
          enable_break_failure_warning ();
-         gdb_bfd_unref (tmp_bfd);
          return 0;
        }
 
-      if (solib_frv_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "enable_break: _dl_debug_addr "
-                           "(prior to relocation) = %s\n",
-                           hex_string_custom (addr, 8));
+      solib_debug_printf ("_dl_debug_addr (prior to relocation) = %s",
+                         hex_string_custom (addr, 8));
 
       addr += displacement_from_map (ldm, addr);
 
-      if (solib_frv_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "enable_break: _dl_debug_addr "
-                           "(after relocation) = %s\n",
-                           hex_string_custom (addr, 8));
+      solib_debug_printf ("_dl_debug_addr (after relocation) = %s",
+                         hex_string_custom (addr, 8));
 
       /* Fetch the address of the r_debug struct.  */
       if (target_read_memory (addr, addr_buf, sizeof addr_buf) != 0)
        {
          warning (_("Unable to fetch contents of _dl_debug_addr "
                     "(at address %s) from dynamic linker"),
-                  hex_string_custom (addr, 8));
+                  hex_string_custom (addr, 8));
        }
       addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
 
-      if (solib_frv_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "enable_break: _dl_debug_addr[0..3] = %s\n",
-                           hex_string_custom (addr, 8));
+      solib_debug_printf ("_dl_debug_addr[0..3] = %s",
+                         hex_string_custom (addr, 8));
 
       /* If it's zero, then the ldso hasn't initialized yet, and so
-         there are no shared libs yet loaded.  */
+        there are no shared libs yet loaded.  */
       if (addr == 0)
        {
-         if (solib_frv_debug)
-           fprintf_unfiltered (gdb_stdlog,
-                               "enable_break: ldso not yet initialized\n");
+         solib_debug_printf ("ldso not yet initialized");
          /* Do not warn, but mark to run again.  */
          return 0;
        }
 
       /* Fetch the r_brk field.  It's 8 bytes from the start of
-         _dl_debug_addr.  */
+        _dl_debug_addr.  */
       if (target_read_memory (addr + 8, addr_buf, sizeof addr_buf) != 0)
        {
          warning (_("Unable to fetch _dl_debug_addr->r_brk "
                     "(at address %s) from dynamic linker"),
-                  hex_string_custom (addr + 8, 8));
+                  hex_string_custom (addr + 8, 8));
          enable_break_failure_warning ();
-         gdb_bfd_unref (tmp_bfd);
          return 0;
        }
       addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
@@ -685,25 +647,21 @@ enable_break2 (void)
        {
          warning (_("Unable to fetch _dl_debug_addr->.r_brk entry point "
                     "(at address %s) from dynamic linker"),
-                  hex_string_custom (addr, 8));
+                  hex_string_custom (addr, 8));
          enable_break_failure_warning ();
-         gdb_bfd_unref (tmp_bfd);
          return 0;
        }
       addr = extract_unsigned_integer (addr_buf, sizeof addr_buf, byte_order);
 
-      /* We're done with the temporary bfd.  */
-      gdb_bfd_unref (tmp_bfd);
-
-      /* We're also done with the loadmap.  */
+      /* We're done with the loadmap.  */
       xfree (ldm);
 
       /* Remove all the solib event breakpoints.  Their addresses
-         may have changed since the last time we ran the program.  */
+        may have changed since the last time we ran the program.  */
       remove_solib_event_breakpoints ();
 
       /* Now (finally!) create the solib breakpoint.  */
-      create_solib_event_breakpoint (target_gdbarch (), addr);
+      create_solib_event_breakpoint (current_inferior ()->arch (), addr);
 
       enable_break2_done = 1;
 
@@ -721,69 +679,49 @@ static int
 enable_break (void)
 {
   asection *interp_sect;
+  CORE_ADDR entry_point;
 
-  if (symfile_objfile == NULL)
+  if (current_program_space->symfile_object_file == NULL)
     {
-      if (solib_frv_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "enable_break: No symbol file found.\n");
+      solib_debug_printf ("No symbol file found.");
       return 0;
     }
 
-  if (!symfile_objfile->ei.entry_point_p)
+  if (!entry_point_address_query (&entry_point))
     {
-      if (solib_frv_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "enable_break: Symbol file has no entry point.\n");
+      solib_debug_printf ("Symbol file has no entry point.");
       return 0;
     }
 
   /* Check for the presence of a .interp section.  If there is no
      such section, the executable is statically linked.  */
 
-  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)
     {
-      if (solib_frv_debug)
-       fprintf_unfiltered (gdb_stdlog,
-                           "enable_break: No .interp section found.\n");
+      solib_debug_printf ("No .interp section found.");
       return 0;
     }
 
-  create_solib_event_breakpoint (target_gdbarch (),
-                                symfile_objfile->ei.entry_point);
+  create_solib_event_breakpoint (current_inferior ()->arch (), entry_point);
 
-  if (solib_frv_debug)
-    fprintf_unfiltered (gdb_stdlog,
-                       "enable_break: solib event breakpoint "
-                       "placed at entry point: %s\n",
-                       hex_string_custom (symfile_objfile->ei.entry_point,
-                                          8));
+  solib_debug_printf ("solib event breakpoint placed at entry point: %s",
+                     hex_string_custom (entry_point, 8));
   return 1;
 }
 
-/* Implement the "special_symbol_handling" target_so_ops method.  */
-
-static void
-frv_special_symbol_handling (void)
-{
-  /* Nothing needed for FRV.  */
-}
-
 static void
 frv_relocate_main_executable (void)
 {
   int status;
   CORE_ADDR exec_addr, interp_addr;
   struct int_elf32_fdpic_loadmap *ldm;
-  struct cleanup *old_chain;
-  struct section_offsets *new_offsets;
   int changed;
-  struct obj_section *osect;
 
-  status = frv_fdpic_loadmap_addresses (target_gdbarch (),
-                                        &interp_addr, &exec_addr);
+  status = frv_fdpic_loadmap_addresses (current_inferior ()->arch (),
+                                       &interp_addr, &exec_addr);
 
   if (status < 0 || (exec_addr == 0 && interp_addr == 0))
     {
@@ -796,28 +734,26 @@ frv_relocate_main_executable (void)
   if (ldm == NULL)
     error (_("Unable to load the executable's loadmap."));
 
-  if (main_executable_lm_info)
-    xfree (main_executable_lm_info);
-  main_executable_lm_info = xcalloc (1, sizeof (struct lm_info));
+  delete main_executable_lm_info;
+  main_executable_lm_info = new lm_info_frv;
   main_executable_lm_info->map = ldm;
 
-  new_offsets = xcalloc (symfile_objfile->num_sections,
-                        sizeof (struct section_offsets));
-  old_chain = make_cleanup (xfree, new_offsets);
+  objfile *objf = current_program_space->symfile_object_file;
+  section_offsets new_offsets (objf->section_offsets.size ());
   changed = 0;
 
-  ALL_OBJFILE_OSECTIONS (symfile_objfile, osect)
+  for (obj_section *osect : objf->sections ())
     {
       CORE_ADDR orig_addr, addr, offset;
       int osect_idx;
       int seg;
       
-      osect_idx = osect->the_bfd_section->index;
+      osect_idx = osect - objf->sections_start;
 
       /* Current address of section.  */
-      addr = obj_section_addr (osect);
+      addr = osect->addr ();
       /* Offset from where this section started.  */
-      offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
+      offset = objf->section_offsets[osect_idx];
       /* Original address prior to any past relocations.  */
       orig_addr = addr - offset;
 
@@ -826,10 +762,10 @@ frv_relocate_main_executable (void)
          if (ldm->segs[seg].p_vaddr <= orig_addr
              && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz)
            {
-             new_offsets->offsets[osect_idx]
+             new_offsets[osect_idx]
                = ldm->segs[seg].addr - ldm->segs[seg].p_vaddr;
 
-             if (new_offsets->offsets[osect_idx] != offset)
+             if (new_offsets[osect_idx] != offset)
                changed = 1;
              break;
            }
@@ -837,12 +773,10 @@ frv_relocate_main_executable (void)
     }
 
   if (changed)
-    objfile_relocate (symfile_objfile, new_offsets);
+    objfile_relocate (objf, new_offsets);
 
-  do_cleanups (old_chain);
-
-  /* Now that symfile_objfile has been relocated, we can compute the
-     GOT value and stash it away.  */
+  /* Now that OBJF has been relocated, we can compute the GOT value
+     and stash it away.  */
   main_executable_lm_info->got_value = main_got ();
 }
 
@@ -867,43 +801,27 @@ frv_solib_create_inferior_hook (int from_tty)
 }
 
 static void
-frv_clear_solib (void)
+frv_clear_solib (program_space *pspace)
 {
   lm_base_cache = 0;
   enable_break2_done = 0;
   main_lm_addr = 0;
-  if (main_executable_lm_info != 0)
-    {
-      xfree (main_executable_lm_info->map);
-      xfree (main_executable_lm_info->dyn_syms);
-      xfree (main_executable_lm_info->dyn_relocs);
-      xfree (main_executable_lm_info);
-      main_executable_lm_info = 0;
-    }
-}
 
-static void
-frv_free_so (struct so_list *so)
-{
-  xfree (so->lm_info->map);
-  xfree (so->lm_info->dyn_syms);
-  xfree (so->lm_info->dyn_relocs);
-  xfree (so->lm_info);
+  delete main_executable_lm_info;
+  main_executable_lm_info = NULL;
 }
 
 static void
-frv_relocate_section_addresses (struct so_list *so,
-                                 struct target_section *sec)
+frv_relocate_section_addresses (solib &so, target_section *sec)
 {
   int seg;
-  struct int_elf32_fdpic_loadmap *map;
-
-  map = so->lm_info->map;
+  auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
+  int_elf32_fdpic_loadmap *map = li->map;
 
   for (seg = 0; seg < map->nsegs; seg++)
     {
       if (map->segs[seg].p_vaddr <= sec->addr
-          && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
+         && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
        {
          CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr;
 
@@ -920,14 +838,14 @@ frv_relocate_section_addresses (struct so_list *so,
 static CORE_ADDR
 main_got (void)
 {
-  struct minimal_symbol *got_sym;
+  struct bound_minimal_symbol got_sym;
 
-  got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_",
-                                  NULL, symfile_objfile);
-  if (got_sym == 0)
+  objfile *objf = current_program_space->symfile_object_file;
+  got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, objf);
+  if (got_sym.minsym == 0)
     return 0;
 
-  return SYMBOL_VALUE_ADDRESS (got_sym);
+  return got_sym.value_address ();
 }
 
 /* Find the global pointer for the given function address ADDR.  */
@@ -935,24 +853,18 @@ main_got (void)
 CORE_ADDR
 frv_fdpic_find_global_pointer (CORE_ADDR addr)
 {
-  struct so_list *so;
-
-  so = master_so_list ();
-  while (so)
+  for (const solib &so : current_program_space->solibs ())
     {
       int seg;
-      struct int_elf32_fdpic_loadmap *map;
-
-      map = so->lm_info->map;
+      auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
+      int_elf32_fdpic_loadmap *map = li->map;
 
       for (seg = 0; seg < map->nsegs; seg++)
        {
          if (map->segs[seg].addr <= addr
              && addr < map->segs[seg].addr + map->segs[seg].p_memsz)
-           return so->lm_info->got_value;
+           return li->got_value;
        }
-
-      so = so->next;
     }
 
   /* Didn't find it in any of the shared objects.  So assume it's in the
@@ -962,7 +874,7 @@ frv_fdpic_find_global_pointer (CORE_ADDR addr)
 
 /* Forward declarations for frv_fdpic_find_canonical_descriptor().  */
 static CORE_ADDR find_canonical_descriptor_in_load_object
-  (CORE_ADDR, CORE_ADDR, const char *, bfd *, struct lm_info *);
+  (CORE_ADDR, CORE_ADDR, const char *, bfd *, lm_info_frv *);
 
 /* Given a function entry point, attempt to find the canonical descriptor
    associated with that entry point.  Return 0 if no canonical descriptor
@@ -974,7 +886,6 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point)
   const char *name;
   CORE_ADDR addr;
   CORE_ADDR got_value;
-  struct int_elf32_fdpic_loadmap *ldm = 0;
   struct symbol *sym;
 
   /* Fetch the corresponding global pointer for the entry point.  */
@@ -987,29 +898,27 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point)
   if (sym == 0)
     name = 0;
   else
-    name = SYMBOL_LINKAGE_NAME (sym);
+    name = sym->linkage_name ();
 
   /* Check the main executable.  */
+  objfile *objf = current_program_space->symfile_object_file;
   addr = find_canonical_descriptor_in_load_object
-           (entry_point, got_value, name, symfile_objfile->obfd,
+          (entry_point, got_value, name, objf->obfd.get (),
            main_executable_lm_info);
 
   /* If descriptor not found via main executable, check each load object
      in list of shared objects.  */
   if (addr == 0)
     {
-      struct so_list *so;
-
-      so = master_so_list ();
-      while (so)
+      for (const solib &so : current_program_space->solibs ())
        {
+         auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
+
          addr = find_canonical_descriptor_in_load_object
-                  (entry_point, got_value, name, so->abfd, so->lm_info);
+                  (entry_point, got_value, name, so.abfd.get(), li);
 
          if (addr != 0)
            break;
-
-         so = so->next;
        }
     }
 
@@ -1019,9 +928,9 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point)
 static CORE_ADDR
 find_canonical_descriptor_in_load_object
   (CORE_ADDR entry_point, CORE_ADDR got_value, const char *name, bfd *abfd,
-   struct lm_info *lm)
+   lm_info_frv *lm)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+  bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   arelent *rel;
   unsigned int i;
   CORE_ADDR addr = 0;
@@ -1088,7 +997,7 @@ find_canonical_descriptor_in_load_object
       rel = lm->dyn_relocs[i];
 
       /* Relocs of interest are those which meet the following
-         criteria:
+        criteria:
 
           - the names match (assuming the caller could provide
             a name which matches ``entry_point'').
@@ -1104,7 +1013,7 @@ find_canonical_descriptor_in_load_object
         this address (which is a GOT entry) to obtain a descriptor
         address.  */
       if ((name == 0 || strcmp (name, (*rel->sym_ptr_ptr)->name) == 0)
-          && rel->howto->type == R_FRV_FUNCDESC)
+         && rel->howto->type == R_FRV_FUNCDESC)
        {
          gdb_byte buf [FRV_PTR_SIZE];
 
@@ -1143,53 +1052,36 @@ find_canonical_descriptor_in_load_object
 CORE_ADDR
 frv_fetch_objfile_link_map (struct objfile *objfile)
 {
-  struct so_list *so;
-
   /* Cause frv_current_sos() to be run if it hasn't been already.  */
   if (main_lm_addr == 0)
-    solib_add (0, 0, 0, 1);
+    solib_add (0, 0, 1);
 
   /* frv_current_sos() will set main_lm_addr for the main executable.  */
-  if (objfile == symfile_objfile)
+  if (objfile == current_program_space->symfile_object_file)
     return main_lm_addr;
 
   /* The other link map addresses may be found by examining the list
      of shared libraries.  */
-  for (so = master_so_list (); so; so = so->next)
+  for (const solib &so : current_program_space->solibs ())
     {
-      if (so->objfile == objfile)
-       return so->lm_info->lm_addr;
+      auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
+
+      if (so.objfile == objfile)
+       return li->lm_addr;
     }
 
   /* Not found!  */
   return 0;
 }
 
-struct target_so_ops frv_so_ops;
-
-/* Provide a prototype to silence -Wmissing-prototypes.  */
-extern initialize_file_ftype _initialize_frv_solib;
-
-void
-_initialize_frv_solib (void)
+const solib_ops frv_so_ops =
 {
-  frv_so_ops.relocate_section_addresses = frv_relocate_section_addresses;
-  frv_so_ops.free_so = frv_free_so;
-  frv_so_ops.clear_solib = frv_clear_solib;
-  frv_so_ops.solib_create_inferior_hook = frv_solib_create_inferior_hook;
-  frv_so_ops.special_symbol_handling = frv_special_symbol_handling;
-  frv_so_ops.current_sos = frv_current_sos;
-  frv_so_ops.open_symbol_file_object = open_symbol_file_object;
-  frv_so_ops.in_dynsym_resolve_code = frv_in_dynsym_resolve_code;
-  frv_so_ops.bfd_open = solib_bfd_open;
-
-  /* Debug this file's internals.  */
-  add_setshow_zuinteger_cmd ("solib-frv", class_maintenance,
-                            &solib_frv_debug, _("\
-Set internal debugging of shared library code for FR-V."), _("\
-Show internal debugging of shared library code for FR-V."), _("\
-When non-zero, FR-V solib specific internal debugging is enabled."),
-                            NULL,
-                            NULL, /* FIXME: i18n: */
-                            &setdebuglist, &showdebuglist);
-}
+  frv_relocate_section_addresses,
+  nullptr,
+  frv_clear_solib,
+  frv_solib_create_inferior_hook,
+  frv_current_sos,
+  open_symbol_file_object,
+  frv_in_dynsym_resolve_code,
+  solib_bfd_open,
+};