Remove indirection from tui_data_window::regs_content
[external/binutils.git] / gdb / dcache.c
index dd66711..1716def 100644 (file)
@@ -1,6 +1,6 @@
 /* Caching code for GDB, the GNU debugger.
 
-   Copyright (C) 1992-2013 Free Software Foundation, Inc.
+   Copyright (C) 1992-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "defs.h"
 #include "dcache.h"
 #include "gdbcmd.h"
-#include <string.h>
 #include "gdbcore.h"
-#include "target.h"
+#include "target-dcache.h"
 #include "inferior.h"
 #include "splay-tree.h"
+#include "gdbarch.h"
 
 /* Commands with a prefix of `{set,show} dcache'.  */
 static struct cmd_list_element *dcache_set_list = NULL;
@@ -126,10 +126,6 @@ static int dcache_read_line (DCACHE *dcache, struct dcache_block *db);
 
 static struct dcache_block *dcache_alloc (DCACHE *dcache, CORE_ADDR addr);
 
-static void dcache_info (char *exp, int tty);
-
-void _initialize_dcache (void);
-
 static int dcache_enabled_p = 0; /* OBSOLETE */
 
 static void
@@ -336,15 +332,14 @@ dcache_read_line (DCACHE *dcache, struct dcache_block *db)
          len     -= reg_len;
          continue;
        }
-      
-      res = target_read (&current_target, TARGET_OBJECT_RAW_MEMORY,
-                        NULL, myaddr, memaddr, reg_len);
-      if (res < reg_len)
+
+      res = target_read_raw_memory (memaddr, myaddr, reg_len);
+      if (res != 0)
        return 0;
 
-      memaddr += res;
-      myaddr += res;
-      len -= res;
+      memaddr += reg_len;
+      myaddr += reg_len;
+      len -= reg_len;
     }
 
   return 1;
@@ -372,8 +367,9 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR addr)
       if (db)
        remove_block (&dcache->freelist, db);
       else
-       db = xmalloc (offsetof (struct dcache_block, data) +
-                     dcache->line_size);
+       db = ((struct dcache_block *)
+             xmalloc (offsetof (struct dcache_block, data)
+                      + dcache->line_size));
 
       dcache->size++;
     }
@@ -414,24 +410,20 @@ dcache_peek_byte (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr)
 
 /* Write the byte at PTR into ADDR in the data cache.
 
-   The caller is responsible for also promptly writing the data
-   through to target memory.
+   The caller should have written the data through to target memory
+   already.
 
-   If addr is not in cache, this function does nothing; writing to
-   an area of memory which wasn't present in the cache doesn't cause
-   it to be loaded in.
+   If ADDR is not in cache, this function does nothing; writing to an
+   area of memory which wasn't present in the cache doesn't cause it
+   to be loaded in.  */
 
-   Always return 1 (meaning success) to simplify dcache_xfer_memory.  */
-
-static int
-dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr)
+static void
+dcache_poke_byte (DCACHE *dcache, CORE_ADDR addr, const gdb_byte *ptr)
 {
   struct dcache_block *db = dcache_hit (dcache, addr);
 
   if (db)
     db->data[XFORM (dcache, addr)] = *ptr;
-
-  return 1;
 }
 
 static int
@@ -450,9 +442,7 @@ dcache_splay_tree_compare (splay_tree_key a, splay_tree_key b)
 DCACHE *
 dcache_init (void)
 {
-  DCACHE *dcache;
-
-  dcache = (DCACHE *) xmalloc (sizeof (*dcache));
+  DCACHE *dcache = XNEW (DCACHE);
 
   dcache->tree = splay_tree_new (dcache_splay_tree_compare,
                                 NULL,
@@ -468,65 +458,50 @@ dcache_init (void)
 }
 
 
-/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
-   to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
-   nonzero. 
+/* Read LEN bytes from dcache memory at MEMADDR, transferring to
+   debugger address MYADDR.  If the data is presently cached, this
+   fills the cache.  Arguments/return are like the target_xfer_partial
+   interface.  */
 
-   Return the number of bytes actually transfered, or -1 if the
-   transfer is not supported or otherwise fails.  Return of a non-negative
-   value less than LEN indicates that no further transfer is possible.
-   NOTE: This is different than the to_xfer_partial interface, in which
-   positive values less than LEN mean further transfers may be possible.  */
-
-int
-dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache,
-                   CORE_ADDR memaddr, gdb_byte *myaddr,
-                   int len, int should_write)
+enum target_xfer_status
+dcache_read_memory_partial (struct target_ops *ops, DCACHE *dcache,
+                           CORE_ADDR memaddr, gdb_byte *myaddr,
+                           ULONGEST len, ULONGEST *xfered_len)
 {
-  int i;
-  int res;
-  int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr);
-
-  xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;
+  ULONGEST i;
 
   /* If this is a different inferior from what we've recorded,
      flush the cache.  */
 
-  if (! ptid_equal (inferior_ptid, dcache->ptid))
+  if (inferior_ptid != dcache->ptid)
     {
       dcache_invalidate (dcache);
       dcache->ptid = inferior_ptid;
     }
 
-  /* Do write-through first, so that if it fails, we don't write to
-     the cache at all.  */
-
-  if (should_write)
-    {
-      res = target_write (ops, TARGET_OBJECT_RAW_MEMORY,
-                         NULL, myaddr, memaddr, len);
-      if (res <= 0)
-       return res;
-      /* Update LEN to what was actually written.  */
-      len = res;
-    }
-      
   for (i = 0; i < len; i++)
     {
-      if (!xfunc (dcache, memaddr + i, myaddr + i))
+      if (!dcache_peek_byte (dcache, memaddr + i, myaddr + i))
        {
          /* That failed.  Discard its cache line so we don't have a
             partially read line.  */
          dcache_invalidate_line (dcache, memaddr + i);
-         /* If we're writing, we still wrote LEN bytes.  */
-         if (should_write)
-           return len;
-         else
-           return i;
+         break;
        }
     }
