* [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets
@ 2014-03-11 12:44 Yao Qi
2014-03-11 12:45 ` [PATCH 3/3] Remove target_read_live_memory Yao Qi
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Yao Qi @ 2014-03-11 12:44 UTC (permalink / raw)
To: gdb-patches
As a follow-up to
[PATCH 7/8] Adjust read_value_memory to use to_xfer_partial
https://sourceware.org/ml/gdb-patches/2014-02/msg00384.html
this patch moves traceframe_available_memory down to the target side.
After this patch, the gdb core code is cleaner, and code on handling
unavailable memory is moved to remote/tfile/ctf targets.
In details, this patch moves traceframe_available_memory code from
memory_xfer_partial_1 to remote target only, so remote target still
uses traceframe_info mechanism to check unavailable memory, and use
remote_ops to read them from read-only sections. We don't use
traceframe_info mechanism for tfile and ctf target, because it is
fast to iterate all traceframes from trace file, so the summary
information got from traceframe_info is not necessary.
This patch also moves two functions to remote.c from target.c,
because they are only used in remote.c. I'll clean them up in another
patch.
This series is tested on x86_64-linux.
gdb:
2014-03-11 Yao Qi <yao@codesourcery.com>
* ctf.c (ctf_xfer_partial): Check the return value of
exec_read_partial_read_only, if it is not TARGET_XFER_OK,
return TARGET_XFER_UNAVAILABLE.
* tracefile-tfile.c (tfile_xfer_partial): Likewise.
* target.c (target_read_live_memory): Move it to remote.c.
(memory_xfer_live_readonly_partial): Likewise.
(memory_xfer_partial_1): Move some code to remote_read_bytes.
* remote.c (target_read_live_memory): Moved from target.c.
(memory_xfer_live_readonly_partial): Likewise.
(remote_read_bytes): Moved from memory_xfer_partial_1.
---
gdb/ctf.c | 16 +++++-
gdb/remote.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++
gdb/target.c | 138 -------------------------------------------------
gdb/tracefile-tfile.c | 16 +++++-
4 files changed, 168 insertions(+), 140 deletions(-)
diff --git a/gdb/ctf.c b/gdb/ctf.c
index 95fd31f..ebd40d6 100644
--- a/gdb/ctf.c
+++ b/gdb/ctf.c
@@ -1377,6 +1377,7 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object,
{
struct bt_iter_pos *pos;
int i = 0;
+ enum target_xfer_status res;
gdb_assert (ctf_iter != NULL);
/* Save the current position. */
@@ -1466,7 +1467,20 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object,
/* Restore the position. */
bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos);
- return exec_read_partial_read_only (readbuf, offset, len, xfered_len);
+ /* Requested memory is unavailable in the context of traceframes,
+ and this address falls within a read-only section, fallback
+ to reading from executable. */
+ res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
+
+ if (res == TARGET_XFER_OK)
+ return TARGET_XFER_OK;
+ else
+ {
+ /* No use trying further, we know some memory starting
+ at MEMADDR isn't available. */
+ *xfered_len = len;
+ return TARGET_XFER_UNAVAILABLE;
+ }
}
else
{
diff --git a/gdb/remote.c b/gdb/remote.c
index e03d3bf..afe9d12 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -6824,6 +6824,87 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len,
packet_format[0], 1);
}
+/* Read memory from the live target, even if currently inspecting a
+ traceframe. The return is the same as that of target_read. */
+
+static enum target_xfer_status
+target_read_live_memory (enum target_object object,
+ ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len,
+ ULONGEST *xfered_len)
+{
+ enum target_xfer_status ret;
+ struct cleanup *cleanup;
+
+ /* Switch momentarily out of tfind mode so to access live memory.
+ Note that this must not clear global state, such as the frame
+ cache, which must still remain valid for the previous traceframe.
+ We may be _building_ the frame cache at this point. */
+ cleanup = make_cleanup_restore_traceframe_number ();
+ set_traceframe_number (-1);
+
+ ret = target_xfer_partial (current_target.beneath, object, NULL,
+ myaddr, NULL, memaddr, len, xfered_len);
+
+ do_cleanups (cleanup);
+ return ret;
+}
+
+/* Using the set of read-only target sections of OPS, read live
+ read-only memory. Note that the actual reads start from the
+ top-most target again.
+
+ For interface/parameters/return description see target.h,
+ to_xfer_partial. */
+
+static enum target_xfer_status
+memory_xfer_live_readonly_partial (struct target_ops *ops,
+ enum target_object object,
+ gdb_byte *readbuf, ULONGEST memaddr,
+ ULONGEST len, ULONGEST *xfered_len)
+{
+ struct target_section *secp;
+ struct target_section_table *table;
+
+ secp = target_section_by_addr (ops, memaddr);
+ if (secp != NULL
+ && (bfd_get_section_flags (secp->the_bfd_section->owner,
+ secp->the_bfd_section)
+ & SEC_READONLY))
+ {
+ struct target_section *p;
+ ULONGEST memend = memaddr + len;
+
+ table = target_get_section_table (ops);
+
+ for (p = table->sections; p < table->sections_end; p++)
+ {
+ if (memaddr >= p->addr)
+ {
+ if (memend <= p->endaddr)
+ {
+ /* Entire transfer is within this section. */
+ return target_read_live_memory (object, memaddr,
+ readbuf, len, xfered_len);
+ }
+ else if (memaddr >= p->endaddr)
+ {
+ /* This section ends before the transfer starts. */
+ continue;
+ }
+ else
+ {
+ /* This section overlaps the transfer. Just do half. */
+ len = p->endaddr - memaddr;
+ return target_read_live_memory (object, memaddr,
+ readbuf, len, xfered_len);
+ }
+ }
+ }
+ }
+
+ return TARGET_XFER_EOF;
+}
+
/* Read memory data directly from the remote machine.
This does not use the data cache; the data cache uses this.
MEMADDR is the address in the remote memory space.
@@ -6847,6 +6928,63 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len,
if (len == 0)
return 0;
+ if (get_traceframe_number () != -1)
+ {
+ VEC(mem_range_s) *available;
+
+ /* If we fail to get the set of available memory, then the
+ target does not support querying traceframe info, and so we
+ attempt reading from the traceframe anyway (assuming the
+ target implements the old QTro packet then). */
+ if (traceframe_available_memory (&available, memaddr, len))
+ {
+ struct cleanup *old_chain;
+
+ old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available);
+
+ if (VEC_empty (mem_range_s, available)
+ || VEC_index (mem_range_s, available, 0)->start != memaddr)
+ {
+ enum target_xfer_status res;
+
+ /* Don't read into the traceframe's available
+ memory. */
+ if (!VEC_empty (mem_range_s, available))
+ {
+ LONGEST oldlen = len;
+
+ len = VEC_index (mem_range_s, available, 0)->start - memaddr;
+ gdb_assert (len <= oldlen);
+ }
+
+ do_cleanups (old_chain);
+
+ /* This goes through the topmost target again. */
+ res = memory_xfer_live_readonly_partial (&remote_ops,
+ TARGET_OBJECT_MEMORY,
+ myaddr, memaddr,
+ len, xfered_len);
+ if (res == TARGET_XFER_OK)
+ return TARGET_XFER_OK;
+ else
+ {
+ /* No use trying further, we know some memory starting
+ at MEMADDR isn't available. */
+ *xfered_len = len;
+ return TARGET_XFER_UNAVAILABLE;
+ }
+ }
+
+ /* Don't try to read more than how much is available, in
+ case the target implements the deprecated QTro packet to
+ cater for older GDBs (the target's knowledge of read-only
+ sections may be outdated by now). */
+ len = VEC_index (mem_range_s, available, 0)->length;
+
+ do_cleanups (old_chain);
+ }
+ }
+
max_buf_size = get_memory_read_packet_size ();
/* The packet buffer will be large enough for the payload;
get_memory_packet_size ensures this. */
diff --git a/gdb/target.c b/gdb/target.c
index f7868c0..c2669c6 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -961,87 +961,6 @@ target_section_by_addr (struct target_ops *target, CORE_ADDR addr)
return NULL;
}
-/* Read memory from the live target, even if currently inspecting a
- traceframe. The return is the same as that of target_read. */
-
-static enum target_xfer_status
-target_read_live_memory (enum target_object object,
- ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len,
- ULONGEST *xfered_len)
-{
- enum target_xfer_status ret;
- struct cleanup *cleanup;
-
- /* Switch momentarily out of tfind mode so to access live memory.
- Note that this must not clear global state, such as the frame
- cache, which must still remain valid for the previous traceframe.
- We may be _building_ the frame cache at this point. */
- cleanup = make_cleanup_restore_traceframe_number ();
- set_traceframe_number (-1);
-
- ret = target_xfer_partial (current_target.beneath, object, NULL,
- myaddr, NULL, memaddr, len, xfered_len);
-
- do_cleanups (cleanup);
- return ret;
-}
-
-/* Using the set of read-only target sections of OPS, read live
- read-only memory. Note that the actual reads start from the
- top-most target again.
-
- For interface/parameters/return description see target.h,
- to_xfer_partial. */
-
-static enum target_xfer_status
-memory_xfer_live_readonly_partial (struct target_ops *ops,
- enum target_object object,
- gdb_byte *readbuf, ULONGEST memaddr,
- ULONGEST len, ULONGEST *xfered_len)
-{
- struct target_section *secp;
- struct target_section_table *table;
-
- secp = target_section_by_addr (ops, memaddr);
- if (secp != NULL
- && (bfd_get_section_flags (secp->the_bfd_section->owner,
- secp->the_bfd_section)
- & SEC_READONLY))
- {
- struct target_section *p;
- ULONGEST memend = memaddr + len;
-
- table = target_get_section_table (ops);
-
- for (p = table->sections; p < table->sections_end; p++)
- {
- if (memaddr >= p->addr)
- {
- if (memend <= p->endaddr)
- {
- /* Entire transfer is within this section. */
- return target_read_live_memory (object, memaddr,
- readbuf, len, xfered_len);
- }
- else if (memaddr >= p->endaddr)
- {
- /* This section ends before the transfer starts. */
- continue;
- }
- else
- {
- /* This section overlaps the transfer. Just do half. */
- len = p->endaddr - memaddr;
- return target_read_live_memory (object, memaddr,
- readbuf, len, xfered_len);
- }
- }
- }
- }
-
- return TARGET_XFER_EOF;
-}
-
/* Read memory from more than one valid target. A core file, for
instance, could have some of memory but delegate other bits to
the target below it. So, we must manually try all targets. */
@@ -1149,63 +1068,6 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
}
}
- /* If reading unavailable memory in the context of traceframes, and
- this address falls within a read-only section, fallback to
- reading from live memory. */
- if (readbuf != NULL && get_traceframe_number () != -1)
- {
- VEC(mem_range_s) *available;
-
- /* If we fail to get the set of available memory, then the
- target does not support querying traceframe info, and so we
- attempt reading from the traceframe anyway (assuming the
- target implements the old QTro packet then). */
- if (traceframe_available_memory (&available, memaddr, len))
- {
- struct cleanup *old_chain;
-
- old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available);
-
- if (VEC_empty (mem_range_s, available)
- || VEC_index (mem_range_s, available, 0)->start != memaddr)
- {
- /* Don't read into the traceframe's available
- memory. */
- if (!VEC_empty (mem_range_s, available))
- {
- LONGEST oldlen = len;
-
- len = VEC_index (mem_range_s, available, 0)->start - memaddr;
- gdb_assert (len <= oldlen);
- }
-
- do_cleanups (old_chain);
-
- /* This goes through the topmost target again. */
- res = memory_xfer_live_readonly_partial (ops, object,
- readbuf, memaddr,
- len, xfered_len);
- if (res == TARGET_XFER_OK)
- return TARGET_XFER_OK;
- else
- {
- /* No use trying further, we know some memory starting
- at MEMADDR isn't available. */
- *xfered_len = len;
- return TARGET_XFER_UNAVAILABLE;
- }
- }
-
- /* Don't try to read more than how much is available, in
- case the target implements the deprecated QTro packet to
- cater for older GDBs (the target's knowledge of read-only
- sections may be outdated by now). */
- len = VEC_index (mem_range_s, available, 0)->length;
-
- do_cleanups (old_chain);
- }
- }
-
/* Try GDB's internal data cache. */
region = lookup_mem_region (memaddr);
/* region->hi == 0 means there's no upper bound. */
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index cbf746d..a36596f 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -900,6 +900,7 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object,
if (get_traceframe_number () != -1)
{
int pos = 0;
+ enum target_xfer_status res;
/* Iterate through the traceframe's blocks, looking for
memory. */
@@ -937,7 +938,20 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object,
pos += (8 + 2 + mlen);
}
- return exec_read_partial_read_only (readbuf, offset, len, xfered_len);
+ /* Requested memory is unavailable in the context of traceframes,
+ and this address falls within a read-only section, fallback
+ to reading from executable. */
+ res = exec_read_partial_read_only (readbuf, offset, len, xfered_len);
+
+ if (res == TARGET_XFER_OK)
+ return TARGET_XFER_OK;
+ else
+ {
+ /* No use trying further, we know some memory starting
+ at MEMADDR isn't available. */
+ *xfered_len = len;
+ return TARGET_XFER_UNAVAILABLE;
+ }
}
else
{
--
1.7.7.6
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 3/3] Remove target_read_live_memory 2014-03-11 12:44 [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets Yao Qi @ 2014-03-11 12:45 ` Yao Qi 2014-03-21 12:01 ` Pedro Alves 2014-03-11 12:45 ` [PATCH 2/3] Factor remote_read_bytes Yao Qi ` (2 subsequent siblings) 3 siblings, 1 reply; 9+ messages in thread From: Yao Qi @ 2014-03-11 12:45 UTC (permalink / raw) To: gdb-patches As we move code on reading unavailable memory to target side, GDB core side doesn't need the "switching momentarily out of tfind mode" dance. The target remote knows how to read live memory (through remote_ops). Remove set_traceframe_number and make_cleanup_restore_traceframe_number, since they are no longer used. gdb: 2014-03-11 Yao Qi <yao@codesourcery.com> * remote.c (target_read_live_memory): Remove. (memory_xfer_live_readonly_partial): Rename it to remote_xfer_live_readonly_partial. Remove arguments 'ops' and 'object'. All callers updated. Call remote_read_bytes_1 instead of target_read_live_memory. * tracepoint.c (set_traceframe_number): Remove. (make_cleanup_restore_traceframe_number): Likewise . * tracepoint.h (set_traceframe_number): Remove declaration. (make_cleanup_restore_traceframe_number): Likewise. --- gdb/remote.c | 47 +++++++++-------------------------------------- gdb/tracepoint.c | 15 --------------- gdb/tracepoint.h | 9 --------- 3 files changed, 9 insertions(+), 62 deletions(-) diff --git a/gdb/remote.c b/gdb/remote.c index b5c6b4b..c31d986 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -6874,46 +6874,19 @@ remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, return TARGET_XFER_OK; } -/* Read memory from the live target, even if currently inspecting a - traceframe. The return is the same as that of target_read. */ - -static enum target_xfer_status -target_read_live_memory (enum target_object object, - ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len, - ULONGEST *xfered_len) -{ - enum target_xfer_status ret; - struct cleanup *cleanup; - - /* Switch momentarily out of tfind mode so to access live memory. - Note that this must not clear global state, such as the frame - cache, which must still remain valid for the previous traceframe. - We may be _building_ the frame cache at this point. */ - cleanup = make_cleanup_restore_traceframe_number (); - set_traceframe_number (-1); - - ret = target_xfer_partial (current_target.beneath, object, NULL, - myaddr, NULL, memaddr, len, xfered_len); - - do_cleanups (cleanup); - return ret; -} - -/* Using the set of read-only target sections of OPS, read live - read-only memory. Note that the actual reads start from the - top-most target again. +/* Using the set of read-only target sections of remote, read live + read-only memory. For interface/parameters/return description see target.h, to_xfer_partial. */ static enum target_xfer_status -memory_xfer_live_readonly_partial (struct target_ops *ops, - enum target_object object, - gdb_byte *readbuf, ULONGEST memaddr, +remote_xfer_live_readonly_partial (gdb_byte *readbuf, ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len) { struct target_section *secp; struct target_section_table *table; + struct target_ops *ops = &remote_ops; secp = target_section_by_addr (ops, memaddr); if (secp != NULL @@ -6933,8 +6906,8 @@ memory_xfer_live_readonly_partial (struct target_ops *ops, if (memend <= p->endaddr) { /* Entire transfer is within this section. */ - return target_read_live_memory (object, memaddr, - readbuf, len, xfered_len); + return remote_read_bytes_1 (memaddr, readbuf, len, + xfered_len); } else if (memaddr >= p->endaddr) { @@ -6945,8 +6918,8 @@ memory_xfer_live_readonly_partial (struct target_ops *ops, { /* This section overlaps the transfer. Just do half. */ len = p->endaddr - memaddr; - return target_read_live_memory (object, memaddr, - readbuf, len, xfered_len); + return remote_read_bytes_1 (memaddr, readbuf, len, + xfered_len); } } } @@ -6998,9 +6971,7 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, do_cleanups (old_chain); /* This goes through the topmost target again. */ - res = memory_xfer_live_readonly_partial (&remote_ops, - TARGET_OBJECT_MEMORY, - myaddr, memaddr, + res = remote_xfer_live_readonly_partial (myaddr, memaddr, len, xfered_len); if (res == TARGET_XFER_OK) return TARGET_XFER_OK; diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 673fddd..c522193 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -3216,15 +3216,6 @@ set_current_traceframe (int num) clear_traceframe_info (); } -/* Make the traceframe NUM be the current trace frame, and do nothing - more. */ - -void -set_traceframe_number (int num) -{ - traceframe_number = num; -} - /* A cleanup used when switching away and back from tfind mode. */ struct current_traceframe_cleanup @@ -3261,12 +3252,6 @@ make_cleanup_restore_current_traceframe (void) restore_current_traceframe_cleanup_dtor); } -struct cleanup * -make_cleanup_restore_traceframe_number (void) -{ - return make_cleanup_restore_integer (&traceframe_number); -} - /* Given a number and address, return an uploaded tracepoint with that number, creating if necessary. */ diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h index 8a1abbf..39b5edb 100644 --- a/gdb/tracepoint.h +++ b/gdb/tracepoint.h @@ -269,21 +269,12 @@ extern int get_traceframe_number (void); /* Returns the tracepoint number for current traceframe. */ extern int get_tracepoint_number (void); -/* Make the traceframe NUM be the current GDB trace frame number, and - do nothing more. In particular, this does not flush the - register/frame caches or notify the target about the trace frame - change, so that is can be used when we need to momentarily access - live memory. Targets lazily switch their current traceframe to - match GDB's traceframe number, at the appropriate times. */ -extern void set_traceframe_number (int); - /* Make the traceframe NUM be the current trace frame, all the way to the target, and flushes all global state (register/frame caches, etc.). */ extern void set_current_traceframe (int num); struct cleanup *make_cleanup_restore_current_traceframe (void); -struct cleanup *make_cleanup_restore_traceframe_number (void); void free_actions (struct breakpoint *); -- 1.7.7.6 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] Remove target_read_live_memory 2014-03-11 12:45 ` [PATCH 3/3] Remove target_read_live_memory Yao Qi @ 2014-03-21 12:01 ` Pedro Alves 2014-03-22 11:23 ` Yao Qi 0 siblings, 1 reply; 9+ messages in thread From: Pedro Alves @ 2014-03-21 12:01 UTC (permalink / raw) To: Yao Qi; +Cc: gdb-patches On 03/11/2014 12:42 PM, Yao Qi wrote: > As we move code on reading unavailable memory to target side, GDB core > side doesn't need the "switching momentarily out of tfind mode" dance. > The target remote knows how to read live memory (through remote_ops). > > Remove set_traceframe_number and > make_cleanup_restore_traceframe_number, since they are no longer used. Awesome. Thanks for doing this. > - > -/* Using the set of read-only target sections of OPS, read live > - read-only memory. Note that the actual reads start from the > - top-most target again. > +/* Using the set of read-only target sections of remote, read live > + read-only memory. > > For interface/parameters/return description see target.h, > to_xfer_partial. */ > > static enum target_xfer_status > -memory_xfer_live_readonly_partial (struct target_ops *ops, > - enum target_object object, > - gdb_byte *readbuf, ULONGEST memaddr, > +remote_xfer_live_readonly_partial (gdb_byte *readbuf, ULONGEST memaddr, > ULONGEST len, ULONGEST *xfered_len) > { > struct target_section *secp; > struct target_section_table *table; > + struct target_ops *ops = &remote_ops; This reference to remote_ops must be removed, per my comment to patch 1. IOW, OPS needs to stay. (The intro comment should then still say "of OPS".) Otherwise looks good. Thanks, -- Pedro Alves ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] Remove target_read_live_memory 2014-03-21 12:01 ` Pedro Alves @ 2014-03-22 11:23 ` Yao Qi 0 siblings, 0 replies; 9+ messages in thread From: Yao Qi @ 2014-03-22 11:23 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches On 03/21/2014 08:00 PM, Pedro Alves wrote: > This reference to remote_ops must be removed, per my comment to patch 1. > IOW, OPS needs to stay. (The intro comment should then still say "of > OPS".) OK, still keep OPS in remote_xfer_live_readonly_partial. Patch below is pushed in. -- Yao (é½å°§) Subject: [PATCH 3/3] Remove target_read_live_memory As we move code on reading unavailable memory to target side, GDB core side doesn't need the "switching momentarily out of tfind mode" dance. The target remote knows how to read live memory (through remote_ops). Remove set_traceframe_number and make_cleanup_restore_traceframe_number, since they are no longer used. gdb: 2014-03-22 Yao Qi <yao@codesourcery.com> * remote.c (target_read_live_memory): Remove. (memory_xfer_live_readonly_partial): Rename it to remote_xfer_live_readonly_partial. Remove argument 'object'. All callers updated. Call remote_read_bytes_1 instead of target_read_live_memory. * tracepoint.c (set_traceframe_number): Remove. (make_cleanup_restore_traceframe_number): Likewise . * tracepoint.h (set_traceframe_number): Remove declaration. (make_cleanup_restore_traceframe_number): Likewise. --- gdb/remote.c | 49 ++++++++++--------------------------------------- gdb/tracepoint.c | 15 --------------- gdb/tracepoint.h | 9 --------- 3 files changed, 10 insertions(+), 63 deletions(-) diff --git a/gdb/remote.c b/gdb/remote.c index 6654713..be8c423 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -6874,43 +6874,16 @@ remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, return TARGET_XFER_OK; } -/* Read memory from the live target, even if currently inspecting a - traceframe. The return is the same as that of target_read. */ - -static enum target_xfer_status -target_read_live_memory (enum target_object object, - ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len, - ULONGEST *xfered_len) -{ - enum target_xfer_status ret; - struct cleanup *cleanup; - - /* Switch momentarily out of tfind mode so to access live memory. - Note that this must not clear global state, such as the frame - cache, which must still remain valid for the previous traceframe. - We may be _building_ the frame cache at this point. */ - cleanup = make_cleanup_restore_traceframe_number (); - set_traceframe_number (-1); - - ret = target_xfer_partial (current_target.beneath, object, NULL, - myaddr, NULL, memaddr, len, xfered_len); - - do_cleanups (cleanup); - return ret; -} - -/* Using the set of read-only target sections of OPS, read live - read-only memory. Note that the actual reads start from the - top-most target again. +/* Using the set of read-only target sections of remote, read live + read-only memory. For interface/parameters/return description see target.h, to_xfer_partial. */ static enum target_xfer_status -memory_xfer_live_readonly_partial (struct target_ops *ops, - enum target_object object, - gdb_byte *readbuf, ULONGEST memaddr, - ULONGEST len, ULONGEST *xfered_len) +remote_xfer_live_readonly_partial (struct target_ops *ops, gdb_byte *readbuf, + ULONGEST memaddr, ULONGEST len, + ULONGEST *xfered_len) { struct target_section *secp; struct target_section_table *table; @@ -6933,8 +6906,8 @@ memory_xfer_live_readonly_partial (struct target_ops *ops, if (memend <= p->endaddr) { /* Entire transfer is within this section. */ - return target_read_live_memory (object, memaddr, - readbuf, len, xfered_len); + return remote_read_bytes_1 (memaddr, readbuf, len, + xfered_len); } else if (memaddr >= p->endaddr) { @@ -6945,8 +6918,8 @@ memory_xfer_live_readonly_partial (struct target_ops *ops, { /* This section overlaps the transfer. Just do half. */ len = p->endaddr - memaddr; - return target_read_live_memory (object, memaddr, - readbuf, len, xfered_len); + return remote_read_bytes_1 (memaddr, readbuf, len, + xfered_len); } } } @@ -6998,9 +6971,7 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, do_cleanups (old_chain); /* This goes through the topmost target again. */ - res = memory_xfer_live_readonly_partial (ops, - TARGET_OBJECT_MEMORY, - myaddr, memaddr, + res = remote_xfer_live_readonly_partial (ops, myaddr, memaddr, len, xfered_len); if (res == TARGET_XFER_OK) return TARGET_XFER_OK; diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index 673fddd..c522193 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -3216,15 +3216,6 @@ set_current_traceframe (int num) clear_traceframe_info (); } -/* Make the traceframe NUM be the current trace frame, and do nothing - more. */ - -void -set_traceframe_number (int num) -{ - traceframe_number = num; -} - /* A cleanup used when switching away and back from tfind mode. */ struct current_traceframe_cleanup @@ -3261,12 +3252,6 @@ make_cleanup_restore_current_traceframe (void) restore_current_traceframe_cleanup_dtor); } -struct cleanup * -make_cleanup_restore_traceframe_number (void) -{ - return make_cleanup_restore_integer (&traceframe_number); -} - /* Given a number and address, return an uploaded tracepoint with that number, creating if necessary. */ diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h index 8a1abbf..39b5edb 100644 --- a/gdb/tracepoint.h +++ b/gdb/tracepoint.h @@ -269,21 +269,12 @@ extern int get_traceframe_number (void); /* Returns the tracepoint number for current traceframe. */ extern int get_tracepoint_number (void); -/* Make the traceframe NUM be the current GDB trace frame number, and - do nothing more. In particular, this does not flush the - register/frame caches or notify the target about the trace frame - change, so that is can be used when we need to momentarily access - live memory. Targets lazily switch their current traceframe to - match GDB's traceframe number, at the appropriate times. */ -extern void set_traceframe_number (int); - /* Make the traceframe NUM be the current trace frame, all the way to the target, and flushes all global state (register/frame caches, etc.). */ extern void set_current_traceframe (int num); struct cleanup *make_cleanup_restore_current_traceframe (void); -struct cleanup *make_cleanup_restore_traceframe_number (void); void free_actions (struct breakpoint *); -- 1.7.7.6 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] Factor remote_read_bytes. 2014-03-11 12:44 [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets Yao Qi 2014-03-11 12:45 ` [PATCH 3/3] Remove target_read_live_memory Yao Qi @ 2014-03-11 12:45 ` Yao Qi 2014-03-21 11:57 ` Pedro Alves 2014-03-21 9:41 ` [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets Yao Qi 2014-03-21 11:56 ` Pedro Alves 3 siblings, 1 reply; 9+ messages in thread From: Yao Qi @ 2014-03-11 12:45 UTC (permalink / raw) To: gdb-patches This patch moves code in remote_read_bytes on reading from the remote stub to a new function remote_read_bytes_1. gdb: 2014-03-11 Yao Qi <yao@codesourcery.com> * remote.c (remote_read_bytes): Move code on reading from the remote stub to ... (remote_read_bytes_1): ... here. New function. --- gdb/remote.c | 97 ++++++++++++++++++++++++++++++++------------------------- 1 files changed, 54 insertions(+), 43 deletions(-) diff --git a/gdb/remote.c b/gdb/remote.c index afe9d12..b5c6b4b 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -6824,6 +6824,56 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len, packet_format[0], 1); } +/* Read memory data directly from the remote machine. + This does not use the data cache; the data cache uses this. + MEMADDR is the address in the remote memory space. + MYADDR is the address of the buffer in our space. + LEN is the number of bytes. + + Return the transferred status, error or OK (an + 'enum target_xfer_status' value). Save the number of bytes + transferred in *XFERED_LEN. */ + +static enum target_xfer_status +remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, + ULONGEST *xfered_len) +{ + struct remote_state *rs = get_remote_state (); + int max_buf_size; /* Max size of packet output buffer. */ + char *p; + int todo; + int i; + + max_buf_size = get_memory_read_packet_size (); + /* The packet buffer will be large enough for the payload; + get_memory_packet_size ensures this. */ + + /* Number if bytes that will fit. */ + todo = min (len, max_buf_size / 2); + + /* Construct "m"<memaddr>","<len>". */ + memaddr = remote_address_masked (memaddr); + p = rs->buf; + *p++ = 'm'; + p += hexnumstr (p, (ULONGEST) memaddr); + *p++ = ','; + p += hexnumstr (p, (ULONGEST) todo); + *p = '\0'; + putpkt (rs->buf); + getpkt (&rs->buf, &rs->buf_size, 0); + if (rs->buf[0] == 'E' + && isxdigit (rs->buf[1]) && isxdigit (rs->buf[2]) + && rs->buf[3] == '\0') + return TARGET_XFER_E_IO; + /* Reply describes memory byte by byte, each byte encoded as two hex + characters. */ + p = rs->buf; + i = hex2bin (p, myaddr, todo); + /* Return what we have. Let higher layers handle partial reads. */ + *xfered_len = (ULONGEST) i; + return TARGET_XFER_OK; +} + /* Read memory from the live target, even if currently inspecting a traceframe. The return is the same as that of target_read. */ @@ -6905,26 +6955,14 @@ memory_xfer_live_readonly_partial (struct target_ops *ops, return TARGET_XFER_EOF; } -/* Read memory data directly from the remote machine. - This does not use the data cache; the data cache uses this. - MEMADDR is the address in the remote memory space. - MYADDR is the address of the buffer in our space. - LEN is the number of bytes. - - Return the transferred status, error or OK (an - 'enum target_xfer_status' value). Save the number of bytes - transferred in *XFERED_LEN. */ +/* Similar to remote_read_bytes_1, but it reads from the remote stub + first if the requested memory is unavailable in traceframe. + Otherwise, fall back to remote_read_bytes_1. */ static enum target_xfer_status remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, ULONGEST *xfered_len) { - struct remote_state *rs = get_remote_state (); - int max_buf_size; /* Max size of packet output buffer. */ - char *p; - int todo; - int i; - if (len == 0) return 0; @@ -6985,34 +7023,7 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, } } - max_buf_size = get_memory_read_packet_size (); - /* The packet buffer will be large enough for the payload; - get_memory_packet_size ensures this. */ - - /* Number if bytes that will fit. */ - todo = min (len, max_buf_size / 2); - - /* Construct "m"<memaddr>","<len>". */ - memaddr = remote_address_masked (memaddr); - p = rs->buf; - *p++ = 'm'; - p += hexnumstr (p, (ULONGEST) memaddr); - *p++ = ','; - p += hexnumstr (p, (ULONGEST) todo); - *p = '\0'; - putpkt (rs->buf); - getpkt (&rs->buf, &rs->buf_size, 0); - if (rs->buf[0] == 'E' - && isxdigit (rs->buf[1]) && isxdigit (rs->buf[2]) - && rs->buf[3] == '\0') - return TARGET_XFER_E_IO; - /* Reply describes memory byte by byte, each byte encoded as two hex - characters. */ - p = rs->buf; - i = hex2bin (p, myaddr, todo); - /* Return what we have. Let higher layers handle partial reads. */ - *xfered_len = (ULONGEST) i; - return TARGET_XFER_OK; + return remote_read_bytes_1 (memaddr, myaddr, len, xfered_len); } \f -- 1.7.7.6 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] Factor remote_read_bytes. 2014-03-11 12:45 ` [PATCH 2/3] Factor remote_read_bytes Yao Qi @ 2014-03-21 11:57 ` Pedro Alves 0 siblings, 0 replies; 9+ messages in thread From: Pedro Alves @ 2014-03-21 11:57 UTC (permalink / raw) To: Yao Qi; +Cc: gdb-patches On 03/11/2014 12:42 PM, Yao Qi wrote: > This patch moves code in remote_read_bytes on reading from the remote > stub to a new function remote_read_bytes_1. > > gdb: > > 2014-03-11 Yao Qi <yao@codesourcery.com> > > * remote.c (remote_read_bytes): Move code on reading from the > remote stub to ... > (remote_read_bytes_1): ... here. New function. OK. Thanks, -- Pedro Alves ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets 2014-03-11 12:44 [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets Yao Qi 2014-03-11 12:45 ` [PATCH 3/3] Remove target_read_live_memory Yao Qi 2014-03-11 12:45 ` [PATCH 2/3] Factor remote_read_bytes Yao Qi @ 2014-03-21 9:41 ` Yao Qi 2014-03-21 11:56 ` Pedro Alves 3 siblings, 0 replies; 9+ messages in thread From: Yao Qi @ 2014-03-21 9:41 UTC (permalink / raw) To: gdb-patches On 03/11/2014 08:42 PM, Yao Qi wrote: > As a follow-up to > > [PATCH 7/8] Adjust read_value_memory to use to_xfer_partial > https://sourceware.org/ml/gdb-patches/2014-02/msg00384.html > > this patch moves traceframe_available_memory down to the target side. > After this patch, the gdb core code is cleaner, and code on handling > unavailable memory is moved to remote/tfile/ctf targets. > > In details, this patch moves traceframe_available_memory code from > memory_xfer_partial_1 to remote target only, so remote target still > uses traceframe_info mechanism to check unavailable memory, and use > remote_ops to read them from read-only sections. We don't use > traceframe_info mechanism for tfile and ctf target, because it is > fast to iterate all traceframes from trace file, so the summary > information got from traceframe_info is not necessary. > > This patch also moves two functions to remote.c from target.c, > because they are only used in remote.c. I'll clean them up in another > patch. > > This series is tested on x86_64-linux. > > gdb: > > 2014-03-11 Yao Qi <yao@codesourcery.com> > > * ctf.c (ctf_xfer_partial): Check the return value of > exec_read_partial_read_only, if it is not TARGET_XFER_OK, > return TARGET_XFER_UNAVAILABLE. > * tracefile-tfile.c (tfile_xfer_partial): Likewise. > * target.c (target_read_live_memory): Move it to remote.c. > (memory_xfer_live_readonly_partial): Likewise. > (memory_xfer_partial_1): Move some code to remote_read_bytes. > * remote.c (target_read_live_memory): Moved from target.c. > (memory_xfer_live_readonly_partial): Likewise. > (remote_read_bytes): Moved from memory_xfer_partial_1. Ping. https://sourceware.org/ml/gdb-patches/2014-03/msg00262.html -- Yao (é½å°§) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets 2014-03-11 12:44 [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets Yao Qi ` (2 preceding siblings ...) 2014-03-21 9:41 ` [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets Yao Qi @ 2014-03-21 11:56 ` Pedro Alves 2014-03-22 11:20 ` Yao Qi 3 siblings, 1 reply; 9+ messages in thread From: Pedro Alves @ 2014-03-21 11:56 UTC (permalink / raw) To: Yao Qi; +Cc: gdb-patches On 03/11/2014 12:42 PM, Yao Qi wrote: > (remote_read_bytes): Moved from memory_xfer_partial_1. Say: (remote_read_bytes): New, factored out from memory_xfer_partial_1. > @@ -6847,6 +6928,63 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, > if (len == 0) > return 0; > > + if (get_traceframe_number () != -1) > + { > + VEC(mem_range_s) *available; > + > + /* If we fail to get the set of available memory, then the > + target does not support querying traceframe info, and so we > + attempt reading from the traceframe anyway (assuming the > + target implements the old QTro packet then). */ > + if (traceframe_available_memory (&available, memaddr, len)) > + { > + struct cleanup *old_chain; > + > + old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available); > + > + if (VEC_empty (mem_range_s, available) > + || VEC_index (mem_range_s, available, 0)->start != memaddr) > + { > + enum target_xfer_status res; > + > + /* Don't read into the traceframe's available > + memory. */ > + if (!VEC_empty (mem_range_s, available)) > + { > + LONGEST oldlen = len; > + > + len = VEC_index (mem_range_s, available, 0)->start - memaddr; > + gdb_assert (len <= oldlen); > + } > + > + do_cleanups (old_chain); > + > + /* This goes through the topmost target again. */ > + res = memory_xfer_live_readonly_partial (&remote_ops, This "&remote_ops" here will be wrong in case we're connected with extended-remote. Looks like remote_read_bytes needs to be gain an ops parameter. Otherwise looks good. Thanks, -- Pedro Alves ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets 2014-03-21 11:56 ` Pedro Alves @ 2014-03-22 11:20 ` Yao Qi 0 siblings, 0 replies; 9+ messages in thread From: Yao Qi @ 2014-03-22 11:20 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb-patches On 03/21/2014 07:56 PM, Pedro Alves wrote: > This "&remote_ops" here will be wrong in case we're connected > with extended-remote. Looks like remote_read_bytes needs to be > gain an ops parameter. Right, add 'ops' argument to remote_read_bytes in the updated patch. Patch below is pushed in. -- Yao (é½å°§) Subject: [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets As a follow-up to [PATCH 7/8] Adjust read_value_memory to use to_xfer_partial https://sourceware.org/ml/gdb-patches/2014-02/msg00384.html this patch moves traceframe_available_memory down to the target side. After this patch, the gdb core code is cleaner, and code on handling unavailable memory is moved to remote/tfile/ctf targets. In details, this patch moves traceframe_available_memory code from memory_xfer_partial_1 to remote target only, so remote target still uses traceframe_info mechanism to check unavailable memory, and use remote_ops to read them from read-only sections. We don't use traceframe_info mechanism for tfile and ctf target, because it is fast to iterate all traceframes from trace file, so the summary information got from traceframe_info is not necessary. This patch also moves two functions to remote.c from target.c, because they are only used in remote.c. I'll clean them up in another patch. gdb: 2014-03-22 Yao Qi <yao@codesourcery.com> * ctf.c (ctf_xfer_partial): Check the return value of exec_read_partial_read_only, if it is not TARGET_XFER_OK, return TARGET_XFER_UNAVAILABLE. * tracefile-tfile.c (tfile_xfer_partial): Likewise. * target.c (target_read_live_memory): Move it to remote.c. (memory_xfer_live_readonly_partial): Likewise. (memory_xfer_partial_1): Move some code to remote_read_bytes. * remote.c (target_read_live_memory): Moved from target.c. (memory_xfer_live_readonly_partial): Likewise. (remote_read_bytes): Factored out from memory_xfer_partial_1. --- gdb/ctf.c | 16 +++++- gdb/remote.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++- gdb/target.c | 138 ---------------------------------------------- gdb/tracefile-tfile.c | 16 +++++- 4 files changed, 171 insertions(+), 143 deletions(-) diff --git a/gdb/ctf.c b/gdb/ctf.c index 95fd31f..ebd40d6 100644 --- a/gdb/ctf.c +++ b/gdb/ctf.c @@ -1377,6 +1377,7 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object, { struct bt_iter_pos *pos; int i = 0; + enum target_xfer_status res; gdb_assert (ctf_iter != NULL); /* Save the current position. */ @@ -1466,7 +1467,20 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object, /* Restore the position. */ bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); - return exec_read_partial_read_only (readbuf, offset, len, xfered_len); + /* Requested memory is unavailable in the context of traceframes, + and this address falls within a read-only section, fallback + to reading from executable. */ + res = exec_read_partial_read_only (readbuf, offset, len, xfered_len); + + if (res == TARGET_XFER_OK) + return TARGET_XFER_OK; + else + { + /* No use trying further, we know some memory starting + at MEMADDR isn't available. */ + *xfered_len = len; + return TARGET_XFER_UNAVAILABLE; + } } else { diff --git a/gdb/remote.c b/gdb/remote.c index e03d3bf..dcee6e1 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -6824,6 +6824,87 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len, packet_format[0], 1); } +/* Read memory from the live target, even if currently inspecting a + traceframe. The return is the same as that of target_read. */ + +static enum target_xfer_status +target_read_live_memory (enum target_object object, + ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len, + ULONGEST *xfered_len) +{ + enum target_xfer_status ret; + struct cleanup *cleanup; + + /* Switch momentarily out of tfind mode so to access live memory. + Note that this must not clear global state, such as the frame + cache, which must still remain valid for the previous traceframe. + We may be _building_ the frame cache at this point. */ + cleanup = make_cleanup_restore_traceframe_number (); + set_traceframe_number (-1); + + ret = target_xfer_partial (current_target.beneath, object, NULL, + myaddr, NULL, memaddr, len, xfered_len); + + do_cleanups (cleanup); + return ret; +} + +/* Using the set of read-only target sections of OPS, read live + read-only memory. Note that the actual reads start from the + top-most target again. + + For interface/parameters/return description see target.h, + to_xfer_partial. */ + +static enum target_xfer_status +memory_xfer_live_readonly_partial (struct target_ops *ops, + enum target_object object, + gdb_byte *readbuf, ULONGEST memaddr, + ULONGEST len, ULONGEST *xfered_len) +{ + struct target_section *secp; + struct target_section_table *table; + + secp = target_section_by_addr (ops, memaddr); + if (secp != NULL + && (bfd_get_section_flags (secp->the_bfd_section->owner, + secp->the_bfd_section) + & SEC_READONLY)) + { + struct target_section *p; + ULONGEST memend = memaddr + len; + + table = target_get_section_table (ops); + + for (p = table->sections; p < table->sections_end; p++) + { + if (memaddr >= p->addr) + { + if (memend <= p->endaddr) + { + /* Entire transfer is within this section. */ + return target_read_live_memory (object, memaddr, + readbuf, len, xfered_len); + } + else if (memaddr >= p->endaddr) + { + /* This section ends before the transfer starts. */ + continue; + } + else + { + /* This section overlaps the transfer. Just do half. */ + len = p->endaddr - memaddr; + return target_read_live_memory (object, memaddr, + readbuf, len, xfered_len); + } + } + } + } + + return TARGET_XFER_EOF; +} + /* Read memory data directly from the remote machine. This does not use the data cache; the data cache uses this. MEMADDR is the address in the remote memory space. @@ -6835,8 +6916,8 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len, transferred in *XFERED_LEN. */ static enum target_xfer_status -remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, - ULONGEST *xfered_len) +remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr, + gdb_byte *myaddr, ULONGEST len, ULONGEST *xfered_len) { struct remote_state *rs = get_remote_state (); int max_buf_size; /* Max size of packet output buffer. */ @@ -6847,6 +6928,63 @@ remote_read_bytes (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len, if (len == 0) return 0; + if (get_traceframe_number () != -1) + { + VEC(mem_range_s) *available; + + /* If we fail to get the set of available memory, then the + target does not support querying traceframe info, and so we + attempt reading from the traceframe anyway (assuming the + target implements the old QTro packet then). */ + if (traceframe_available_memory (&available, memaddr, len)) + { + struct cleanup *old_chain; + + old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available); + + if (VEC_empty (mem_range_s, available) + || VEC_index (mem_range_s, available, 0)->start != memaddr) + { + enum target_xfer_status res; + + /* Don't read into the traceframe's available + memory. */ + if (!VEC_empty (mem_range_s, available)) + { + LONGEST oldlen = len; + + len = VEC_index (mem_range_s, available, 0)->start - memaddr; + gdb_assert (len <= oldlen); + } + + do_cleanups (old_chain); + + /* This goes through the topmost target again. */ + res = memory_xfer_live_readonly_partial (ops, + TARGET_OBJECT_MEMORY, + myaddr, memaddr, + len, xfered_len); + if (res == TARGET_XFER_OK) + return TARGET_XFER_OK; + else + { + /* No use trying further, we know some memory starting + at MEMADDR isn't available. */ + *xfered_len = len; + return TARGET_XFER_UNAVAILABLE; + } + } + + /* Don't try to read more than how much is available, in + case the target implements the deprecated QTro packet to + cater for older GDBs (the target's knowledge of read-only + sections may be outdated by now). */ + len = VEC_index (mem_range_s, available, 0)->length; + + do_cleanups (old_chain); + } + } + max_buf_size = get_memory_read_packet_size (); /* The packet buffer will be large enough for the payload; get_memory_packet_size ensures this. */ @@ -8698,7 +8836,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object, if (writebuf != NULL) return remote_write_bytes (offset, writebuf, len, xfered_len); else - return remote_read_bytes (offset, readbuf, len, xfered_len); + return remote_read_bytes (ops, offset, readbuf, len, xfered_len); } /* Handle SPU memory using qxfer packets. */ diff --git a/gdb/target.c b/gdb/target.c index 0d22297..1b48f79 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -940,87 +940,6 @@ target_section_by_addr (struct target_ops *target, CORE_ADDR addr) return NULL; } -/* Read memory from the live target, even if currently inspecting a - traceframe. The return is the same as that of target_read. */ - -static enum target_xfer_status -target_read_live_memory (enum target_object object, - ULONGEST memaddr, gdb_byte *myaddr, ULONGEST len, - ULONGEST *xfered_len) -{ - enum target_xfer_status ret; - struct cleanup *cleanup; - - /* Switch momentarily out of tfind mode so to access live memory. - Note that this must not clear global state, such as the frame - cache, which must still remain valid for the previous traceframe. - We may be _building_ the frame cache at this point. */ - cleanup = make_cleanup_restore_traceframe_number (); - set_traceframe_number (-1); - - ret = target_xfer_partial (current_target.beneath, object, NULL, - myaddr, NULL, memaddr, len, xfered_len); - - do_cleanups (cleanup); - return ret; -} - -/* Using the set of read-only target sections of OPS, read live - read-only memory. Note that the actual reads start from the - top-most target again. - - For interface/parameters/return description see target.h, - to_xfer_partial. */ - -static enum target_xfer_status -memory_xfer_live_readonly_partial (struct target_ops *ops, - enum target_object object, - gdb_byte *readbuf, ULONGEST memaddr, - ULONGEST len, ULONGEST *xfered_len) -{ - struct target_section *secp; - struct target_section_table *table; - - secp = target_section_by_addr (ops, memaddr); - if (secp != NULL - && (bfd_get_section_flags (secp->the_bfd_section->owner, - secp->the_bfd_section) - & SEC_READONLY)) - { - struct target_section *p; - ULONGEST memend = memaddr + len; - - table = target_get_section_table (ops); - - for (p = table->sections; p < table->sections_end; p++) - { - if (memaddr >= p->addr) - { - if (memend <= p->endaddr) - { - /* Entire transfer is within this section. */ - return target_read_live_memory (object, memaddr, - readbuf, len, xfered_len); - } - else if (memaddr >= p->endaddr) - { - /* This section ends before the transfer starts. */ - continue; - } - else - { - /* This section overlaps the transfer. Just do half. */ - len = p->endaddr - memaddr; - return target_read_live_memory (object, memaddr, - readbuf, len, xfered_len); - } - } - } - } - - return TARGET_XFER_EOF; -} - /* Read memory from more than one valid target. A core file, for instance, could have some of memory but delegate other bits to the target below it. So, we must manually try all targets. */ @@ -1128,63 +1047,6 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object, } } - /* If reading unavailable memory in the context of traceframes, and - this address falls within a read-only section, fallback to - reading from live memory. */ - if (readbuf != NULL && get_traceframe_number () != -1) - { - VEC(mem_range_s) *available; - - /* If we fail to get the set of available memory, then the - target does not support querying traceframe info, and so we - attempt reading from the traceframe anyway (assuming the - target implements the old QTro packet then). */ - if (traceframe_available_memory (&available, memaddr, len)) - { - struct cleanup *old_chain; - - old_chain = make_cleanup (VEC_cleanup(mem_range_s), &available); - - if (VEC_empty (mem_range_s, available) - || VEC_index (mem_range_s, available, 0)->start != memaddr) - { - /* Don't read into the traceframe's available - memory. */ - if (!VEC_empty (mem_range_s, available)) - { - LONGEST oldlen = len; - - len = VEC_index (mem_range_s, available, 0)->start - memaddr; - gdb_assert (len <= oldlen); - } - - do_cleanups (old_chain); - - /* This goes through the topmost target again. */ - res = memory_xfer_live_readonly_partial (ops, object, - readbuf, memaddr, - len, xfered_len); - if (res == TARGET_XFER_OK) - return TARGET_XFER_OK; - else - { - /* No use trying further, we know some memory starting - at MEMADDR isn't available. */ - *xfered_len = len; - return TARGET_XFER_UNAVAILABLE; - } - } - - /* Don't try to read more than how much is available, in - case the target implements the deprecated QTro packet to - cater for older GDBs (the target's knowledge of read-only - sections may be outdated by now). */ - len = VEC_index (mem_range_s, available, 0)->length; - - do_cleanups (old_chain); - } - } - /* Try GDB's internal data cache. */ region = lookup_mem_region (memaddr); /* region->hi == 0 means there's no upper bound. */ diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c index cbf746d..a36596f 100644 --- a/gdb/tracefile-tfile.c +++ b/gdb/tracefile-tfile.c @@ -900,6 +900,7 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object, if (get_traceframe_number () != -1) { int pos = 0; + enum target_xfer_status res; /* Iterate through the traceframe's blocks, looking for memory. */ @@ -937,7 +938,20 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object, pos += (8 + 2 + mlen); } - return exec_read_partial_read_only (readbuf, offset, len, xfered_len); + /* Requested memory is unavailable in the context of traceframes, + and this address falls within a read-only section, fallback + to reading from executable. */ + res = exec_read_partial_read_only (readbuf, offset, len, xfered_len); + + if (res == TARGET_XFER_OK) + return TARGET_XFER_OK; + else + { + /* No use trying further, we know some memory starting + at MEMADDR isn't available. */ + *xfered_len = len; + return TARGET_XFER_UNAVAILABLE; + } } else { -- 1.7.7.6 ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2014-03-22 11:23 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-03-11 12:44 [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets Yao Qi 2014-03-11 12:45 ` [PATCH 3/3] Remove target_read_live_memory Yao Qi 2014-03-21 12:01 ` Pedro Alves 2014-03-22 11:23 ` Yao Qi 2014-03-11 12:45 ` [PATCH 2/3] Factor remote_read_bytes Yao Qi 2014-03-21 11:57 ` Pedro Alves 2014-03-21 9:41 ` [PATCH 1/3] Move the traceframe_available_memory code from memory_xfer_partial_1 down to the targets Yao Qi 2014-03-21 11:56 ` Pedro Alves 2014-03-22 11:20 ` Yao Qi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox