* linux-low.c (linux_prepare_to_access_memory): New.
authorPedro Alves <palves@redhat.com>
Thu, 26 Aug 2010 23:17:22 +0000 (23:17 +0000)
committerPedro Alves <palves@redhat.com>
Thu, 26 Aug 2010 23:17:22 +0000 (23:17 +0000)
(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.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/gdbserver/linux-x86-low.c
gdb/gdbserver/nto-low.c
gdb/gdbserver/server.c
gdb/gdbserver/spu-low.c
gdb/gdbserver/target.h
gdb/gdbserver/win32-low.c

index 682d8f93783aeeb7afcf7866dba13887ce942405..b31695438ed60a70fe325aa7dd3dd4d900b3d4a2 100644 (file)
@@ -1,3 +1,25 @@
+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.
index 62d1fb883c0fc82f3262f5ea1a6f8b9d76f84f57..7fa9336e8cd550881cdafe50b683f57bcd51b21b 100644 (file)
@@ -5005,6 +5005,25 @@ linux_unpause_all (int unfreeze)
   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,
@@ -5043,6 +5062,8 @@ static struct target_ops linux_target_ops = {
   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,
index 841f0536132cdf22b9626639906e5c65998bdfb5..b169b75543397d78d60610d60cb8ee40ec36eedf 100644 (file)
@@ -546,7 +546,7 @@ i386_dr_low_get_status (void)
   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)
@@ -555,7 +555,16 @@ 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':
@@ -574,7 +583,16 @@ x86_remove_point (char type, CORE_ADDR addr, int len)
   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':
index 17548a42e1fc208639a40906402b1c3ddf91f9ce..4502ee7f92129a99ea24b2cec54979e56569f5cb 100644 (file)
@@ -913,6 +913,8 @@ static struct target_ops nto_target_ops = {
   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 */
index 9e87b20ae4eaa4438b841de7b906b9ed1e578b2b..5daf4b53f2d71d1c3f9797fe714da12590603683 100644 (file)
@@ -539,8 +539,10 @@ monitor_show_help (void)
 /* 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;
@@ -558,19 +560,36 @@ read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
       /* (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.  */
@@ -584,7 +603,7 @@ handle_search_memory_1 (CORE_ADDR start_addr, CORE_ADDR search_space_len,
 {
   /* 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);
@@ -635,8 +654,8 @@ handle_search_memory_1 (CORE_ADDR start_addr, CORE_ADDR search_space_len,
                        ? 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);
@@ -2924,7 +2943,7 @@ process_serial_event (void)
     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);
@@ -2932,7 +2951,7 @@ process_serial_event (void)
     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);
@@ -2941,7 +2960,7 @@ process_serial_event (void)
       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);
index 2188d64ede7ac1815ee4a7ee3224d5ead6c7590f..dc301b2ed164d05abef150e03cd450c643c0618c 100644 (file)
@@ -653,6 +653,8 @@ static struct target_ops spu_target_ops = {
   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,
index 1f9f921c68be5a6649f74cab76a795db24395256..8126f857f715febe455f2171b7fac8478eb2de3f 100644 (file)
@@ -181,6 +181,23 @@ struct target_ops
 
   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.
 
@@ -469,6 +486,18 @@ int start_non_stop (int nonstop);
 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,
index 72184f304f3661046a3c5b614d53ddbd1a906a84..f64673849cbac0004cf2b15ccaa0ab5313d3cf35 100644 (file)
@@ -1781,6 +1781,8 @@ static struct target_ops win32_target_ops = {
   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 */