|
|
@ -1388,19 +1388,15 @@ memory_xfer_live_readonly_partial (struct target_ops *ops, |
|
|
For docs see target.h, to_xfer_partial. */ |
|
|
For docs see target.h, to_xfer_partial. */ |
|
|
|
|
|
|
|
|
static LONGEST |
|
|
static LONGEST |
|
|
memory_xfer_partial (struct target_ops *ops, enum target_object object, |
|
|
memory_xfer_partial_1 (struct target_ops *ops, enum target_object object, |
|
|
void *readbuf, const void *writebuf, ULONGEST memaddr, |
|
|
void *readbuf, const void *writebuf, ULONGEST memaddr, |
|
|
LONGEST len) |
|
|
LONGEST len) |
|
|
{ |
|
|
{ |
|
|
LONGEST res; |
|
|
LONGEST res; |
|
|
int reg_len; |
|
|
int reg_len; |
|
|
struct mem_region *region; |
|
|
struct mem_region *region; |
|
|
struct inferior *inf; |
|
|
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
|
|
|
/* For accesses to unmapped overlay sections, read directly from
|
|
|
files. Must do this first, as MEMADDR may need adjustment. */ |
|
|
files. Must do this first, as MEMADDR may need adjustment. */ |
|
|
if (readbuf != NULL && overlay_debugging) |
|
|
if (readbuf != NULL && overlay_debugging) |
|
|
@ -1551,11 +1547,7 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object, |
|
|
if (res <= 0) |
|
|
if (res <= 0) |
|
|
return -1; |
|
|
return -1; |
|
|
else |
|
|
else |
|
|
{ |
|
|
return res; |
|
|
if (readbuf && !show_memory_breakpoints) |
|
|
|
|
|
breakpoint_restore_shadows (readbuf, memaddr, reg_len); |
|
|
|
|
|
return res; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* If none of those methods found the memory we wanted, fall back
|
|
|
/* 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); |
|
|
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
|
|
|
/* 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 the stack. Even if this write is not tagged as such, we still need |
|
|
to update the cache. */ |
|
|
to update the cache. */ |
|
|
@ -1606,6 +1595,48 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object, |
|
|
return res; |
|
|
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 |
|
|
static void |
|
|
restore_show_memory_breakpoints (void *arg) |
|
|
restore_show_memory_breakpoints (void *arg) |
|
|
{ |
|
|
{ |
|
|
@ -1761,6 +1792,25 @@ target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len) |
|
|
return EIO; |
|
|
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. */ |
|
|
/* Fetch the target's memory map. */ |
|
|
|
|
|
|
|
|
VEC(mem_region_s) * |
|
|
VEC(mem_region_s) * |
|
|
|