diff mbox

[v6,06/10] Prepare linux_find_memory_regions_full & co. for move

Message ID 20150607200510.8918.28582.stgit@host1.jankratochvil.net
State New
Headers show

Commit Message

Jan Kratochvil June 7, 2015, 8:05 p.m. UTC
Hi,

prepare code for move into gdb/common/.

Approved by:
	https://sourceware.org/ml/gdb-patches/2014-05/msg00371.html


Jan


gdb/ChangeLog
2014-02-26  Aleksandar Ristovski  <aristovski@qnx.com
	    Jan Kratochvil  <jan.kratochvil@redhat.com>

	Prepare linux_find_memory_regions_full & co. for move.
	* linux-tdep.c (linux_find_memory_region_ftype): Comment.
	(linux_find_memory_regions_full): Change signature and prepare
	for moving to linux-maps.
	(linux_find_memory_regions_data): Rename field 'obfd' to 'data'.
	(linux_find_memory_regions_thunk): New.
	(linux_find_memory_regions_thunk): Use 'data' field instead of 'obfd'.
	(linux_find_memory_regions_gdb): New.
	(linux_find_memory_regions): Rename argument 'obfd' to 'func_data'.
	(linux_make_mappings_corefile_notes): Use
	linux_find_memory_regions_gdb.
	* target.c (read_alloc_pread_ftype): New typedef.
	(target_fileio_read_alloc_1_pread): New function.
	(read_alloc): Refactor from target_fileio_read_alloc_1.
	(read_stralloc_func_ftype): New typedef.
	(target_fileio_read_alloc_1): New implementation. Use read_alloc.
	(read_stralloc): Refactored from target_fileio_read_stralloc.
	(target_fileio_read_stralloc): New implementation, use read_stralloc.
---
 gdb/linux-tdep.c |  121 +++++++++++++++++++++++++++++++++---------------------
 gdb/target.c     |   93 ++++++++++++++++++++++++++++--------------
 2 files changed, 138 insertions(+), 76 deletions(-)
diff mbox

Patch

diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index b0981f5..4618415 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -1098,6 +1098,10 @@  linux_core_info_proc (struct gdbarch *gdbarch, const char *args,
     error (_("unable to handle request"));
 }
 
+/* Callback function for linux_find_memory_regions_full.  If it returns
+   non-zero linux_find_memory_regions_full returns immediately with that
+   value.  */
+
 typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size,
 					    ULONGEST offset, ULONGEST inode,
 					    int read, int write,
@@ -1105,42 +1109,22 @@  typedef int linux_find_memory_region_ftype (ULONGEST vaddr, ULONGEST size,
 					    const char *filename,
 					    void *data);
 
-/* List memory regions in the inferior for a corefile.  */
+/* List memory regions in the inferior PID matched to FILTERFLAGS for
+   a corefile.  Call FUNC with FUNC_DATA for each such region.  Return
+   immediately with the value returned by FUNC if it is non-zero.
+   *MEMORY_TO_FREE_PTR should be registered to be freed automatically if
+   called FUNC throws an exception.  MEMORY_TO_FREE_PTR can be also
+   passed as NULL if it is not used.  Return -1 if error occurs, 0 if
+   all memory regions have been processed or return the value from FUNC
+   if FUNC returns non-zero.  */
 
 static int
-linux_find_memory_regions_full (struct gdbarch *gdbarch,
+linux_find_memory_regions_full (pid_t pid, enum filterflags filterflags,
 				linux_find_memory_region_ftype *func,
-				void *obfd)
+				void *func_data)
 {
   char mapsfilename[100];
-  char coredumpfilter_name[100];
-  char *data, *coredumpfilterdata;
-  pid_t pid;
-  /* Default dump behavior of coredump_filter (0x33), according to
-     Documentation/filesystems/proc.txt from the Linux kernel
-     tree.  */
-  enum filterflags filterflags = (COREFILTER_ANON_PRIVATE
-				  | COREFILTER_ANON_SHARED
-				  | COREFILTER_ELF_HEADERS
-				  | COREFILTER_HUGETLB_PRIVATE);
-
-  /* We need to know the real target PID to access /proc.  */
-  if (current_inferior ()->fake_pid_p)
-    return 1;
-
-  pid = current_inferior ()->pid;
-
-  if (use_coredump_filter)
-    {
-      xsnprintf (coredumpfilter_name, sizeof (coredumpfilter_name),
-		 "/proc/%d/coredump_filter", pid);
-      coredumpfilterdata = target_fileio_read_stralloc (coredumpfilter_name);
-      if (coredumpfilterdata != NULL)
-	{
-	  sscanf (coredumpfilterdata, "%x", &filterflags);
-	  xfree (coredumpfilterdata);
-	}
-    }
+  char *data;
 
   xsnprintf (mapsfilename, sizeof mapsfilename, "/proc/%d/smaps", pid);
   data = target_fileio_read_stralloc (mapsfilename);
@@ -1155,6 +1139,7 @@  linux_find_memory_regions_full (struct gdbarch *gdbarch,
     {
       struct cleanup *cleanup = make_cleanup (xfree, data);
       char *line, *t;
+      int retval = 0;
 
       line = strtok_r (data, "\n", &t);
       while (line != NULL)
@@ -1269,17 +1254,20 @@  linux_find_memory_regions_full (struct gdbarch *gdbarch,
 
 	  /* Invoke the callback function to create the corefile segment.  */
 	  if (should_dump_p)
-	    func (addr, endaddr - addr, offset, inode,
-		  read, write, exec, 1, /* MODIFIED is true because we
-					   want to dump the mapping.  */
-		  filename, obfd);
+	    retval = func (addr, endaddr - addr, offset, inode,
+			   read, write, exec,
+			   1, /* MODIFIED is true because we want to dump the
+				 mapping.  */
+			   filename, func_data);
+	  if (retval != 0)
+	    break;
 	}
 
       do_cleanups (cleanup);
-      return 0;
+      return retval;
     }
 
-  return 1;
+  return -1;
 }
 
 /* A structure for passing information through
@@ -1293,9 +1281,11 @@  struct linux_find_memory_regions_data
 
   /* The original datum.  */
 
-  void *obfd;
+  void *data;
 };
 
