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:
Pedro Alves
2011-12-06 20:03:14 +00:00
parent 31aba06f31
commit f0ba3972e9
8 changed files with 171 additions and 29 deletions

View 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) *