gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / objfiles.c
index bae556a1ff0b56eca5ef1799da0f7365e34ee7cb..3aa7973e0d563ee64e0a5b8e45adbfd709e660e8 100644 (file)
@@ -1,6 +1,6 @@
 /* GDB routines for manipulating objfiles.
 
-   Copyright (C) 1992-2019 Free Software Foundation, Inc.
+   Copyright (C) 1992-2020 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
@@ -54,6 +54,7 @@
 #include "btrace.h"
 #include "gdbsupport/pathstuff.h"
 
+#include <algorithm>
 #include <vector>
 
 /* Keep a registry of per-objfile data-pointers required by other GDB
@@ -371,31 +372,6 @@ objfile::objfile (bfd *abfd, const char *name, objfile_flags flags_)
     }
 
   per_bfd = get_objfile_bfd_data (this, abfd);
-
-  /* Add this file onto the tail of the linked list of other such files.  */
-
-  if (object_files == NULL)
-    object_files = this;
-  else
-    {
-      struct objfile *last_one;
-
-      for (last_one = object_files;
-          last_one->next;
-          last_one = last_one->next);
-      last_one->next = this;
-    }
-
-  /* Rebuild section map next time we need it.  */
-  get_objfile_pspace_data (pspace)->new_objfiles_available = 1;
-}
-
-/* Retrieve the gdbarch associated with OBJFILE.  */
-
-struct gdbarch *
-get_objfile_arch (const struct objfile *objfile)
-{
-  return objfile->per_bfd->gdbarch;
 }
 
 /* If there is a valid and known entry point, function fills *ENTRY_P with it
@@ -407,9 +383,9 @@ entry_point_address_query (CORE_ADDR *entry_p)
   if (symfile_objfile == NULL || !symfile_objfile->per_bfd->ei.entry_point_p)
     return 0;
 
+  int idx = symfile_objfile->per_bfd->ei.the_bfd_section_index;
   *entry_p = (symfile_objfile->per_bfd->ei.entry_point
-             + ANOFFSET (symfile_objfile->section_offsets,
-                         symfile_objfile->per_bfd->ei.the_bfd_section_index));
+             + symfile_objfile->section_offsets[idx]);
 
   return 1;
 }
@@ -473,65 +449,9 @@ separate_debug_iterator::operator++ ()
   return *this;
 }
 
-/* Put one object file before a specified on in the global list.
-   This can be used to make sure an object file is destroyed before
-   another when using objfiles_safe to free all objfiles.  */
-void
-put_objfile_before (struct objfile *objfile, struct objfile *before_this)
-{
-  struct objfile **objp;
-
-  unlink_objfile (objfile);
-  
-  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
-    {
-      if (*objp == before_this)
-       {
-         objfile->next = *objp;
-         *objp = objfile;
-         return;
-       }
-    }
-  
-  internal_error (__FILE__, __LINE__,
-                 _("put_objfile_before: before objfile not in list"));
-}
-
-/* Unlink OBJFILE from the list of known objfiles, if it is found in the
-   list.
-
-   It is not a bug, or error, to call this function if OBJFILE is not known
-   to be in the current list.  This is done in the case of mapped objfiles,
-   for example, just to ensure that the mapped objfile doesn't appear twice
-   in the list.  Since the list is threaded, linking in a mapped objfile
-   twice would create a circular list.
-
-   If OBJFILE turns out to be in the list, we zap it's NEXT pointer after
-   unlinking it, just to ensure that we have completely severed any linkages
-   between the OBJFILE and the list.  */
-
-void
-unlink_objfile (struct objfile *objfile)
-{
-  struct objfile **objpp;
-
-  for (objpp = &object_files; *objpp != NULL; objpp = &((*objpp)->next))
-    {
-      if (*objpp == objfile)
-       {
-         *objpp = (*objpp)->next;
-         objfile->next = NULL;
-         return;
-       }
-    }
-
-  internal_error (__FILE__, __LINE__,
-                 _("unlink_objfile: objfile already unlinked"));
-}
-
 /* Add OBJFILE as a separate debug objfile of PARENT.  */
 
