Fix an illegal memory access triggered when trying to examine an input file containin...
[deliverable/binutils-gdb.git] / gdb / addrmap.c
index fd800cfddba1b81050e3f391c3ba43c990d97ff0..db6f160b506f9c6ddeeb8dbdc889e96de5cec386 100644 (file)
@@ -1,12 +1,12 @@
 /* addrmap.c --- implementation of address map data structure.
 
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-
-#include <stdlib.h>
-
 #include "splay-tree.h"
 #include "gdb_obstack.h"
 #include "addrmap.h"
-#include "gdb_assert.h"
 
+/* Make sure splay trees can actually hold the values we want to
+   store in them.  */
+gdb_static_assert (sizeof (splay_tree_key) >= sizeof (CORE_ADDR *));
+gdb_static_assert (sizeof (splay_tree_value) >= sizeof (void *));
 
 \f
 /* The "abstract class".  */
    implementation.  */
 struct addrmap_funcs
 {
-  void (*set_empty) (struct addrmap *this,
+  void (*set_empty) (struct addrmap *self,
                      CORE_ADDR start, CORE_ADDR end_inclusive,
                      void *obj);
-  void *(*find) (struct addrmap *this, CORE_ADDR addr);
-  struct addrmap *(*create_fixed) (struct addrmap *this,
+  void *(*find) (struct addrmap *self, CORE_ADDR addr);
+  struct addrmap *(*create_fixed) (struct addrmap *self,
                                    struct obstack *obstack);
-  void (*relocate) (struct addrmap *this, CORE_ADDR offset);
+  void (*relocate) (struct addrmap *self, CORE_ADDR offset);
+  int (*foreach) (struct addrmap *self, addrmap_foreach_fn fn, void *data);
 };
 
 
 struct addrmap
 {
-  struct addrmap_funcs *funcs;
+  const struct addrmap_funcs *funcs;
 };
 
 
@@ -84,6 +83,11 @@ addrmap_relocate (struct addrmap *map, CORE_ADDR offset)
 }
 
 
+int
+addrmap_foreach (struct addrmap *map, addrmap_foreach_fn fn, void *data)
+{
+  return map->funcs->foreach (map, fn, data);
+}
 \f
 /* Fixed address maps.  */
 
@@ -114,7 +118,7 @@ struct addrmap_fixed
 
 
 static void
-addrmap_fixed_set_empty (struct addrmap *this,
+addrmap_fixed_set_empty (struct addrmap *self,
                    CORE_ADDR start, CORE_ADDR end_inclusive,
                    void *obj)
 {
@@ -125,9 +129,9 @@ addrmap_fixed_set_empty (struct addrmap *this,
 
 
 static void *
-addrmap_fixed_find (struct addrmap *this, CORE_ADDR addr)
+addrmap_fixed_find (struct addrmap *self, CORE_ADDR addr)
 {
-  struct addrmap_fixed *map = (struct addrmap_fixed *) this;
+  struct addrmap_fixed *map = (struct addrmap_fixed *) self;
   struct addrmap_transition *bottom = &map->transitions[0];
   struct addrmap_transition *top = &map->transitions[map->num_transitions - 1];
 
@@ -158,16 +162,18 @@ addrmap_fixed_find (struct addrmap *this, CORE_ADDR addr)
 
 
 static struct addrmap *
-addrmap_fixed_create_fixed (struct addrmap *this, struct obstack *obstack)
+addrmap_fixed_create_fixed (struct addrmap *self, struct obstack *obstack)
 {
-  abort ();
+  internal_error (__FILE__, __LINE__,
+                  _("addrmap_create_fixed is not implemented yet "
+                    "for fixed addrmaps"));
 }
 
 
 static void
-addrmap_fixed_relocate (struct addrmap *this, CORE_ADDR offset)
+addrmap_fixed_relocate (struct addrmap *self, CORE_ADDR offset)
 {
-  struct addrmap_fixed *map = (struct addrmap_fixed *) this;
+  struct addrmap_fixed *map = (struct addrmap_fixed *) self;
   size_t i;
 
   for (i = 0; i < map->num_transitions; i++)
@@ -175,12 +181,32 @@ addrmap_fixed_relocate (struct addrmap *this, CORE_ADDR offset)
 }
 
 
-static struct addrmap_funcs addrmap_fixed_funcs =
+static int
+addrmap_fixed_foreach (struct addrmap *self, addrmap_foreach_fn fn,
+                      void *data)
+{
+  struct addrmap_fixed *map = (struct addrmap_fixed *) self;
+  size_t i;
+
+  for (i = 0; i < map->num_transitions; i++)
+    {
+      int res = fn (data, map->transitions[i].addr, map->transitions[i].value);
+
+      if (res != 0)
+       return res;
+    }
+
+  return 0;
+}
+
+
+static const struct addrmap_funcs addrmap_fixed_funcs =
 {
-  .set_empty    = addrmap_fixed_set_empty,
-  .find         = addrmap_fixed_find,
-  .create_fixed = addrmap_fixed_create_fixed,
-  .relocate     = addrmap_fixed_relocate
+  addrmap_fixed_set_empty,
+  addrmap_fixed_find,
+  addrmap_fixed_create_fixed,
+  addrmap_fixed_relocate,
+  addrmap_fixed_foreach
 };
 
 
@@ -223,9 +249,9 @@ struct addrmap_mutable
 static splay_tree_key
 allocate_key (struct addrmap_mutable *map, CORE_ADDR addr)
 {
-  CORE_ADDR *key = obstack_alloc (map->obstack, sizeof (*key));
-  *key = addr;
+  CORE_ADDR *key = XOBNEW (map->obstack, CORE_ADDR);
 
+  *key = addr;
   return (splay_tree_key) key;
 }
 
@@ -252,6 +278,13 @@ addrmap_splay_tree_successor (struct addrmap_mutable *map, CORE_ADDR addr)
 }
 
 
+static void
+addrmap_splay_tree_remove (struct addrmap_mutable *map, CORE_ADDR addr)
+{
+  splay_tree_remove (map->tree, (splay_tree_key) &addr);
+}
+
+
 static CORE_ADDR
 addrmap_node_key (splay_tree_node node)
 {
@@ -274,7 +307,8 @@ addrmap_node_set_value (splay_tree_node node, void *value)
 
 
 static void
-addrmap_splay_tree_insert (struct addrmap_mutable *map, CORE_ADDR key, void *value)
+addrmap_splay_tree_insert (struct addrmap_mutable *map,
+                          CORE_ADDR key, void *value)
 {
   splay_tree_insert (map->tree,
                      allocate_key (map, key),
@@ -286,26 +320,26 @@ addrmap_splay_tree_insert (struct addrmap_mutable *map, CORE_ADDR key, void *val
    tree node at ADDR, even if it would represent a "transition" from
    one value to the same value.  */
 static void
-force_transition (struct addrmap_mutable *this, CORE_ADDR addr)
+force_transition (struct addrmap_mutable *self, CORE_ADDR addr)
 {
   splay_tree_node n
-    = addrmap_splay_tree_lookup (this, addr);
+    = addrmap_splay_tree_lookup (self, addr);
 
   if (! n)
     {
-      n = addrmap_splay_tree_predecessor (this, addr);
-      addrmap_splay_tree_insert (this, addr,
+      n = addrmap_splay_tree_predecessor (self, addr);
+      addrmap_splay_tree_insert (self, addr,
                                  n ? addrmap_node_value (n) : NULL);
     }
 }
 
 
 static void
-addrmap_mutable_set_empty (struct addrmap *this,
+addrmap_mutable_set_empty (struct addrmap *self,
                            CORE_ADDR start, CORE_ADDR end_inclusive,
                            void *obj)
 {
-  struct addrmap_mutable *map = (struct addrmap_mutable *) this;
+  struct addrmap_mutable *map = (struct addrmap_mutable *) self;
   splay_tree_node n, next;
   void *prior_value;
 
@@ -347,7 +381,7 @@ addrmap_mutable_set_empty (struct addrmap *this,
     {
       next = addrmap_splay_tree_successor (map, addrmap_node_key (n));
       if (addrmap_node_value (n) == prior_value)
-        splay_tree_remove (map->tree, addrmap_node_key (n));
+        addrmap_splay_tree_remove (map, addrmap_node_key (n));
       else
         prior_value = addrmap_node_value (n);
     }
@@ -355,10 +389,12 @@ addrmap_mutable_set_empty (struct addrmap *this,
 
 
 static void *
-addrmap_mutable_find (struct addrmap *this, CORE_ADDR addr)
+addrmap_mutable_find (struct addrmap *self, CORE_ADDR addr)
 {
   /* Not needed yet.  */
-  abort ();
+  internal_error (__FILE__, __LINE__,
+                  _("addrmap_find is not implemented yet "
+                    "for mutable addrmaps"));
 }
 
 
@@ -391,24 +427,24 @@ splay_foreach_copy (splay_tree_node n, void *closure)
 
 
 static struct addrmap *
-addrmap_mutable_create_fixed (struct addrmap *this, struct obstack *obstack)
+addrmap_mutable_create_fixed (struct addrmap *self, struct obstack *obstack)
 {
-  struct addrmap_mutable *mutable = (struct addrmap_mutable *) this;
+  struct addrmap_mutable *mutable_obj = (struct addrmap_mutable *) self;
   struct addrmap_fixed *fixed;
   size_t num_transitions;
+  size_t alloc_len;
 
   /* Count the number of transitions in the tree.  */
   num_transitions = 0;
-  splay_tree_foreach (mutable->tree, splay_foreach_count, &num_transitions);
+  splay_tree_foreach (mutable_obj->tree, splay_foreach_count, &num_transitions);
 
   /* Include an extra entry for the transition at zero (which fixed
      maps have, but mutable maps do not.)  */
   num_transitions++;
 
-  fixed = obstack_alloc (obstack,
-                         (sizeof (*fixed)
-                          + (num_transitions
-                             * sizeof (fixed->transitions[0]))));
+  alloc_len = sizeof (*fixed)
+             + (num_transitions * sizeof (fixed->transitions[0]));
+  fixed = (struct addrmap_fixed *) obstack_alloc (obstack, alloc_len);
   fixed->addrmap.funcs = &addrmap_fixed_funcs;
   fixed->num_transitions = 1;
   fixed->transitions[0].addr = 0;
@@ -416,7 +452,7 @@ addrmap_mutable_create_fixed (struct addrmap *this, struct obstack *obstack)
 
   /* Copy all entries from the splay tree to the array, in order 
      of increasing address.  */
-  splay_tree_foreach (mutable->tree, splay_foreach_copy, fixed);
+  splay_tree_foreach (mutable_obj->tree, splay_foreach_copy, fixed);
 
   /* We should have filled the array.  */
   gdb_assert (fixed->num_transitions == num_transitions);
@@ -426,26 +462,65 @@ addrmap_mutable_create_fixed (struct addrmap *this, struct obstack *obstack)
 
 
 static void
-addrmap_mutable_relocate (struct addrmap *this, CORE_ADDR offset)
+addrmap_mutable_relocate (struct addrmap *self, CORE_ADDR offset)
 {
   /* Not needed yet.  */
-  abort ();
+  internal_error (__FILE__, __LINE__,
+                  _("addrmap_relocate is not implemented yet "
+                    "for mutable addrmaps"));
 }
 
 
-static struct addrmap_funcs addrmap_mutable_funcs =
+/* Struct to map addrmap's foreach function to splay_tree's version.  */
+struct mutable_foreach_data
 {
-  .set_empty    = addrmap_mutable_set_empty,
-  .find         = addrmap_mutable_find,
-  .create_fixed = addrmap_mutable_create_fixed,
-  .relocate     = addrmap_mutable_relocate
+  addrmap_foreach_fn fn;
+  void *data;
+};
+
+
+/* This is a splay_tree_foreach_fn.  */
+
+static int
+addrmap_mutable_foreach_worker (splay_tree_node node, void *data)
+{
+  struct mutable_foreach_data *foreach_data
+    = (struct mutable_foreach_data *) data;
+
+  return foreach_data->fn (foreach_data->data,
+                          addrmap_node_key (node),
+                          addrmap_node_value (node));
+}
+
+
+static int
+addrmap_mutable_foreach (struct addrmap *self, addrmap_foreach_fn fn,
+                        void *data)
+{
+  struct addrmap_mutable *mutable_obj = (struct addrmap_mutable *) self;
+  struct mutable_foreach_data foreach_data;
+
+  foreach_data.fn = fn;
+  foreach_data.data = data;
+  return splay_tree_foreach (mutable_obj->tree, addrmap_mutable_foreach_worker,
+                            &foreach_data);
+}
+
+
+static const struct addrmap_funcs addrmap_mutable_funcs =
+{
+  addrmap_mutable_set_empty,
+  addrmap_mutable_find,
+  addrmap_mutable_create_fixed,
+  addrmap_mutable_relocate,
+  addrmap_mutable_foreach
 };
 
 
 static void *
 splay_obstack_alloc (int size, void *closure)
 {
-  struct addrmap_mutable *map = closure;
+  struct addrmap_mutable *map = (struct addrmap_mutable *) closure;
   splay_tree_node n;
 
   /* We should only be asked to allocate nodes and larger things.
@@ -467,8 +542,8 @@ splay_obstack_alloc (int size, void *closure)
 static void
 splay_obstack_free (void *obj, void *closure)
 {
-  struct addrmap_mutable *map = closure;
-  splay_tree_node n = obj;
+  struct addrmap_mutable *map = (struct addrmap_mutable *) closure;
+  splay_tree_node n = (splay_tree_node) obj;
 
   /* We've asserted in the allocation function that we only allocate
      nodes or larger things, so it should be safe to put whatever
@@ -498,7 +573,7 @@ splay_compare_CORE_ADDR_ptr (splay_tree_key ak, splay_tree_key bk)
 struct addrmap *
 addrmap_create_mutable (struct obstack *obstack)
 {
-  struct addrmap_mutable *map = obstack_alloc (obstack, sizeof (*map));
+  struct addrmap_mutable *map = XOBNEW (obstack, struct addrmap_mutable);
 
   map->addrmap.funcs = &addrmap_mutable_funcs;
   map->obstack = obstack;
@@ -517,16 +592,3 @@ addrmap_create_mutable (struct obstack *obstack)
 
   return (struct addrmap *) map;
 }
-
-
-\f
-/* Initialization.  */
-
-void
-_initialize_addrmap (void)
-{
-  /* Make sure splay trees can actually hold the values we want to 
-     store in them.  */
-  gdb_assert (sizeof (splay_tree_key) >= sizeof (CORE_ADDR *));
-  gdb_assert (sizeof (splay_tree_value) >= sizeof (void *));
-}
This page took 0.036996 seconds and 4 git commands to generate.