gdb/addrmap.c - gdb
Global variables defined
Data types defined
Functions defined
Source code
- #include "defs.h"
- #include "splay-tree.h"
- #include "gdb_obstack.h"
- #include "addrmap.h"
- struct addrmap_funcs
- {
- void (*set_empty) (struct addrmap *this,
- CORE_ADDR start, CORE_ADDR end_inclusive,
- void *obj);
- void *(*find) (struct addrmap *this, CORE_ADDR addr);
- struct addrmap *(*create_fixed) (struct addrmap *this,
- struct obstack *obstack);
- void (*relocate) (struct addrmap *this, CORE_ADDR offset);
- int (*foreach) (struct addrmap *this, addrmap_foreach_fn fn, void *data);
- };
- struct addrmap
- {
- const struct addrmap_funcs *funcs;
- };
- void
- addrmap_set_empty (struct addrmap *map,
- CORE_ADDR start, CORE_ADDR end_inclusive,
- void *obj)
- {
- map->funcs->set_empty (map, start, end_inclusive, obj);
- }
- void *
- addrmap_find (struct addrmap *map, CORE_ADDR addr)
- {
- return map->funcs->find (map, addr);
- }
- struct addrmap *
- addrmap_create_fixed (struct addrmap *original, struct obstack *obstack)
- {
- return original->funcs->create_fixed (original, obstack);
- }
- void
- addrmap_relocate (struct addrmap *map, CORE_ADDR offset)
- {
- map->funcs->relocate (map, offset);
- }
- int
- addrmap_foreach (struct addrmap *map, addrmap_foreach_fn fn, void *data)
- {
- return map->funcs->foreach (map, fn, data);
- }
- struct addrmap_transition
- {
- CORE_ADDR addr;
- void *value;
- };
- struct addrmap_fixed
- {
- struct addrmap addrmap;
-
- size_t num_transitions;
-
- struct addrmap_transition transitions[1];
- };
- static void
- addrmap_fixed_set_empty (struct addrmap *this,
- CORE_ADDR start, CORE_ADDR end_inclusive,
- void *obj)
- {
- internal_error (__FILE__, __LINE__,
- "addrmap_fixed_set_empty: "
- "fixed addrmaps can't be changed\n");
- }
- static void *
- addrmap_fixed_find (struct addrmap *this, CORE_ADDR addr)
- {
- struct addrmap_fixed *map = (struct addrmap_fixed *) this;
- struct addrmap_transition *bottom = &map->transitions[0];
- struct addrmap_transition *top = &map->transitions[map->num_transitions - 1];
- while (bottom < top)
- {
-
- struct addrmap_transition *mid = top - (top - bottom) / 2;
- if (mid->addr == addr)
- {
- bottom = mid;
- break;
- }
- else if (mid->addr < addr)
-
- bottom = mid;
- else
- top = mid - 1;
- }
- return bottom->value;
- }
- static struct addrmap *
- addrmap_fixed_create_fixed (struct addrmap *this, struct obstack *obstack)
- {
- 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)
- {
- struct addrmap_fixed *map = (struct addrmap_fixed *) this;
- size_t i;
- for (i = 0; i < map->num_transitions; i++)
- map->transitions[i].addr += offset;
- }
- static int
- addrmap_fixed_foreach (struct addrmap *this, addrmap_foreach_fn fn,
- void *data)
- {
- struct addrmap_fixed *map = (struct addrmap_fixed *) this;
- 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 =
- {
- addrmap_fixed_set_empty,
- addrmap_fixed_find,
- addrmap_fixed_create_fixed,
- addrmap_fixed_relocate,
- addrmap_fixed_foreach
- };
- struct addrmap_mutable
- {
- struct addrmap addrmap;
-
- struct obstack *obstack;
-
- splay_tree tree;
-
- splay_tree_node free_nodes;
- };
- static splay_tree_key
- allocate_key (struct addrmap_mutable *map, CORE_ADDR addr)
- {
- CORE_ADDR *key = obstack_alloc (map->obstack, sizeof (*key));
- *key = addr;
- return (splay_tree_key) key;
- }
- static splay_tree_node
- addrmap_splay_tree_lookup (struct addrmap_mutable *map, CORE_ADDR addr)
- {
- return splay_tree_lookup (map->tree, (splay_tree_key) &addr);
- }
- static splay_tree_node
- addrmap_splay_tree_predecessor (struct addrmap_mutable *map, CORE_ADDR addr)
- {
- return splay_tree_predecessor (map->tree, (splay_tree_key) &addr);
- }
- static splay_tree_node
- addrmap_splay_tree_successor (struct addrmap_mutable *map, CORE_ADDR addr)
- {
- return splay_tree_successor (map->tree, (splay_tree_key) &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)
- {
- return * (CORE_ADDR *) node->key;
- }
- static void *
- addrmap_node_value (splay_tree_node node)
- {
- return (void *) node->value;
- }
- static void
- addrmap_node_set_value (splay_tree_node node, void *value)
- {
- node->value = (splay_tree_value) value;
- }
- static void
- addrmap_splay_tree_insert (struct addrmap_mutable *map,
- CORE_ADDR key, void *value)
- {
- splay_tree_insert (map->tree,
- allocate_key (map, key),
- (splay_tree_value) value);
- }
- static void
- force_transition (struct addrmap_mutable *this, CORE_ADDR addr)
- {
- splay_tree_node n
- = addrmap_splay_tree_lookup (this, addr);
- if (! n)
- {
- n = addrmap_splay_tree_predecessor (this, addr);
- addrmap_splay_tree_insert (this, addr,
- n ? addrmap_node_value (n) : NULL);
- }
- }
- static void
- addrmap_mutable_set_empty (struct addrmap *this,
- CORE_ADDR start, CORE_ADDR end_inclusive,
- void *obj)
- {
- struct addrmap_mutable *map = (struct addrmap_mutable *) this;
- splay_tree_node n, next;
- void *prior_value;
-
- gdb_assert (obj);
-
-
- force_transition (map, start);
- if (end_inclusive < CORE_ADDR_MAX)
- force_transition (map, end_inclusive + 1);
-
- for (n = addrmap_splay_tree_lookup (map, start), gdb_assert (n);
- n && addrmap_node_key (n) <= end_inclusive;
- n = addrmap_splay_tree_successor (map, addrmap_node_key (n)))
- {
- if (! addrmap_node_value (n))
- addrmap_node_set_value (n, obj);
- }
-
- n = addrmap_splay_tree_predecessor (map, start);
- prior_value = n ? addrmap_node_value (n) : NULL;
- for (n = addrmap_splay_tree_lookup (map, start), gdb_assert (n);
- n && (end_inclusive == CORE_ADDR_MAX
- || addrmap_node_key (n) <= end_inclusive + 1);
- n = next)
- {
- next = addrmap_splay_tree_successor (map, addrmap_node_key (n));
- if (addrmap_node_value (n) == prior_value)
- addrmap_splay_tree_remove (map, addrmap_node_key (n));
- else
- prior_value = addrmap_node_value (n);
- }
- }
- static void *
- addrmap_mutable_find (struct addrmap *this, CORE_ADDR addr)
- {
-
- internal_error (__FILE__, __LINE__,
- _("addrmap_find is not implemented yet "
- "for mutable addrmaps"));
- }
- static int
- splay_foreach_count (splay_tree_node n, void *closure)
- {
- size_t *count = (size_t *) closure;
- (*count)++;
- return 0;
- }
- static int
- splay_foreach_copy (splay_tree_node n, void *closure)
- {
- struct addrmap_fixed *fixed = (struct addrmap_fixed *) closure;
- struct addrmap_transition *t = &fixed->transitions[fixed->num_transitions];
- t->addr = addrmap_node_key (n);
- t->value = addrmap_node_value (n);
- fixed->num_transitions++;
- return 0;
- }
- static struct addrmap *
- addrmap_mutable_create_fixed (struct addrmap *this, struct obstack *obstack)
- {
- struct addrmap_mutable *mutable = (struct addrmap_mutable *) this;
- struct addrmap_fixed *fixed;
- size_t num_transitions;
-
- num_transitions = 0;
- splay_tree_foreach (mutable->tree, splay_foreach_count, &num_transitions);
-
- num_transitions++;
- fixed = obstack_alloc (obstack,
- (sizeof (*fixed)
- + (num_transitions
- * sizeof (fixed->transitions[0]))));
- fixed->addrmap.funcs = &addrmap_fixed_funcs;
- fixed->num_transitions = 1;
- fixed->transitions[0].addr = 0;
- fixed->transitions[0].value = NULL;
-
- splay_tree_foreach (mutable->tree, splay_foreach_copy, fixed);
-
- gdb_assert (fixed->num_transitions == num_transitions);
- return (struct addrmap *) fixed;
- }
- static void
- addrmap_mutable_relocate (struct addrmap *this, CORE_ADDR offset)
- {
-
- internal_error (__FILE__, __LINE__,
- _("addrmap_relocate is not implemented yet "
- "for mutable addrmaps"));
- }
- struct mutable_foreach_data
- {
- addrmap_foreach_fn fn;
- void *data;
- };
- static int
- addrmap_mutable_foreach_worker (splay_tree_node node, void *data)
- {
- struct mutable_foreach_data *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 *this, addrmap_foreach_fn fn,
- void *data)
- {
- struct addrmap_mutable *mutable = (struct addrmap_mutable *) this;
- struct mutable_foreach_data foreach_data;
- foreach_data.fn = fn;
- foreach_data.data = data;
- return splay_tree_foreach (mutable->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;
- splay_tree_node n;
-
- gdb_assert (size >= sizeof (*n));
- if (map->free_nodes)
- {
- n = map->free_nodes;
- map->free_nodes = n->right;
- return n;
- }
- else
- return obstack_alloc (map->obstack, size);
- }
- static void
- splay_obstack_free (void *obj, void *closure)
- {
- struct addrmap_mutable *map = closure;
- splay_tree_node n = obj;
-
- n->right = map->free_nodes;
- map->free_nodes = n;
- }
- static int
- splay_compare_CORE_ADDR_ptr (splay_tree_key ak, splay_tree_key bk)
- {
- CORE_ADDR a = * (CORE_ADDR *) ak;
- CORE_ADDR b = * (CORE_ADDR *) bk;
-
- if (a < b)
- return -1;
- else if (a == b)
- return 0;
- else
- return 1;
- }
- struct addrmap *
- addrmap_create_mutable (struct obstack *obstack)
- {
- struct addrmap_mutable *map = obstack_alloc (obstack, sizeof (*map));
- map->addrmap.funcs = &addrmap_mutable_funcs;
- map->obstack = obstack;
-
- map->free_nodes = NULL;
- map->tree = splay_tree_new_with_allocator (splay_compare_CORE_ADDR_ptr,
- NULL,
- NULL,
- splay_obstack_alloc,
- splay_obstack_free,
- map);
- return (struct addrmap *) map;
- }
- extern initialize_file_ftype _initialize_addrmap;
- void
- _initialize_addrmap (void)
- {
-
- gdb_assert (sizeof (splay_tree_key) >= sizeof (CORE_ADDR *));
- gdb_assert (sizeof (splay_tree_value) >= sizeof (void *));
- }