-void
+static void
 add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent)
 {
   gdb_assert (objfile && parent);
@@ -546,10 +466,35 @@ add_separate_debug_objfile (struct objfile *objfile, struct objfile *parent)
   objfile->separate_debug_objfile_backlink = parent;
   objfile->separate_debug_objfile_link = parent->separate_debug_objfile;
   parent->separate_debug_objfile = objfile;
+}
+
+/* See objfiles.h.  */
+
+objfile *
+objfile::make (bfd *bfd_, const char *name_, objfile_flags flags_,
+              objfile *parent)
+{
+  objfile *result = new objfile (bfd_, name_, flags_);
+  if (parent != nullptr)
+    add_separate_debug_objfile (result, parent);
+
+  /* Using std::make_shared might be a bit nicer here, but that would
+     require making the constructor public.  */
+  current_program_space->add_objfile (std::shared_ptr<objfile> (result),
+                                     parent);
+
+  /* Rebuild section map next time we need it.  */
+  get_objfile_pspace_data (current_program_space)->new_objfiles_available = 1;
 
-  /* Put the separate debug object before the normal one, this is so that
-     usage of objfiles_safe will stay safe.  */
-  put_objfile_before (objfile, parent);
+  return result;
+}
+
+/* See objfiles.h.  */
+
+void
+objfile::unlink ()
+{
+  current_program_space->remove_objfile (this);
 }
 
 /* Free all separate debug objfile of OBJFILE, but don't free OBJFILE
@@ -563,7 +508,7 @@ free_objfile_separate_debug (struct objfile *objfile)
   for (child = objfile->separate_debug_objfile; child;)
     {
       struct objfile *next_child = child->separate_debug_objfile_link;
-      delete child;
+      child->unlink ();
       child = next_child;
     }
 }
@@ -639,13 +584,6 @@ objfile::~objfile ()
   else
     delete per_bfd;
 
-  /* Remove it from the chain of all objfiles.  */
-
-  unlink_objfile (this);
-
-  if (this == symfile_objfile)
-    symfile_objfile = NULL;
-
   /* Before the symbol table code was redone to make it easier to
      selectively load and remove information particular to a specific
      linkage unit, gdb used to do these things whenever the monolithic
@@ -674,28 +612,13 @@ objfile::~objfile ()
   get_objfile_pspace_data (pspace)->section_map_dirty = 1;
 }
 
-/* Free all the object files at once and clean up their users.  */
-
-void
-free_all_objfiles (void)
-{
-  struct so_list *so;
-
-  /* Any objfile reference would become stale.  */
-  for (so = master_so_list (); so; so = so->next)
-    gdb_assert (so->objfile == NULL);
-
-  for (objfile *objfile : current_program_space->objfiles_safe ())
-    delete objfile;
-  clear_symtab_users (0);
-}
 \f
 /* A helper function for objfile_relocate1 that relocates a single
    symbol.  */
 
 static void
 relocate_one_symbol (struct symbol *sym, struct objfile *objfile,
-                    struct section_offsets *delta)
+                    const section_offsets &delta)
 {
   fixup_symbol_section (sym, objfile);
 
@@ -709,7 +632,7 @@ relocate_one_symbol (struct symbol *sym, struct objfile *objfile,
     {
       SET_SYMBOL_VALUE_ADDRESS (sym,
                                SYMBOL_VALUE_ADDRESS (sym)
-                               + ANOFFSET (delta, SYMBOL_SECTION (sym)));
+                               + delta[SYMBOL_SECTION (sym)]);
     }
 }
 
@@ -719,19 +642,16 @@ relocate_one_symbol (struct symbol *sym, struct objfile *objfile,
 
 static int
 objfile_relocate1 (struct objfile *objfile, 
-                  const struct section_offsets *new_offsets)
+                  const section_offsets &new_offsets)
 {
-  struct section_offsets *delta =
-    ((struct section_offsets *) 
-     alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)));
+  section_offsets delta (objfile->section_offsets.size ());
 
   int something_changed = 0;
 
-  for (int i = 0; i < objfile->num_sections; ++i)
+  for (int i = 0; i < objfile->section_offsets.size (); ++i)
     {
-      delta->offsets[i] =
-       ANOFFSET (new_offsets, i) - ANOFFSET (objfile->section_offsets, i);
-      if (ANOFFSET (delta, i) != 0)
+      delta[i] = new_offsets[i] - objfile->section_offsets[i];
+      if (delta[i] != 0)
        something_changed = 1;
     }
   if (!something_changed)
@@ -750,9 +670,7 @@ objfile_relocate1 (struct objfile *objfile,
            if (l)
              {
                for (int i = 0; i < l->nitems; ++i)
-                 l->item[i].pc += ANOFFSET (delta,
-                                            COMPUNIT_BLOCK_LINE_SECTION
-                                            (cust));
+                 l->item[i].pc += delta[COMPUNIT_BLOCK_LINE_SECTION (cust)];
              }
          }
       }
