From: Yao Qi Date: Tue, 11 Feb 2014 04:20:05 +0000 (+0800) Subject: Use new to_xfer_partial interface in ctf and tfile target X-Git-Tag: gdb-7.8-release~1010 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1ee79381dd9cc2438a61fe4a96294682744d2458;p=external%2Fbinutils.git 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 11b70b8..55745af 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 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 ... * exec.c (exec_read_partial_read_only): ... it. New function. * tracefile-tfile.c (tfile_xfer_partial): Likewise. diff --git a/gdb/ctf.c b/gdb/ctf.c index 9c8f4d7..95fd31f 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 74c61eb..607f5ac 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -615,6 +615,60 @@ section_table_available_memory (VEC(mem_range_s) *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, ULONGEST *xfered_len, diff --git a/gdb/exec.h b/gdb/exec.h index 960c585..84dc40f 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 02122eb..cbf746d 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'