mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 01:07:52 +00:00
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.
This commit is contained in:
80
gdb/target.c
80
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) *
|
||||
|
||||
Reference in New Issue
Block a user