* regcache.c (regcache_xmalloc): Add aspace argument. Use it
[deliverable/binutils-gdb.git] / gdb / regcache.c
index 2604d287f7cbd9088f6edf547c065895beb1e1b0..d6f58fe9613bc1b29b4c370b3035ce66a20770a3 100644 (file)
@@ -1,7 +1,7 @@
 /* Cache and manage the values of registers for GDB, the GNU debugger.
 
    Copyright (C) 1986, 1987, 1989, 1991, 1994, 1995, 1996, 1998, 2000, 2001,
-   2002, 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
+   2002, 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -185,6 +185,11 @@ register_size (struct gdbarch *gdbarch, int regnum)
 struct regcache
 {
   struct regcache_descr *descr;
+
+  /* The address space of this register cache (for registers where it
+     makes sense, like PC or SP).  */
+  struct address_space *aspace;
+
   /* The register buffers.  A read-only register cache can hold the
      full [0 .. gdbarch_num_regs + gdbarch_num_pseudo_regs) while a read/write
      register cache can only hold [0 .. gdbarch_num_regs).  */
@@ -207,7 +212,7 @@ struct regcache
 };
 
 struct regcache *
-regcache_xmalloc (struct gdbarch *gdbarch)
+regcache_xmalloc (struct gdbarch *gdbarch, struct address_space *aspace)
 {
   struct regcache_descr *descr;
   struct regcache *regcache;
@@ -219,6 +224,7 @@ regcache_xmalloc (struct gdbarch *gdbarch)
     = XCALLOC (descr->sizeof_raw_registers, gdb_byte);
   regcache->register_valid_p
     = XCALLOC (descr->sizeof_raw_register_valid_p, gdb_byte);
+  regcache->aspace = aspace;
   regcache->readonly_p = 1;
   regcache->ptid = minus_one_ptid;
   return regcache;
@@ -254,6 +260,12 @@ get_regcache_arch (const struct regcache *regcache)
   return regcache->descr->gdbarch;
 }
 
+struct address_space *
+get_regcache_aspace (const struct regcache *regcache)
+{
+  return regcache->aspace;
+}
+
 /* Return  a pointer to register REGNUM's buffer cache.  */
 
 static gdb_byte *
@@ -340,10 +352,12 @@ regcache_cpy (struct regcache *dst, struct regcache *src)
 {
   int i;
   gdb_byte *buf;
+
   gdb_assert (src != NULL && dst != NULL);
   gdb_assert (src->descr->gdbarch == dst->descr->gdbarch);
   gdb_assert (src != dst);
   gdb_assert (src->readonly_p || dst->readonly_p);
+
   if (!src->readonly_p)
     regcache_save (dst, do_cooked_read, src);
   else if (!dst->readonly_p)
@@ -362,6 +376,7 @@ regcache_cpy_no_passthrough (struct regcache *dst, struct regcache *src)
      move of data into the current regcache.  Doing this would be
      silly - it would mean that valid_p would be completely invalid.  */
   gdb_assert (dst->readonly_p);
+
   memcpy (dst->registers, src->registers, dst->descr->sizeof_raw_registers);
   memcpy (dst->register_valid_p, src->register_valid_p,
          dst->descr->sizeof_raw_register_valid_p);
@@ -371,7 +386,7 @@ struct regcache *
 regcache_dup (struct regcache *src)
 {
   struct regcache *newbuf;
-  newbuf = regcache_xmalloc (src->descr->gdbarch);
+  newbuf = regcache_xmalloc (src->descr->gdbarch, get_regcache_aspace (src));
   regcache_cpy (newbuf, src);
   return newbuf;
 }
@@ -380,7 +395,7 @@ struct regcache *
 regcache_dup_no_passthrough (struct regcache *src)
 {
   struct regcache *newbuf;
-  newbuf = regcache_xmalloc (src->descr->gdbarch);
+  newbuf = regcache_xmalloc (src->descr->gdbarch, get_regcache_aspace (src));
   regcache_cpy_no_passthrough (newbuf, src);
   return newbuf;
 }
@@ -410,36 +425,62 @@ regcache_invalidate (struct regcache *regcache, int regnum)
 
 
 /* Global structure containing the current regcache.  */
-/* FIXME: cagney/2002-05-11: The two global arrays registers[] and
-   deprecated_register_valid[] currently point into this structure.  */
-static struct regcache *current_regcache;
 
 /* NOTE: this is a write-through cache.  There is no "dirty" bit for
    recording if the register values have been changed (eg. by the
    user).  Therefore all registers must be written back to the
    target when appropriate.  */
 
-struct regcache *get_thread_regcache (ptid_t ptid)
+struct regcache_list
 {
-  /* NOTE: uweigand/2007-05-05:  We need to detect the thread's
-     current architecture at this point.  */
-  struct gdbarch *thread_gdbarch = current_gdbarch;
+  struct regcache *regcache;
+  struct regcache_list *next;
+};
 
-  if (current_regcache && ptid_equal (current_regcache->ptid, ptid)
-      && get_regcache_arch (current_regcache) == thread_gdbarch)
-    return current_regcache;
+static struct regcache_list *current_regcache;
 
-  if (current_regcache)
-    regcache_xfree (current_regcache);
+struct regcache *
+get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch)
+{
+  struct regcache_list *list;
+  struct regcache *new_regcache;
+
+  for (list = current_regcache; list; list = list->next)
+    if (ptid_equal (list->regcache->ptid, ptid)
+       && get_regcache_arch (list->regcache) == gdbarch)
+      return list->regcache;
+
+  new_regcache = regcache_xmalloc (gdbarch,
+                                  target_thread_address_space (ptid));
+  new_regcache->readonly_p = 0;
+  new_regcache->ptid = ptid;
+  gdb_assert (new_regcache->aspace != NULL);
+
+  list = xmalloc (sizeof (struct regcache_list));
+  list->regcache = new_regcache;
+  list->next = current_regcache;
+  current_regcache = list;
+
+  return new_regcache;
+}
 
