diff options
author | Pedro Alves <palves@redhat.com> | 2011-12-06 20:03:14 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2011-12-06 20:03:14 +0000 |
commit | f0ba3972e968a8f328d2d465bbd1218e228fbf2a (patch) | |
tree | daeb62e5fc8f74947ee31f0f14a3bcccd14f2006 /gdb/target.c | |
parent | 31aba06f31d348be54adb50195af858baff6256f (diff) | |
download | gdb-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.c | 80 |
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) * |