aboutsummaryrefslogtreecommitdiff
path: root/gdb/target.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2011-12-06 20:03:14 +0000
committerPedro Alves <palves@redhat.com>2011-12-06 20:03:14 +0000
commitf0ba3972e968a8f328d2d465bbd1218e228fbf2a (patch)
treedaeb62e5fc8f74947ee31f0f14a3bcccd14f2006 /gdb/target.c
parent31aba06f31d348be54adb50195af858baff6256f (diff)
downloadgdb-f0ba3972e968a8f328d2d465bbd1218e228fbf2a.zip
gdb-f0ba3972e968a8f328d2d465bbd1218e228fbf2a.tar.gz
gdb-f0ba3972e968a8f328d2d465bbd1218e228fbf2a.tar.bz2
2011-12-06 Pedro Alves <pedro@codesourcery.com>
gdb/ * breakpoint.c (breakpoint_restore_shadows): Rename to ... (breakpoint_xfer_memory): ... this. Change prototype. Handle memory writes too. * breakpoint.h (breakpoint_restore_shadows): Delete. (breakpoint_xfer_memory): Declare. * mem-break.c (default_memory_insert_breakpoint) (default_memory_remove_breakpoint): Use target_write_raw_memory. (memory_xfer_partial): Rename to ... (memory_xfer_partial_1): ... this. Don't mask out breakpoints here. (memory_xfer_partial): New. (target_write_raw_memory): New. * target.h (target_write_raw_memory): New. gdb/testsuite/ * gdb.base/break-always.exp: Test changing memory at addresses with breakpoints inserted.
Diffstat (limited to 'gdb/target.c')
-rw-r--r--gdb/target.c80
1 files changed, 65 insertions, 15 deletions
diff --git a/gdb/target.c b/gdb/target.c
index 6358b00..5700066 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -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) *