-  current_regcache = regcache_xmalloc (thread_gdbarch);
-  current_regcache->readonly_p = 0;
-  current_regcache->ptid = ptid;
+static ptid_t current_thread_ptid;
+static struct gdbarch *current_thread_arch;
 
-  return current_regcache;
+struct regcache *
+get_thread_regcache (ptid_t ptid)
+{
+  if (!current_thread_arch || !ptid_equal (current_thread_ptid, ptid))
+    {
+      current_thread_ptid = ptid;
+      current_thread_arch = target_thread_architecture (ptid);
+    }
+
+  return get_thread_arch_regcache (ptid, current_thread_arch);
 }
 
-struct regcache *get_current_regcache (void)
+struct regcache *
+get_current_regcache (void)
 {
   return get_thread_regcache (inferior_ptid);
 }
@@ -458,9 +499,11 @@ regcache_observer_target_changed (struct target_ops *target)
 static void
 regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
 {
-  if (current_regcache != NULL
-      && ptid_equal (current_regcache->ptid, old_ptid))
-    current_regcache->ptid = new_ptid;
+  struct regcache_list *list;
+
+  for (list = current_regcache; list; list = list->next)
+    if (ptid_equal (list->regcache->ptid, old_ptid))
+      list->regcache->ptid = new_ptid;
 }
 
 /* Low level examining and depositing of registers.
@@ -477,11 +520,20 @@ regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
 void
 registers_changed (void)
 {
-  int i;
+  struct regcache_list *list, *next;
+
+  for (list = current_regcache; list; list = next)
+    {
+      next = list->next;
+      regcache_xfree (list->regcache);
+      xfree (list);
+    }
 
-  regcache_xfree (current_regcache);
   current_regcache = NULL;
 
+  current_thread_ptid = null_ptid;
+  current_thread_arch = NULL;
+
   /* Need to forget about any frames we have cached, too. */
   reinit_frame_cache ();
 
@@ -535,8 +587,9 @@ regcache_raw_read_signed (struct regcache *regcache, int regnum, LONGEST *val)
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
   regcache_raw_read (regcache, regnum, buf);
-  (*val) = extract_signed_integer (buf,
-                                  regcache->descr->sizeof_register[regnum]);
+  (*val) = extract_signed_integer
+            (buf, regcache->descr->sizeof_register[regnum],
+             gdbarch_byte_order (regcache->descr->gdbarch));
 }
 
 void