+static linux_find_memory_region_ftype linux_find_memory_regions_thunk;
+
 /* A callback for linux_find_memory_regions that converts between the
    "full"-style callback and find_memory_region_ftype.  */
 
@@ -1307,7 +1297,47 @@  linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size,
 {
   struct linux_find_memory_regions_data *data = arg;
 
-  return data->func (vaddr, size, read, write, exec, modified, data->obfd);
+  return data->func (vaddr, size, read, write, exec, modified, data->data);
+}
+
+/* Wrapper of linux_find_memory_regions_full handling FAKE_PID_P in GDB.  */
+
+static int
+linux_find_memory_regions_gdb (struct gdbarch *gdbarch,
+			       linux_find_memory_region_ftype *func,
+			       void *func_data)
+{
+  pid_t pid;
+  /* Default dump behavior of coredump_filter (0x33), according to
+     Documentation/filesystems/proc.txt from the Linux kernel
+     tree.  */
+  enum filterflags filterflags = (COREFILTER_ANON_PRIVATE
+				  | COREFILTER_ANON_SHARED
+				  | COREFILTER_ELF_HEADERS
+				  | COREFILTER_HUGETLB_PRIVATE);
+
+  /* We need to know the real target PID so
+     linux_find_memory_regions_full can access /proc.  */
+  if (current_inferior ()->fake_pid_p)
+    return -1;
+
+  pid = current_inferior ()->pid;
+
+  if (use_coredump_filter)
+    {
+      char coredumpfilter_name[100], *coredumpfilterdata;
+
+      xsnprintf (coredumpfilter_name, sizeof (coredumpfilter_name),
+		 "/proc/%d/coredump_filter", pid);
+      coredumpfilterdata = target_fileio_read_stralloc (coredumpfilter_name);
+      if (coredumpfilterdata != NULL)
+	{
+	  sscanf (coredumpfilterdata, "%x", &filterflags);
+	  xfree (coredumpfilterdata);
+	}
+    }
+
+  return linux_find_memory_regions_full (pid, filterflags, func, func_data);
 }
 
 /* A variant of linux_find_memory_regions_full that is suitable as the
@@ -1315,16 +1345,15 @@  linux_find_memory_regions_thunk (ULONGEST vaddr, ULONGEST size,
 
 static int
 linux_find_memory_regions (struct gdbarch *gdbarch,
-			   find_memory_region_ftype func, void *obfd)
+			   find_memory_region_ftype func, void *func_data)
 {
   struct linux_find_memory_regions_data data;
 
   data.func = func;
-  data.obfd = obfd;
+  data.data = func_data;
 
-  return linux_find_memory_regions_full (gdbarch,
-					 linux_find_memory_regions_thunk,
-					 &data);
+  return linux_find_memory_regions_gdb (gdbarch,
+					linux_find_memory_regions_thunk, &data);
 }
 
 /* Determine which signal stopped execution.  */
@@ -1506,8 +1535,8 @@  linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
   pack_long (buf, long_type, 1);
   obstack_grow (&data_obstack, buf, TYPE_LENGTH (long_type));
 
-  linux_find_memory_regions_full (gdbarch, linux_make_mappings_callback,
-				  &mapping_data);
+  linux_find_memory_regions_gdb (gdbarch, linux_make_mappings_callback,
+				 &mapping_data);
 
   if (mapping_data.file_count != 0)
     {
diff --git a/gdb/target.c b/gdb/target.c
index 306c21d..d11e7dc 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2942,6 +2942,22 @@  target_fileio_close_cleanup (void *opaque)
   target_fileio_close (fd, &target_errno);
 }
 
