(linux_unprepare_to_access_memory): New.
(linux_target_ops): Install them.
* server.c (read_memory): Rename to ...
(gdb_read_memory): ... this. Use
prepare_to_access_memory/prepare_to_access_memory.
(write_memory): Rename to ...
(gdb_write_memory): ... this. Use
prepare_to_access_memory/prepare_to_access_memory.
(handle_search_memory_1): Adjust.
(process_serial_event): Adjust.
* target.h (struct target_ops): New fields
prepare_to_access_memory and unprepare_to_access_memory.
(prepare_to_access_memory, unprepare_to_access_memory): New.
* linux-x86-low.c (x86_insert_point, x86_remove_point): Use
prepare_to_access_memory/prepare_to_access_memory.
* nto-low.c (nto_target_ops): Adjust.
* spu-low.c (spu_target_ops): Adjust.
* win32-low.c (win32_target_ops): Adjust.
+2010-08-26 Pedro Alves <pedro@codesourcery.com>
+
+ * linux-low.c (linux_prepare_to_access_memory): New.
+ (linux_unprepare_to_access_memory): New.
+ (linux_target_ops): Install them.
+ * server.c (read_memory): Rename to ...
+ (gdb_read_memory): ... this. Use
+ prepare_to_access_memory/prepare_to_access_memory.
+ (write_memory): Rename to ...
+ (gdb_write_memory): ... this. Use
+ prepare_to_access_memory/prepare_to_access_memory.
+ (handle_search_memory_1): Adjust.
+ (process_serial_event): Adjust.
+ * target.h (struct target_ops): New fields
+ prepare_to_access_memory and unprepare_to_access_memory.
+ (prepare_to_access_memory, unprepare_to_access_memory): New.
+ * linux-x86-low.c (x86_insert_point, x86_remove_point): Use
+ prepare_to_access_memory/prepare_to_access_memory.
+ * nto-low.c (nto_target_ops): Adjust.
+ * spu-low.c (spu_target_ops): Adjust.
+ * win32-low.c (win32_target_ops): Adjust.
+
2010-08-26 Pedro Alves <pedro@codesourcery.com>
* Makefile.in (WARN_CFLAGS): Get it from configure.
unstop_all_lwps (unfreeze, NULL);
}
+static int
+linux_prepare_to_access_memory (void)
+{
+ /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
+ running LWP. */
+ if (non_stop)
+ linux_pause_all (1);
+ return 0;
+}
+
+static void
+linux_unprepare_to_access_memory (void)
+{
+ /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
+ running LWP. */
+ if (non_stop)
+ linux_unpause_all (1);
+}
+
static int
linux_install_fast_tracepoint_jump_pad (CORE_ADDR tpoint, CORE_ADDR tpaddr,
CORE_ADDR collector,
linux_wait,
linux_fetch_registers,
linux_store_registers,
+ linux_prepare_to_access_memory,
+ linux_unprepare_to_access_memory,
linux_read_memory,
linux_write_memory,
linux_look_up_symbols,
return x86_linux_dr_get (ptid, DR_STATUS);
}
\f
-/* Watchpoint support. */
+/* Breakpoint/Watchpoint support. */
static int
x86_insert_point (char type, CORE_ADDR addr, int len)
switch (type)
{
case '0':
- return set_gdb_breakpoint_at (addr);
+ {
+ int ret;
+
+ ret = prepare_to_access_memory ();
+ if (ret)
+ return -1;
+ ret = set_gdb_breakpoint_at (addr);
+ unprepare_to_access_memory ();
+ return ret;
+ }
case '2':
case '3':
case '4':
switch (type)
{
case '0':
- return delete_gdb_breakpoint_at (addr);
+ {
+ int ret;
+
+ ret = prepare_to_access_memory ();
+ if (ret)
+ return -1;
+ ret = delete_gdb_breakpoint_at (addr);
+ unprepare_to_access_memory ();
+ return ret;
+ }
case '2':
case '3':
case '4':
nto_wait,
nto_fetch_registers,
nto_store_registers,
+ NULL, /* prepare_to_access_memory */
+ NULL, /* unprepare_to_access_memory */
nto_read_memory,
nto_write_memory,
NULL, /* nto_look_up_symbols */
/* Read trace frame or inferior memory. */
static int
-read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
+gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
+ int ret;
+
if (current_traceframe >= 0)
{
ULONGEST nbytes;
/* (assume no half-trace half-real blocks for now) */
}
- return read_inferior_memory (memaddr, myaddr, len);
+ ret = prepare_to_access_memory ();
+ if (ret == 0)
+ {
+ ret = read_inferior_memory (memaddr, myaddr, len);
+ unprepare_to_access_memory ();
+ }
+
+ return ret;
}
/* Write trace frame or inferior memory. Actually, writing to trace
frames is forbidden. */
static int
-write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
+gdb_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
{
if (current_traceframe >= 0)
return EIO;
else
- return write_inferior_memory (memaddr, myaddr, len);
+ {
+ int ret;
+
+ ret = prepare_to_access_memory ();
+ if (ret == 0)
+ {
+ ret = write_inferior_memory (memaddr, myaddr, len);
+ unprepare_to_access_memory ();
+ }
+ return ret;
+ }
}
/* Subroutine of handle_search_memory to simplify it. */
{
/* Prime the search buffer. */
- if (read_memory (start_addr, search_buf, search_buf_size) != 0)
+ if (gdb_read_memory (start_addr, search_buf, search_buf_size) != 0)
{
warning ("Unable to access target memory at 0x%lx, halting search.",
(long) start_addr);
? search_space_len - keep_len
: chunk_size);
- if (read_memory (read_addr, search_buf + keep_len,
- nr_to_read) != 0)
+ if (gdb_read_memory (read_addr, search_buf + keep_len,
+ nr_to_read) != 0)
{
warning ("Unable to access target memory at 0x%lx, halting search.",
(long) read_addr);
case 'm':
require_running (own_buf);
decode_m_packet (&own_buf[1], &mem_addr, &len);
- if (read_memory (mem_addr, mem_buf, len) == 0)
+ if (gdb_read_memory (mem_addr, mem_buf, len) == 0)
convert_int_to_ascii (mem_buf, own_buf, len);
else
write_enn (own_buf);
case 'M':
require_running (own_buf);
decode_M_packet (&own_buf[1], &mem_addr, &len, &mem_buf);
- if (write_memory (mem_addr, mem_buf, len) == 0)
+ if (gdb_write_memory (mem_addr, mem_buf, len) == 0)
write_ok (own_buf);
else
write_enn (own_buf);
require_running (own_buf);
if (decode_X_packet (&own_buf[1], packet_len - 1,
&mem_addr, &len, &mem_buf) < 0
- || write_memory (mem_addr, mem_buf, len) != 0)
+ || gdb_write_memory (mem_addr, mem_buf, len) != 0)
write_enn (own_buf);
else
write_ok (own_buf);
spu_wait,
spu_fetch_registers,
spu_store_registers,
+ NULL, /* prepare_to_access_memory */
+ NULL, /* unprepare_to_access_memory */
spu_read_memory,
spu_write_memory,
spu_look_up_symbols,
void (*store_registers) (struct regcache *regcache, int regno);
+ /* Prepare to read or write memory from the inferior process.
+ Targets use this to do what is necessary to get the state of the
+ inferior such that it is possible to access memory.
+
+ This should generally only be called from client facing routines,
+ such as gdb_read_memory/gdb_write_memory, or the insert_point
+ callbacks.
+
+ Like `read_memory' and `write_memory' below, returns 0 on success
+ and errno on failure. */
+
+ int (*prepare_to_access_memory) (void);
+
+ /* Undo the effects of prepare_to_access_memory. */
+
+ void (*unprepare_to_access_memory) (void);
+
/* Read memory from the inferior process. This should generally be
called through read_inferior_memory, which handles breakpoint shadowing.
ptid_t mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options,
int connected_wait);
+#define prepare_to_access_memory() \
+ (the_target->prepare_to_access_memory \
+ ? (*the_target->prepare_to_access_memory) () \
+ : 0)
+
+#define unprepare_to_access_memory() \
+ do \
+ { \
+ if (the_target->unprepare_to_access_memory) \
+ (*the_target->unprepare_to_access_memory) (); \
+ } while (0)
+
int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);
int write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
win32_wait,
win32_fetch_inferior_registers,
win32_store_inferior_registers,
+ NULL, /* prepare_to_access_memory */
+ NULL, /* unprepare_to_access_memory */
win32_read_inferior_memory,
win32_write_inferior_memory,
NULL, /* lookup_symbols */