@@ -763,8 +681,7 @@ objfile_relocate1 (struct objfile *objfile,
        int block_line_section = COMPUNIT_BLOCK_LINE_SECTION (cust);
 
        if (BLOCKVECTOR_MAP (bv))
-         addrmap_relocate (BLOCKVECTOR_MAP (bv),
-                           ANOFFSET (delta, block_line_section));
+         addrmap_relocate (BLOCKVECTOR_MAP (bv), delta[block_line_section]);
 
        for (int i = 0; i < BLOCKVECTOR_NBLOCKS (bv); ++i)
          {
@@ -773,16 +690,14 @@ objfile_relocate1 (struct objfile *objfile,
            struct mdict_iterator miter;
 
            b = BLOCKVECTOR_BLOCK (bv, i);
-           BLOCK_START (b) += ANOFFSET (delta, block_line_section);
-           BLOCK_END (b) += ANOFFSET (delta, block_line_section);
+           BLOCK_START (b) += delta[block_line_section];
+           BLOCK_END (b) += delta[block_line_section];
 
            if (BLOCK_RANGES (b) != nullptr)
              for (int j = 0; j < BLOCK_NRANGES (b); j++)
                {
-                 BLOCK_RANGE_START (b, j)
-                   += ANOFFSET (delta, block_line_section);
-                 BLOCK_RANGE_END (b, j) += ANOFFSET (delta,
-                                                     block_line_section);
+                 BLOCK_RANGE_START (b, j) += delta[block_line_section];
+                 BLOCK_RANGE_END (b, j) += delta[block_line_section];
                }
 
            /* We only want to iterate over the local symbols, not any
@@ -810,8 +725,8 @@ objfile_relocate1 (struct objfile *objfile,
   {
     int i;
 
-    for (i = 0; i < objfile->num_sections; ++i)
-      (objfile->section_offsets)->offsets[i] = ANOFFSET (new_offsets, i);
+    for (i = 0; i < objfile->section_offsets.size (); ++i)
+      objfile->section_offsets[i] = new_offsets[i];
   }
 
   /* Rebuild section map next time we need it.  */
@@ -842,7 +757,7 @@ objfile_relocate1 (struct objfile *objfile,
 
 void
 objfile_relocate (struct objfile *objfile,
-                 const struct section_offsets *new_offsets)
+                 const section_offsets &new_offsets)
 {
   int changed = 0;
 
@@ -861,15 +776,13 @@ objfile_relocate (struct objfile *objfile,
 
       addr_info_make_relative (&objfile_addrs, debug_objfile->obfd);
 
-      gdb_assert (debug_objfile->num_sections
+      gdb_assert (debug_objfile->section_offsets.size ()
                  == gdb_bfd_count_sections (debug_objfile->obfd));
-      std::vector<struct section_offsets>
-       new_debug_offsets (SIZEOF_N_SECTION_OFFSETS (debug_objfile->num_sections));
-      relative_addr_info_to_section_offsets (new_debug_offsets.data (),
-                                            debug_objfile->num_sections,
-                                            objfile_addrs);
+      section_offsets new_debug_offsets
+       (debug_objfile->section_offsets.size ());
+      relative_addr_info_to_section_offsets (new_debug_offsets, objfile_addrs);
 
-      changed |= objfile_relocate1 (debug_objfile, new_debug_offsets.data ());
+      changed |= objfile_relocate1 (debug_objfile, new_debug_offsets);
     }
 
   /* Relocate breakpoints as necessary, after things are relocated.  */
@@ -884,14 +797,7 @@ objfile_relocate (struct objfile *objfile,
 static int
 objfile_rebase1 (struct objfile *objfile, CORE_ADDR slide)
 {
-  struct section_offsets *new_offsets =
-    ((struct section_offsets *)
-     alloca (SIZEOF_N_SECTION_OFFSETS (objfile->num_sections)));
-  int i;
-
-  for (i = 0; i < objfile->num_sections; ++i)
-    new_offsets->offsets[i] = slide;
-
+  section_offsets new_offsets (objfile->section_offsets.size (), slide);
   return objfile_relocate1 (objfile, new_offsets);
 }
 
@@ -995,7 +901,7 @@ objfile_purge_solibs (void)
         be soon.  */
 
       if (!(objf->flags & OBJF_USERLOADED) && (objf->flags & OBJF_SHARED))
-       delete objf;
+       objf->unlink ();
     }
 }
 
@@ -1019,18 +925,16 @@ have_minimal_symbols (void)
 
 /* Qsort comparison function.  */
 
-static int
-qsort_cmp (const void *a, const void *b)
+static bool
+sort_cmp (const struct obj_section *sect1, const obj_section *sect2)
 {
-  const struct obj_section *sect1 = *(const struct obj_section **) a;
-  const struct obj_section *sect2 = *(const struct obj_section **) b;
   const CORE_ADDR sect1_addr = obj_section_addr (sect1);
   const CORE_ADDR sect2_addr = obj_section_addr (sect2);
 
   if (sect1_addr < sect2_addr)
-    return -1;
+    return true;
   else if (sect1_addr > sect2_addr)
-    return 1;
+    return false;
   else
     {
       /* Sections are at the same address.  This could happen if
@@ -1047,29 +951,33 @@ qsort_cmp (const void *a, const void *b)
          /* Case A.  The ordering doesn't matter: separate debuginfo files
             will be filtered out later.  */
 
-         return 0;
+         return false;
        }
 
       /* Case B.  Maintain stable sort order, so bugs in GDB are easier to
         triage.  This section could be slow (since we iterate over all
-        objfiles in each call to qsort_cmp), but this shouldn't happen
+        objfiles in each call to sort_cmp), but this shouldn't happen
         very often (GDB is already in a confused state; one hopes this
         doesn't happen at all).  If you discover that significant time is
         spent in the loops below, do 'set complaints 100' and examine the
         resulting complaints.  */
-
       if (objfile1 == objfile2)
        {
-         /* Both sections came from the same objfile.  We are really confused.
-            Sort on sequence order of sections within the objfile.  */
+         /* Both sections came from the same objfile.  We are really
+            confused.  Sort on sequence order of sections within the
+            objfile.  The order of checks is important here, if we find a
+            match on SECT2 first then either SECT2 is before SECT1, or,
+            SECT2 == SECT1, in both cases we should return false.  The
+            second case shouldn't occur during normal use, but std::sort
+            does check that '!(a < a)' when compiled in debug mode.  */
 
          const struct obj_section *osect;
 
          ALL_OBJFILE_OSECTIONS (objfile1, osect)
-           if (osect == sect1)
-             return -1;
-           else if (osect == sect2)
-             return 1;
+           if (osect == sect2)
+             return false;
+           else if (osect == sect1)
+             return true;
 
          /* We should have found one of the sections before getting here.  */
          gdb_assert_not_reached ("section not found");
@@ -1080,9 +988,9 @@ qsort_cmp (const void *a, const void *b)
 
          for (objfile *objfile : current_program_space->objfiles ())
            if (objfile == objfile1)
-             return -1;
+             return true;
            else if (objfile == objfile2)
-             return 1;
+             return false;
 
          /* We should have found one of the objfiles before getting here.  */
          gdb_assert_not_reached ("objfile not found");
@@ -1091,7 +999,7 @@ qsort_cmp (const void *a, const void *b)
 
   /* Unreachable.  */
   gdb_assert_not_reached ("unexpected code path");
-  return 0;
+  return false;
 }
 
 /* Select "better" obj_section to keep.  We prefer the one that came from
@@ -1216,7 +1124,7 @@ filter_overlapping_sections (struct obj_section **map, int map_size)
 
              const CORE_ADDR sect2_endaddr = obj_section_endaddr (sect2);
 
-             struct gdbarch *const gdbarch = get_objfile_arch (objf1);
+             struct gdbarch *const gdbarch = objf1->arch ();
 
              complaint (_("unexpected overlap between:\n"
                           " (A) section `%s' from `%s' [%s, %s)\n"
@@ -1283,7 +1191,7 @@ update_section_map (struct program_space *pspace,
       if (insert_section_p (objfile->obfd, s->the_bfd_section))
        map[i++] = s;
 
-  qsort (map, alloc_size, sizeof (*map), qsort_cmp);
+  std::sort (map, map + alloc_size, sort_cmp);
   map_size = filter_debuginfo_sections(map, alloc_size);
   map_size = filter_overlapping_sections(map, map_size);
 
@@ -1395,16 +1303,15 @@ inhibit_section_map_updates (struct program_space *pspace)
     (&get_objfile_pspace_data (pspace)->inhibit_updates, 1);
 }
 
-/* Return 1 if ADDR maps into one of the sections of OBJFILE and 0
-   otherwise.  */
+/* See objfiles.h.  */
 
-int
+bool
 is_addr_in_objfile (CORE_ADDR addr, const struct objfile *objfile)
 {
   struct obj_section *osect;
 
   if (objfile == NULL)
-    return 0;
+    return false;
 
   ALL_OBJFILE_OSECTIONS (objfile, osect)
     {
@@ -1413,12 +1320,14 @@ is_addr_in_objfile (CORE_ADDR addr, const struct objfile *objfile)
 
       if (obj_section_addr (osect) <= addr
          && addr < obj_section_endaddr (osect))
-       return 1;
+       return true;
     }
-  return 0;
+  return false;
 }
 
-int
+/* See objfiles.h.  */
+
+bool
 shared_objfile_contains_address_p (struct program_space *pspace,
                                   CORE_ADDR address)
 {
@@ -1426,10 +1335,10 @@ shared_objfile_contains_address_p (struct program_space *pspace,
     {
       if ((objfile->flags & OBJF_SHARED) != 0
          && is_addr_in_objfile (address, objfile))
-       return 1;
+       return true;
     }
 
-  return 0;
+  return false;
 }
 
 /* The default implementation for the "iterate_over_objfiles_in_search_order"
This page took 0.049406 seconds and 4 git commands to generate.