@@ -548,8 +601,9 @@ regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_raw_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
   regcache_raw_read (regcache, regnum, buf);
-  (*val) = extract_unsigned_integer (buf,
-                                    regcache->descr->sizeof_register[regnum]);
+  (*val) = extract_unsigned_integer
+            (buf, regcache->descr->sizeof_register[regnum],
+             gdbarch_byte_order (regcache->descr->gdbarch));
 }
 
 void
@@ -559,7 +613,8 @@ regcache_raw_write_signed (struct regcache *regcache, int regnum, LONGEST val)
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
-  store_signed_integer (buf, regcache->descr->sizeof_register[regnum], val);
+  store_signed_integer (buf, regcache->descr->sizeof_register[regnum],
+                       gdbarch_byte_order (regcache->descr->gdbarch), val);
   regcache_raw_write (regcache, regnum, buf);
 }
 
@@ -571,7 +626,8 @@ regcache_raw_write_unsigned (struct regcache *regcache, int regnum,
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >=0 && regnum < regcache->descr->nr_raw_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
-  store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum], val);
+  store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum],
+                         gdbarch_byte_order (regcache->descr->gdbarch), val);
   regcache_raw_write (regcache, regnum, buf);
 }
 
@@ -602,8 +658,9 @@ regcache_cooked_read_signed (struct regcache *regcache, int regnum,
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
   regcache_cooked_read (regcache, regnum, buf);
-  (*val) = extract_signed_integer (buf,
-                                  regcache->descr->sizeof_register[regnum]);
+  (*val) = extract_signed_integer
+            (buf, regcache->descr->sizeof_register[regnum],
+             gdbarch_byte_order (regcache->descr->gdbarch));
 }
 
 void
@@ -615,8 +672,9 @@ regcache_cooked_read_unsigned (struct regcache *regcache, int regnum,
   gdb_assert (regnum >= 0 && regnum < regcache->descr->nr_cooked_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
   regcache_cooked_read (regcache, regnum, buf);
-  (*val) = extract_unsigned_integer (buf,
-                                    regcache->descr->sizeof_register[regnum]);
+  (*val) = extract_unsigned_integer
+            (buf, regcache->descr->sizeof_register[regnum],
+             gdbarch_byte_order (regcache->descr->gdbarch));
 }
 
 void
@@ -627,7 +685,8 @@ regcache_cooked_write_signed (struct regcache *regcache, int regnum,
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
-  store_signed_integer (buf, regcache->descr->sizeof_register[regnum], val);
+  store_signed_integer (buf, regcache->descr->sizeof_register[regnum],
+                       gdbarch_byte_order (regcache->descr->gdbarch), val);
   regcache_cooked_write (regcache, regnum, buf);
 }
 
@@ -639,7 +698,8 @@ regcache_cooked_write_unsigned (struct regcache *regcache, int regnum,
   gdb_assert (regcache != NULL);
   gdb_assert (regnum >=0 && regnum < regcache->descr->nr_cooked_registers);
   buf = alloca (regcache->descr->sizeof_register[regnum]);
-  store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum], val);
+  store_unsigned_integer (buf, regcache->descr->sizeof_register[regnum],
+                         gdbarch_byte_order (regcache->descr->gdbarch), val);
   regcache_cooked_write (regcache, regnum, buf);
 }
 
@@ -841,12 +901,6 @@ regcache_read_pc (struct regcache *regcache)
   return pc_val;
 }
 
-CORE_ADDR
-read_pc (void)
-{
-  return regcache_read_pc (get_current_regcache ());
-}
-
 void
 regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
@@ -860,12 +914,10 @@ regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
   else
     internal_error (__FILE__, __LINE__,
                    _("regcache_write_pc: Unable to update PC"));
-}
 
-void
-write_pc (CORE_ADDR pc)
-{
-  regcache_write_pc (get_current_regcache (), pc);
+  /* Writing the PC (for instance, from "load") invalidates the
+     current frame.  */
+  reinit_frame_cache ();
 }
 
 
This page took 0.029599 seconds and 4 git commands to generate.