diff options
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.trace/tfile.c | 38 | ||||
-rw-r--r-- | gdb/testsuite/gdb.trace/tfile.exp | 7 | ||||
-rw-r--r-- | gdb/tracepoint.c | 65 |
5 files changed, 103 insertions, 22 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 25f8a1d..46b161e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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> diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c748f94..1b2f843 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -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". diff --git a/gdb/testsuite/gdb.trace/tfile.c b/gdb/testsuite/gdb.trace/tfile.c index 4deba06..e9c1831 100644 --- a/gdb/testsuite/gdb.trace/tfile.c +++ b/gdb/testsuite/gdb.trace/tfile.c @@ -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); diff --git a/gdb/testsuite/gdb.trace/tfile.exp b/gdb/testsuite/gdb.trace/tfile.exp index a0a73ee..2140a45 100644 --- a/gdb/testsuite/gdb.trace/tfile.exp +++ b/gdb/testsuite/gdb.trace/tfile.exp @@ -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" diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 0fb0e93..331d46c 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -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; |