]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/target.c
2011-12-06 Pedro Alves <pedro@codesourcery.com>
[thirdparty/binutils-gdb.git] / gdb / target.c
index 6358b00f487e80f71ba7a9c1f8928d9516c8700a..5700066415fdfd986c7ac3a16429eb85b34e55fa 100644 (file)
@@ -1388,19 +1388,15 @@ memory_xfer_live_readonly_partial (struct target_ops *ops,
    For docs see target.h, to_xfer_partial.  */
 
 static LONGEST
-memory_xfer_partial (struct target_ops *ops, enum target_object object,
-                    void *readbuf, const void *writebuf, ULONGEST memaddr,
-                    LONGEST len)
+memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
+                      void *readbuf, const void *writebuf, ULONGEST memaddr,
+                      LONGEST len)
 {
   LONGEST res;
   int reg_len;
   struct mem_region *region;
   struct inferior *inf;
 
-  /* Zero length requests are ok and require no work.  */
-  if (len == 0)
-    return 0;
-
   /* For accesses to unmapped overlay sections, read directly from
      files.  Must do this first, as MEMADDR may need adjustment.  */
   if (readbuf != NULL && overlay_debugging)
@@ -1551,11 +1547,7 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
       if (res <= 0)
        return -1;
       else
-       {
-         if (readbuf && !show_memory_breakpoints)
-           breakpoint_restore_shadows (readbuf, memaddr, reg_len);
-         return res;
-       }
+       return res;
     }
 
   /* If none of those methods found the memory we wanted, fall back
@@ -1584,9 +1576,6 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
     }
   while (ops != NULL);
 
-  if (res > 0 && readbuf != NULL && !show_memory_breakpoints)
-    breakpoint_restore_shadows (readbuf, memaddr, reg_len);
-
   /* Make sure the cache gets updated no matter what - if we are writing
      to the stack.  Even if this write is not tagged as such, we still need
      to update the cache.  */
@@ -1606,6 +1595,48 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
   return res;
 }
 
+/* Perform a partial memory transfer.  For docs see target.h,
+   to_xfer_partial.  */
+
+static LONGEST
+memory_xfer_partial (struct target_ops *ops, enum target_object object,
+                    void *readbuf, const void *writebuf, ULONGEST memaddr,
+                    LONGEST len)
+{
+  int res;
+
+  /* Zero length requests are ok and require no work.  */
+  if (len == 0)
+    return 0;
+
+  /* Fill in READBUF with breakpoint shadows, or WRITEBUF with
+     breakpoint insns, thus hiding out from higher layers whether
+     there are software breakpoints inserted in the code stream.  */
+  if (readbuf != NULL)
+    {
+      res = memory_xfer_partial_1 (ops, object, readbuf, NULL, memaddr, len);
+
+      if (res > 0 && !show_memory_breakpoints)
+       breakpoint_xfer_memory (readbuf, NULL, NULL, memaddr, res);
+    }
+  else
+    {
+      void *buf;
+      struct cleanup *old_chain;
+
+      buf = xmalloc (len);
+      old_chain = make_cleanup (xfree, buf);
+      memcpy (buf, writebuf, len);
+
+      breakpoint_xfer_memory (NULL, buf, writebuf, memaddr, len);
+      res = memory_xfer_partial_1 (ops, object, NULL, buf, memaddr, len);
+
+      do_cleanups (old_chain);
+    }
+
+  return res;
+}
+
 static void
 restore_show_memory_breakpoints (void *arg)
 {
@@ -1761,6 +1792,25 @@ target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
     return EIO;
 }
 
+/* Write LEN bytes from MYADDR to target raw memory at address
+   MEMADDR.  Returns either 0 for success or an errno value if any
+   error occurs.  If an error occurs, no guarantee is made about how
+   much data got written.  Callers that can deal with partial writes
+   should call target_write.  */
+
+int
+target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
+{
+  /* Dispatch to the topmost target, not the flattened current_target.
+     Memory accesses check target->to_has_(all_)memory, and the
+     flattened target doesn't inherit those.  */
+  if (target_write (current_target.beneath, TARGET_OBJECT_RAW_MEMORY, NULL,
+                   myaddr, memaddr, len) == len)
+    return 0;
+  else
+    return EIO;
+}
+
 /* Fetch the target's memory map.  */
 
 VEC(mem_region_s) *