-    
-  return len;
+
+  if (i == 0)
+    {
+      /* Even though reading the whole line failed, we may be able to
+        read a piece starting where the caller wanted.  */
+      return raw_memory_xfer_partial (ops, myaddr, NULL, memaddr, len,
+                                     xfered_len);
+    }
+  else
+    {
+      *xfered_len = i;
+      return TARGET_XFER_OK;
+    }
 }
 
 /* FIXME: There would be some benefit to making the cache write-back and
@@ -538,17 +513,26 @@ dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache,
    "logically" connected but not actually a single call to one of the
    memory transfer functions.  */
 
-/* Just update any cache lines which are already present.  This is called
-   by memory_xfer_partial in cases where the access would otherwise not go
-   through the cache.  */
+/* Just update any cache lines which are already present.  This is
+   called by the target_xfer_partial machinery when writing raw
+   memory.  */
 
 void
-dcache_update (DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+dcache_update (DCACHE *dcache, enum target_xfer_status status,
+              CORE_ADDR memaddr, const gdb_byte *myaddr,
+              ULONGEST len)
 {
-  int i;
+  ULONGEST i;
 
   for (i = 0; i < len; i++)
-    dcache_poke_byte (dcache, memaddr + i, myaddr + i);
+    if (status == TARGET_XFER_OK)
+      dcache_poke_byte (dcache, memaddr + i, myaddr + i);
+    else
+      {
+       /* Discard the whole cache line so we don't have a partially
+          valid line.  */
+       dcache_invalidate_line (dcache, memaddr + i);
+      }
 }
 
 /* Print DCACHE line INDEX.  */
@@ -600,7 +584,7 @@ dcache_print_line (DCACHE *dcache, int index)
 /* Parse EXP and show the info about DCACHE.  */
 
 static void
-dcache_info_1 (DCACHE *dcache, char *exp)
+dcache_info_1 (DCACHE *dcache, const char *exp)
 {
   splay_tree_node n;
   int i, refcount;
@@ -612,7 +596,7 @@ dcache_info_1 (DCACHE *dcache, char *exp)
       i = strtol (exp, &linestart, 10);
       if (linestart == exp || i < 0)
        {
-         printf_filtered (_("Usage: info dcache [linenumber]\n"));
+         printf_filtered (_("Usage: info dcache [LINENUMBER]\n"));
           return;
        }
 
@@ -625,14 +609,14 @@ dcache_info_1 (DCACHE *dcache, char *exp)
                   dcache ? (unsigned) dcache->line_size
                   : dcache_line_size);
 
-  if (dcache == NULL || ptid_equal (dcache->ptid, null_ptid))
+  if (dcache == NULL || dcache->ptid == null_ptid)
     {
       printf_filtered (_("No data cache available.\n"));
       return;
     }
 
   printf_filtered (_("Contains data for %s\n"),
-                  target_pid_to_str (dcache->ptid));
+                  target_pid_to_str (dcache->ptid).c_str ());
 
   refcount = 0;
 
@@ -655,13 +639,13 @@ dcache_info_1 (DCACHE *dcache, char *exp)
 }
 
 static void
-dcache_info (char *exp, int tty)
+info_dcache_command (const char *exp, int tty)
 {
   dcache_info_1 (target_dcache_get (), exp);
 }
 
 static void
-set_dcache_size (char *args, int from_tty,
+set_dcache_size (const char *args, int from_tty,
                 struct cmd_list_element *c)
 {
   if (dcache_size == 0)
@@ -673,7 +657,7 @@ set_dcache_size (char *args, int from_tty,
 }
 
 static void
-set_dcache_line_size (char *args, int from_tty,
+set_dcache_line_size (const char *args, int from_tty,
                      struct cmd_list_element *c)
 {
   if (dcache_line_size < 2
@@ -687,15 +671,15 @@ set_dcache_line_size (char *args, int from_tty,
 }
 
 static void
-set_dcache_command (char *arg, int from_tty)
+set_dcache_command (const char *arg, int from_tty)
 {
   printf_unfiltered (
      "\"set dcache\" must be followed by the name of a subcommand.\n");
-  help_list (dcache_set_list, "set dcache ", -1, gdb_stdout);
+  help_list (dcache_set_list, "set dcache ", all_commands, gdb_stdout);
 }
 
 static void
-show_dcache_command (char *args, int from_tty)
+show_dcache_command (const char *args, int from_tty)
 {
   cmd_show_list (dcache_show_list, from_tty, "");
 }
@@ -715,12 +699,13 @@ exists only for compatibility reasons."),
                           show_dcache_enabled_p,
                           &setlist, &showlist);
 
-  add_info ("dcache", dcache_info,
+  add_info ("dcache", info_dcache_command,
            _("\
 Print information on the dcache performance.\n\
+Usage: info dcache [LINENUMBER]\n\
 With no arguments, this command prints the cache configuration and a\n\
-summary of each line in the cache.  Use \"info dcache <lineno> to dump\"\n\
-the contents of a given line."));
+summary of each line in the cache.  With an argument, dump\"\n\
+the contents of the given line."));
 
   add_prefix_cmd ("dcache", class_obscure, set_dcache_command, _("\
 Use this command to set number of lines in dcache and line-size."),