* gdbserver/low-hppabsd.c (read_inferior_memory): Add explicit
[deliverable/binutils-gdb.git] / gdb / target.c
index ec4d01eff0ba13c7a1da777312c8463cd2009484..f21518ff04de4ad8a437227e046e640981195870 100644 (file)
@@ -1,5 +1,6 @@
 /* Select target systems and architectures at runtime for GDB.
-   Copyright 1990, 1992-1995, 1998-2000 Free Software Foundation, Inc.
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
    This file is part of GDB.
@@ -21,7 +22,6 @@
 
 #include "defs.h"
 #include <errno.h>
-#include <ctype.h>
 #include "gdb_string.h"
 #include "target.h"
 #include "gdbcmd.h"
@@ -33,6 +33,7 @@
 #include "gdb_wait.h"
 #include "dcache.h"
 #include <signal.h>
+#include "regcache.h"
 
 extern int errno;
 
@@ -102,7 +103,8 @@ static void debug_to_store_registers (int);
 static void debug_to_prepare_to_store (void);
 
 static int
-debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *);
+debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct mem_attrib *, 
+                     struct target_ops *);
 
 static void debug_to_files_info (struct target_ops *);
 
@@ -379,7 +381,7 @@ cleanup_target (struct target_ops *t)
            (void (*) (void)) 
            noprocess);
   de_fault (to_xfer_memory, 
-           (int (*) (CORE_ADDR, char *, int, int, struct target_ops *)) 
+           (int (*) (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *)) 
            nomemory);
   de_fault (to_files_info, 
            (void (*) (struct target_ops *)) 
@@ -640,7 +642,7 @@ push_target (struct target_ops *t)
       fprintf_unfiltered (gdb_stderr,
                          "Magic number of %s target struct wrong\n",
                          t->to_shortname);
-      abort ();
+      internal_error (__FILE__, __LINE__, "failed internal consistency check");
     }
 
   /* Find the proper stratum to install this target in. */
@@ -736,7 +738,7 @@ pop_target (void)
   fprintf_unfiltered (gdb_stderr,
                      "pop_target couldn't find target %s\n",
                      current_target.to_shortname);
-  abort ();
+  internal_error (__FILE__, __LINE__, "failed internal consistency check");
 }
 
 #undef MIN
@@ -843,7 +845,8 @@ target_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
    Result is -1 on error, or the number of bytes transfered.  */
 
 int
-do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
+do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+               struct mem_attrib *attrib)
 {
   int res;
   int done = 0;
@@ -860,7 +863,7 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
 
   /* The quick case is that the top target can handle the transfer.  */
   res = current_target.to_xfer_memory
-    (memaddr, myaddr, len, write, &current_target);
+    (memaddr, myaddr, len, write, attrib, &current_target);
 
   /* If res <= 0 then we call it again in the loop.  Ah well. */
   if (res <= 0)
@@ -871,7 +874,7 @@ do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
          if (!t->to_has_memory)
            continue;
 
-         res = t->to_xfer_memory (memaddr, myaddr, len, write, t);
+         res = t->to_xfer_memory (memaddr, myaddr, len, write, attrib, t);
          if (res > 0)
            break;              /* Handled all or part of xfer */
          if (t->to_has_all_memory)
@@ -895,6 +898,8 @@ static int
 target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
 {
   int res;
+  int reg_len;
+  struct mem_region *region;
 
   /* Zero length requests are ok and require no work.  */
   if (len == 0)
@@ -904,22 +909,52 @@ target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write)
 
   while (len > 0)
     {
-      res = dcache_xfer_memory(target_dcache, memaddr, myaddr, len, write);
-      if (res <= 0)
+      region = lookup_mem_region(memaddr);
+      if (memaddr + len < region->hi)
+       reg_len = len;
+      else
+       reg_len = region->hi - memaddr;
+
+      switch (region->attrib.mode)
        {
-         /* If this address is for nonexistent memory,
-            read zeros if reading, or do nothing if writing.  Return error. */
+       case MEM_RO:
+         if (write)
+           return EIO;
+         break;
+         
+       case MEM_WO:
          if (!write)
-           memset (myaddr, 0, len);
-         if (errno == 0)
            return EIO;
-         else
-           return errno;
+         break;
        }
 
-      memaddr += res;
-      myaddr  += res;
-      len     -= res;
+      while (reg_len > 0)
+       {
+         if (region->attrib.cache)
+           res = dcache_xfer_memory(target_dcache, memaddr, myaddr,
+                                    reg_len, write);
+         else
+           res = do_xfer_memory(memaddr, myaddr, reg_len, write,
+                                &region->attrib);
+             
+         if (res <= 0)
+           {
+             /* If this address is for nonexistent memory, read zeros
+                if reading, or do nothing if writing.  Return
+                error. */
+             if (!write)
+               memset (myaddr, 0, len);
+             if (errno == 0)
+               return EIO;
+             else
+               return errno;
+           }
+
+         memaddr += res;
+         myaddr  += res;
+         len     -= res;
+         reg_len -= res;
+       }
     }
   
   return 0;                    /* We managed to cover it all somehow. */
@@ -935,6 +970,8 @@ target_xfer_memory_partial (CORE_ADDR memaddr, char *myaddr, int len,
                            int write_p, int *err)
 {
   int res;
+  int reg_len;
+  struct mem_region *region;
 
   /* Zero length requests are ok and require no work.  */
   if (len == 0)
@@ -943,7 +980,38 @@ target_xfer_memory_partial (CORE_ADDR memaddr, char *myaddr, int len,
       return 0;
     }
 
-  res = dcache_xfer_memory (target_dcache, memaddr, myaddr, len, write_p);
+  region = lookup_mem_region(memaddr);
+  if (memaddr + len < region->hi)
+    reg_len = len;
+  else
+    reg_len = region->hi - memaddr;
+
+  switch (region->attrib.mode)
+    {
+    case MEM_RO:
+      if (write_p)
+       {
+         *err = EIO;
+         return -1;
+       }
+      break;
+
+    case MEM_WO:
+      if (write_p)
+       {
+         *err = EIO;
+         return -1;
+       }
+      break;
+    }
+
+  if (region->attrib.cache)
+    res = dcache_xfer_memory (target_dcache, memaddr, myaddr,
+                             reg_len, write_p);
+  else
+    res = do_xfer_memory (memaddr, myaddr, reg_len, write_p,
+                         &region->attrib);
+      
   if (res <= 0)
     {
       if (errno != 0)
@@ -2313,11 +2381,13 @@ debug_to_prepare_to_store (void)
 
 static int
 debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
+                     struct mem_attrib *attrib,
                      struct target_ops *target)
 {
   int retval;
 
-  retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write, target);
+  retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write,
+                                       attrib, target);
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d",
@@ -2924,5 +2994,5 @@ When non-zero, target debugging is enabled.", &setdebuglist),
   target_dcache = dcache_init();
 
   if (!STREQ (signals[TARGET_SIGNAL_LAST].string, "TARGET_SIGNAL_MAGIC"))
-    abort ();
+    internal_error (__FILE__, __LINE__, "failed internal consistency check");
 }
This page took 0.028271 seconds and 4 git commands to generate.