[PATCH 6/8] Use new to_xfer_partial interface in ctf and tfile target

Yao Qi yao@codesourcery.com
Wed Feb 12 06:08:00 GMT 2014


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.

gdb:

2014-02-12  Yao Qi  <yao@codesourcery.com>

	* exec.c (section_table_available_memory): Make it static.  Move
	comments from exec.h.
	(section_table_xfer_available_memory): New function.
	* exec.h (section_table_available_memory): Remove declaration.
	(section_table_xfer_available_memory): Declare.
	* ctf.c (ctf_xfer_partial): Call
	section_table_xfer_available_memory.
	* tracefile-tfile.c (tfile_xfer_partial): Likewise.
---
 gdb/ctf.c             |    9 +++++-
 gdb/exec.c            |   61 ++++++++++++++++++++++++++++++++++++++++++++++++-
 gdb/exec.h            |   19 ++++++---------
 gdb/tracefile-tfile.c |   10 ++++++-
 4 files changed, 83 insertions(+), 16 deletions(-)

diff --git a/gdb/ctf.c b/gdb/ctf.c
index 96ea966..62152d3 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_only_xfer_partial (readbuf, offset, len, xfered_len);
+      return exec_read_only_xfer_partial (readbuf, offset, len, xfered_len);
+    }
+  else
+    {
+      /* Fallback to reading from read-only sections.  */
+      return section_table_xfer_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 bf422a7..e649bf0 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -576,7 +576,12 @@ exec_read_only_xfer_partial (gdb_byte *readbuf, ULONGEST offset,
   return TARGET_XFER_E_IO;
 }
 
-VEC(mem_range_s) *
+/* Appends all read-only memory ranges found in the target section
+   table defined by SECTIONS and SECTIONS_END, starting at (and
+   intersected with) MEMADDR for LEN bytes.  Returns the augmented
+   VEC.  */
+
+static VEC(mem_range_s) *
 section_table_available_memory (VEC(mem_range_s) *memory,
 				CORE_ADDR memaddr, ULONGEST len,
 				struct target_section *sections,
@@ -614,6 +619,60 @@ section_table_available_memory (VEC(mem_range_s) *memory,
 }
 
 enum target_xfer_status
+section_table_xfer_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_only_xfer_partial (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 a0c59c2..f6ccf07 100644
--- a/gdb/exec.h
+++ b/gdb/exec.h
@@ -55,17 +55,6 @@ extern enum target_xfer_status
   exec_read_only_xfer_partial (gdb_byte *readbuf, ULONGEST offset,
 			       ULONGEST len, ULONGEST *xfered_len);
 
-/* Appends all read-only memory ranges found in the target section
-   table defined by SECTIONS and SECTIONS_END, starting at (and
-   intersected with) MEMADDR for LEN bytes.  Returns the augmented
-   VEC.  */
-
-extern VEC(mem_range_s) *
-  section_table_available_memory (VEC(mem_range_s) *ranges,
-				  CORE_ADDR memaddr, ULONGEST len,
-				  struct target_section *sections,
-				  struct target_section *sections_end);
-
 /* Read or write from mappable sections of BFD executable files.
 
    Request to transfer up to LEN 8-bit bytes of the target sections
@@ -91,6 +80,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_only_xfer_partial, but return
+   TARGET_XFER_E_UNAVAILABLE is data is unavailable.  */
+
+extern enum target_xfer_status
+  section_table_xfer_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 dcd46e4..c3cc6a4 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -931,9 +931,15 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object,
 	  /* Skip over this block.  */
 	  pos += (8 + 2 + mlen);
 	}
-    }
 
-  return exec_read_only_xfer_partial (readbuf, offset, len, xfered_len);
+      return exec_read_only_xfer_partial (readbuf, offset, len, xfered_len);
+    }
+  else
+    {
+      /* Fallback to reading from read-only sections.  */
+      return section_table_xfer_available_memory (readbuf, offset, len,
+						  xfered_len);
+    }
 }
 
 /* Iterate through the blocks of a trace frame, looking for a 'V'
-- 
1.7.7.6



More information about the Gdb-patches mailing list