File gdb-6.8-bz254229-gcore-prpsinfo.patch of Package gdb

Index: gdb-7.1.90.20100711/bfd/elf-bfd.h
===================================================================
--- gdb-7.1.90.20100711.orig/bfd/elf-bfd.h	2010-06-27 06:07:51.000000000 +0200
+++ gdb-7.1.90.20100711/bfd/elf-bfd.h	2010-07-12 23:00:04.000000000 +0200
@@ -2171,8 +2171,9 @@ extern Elf_Internal_Phdr * _bfd_elf_find
 /* Exported interface for writing elf corefile notes. */
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
+#include <sys/procfs.h>
 extern char *elfcore_write_prpsinfo
-  (bfd *, char *, int *, const char *, const char *);
+  (bfd *, char *, int *, const prpsinfo_t *);
 extern char *elfcore_write_prstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char * elfcore_write_pstatus
Index: gdb-7.1.90.20100711/bfd/elf.c
===================================================================
--- gdb-7.1.90.20100711.orig/bfd/elf.c	2010-05-18 05:31:05.000000000 +0200
+++ gdb-7.1.90.20100711/bfd/elf.c	2010-07-12 22:51:17.000000000 +0200
@@ -8582,13 +8582,12 @@ elfcore_write_note (bfd *abfd,
   return buf;
 }
 
-#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
+#if defined (HAVE_PRPSINFO_T)
 char *
 elfcore_write_prpsinfo (bfd  *abfd,
 			char *buf,
 			int  *bufsiz,
-			const char *fname,
-			const char *psargs)
+			const prpsinfo_t *input)
 {
   const char *note_name = "CORE";
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
@@ -8596,48 +8595,55 @@ elfcore_write_prpsinfo (bfd  *abfd,
   if (bed->elf_backend_write_core_note != NULL)
     {
       char *ret;
+      char fname[sizeof (input->pr_fname) + 1];
+      char psargs[sizeof (input->pr_psargs) + 1];
+
+      strncpy (fname, input->pr_fname, sizeof (input->pr_fname));
+      fname[sizeof (input->pr_fname)] = 0;
+      strncpy (psargs, input->pr_psargs, sizeof (input->pr_psargs));
+      psargs[sizeof (input->pr_psargs)] = 0;
+
       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
 						 NT_PRPSINFO, fname, psargs);
       if (ret != NULL)
 	return ret;
     }
 
-#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
+#if defined (HAVE_PRPSINFO32_T)
   if (bed->s->elfclass == ELFCLASS32)
     {
-#if defined (HAVE_PSINFO32_T)
-      psinfo32_t data;
-      int note_type = NT_PSINFO;
-#else
       prpsinfo32_t data;
       int note_type = NT_PRPSINFO;
-#endif
 
       memset (&data, 0, sizeof (data));
-      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+      data.pr_state = input->pr_state;
+      data.pr_sname = input->pr_sname;
+      data.pr_zomb = input->pr_zomb;
+      data.pr_nice = input->pr_nice;
+      data.pr_flag = input->pr_flag;
+      data.pr_uid = input->pr_uid;
+      data.pr_gid = input->pr_gid;
+      data.pr_pid = input->pr_pid;
+      data.pr_ppid = input->pr_ppid;
+      data.pr_pgrp = input->pr_pgrp;
+      data.pr_sid = input->pr_sid;
+      BFD_ASSERT (sizeof (data.pr_fname) == sizeof (input->pr_fname));
+      memcpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      BFD_ASSERT (sizeof (data.pr_psargs) == sizeof (input->pr_psargs));
+      memcpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 note_name, note_type, &data, sizeof (data));
     }
   else
 #endif
     {
-#if defined (HAVE_PSINFO_T)
-      psinfo_t data;
-      int note_type = NT_PSINFO;
-#else
-      prpsinfo_t data;
       int note_type = NT_PRPSINFO;
-#endif
 
-      memset (&data, 0, sizeof (data));
-      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
-				 note_name, note_type, &data, sizeof (data));
+				 note_name, note_type, input, sizeof (*input));
     }
 }
-#endif	/* PSINFO_T or PRPSINFO_T */
+#endif	/* PRPSINFO_T */
 
 #if defined (HAVE_PRSTATUS_T)
 char *
Index: gdb-7.1.90.20100711/gdb/linux-nat.c
===================================================================
--- gdb-7.1.90.20100711.orig/gdb/linux-nat.c	2010-07-12 23:05:22.000000000 +0200
+++ gdb-7.1.90.20100711/gdb/linux-nat.c	2010-07-12 22:57:34.000000000 +0200
@@ -4466,6 +4466,131 @@ linux_spu_make_corefile_notes (bfd *obfd
   return args.note_data;
 }
 