+typedef int (read_alloc_pread_ftype) (int handle, gdb_byte *read_buf, int len,
+				      ULONGEST offset, int *target_errno);
+
+static read_alloc_pread_ftype target_fileio_read_alloc_1_pread;
+
+/* Helper for target_fileio_read_alloc_1 to make it interruptible.  */
+
+static int
+target_fileio_read_alloc_1_pread (int handle, gdb_byte *read_buf, int len,
+				  ULONGEST offset, int *target_errno)
+{
+  QUIT;
+
+  return target_fileio_pread (handle, read_buf, len, offset, target_errno);
+}
+
 /* Read target file FILENAME.  Store the result in *BUF_P and
    return the size of the transferred data.  PADDING additional bytes are
    available in *BUF_P.  This is a helper function for
@@ -2949,22 +2965,14 @@  target_fileio_close_cleanup (void *opaque)
    information.  */
 
 static LONGEST
-target_fileio_read_alloc_1 (const char *filename,
-			    gdb_byte **buf_p, int padding)
+read_alloc (gdb_byte **buf_p, int handle, read_alloc_pread_ftype *pread_func,
+	    int padding)
 {
-  struct cleanup *close_cleanup;
   size_t buf_alloc, buf_pos;
   gdb_byte *buf;
   LONGEST n;
-  int fd;
   int target_errno;
 
-  fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno);
-  if (fd == -1)
-    return -1;
-
-  close_cleanup = make_cleanup (target_fileio_close_cleanup, &fd);
-
   /* Start by reading up to 4K at a time.  The target will throttle
      this number down if necessary.  */
   buf_alloc = 4096;
@@ -2972,25 +2980,24 @@  target_fileio_read_alloc_1 (const char *filename,
   buf_pos = 0;
   while (1)
     {
-      n = target_fileio_pread (fd, &buf[buf_pos],
-			       buf_alloc - buf_pos - padding, buf_pos,
-			       &target_errno);
-      if (n < 0)
-	{
-	  /* An error occurred.  */
-	  do_cleanups (close_cleanup);
-	  xfree (buf);
-	  return -1;
-	}
-      else if (n == 0)
+      n = pread_func (handle, &buf[buf_pos], buf_alloc - buf_pos - padding,
+		      buf_pos, &target_errno);
+      if (n <= 0)
 	{
-	  /* Read all there was.  */
-	  do_cleanups (close_cleanup);
-	  if (buf_pos == 0)
+	  if (n < 0 || (n == 0 && buf_pos == 0))
 	    xfree (buf);
 	  else
 	    *buf_p = buf;
-	  return buf_pos;
+	  if (n < 0)
+	    {
+	      /* An error occurred.  */
+	      return -1;
+	    }
+	  else
+	    {
+	      /* Read all there was.  */
+	      return buf_pos;
+	    }
 	}
 
       buf_pos += n;
@@ -3001,11 +3008,32 @@  target_fileio_read_alloc_1 (const char *filename,
 	  buf_alloc *= 2;
 	  buf = xrealloc (buf, buf_alloc);
 	}
-
-      QUIT;
     }
 }
 
+typedef LONGEST (read_stralloc_func_ftype) (const char *filename,
+					    gdb_byte **buf_p, int padding);
+
+static read_stralloc_func_ftype target_fileio_read_alloc_1;
+
+static LONGEST
+target_fileio_read_alloc_1 (const char *filename,
+			    gdb_byte **buf_p, int padding)
+{
+  struct cleanup *close_cleanup;
+  int fd, target_errno;
+  LONGEST retval;
+
+  fd = target_fileio_open (filename, FILEIO_O_RDONLY, 0700, &target_errno);
+  if (fd == -1)
+    return -1;
+
+  close_cleanup = make_cleanup (target_fileio_close_cleanup, &fd);
+  retval = read_alloc (buf_p, fd, target_fileio_read_alloc_1_pread, padding);
+  do_cleanups (close_cleanup);
+  return retval;
+}
+
 /* Read target file FILENAME.  Store the result in *BUF_P and return
    the size of the transferred data.  See the declaration in "target.h"
    function for more information about the return value.  */
@@ -3022,14 +3050,14 @@  target_fileio_read_alloc (const char *filename, gdb_byte **buf_p)
    are returned as allocated but empty strings.  A warning is issued
    if the result contains any embedded NUL bytes.  */
 
-char *
-target_fileio_read_stralloc (const char *filename)
+static char *
+read_stralloc (const char *filename, read_stralloc_func_ftype *func)
 {
   gdb_byte *buffer;
   char *bufstr;
   LONGEST i, transferred;
 
-  transferred = target_fileio_read_alloc_1 (filename, &buffer, 1);
+  transferred = func (filename, &buffer, 1);
   bufstr = (char *) buffer;
 
   if (transferred < 0)
@@ -3053,6 +3081,11 @@  target_fileio_read_stralloc (const char *filename)
   return bufstr;
 }
 
+char *
+target_fileio_read_stralloc (const char *filename)
+{
+  return read_stralloc (filename, target_fileio_read_alloc_1);
+}
 
 static int
 default_region_ok_for_hw_watchpoint (struct target_ops *self,