From 1ee79381dd9cc2438a61fe4a96294682744d2458 Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Tue, 11 Feb 2014 12:20:05 +0800 Subject: [PATCH] Use new to_xfer_partial interface in ctf and tfile target This patch adjust both ctf and tfile target implementation of to_xfer_partial, to return TARGET_XFER_E_UNAVAILABLE and set *XFERED_LEN if data is unavailable. Note that some code on xfer in exec.c can be shared, but we can do it in a separate pass later. gdb: 2014-02-23 Yao Qi * exec.c (section_table_read_available_memory): New function. * exec.h (section_table_read_available_memory): Declare. * ctf.c (ctf_xfer_partial): Call section_table_read_available_memory. * tracefile-tfile.c (tfile_xfer_partial): Likewise. --- gdb/ChangeLog | 8 +++++++ gdb/ctf.c | 9 ++++++-- gdb/exec.c | 54 +++++++++++++++++++++++++++++++++++++++++++ gdb/exec.h | 8 +++++++ gdb/tracefile-tfile.c | 10 ++++++-- 5 files changed, 85 insertions(+), 4 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 11b70b817d..55745af8ae 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2014-02-23 Yao Qi + + * exec.c (section_table_read_available_memory): New function. + * exec.h (section_table_read_available_memory): Declare. + * ctf.c (ctf_xfer_partial): Call + section_table_read_available_memory. + * tracefile-tfile.c (tfile_xfer_partial): Likewise. + 2014-02-23 Yao Qi * ctf.c (ctf_xfer_partial): Move code to ... diff --git a/gdb/ctf.c b/gdb/ctf.c index 9c8f4d73cc..95fd31f501 100644 --- a/gdb/ctf.c +++ b/gdb/ctf.c @@ -1465,9 +1465,14 @@ 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); + return exec_read_partial_read_only (readbuf, offset, len, xfered_len); + } + else + { + /* Fallback to reading from read-only sections. */ + return section_table_read_available_memory (readbuf, offset, len, xfered_len); + } } /* This is the implementation of target_ops method diff --git a/gdb/exec.c b/gdb/exec.c index 74c61eb810..607f5acc14 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -614,6 +614,60 @@ section_table_available_memory (VEC(mem_range_s) *memory, return memory; } +enum target_xfer_status +section_table_read_available_memory (gdb_byte *readbuf, ULONGEST offset, + ULONGEST len, ULONGEST *xfered_len) +{ + VEC(mem_range_s) *available_memory = NULL; + struct target_section_table *table; + struct cleanup *old_chain; + mem_range_s *r; + int i; + + table = target_get_section_table (&exec_ops); + available_memory = section_table_available_memory (available_memory, + offset, len, + table->sections, + table->sections_end); + + old_chain = make_cleanup (VEC_cleanup(mem_range_s), + &available_memory); + + normalize_mem_ranges (available_memory); + + for (i = 0; + VEC_iterate (mem_range_s, available_memory, i, r); + i++) + { + if (mem_ranges_overlap (r->start, r->length, offset, len)) + { + CORE_ADDR end; + enum target_xfer_status status; + + /* Get the intersection window. */ + end = min (offset + len, r->start + r->length); + + gdb_assert (end - offset <= len); + + if (offset >= r->start) + status = exec_read_partial_read_only (readbuf, offset, + end - offset, + xfered_len); + else + { + *xfered_len = r->start - offset; + status = TARGET_XFER_E_UNAVAILABLE; + } + do_cleanups (old_chain); + return status; + } + } + do_cleanups (old_chain); + + *xfered_len = len; + return TARGET_XFER_E_UNAVAILABLE; +} + enum target_xfer_status section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, diff --git a/gdb/exec.h b/gdb/exec.h index 960c58563e..84dc40f4bd 100644 --- a/gdb/exec.h +++ b/gdb/exec.h @@ -91,6 +91,14 @@ extern enum target_xfer_status struct target_section *, const char *); +/* Read from mappable read-only sections of BFD executable files. + Similar to exec_read_partial_read_only, but return + TARGET_XFER_E_UNAVAILABLE if data is unavailable. */ + +extern enum target_xfer_status + section_table_read_available_memory (gdb_byte *readbuf, ULONGEST offset, + ULONGEST len, ULONGEST *xfered_len); + /* Set the loaded address of a section. */ extern void exec_set_section_address (const char *, int, CORE_ADDR); diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c index 02122eb35b..cbf746d845 100644 --- a/gdb/tracefile-tfile.c +++ b/gdb/tracefile-tfile.c @@ -936,9 +936,15 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object, /* Skip over this block. */ pos += (8 + 2 + mlen); } - } - return exec_read_partial_read_only (readbuf, offset, len, xfered_len); + return exec_read_partial_read_only (readbuf, offset, len, xfered_len); + } + else + { + /* Fallback to reading from read-only sections. */ + return section_table_read_available_memory (readbuf, offset, len, + xfered_len); + } } /* Iterate through the blocks of a trace frame, looking for a 'V' -- 2.34.1