Fix ChangeLog entry format
[deliverable/binutils-gdb.git] / gdb / gdbserver / regcache.c
index bed10b48a0e75f720d3a9c9325a0693bc64e06d2..2af8e241d98db5a8795682aa203f1585a4820ddb 100644 (file)
@@ -1,5 +1,5 @@
 /* Register support routines for the remote server for GDB.
-   Copyright (C) 2001-2014 Free Software Foundation, Inc.
+   Copyright (C) 2001-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdbthread.h"
 #include "tdesc.h"
 #include "rsp-low.h"
-
-#include <stdlib.h>
-#include <string.h>
-
 #ifndef IN_PROCESS_AGENT
 
 struct regcache *
@@ -32,7 +28,7 @@ get_thread_regcache (struct thread_info *thread, int fetch)
 {
   struct regcache *regcache;
 
-  regcache = (struct regcache *) inferior_regcache_data (thread);
+  regcache = inferior_regcache_data (thread);
 
   /* Threads' regcaches are created lazily, because biarch targets add
      the main thread/lwp before seeing it stop for the first time, and
@@ -45,8 +41,7 @@ get_thread_regcache (struct thread_info *thread, int fetch)
     {
       struct process_info *proc = get_thread_process (thread);
 
-      if (proc->tdesc == NULL)
-       fatal ("no target description");
+      gdb_assert (proc->tdesc != NULL);
 
       regcache = new_register_cache (proc->tdesc);
       set_inferior_regcache_data (thread, regcache);
@@ -54,34 +49,45 @@ get_thread_regcache (struct thread_info *thread, int fetch)
 
   if (fetch && regcache->registers_valid == 0)
     {
-      struct thread_info *saved_inferior = current_inferior;
+      struct thread_info *saved_thread = current_thread;
 
-      current_inferior = thread;
+      current_thread = thread;
+      /* Invalidate all registers, to prevent stale left-overs.  */
+      memset (regcache->register_status, REG_UNAVAILABLE,
+             regcache->tdesc->num_registers);
       fetch_inferior_registers (regcache, -1);
-      current_inferior = saved_inferior;
+      current_thread = saved_thread;
       regcache->registers_valid = 1;
     }
 
   return regcache;
 }
 
+/* See common/common-regcache.h.  */
+
+struct regcache *
+get_thread_regcache_for_ptid (ptid_t ptid)
+{
+  return get_thread_regcache (find_thread_ptid (ptid), 1);
+}
+
 void
 regcache_invalidate_thread (struct thread_info *thread)
 {
   struct regcache *regcache;
 
-  regcache = (struct regcache *) inferior_regcache_data (thread);
+  regcache = inferior_regcache_data (thread);
 
   if (regcache == NULL)
     return;
 
   if (regcache->registers_valid)
     {
-      struct thread_info *saved_inferior = current_inferior;
+      struct thread_info *saved_thread = current_thread;
 
-      current_inferior = thread;
+      current_thread = thread;
       store_inferior_registers (regcache, -1);
-      current_inferior = saved_inferior;
+      current_thread = saved_thread;
     }
 
   regcache->registers_valid = 0;
@@ -101,13 +107,23 @@ regcache_invalidate_one (struct inferior_list_entry *entry,
   return 0;
 }
 
+/* See regcache.h.  */
+
+void
+regcache_invalidate_pid (int pid)
+{
+  find_inferior (&all_threads, regcache_invalidate_one, &pid);
+}
+
+/* See regcache.h.  */
+
 void
 regcache_invalidate (void)
 {
   /* Only update the threads of the current process.  */
-  int pid = ptid_get_pid (current_inferior->entry.id);
+  int pid = ptid_get_pid (current_thread->entry.id);
 
-  find_inferior (&all_threads, regcache_invalidate_one, &pid);
+  regcache_invalidate_pid (pid);
 }
 
 #endif
@@ -117,25 +133,26 @@ init_register_cache (struct regcache *regcache,
                     const struct target_desc *tdesc,
                     unsigned char *regbuf)
 {
-#ifndef IN_PROCESS_AGENT
   if (regbuf == NULL)
     {
+#ifndef IN_PROCESS_AGENT
       /* Make sure to zero-initialize the register cache when it is
         created, in case there are registers the target never
         fetches.  This way they'll read as zero instead of
         garbage.  */
       regcache->tdesc = tdesc;
-      regcache->registers = xcalloc (1, tdesc->registers_size);
+      regcache->registers
+       = (unsigned char *) xcalloc (1, tdesc->registers_size);
       regcache->registers_owned = 1;
-      regcache->register_status = xcalloc (1, tdesc->num_registers);
-      gdb_assert (REG_UNAVAILABLE == 0);
-    }
-  else
+      regcache->register_status
+       = (unsigned char *) xmalloc (tdesc->num_registers);
+      memset ((void *) regcache->register_status, REG_UNAVAILABLE,
+             tdesc->num_registers);
 #else
-  if (regbuf == NULL)
-    fatal ("init_register_cache: can't allocate memory from the heap");
-  else
+      gdb_assert_not_reached ("can't allocate memory from the heap");
 #endif
+    }
+  else
     {
       regcache->tdesc = tdesc;
       regcache->registers = regbuf;
@@ -155,11 +172,10 @@ init_register_cache (struct regcache *regcache,
 struct regcache *
 new_register_cache (const struct target_desc *tdesc)
 {
-  struct regcache *regcache;
+  struct regcache *regcache = XCNEW (struct regcache);
 
   gdb_assert (tdesc->registers_size != 0);
 
-  regcache = xmalloc (sizeof (*regcache));
   return init_register_cache (regcache, tdesc, NULL);
 }
 
@@ -237,18 +253,6 @@ registers_from_string (struct regcache *regcache, char *buf)
   hex2bin (buf, registers, len / 2);
 }
 
-struct reg *
-find_register_by_name (const struct target_desc *tdesc, const char *name)
-{
-  int i;
-
-  for (i = 0; i < tdesc->num_registers; i++)
-    if (strcmp (name, tdesc->reg_defs[i].name) == 0)
-      return &tdesc->reg_defs[i];
-  fatal ("Unknown register %s requested", name);
-  return 0;
-}
-
 int
 find_regno (const struct target_desc *tdesc, const char *name)
 {
@@ -257,8 +261,8 @@ find_regno (const struct target_desc *tdesc, const char *name)
   for (i = 0; i < tdesc->num_registers; i++)
     if (strcmp (name, tdesc->reg_defs[i].name) == 0)
       return i;
-  fatal ("Unknown register %s requested", name);
-  return -1;
+  internal_error (__FILE__, __LINE__, "Unknown register %s requested",
+                 name);
 }
 
 struct reg *
@@ -273,8 +277,7 @@ find_register_by_number (const struct target_desc *tdesc, int n)
 static void
 free_register_cache_thread (struct thread_info *thread)
 {
-  struct regcache *regcache
-    = (struct regcache *) inferior_regcache_data (thread);
+  struct regcache *regcache = inferior_regcache_data (thread);
 
   if (regcache != NULL)
     {
@@ -312,6 +315,14 @@ register_size (const struct target_desc *tdesc, int n)
   return tdesc->reg_defs[n].size / 8;
 }
 
+/* See common/common-regcache.h.  */
+
+int
+regcache_register_size (const struct regcache *regcache, int n)
+{
+  return register_size (regcache->tdesc, n);
+}
+
 static unsigned char *
 register_data (struct regcache *regcache, int n, int fetch)
 {
@@ -413,6 +424,28 @@ collect_register (struct regcache *regcache, int n, void *buf)
          register_size (regcache->tdesc, n));
 }
 
+enum register_status
+regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
+                           ULONGEST *val)
+{
+  int size;
+
+  gdb_assert (regcache != NULL);
+  gdb_assert (regnum >= 0 && regnum < regcache->tdesc->num_registers);
+
+  size = register_size (regcache->tdesc, regnum);
+
+  if (size > (int) sizeof (ULONGEST))
+    error (_("That operation is not available on integers of more than"
+            "%d bytes."),
+          (int) sizeof (ULONGEST));
+
+  *val = 0;
+  collect_register (regcache, regnum, val);
+
+  return REG_VALID;
+}
+
 #ifndef IN_PROCESS_AGENT
 
 void
This page took 0.032242 seconds and 4 git commands to generate.