Add PR mention to previous commit
[deliverable/binutils-gdb.git] / gdb / dcache.c
index 804d567d1f8a24d9243c0abe4e515095a242e937..c8832fd36b5ba19479f92bf31787bc76ff061c67 100644 (file)
@@ -1,6 +1,6 @@
 /* Caching code for GDB, the GNU debugger.
 
-   Copyright (C) 1992-2013 Free Software Foundation, Inc.
+   Copyright (C) 1992-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -20,7 +20,6 @@
 #include "defs.h"
 #include "dcache.h"
 #include "gdbcmd.h"
-#include <string.h>
 #include "gdbcore.h"
 #include "target-dcache.h"
 #include "inferior.h"
@@ -126,9 +125,7 @@ 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 void info_dcache_command (char *exp, int tty);
 
 static int dcache_enabled_p = 0; /* OBSOLETE */
 
@@ -371,8 +368,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++;
     }
@@ -413,24 +411,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.
-
-   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.
+   The caller should have written the data through to target memory
+   already.
 
-   Always return 1 (meaning success) to simplify dcache_xfer_memory.  */
+   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.  */
 
-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
@@ -449,9 +443,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,
@@ -467,26 +459,17 @@ 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. 
-
-   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.  */
+/* 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.  */
 
-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.  */
@@ -497,35 +480,29 @@ dcache_xfer_memory (struct target_ops *ops, DCACHE *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
@@ -537,17 +514,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.  */
@@ -654,7 +640,7 @@ dcache_info_1 (DCACHE *dcache, char *exp)
 }
 
 static void
-dcache_info (char *exp, int tty)
+info_dcache_command (char *exp, int tty)
 {
   dcache_info_1 (target_dcache_get (), exp);
 }
@@ -686,15 +672,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, "");
 }
@@ -714,7 +700,7 @@ 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\
 With no arguments, this command prints the cache configuration and a\n\
This page took 0.041983 seconds and 4 git commands to generate.