2010-04-05 Stan Shebs <stan@codesourcery.com>
authorStan Shebs <shebs@codesourcery.com>
Mon, 5 Apr 2010 21:57:18 +0000 (21:57 +0000)
committerStan Shebs <shebs@codesourcery.com>
Mon, 5 Apr 2010 21:57:18 +0000 (21:57 +0000)
* tracepoint.c: Include gdbcore.h.
(tfile_xfer_partial): Return partial results, also try reading
from executable.
(tfile_has_all_memory): New function.
(init_tfile_ops): Use it.

* gdb.trace/tfile.c: Add a variable split across two blocks, and a
constant global.
* gdb.trace/tfile.exp: Try to print them.

gdb/ChangeLog
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.trace/tfile.c
gdb/testsuite/gdb.trace/tfile.exp
gdb/tracepoint.c

index 25f8a1d..46b161e 100644 (file)
@@ -1,3 +1,11 @@
+2010-04-05  Stan Shebs  <stan@codesourcery.com>
+
+       * tracepoint.c: Include gdbcore.h.
+       (tfile_xfer_partial): Return partial results, also try reading
+       from executable.
+       (tfile_has_all_memory): New function.
+       (init_tfile_ops): Use it.
+
 2010-04-05  Sergio Durigan Junior  <sergiodj@redhat.com>
 
        PR gdb/10736:
@@ -81,6 +89,7 @@
        * remote.c (remote_parse_stop_reply): Use hex_string instead
        of phex_nz for error.
 
+>>>>>>> 1.11571
 2010-04-01  Stan Shebs  <stan@codesourcery.com>
            Nathan Sidwell  <nathan@codesourcery.com>
 
index c748f94..1b2f843 100644 (file)
@@ -1,3 +1,9 @@
+2010-04-05  Stan Shebs  <stan@codesourcery.com>
+
+       * gdb.trace/tfile.c: Add a variable split across two blocks, and a
+       constant global.
+       * gdb.trace/tfile.exp: Try to print them.
+
 2010-04-04  Stan Shebs  <stan@codesourcery.com>
 
        * gdb.base/completion.exp: Update for new "info watchpoints".
index 4deba06..e9c1831 100644 (file)
@@ -15,6 +15,10 @@ char *tfsizeptr;
 
 int testglob = 31415;
 
+int testglob2 = 271828;
+
+const int constglob = 10000;
+
 int
 start_trace_file (char *filename)
 {
@@ -40,12 +44,30 @@ finish_trace_file (int fd)
   close (fd);
 }
 