+/* Should be always true for Linux */
+#define HAVE_PRPSINFO_T 1
+
+#if defined (HAVE_PRPSINFO_T)
+
+/* Fills struct elf_prpsinfo{32,64} as much as possible, imitate Linux kernel
+   binfmt_elf.c.  Unknown values are filled with zeroes.  The structure is
+   malloced.  */
+
+static const prpsinfo_t *
+fill_prpsinfo (void)
+{
+  struct stat sb;
+  char filename[sizeof ("/proc//cmdline") + sizeof (int) * 3 + 2];
+  char buf[1024];
+  char proc_state[5];
+  char proc_cmdline[sizeof (((struct elf_prpsinfo*)0)->pr_psargs) + 1];
+  unsigned flags;
+  long proc_nice;
+  unsigned proc_ppid;
+  unsigned proc_pgid;
+  unsigned proc_sid;
+  pid_t pid;
+  int fd, n;
+  char *cp, *proc_comm, *state_s;
+  /* String comes from Linux kernel binfmt_elf.c FILL_PSINFO but it is already
+     obsolete there to <linux/sched.h> TASK_* constants.  */
+  const char state_string[] = "RSDTZW";
+  int state_num;
+  static prpsinfo_t retval;
+
+  /* Get /proc/$PID/stat.  */
+  pid = ptid_get_pid (inferior_ptid);
+  sprintf (filename, "/proc/%u/stat", (unsigned)pid);
+  fd = open (filename, O_RDONLY);
+  if (fd < 0)
+    return NULL;
+  fstat (fd, &sb); /* No error checking (can it ever happen?).  */
+  n = read (fd, buf, sizeof (buf) - 1);
+  close (fd);
+  if (n < 0)
+    return NULL;
+  buf[n] = 0;
+
+  cp = strrchr (buf, ')'); /* Split into "PID (COMM" and "<rest>".  */
+  if (!cp)
+    return NULL;
+  *cp = 0;
+
+  /* Grab COMM.  */
+  proc_comm = strchr (buf, '(');
+  if (!proc_comm)
+    return NULL;
+  proc_comm++;
+
+  /* Read /proc/$PID/cmdline.  */
+  proc_cmdline[0] = 0;
+  strcpy (strrchr (filename, '/'), "/cmdline");
+  fd = open (filename, O_RDONLY);
+  if (fd >= 0)
+    {
+      int n;
+
+      n = read (fd, proc_cmdline, sizeof (proc_cmdline) - 1);
+      if (n < 0)
+	n = 0;
+      proc_cmdline[n] = 0;
+      while (n--) /* Replace NULs with spaces.  */
+	if (proc_cmdline[n] == 0)
+	  proc_cmdline[n] = ' ';
+      close (fd);
+    }
+
+  /* Parse /proc/$PID/stat.  */
+  n = sscanf (cp + 2, /* skip ") " */
+	      "%4s %u "          /* state, ppid */
+	      "%u %u %*s %*s "   /* pgid, sid, tty, tpgid */
+	      "%u %*s %*s %*s "  /* flags, min_flt, cmin_flt, maj_flt */
+	      "%*s "             /* cmaj_flt */
+	      "%*s %*s "         /* utime, stime */
+	      "%*s %*s %*s "     /* cutime, cstime, priority */
+	      "%ld "             /* nice */
+	      /*"%*s %*s "          timeout, it_real_value */
+	      /*"%lu "              start_time */
+	      /*"%lu "              vsize */
+	      /*"%lu "              rss */
+	      /*"%lu %lu %lu "      rss_rlim, start_code, end_code */
+	      /*"%lu %lu %lu "      start_stack, kstk_esp, kstk_eip */
+	      /*"%u %u %u %u "      signal, blocked, sigignore, sigcatch */
+	      /*"%lu %lu %lu"       wchan, nswap, cnswap */
+	      , proc_state, &proc_ppid,
+	      &proc_pgid, &proc_sid,
+	      &flags,
+	      &proc_nice);
+  if (n != 6)
+    return NULL;
+
+  state_s = strchr (state_string, proc_state[0]);
+  if (state_s != NULL)
+    state_num = state_s - state_string;
+  else
+    {
+      /* 0 means Running, some more unusal state would be better.  */
+      state_num = 0;
+    }
+
+  memset (&retval, 0, sizeof (retval));
+  retval.pr_state = state_num;
+  retval.pr_sname = proc_state[0];
+  retval.pr_zomb = (proc_state[0] == 'Z');
+  retval.pr_nice = proc_nice;
+  retval.pr_flag = flags;
+  retval.pr_uid = sb.st_uid;
+  retval.pr_gid = sb.st_gid;
+  retval.pr_pid = pid;
+  retval.pr_ppid = proc_ppid;
+  retval.pr_pgrp = proc_pgid;
+  retval.pr_sid = proc_sid;
+  strncpy (retval.pr_fname, proc_comm, sizeof (retval.pr_fname));
+  strncpy (retval.pr_psargs, proc_cmdline, sizeof (retval.pr_psargs));
+
+  return &retval;
+}
+#endif
+
 /* Fills the "to_make_corefile_note" target vector.  Builds the note
    section for a corefile, and returns it in a malloc buffer.  */
 
@@ -4484,26 +4609,11 @@ linux_nat_make_corefile_notes (bfd *obfd
 
   if (get_exec_file (0))
     {
-      strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
-      strncpy (psargs, get_exec_file (0), sizeof (psargs));
-      if (get_inferior_args ())
-	{
-	  char *string_end;
-	  char *psargs_end = psargs + sizeof (psargs);
-
-	  /* linux_elfcore_write_prpsinfo () handles zero unterminated
-	     strings fine.  */
-	  string_end = memchr (psargs, 0, sizeof (psargs));
-	  if (string_end != NULL)
-	    {
-	      *string_end++ = ' ';
-	      strncpy (string_end, get_inferior_args (),
-		       psargs_end - string_end);
-	    }
-	}
+      const prpsinfo_t *data = fill_prpsinfo ();
+
       note_data = (char *) elfcore_write_prpsinfo (obfd,
 						   note_data,
-						   note_size, fname, psargs);
+						   note_size, data);
     }
 
   /* Dump information for threads.  */
Index: gdb-7.1.90.20100711/gdb/procfs.c
===================================================================
--- gdb-7.1.90.20100711.orig/gdb/procfs.c	2010-07-07 18:15:16.000000000 +0200
+++ gdb-7.1.90.20100711/gdb/procfs.c	2010-07-12 23:05:23.000000000 +0200
@@ -5770,6 +5770,7 @@ procfs_make_note_section (bfd *obfd, int
   note_data = (char *) elfcore_write_prpsinfo (obfd,
 					       note_data,
 					       note_size,
+					       NULL,
 					       fname,
 					       psargs);