+
+void
+add_memory_block (char *addr, int size)
+{
+  short short_x;
+  long long ll_x;
+
+  *((char *) trptr) = 'M';
+  trptr += 1;
+  ll_x = (long) addr;
+  memcpy (trptr, &ll_x, sizeof (long long));
+  trptr += sizeof (long long);
+  short_x = size;
+  memcpy (trptr, &short_x, 2);
+  trptr += 2;
+  memcpy (trptr, addr, size);
+  trptr += size;
+}
+
 void
 write_basic_trace_file (void)
 {
   int fd, int_x;
   short short_x;
-  long long ll_x;
 
   fd = start_trace_file ("basic.tf");
 
@@ -82,16 +104,10 @@ write_basic_trace_file (void)
   trptr += 2;
   tfsizeptr = trptr;
   trptr += 4;
-  *((char *) trptr) = 'M';
-  trptr += 1;
-  ll_x = (long) &testglob;
-  memcpy (trptr, &ll_x, sizeof (long long));
-  trptr += sizeof (long long);
-  short_x = sizeof (testglob);
-  memcpy (trptr, &short_x, 2);
-  trptr += 2;
-  memcpy (trptr, &testglob, sizeof (testglob));
-  trptr += sizeof (testglob);
+  add_memory_block (&testglob, sizeof (testglob));
+  /* Divide a variable between two separate memory blocks.  */
+  add_memory_block (&testglob2, 1);
+  add_memory_block (((char*) &testglob2) + 1, sizeof (testglob2) - 1);
   /* Go back and patch in the frame size.  */
   int_x = trptr - tfsizeptr - sizeof (int);
   memcpy (tfsizeptr, &int_x, 4);
index a0a73ee..2140a45 100644 (file)
@@ -74,8 +74,15 @@ gdb_test "tfind 0" \
 \#0  write_basic_trace_file ().*" \
     "tfind 0 on trace file"
 
+# Note that there is no tracepoint collecting these globals, we
+# just happen to know they are covered by the trace frame.
+
 gdb_test "print testglob" " = 31415" "print testglob on trace file"
 
+gdb_test "print testglob2" " = 271828" "print testglob2 on trace file"
+
+gdb_test "print constglob" " = 10000" "print constglob on trace file"
+
 gdb_test "tfind" "Target failed to find requested trace frame." \
     "tfind does not find a second frame in trace file"
 
index 0fb0e93..331d46c 100644 (file)
@@ -45,6 +45,7 @@
 #include "filenames.h"
 #include "gdbthread.h"
 #include "stack.h"
+#include "gdbcore.h"
 
 #include "ax.h"
 #include "ax-gdb.h"
@@ -3793,7 +3794,7 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object,
 {
   char block_type;
   int pos, gotten;
-  ULONGEST maddr;
+  ULONGEST maddr, amt;
   unsigned short mlen;
 
   /* We're only doing regular memory for now.  */
@@ -3831,16 +3832,19 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object,
            perror_with_name (trace_filename);
          else if (gotten < 2)
            error (_("Premature end of file while reading trace file"));
-         if (maddr <= offset && (offset + len) <= (maddr + mlen))
-           {
-             gotten = read (trace_fd, readbuf, mlen);
-             if (gotten < 0)
-               perror_with_name (trace_filename);
-             else if (gotten < mlen)
-               error (_("Premature end of file qwhile reading trace file"));
-
-             return mlen;
-           }
+         /* If the block includes the first part of the desired
+            range, return as much it has; GDB will re-request the
+            remainder, which might be in a different block of this
+            trace frame.  */
+         if (maddr <= offset && offset < (maddr + mlen))
+           {
+             amt = (maddr + mlen) - offset;
+             if (amt > len)
+               amt = len;
+
+             read (trace_fd, readbuf, amt);
+             return amt;
+           }
          lseek (trace_fd, mlen, SEEK_CUR);
          pos += (8 + 2 + mlen);
          break;
@@ -3854,6 +3858,38 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object,
          break;
        }
     }
+
+  /* It's unduly pedantic to refuse to look at the executable for
+     read-only pieces; so do the equivalent of readonly regions aka
+     QTro packet.  */
+  /* FIXME account for relocation at some point */
+  if (exec_bfd)
+    {
+      asection *s;
+      bfd_size_type size;
+      bfd_vma lma;
+
+      for (s = exec_bfd->sections; s; s = s->next)
+       {
+         if ((s->flags & SEC_LOAD) == 0 ||
+             (s->flags & SEC_READONLY) == 0)
+           continue;
+
+         lma = s->lma;
+         size = bfd_get_section_size (s);
+         if (lma <= offset && offset < (lma + size))
+           {
+             amt = (lma + size) - offset;
+             if (amt > len)
+               amt = len;
+
+             amt = bfd_get_section_contents (exec_bfd, s,
+                                             readbuf, offset - lma, amt);
+             return amt;
+           }
+       }
+    }
+
   /* Indicate failure to find the requested memory block.  */
   return -1;
 }
@@ -3923,6 +3959,12 @@ tfile_get_trace_state_variable_value (int tsvnum, LONGEST *val)
 }
 
 static int
+tfile_has_all_memory (struct target_ops *ops)
+{
+  return 1;
+}
+
+static int
 tfile_has_memory (struct target_ops *ops)
 {
   return 1;
@@ -3958,6 +4000,7 @@ init_tfile_ops (void)
   /* core_stratum might seem more logical, but GDB doesn't like having
      more than one core_stratum vector.  */
   tfile_ops.to_stratum = process_stratum;
+  tfile_ops.to_has_all_memory = tfile_has_all_memory;
   tfile_ops.to_has_memory = tfile_has_memory;
   tfile_ops.to_has_stack = tfile_has_stack;
   tfile_ops.to_has_registers = tfile_has_registers;