public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
@ 2012-12-17  3:10 Sergio Durigan Junior
  2012-12-17 15:43 ` H.J. Lu
  2012-12-18 17:38 ` Jan Kratochvil
  0 siblings, 2 replies; 21+ messages in thread
From: Sergio Durigan Junior @ 2012-12-17  3:10 UTC (permalink / raw)
  To: Binutils Development; +Cc: GDB Patches, Pedro Alves, H.J. Lu

Hi,

This is a follow-up on:
     <http://sourceware.org/ml/binutils/2012-11/msg00240.html>

Sorry for the delay on this.  I addressed Pedro's and H.J.'s comments,
and took some time to test the patch on different architectures.

It also took me some time to decide the best way to handle several
little issues that I was facing: different declarations for PPC needed,
different declarations for PRPSINFO structures, etc.

Anyway, I hope I managed to solve these problems, but I would really
appreciate some comments (if you have, of course) about the code.  The
idea was to simplify the handling of PRPSINFO, so:

1) I created elf_{internal,external}_prpsinfo* structures, organized
differently according to their purposes.

2) I created the new PRPSINFO*_COPY_FIELDS macros, which take care of
(duh) copying the fields from the internal to the external structures,
obeying bitness and such.

3) I also took the liberty to implement the i386 version of the
*_write_core_note.

4) I removed some dependency on the CORE_HEADER macro (suggested by
Pedro).  Not sure if everything is correct, though.

Anyway, I guess those are the main changes.  Please let me know if you
have some question about the patch.  Thanks.

-- 
Sergio

2012-12-17  Sergio Durigan Junior  <sergiodj@redhat.com>

	* Makefile.in (BUILD_CFILES): Add `elf-psinfo.h'.
	* elf-bfd.h (elf_internal_prpsinfo): Forward declaration for
	structure.
	(elfcore_write_prpsinfo): Change prototype, accepting
	`elf_internal_prpsinfo' as argument.
	* elf-psinfo.h: New file.
	* elf.c: Include `elf-psinfo.h'.
	(elfcore_psinfo_t, elfcore_psinfo32_t): Remove declarations.
	(elfcore_grok_psinfo): Refactor the #ifdef's to not consider
	`HAVE_PRPSINFO*' defines.
	(elfcore_write_prpsinfo): Change prototype, accepting
	`elf_internal_prpsinfo' as argument.  Rewrite parts of the code to
	make use of the new argument.
	* elf32-arm.c: Include `elf-psinfo.h'.
	(elf32_arm_nabi_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf32-i386.c: Include `elf-bfd.h', `elf-psinfo.h' and `stdarg.h'.
	Include `CORE_HEADER' if defined.
	(elf_i386_write_core_note): New function.
	* elf32-ppc.c: Include `elf-psinfo.h'.
	(ppc_elf_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf64-ppc.c: Include `elf-psinfo.h'.
	(ppc64_elf_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf64-x86-64.c: Include `elf-psinfo.h'.  Include `stdarg.h'
	unconditionally.
	(elf_x86_64_write_core_note): Remove `#ifdef CORE_HEADER', making the
	function unconditionally available.  Refactor `NT_PRPSINFO' case.
	* hosts/x86-64linux.h (HAVE_PRPSINFO32_T, HAVE_PRPSINFO32_T_PR_PID,
	elf_prpsinfo32, elf_prpsinfo64, prpsinfo32_t, prpsinfo64_t): Remove
	definitions, moving some of them to `elf-psinfo.h'.

---
 bfd/Makefile.in         |    2 +-
 bfd/elf-bfd.h           |    6 +-
 bfd/elf-psinfo.h        |  215 +++++++++++++++++++++++++++++++++++++++++++++++
 bfd/elf.c               |   38 ++++-----
 bfd/elf32-arm.c         |   13 ++-
 bfd/elf32-i386.c        |   70 +++++++++++++++
 bfd/elf32-ppc.c         |   14 ++-
 bfd/elf64-ppc.c         |   14 ++-
 bfd/elf64-x86-64.c      |   36 ++++----
 bfd/hosts/x86-64linux.h |   37 --------
 10 files changed, 353 insertions(+), 92 deletions(-)
 create mode 100644 bfd/elf-psinfo.h

diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 92d9d08..e12deb5 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1050,7 +1050,7 @@ BUILD_CFILES = \
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
-	elf-bfd.h elf-hppa.h elf32-hppa.h \
+	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
 	elf64-hppa.h elfcode.h elfcore.h \
 	freebsd.h genlink.h go32stub.h \
 	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index b8d82b1..d314291 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2234,11 +2234,15 @@ extern bfd_boolean bfd_elf_lookup_section_flags
 extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
   (bfd * abfd, asection * section);
 
+/* Forward declaration of prpsinfo.  See `elf-psinfo.h' for more details.  */
+
+struct elf_internal_prpsinfo;
+
 /* Exported interface for writing elf corefile notes. */
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
 extern char *elfcore_write_prpsinfo
-  (bfd *, char *, int *, const char *, const char *);
+  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
 extern char *elfcore_write_prstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char * elfcore_write_pstatus
diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
new file mode 100644
index 0000000..61b38e1
--- /dev/null
+++ b/bfd/elf-psinfo.h
@@ -0,0 +1,215 @@
+/* Declarations for PRPSINFO structures under ELF on GNU/Linux.
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#undef HAVE_PRPSINFO32_T
+#define HAVE_PRPSINFO32_T
+#undef HAVE_PRPSINFO32_T_PR_PID
+#define HAVE_PRPSINFO32_T_PR_PID
+
+/* Maximum size of the arguments that can be stored in a PRPSINFO
+   structure.  */
+
+#define ELF_PRARGSZ (80)
+
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of the corefile.
+
+   This is an "internal" structure in the sense that it should be used to
+   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
+   so things like endianess shouldn't be an issue.  This structure will
+   eventually be converted in one of the `elf_external_*' structures
+   below.  */
+
+struct elf_internal_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long pr_flag;		/* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[2];
+    char pr_gid[2];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* External 32-bit PPC structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   The reason why we have a different structure only for PPC is because
+   on this architecture (and *only* here!) the size of 32-bit structure
+   changes.  This is due to the different sizes of `pr_uid' and `pr_gid',
+   which on non-PPC architectures are declared as `short int' and on PPC
+   architectures are declared as `int'.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_ppc_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_16 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_16 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_PPC_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   Differently from the 32-bit version, the PowerPC guys made our lives better
+   and used the same size as the other architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo64
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[8];			/* Flags.  */
+    char gap[4];
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo64'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO64_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_64 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* Process info.  In the end we do provide typedefs for them.  */
+
+typedef struct elf_external_prpsinfo32 prpsinfo32_t;
+typedef struct elf_external_prpsinfo64 prpsinfo64_t;
diff --git a/bfd/elf.c b/bfd/elf.c
index a92dd5d..a39b88c 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -44,6 +44,7 @@ SECTION
 #include "elf-bfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
+#include "elf-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -8161,13 +8162,6 @@ elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
   return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
 }
 
-#if defined (HAVE_PRPSINFO_T)
-typedef prpsinfo_t   elfcore_psinfo_t;
-#if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
-typedef prpsinfo32_t elfcore_psinfo32_t;
-#endif
-#endif
-
 #if defined (HAVE_PSINFO_T)
 typedef psinfo_t   elfcore_psinfo_t;
 #if defined (HAVE_PSINFO32_T)		/* Sparc64 cross Sparc32 */
@@ -8201,17 +8195,17 @@ _bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
   return dups;
 }
 
-#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
 static bfd_boolean
 elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 {
+#if defined (HAVE_PSINFO_T)
   if (note->descsz == sizeof (elfcore_psinfo_t))
     {
       elfcore_psinfo_t psinfo;
 
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
-#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
+#if defined (HAVE_PSINFO_T_PR_PID)
       elf_tdata (abfd)->core_pid = psinfo.pr_pid;
 #endif
       elf_tdata (abfd)->core_program
@@ -8222,7 +8216,7 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
 				sizeof (psinfo.pr_psargs));
     }
-#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
+#if defined (HAVE_PSINFO32_T)
   else if (note->descsz == sizeof (elfcore_psinfo32_t))
     {
       /* 64-bit host, 32-bit corefile */
@@ -8230,7 +8224,7 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
-#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
+#if defined (HAVE_PSINFO32_T_PR_PID)
       elf_tdata (abfd)->core_pid = psinfo.pr_pid;
 #endif
       elf_tdata (abfd)->core_program
@@ -8261,10 +8255,14 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
     if (0 < n && command[n - 1] == ' ')
       command[n - 1] = '\0';
   }
+#else /* defined (HAVE_PSINFO_T) */
+  /* Avoid compiler warning about "unused variables".  */
+  (void) abfd;
+  (void) note;
 
   return TRUE;
+#endif
 }
-#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */
 
 #if defined (HAVE_PSTATUS_T)
 static bfd_boolean
@@ -9062,16 +9060,16 @@ char *
 elfcore_write_prpsinfo (bfd  *abfd,
 			char *buf,
 			int  *bufsiz,
-			const char *fname,
-			const char *psargs)
+			const struct elf_internal_prpsinfo *input)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (bed->elf_backend_write_core_note != NULL)
     {
       char *ret;
+
       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
-						 NT_PRPSINFO, fname, psargs);
+						 NT_PRPSINFO, input);
       if (ret != NULL)
 	return ret;
     }
@@ -9089,8 +9087,8 @@ elfcore_write_prpsinfo (bfd  *abfd,
 #endif
 
       memset (&data, 0, sizeof (data));
-      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
@@ -9101,13 +9099,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
       psinfo_t data;
       int note_type = NT_PSINFO;
 #else
-      prpsinfo_t data;
+      prpsinfo64_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));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index fd7d26a..cacc895 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -30,6 +30,7 @@
 #include "elf-nacl.h"
 #include "elf-vxworks.h"
 #include "elf/arm.h"
+#include "elf-psinfo.h"
 
 /* Return the relocation section associated with NAME.  HTAB is the
    bfd's elf32_arm_link_hash_entry.  */
@@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       {
-	char data[124];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 28, va_arg (ap, const char *), 16);
-	strncpy (data + 44, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
 
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index a188cec..5b81baa 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -31,12 +31,20 @@
 #include "objalloc.h"
 #include "hashtab.h"
 #include "dwarf2.h"
+#include "elf-bfd.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 /* 386 uses REL relocations instead of RELA.  */
 #define USE_REL	1
 
 #include "elf/i386.h"
 
+#ifdef CORE_HEADER
+#include CORE_HEADER
+#endif
+
 static reloc_howto_type elf_howto_table[]=
 {
   HOWTO(R_386_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
@@ -500,6 +508,67 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
   return TRUE;
 }
+
+static char *
+elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+			  int note_type, ...)
+{
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  va_list ap;
+  const struct elf_internal_prpsinfo *prpsinfo;
+  long pid;
+  int cursig;
+  const void *gregs;
+  struct elf_external_prpsinfo32 data;
+
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+      va_start (ap, note_type);
+      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
+      va_end (ap);
+
+      memset (&data, 0, sizeof (data));
+      PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
+      return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+				 &data, sizeof (data));
+      /* NOTREACHED */
+
+    case NT_PRSTATUS:
+      va_start (ap, note_type);
+      pid = va_arg (ap, long);
+      cursig = va_arg (ap, int);
+      gregs = va_arg (ap, const void *);
+      va_end (ap);
+
+      if (bed->elf_machine_code == EM_X86_64)
+	{
+	  prstatusx32_t prstat;
+	  memset (&prstat, 0, sizeof (prstat));
+	  prstat.pr_pid = pid;
+	  prstat.pr_cursig = cursig;
+	  memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
+	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+				     &prstat, sizeof (prstat));
+	}
+      else
+	{
+	  prstatus32_t prstat;
+	  memset (&prstat, 0, sizeof (prstat));
+	  prstat.pr_pid = pid;
+	  prstat.pr_cursig = cursig;
+	  memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
+	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+				     &prstat, sizeof (prstat));
+	}
+    }
+  /* NOTREACHED */
+}
+
 \f
 /* Functions for the i386 ELF linker.
 
@@ -5140,6 +5209,7 @@ elf_i386_add_symbol_hook (bfd * abfd,
 #define elf_backend_gc_sweep_hook	      elf_i386_gc_sweep_hook
 #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
 #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
+#define elf_backend_write_core_note	      elf_i386_write_core_note
 #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
 #define elf_backend_relocate_section	      elf_i386_relocate_section
 #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 5241926..2869663 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -37,6 +37,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "elf-psinfo.h"
 
 typedef enum split16_format_type
 {
@@ -2222,16 +2223,19 @@ ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 
     case NT_PRPSINFO:
       {
-	char data[128];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_ppc_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 32, va_arg (ap, const char *), 16);
-	strncpy (data + 48, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_PPC_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 10b6f9d..4eda989 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -34,6 +34,7 @@
 #include "elf-bfd.h"
 #include "elf/ppc64.h"
 #include "elf64-ppc.h"
+#include "elf-psinfo.h"
 #include "dwarf2.h"
 
 static bfd_reloc_status_type ppc64_elf_ha_reloc
@@ -2718,16 +2719,19 @@ ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
 
     case NT_PRPSINFO:
       {
-	char data[136];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo64 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 40, va_arg (ap, const char *), 16);
-	strncpy (data + 56, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 283681c..2c9939d 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -32,11 +32,13 @@
 #include "hashtab.h"
 #include "dwarf2.h"
 #include "libiberty.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 #include "elf/x86-64.h"
 
 #ifdef CORE_HEADER
-#include <stdarg.h>
 #include CORE_HEADER
 #endif
 
@@ -415,14 +417,13 @@ elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
-#ifdef CORE_HEADER
 static char *
 elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 			    int note_type, ...)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   va_list ap;
-  const char *fname, *psargs;
+  const struct elf_internal_prpsinfo *prpsinfo;
   long pid;
   int cursig;
   const void *gregs;
@@ -434,27 +435,28 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       va_start (ap, note_type);
-      fname = va_arg (ap, const char *);
-      psargs = va_arg (ap, const char *);
+      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
       va_end (ap);
 
       if (bed->s->elfclass == ELFCLASS32)
 	{
-	  prpsinfo32_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo32 data32;
+
+	  memset (&data32, 0, sizeof (data32));
+	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data32);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data32, sizeof (data32));
 	}
       else
 	{
-	  prpsinfo64_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo64 data64;
+
+	  memset (&data64, 0, sizeof (data64));
+	  PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data64);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data64, sizeof (data64));
 	}
       /* NOTREACHED */
 
@@ -501,7 +503,7 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
     }
   /* NOTREACHED */
 }
-#endif
+
 \f
 /* Functions for the x86-64 ELF linker.	 */
 
@@ -5225,9 +5227,7 @@ static const struct bfd_elf_special_section
 #define elf_backend_gc_sweep_hook	    elf_x86_64_gc_sweep_hook
 #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
 #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
-#ifdef CORE_HEADER
 #define elf_backend_write_core_note	    elf_x86_64_write_core_note
-#endif
 #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
 #define elf_backend_relocate_section	    elf_x86_64_relocate_section
 #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
diff --git a/bfd/hosts/x86-64linux.h b/bfd/hosts/x86-64linux.h
index 78be09a..6070978 100644
--- a/bfd/hosts/x86-64linux.h
+++ b/bfd/hosts/x86-64linux.h
@@ -43,11 +43,6 @@ typedef unsigned long long int uint64_t;
 /* Unsigned 64-bit integer aligned to 8 bytes.  */
 typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
 
-#undef HAVE_PRPSINFO32_T
-#define HAVE_PRPSINFO32_T
-#undef HAVE_PRPSINFO32_T_PR_PID
-#define HAVE_PRPSINFO32_T_PR_PID
-
 #undef HAVE_PRSTATUS32_T
 #define HAVE_PRSTATUS32_T
 
@@ -191,36 +186,6 @@ struct elf_prstatus64
     int pr_fpvalid;			/* True if math copro being used.  */
   };
 
-struct elf_prpsinfo32
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    unsigned int pr_flag;		/* Flags.  */
-    unsigned short int pr_uid;
-    unsigned short int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
-struct elf_prpsinfo64
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    a8_uint64_t pr_flag;		/* Flags.  */
-    unsigned int pr_uid;
-    unsigned int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
 /* The rest of this file provides the types for emulation of the
    Solaris <proc_service.h> interfaces that should be implemented by
    users of libthread_db.  */
@@ -229,5 +194,3 @@ struct elf_prpsinfo64
 typedef struct elf_prstatus32 prstatus32_t;
 typedef struct elf_prstatusx32 prstatusx32_t;
 typedef struct elf_prstatus64 prstatus64_t;
-typedef struct elf_prpsinfo32 prpsinfo32_t;
-typedef struct elf_prpsinfo64 prpsinfo64_t;
-- 
1.7.7.6

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-17  3:10 [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils Sergio Durigan Junior
@ 2012-12-17 15:43 ` H.J. Lu
  2012-12-17 17:41   ` Sergio Durigan Junior
  2012-12-18 17:38 ` Jan Kratochvil
  1 sibling, 1 reply; 21+ messages in thread
From: H.J. Lu @ 2012-12-17 15:43 UTC (permalink / raw)
  To: Sergio Durigan Junior; +Cc: Binutils Development, GDB Patches, Pedro Alves

On Sun, Dec 16, 2012 at 7:09 PM, Sergio Durigan Junior
<sergiodj@redhat.com> wrote:
> Hi,
>
> This is a follow-up on:
>      <http://sourceware.org/ml/binutils/2012-11/msg00240.html>
>
> Sorry for the delay on this.  I addressed Pedro's and H.J.'s comments,
> and took some time to test the patch on different architectures.
>
> It also took me some time to decide the best way to handle several
> little issues that I was facing: different declarations for PPC needed,
> different declarations for PRPSINFO structures, etc.
>
> Anyway, I hope I managed to solve these problems, but I would really
> appreciate some comments (if you have, of course) about the code.  The
> idea was to simplify the handling of PRPSINFO, so:
>
> 1) I created elf_{internal,external}_prpsinfo* structures, organized
> differently according to their purposes.
>
> 2) I created the new PRPSINFO*_COPY_FIELDS macros, which take care of
> (duh) copying the fields from the internal to the external structures,
> obeying bitness and such.
>
> 3) I also took the liberty to implement the i386 version of the
> *_write_core_note.
>
> 4) I removed some dependency on the CORE_HEADER macro (suggested by
> Pedro).  Not sure if everything is correct, though.
>
> Anyway, I guess those are the main changes.  Please let me know if you
> have some question about the patch.  Thanks.
>

> +
> +static char *
> +elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
> +                         int note_type, ...)
> +{
> +  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
> +  va_list ap;
> +  const struct elf_internal_prpsinfo *prpsinfo;
> +  long pid;
> +  int cursig;
> +  const void *gregs;
> +  struct elf_external_prpsinfo32 data;
> +
> +  switch (note_type)
> +    {
> +    default:
> +      return NULL;
> +
> +    case NT_PRPSINFO:
> +      va_start (ap, note_type);
> +      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
> +      va_end (ap);
> +
> +      memset (&data, 0, sizeof (data));
> +      PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
> +
> +      return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
> +                                &data, sizeof (data));
> +      /* NOTREACHED */
> +
> +    case NT_PRSTATUS:
> +      va_start (ap, note_type);
> +      pid = va_arg (ap, long);
> +      cursig = va_arg (ap, int);
> +      gregs = va_arg (ap, const void *);
> +      va_end (ap);
> +
> +      if (bed->elf_machine_code == EM_X86_64)
> +       {
> +         prstatusx32_t prstat;
> +         memset (&prstat, 0, sizeof (prstat));
> +         prstat.pr_pid = pid;
> +         prstat.pr_cursig = cursig;
> +         memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
> +         return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
> +                                    &prstat, sizeof (prstat));
> +       }
> +      else

When will elf_i386_write_core_note be called for
x32 process?


-- 
H.J.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-17 15:43 ` H.J. Lu
@ 2012-12-17 17:41   ` Sergio Durigan Junior
  2012-12-17 17:44     ` H.J. Lu
  0 siblings, 1 reply; 21+ messages in thread
From: Sergio Durigan Junior @ 2012-12-17 17:41 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils Development, GDB Patches, Pedro Alves

On Monday, December 17 2012, H. J. Lu wrote:

> On Sun, Dec 16, 2012 at 7:09 PM, Sergio Durigan Junior
> <sergiodj@redhat.com> wrote:

>> +      if (bed->elf_machine_code == EM_X86_64)
>> +       {
>> +         prstatusx32_t prstat;
>> +         memset (&prstat, 0, sizeof (prstat));
>> +         prstat.pr_pid = pid;
>> +         prstat.pr_cursig = cursig;
>> +         memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
>> +         return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
>> +                                    &prstat, sizeof (prstat));
>> +       }
>> +      else
>
> When will elf_i386_write_core_note be called for
> x32 process?

Ops, sorry, that code sneaked in apparently.  Here's the new version of
the patch.

-- 
Sergio

---
 bfd/Makefile.in         |    2 +-
 bfd/elf-bfd.h           |    6 +-
 bfd/elf-psinfo.h        |  215 +++++++++++++++++++++++++++++++++++++++++++++++
 bfd/elf.c               |   38 ++++-----
 bfd/elf32-arm.c         |   13 ++-
 bfd/elf32-i386.c        |   62 ++++++++++++++
 bfd/elf32-ppc.c         |   14 ++-
 bfd/elf64-ppc.c         |   14 ++-
 bfd/elf64-x86-64.c      |   36 ++++----
 bfd/hosts/x86-64linux.h |   37 --------
 10 files changed, 345 insertions(+), 92 deletions(-)
 create mode 100644 bfd/elf-psinfo.h

diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 92d9d08..e12deb5 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1050,7 +1050,7 @@ BUILD_CFILES = \
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
-	elf-bfd.h elf-hppa.h elf32-hppa.h \
+	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
 	elf64-hppa.h elfcode.h elfcore.h \
 	freebsd.h genlink.h go32stub.h \
 	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index b8d82b1..d314291 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2234,11 +2234,15 @@ extern bfd_boolean bfd_elf_lookup_section_flags
 extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
   (bfd * abfd, asection * section);
 
+/* Forward declaration of prpsinfo.  See `elf-psinfo.h' for more details.  */
+
+struct elf_internal_prpsinfo;
+
 /* Exported interface for writing elf corefile notes. */
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
 extern char *elfcore_write_prpsinfo
-  (bfd *, char *, int *, const char *, const char *);
+  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
 extern char *elfcore_write_prstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char * elfcore_write_pstatus
diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
new file mode 100644
index 0000000..61b38e1
--- /dev/null
+++ b/bfd/elf-psinfo.h
@@ -0,0 +1,215 @@
+/* Declarations for PRPSINFO structures under ELF on GNU/Linux.
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#undef HAVE_PRPSINFO32_T
+#define HAVE_PRPSINFO32_T
+#undef HAVE_PRPSINFO32_T_PR_PID
+#define HAVE_PRPSINFO32_T_PR_PID
+
+/* Maximum size of the arguments that can be stored in a PRPSINFO
+   structure.  */
+
+#define ELF_PRARGSZ (80)
+
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of the corefile.
+
+   This is an "internal" structure in the sense that it should be used to
+   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
+   so things like endianess shouldn't be an issue.  This structure will
+   eventually be converted in one of the `elf_external_*' structures
+   below.  */
+
+struct elf_internal_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long pr_flag;		/* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[2];
+    char pr_gid[2];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* External 32-bit PPC structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   The reason why we have a different structure only for PPC is because
+   on this architecture (and *only* here!) the size of 32-bit structure
+   changes.  This is due to the different sizes of `pr_uid' and `pr_gid',
+   which on non-PPC architectures are declared as `short int' and on PPC
+   architectures are declared as `int'.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_ppc_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_16 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_16 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_PPC_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   Differently from the 32-bit version, the PowerPC guys made our lives better
+   and used the same size as the other architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo64
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[8];			/* Flags.  */
+    char gap[4];
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo64'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO64_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_64 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* Process info.  In the end we do provide typedefs for them.  */
+
+typedef struct elf_external_prpsinfo32 prpsinfo32_t;
+typedef struct elf_external_prpsinfo64 prpsinfo64_t;
diff --git a/bfd/elf.c b/bfd/elf.c
index a92dd5d..a39b88c 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -44,6 +44,7 @@ SECTION
 #include "elf-bfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
+#include "elf-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -8161,13 +8162,6 @@ elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
   return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
 }
 
-#if defined (HAVE_PRPSINFO_T)
-typedef prpsinfo_t   elfcore_psinfo_t;
-#if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
-typedef prpsinfo32_t elfcore_psinfo32_t;
-#endif
-#endif
-
 #if defined (HAVE_PSINFO_T)
 typedef psinfo_t   elfcore_psinfo_t;
 #if defined (HAVE_PSINFO32_T)		/* Sparc64 cross Sparc32 */
@@ -8201,17 +8195,17 @@ _bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
   return dups;
 }
 
-#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
 static bfd_boolean
 elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 {
+#if defined (HAVE_PSINFO_T)
   if (note->descsz == sizeof (elfcore_psinfo_t))
     {
       elfcore_psinfo_t psinfo;
 
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
-#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
+#if defined (HAVE_PSINFO_T_PR_PID)
       elf_tdata (abfd)->core_pid = psinfo.pr_pid;
 #endif
       elf_tdata (abfd)->core_program
@@ -8222,7 +8216,7 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
 				sizeof (psinfo.pr_psargs));
     }
-#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
+#if defined (HAVE_PSINFO32_T)
   else if (note->descsz == sizeof (elfcore_psinfo32_t))
     {
       /* 64-bit host, 32-bit corefile */
@@ -8230,7 +8224,7 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
-#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
+#if defined (HAVE_PSINFO32_T_PR_PID)
       elf_tdata (abfd)->core_pid = psinfo.pr_pid;
 #endif
       elf_tdata (abfd)->core_program
@@ -8261,10 +8255,14 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
     if (0 < n && command[n - 1] == ' ')
       command[n - 1] = '\0';
   }
+#else /* defined (HAVE_PSINFO_T) */
+  /* Avoid compiler warning about "unused variables".  */
+  (void) abfd;
+  (void) note;
 
   return TRUE;
+#endif
 }
-#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */
 
 #if defined (HAVE_PSTATUS_T)
 static bfd_boolean
@@ -9062,16 +9060,16 @@ char *
 elfcore_write_prpsinfo (bfd  *abfd,
 			char *buf,
 			int  *bufsiz,
-			const char *fname,
-			const char *psargs)
+			const struct elf_internal_prpsinfo *input)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (bed->elf_backend_write_core_note != NULL)
     {
       char *ret;
+
       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
-						 NT_PRPSINFO, fname, psargs);
+						 NT_PRPSINFO, input);
       if (ret != NULL)
 	return ret;
     }
@@ -9089,8 +9087,8 @@ elfcore_write_prpsinfo (bfd  *abfd,
 #endif
 
       memset (&data, 0, sizeof (data));
-      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
@@ -9101,13 +9099,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
       psinfo_t data;
       int note_type = NT_PSINFO;
 #else
-      prpsinfo_t data;
+      prpsinfo64_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));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index fd7d26a..cacc895 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -30,6 +30,7 @@
 #include "elf-nacl.h"
 #include "elf-vxworks.h"
 #include "elf/arm.h"
+#include "elf-psinfo.h"
 
 /* Return the relocation section associated with NAME.  HTAB is the
    bfd's elf32_arm_link_hash_entry.  */
@@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       {
-	char data[124];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 28, va_arg (ap, const char *), 16);
-	strncpy (data + 44, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
 
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index a188cec..70b5e9b 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -31,12 +31,20 @@
 #include "objalloc.h"
 #include "hashtab.h"
 #include "dwarf2.h"
+#include "elf-bfd.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 /* 386 uses REL relocations instead of RELA.  */
 #define USE_REL	1
 
 #include "elf/i386.h"
 
+#ifdef CORE_HEADER
+#include CORE_HEADER
+#endif
+
 static reloc_howto_type elf_howto_table[]=
 {
   HOWTO(R_386_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
@@ -500,6 +508,59 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
   return TRUE;
 }
+
+static char *
+elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+			  int note_type, ...)
+{
+  va_list ap;
+
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+	{
+	  const struct elf_internal_prpsinfo *prpsinfo;
+	  struct elf_external_prpsinfo32 data;
+
+	  va_start (ap, note_type);
+	  prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
+	  va_end (ap);
+
+	  memset (&data, 0, sizeof (data));
+	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
+	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+				     &data, sizeof (data));
+	}
+      /* NOTREACHED */
+
+    case NT_PRSTATUS:
+	{
+	  long pid;
+	  int cursig;
+	  const void *gregs;
+	  prstatus32_t prstat;
+
+	  va_start (ap, note_type);
+	  pid = va_arg (ap, long);
+	  cursig = va_arg (ap, int);
+	  gregs = va_arg (ap, const void *);
+	  va_end (ap);
+
+	  memset (&prstat, 0, sizeof (prstat));
+	  prstat.pr_pid = pid;
+	  prstat.pr_cursig = cursig;
+	  memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
+	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+				     &prstat, sizeof (prstat));
+	}
+    }
+  /* NOTREACHED */
+}
+
 \f
 /* Functions for the i386 ELF linker.
 
@@ -5140,6 +5201,7 @@ elf_i386_add_symbol_hook (bfd * abfd,
 #define elf_backend_gc_sweep_hook	      elf_i386_gc_sweep_hook
 #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
 #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
+#define elf_backend_write_core_note	      elf_i386_write_core_note
 #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
 #define elf_backend_relocate_section	      elf_i386_relocate_section
 #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 5241926..2869663 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -37,6 +37,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "elf-psinfo.h"
 
 typedef enum split16_format_type
 {
@@ -2222,16 +2223,19 @@ ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 
     case NT_PRPSINFO:
       {
-	char data[128];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_ppc_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 32, va_arg (ap, const char *), 16);
-	strncpy (data + 48, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_PPC_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 10b6f9d..4eda989 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -34,6 +34,7 @@
 #include "elf-bfd.h"
 #include "elf/ppc64.h"
 #include "elf64-ppc.h"
+#include "elf-psinfo.h"
 #include "dwarf2.h"
 
 static bfd_reloc_status_type ppc64_elf_ha_reloc
@@ -2718,16 +2719,19 @@ ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
 
     case NT_PRPSINFO:
       {
-	char data[136];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo64 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 40, va_arg (ap, const char *), 16);
-	strncpy (data + 56, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 283681c..2c9939d 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -32,11 +32,13 @@
 #include "hashtab.h"
 #include "dwarf2.h"
 #include "libiberty.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 #include "elf/x86-64.h"
 
 #ifdef CORE_HEADER
-#include <stdarg.h>
 #include CORE_HEADER
 #endif
 
@@ -415,14 +417,13 @@ elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
-#ifdef CORE_HEADER
 static char *
 elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 			    int note_type, ...)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   va_list ap;
-  const char *fname, *psargs;
+  const struct elf_internal_prpsinfo *prpsinfo;
   long pid;
   int cursig;
   const void *gregs;
@@ -434,27 +435,28 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       va_start (ap, note_type);
-      fname = va_arg (ap, const char *);
-      psargs = va_arg (ap, const char *);
+      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
       va_end (ap);
 
       if (bed->s->elfclass == ELFCLASS32)
 	{
-	  prpsinfo32_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo32 data32;
+
+	  memset (&data32, 0, sizeof (data32));
+	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data32);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data32, sizeof (data32));
 	}
       else
 	{
-	  prpsinfo64_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo64 data64;
+
+	  memset (&data64, 0, sizeof (data64));
+	  PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data64);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data64, sizeof (data64));
 	}
       /* NOTREACHED */
 
@@ -501,7 +503,7 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
     }
   /* NOTREACHED */
 }
-#endif
+
 \f
 /* Functions for the x86-64 ELF linker.	 */
 
@@ -5225,9 +5227,7 @@ static const struct bfd_elf_special_section
 #define elf_backend_gc_sweep_hook	    elf_x86_64_gc_sweep_hook
 #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
 #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
-#ifdef CORE_HEADER
 #define elf_backend_write_core_note	    elf_x86_64_write_core_note
-#endif
 #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
 #define elf_backend_relocate_section	    elf_x86_64_relocate_section
 #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
diff --git a/bfd/hosts/x86-64linux.h b/bfd/hosts/x86-64linux.h
index 78be09a..6070978 100644
--- a/bfd/hosts/x86-64linux.h
+++ b/bfd/hosts/x86-64linux.h
@@ -43,11 +43,6 @@ typedef unsigned long long int uint64_t;
 /* Unsigned 64-bit integer aligned to 8 bytes.  */
 typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
 
-#undef HAVE_PRPSINFO32_T
-#define HAVE_PRPSINFO32_T
-#undef HAVE_PRPSINFO32_T_PR_PID
-#define HAVE_PRPSINFO32_T_PR_PID
-
 #undef HAVE_PRSTATUS32_T
 #define HAVE_PRSTATUS32_T
 
@@ -191,36 +186,6 @@ struct elf_prstatus64
     int pr_fpvalid;			/* True if math copro being used.  */
   };
 
-struct elf_prpsinfo32
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    unsigned int pr_flag;		/* Flags.  */
-    unsigned short int pr_uid;
-    unsigned short int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
-struct elf_prpsinfo64
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    a8_uint64_t pr_flag;		/* Flags.  */
-    unsigned int pr_uid;
-    unsigned int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
 /* The rest of this file provides the types for emulation of the
    Solaris <proc_service.h> interfaces that should be implemented by
    users of libthread_db.  */
@@ -229,5 +194,3 @@ struct elf_prpsinfo64
 typedef struct elf_prstatus32 prstatus32_t;
 typedef struct elf_prstatusx32 prstatusx32_t;
 typedef struct elf_prstatus64 prstatus64_t;
-typedef struct elf_prpsinfo32 prpsinfo32_t;
-typedef struct elf_prpsinfo64 prpsinfo64_t;
-- 
1.7.7.6

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-17 17:41   ` Sergio Durigan Junior
@ 2012-12-17 17:44     ` H.J. Lu
  2012-12-17 17:51       ` Sergio Durigan Junior
  0 siblings, 1 reply; 21+ messages in thread
From: H.J. Lu @ 2012-12-17 17:44 UTC (permalink / raw)
  To: Sergio Durigan Junior; +Cc: Binutils Development, GDB Patches, Pedro Alves

On Mon, Dec 17, 2012 at 9:41 AM, Sergio Durigan Junior
<sergiodj@redhat.com> wrote:
> On Monday, December 17 2012, H. J. Lu wrote:
>
>> On Sun, Dec 16, 2012 at 7:09 PM, Sergio Durigan Junior
>> <sergiodj@redhat.com> wrote:
>
>>> +      if (bed->elf_machine_code == EM_X86_64)
>>> +       {
>>> +         prstatusx32_t prstat;
>>> +         memset (&prstat, 0, sizeof (prstat));
>>> +         prstat.pr_pid = pid;
>>> +         prstat.pr_cursig = cursig;
>>> +         memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
>>> +         return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
>>> +                                    &prstat, sizeof (prstat));
>>> +       }
>>> +      else
>>
>> When will elf_i386_write_core_note be called for
>> x32 process?
>
> Ops, sorry, that code sneaked in apparently.  Here's the new version of
> the patch.
>

Can you create a git GDB branch for me to try?


-- 
H.J.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-17 17:44     ` H.J. Lu
@ 2012-12-17 17:51       ` Sergio Durigan Junior
  2012-12-17 22:01         ` H.J. Lu
  0 siblings, 1 reply; 21+ messages in thread
From: Sergio Durigan Junior @ 2012-12-17 17:51 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils Development, GDB Patches, Pedro Alves

On Monday, December 17 2012, H. J. Lu wrote:

>> Ops, sorry, that code sneaked in apparently.  Here's the new version of
>> the patch.
>>
>
> Can you create a git GDB branch for me to try?

Yep.

The branch is named archer-sergiodj-gcore-prpsinfo on
git://sourceware.org/git/archer.git .

Thanks,

-- 
Sergio

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-17 17:51       ` Sergio Durigan Junior
@ 2012-12-17 22:01         ` H.J. Lu
  2012-12-18  5:47           ` Sergio Durigan Junior
  0 siblings, 1 reply; 21+ messages in thread
From: H.J. Lu @ 2012-12-17 22:01 UTC (permalink / raw)
  To: Sergio Durigan Junior; +Cc: Binutils Development, GDB Patches, Pedro Alves

On Mon, Dec 17, 2012 at 9:50 AM, Sergio Durigan Junior
<sergiodj@redhat.com> wrote:
> On Monday, December 17 2012, H. J. Lu wrote:
>
>>> Ops, sorry, that code sneaked in apparently.  Here's the new version of
>>> the patch.
>>>
>>
>> Can you create a git GDB branch for me to try?
>
> Yep.
>
> The branch is named archer-sergiodj-gcore-prpsinfo on
> git://sourceware.org/git/archer.git .
>

I tried it and it works for x32.

Thanks.


-- 
H.J.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-17 22:01         ` H.J. Lu
@ 2012-12-18  5:47           ` Sergio Durigan Junior
  2012-12-18 15:43             ` H.J. Lu
  0 siblings, 1 reply; 21+ messages in thread
From: Sergio Durigan Junior @ 2012-12-18  5:47 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils Development, GDB Patches, Pedro Alves

On Monday, December 17 2012, H. J. Lu wrote:

> I tried it and it works for x32.

Thanks for trying it out, H.J.  I will wait until other maintainers
review this code, since it touches more architectures as well, before I
commit the patch.  But I assume your message means approval for x32,
right?

Thanks,

-- 
Sergio

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-18  5:47           ` Sergio Durigan Junior
@ 2012-12-18 15:43             ` H.J. Lu
  0 siblings, 0 replies; 21+ messages in thread
From: H.J. Lu @ 2012-12-18 15:43 UTC (permalink / raw)
  To: Sergio Durigan Junior; +Cc: Binutils Development, GDB Patches, Pedro Alves

On Mon, Dec 17, 2012 at 9:46 PM, Sergio Durigan Junior
<sergiodj@redhat.com> wrote:
> On Monday, December 17 2012, H. J. Lu wrote:
>
>> I tried it and it works for x32.
>
> Thanks for trying it out, H.J.  I will wait until other maintainers
> review this code, since it touches more architectures as well, before I
> commit the patch.  But I assume your message means approval for x32,
> right?
>

OK for i386 and x86-64 changes in BFD.

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-17  3:10 [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils Sergio Durigan Junior
  2012-12-17 15:43 ` H.J. Lu
@ 2012-12-18 17:38 ` Jan Kratochvil
  2012-12-18 19:19   ` Sergio Durigan Junior
  1 sibling, 1 reply; 21+ messages in thread
From: Jan Kratochvil @ 2012-12-18 17:38 UTC (permalink / raw)
  To: Sergio Durigan Junior
  Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

Hi Sergio,

I do not feel too confident in bfd/ but at least there may be more response to
my wrong comments.


> diff --git a/bfd/Makefile.in b/bfd/Makefile.in
> index 92d9d08..e12deb5 100644
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -1050,7 +1050,7 @@ BUILD_CFILES = \
>  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
>  SOURCE_HFILES = \
>  	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
> -	elf-bfd.h elf-hppa.h elf32-hppa.h \
> +	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
>  	elf64-hppa.h elfcode.h elfcore.h \
>  	freebsd.h genlink.h go32stub.h \
>  	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
> index b8d82b1..d314291 100644
> --- a/bfd/elf-bfd.h
> +++ b/bfd/elf-bfd.h
> @@ -2234,11 +2234,15 @@ extern bfd_boolean bfd_elf_lookup_section_flags
>  extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
>    (bfd * abfd, asection * section);
>  
> +/* Forward declaration of prpsinfo.  See `elf-psinfo.h' for more details.  */
> +
> +struct elf_internal_prpsinfo;
> +
>  /* Exported interface for writing elf corefile notes. */
>  extern char *elfcore_write_note
>    (bfd *, char *, int *, const char *, int, const void *, int);
>  extern char *elfcore_write_prpsinfo
> -  (bfd *, char *, int *, const char *, const char *);
> +  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
>  extern char *elfcore_write_prstatus
>    (bfd *, char *, int *, long, int, const void *);
>  extern char * elfcore_write_pstatus
> diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
> new file mode 100644
> index 0000000..61b38e1
> --- /dev/null
> +++ b/bfd/elf-psinfo.h
> @@ -0,0 +1,215 @@
> +/* Declarations for PRPSINFO structures under ELF on GNU/Linux.
> +   Copyright 2012 Free Software Foundation, Inc.
> +
> +   This file is part of BFD, the Binary File Descriptor library.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; if not, write to the Free Software
> +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
> +   MA 02110-1301, USA.  */
> +
> +#undef HAVE_PRPSINFO32_T
> +#define HAVE_PRPSINFO32_T
> +#undef HAVE_PRPSINFO32_T_PR_PID
> +#define HAVE_PRPSINFO32_T_PR_PID

This does not seem to be useful, these are auto-detected by configure and
elf-psinfo.h is included unconditionally.  Therefore they could be completely
removed.

But in reality they should not be removed as your elf-core definitions do not
cover very every target supported by bfd, only some of them.



> +
> +/* Maximum size of the arguments that can be stored in a PRPSINFO
> +   structure.  */
> +
> +#define ELF_PRARGSZ (80)
> +
> +/* Internal structure which holds information to be included in the
> +   PRPSINFO section of the corefile.
> +
> +   This is an "internal" structure in the sense that it should be used to
> +   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
> +   so things like endianess shouldn't be an issue.  This structure will
> +   eventually be converted in one of the `elf_external_*' structures
> +   below.  */
> +
> +struct elf_internal_prpsinfo
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    unsigned long pr_flag;		/* Flags.  */
> +    unsigned int pr_uid;
> +    unsigned int pr_gid;
> +    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
> +    /* Lots missing */
> +    char pr_fname[16];			/* Filename of executable.  */
> +    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
> +  };
> +
> +/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
> +   thus we choose to use char arrays here in order to avoid dealing with
> +   different types in different architectures.
> +
> +   This structure will ultimately be written in the corefile's note section,
> +   as the PRPSINFO.  */
> +
> +struct elf_external_prpsinfo32
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    char pr_flag[4];			/* Flags.  */
> +    char pr_uid[2];
> +    char pr_gid[2];
> +    char pr_pid[4];
> +    char pr_ppid[4];
> +    char pr_pgrp[4];
> +    char pr_sid[4];
> +    /* Lots missing */
> +    char pr_fname[16];			/* Filename of executable.  */
> +    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
> +  };

As it does not match very every arch I believe you should just copy it into
elf*-*.c files containing the *_elf_write_core_note function for archs where
you have verified (by comparing some headers, not just by experiment) it does
match.


> +
> +/* External 32-bit PPC structure for PRPSINFO.

If it is arch-specific then it should not be in a generic file.

I believe elf32-ppc.c and elf64-ppc.c files are fine for it.


In the end I do not see a use for this header file.


> diff --git a/bfd/elf.c b/bfd/elf.c
> index a92dd5d..a39b88c 100644
> --- a/bfd/elf.c
> +++ b/bfd/elf.c
> @@ -44,6 +44,7 @@ SECTION
>  #include "elf-bfd.h"
>  #include "libiberty.h"
>  #include "safe-ctype.h"
> +#include "elf-psinfo.h"
>  
>  #ifdef CORE_HEADER
>  #include CORE_HEADER
> @@ -8161,13 +8162,6 @@ elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
>    return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
>  }
>  
> -#if defined (HAVE_PRPSINFO_T)
> -typedef prpsinfo_t   elfcore_psinfo_t;
> -#if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
> -typedef prpsinfo32_t elfcore_psinfo32_t;
> -#endif
> -#endif
> -

This is arch-independent file (elf.c).  Some targets are unverified they match
your new ABI elfcore definition.  As they may provide correct system
prpsinfo_t defintion you should use it there, if available.


>  #if defined (HAVE_PSINFO_T)
>  typedef psinfo_t   elfcore_psinfo_t;
>  #if defined (HAVE_PSINFO32_T)		/* Sparc64 cross Sparc32 */
> @@ -8201,17 +8195,17 @@ _bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
>    return dups;
>  }
>  
> -#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)

All these changes are like the comment above.


>  static bfd_boolean
>  elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>  {
> +#if defined (HAVE_PSINFO_T)
>    if (note->descsz == sizeof (elfcore_psinfo_t))
>      {
>        elfcore_psinfo_t psinfo;
>  
>        memcpy (&psinfo, note->descdata, sizeof (psinfo));
>  
> -#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
> +#if defined (HAVE_PSINFO_T_PR_PID)
>        elf_tdata (abfd)->core_pid = psinfo.pr_pid;
>  #endif
>        elf_tdata (abfd)->core_program
> @@ -8222,7 +8216,7 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>  	= _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
>  				sizeof (psinfo.pr_psargs));
>      }
> -#if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
> +#if defined (HAVE_PSINFO32_T)
>    else if (note->descsz == sizeof (elfcore_psinfo32_t))
>      {
>        /* 64-bit host, 32-bit corefile */
> @@ -8230,7 +8224,7 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>  
>        memcpy (&psinfo, note->descdata, sizeof (psinfo));
>  
> -#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
> +#if defined (HAVE_PSINFO32_T_PR_PID)
>        elf_tdata (abfd)->core_pid = psinfo.pr_pid;
>  #endif
>        elf_tdata (abfd)->core_program
> @@ -8261,10 +8255,14 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>      if (0 < n && command[n - 1] == ' ')
>        command[n - 1] = '\0';
>    }
> +#else /* defined (HAVE_PSINFO_T) */
> +  /* Avoid compiler warning about "unused variables".  */
> +  (void) abfd;
> +  (void) note;
>  
>    return TRUE;
> +#endif
>  }
> -#endif /* defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T) */
>  
>  #if defined (HAVE_PSTATUS_T)
>  static bfd_boolean
> @@ -9062,16 +9060,16 @@ char *
>  elfcore_write_prpsinfo (bfd  *abfd,
>  			char *buf,
>  			int  *bufsiz,
> -			const char *fname,
> -			const char *psargs)
> +			const struct elf_internal_prpsinfo *input)
>  {
>    const struct elf_backend_data *bed = get_elf_backend_data (abfd);
>  
>    if (bed->elf_backend_write_core_note != NULL)
>      {
>        char *ret;
> +
>        ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
> -						 NT_PRPSINFO, fname, psargs);
> +						 NT_PRPSINFO, input);
>        if (ret != NULL)
>  	return ret;
>      }
> @@ -9089,8 +9087,8 @@ elfcore_write_prpsinfo (bfd  *abfd,
>  #endif
>  
>        memset (&data, 0, sizeof (data));
> -      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
> -      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
> +      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
> +      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
>        return elfcore_write_note (abfd, buf, bufsiz,
>  				 "CORE", note_type, &data, sizeof (data));
>      }
> @@ -9101,13 +9099,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
>        psinfo_t data;
>        int note_type = NT_PSINFO;
>  #else
> -      prpsinfo_t data;
> +      prpsinfo64_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));
> +      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
> +      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
>        return elfcore_write_note (abfd, buf, bufsiz,
>  				 "CORE", note_type, &data, sizeof (data));
>      }
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index fd7d26a..cacc895 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -30,6 +30,7 @@
>  #include "elf-nacl.h"
>  #include "elf-vxworks.h"
>  #include "elf/arm.h"
> +#include "elf-psinfo.h"
>  
>  /* Return the relocation section associated with NAME.  HTAB is the
>     bfd's elf32_arm_link_hash_entry.  */
> @@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  
>      case NT_PRPSINFO:
>        {
> -	char data[124];
> +	const struct elf_internal_prpsinfo *prpsinfo;
> +	struct elf_external_prpsinfo32 data;
>  	va_list ap;
>  
>  	va_start (ap, note_type);
> -	memset (data, 0, sizeof (data));
> -	strncpy (data + 28, va_arg (ap, const char *), 16);
> -	strncpy (data + 44, va_arg (ap, const char *), 80);
> +	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>  	va_end (ap);
>  
> +	memset (&data, 0, sizeof (data));
> +	PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
> +
>  	return elfcore_write_note (abfd, buf, bufsiz,
> -				   "CORE", note_type, data, sizeof (data));
> +				   "CORE", note_type, &data, sizeof (data));
>        }
>  
>      case NT_PRSTATUS:
> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> index a188cec..5b81baa 100644
> --- a/bfd/elf32-i386.c
> +++ b/bfd/elf32-i386.c
> @@ -31,12 +31,20 @@
>  #include "objalloc.h"
>  #include "hashtab.h"
>  #include "dwarf2.h"
> +#include "elf-bfd.h"
> +#include "elf-psinfo.h"
> +
> +#include <stdarg.h>
>  
>  /* 386 uses REL relocations instead of RELA.  */
>  #define USE_REL	1
>  
>  #include "elf/i386.h"
>  
> +#ifdef CORE_HEADER
> +#include CORE_HEADER
> +#endif

I believe new CORE_HEADER should not be introduced, they are rather deprecated
as they depend on system <procfs.h> which is not compatible for cross-build
core handling.  (But I may be completely wrong here.)


> +
>  static reloc_howto_type elf_howto_table[]=
>  {
>    HOWTO(R_386_NONE, 0, 0, 0, FALSE, 0, complain_overflow_bitfield,
> @@ -500,6 +508,67 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>  
>    return TRUE;
>  }
> +
> +static char *
> +elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
> +			  int note_type, ...)
> +{
> +  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
> +  va_list ap;
> +  const struct elf_internal_prpsinfo *prpsinfo;
> +  long pid;
> +  int cursig;
> +  const void *gregs;
> +  struct elf_external_prpsinfo32 data;
> +
> +  switch (note_type)
> +    {
> +    default:
> +      return NULL;
> +
> +    case NT_PRPSINFO:
> +      va_start (ap, note_type);
> +      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
> +      va_end (ap);

Maybe to use a union pointer instead?  But nothing serious, fine with va_arg.


> +
> +      memset (&data, 0, sizeof (data));
> +      PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
> +
> +      return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
> +				 &data, sizeof (data));
> +      /* NOTREACHED */


Thanks,
Jan

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-18 17:38 ` Jan Kratochvil
@ 2012-12-18 19:19   ` Sergio Durigan Junior
  2012-12-18 19:43     ` Jan Kratochvil
  0 siblings, 1 reply; 21+ messages in thread
From: Sergio Durigan Junior @ 2012-12-18 19:19 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

Thanks for the review.

On Tuesday, December 18 2012, Jan Kratochvil wrote:

>> diff --git a/bfd/Makefile.in b/bfd/Makefile.in
>> index 92d9d08..e12deb5 100644
>> --- a/bfd/Makefile.in
>> +++ b/bfd/Makefile.in
>> @@ -1050,7 +1050,7 @@ BUILD_CFILES = \
>>  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
>>  SOURCE_HFILES = \
>>  	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
>> -	elf-bfd.h elf-hppa.h elf32-hppa.h \
>> +	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
>>  	elf64-hppa.h elfcode.h elfcore.h \
>>  	freebsd.h genlink.h go32stub.h \
>>  	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
>> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
>> index b8d82b1..d314291 100644
>> --- a/bfd/elf-bfd.h
>> +++ b/bfd/elf-bfd.h
>> @@ -2234,11 +2234,15 @@ extern bfd_boolean bfd_elf_lookup_section_flags
>>  extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
>>    (bfd * abfd, asection * section);
>>  
>> +/* Forward declaration of prpsinfo.  See `elf-psinfo.h' for more details.  */
>> +
>> +struct elf_internal_prpsinfo;
>> +
>>  /* Exported interface for writing elf corefile notes. */
>>  extern char *elfcore_write_note
>>    (bfd *, char *, int *, const char *, int, const void *, int);
>>  extern char *elfcore_write_prpsinfo
>> -  (bfd *, char *, int *, const char *, const char *);
>> +  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
>>  extern char *elfcore_write_prstatus
>>    (bfd *, char *, int *, long, int, const void *);
>>  extern char * elfcore_write_pstatus
>> diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
>> new file mode 100644
>> index 0000000..61b38e1
>> --- /dev/null
>> +++ b/bfd/elf-psinfo.h
>> @@ -0,0 +1,215 @@
>> +/* Declarations for PRPSINFO structures under ELF on GNU/Linux.
>> +   Copyright 2012 Free Software Foundation, Inc.
>> +
>> +   This file is part of BFD, the Binary File Descriptor library.
>> +
>> +   This program is free software; you can redistribute it and/or modify
>> +   it under the terms of the GNU General Public License as published by
>> +   the Free Software Foundation; either version 3 of the License, or
>> +   (at your option) any later version.
>> +
>> +   This program is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> +   GNU General Public License for more details.
>> +
>> +   You should have received a copy of the GNU General Public License
>> +   along with this program; if not, write to the Free Software
>> +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
>> +   MA 02110-1301, USA.  */
>> +
>> +#undef HAVE_PRPSINFO32_T
>> +#define HAVE_PRPSINFO32_T
>> +#undef HAVE_PRPSINFO32_T_PR_PID
>> +#define HAVE_PRPSINFO32_T_PR_PID
>
> This does not seem to be useful, these are auto-detected by configure and
> elf-psinfo.h is included unconditionally.  Therefore they could be completely
> removed.

Indeed, I removed the last referecen to those defines a few minutes
before sending the patch.  I agree.

> But in reality they should not be removed as your elf-core definitions do not
> cover very every target supported by bfd, only some of them.

The patch covers the existing targets that already implemented the
*_write_core_note function, with the exception of i386 which is a new
implementation.  So I still agree with your comment above, that the
defines can be removed.

>> +/* Maximum size of the arguments that can be stored in a PRPSINFO
>> +   structure.  */
>> +
>> +#define ELF_PRARGSZ (80)
>> +
>> +/* Internal structure which holds information to be included in the
>> +   PRPSINFO section of the corefile.
>> +
>> +   This is an "internal" structure in the sense that it should be used to
>> +   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
>> +   so things like endianess shouldn't be an issue.  This structure will
>> +   eventually be converted in one of the `elf_external_*' structures
>> +   below.  */
>> +
>> +struct elf_internal_prpsinfo
>> +  {
>> +    char pr_state;			/* Numeric process state.  */
>> +    char pr_sname;			/* Char for pr_state.  */
>> +    char pr_zomb;			/* Zombie.  */
>> +    char pr_nice;			/* Nice val.  */
>> +    unsigned long pr_flag;		/* Flags.  */
>> +    unsigned int pr_uid;
>> +    unsigned int pr_gid;
>> +    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
>> +    /* Lots missing */
>> +    char pr_fname[16];			/* Filename of executable.  */
>> +    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
>> +  };
>> +
>> +/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
>> +   thus we choose to use char arrays here in order to avoid dealing with
>> +   different types in different architectures.
>> +
>> +   This structure will ultimately be written in the corefile's note section,
>> +   as the PRPSINFO.  */
>> +
>> +struct elf_external_prpsinfo32
>> +  {
>> +    char pr_state;			/* Numeric process state.  */
>> +    char pr_sname;			/* Char for pr_state.  */
>> +    char pr_zomb;			/* Zombie.  */
>> +    char pr_nice;			/* Nice val.  */
>> +    char pr_flag[4];			/* Flags.  */
>> +    char pr_uid[2];
>> +    char pr_gid[2];
>> +    char pr_pid[4];
>> +    char pr_ppid[4];
>> +    char pr_pgrp[4];
>> +    char pr_sid[4];
>> +    /* Lots missing */
>> +    char pr_fname[16];			/* Filename of executable.  */
>> +    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
>> +  };
>
> As it does not match very every arch I believe you should just copy it into
> elf*-*.c files containing the *_elf_write_core_note function for archs where
> you have verified (by comparing some headers, not just by experiment) it does
> match.

I disagree.  As I said above, the patch covers all targets that were
already implementing *_write_core_note.  If some new target decides to
implement it, it is just a matter of including "elf-psinfo.h" and using
the right structures.

>> +
>> +/* External 32-bit PPC structure for PRPSINFO.
>
> If it is arch-specific then it should not be in a generic file.
>
> I believe elf32-ppc.c and elf64-ppc.c files are fine for it.

Ok, I am fine with that.  I made this decision based on a quick chat
that I had with Pedro, asking him if it would be OK to create an
arch-specific structure for the case of 32-bit PPC.

I will move this definition to elf32-ppc.c, which is the only place that
uses this.

> In the end I do not see a use for this header file.

As I said above, I disagree.  The header file is useful for having a
single place which defines those structures (i.e., i386, x32 and ARM use
the same elf_external_prpsinfo32 strucutre).  Also, the header is useful
for including in the BFD clients (I'm thiking "GDB" here) which can use
the elf_internal_prpsinfo strucuture to pass information to BFD.

However, I agree with you that the arch-specific external structures
(like the PPC above) can be declared in their .c files.

>> diff --git a/bfd/elf.c b/bfd/elf.c
>> index a92dd5d..a39b88c 100644
>> --- a/bfd/elf.c
>> +++ b/bfd/elf.c
>> @@ -44,6 +44,7 @@ SECTION
>>  #include "elf-bfd.h"
>>  #include "libiberty.h"
>>  #include "safe-ctype.h"
>> +#include "elf-psinfo.h"
>>  
>>  #ifdef CORE_HEADER
>>  #include CORE_HEADER
>> @@ -8161,13 +8162,6 @@ elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
>>    return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
>>  }
>>  
>> -#if defined (HAVE_PRPSINFO_T)
>> -typedef prpsinfo_t   elfcore_psinfo_t;
>> -#if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
>> -typedef prpsinfo32_t elfcore_psinfo32_t;
>> -#endif
>> -#endif
>> -
>
> This is arch-independent file (elf.c).  Some targets are unverified they match
> your new ABI elfcore definition.  As they may provide correct system
> prpsinfo_t defintion you should use it there, if available.

Ok, I will revert this change.

>>  #if defined (HAVE_PSINFO_T)
>>  typedef psinfo_t   elfcore_psinfo_t;
>>  #if defined (HAVE_PSINFO32_T)		/* Sparc64 cross Sparc32 */
>> @@ -8201,17 +8195,17 @@ _bfd_elfcore_strndup (bfd *abfd, char *start, size_t max)
>>    return dups;
>>  }
>>  
>> -#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
>
> All these changes are like the comment above.

I will revert this.

>> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
>> index fd7d26a..cacc895 100644
>> --- a/bfd/elf32-arm.c
>> +++ b/bfd/elf32-arm.c
>> @@ -30,6 +30,7 @@
>>  #include "elf-nacl.h"
>>  #include "elf-vxworks.h"
>>  #include "elf/arm.h"
>> +#include "elf-psinfo.h"
>>  
>>  /* Return the relocation section associated with NAME.  HTAB is the
>>     bfd's elf32_arm_link_hash_entry.  */
>> @@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>>  
>>      case NT_PRPSINFO:
>>        {
>> -	char data[124];
>> +	const struct elf_internal_prpsinfo *prpsinfo;
>> +	struct elf_external_prpsinfo32 data;
>>  	va_list ap;
>>  
>>  	va_start (ap, note_type);
>> -	memset (data, 0, sizeof (data));
>> -	strncpy (data + 28, va_arg (ap, const char *), 16);
>> -	strncpy (data + 44, va_arg (ap, const char *), 80);
>> +	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>>  	va_end (ap);
>>  
>> +	memset (&data, 0, sizeof (data));
>> +	PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
>> +
>>  	return elfcore_write_note (abfd, buf, bufsiz,
>> -				   "CORE", note_type, data, sizeof (data));
>> +				   "CORE", note_type, &data, sizeof (data));
>>        }
>>  
>>      case NT_PRSTATUS:
>> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
>> index a188cec..5b81baa 100644
>> --- a/bfd/elf32-i386.c
>> +++ b/bfd/elf32-i386.c
>> @@ -31,12 +31,20 @@
>>  #include "objalloc.h"
>>  #include "hashtab.h"
>>  #include "dwarf2.h"
>> +#include "elf-bfd.h"
>> +#include "elf-psinfo.h"
>> +
>> +#include <stdarg.h>
>>  
>>  /* 386 uses REL relocations instead of RELA.  */
>>  #define USE_REL	1
>>  
>>  #include "elf/i386.h"
>>  
>> +#ifdef CORE_HEADER
>> +#include CORE_HEADER
>> +#endif
>
> I believe new CORE_HEADER should not be introduced, they are rather deprecated
> as they depend on system <procfs.h> which is not compatible for cross-build
> core handling.  (But I may be completely wrong here.)

Yeah, this is a point of confusion for me as well.  I will remove this
part, and resubmit the patch.  Let's wait until someone more experienced
comments.  BTW, in order to be able to remove this, I had to "return
NULL" when handling the "NT_PRSTATUS" case inside the
elf_i386_write_core_note.

Ok, here is the new version of the patch, with some of your comments
addressed.  I didn't make some changes suggested above because of my
disagreement, but we can keep discussing.

Thanks,

-- 
Sergio

---
 bfd/Makefile.in         |    2 +-
 bfd/elf-bfd.h           |    6 ++-
 bfd/elf-psinfo.h        |  155 +++++++++++++++++++++++++++++++++++++++++++++++
 bfd/elf.c               |   17 +++---
 bfd/elf32-arm.c         |   13 +++--
 bfd/elf32-i386.c        |   42 +++++++++++++
 bfd/elf32-ppc.c         |   69 +++++++++++++++++++--
 bfd/elf64-ppc.c         |   14 +++--
 bfd/elf64-x86-64.c      |   36 ++++++------
 bfd/hosts/x86-64linux.h |   37 -----------
 10 files changed, 311 insertions(+), 80 deletions(-)
 create mode 100644 bfd/elf-psinfo.h

diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index 92d9d08..e12deb5 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1050,7 +1050,7 @@ BUILD_CFILES = \
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
-	elf-bfd.h elf-hppa.h elf32-hppa.h \
+	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
 	elf64-hppa.h elfcode.h elfcore.h \
 	freebsd.h genlink.h go32stub.h \
 	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index b8d82b1..d314291 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2234,11 +2234,15 @@ extern bfd_boolean bfd_elf_lookup_section_flags
 extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
   (bfd * abfd, asection * section);
 
+/* Forward declaration of prpsinfo.  See `elf-psinfo.h' for more details.  */
+
+struct elf_internal_prpsinfo;
+
 /* Exported interface for writing elf corefile notes. */
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
 extern char *elfcore_write_prpsinfo
-  (bfd *, char *, int *, const char *, const char *);
+  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
 extern char *elfcore_write_prstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char * elfcore_write_pstatus
diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
new file mode 100644
index 0000000..b2d6092
--- /dev/null
+++ b/bfd/elf-psinfo.h
@@ -0,0 +1,155 @@
+/* Declarations for PRPSINFO structures under ELF on GNU/Linux.
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* Maximum size of the arguments that can be stored in a PRPSINFO
+   structure.  */
+
+#define ELF_PRARGSZ (80)
+
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of the corefile.
+
+   This is an "internal" structure in the sense that it should be used to
+   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
+   so things like endianess shouldn't be an issue.  This structure will
+   eventually be converted in one of the `elf_external_*' structures
+   below.  */
+
+struct elf_internal_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long pr_flag;		/* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[2];
+    char pr_gid[2];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_16 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_16 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   Differently from the 32-bit version, the PowerPC guys made our lives better
+   and used the same size as the other architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo64
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[8];			/* Flags.  */
+    char gap[4];
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo64'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO64_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_64 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* Process info.  In the end we do provide typedefs for them.  */
+
+typedef struct elf_external_prpsinfo32 prpsinfo32_t;
+typedef struct elf_external_prpsinfo64 prpsinfo64_t;
diff --git a/bfd/elf.c b/bfd/elf.c
index a92dd5d..4556386 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -44,6 +44,7 @@ SECTION
 #include "elf-bfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
+#include "elf-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -9062,16 +9063,16 @@ char *
 elfcore_write_prpsinfo (bfd  *abfd,
 			char *buf,
 			int  *bufsiz,
-			const char *fname,
-			const char *psargs)
+			const struct elf_internal_prpsinfo *input)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (bed->elf_backend_write_core_note != NULL)
     {
       char *ret;
+
       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
-						 NT_PRPSINFO, fname, psargs);
+						 NT_PRPSINFO, input);
       if (ret != NULL)
 	return ret;
     }
@@ -9089,8 +9090,8 @@ elfcore_write_prpsinfo (bfd  *abfd,
 #endif
 
       memset (&data, 0, sizeof (data));
-      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
@@ -9101,13 +9102,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
       psinfo_t data;
       int note_type = NT_PSINFO;
 #else
-      prpsinfo_t data;
+      prpsinfo64_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));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index fd7d26a..cacc895 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -30,6 +30,7 @@
 #include "elf-nacl.h"
 #include "elf-vxworks.h"
 #include "elf/arm.h"
+#include "elf-psinfo.h"
 
 /* Return the relocation section associated with NAME.  HTAB is the
    bfd's elf32_arm_link_hash_entry.  */
@@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       {
-	char data[124];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 28, va_arg (ap, const char *), 16);
-	strncpy (data + 44, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
 
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index a188cec..4a14fc9 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -31,6 +31,10 @@
 #include "objalloc.h"
 #include "hashtab.h"
 #include "dwarf2.h"
+#include "elf-bfd.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 /* 386 uses REL relocations instead of RELA.  */
 #define USE_REL	1
@@ -500,6 +504,43 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
   return TRUE;
 }
+
+static char *
+elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+			  int note_type, ...)
+{
+  va_list ap;
+
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+	{
+	  const struct elf_internal_prpsinfo *prpsinfo;
+	  struct elf_external_prpsinfo32 data;
+
+	  va_start (ap, note_type);
+	  prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
+	  va_end (ap);
+
+	  memset (&data, 0, sizeof (data));
+	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
+	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+				     &data, sizeof (data));
+	}
+      /* NOTREACHED */
+
+    case NT_PRSTATUS:
+      /* FIXME: For now, to avoid the inclusion of the "CORE_HEADER", we
+	 return NULL and delegate this to elfcore_write_prstatus.  */
+      return NULL;
+    }
+  /* NOTREACHED */
+}
+
 \f
 /* Functions for the i386 ELF linker.
 
@@ -5140,6 +5181,7 @@ elf_i386_add_symbol_hook (bfd * abfd,
 #define elf_backend_gc_sweep_hook	      elf_i386_gc_sweep_hook
 #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
 #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
+#define elf_backend_write_core_note	      elf_i386_write_core_note
 #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
 #define elf_backend_relocate_section	      elf_i386_relocate_section
 #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 5241926..199affa 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -37,6 +37,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "elf-psinfo.h"
 
 typedef enum split16_format_type
 {
@@ -2212,6 +2213,61 @@ ppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
+/* External 32-bit PPC structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   The reason why we have a different structure only for PPC is because
+   on this architecture (and *only* here!) the size of 32-bit structure
+   changes.  This is due to the different sizes of `pr_uid' and `pr_gid',
+   which on non-PPC architectures are declared as `short int' and on PPC
+   architectures are declared as `int'.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_ppc_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_PPC_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
 static char *
 ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 {
@@ -2222,16 +2278,19 @@ ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 
     case NT_PRPSINFO:
       {
-	char data[128];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_ppc_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 32, va_arg (ap, const char *), 16);
-	strncpy (data + 48, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_PPC_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 10b6f9d..4eda989 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -34,6 +34,7 @@
 #include "elf-bfd.h"
 #include "elf/ppc64.h"
 #include "elf64-ppc.h"
+#include "elf-psinfo.h"
 #include "dwarf2.h"
 
 static bfd_reloc_status_type ppc64_elf_ha_reloc
@@ -2718,16 +2719,19 @@ ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
 
     case NT_PRPSINFO:
       {
-	char data[136];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo64 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 40, va_arg (ap, const char *), 16);
-	strncpy (data + 56, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 283681c..2c9939d 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -32,11 +32,13 @@
 #include "hashtab.h"
 #include "dwarf2.h"
 #include "libiberty.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 #include "elf/x86-64.h"
 
 #ifdef CORE_HEADER
-#include <stdarg.h>
 #include CORE_HEADER
 #endif
 
@@ -415,14 +417,13 @@ elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
-#ifdef CORE_HEADER
 static char *
 elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 			    int note_type, ...)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   va_list ap;
-  const char *fname, *psargs;
+  const struct elf_internal_prpsinfo *prpsinfo;
   long pid;
   int cursig;
   const void *gregs;
@@ -434,27 +435,28 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       va_start (ap, note_type);
-      fname = va_arg (ap, const char *);
-      psargs = va_arg (ap, const char *);
+      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
       va_end (ap);
 
       if (bed->s->elfclass == ELFCLASS32)
 	{
-	  prpsinfo32_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo32 data32;
+
+	  memset (&data32, 0, sizeof (data32));
+	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data32);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data32, sizeof (data32));
 	}
       else
 	{
-	  prpsinfo64_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo64 data64;
+
+	  memset (&data64, 0, sizeof (data64));
+	  PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data64);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data64, sizeof (data64));
 	}
       /* NOTREACHED */
 
@@ -501,7 +503,7 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
     }
   /* NOTREACHED */
 }
-#endif
+
 \f
 /* Functions for the x86-64 ELF linker.	 */
 
@@ -5225,9 +5227,7 @@ static const struct bfd_elf_special_section
 #define elf_backend_gc_sweep_hook	    elf_x86_64_gc_sweep_hook
 #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
 #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
-#ifdef CORE_HEADER
 #define elf_backend_write_core_note	    elf_x86_64_write_core_note
-#endif
 #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
 #define elf_backend_relocate_section	    elf_x86_64_relocate_section
 #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
diff --git a/bfd/hosts/x86-64linux.h b/bfd/hosts/x86-64linux.h
index 78be09a..6070978 100644
--- a/bfd/hosts/x86-64linux.h
+++ b/bfd/hosts/x86-64linux.h
@@ -43,11 +43,6 @@ typedef unsigned long long int uint64_t;
 /* Unsigned 64-bit integer aligned to 8 bytes.  */
 typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
 
-#undef HAVE_PRPSINFO32_T
-#define HAVE_PRPSINFO32_T
-#undef HAVE_PRPSINFO32_T_PR_PID
-#define HAVE_PRPSINFO32_T_PR_PID
-
 #undef HAVE_PRSTATUS32_T
 #define HAVE_PRSTATUS32_T
 
@@ -191,36 +186,6 @@ struct elf_prstatus64
     int pr_fpvalid;			/* True if math copro being used.  */
   };
 
-struct elf_prpsinfo32
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    unsigned int pr_flag;		/* Flags.  */
-    unsigned short int pr_uid;
-    unsigned short int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
-struct elf_prpsinfo64
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    a8_uint64_t pr_flag;		/* Flags.  */
-    unsigned int pr_uid;
-    unsigned int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
 /* The rest of this file provides the types for emulation of the
    Solaris <proc_service.h> interfaces that should be implemented by
    users of libthread_db.  */
@@ -229,5 +194,3 @@ struct elf_prpsinfo64
 typedef struct elf_prstatus32 prstatus32_t;
 typedef struct elf_prstatusx32 prstatusx32_t;
 typedef struct elf_prstatus64 prstatus64_t;
-typedef struct elf_prpsinfo32 prpsinfo32_t;
-typedef struct elf_prpsinfo64 prpsinfo64_t;
-- 
1.7.7.6

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-18 19:19   ` Sergio Durigan Junior
@ 2012-12-18 19:43     ` Jan Kratochvil
  2012-12-30  1:50       ` Sergio Durigan Junior
  0 siblings, 1 reply; 21+ messages in thread
From: Jan Kratochvil @ 2012-12-18 19:43 UTC (permalink / raw)
  To: Sergio Durigan Junior
  Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

On Tue, 18 Dec 2012 20:19:06 +0100, Sergio Durigan Junior wrote:
> On Tuesday, December 18 2012, Jan Kratochvil wrote:
> The patch covers the existing targets that already implemented the
> *_write_core_note function, with the exception of i386 which is a new
> implementation.

OK.


> I disagree.  As I said above, the patch covers all targets that were
> already implementing *_write_core_note.  If some new target decides to
> implement it, it is just a matter of including "elf-psinfo.h" and using
> the right structures.

OK.


> As I said above, I disagree.  The header file is useful for having a
> single place which defines those structures (i.e., i386, x32 and ARM use
> the same elf_external_prpsinfo32 strucutre).

That is a matter of opinion -> bfd maintainers, whether to copy the definition
into each arch file or have some common header file for it despite it is
compatible only with some of the archs.


> Also, the header is useful
> for including in the BFD clients (I'm thiking "GDB" here) which can use
> the elf_internal_prpsinfo strucuture to pass information to BFD.

I forgot about elf_internal_prpsinfo, that one needs to be included in BFD
applications (like GDB).  But elf_internal_prpsinfo should be then in
a different file, maybe bfd.h?  (I do not know much.)  GDB does not need to
know the elf_external_* layouts so those should not be defined in header
file(s) available to GDB.


Thanks,
Jan

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-18 19:43     ` Jan Kratochvil
@ 2012-12-30  1:50       ` Sergio Durigan Junior
  2013-01-01 14:30         ` Jan Kratochvil
  0 siblings, 1 reply; 21+ messages in thread
From: Sergio Durigan Junior @ 2012-12-30  1:50 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

On Tuesday, December 18 2012, Jan Kratochvil wrote:

> On Tue, 18 Dec 2012 20:19:06 +0100, Sergio Durigan Junior wrote:
>> As I said above, I disagree.  The header file is useful for having a
>> single place which defines those structures (i.e., i386, x32 and ARM use
>> the same elf_external_prpsinfo32 strucutre).
>
> That is a matter of opinion -> bfd maintainers, whether to copy the definition
> into each arch file or have some common header file for it despite it is
> compatible only with some of the archs.

I agree it's a matter of opinion, I will wait until one of the
maintainers say something about it.

>> Also, the header is useful
>> for including in the BFD clients (I'm thiking "GDB" here) which can use
>> the elf_internal_prpsinfo strucuture to pass information to BFD.
>
> I forgot about elf_internal_prpsinfo, that one needs to be included in BFD
> applications (like GDB).  But elf_internal_prpsinfo should be then in
> a different file, maybe bfd.h?  (I do not know much.)  GDB does not need to
> know the elf_external_* layouts so those should not be defined in header
> file(s) available to GDB.

Agreed, this new version of the patch reflects the change.  I decided to
move the definition of elf_internal_prpsinfo to elf-bfd.h, it's a better
place IMO.  I will also send an updated version of the GDB patch which
doesn't include elf-psinfo.h.

Thanks,

-- 
Sergio

2012-12-29  Sergio Durigan Junior  <sergiodj@redhat.com>

	* Makefile.in (BUILD_CFILES): Add `elf-psinfo.h'.
	* elf-bfd.h (ELF_PRARGSZ): New conditional definition.
	(elf_internal_prpsinfo): New structure declaration.
	(elfcore_write_prpsinfo): Change prototype, accepting
	`elf_internal_prpsinfo' as argument.
	* elf-psinfo.h: New file.
	* elf.c	(elfcore_write_prpsinfo): Change prototype, accepting
	`elf_internal_prpsinfo' as argument.  Rewrite parts of the code to
	make use of the new argument.
	* elf32-arm.c: Include `elf-psinfo.h'.
	(elf32_arm_nabi_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf32-i386.c: Include `elf-bfd.h', `elf-psinfo.h' and `stdarg.h'.
	(elf_i386_write_core_note): New function.
	* elf32-ppc.c: Include `elf-psinfo.h'.
	(elf_external_ppc_prpsinfo32): New structure declaration.
	(ppc_elf_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf64-ppc.c: Include `elf-psinfo.h'.
	(ppc64_elf_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf64-x86-64.c: Include `elf-psinfo.h'.  Include `stdarg.h'
	unconditionally.
	(elf_x86_64_write_core_note): Remove `#ifdef CORE_HEADER', making the
	function unconditionally available.  Refactor `NT_PRPSINFO' case.
	* hosts/x86-64linux.h (HAVE_PRPSINFO32_T, HAVE_PRPSINFO32_T_PR_PID,
	elf_prpsinfo32, elf_prpsinfo64, prpsinfo32_t, prpsinfo64_t): Remove
	definitions, moving some of them to `elf-psinfo.h'.

---
 bfd/Makefile.in         |    2 +-
 bfd/elf-bfd.h           |   38 +++++++++++++-
 bfd/elf-psinfo.h        |  133 +++++++++++++++++++++++++++++++++++++++++++++++
 bfd/elf.c               |   17 +++---
 bfd/elf32-arm.c         |   13 +++--
 bfd/elf32-i386.c        |   42 +++++++++++++++
 bfd/elf32-ppc.c         |   70 +++++++++++++++++++++++--
 bfd/elf64-ppc.c         |   14 +++--
 bfd/elf64-x86-64.c      |   36 ++++++------
 bfd/hosts/x86-64linux.h |   37 -------------
 10 files changed, 322 insertions(+), 80 deletions(-)
 create mode 100644 bfd/elf-psinfo.h

diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index c51c342..adea836 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1068,7 +1068,7 @@ BUILD_CFILES = \
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
-	elf-bfd.h elf-hppa.h elf32-hppa.h \
+	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
 	elf64-hppa.h elfcode.h elfcore.h \
 	freebsd.h genlink.h go32stub.h \
 	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index b8d82b1..90ced7a 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1722,6 +1722,38 @@ struct elf_obj_tdata
   (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
 #define elf_other_obj_attributes_proc(bfd) \
   (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
+
+#ifndef ELF_PRARGSZ
+/* Maximum size of the arguments that can be stored in a PRPSINFO
+   structure.  */
+
+#define ELF_PRARGSZ (80)
+#endif
+
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of the corefile.
+
+   This is an "internal" structure in the sense that it should be used to
+   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
+   so things like endianess shouldn't be an issue.  This structure will
+   eventually be converted in one of the `elf_external_*' structures
+   below.  */
+
+struct elf_internal_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long pr_flag;		/* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
 \f
 extern void _bfd_elf_swap_verdef_in
   (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
@@ -2234,11 +2266,15 @@ extern bfd_boolean bfd_elf_lookup_section_flags
 extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
   (bfd * abfd, asection * section);
 
+/* Forward declaration of prpsinfo.  See `elf-psinfo.h' for more details.  */
+
+struct elf_internal_prpsinfo;
+
 /* Exported interface for writing elf corefile notes. */
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
 extern char *elfcore_write_prpsinfo
-  (bfd *, char *, int *, const char *, const char *);
+  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
 extern char *elfcore_write_prstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char * elfcore_write_pstatus
diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
new file mode 100644
index 0000000..ddf3aa1
--- /dev/null
+++ b/bfd/elf-psinfo.h
@@ -0,0 +1,133 @@
+/* Declarations for PRPSINFO structures under ELF on GNU/Linux.
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#ifndef ELF_PRARGSZ
+/* Maximum size of the arguments that can be stored in a PRPSINFO
+   structure.  */
+
+#define ELF_PRARGSZ (80)
+#endif
+
+/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[2];
+    char pr_gid[2];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_16 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_16 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   Differently from the 32-bit version, the PowerPC guys made our lives better
+   and used the same size as the other architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo64
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[8];			/* Flags.  */
+    char gap[4];
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo64'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO64_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_64 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* Process info.  In the end we do provide typedefs for them.  */
+
+typedef struct elf_external_prpsinfo32 prpsinfo32_t;
+typedef struct elf_external_prpsinfo64 prpsinfo64_t;
diff --git a/bfd/elf.c b/bfd/elf.c
index 17e9ad4..aad8b27 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -44,6 +44,7 @@ SECTION
 #include "elf-bfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
+#include "elf-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -9063,16 +9064,16 @@ char *
 elfcore_write_prpsinfo (bfd  *abfd,
 			char *buf,
 			int  *bufsiz,
-			const char *fname,
-			const char *psargs)
+			const struct elf_internal_prpsinfo *input)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (bed->elf_backend_write_core_note != NULL)
     {
       char *ret;
+
       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
-						 NT_PRPSINFO, fname, psargs);
+						 NT_PRPSINFO, input);
       if (ret != NULL)
 	return ret;
     }
@@ -9090,8 +9091,8 @@ elfcore_write_prpsinfo (bfd  *abfd,
 #endif
 
       memset (&data, 0, sizeof (data));
-      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
@@ -9102,13 +9103,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
       psinfo_t data;
       int note_type = NT_PSINFO;
 #else
-      prpsinfo_t data;
+      prpsinfo64_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));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index e2f8a96..a354602 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -30,6 +30,7 @@
 #include "elf-nacl.h"
 #include "elf-vxworks.h"
 #include "elf/arm.h"
+#include "elf-psinfo.h"
 
 /* Return the relocation section associated with NAME.  HTAB is the
    bfd's elf32_arm_link_hash_entry.  */
@@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       {
-	char data[124];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 28, va_arg (ap, const char *), 16);
-	strncpy (data + 44, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
 
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index f76c7a7..0198eef 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -31,6 +31,10 @@
 #include "objalloc.h"
 #include "hashtab.h"
 #include "dwarf2.h"
+#include "elf-bfd.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 /* 386 uses REL relocations instead of RELA.  */
 #define USE_REL	1
@@ -500,6 +504,43 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
   return TRUE;
 }
+
+static char *
+elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+			  int note_type, ...)
+{
+  va_list ap;
+
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+	{
+	  const struct elf_internal_prpsinfo *prpsinfo;
+	  struct elf_external_prpsinfo32 data;
+
+	  va_start (ap, note_type);
+	  prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
+	  va_end (ap);
+
+	  memset (&data, 0, sizeof (data));
+	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
+	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+				     &data, sizeof (data));
+	}
+      /* NOTREACHED */
+
+    case NT_PRSTATUS:
+      /* FIXME: For now, to avoid the inclusion of the "CORE_HEADER", we
+	 return NULL and delegate this to elfcore_write_prstatus.  */
+      return NULL;
+    }
+  /* NOTREACHED */
+}
+
 \f
 /* Functions for the i386 ELF linker.
 
@@ -5042,6 +5083,7 @@ elf_i386_add_symbol_hook (bfd * abfd,
 #define elf_backend_gc_sweep_hook	      elf_i386_gc_sweep_hook
 #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
 #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
+#define elf_backend_write_core_note	      elf_i386_write_core_note
 #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
 #define elf_backend_relocate_section	      elf_i386_relocate_section
 #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 5241926..b239e5c 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -37,6 +37,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "elf-psinfo.h"
 
 typedef enum split16_format_type
 {
@@ -1777,6 +1778,62 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
 	 0xffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 };
+
+/* External 32-bit PPC structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   The reason why we have a different structure only for PPC is because
+   on this architecture (and *only* here!) the size of 32-bit structure
+   changes.  This is due to the different sizes of `pr_uid' and `pr_gid',
+   which on non-PPC architectures are declared as `short int' and on PPC
+   architectures are declared as `int'.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_ppc_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_PPC_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
 \f
 /* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
 
@@ -2222,16 +2279,19 @@ ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 
     case NT_PRPSINFO:
       {
-	char data[128];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_ppc_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 32, va_arg (ap, const char *), 16);
-	strncpy (data + 48, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_PPC_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 10b6f9d..4eda989 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -34,6 +34,7 @@
 #include "elf-bfd.h"
 #include "elf/ppc64.h"
 #include "elf64-ppc.h"
+#include "elf-psinfo.h"
 #include "dwarf2.h"
 
 static bfd_reloc_status_type ppc64_elf_ha_reloc
@@ -2718,16 +2719,19 @@ ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
 
     case NT_PRPSINFO:
       {
-	char data[136];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo64 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 40, va_arg (ap, const char *), 16);
-	strncpy (data + 56, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 92bf991..c9bcf48 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -32,11 +32,13 @@
 #include "hashtab.h"
 #include "dwarf2.h"
 #include "libiberty.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 #include "elf/x86-64.h"
 
 #ifdef CORE_HEADER
-#include <stdarg.h>
 #include CORE_HEADER
 #endif
 
@@ -415,14 +417,13 @@ elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
-#ifdef CORE_HEADER
 static char *
 elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 			    int note_type, ...)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   va_list ap;
-  const char *fname, *psargs;
+  const struct elf_internal_prpsinfo *prpsinfo;
   long pid;
   int cursig;
   const void *gregs;
@@ -434,27 +435,28 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       va_start (ap, note_type);
-      fname = va_arg (ap, const char *);
-      psargs = va_arg (ap, const char *);
+      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
       va_end (ap);
 
       if (bed->s->elfclass == ELFCLASS32)
 	{
-	  prpsinfo32_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo32 data32;
+
+	  memset (&data32, 0, sizeof (data32));
+	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data32);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data32, sizeof (data32));
 	}
       else
 	{
-	  prpsinfo64_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo64 data64;
+
+	  memset (&data64, 0, sizeof (data64));
+	  PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data64);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data64, sizeof (data64));
 	}
       /* NOTREACHED */
 
@@ -501,7 +503,7 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
     }
   /* NOTREACHED */
 }
-#endif
+
 \f
 /* Functions for the x86-64 ELF linker.	 */
 
@@ -5157,9 +5159,7 @@ static const struct bfd_elf_special_section
 #define elf_backend_gc_sweep_hook	    elf_x86_64_gc_sweep_hook
 #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
 #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
-#ifdef CORE_HEADER
 #define elf_backend_write_core_note	    elf_x86_64_write_core_note
-#endif
 #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
 #define elf_backend_relocate_section	    elf_x86_64_relocate_section
 #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
diff --git a/bfd/hosts/x86-64linux.h b/bfd/hosts/x86-64linux.h
index 78be09a..6070978 100644
--- a/bfd/hosts/x86-64linux.h
+++ b/bfd/hosts/x86-64linux.h
@@ -43,11 +43,6 @@ typedef unsigned long long int uint64_t;
 /* Unsigned 64-bit integer aligned to 8 bytes.  */
 typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
 
-#undef HAVE_PRPSINFO32_T
-#define HAVE_PRPSINFO32_T
-#undef HAVE_PRPSINFO32_T_PR_PID
-#define HAVE_PRPSINFO32_T_PR_PID
-
 #undef HAVE_PRSTATUS32_T
 #define HAVE_PRSTATUS32_T
 
@@ -191,36 +186,6 @@ struct elf_prstatus64
     int pr_fpvalid;			/* True if math copro being used.  */
   };
 
-struct elf_prpsinfo32
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    unsigned int pr_flag;		/* Flags.  */
-    unsigned short int pr_uid;
-    unsigned short int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
-struct elf_prpsinfo64
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    a8_uint64_t pr_flag;		/* Flags.  */
-    unsigned int pr_uid;
-    unsigned int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
 /* The rest of this file provides the types for emulation of the
    Solaris <proc_service.h> interfaces that should be implemented by
    users of libthread_db.  */
@@ -229,5 +194,3 @@ struct elf_prpsinfo64
 typedef struct elf_prstatus32 prstatus32_t;
 typedef struct elf_prstatusx32 prstatusx32_t;
 typedef struct elf_prstatus64 prstatus64_t;
-typedef struct elf_prpsinfo32 prpsinfo32_t;
-typedef struct elf_prpsinfo64 prpsinfo64_t;
-- 
1.7.7.6

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2012-12-30  1:50       ` Sergio Durigan Junior
@ 2013-01-01 14:30         ` Jan Kratochvil
  2013-01-02 23:32           ` Sergio Durigan Junior
  0 siblings, 1 reply; 21+ messages in thread
From: Jan Kratochvil @ 2013-01-01 14:30 UTC (permalink / raw)
  To: Sergio Durigan Junior
  Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

Hi Sergio,

thanks for the updated, I have just seen some more minor issues:


On Sun, 30 Dec 2012 02:49:36 +0100, Sergio Durigan Junior wrote:
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -1068,7 +1068,7 @@ BUILD_CFILES = \
>  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
>  SOURCE_HFILES = \
>  	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
> -	elf-bfd.h elf-hppa.h elf32-hppa.h \
> +	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
>  	elf64-hppa.h elfcode.h elfcore.h \
>  	freebsd.h genlink.h go32stub.h \
>  	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
> index b8d82b1..90ced7a 100644
> --- a/bfd/elf-bfd.h
> +++ b/bfd/elf-bfd.h
> @@ -1722,6 +1722,38 @@ struct elf_obj_tdata
>    (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
>  #define elf_other_obj_attributes_proc(bfd) \
>    (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
> +
> +#ifndef ELF_PRARGSZ
> +/* Maximum size of the arguments that can be stored in a PRPSINFO
> +   structure.  */
> +
> +#define ELF_PRARGSZ (80)
> +#endif

This should be unrelated to the system definition, BFD now defines everything
about PRPSINFO on its own and different system definiton of it can just break
it.  Host system may be some exotic kind with no core files support by BFD.


> +
> +/* Internal structure which holds information to be included in the
> +   PRPSINFO section of the corefile.
> +
> +   This is an "internal" structure in the sense that it should be used to
> +   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
> +   so things like endianess shouldn't be an issue.  This structure will
> +   eventually be converted in one of the `elf_external_*' structures
> +   below.  */
> +
> +struct elf_internal_prpsinfo
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    unsigned long pr_flag;		/* Flags.  */
> +    unsigned int pr_uid;
> +    unsigned int pr_gid;
> +    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
> +    /* Lots missing */

This comment seems off-topic here.  It fully represents the core file
structure.


> +    char pr_fname[16];			/* Filename of executable.  */
> +    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */

As this is only internal representation the sizes can be +1 including the
terminating '\0' for a more convenient use by the callers.


> +  };
> +
>  \f
>  extern void _bfd_elf_swap_verdef_in
>    (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
> @@ -2234,11 +2266,15 @@ extern bfd_boolean bfd_elf_lookup_section_flags
>  extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
>    (bfd * abfd, asection * section);
>  
> +/* Forward declaration of prpsinfo.  See `elf-psinfo.h' for more details.  */
> +
> +struct elf_internal_prpsinfo;
> +
>  /* Exported interface for writing elf corefile notes. */
>  extern char *elfcore_write_note
>    (bfd *, char *, int *, const char *, int, const void *, int);
>  extern char *elfcore_write_prpsinfo
> -  (bfd *, char *, int *, const char *, const char *);
> +  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
>  extern char *elfcore_write_prstatus
>    (bfd *, char *, int *, long, int, const void *);
>  extern char * elfcore_write_pstatus
> diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
> new file mode 100644
> index 0000000..ddf3aa1
> --- /dev/null
> +++ b/bfd/elf-psinfo.h
> @@ -0,0 +1,133 @@
> +/* Declarations for PRPSINFO structures under ELF on GNU/Linux.

s/Declarations/Definitions/


> +   Copyright 2012 Free Software Foundation, Inc.

2013 now. :-)


> +
> +   This file is part of BFD, the Binary File Descriptor library.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; if not, write to the Free Software
> +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
> +   MA 02110-1301, USA.  */
> +
> +#ifndef ELF_PRARGSZ
> +/* Maximum size of the arguments that can be stored in a PRPSINFO
> +   structure.  */
> +
> +#define ELF_PRARGSZ (80)
> +#endif

The same comment as above.


> +
> +/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
> +   thus we choose to use char arrays here in order to avoid dealing with
> +   different types in different architectures.
> +
> +   This structure will ultimately be written in the corefile's note section,
> +   as the PRPSINFO.  */
> +
> +struct elf_external_prpsinfo32
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    char pr_flag[4];			/* Flags.  */
> +    char pr_uid[2];
> +    char pr_gid[2];
> +    char pr_pid[4];
> +    char pr_ppid[4];
> +    char pr_pgrp[4];
> +    char pr_sid[4];
> +    /* Lots missing */

Also unrelated comment I think.  It is in Linux kernel where this IMO means
that the core file could contain more info.  But it can no longer be changed
so I find the comment irrelevant now.


> +    char pr_fname[16];			/* Filename of executable.  */
> +    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
> +  };
> +
> +/* Helper macro to copy (properly handling endianess) things from the
> +   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo32'
> +   structure.
> +
> +   Note that FROM should be a pointer, and TO should be the explicit type.  */
> +
> +#define PRPSINFO32_COPY_FIELDS(abfd, from, to) \
> +  do \
> +    { \
> +      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
> +      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
> +      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
> +      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
> +      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
> +      H_PUT_16 (abfd, from->pr_uid, to.pr_uid); \
> +      H_PUT_16 (abfd, from->pr_gid, to.pr_gid); \
> +      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
> +      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
> +      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
> +      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
> +      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
> +      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
> +    } while (0)
> +
> +/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
> +   thus we choose to use char arrays here in order to avoid dealing with
> +   different types in different architectures.
> +
> +   Differently from the 32-bit version, the PowerPC guys made our lives better
> +   and used the same size as the other architectures.
> +
> +   This structure will ultimately be written in the corefile's note section,
> +   as the PRPSINFO.  */
> +
> +struct elf_external_prpsinfo64
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    char pr_flag[8];			/* Flags.  */
> +    char gap[4];
> +    char pr_uid[4];
> +    char pr_gid[4];
> +    char pr_pid[4];
> +    char pr_ppid[4];
> +    char pr_pgrp[4];
> +    char pr_sid[4];
> +    /* Lots missing */
> +    char pr_fname[16];			/* Filename of executable.  */
> +    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
> +  };
> +
> +/* Helper macro to copy (properly handling endianess) things from the
> +   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo64'
> +   structure.
> +
> +   Note that FROM should be a pointer, and TO should be the explicit type.  */
> +
> +#define PRPSINFO64_COPY_FIELDS(abfd, from, to) \
> +  do \
> +    { \
> +      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
> +      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
> +      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
> +      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
> +      H_PUT_64 (abfd, from->pr_flag, to.pr_flag); \
> +      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
> +      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
> +      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
> +      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
> +      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
> +      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
> +      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
> +      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
> +    } while (0)
> +
> +/* Process info.  In the end we do provide typedefs for them.  */
> +
> +typedef struct elf_external_prpsinfo32 prpsinfo32_t;
> +typedef struct elf_external_prpsinfo64 prpsinfo64_t;

There was some comment that *_t types are reserved for system (POSIX?) use.
So when BFD now now longer uses the system ones and fully defines them on its
own they should have some different namespace, not *_t.



> diff --git a/bfd/elf.c b/bfd/elf.c
> index 17e9ad4..aad8b27 100644
> --- a/bfd/elf.c
> +++ b/bfd/elf.c
> @@ -44,6 +44,7 @@ SECTION
>  #include "elf-bfd.h"
>  #include "libiberty.h"
>  #include "safe-ctype.h"
> +#include "elf-psinfo.h"
>  
>  #ifdef CORE_HEADER
>  #include CORE_HEADER
> @@ -9063,16 +9064,16 @@ char *
>  elfcore_write_prpsinfo (bfd  *abfd,
>  			char *buf,
>  			int  *bufsiz,
> -			const char *fname,
> -			const char *psargs)
> +			const struct elf_internal_prpsinfo *input)
>  {
>    const struct elf_backend_data *bed = get_elf_backend_data (abfd);
>  
>    if (bed->elf_backend_write_core_note != NULL)
>      {
>        char *ret;
> +
>        ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
> -						 NT_PRPSINFO, fname, psargs);
> +						 NT_PRPSINFO, input);
>        if (ret != NULL)
>  	return ret;
>      }
> @@ -9090,8 +9091,8 @@ elfcore_write_prpsinfo (bfd  *abfd,
>  #endif
>  
>        memset (&data, 0, sizeof (data));
> -      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
> -      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
> +      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
> +      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
>        return elfcore_write_note (abfd, buf, bufsiz,
>  				 "CORE", note_type, &data, sizeof (data));
>      }
> @@ -9102,13 +9103,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
>        psinfo_t data;
>        int note_type = NT_PSINFO;
>  #else
> -      prpsinfo_t data;
> +      prpsinfo64_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));
> +      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
> +      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
>        return elfcore_write_note (abfd, buf, bufsiz,
>  				 "CORE", note_type, &data, sizeof (data));
>      }
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index e2f8a96..a354602 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -30,6 +30,7 @@
>  #include "elf-nacl.h"
>  #include "elf-vxworks.h"
>  #include "elf/arm.h"
> +#include "elf-psinfo.h"
>  
>  /* Return the relocation section associated with NAME.  HTAB is the
>     bfd's elf32_arm_link_hash_entry.  */
> @@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  
>      case NT_PRPSINFO:
>        {
> -	char data[124];
> +	const struct elf_internal_prpsinfo *prpsinfo;
> +	struct elf_external_prpsinfo32 data;
>  	va_list ap;
>  
>  	va_start (ap, note_type);
> -	memset (data, 0, sizeof (data));
> -	strncpy (data + 28, va_arg (ap, const char *), 16);
> -	strncpy (data + 44, va_arg (ap, const char *), 80);
> +	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>  	va_end (ap);
>  
> +	memset (&data, 0, sizeof (data));
> +	PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
> +
>  	return elfcore_write_note (abfd, buf, bufsiz,
> -				   "CORE", note_type, data, sizeof (data));
> +				   "CORE", note_type, &data, sizeof (data));
>        }
>  
>      case NT_PRSTATUS:
> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> index f76c7a7..0198eef 100644
> --- a/bfd/elf32-i386.c
> +++ b/bfd/elf32-i386.c
> @@ -31,6 +31,10 @@
>  #include "objalloc.h"
>  #include "hashtab.h"
>  #include "dwarf2.h"
> +#include "elf-bfd.h"
> +#include "elf-psinfo.h"
> +
> +#include <stdarg.h>
>  
>  /* 386 uses REL relocations instead of RELA.  */
>  #define USE_REL	1
> @@ -500,6 +504,43 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>  
>    return TRUE;
>  }
> +
> +static char *
> +elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
> +			  int note_type, ...)
> +{
> +  va_list ap;
> +
> +  switch (note_type)
> +    {
> +    default:
> +      return NULL;
> +
> +    case NT_PRPSINFO:
> +	{
> +	  const struct elf_internal_prpsinfo *prpsinfo;
> +	  struct elf_external_prpsinfo32 data;
> +
> +	  va_start (ap, note_type);
> +	  prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
> +	  va_end (ap);
> +
> +	  memset (&data, 0, sizeof (data));
> +	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
> +
> +	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
> +				     &data, sizeof (data));
> +	}
> +      /* NOTREACHED */
> +
> +    case NT_PRSTATUS:
> +      /* FIXME: For now, to avoid the inclusion of the "CORE_HEADER", we
> +	 return NULL and delegate this to elfcore_write_prstatus.  */
> +      return NULL;

I do not think this 'case NT_PRSTATUS:' needs to be here at all, it is also in
fact unrelated to this patchset, but that is again just a matter of style,
-> bfd maintainers.


> +    }
> +  /* NOTREACHED */
> +}
> +
>  \f
>  /* Functions for the i386 ELF linker.
>  
> @@ -5042,6 +5083,7 @@ elf_i386_add_symbol_hook (bfd * abfd,
>  #define elf_backend_gc_sweep_hook	      elf_i386_gc_sweep_hook
>  #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
>  #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
> +#define elf_backend_write_core_note	      elf_i386_write_core_note
>  #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
>  #define elf_backend_relocate_section	      elf_i386_relocate_section
>  #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
> diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
> index 5241926..b239e5c 100644
> --- a/bfd/elf32-ppc.c
> +++ b/bfd/elf32-ppc.c
> @@ -37,6 +37,7 @@
>  #include "elf32-ppc.h"
>  #include "elf-vxworks.h"
>  #include "dwarf2.h"
> +#include "elf-psinfo.h"
>  
>  typedef enum split16_format_type
>  {
> @@ -1777,6 +1778,62 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
>  	 0xffff,		/* dst_mask */
>  	 FALSE),		/* pcrel_offset */
>  };
> +
> +/* External 32-bit PPC structure for PRPSINFO.  This structure is ABI-defined,
> +   thus we choose to use char arrays here in order to avoid dealing with
> +   different types in different architectures.
> +
> +   The reason why we have a different structure only for PPC is because
> +   on this architecture (and *only* here!) the size of 32-bit structure
> +   changes.  This is due to the different sizes of `pr_uid' and `pr_gid',
> +   which on non-PPC architectures are declared as `short int' and on PPC
> +   architectures are declared as `int'.
> +
> +   This structure will ultimately be written in the corefile's note section,
> +   as the PRPSINFO.  */
> +
> +struct elf_external_ppc_prpsinfo32
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    char pr_flag[4];			/* Flags.  */
> +    char pr_uid[4];
> +    char pr_gid[4];
> +    char pr_pid[4];
> +    char pr_ppid[4];
> +    char pr_pgrp[4];
> +    char pr_sid[4];
> +    /* Lots missing */

Likewise.


> +    char pr_fname[16];			/* Filename of executable.  */
> +    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
> +  };
> +
> +/* Helper macro to copy (properly handling endianess) things from the
> +   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
> +   structure.
> +
> +   Note that FROM should be a pointer, and TO should be the explicit type.  */
> +
> +#define PRPSINFO32_PPC_COPY_FIELDS(abfd, from, to) \
> +  do \
> +    { \
> +      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
> +      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
> +      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
> +      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
> +      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
> +      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
> +      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
> +      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
> +      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
> +      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
> +      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
> +      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
> +      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
> +    } while (0)
> +
>  \f
>  /* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
>  
> @@ -2222,16 +2279,19 @@ ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
>  
>      case NT_PRPSINFO:
>        {
> -	char data[128];
> +	const struct elf_internal_prpsinfo *prpsinfo;
> +	struct elf_external_ppc_prpsinfo32 data;
>  	va_list ap;
>  
>  	va_start (ap, note_type);
> -	memset (data, 0, sizeof (data));
> -	strncpy (data + 32, va_arg (ap, const char *), 16);
> -	strncpy (data + 48, va_arg (ap, const char *), 80);
> +	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>  	va_end (ap);
> +
> +	memset (&data, 0, sizeof (data));
> +	PRPSINFO32_PPC_COPY_FIELDS (abfd, prpsinfo, data);
> +
>  	return elfcore_write_note (abfd, buf, bufsiz,
> -				   "CORE", note_type, data, sizeof (data));
> +				   "CORE", note_type, &data, sizeof (data));
>        }
>  
>      case NT_PRSTATUS:
> diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
> index 10b6f9d..4eda989 100644
> --- a/bfd/elf64-ppc.c
> +++ b/bfd/elf64-ppc.c
> @@ -34,6 +34,7 @@
>  #include "elf-bfd.h"
>  #include "elf/ppc64.h"
>  #include "elf64-ppc.h"
> +#include "elf-psinfo.h"
>  #include "dwarf2.h"
>  
>  static bfd_reloc_status_type ppc64_elf_ha_reloc
> @@ -2718,16 +2719,19 @@ ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
>  
>      case NT_PRPSINFO:
>        {
> -	char data[136];
> +	const struct elf_internal_prpsinfo *prpsinfo;
> +	struct elf_external_prpsinfo64 data;
>  	va_list ap;
>  
>  	va_start (ap, note_type);
> -	memset (data, 0, sizeof (data));
> -	strncpy (data + 40, va_arg (ap, const char *), 16);
> -	strncpy (data + 56, va_arg (ap, const char *), 80);
> +	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>  	va_end (ap);
> +
> +	memset (&data, 0, sizeof (data));
> +	PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data);
> +
>  	return elfcore_write_note (abfd, buf, bufsiz,
> -				   "CORE", note_type, data, sizeof (data));
> +				   "CORE", note_type, &data, sizeof (data));
>        }
>  
>      case NT_PRSTATUS:
> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> index 92bf991..c9bcf48 100644
> --- a/bfd/elf64-x86-64.c
> +++ b/bfd/elf64-x86-64.c
> @@ -32,11 +32,13 @@
>  #include "hashtab.h"
>  #include "dwarf2.h"
>  #include "libiberty.h"
> +#include "elf-psinfo.h"
> +
> +#include <stdarg.h>
>  
>  #include "elf/x86-64.h"
>  
>  #ifdef CORE_HEADER
> -#include <stdarg.h>
>  #include CORE_HEADER
>  #endif
>  
> @@ -415,14 +417,13 @@ elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>    return TRUE;
>  }
>  
> -#ifdef CORE_HEADER

I think the NT_PRSTATUS part still needs to have #ifdef CORE_HEADER (and using
the NULL return fallback if CORE_HEADER is not available).


>  static char *
>  elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  			    int note_type, ...)
>  {
>    const struct elf_backend_data *bed = get_elf_backend_data (abfd);
>    va_list ap;
> -  const char *fname, *psargs;
> +  const struct elf_internal_prpsinfo *prpsinfo;
>    long pid;
>    int cursig;
>    const void *gregs;
> @@ -434,27 +435,28 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  
>      case NT_PRPSINFO:
>        va_start (ap, note_type);
> -      fname = va_arg (ap, const char *);
> -      psargs = va_arg (ap, const char *);
> +      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>        va_end (ap);
>  
>        if (bed->s->elfclass == ELFCLASS32)
>  	{
> -	  prpsinfo32_t data;
> -	  memset (&data, 0, sizeof (data));
> -	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
> -	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
> +	  struct elf_external_prpsinfo32 data32;
> +
> +	  memset (&data32, 0, sizeof (data32));
> +	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data32);
> +
>  	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
> -				     &data, sizeof (data));
> +				     &data32, sizeof (data32));
>  	}
>        else
>  	{
> -	  prpsinfo64_t data;
> -	  memset (&data, 0, sizeof (data));
> -	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
> -	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
> +	  struct elf_external_prpsinfo64 data64;
> +
> +	  memset (&data64, 0, sizeof (data64));
> +	  PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data64);
> +
>  	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
> -				     &data, sizeof (data));
> +				     &data64, sizeof (data64));
>  	}
>        /* NOTREACHED */
>  
> @@ -501,7 +503,7 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>      }
>    /* NOTREACHED */
>  }
> -#endif
> +
>  \f
>  /* Functions for the x86-64 ELF linker.	 */
>  
> @@ -5157,9 +5159,7 @@ static const struct bfd_elf_special_section
>  #define elf_backend_gc_sweep_hook	    elf_x86_64_gc_sweep_hook
>  #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
>  #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
> -#ifdef CORE_HEADER
>  #define elf_backend_write_core_note	    elf_x86_64_write_core_note
> -#endif
>  #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
>  #define elf_backend_relocate_section	    elf_x86_64_relocate_section
>  #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
> diff --git a/bfd/hosts/x86-64linux.h b/bfd/hosts/x86-64linux.h
> index 78be09a..6070978 100644
> --- a/bfd/hosts/x86-64linux.h
> +++ b/bfd/hosts/x86-64linux.h
> @@ -43,11 +43,6 @@ typedef unsigned long long int uint64_t;
>  /* Unsigned 64-bit integer aligned to 8 bytes.  */
>  typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
>  
> -#undef HAVE_PRPSINFO32_T
> -#define HAVE_PRPSINFO32_T
> -#undef HAVE_PRPSINFO32_T_PR_PID
> -#define HAVE_PRPSINFO32_T_PR_PID
> -
>  #undef HAVE_PRSTATUS32_T
>  #define HAVE_PRSTATUS32_T
>  
> @@ -191,36 +186,6 @@ struct elf_prstatus64
>      int pr_fpvalid;			/* True if math copro being used.  */
>    };
>  
> -struct elf_prpsinfo32
> -  {
> -    char pr_state;			/* Numeric process state.  */
> -    char pr_sname;			/* Char for pr_state.  */
> -    char pr_zomb;			/* Zombie.  */
> -    char pr_nice;			/* Nice val.  */
> -    unsigned int pr_flag;		/* Flags.  */
> -    unsigned short int pr_uid;
> -    unsigned short int pr_gid;
> -    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
> -    /* Lots missing */
> -    char pr_fname[16];			/* Filename of executable.  */
> -    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
> -  };
> -
> -struct elf_prpsinfo64
> -  {
> -    char pr_state;			/* Numeric process state.  */
> -    char pr_sname;			/* Char for pr_state.  */
> -    char pr_zomb;			/* Zombie.  */
> -    char pr_nice;			/* Nice val.  */
> -    a8_uint64_t pr_flag;		/* Flags.  */
> -    unsigned int pr_uid;
> -    unsigned int pr_gid;
> -    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
> -    /* Lots missing */
> -    char pr_fname[16];			/* Filename of executable.  */
> -    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
> -  };
> -
>  /* The rest of this file provides the types for emulation of the
>     Solaris <proc_service.h> interfaces that should be implemented by
>     users of libthread_db.  */
> @@ -229,5 +194,3 @@ struct elf_prpsinfo64
>  typedef struct elf_prstatus32 prstatus32_t;
>  typedef struct elf_prstatusx32 prstatusx32_t;
>  typedef struct elf_prstatus64 prstatus64_t;
> -typedef struct elf_prpsinfo32 prpsinfo32_t;
> -typedef struct elf_prpsinfo64 prpsinfo64_t;
> -- 
> 1.7.7.6


Thanks,
Jan

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2013-01-01 14:30         ` Jan Kratochvil
@ 2013-01-02 23:32           ` Sergio Durigan Junior
  2013-01-03 13:44             ` Jan Kratochvil
  0 siblings, 1 reply; 21+ messages in thread
From: Sergio Durigan Junior @ 2013-01-02 23:32 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

On Tuesday, January 01 2013, Jan Kratochvil wrote:

> thanks for the updated, I have just seen some more minor issues:

Thanks for the comments.  I have some questions.

> On Sun, 30 Dec 2012 02:49:36 +0100, Sergio Durigan Junior wrote:
>> --- a/bfd/Makefile.in
>> +++ b/bfd/Makefile.in
>> @@ -1068,7 +1068,7 @@ BUILD_CFILES = \
>>  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
>>  SOURCE_HFILES = \
>>  	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
>> -	elf-bfd.h elf-hppa.h elf32-hppa.h \
>> +	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
>>  	elf64-hppa.h elfcode.h elfcore.h \
>>  	freebsd.h genlink.h go32stub.h \
>>  	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
>> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
>> index b8d82b1..90ced7a 100644
>> --- a/bfd/elf-bfd.h
>> +++ b/bfd/elf-bfd.h
>> @@ -1722,6 +1722,38 @@ struct elf_obj_tdata
>>    (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
>>  #define elf_other_obj_attributes_proc(bfd) \
>>    (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
>> +
>> +#ifndef ELF_PRARGSZ
>> +/* Maximum size of the arguments that can be stored in a PRPSINFO
>> +   structure.  */
>> +
>> +#define ELF_PRARGSZ (80)
>> +#endif
>
> This should be unrelated to the system definition, BFD now defines everything
> about PRPSINFO on its own and different system definiton of it can just break
> it.  Host system may be some exotic kind with no core files support by
> BFD.

Ok, I understand your argument, but it is not clear what you are
suggesting.  This definition should be present here and in the
elf-psinfo.h file.

>> +/* Internal structure which holds information to be included in the
>> +   PRPSINFO section of the corefile.
>> +
>> +   This is an "internal" structure in the sense that it should be used to
>> +   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
>> +   so things like endianess shouldn't be an issue.  This structure will
>> +   eventually be converted in one of the `elf_external_*' structures
>> +   below.  */
>> +
>> +struct elf_internal_prpsinfo
>> +  {
>> +    char pr_state;			/* Numeric process state.  */
>> +    char pr_sname;			/* Char for pr_state.  */
>> +    char pr_zomb;			/* Zombie.  */
>> +    char pr_nice;			/* Nice val.  */
>> +    unsigned long pr_flag;		/* Flags.  */
>> +    unsigned int pr_uid;
>> +    unsigned int pr_gid;
>> +    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
>> +    /* Lots missing */
>
> This comment seems off-topic here.  It fully represents the core file
> structure.

I can remove the comment, but it doesn't say that the structure does not
represent a corefile struct.  It just explains the reason why it is
called "internal".

>> +
>> +   This file is part of BFD, the Binary File Descriptor library.
>> +
>> +   This program is free software; you can redistribute it and/or modify
>> +   it under the terms of the GNU General Public License as published by
>> +   the Free Software Foundation; either version 3 of the License, or
>> +   (at your option) any later version.
>> +
>> +   This program is distributed in the hope that it will be useful,
>> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
>> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> +   GNU General Public License for more details.
>> +
>> +   You should have received a copy of the GNU General Public License
>> +   along with this program; if not, write to the Free Software
>> +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
>> +   MA 02110-1301, USA.  */
>> +
>> +#ifndef ELF_PRARGSZ
>> +/* Maximum size of the arguments that can be stored in a PRPSINFO
>> +   structure.  */
>> +
>> +#define ELF_PRARGSZ (80)
>> +#endif
>
> The same comment as above.

The same question as above.

>> +/* Process info.  In the end we do provide typedefs for them.  */
>> +
>> +typedef struct elf_external_prpsinfo32 prpsinfo32_t;
>> +typedef struct elf_external_prpsinfo64 prpsinfo64_t;
>
> There was some comment that *_t types are reserved for system (POSIX?) use.
> So when BFD now now longer uses the system ones and fully defines them on its
> own they should have some different namespace, not *_t.

Ok, but renaming these types will require renaming the files that use
them as well.

Thanks,

-- 
Sergio

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2013-01-02 23:32           ` Sergio Durigan Junior
@ 2013-01-03 13:44             ` Jan Kratochvil
  2013-01-03 15:46               ` Sergio Durigan Junior
  0 siblings, 1 reply; 21+ messages in thread
From: Jan Kratochvil @ 2013-01-03 13:44 UTC (permalink / raw)
  To: Sergio Durigan Junior
  Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

On Thu, 03 Jan 2013 00:32:12 +0100, Sergio Durigan Junior wrote:
> On Tuesday, January 01 2013, Jan Kratochvil wrote:
> > On Sun, 30 Dec 2012 02:49:36 +0100, Sergio Durigan Junior wrote:
> >> --- a/bfd/elf-bfd.h
> >> +++ b/bfd/elf-bfd.h
> >> @@ -1722,6 +1722,38 @@ struct elf_obj_tdata
> >>    (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
> >>  #define elf_other_obj_attributes_proc(bfd) \
> >>    (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
> >> +
> >> +#ifndef ELF_PRARGSZ
> >> +/* Maximum size of the arguments that can be stored in a PRPSINFO
> >> +   structure.  */
> >> +
> >> +#define ELF_PRARGSZ (80)
> >> +#endif
> >
> > This should be unrelated to the system definition, BFD now defines everything
> > about PRPSINFO on its own and different system definiton of it can just break
> > it.  Host system may be some exotic kind with no core files support by
> > BFD.
> 
> Ok, I understand your argument, but it is not clear what you are
> suggesting.  This definition should be present here and in the
> elf-psinfo.h file.

Suggesting for example instead of

+    char pr_psargs[ELF_PRARGSZ];       /* Initial part of arg list.  */

to just use

+    char pr_psargs[80];                /* Initial part of arg list.  */

although as I also suggested:
  On Tue, 01 Jan 2013 15:30:27 +0100, Jan Kratochvil wrote:
  > As this is only internal representation the sizes can be +1 including the
  > terminating '\0' for a more convenient use by the callers.

it could be (no longer requiring those strncpy around):

+    char pr_psargs[81];                /* Initial part of arg list.  */


If you prefer it could be (note the different bfd-only #define name):

+#define BFD_ELF_PRARGSZ (80)
+    char pr_psargs[BFD_ELF_PRARGSZ + 1]; /* Initial part of arg list.  */

but I do not see a reason for such #define.


The goal is not to clash with the existing system symbol ELF_PRARGSZ as that's
symbol meaning is different (irrelevant for the internal BFD representation).


> >> +/* Internal structure which holds information to be included in the
> >> +   PRPSINFO section of the corefile.
> >> +
> >> +   This is an "internal" structure in the sense that it should be used to
> >> +   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
> >> +   so things like endianess shouldn't be an issue.  This structure will
> >> +   eventually be converted in one of the `elf_external_*' structures
> >> +   below.  */
> >> +
> >> +struct elf_internal_prpsinfo
> >> +  {
> >> +    char pr_state;			/* Numeric process state.  */
> >> +    char pr_sname;			/* Char for pr_state.  */
> >> +    char pr_zomb;			/* Zombie.  */
> >> +    char pr_nice;			/* Nice val.  */
> >> +    unsigned long pr_flag;		/* Flags.  */
> >> +    unsigned int pr_uid;
> >> +    unsigned int pr_gid;
> >> +    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
> >> +    /* Lots missing */
> >
> > This comment seems off-topic here.  It fully represents the core file
> > structure.
> 
> I can remove the comment, but it doesn't say that the structure does not
> represent a corefile struct.  It just explains the reason why it is
> called "internal".

As /usr/include/linux/elfcore.h (=from Linux kernel) contains:

struct elf_prpsinfo
{
[...]
        pid_t   pr_pid, pr_ppid, pr_pgrp, pr_sid;
        /* Lots missing */
        char    pr_fname[16];   /* filename of executable */
[...]
};

we should look at it from the point of Linux kernel.  It probably made sense
as Linux kernel could store some more info there.

But currently neither Linux kernel nor BFD can change the binary format
anymore so (1) I do not want to discuss whether it should be removed from
Linux kernel or not, that is offtopic, (2) in BFD it seems irrelevant to me,
BFD only needs to mimic the Linux kernel binary structure, there is nothing
missing in BFD as BFD decodes very every field Linux kernel stores there.


> >> +/* Process info.  In the end we do provide typedefs for them.  */
> >> +
> >> +typedef struct elf_external_prpsinfo32 prpsinfo32_t;
> >> +typedef struct elf_external_prpsinfo64 prpsinfo64_t;
> >
> > There was some comment that *_t types are reserved for system (POSIX?) use.
> > So when BFD now now longer uses the system ones and fully defines them on its
> > own they should have some different namespace, not *_t.
> 
> Ok, but renaming these types will require renaming the files that use
> them as well.

Yes.


Thanks,
Jan

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2013-01-03 13:44             ` Jan Kratochvil
@ 2013-01-03 15:46               ` Sergio Durigan Junior
  2013-01-04  4:40                 ` Sergio Durigan Junior
  0 siblings, 1 reply; 21+ messages in thread
From: Sergio Durigan Junior @ 2013-01-03 15:46 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

On Thursday, January 03 2013, Jan Kratochvil wrote:

> On Thu, 03 Jan 2013 00:32:12 +0100, Sergio Durigan Junior wrote:
>> On Tuesday, January 01 2013, Jan Kratochvil wrote:
>> > On Sun, 30 Dec 2012 02:49:36 +0100, Sergio Durigan Junior wrote:
>> >> +/* Internal structure which holds information to be included in the
>> >> +   PRPSINFO section of the corefile.
>> >> +
>> >> +   This is an "internal" structure in the sense that it should be used to
>> >> +   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
>> >> +   so things like endianess shouldn't be an issue.  This structure will
>> >> +   eventually be converted in one of the `elf_external_*' structures
>> >> +   below.  */
>> >> +
>> >> +struct elf_internal_prpsinfo
>> >> +  {
>> >> +    char pr_state;			/* Numeric process state.  */
>> >> +    char pr_sname;			/* Char for pr_state.  */
>> >> +    char pr_zomb;			/* Zombie.  */
>> >> +    char pr_nice;			/* Nice val.  */
>> >> +    unsigned long pr_flag;		/* Flags.  */
>> >> +    unsigned int pr_uid;
>> >> +    unsigned int pr_gid;
>> >> +    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
>> >> +    /* Lots missing */
>> >
>> > This comment seems off-topic here.  It fully represents the core file
>> > structure.
>> 
>> I can remove the comment, but it doesn't say that the structure does not
>> represent a corefile struct.  It just explains the reason why it is
>> called "internal".
>
> As /usr/include/linux/elfcore.h (=from Linux kernel) contains:
>
> struct elf_prpsinfo
> {
> [...]
>         pid_t   pr_pid, pr_ppid, pr_pgrp, pr_sid;
>         /* Lots missing */
>         char    pr_fname[16];   /* filename of executable */
> [...]
> };
>
> we should look at it from the point of Linux kernel.  It probably made sense
> as Linux kernel could store some more info there.

Ops, sorry, I thought you were talking about the comment above the
structure, and not about the "Lots missing".  Then I agree, it can be
removed.  Sorry about the confusion.  I will send an updated patch in a
few moments.

-- 
Sergio

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2013-01-03 15:46               ` Sergio Durigan Junior
@ 2013-01-04  4:40                 ` Sergio Durigan Junior
  2013-01-09 20:49                   ` Sergio Durigan Junior
  2013-01-10 18:26                   ` Pedro Alves
  0 siblings, 2 replies; 21+ messages in thread
From: Sergio Durigan Junior @ 2013-01-04  4:40 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

On Thursday, January 03 2013, I wrote:

> Ops, sorry, I thought you were talking about the comment above the
> structure, and not about the "Lots missing".  Then I agree, it can be
> removed.  Sorry about the confusion.  I will send an updated patch in a
> few moments.

Here it is.  Thanks for the comments.

-- 
Sergio

2013-01-04  Sergio Durigan Junior  <sergiodj@redhat.com>

	* Makefile.in (BUILD_CFILES): Add `elf-psinfo.h'.
	* elf-bfd.h (ELF_PRARGSZ): New conditional definition.
	(elf_internal_prpsinfo): New structure declaration.
	(elfcore_write_prpsinfo): Change prototype, accepting
	`elf_internal_prpsinfo' as argument.
	* elf-psinfo.h: New file.
	* elf.c	(elfcore_write_prpsinfo): Change prototype, accepting
	`elf_internal_prpsinfo' as argument.  Rewrite parts of the code to
	make use of the new argument.
	* elf32-arm.c: Include `elf-psinfo.h'.
	(elf32_arm_nabi_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf32-i386.c: Include `elf-bfd.h', `elf-psinfo.h' and `stdarg.h'.
	(elf_i386_write_core_note): New function.
	* elf32-ppc.c: Include `elf-psinfo.h'.
	(elf_external_ppc_prpsinfo32): New structure declaration.
	(ppc_elf_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf64-ppc.c: Include `elf-psinfo.h'.
	(ppc64_elf_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf64-x86-64.c: Include `elf-psinfo.h'.  Include `stdarg.h'
	unconditionally.
	(elf_x86_64_write_core_note): Remove `#ifdef CORE_HEADER', making the
	function unconditionally available.  Refactor `NT_PRPSINFO' case.
	Refactor `NT_PRSTATUS' case, making it conditional to `CORE_HEADER'.
	* hosts/x86-64linux.h (HAVE_PRPSINFO32_T, HAVE_PRPSINFO32_T_PR_PID,
	elf_prpsinfo32, elf_prpsinfo64, prpsinfo32_t, prpsinfo64_t): Remove
	definitions, moving some of them to `elf-psinfo.h'.

---
 bfd/Makefile.in         |    2 +-
 bfd/elf-bfd.h           |   26 +++++++++-
 bfd/elf-psinfo.h        |  124 +++++++++++++++++++++++++++++++++++++++++++++++
 bfd/elf.c               |   21 ++++----
 bfd/elf32-arm.c         |   13 +++--
 bfd/elf32-i386.c        |   37 ++++++++++++++
 bfd/elf32-ppc.c         |   70 ++++++++++++++++++++++++--
 bfd/elf64-ppc.c         |   14 +++--
 bfd/elf64-x86-64.c      |   40 ++++++++-------
 bfd/hosts/x86-64linux.h |   37 --------------
 10 files changed, 302 insertions(+), 82 deletions(-)
 create mode 100644 bfd/elf-psinfo.h

diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index c51c342..adea836 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1068,7 +1068,7 @@ BUILD_CFILES = \
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
-	elf-bfd.h elf-hppa.h elf32-hppa.h \
+	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
 	elf64-hppa.h elfcode.h elfcore.h \
 	freebsd.h genlink.h go32stub.h \
 	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index b8d82b1..1572cba 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1722,6 +1722,30 @@ struct elf_obj_tdata
   (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
 #define elf_other_obj_attributes_proc(bfd) \
   (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
+
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of the corefile.
+
+   This is an "internal" structure in the sense that it should be used to
+   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
+   so things like endianess shouldn't be an issue.  This structure will
+   eventually be converted in one of the `elf_external_*' structures
+   below.  */
+
+struct elf_internal_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long pr_flag;		/* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    char pr_fname[16 + 1];		/* Filename of executable.  */
+    char pr_psargs[80 + 1];		/* Initial part of arg list.  */
+  };
+
 \f
 extern void _bfd_elf_swap_verdef_in
   (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
@@ -2238,7 +2262,7 @@ extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
 extern char *elfcore_write_prpsinfo
-  (bfd *, char *, int *, const char *, const char *);
+  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
 extern char *elfcore_write_prstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char * elfcore_write_pstatus
diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
new file mode 100644
index 0000000..6689a58
--- /dev/null
+++ b/bfd/elf-psinfo.h
@@ -0,0 +1,124 @@
+/* Definitions for PRPSINFO structures under ELF on GNU/Linux.
+   Copyright 2013 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[2];
+    char pr_gid[2];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_16 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_16 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   Differently from the 32-bit version, the PowerPC guys made our lives better
+   and used the same size as the other architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo64
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[8];			/* Flags.  */
+    char gap[4];
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo64'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO64_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_64 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* Process info.  In the end we do provide typedefs for them.  */
+
+typedef struct elf_external_prpsinfo32 prpsinfo32;
+typedef struct elf_external_prpsinfo64 prpsinfo64;
diff --git a/bfd/elf.c b/bfd/elf.c
index 17e9ad4..c4f04ea 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -44,6 +44,7 @@ SECTION
 #include "elf-bfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
+#include "elf-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -8165,7 +8166,7 @@ elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
 #if defined (HAVE_PRPSINFO_T)
 typedef prpsinfo_t   elfcore_psinfo_t;
 #if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
-typedef prpsinfo32_t elfcore_psinfo32_t;
+typedef prpsinfo32 elfcore_psinfo32_t;
 #endif
 #endif
 
@@ -9063,16 +9064,16 @@ char *
 elfcore_write_prpsinfo (bfd  *abfd,
 			char *buf,
 			int  *bufsiz,
-			const char *fname,
-			const char *psargs)
+			const struct elf_internal_prpsinfo *input)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (bed->elf_backend_write_core_note != NULL)
     {
       char *ret;
+
       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
-						 NT_PRPSINFO, fname, psargs);
+						 NT_PRPSINFO, input);
       if (ret != NULL)
 	return ret;
     }
@@ -9085,13 +9086,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
       psinfo32_t data;
       int note_type = NT_PSINFO;
 #else
-      prpsinfo32_t data;
+      prpsinfo32 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));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
@@ -9102,13 +9103,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
       psinfo_t data;
       int note_type = NT_PSINFO;
 #else
-      prpsinfo_t data;
+      prpsinfo64 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));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index e2f8a96..a354602 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -30,6 +30,7 @@
 #include "elf-nacl.h"
 #include "elf-vxworks.h"
 #include "elf/arm.h"
+#include "elf-psinfo.h"
 
 /* Return the relocation section associated with NAME.  HTAB is the
    bfd's elf32_arm_link_hash_entry.  */
@@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       {
-	char data[124];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 28, va_arg (ap, const char *), 16);
-	strncpy (data + 44, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
 
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index f76c7a7..45a1e26 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -31,6 +31,10 @@
 #include "objalloc.h"
 #include "hashtab.h"
 #include "dwarf2.h"
+#include "elf-bfd.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 /* 386 uses REL relocations instead of RELA.  */
 #define USE_REL	1
@@ -500,6 +504,38 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
   return TRUE;
 }
+
+static char *
+elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+			  int note_type, ...)
+{
+  va_list ap;
+
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+	{
+	  const struct elf_internal_prpsinfo *prpsinfo;
+	  struct elf_external_prpsinfo32 data;
+
+	  va_start (ap, note_type);
+	  prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
+	  va_end (ap);
+
+	  memset (&data, 0, sizeof (data));
+	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
+
+	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+				     &data, sizeof (data));
+	}
+      /* NOTREACHED */
+    }
+  /* NOTREACHED */
+}
+
 \f
 /* Functions for the i386 ELF linker.
 
@@ -5042,6 +5078,7 @@ elf_i386_add_symbol_hook (bfd * abfd,
 #define elf_backend_gc_sweep_hook	      elf_i386_gc_sweep_hook
 #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
 #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
+#define elf_backend_write_core_note	      elf_i386_write_core_note
 #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
 #define elf_backend_relocate_section	      elf_i386_relocate_section
 #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 5241926..02d494f 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -37,6 +37,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "elf-psinfo.h"
 
 typedef enum split16_format_type
 {
@@ -1777,6 +1778,62 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
 	 0xffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 };
+
+/* External 32-bit PPC structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   The reason why we have a different structure only for PPC is because
+   on this architecture (and *only* here!) the size of 32-bit structure
+   changes.  This is due to the different sizes of `pr_uid' and `pr_gid',
+   which on non-PPC architectures are declared as `short int' and on PPC
+   architectures are declared as `int'.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_ppc_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to copy (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_PPC_COPY_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
 \f
 /* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
 
@@ -2222,16 +2279,19 @@ ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 
     case NT_PRPSINFO:
       {
-	char data[128];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_ppc_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 32, va_arg (ap, const char *), 16);
-	strncpy (data + 48, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_PPC_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 10b6f9d..4eda989 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -34,6 +34,7 @@
 #include "elf-bfd.h"
 #include "elf/ppc64.h"
 #include "elf64-ppc.h"
+#include "elf-psinfo.h"
 #include "dwarf2.h"
 
 static bfd_reloc_status_type ppc64_elf_ha_reloc
@@ -2718,16 +2719,19 @@ ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
 
     case NT_PRPSINFO:
       {
-	char data[136];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo64 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 40, va_arg (ap, const char *), 16);
-	strncpy (data + 56, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 92bf991..40ce80f 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -32,11 +32,13 @@
 #include "hashtab.h"
 #include "dwarf2.h"
 #include "libiberty.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 #include "elf/x86-64.h"
 
 #ifdef CORE_HEADER
-#include <stdarg.h>
 #include CORE_HEADER
 #endif
 
@@ -415,14 +417,13 @@ elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
-#ifdef CORE_HEADER
 static char *
 elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 			    int note_type, ...)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   va_list ap;
-  const char *fname, *psargs;
+  const struct elf_internal_prpsinfo *prpsinfo;
   long pid;
   int cursig;
   const void *gregs;
@@ -434,31 +435,33 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       va_start (ap, note_type);
-      fname = va_arg (ap, const char *);
-      psargs = va_arg (ap, const char *);
+      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
       va_end (ap);
 
       if (bed->s->elfclass == ELFCLASS32)
 	{
-	  prpsinfo32_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo32 data32;
+
+	  memset (&data32, 0, sizeof (data32));
+	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data32);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data32, sizeof (data32));
 	}
       else
 	{
-	  prpsinfo64_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo64 data64;
+
+	  memset (&data64, 0, sizeof (data64));
+	  PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data64);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data64, sizeof (data64));
 	}
       /* NOTREACHED */
 
     case NT_PRSTATUS:
+#ifdef CORE_HEADER
       va_start (ap, note_type);
       pid = va_arg (ap, long);
       cursig = va_arg (ap, int);
@@ -498,10 +501,13 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
 				     &prstat, sizeof (prstat));
 	}
+#else
+      return NULL;
+#endif /* CORE_HEADER */
     }
   /* NOTREACHED */
 }
-#endif
+
 \f
 /* Functions for the x86-64 ELF linker.	 */
 
@@ -5157,9 +5163,7 @@ static const struct bfd_elf_special_section
 #define elf_backend_gc_sweep_hook	    elf_x86_64_gc_sweep_hook
 #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
 #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
-#ifdef CORE_HEADER
 #define elf_backend_write_core_note	    elf_x86_64_write_core_note
-#endif
 #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
 #define elf_backend_relocate_section	    elf_x86_64_relocate_section
 #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
diff --git a/bfd/hosts/x86-64linux.h b/bfd/hosts/x86-64linux.h
index 78be09a..6070978 100644
--- a/bfd/hosts/x86-64linux.h
+++ b/bfd/hosts/x86-64linux.h
@@ -43,11 +43,6 @@ typedef unsigned long long int uint64_t;
 /* Unsigned 64-bit integer aligned to 8 bytes.  */
 typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
 
-#undef HAVE_PRPSINFO32_T
-#define HAVE_PRPSINFO32_T
-#undef HAVE_PRPSINFO32_T_PR_PID
-#define HAVE_PRPSINFO32_T_PR_PID
-
 #undef HAVE_PRSTATUS32_T
 #define HAVE_PRSTATUS32_T
 
@@ -191,36 +186,6 @@ struct elf_prstatus64
     int pr_fpvalid;			/* True if math copro being used.  */
   };
 
-struct elf_prpsinfo32
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    unsigned int pr_flag;		/* Flags.  */
-    unsigned short int pr_uid;
-    unsigned short int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
-struct elf_prpsinfo64
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    a8_uint64_t pr_flag;		/* Flags.  */
-    unsigned int pr_uid;
-    unsigned int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
 /* The rest of this file provides the types for emulation of the
    Solaris <proc_service.h> interfaces that should be implemented by
    users of libthread_db.  */
@@ -229,5 +194,3 @@ struct elf_prpsinfo64
 typedef struct elf_prstatus32 prstatus32_t;
 typedef struct elf_prstatusx32 prstatusx32_t;
 typedef struct elf_prstatus64 prstatus64_t;
-typedef struct elf_prpsinfo32 prpsinfo32_t;
-typedef struct elf_prpsinfo64 prpsinfo64_t;
-- 
1.7.7.6

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2013-01-04  4:40                 ` Sergio Durigan Junior
@ 2013-01-09 20:49                   ` Sergio Durigan Junior
  2013-01-10 18:26                   ` Pedro Alves
  1 sibling, 0 replies; 21+ messages in thread
From: Sergio Durigan Junior @ 2013-01-09 20:49 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Binutils Development, GDB Patches, Pedro Alves, H.J. Lu

On Friday, January 04 2013, I wrote:

> On Thursday, January 03 2013, I wrote:
>
>> Ops, sorry, I thought you were talking about the comment above the
>> structure, and not about the "Lots missing".  Then I agree, it can be
>> removed.  Sorry about the confusion.  I will send an updated patch in a
>> few moments.
>
> Here it is.  Thanks for the comments.

Ping.

I can send an updated version if needed.

Thanks,

> 2013-01-04  Sergio Durigan Junior  <sergiodj@redhat.com>
>
> 	* Makefile.in (BUILD_CFILES): Add `elf-psinfo.h'.
> 	* elf-bfd.h (ELF_PRARGSZ): New conditional definition.
> 	(elf_internal_prpsinfo): New structure declaration.
> 	(elfcore_write_prpsinfo): Change prototype, accepting
> 	`elf_internal_prpsinfo' as argument.
> 	* elf-psinfo.h: New file.
> 	* elf.c	(elfcore_write_prpsinfo): Change prototype, accepting
> 	`elf_internal_prpsinfo' as argument.  Rewrite parts of the code to
> 	make use of the new argument.
> 	* elf32-arm.c: Include `elf-psinfo.h'.
> 	(elf32_arm_nabi_write_core_note): Refactor `NT_PRPSINFO' case.
> 	* elf32-i386.c: Include `elf-bfd.h', `elf-psinfo.h' and `stdarg.h'.
> 	(elf_i386_write_core_note): New function.
> 	* elf32-ppc.c: Include `elf-psinfo.h'.
> 	(elf_external_ppc_prpsinfo32): New structure declaration.
> 	(ppc_elf_write_core_note): Refactor `NT_PRPSINFO' case.
> 	* elf64-ppc.c: Include `elf-psinfo.h'.
> 	(ppc64_elf_write_core_note): Refactor `NT_PRPSINFO' case.
> 	* elf64-x86-64.c: Include `elf-psinfo.h'.  Include `stdarg.h'
> 	unconditionally.
> 	(elf_x86_64_write_core_note): Remove `#ifdef CORE_HEADER', making the
> 	function unconditionally available.  Refactor `NT_PRPSINFO' case.
> 	Refactor `NT_PRSTATUS' case, making it conditional to `CORE_HEADER'.
> 	* hosts/x86-64linux.h (HAVE_PRPSINFO32_T, HAVE_PRPSINFO32_T_PR_PID,
> 	elf_prpsinfo32, elf_prpsinfo64, prpsinfo32_t, prpsinfo64_t): Remove
> 	definitions, moving some of them to `elf-psinfo.h'.
>
> ---
>  bfd/Makefile.in         |    2 +-
>  bfd/elf-bfd.h           |   26 +++++++++-
>  bfd/elf-psinfo.h        |  124 +++++++++++++++++++++++++++++++++++++++++++++++
>  bfd/elf.c               |   21 ++++----
>  bfd/elf32-arm.c         |   13 +++--
>  bfd/elf32-i386.c        |   37 ++++++++++++++
>  bfd/elf32-ppc.c         |   70 ++++++++++++++++++++++++--
>  bfd/elf64-ppc.c         |   14 +++--
>  bfd/elf64-x86-64.c      |   40 ++++++++-------
>  bfd/hosts/x86-64linux.h |   37 --------------
>  10 files changed, 302 insertions(+), 82 deletions(-)
>  create mode 100644 bfd/elf-psinfo.h
>
> diff --git a/bfd/Makefile.in b/bfd/Makefile.in
> index c51c342..adea836 100644
> --- a/bfd/Makefile.in
> +++ b/bfd/Makefile.in
> @@ -1068,7 +1068,7 @@ BUILD_CFILES = \
>  CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
>  SOURCE_HFILES = \
>  	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
> -	elf-bfd.h elf-hppa.h elf32-hppa.h \
> +	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
>  	elf64-hppa.h elfcode.h elfcore.h \
>  	freebsd.h genlink.h go32stub.h \
>  	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
> diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
> index b8d82b1..1572cba 100644
> --- a/bfd/elf-bfd.h
> +++ b/bfd/elf-bfd.h
> @@ -1722,6 +1722,30 @@ struct elf_obj_tdata
>    (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
>  #define elf_other_obj_attributes_proc(bfd) \
>    (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
> +
> +/* Internal structure which holds information to be included in the
> +   PRPSINFO section of the corefile.
> +
> +   This is an "internal" structure in the sense that it should be used to
> +   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
> +   so things like endianess shouldn't be an issue.  This structure will
> +   eventually be converted in one of the `elf_external_*' structures
> +   below.  */
> +
> +struct elf_internal_prpsinfo
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    unsigned long pr_flag;		/* Flags.  */
> +    unsigned int pr_uid;
> +    unsigned int pr_gid;
> +    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
> +    char pr_fname[16 + 1];		/* Filename of executable.  */
> +    char pr_psargs[80 + 1];		/* Initial part of arg list.  */
> +  };
> +
>  \f
>  extern void _bfd_elf_swap_verdef_in
>    (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
> @@ -2238,7 +2262,7 @@ extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
>  extern char *elfcore_write_note
>    (bfd *, char *, int *, const char *, int, const void *, int);
>  extern char *elfcore_write_prpsinfo
> -  (bfd *, char *, int *, const char *, const char *);
> +  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
>  extern char *elfcore_write_prstatus
>    (bfd *, char *, int *, long, int, const void *);
>  extern char * elfcore_write_pstatus
> diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
> new file mode 100644
> index 0000000..6689a58
> --- /dev/null
> +++ b/bfd/elf-psinfo.h
> @@ -0,0 +1,124 @@
> +/* Definitions for PRPSINFO structures under ELF on GNU/Linux.
> +   Copyright 2013 Free Software Foundation, Inc.
> +
> +   This file is part of BFD, the Binary File Descriptor library.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; if not, write to the Free Software
> +   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
> +   MA 02110-1301, USA.  */
> +
> +/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
> +   thus we choose to use char arrays here in order to avoid dealing with
> +   different types in different architectures.
> +
> +   This structure will ultimately be written in the corefile's note section,
> +   as the PRPSINFO.  */
> +
> +struct elf_external_prpsinfo32
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    char pr_flag[4];			/* Flags.  */
> +    char pr_uid[2];
> +    char pr_gid[2];
> +    char pr_pid[4];
> +    char pr_ppid[4];
> +    char pr_pgrp[4];
> +    char pr_sid[4];
> +    char pr_fname[16];			/* Filename of executable.  */
> +    char pr_psargs[80];			/* Initial part of arg list.  */
> +  };
> +
> +/* Helper macro to copy (properly handling endianess) things from the
> +   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo32'
> +   structure.
> +
> +   Note that FROM should be a pointer, and TO should be the explicit type.  */
> +
> +#define PRPSINFO32_COPY_FIELDS(abfd, from, to) \
> +  do \
> +    { \
> +      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
> +      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
> +      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
> +      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
> +      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
> +      H_PUT_16 (abfd, from->pr_uid, to.pr_uid); \
> +      H_PUT_16 (abfd, from->pr_gid, to.pr_gid); \
> +      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
> +      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
> +      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
> +      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
> +      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
> +      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
> +    } while (0)
> +
> +/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
> +   thus we choose to use char arrays here in order to avoid dealing with
> +   different types in different architectures.
> +
> +   Differently from the 32-bit version, the PowerPC guys made our lives better
> +   and used the same size as the other architectures.
> +
> +   This structure will ultimately be written in the corefile's note section,
> +   as the PRPSINFO.  */
> +
> +struct elf_external_prpsinfo64
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    char pr_flag[8];			/* Flags.  */
> +    char gap[4];
> +    char pr_uid[4];
> +    char pr_gid[4];
> +    char pr_pid[4];
> +    char pr_ppid[4];
> +    char pr_pgrp[4];
> +    char pr_sid[4];
> +    char pr_fname[16];			/* Filename of executable.  */
> +    char pr_psargs[80];			/* Initial part of arg list.  */
> +  };
> +
> +/* Helper macro to copy (properly handling endianess) things from the
> +   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo64'
> +   structure.
> +
> +   Note that FROM should be a pointer, and TO should be the explicit type.  */
> +
> +#define PRPSINFO64_COPY_FIELDS(abfd, from, to) \
> +  do \
> +    { \
> +      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
> +      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
> +      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
> +      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
> +      H_PUT_64 (abfd, from->pr_flag, to.pr_flag); \
> +      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
> +      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
> +      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
> +      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
> +      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
> +      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
> +      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
> +      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
> +    } while (0)
> +
> +/* Process info.  In the end we do provide typedefs for them.  */
> +
> +typedef struct elf_external_prpsinfo32 prpsinfo32;
> +typedef struct elf_external_prpsinfo64 prpsinfo64;
> diff --git a/bfd/elf.c b/bfd/elf.c
> index 17e9ad4..c4f04ea 100644
> --- a/bfd/elf.c
> +++ b/bfd/elf.c
> @@ -44,6 +44,7 @@ SECTION
>  #include "elf-bfd.h"
>  #include "libiberty.h"
>  #include "safe-ctype.h"
> +#include "elf-psinfo.h"
>  
>  #ifdef CORE_HEADER
>  #include CORE_HEADER
> @@ -8165,7 +8166,7 @@ elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
>  #if defined (HAVE_PRPSINFO_T)
>  typedef prpsinfo_t   elfcore_psinfo_t;
>  #if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
> -typedef prpsinfo32_t elfcore_psinfo32_t;
> +typedef prpsinfo32 elfcore_psinfo32_t;
>  #endif
>  #endif
>  
> @@ -9063,16 +9064,16 @@ char *
>  elfcore_write_prpsinfo (bfd  *abfd,
>  			char *buf,
>  			int  *bufsiz,
> -			const char *fname,
> -			const char *psargs)
> +			const struct elf_internal_prpsinfo *input)
>  {
>    const struct elf_backend_data *bed = get_elf_backend_data (abfd);
>  
>    if (bed->elf_backend_write_core_note != NULL)
>      {
>        char *ret;
> +
>        ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
> -						 NT_PRPSINFO, fname, psargs);
> +						 NT_PRPSINFO, input);
>        if (ret != NULL)
>  	return ret;
>      }
> @@ -9085,13 +9086,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
>        psinfo32_t data;
>        int note_type = NT_PSINFO;
>  #else
> -      prpsinfo32_t data;
> +      prpsinfo32 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));
> +      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
> +      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
>        return elfcore_write_note (abfd, buf, bufsiz,
>  				 "CORE", note_type, &data, sizeof (data));
>      }
> @@ -9102,13 +9103,13 @@ elfcore_write_prpsinfo (bfd  *abfd,
>        psinfo_t data;
>        int note_type = NT_PSINFO;
>  #else
> -      prpsinfo_t data;
> +      prpsinfo64 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));
> +      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
> +      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
>        return elfcore_write_note (abfd, buf, bufsiz,
>  				 "CORE", note_type, &data, sizeof (data));
>      }
> diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
> index e2f8a96..a354602 100644
> --- a/bfd/elf32-arm.c
> +++ b/bfd/elf32-arm.c
> @@ -30,6 +30,7 @@
>  #include "elf-nacl.h"
>  #include "elf-vxworks.h"
>  #include "elf/arm.h"
> +#include "elf-psinfo.h"
>  
>  /* Return the relocation section associated with NAME.  HTAB is the
>     bfd's elf32_arm_link_hash_entry.  */
> @@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  
>      case NT_PRPSINFO:
>        {
> -	char data[124];
> +	const struct elf_internal_prpsinfo *prpsinfo;
> +	struct elf_external_prpsinfo32 data;
>  	va_list ap;
>  
>  	va_start (ap, note_type);
> -	memset (data, 0, sizeof (data));
> -	strncpy (data + 28, va_arg (ap, const char *), 16);
> -	strncpy (data + 44, va_arg (ap, const char *), 80);
> +	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>  	va_end (ap);
>  
> +	memset (&data, 0, sizeof (data));
> +	PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
> +
>  	return elfcore_write_note (abfd, buf, bufsiz,
> -				   "CORE", note_type, data, sizeof (data));
> +				   "CORE", note_type, &data, sizeof (data));
>        }
>  
>      case NT_PRSTATUS:
> diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
> index f76c7a7..45a1e26 100644
> --- a/bfd/elf32-i386.c
> +++ b/bfd/elf32-i386.c
> @@ -31,6 +31,10 @@
>  #include "objalloc.h"
>  #include "hashtab.h"
>  #include "dwarf2.h"
> +#include "elf-bfd.h"
> +#include "elf-psinfo.h"
> +
> +#include <stdarg.h>
>  
>  /* 386 uses REL relocations instead of RELA.  */
>  #define USE_REL	1
> @@ -500,6 +504,38 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>  
>    return TRUE;
>  }
> +
> +static char *
> +elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
> +			  int note_type, ...)
> +{
> +  va_list ap;
> +
> +  switch (note_type)
> +    {
> +    default:
> +      return NULL;
> +
> +    case NT_PRPSINFO:
> +	{
> +	  const struct elf_internal_prpsinfo *prpsinfo;
> +	  struct elf_external_prpsinfo32 data;
> +
> +	  va_start (ap, note_type);
> +	  prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
> +	  va_end (ap);
> +
> +	  memset (&data, 0, sizeof (data));
> +	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data);
> +
> +	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
> +				     &data, sizeof (data));
> +	}
> +      /* NOTREACHED */
> +    }
> +  /* NOTREACHED */
> +}
> +
>  \f
>  /* Functions for the i386 ELF linker.
>  
> @@ -5042,6 +5078,7 @@ elf_i386_add_symbol_hook (bfd * abfd,
>  #define elf_backend_gc_sweep_hook	      elf_i386_gc_sweep_hook
>  #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
>  #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
> +#define elf_backend_write_core_note	      elf_i386_write_core_note
>  #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
>  #define elf_backend_relocate_section	      elf_i386_relocate_section
>  #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
> diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
> index 5241926..02d494f 100644
> --- a/bfd/elf32-ppc.c
> +++ b/bfd/elf32-ppc.c
> @@ -37,6 +37,7 @@
>  #include "elf32-ppc.h"
>  #include "elf-vxworks.h"
>  #include "dwarf2.h"
> +#include "elf-psinfo.h"
>  
>  typedef enum split16_format_type
>  {
> @@ -1777,6 +1778,62 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
>  	 0xffff,		/* dst_mask */
>  	 FALSE),		/* pcrel_offset */
>  };
> +
> +/* External 32-bit PPC structure for PRPSINFO.  This structure is ABI-defined,
> +   thus we choose to use char arrays here in order to avoid dealing with
> +   different types in different architectures.
> +
> +   The reason why we have a different structure only for PPC is because
> +   on this architecture (and *only* here!) the size of 32-bit structure
> +   changes.  This is due to the different sizes of `pr_uid' and `pr_gid',
> +   which on non-PPC architectures are declared as `short int' and on PPC
> +   architectures are declared as `int'.
> +
> +   This structure will ultimately be written in the corefile's note section,
> +   as the PRPSINFO.  */
> +
> +struct elf_external_ppc_prpsinfo32
> +  {
> +    char pr_state;			/* Numeric process state.  */
> +    char pr_sname;			/* Char for pr_state.  */
> +    char pr_zomb;			/* Zombie.  */
> +    char pr_nice;			/* Nice val.  */
> +    char pr_flag[4];			/* Flags.  */
> +    char pr_uid[4];
> +    char pr_gid[4];
> +    char pr_pid[4];
> +    char pr_ppid[4];
> +    char pr_pgrp[4];
> +    char pr_sid[4];
> +    /* Lots missing */
> +    char pr_fname[16];			/* Filename of executable.  */
> +    char pr_psargs[80];			/* Initial part of arg list.  */
> +  };
> +
> +/* Helper macro to copy (properly handling endianess) things from the
> +   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
> +   structure.
> +
> +   Note that FROM should be a pointer, and TO should be the explicit type.  */
> +
> +#define PRPSINFO32_PPC_COPY_FIELDS(abfd, from, to) \
> +  do \
> +    { \
> +      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
> +      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
> +      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
> +      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
> +      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
> +      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
> +      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
> +      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
> +      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
> +      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
> +      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
> +      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
> +      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
> +    } while (0)
> +
>  \f
>  /* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
>  
> @@ -2222,16 +2279,19 @@ ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
>  
>      case NT_PRPSINFO:
>        {
> -	char data[128];
> +	const struct elf_internal_prpsinfo *prpsinfo;
> +	struct elf_external_ppc_prpsinfo32 data;
>  	va_list ap;
>  
>  	va_start (ap, note_type);
> -	memset (data, 0, sizeof (data));
> -	strncpy (data + 32, va_arg (ap, const char *), 16);
> -	strncpy (data + 48, va_arg (ap, const char *), 80);
> +	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>  	va_end (ap);
> +
> +	memset (&data, 0, sizeof (data));
> +	PRPSINFO32_PPC_COPY_FIELDS (abfd, prpsinfo, data);
> +
>  	return elfcore_write_note (abfd, buf, bufsiz,
> -				   "CORE", note_type, data, sizeof (data));
> +				   "CORE", note_type, &data, sizeof (data));
>        }
>  
>      case NT_PRSTATUS:
> diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
> index 10b6f9d..4eda989 100644
> --- a/bfd/elf64-ppc.c
> +++ b/bfd/elf64-ppc.c
> @@ -34,6 +34,7 @@
>  #include "elf-bfd.h"
>  #include "elf/ppc64.h"
>  #include "elf64-ppc.h"
> +#include "elf-psinfo.h"
>  #include "dwarf2.h"
>  
>  static bfd_reloc_status_type ppc64_elf_ha_reloc
> @@ -2718,16 +2719,19 @@ ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
>  
>      case NT_PRPSINFO:
>        {
> -	char data[136];
> +	const struct elf_internal_prpsinfo *prpsinfo;
> +	struct elf_external_prpsinfo64 data;
>  	va_list ap;
>  
>  	va_start (ap, note_type);
> -	memset (data, 0, sizeof (data));
> -	strncpy (data + 40, va_arg (ap, const char *), 16);
> -	strncpy (data + 56, va_arg (ap, const char *), 80);
> +	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>  	va_end (ap);
> +
> +	memset (&data, 0, sizeof (data));
> +	PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data);
> +
>  	return elfcore_write_note (abfd, buf, bufsiz,
> -				   "CORE", note_type, data, sizeof (data));
> +				   "CORE", note_type, &data, sizeof (data));
>        }
>  
>      case NT_PRSTATUS:
> diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
> index 92bf991..40ce80f 100644
> --- a/bfd/elf64-x86-64.c
> +++ b/bfd/elf64-x86-64.c
> @@ -32,11 +32,13 @@
>  #include "hashtab.h"
>  #include "dwarf2.h"
>  #include "libiberty.h"
> +#include "elf-psinfo.h"
> +
> +#include <stdarg.h>
>  
>  #include "elf/x86-64.h"
>  
>  #ifdef CORE_HEADER
> -#include <stdarg.h>
>  #include CORE_HEADER
>  #endif
>  
> @@ -415,14 +417,13 @@ elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>    return TRUE;
>  }
>  
> -#ifdef CORE_HEADER
>  static char *
>  elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  			    int note_type, ...)
>  {
>    const struct elf_backend_data *bed = get_elf_backend_data (abfd);
>    va_list ap;
> -  const char *fname, *psargs;
> +  const struct elf_internal_prpsinfo *prpsinfo;
>    long pid;
>    int cursig;
>    const void *gregs;
> @@ -434,31 +435,33 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  
>      case NT_PRPSINFO:
>        va_start (ap, note_type);
> -      fname = va_arg (ap, const char *);
> -      psargs = va_arg (ap, const char *);
> +      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
>        va_end (ap);
>  
>        if (bed->s->elfclass == ELFCLASS32)
>  	{
> -	  prpsinfo32_t data;
> -	  memset (&data, 0, sizeof (data));
> -	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
> -	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
> +	  struct elf_external_prpsinfo32 data32;
> +
> +	  memset (&data32, 0, sizeof (data32));
> +	  PRPSINFO32_COPY_FIELDS (abfd, prpsinfo, data32);
> +
>  	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
> -				     &data, sizeof (data));
> +				     &data32, sizeof (data32));
>  	}
>        else
>  	{
> -	  prpsinfo64_t data;
> -	  memset (&data, 0, sizeof (data));
> -	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
> -	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
> +	  struct elf_external_prpsinfo64 data64;
> +
> +	  memset (&data64, 0, sizeof (data64));
> +	  PRPSINFO64_COPY_FIELDS (abfd, prpsinfo, data64);
> +
>  	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
> -				     &data, sizeof (data));
> +				     &data64, sizeof (data64));
>  	}
>        /* NOTREACHED */
>  
>      case NT_PRSTATUS:
> +#ifdef CORE_HEADER
>        va_start (ap, note_type);
>        pid = va_arg (ap, long);
>        cursig = va_arg (ap, int);
> @@ -498,10 +501,13 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
>  				     &prstat, sizeof (prstat));
>  	}
> +#else
> +      return NULL;
> +#endif /* CORE_HEADER */
>      }
>    /* NOTREACHED */
>  }
> -#endif
> +
>  \f
>  /* Functions for the x86-64 ELF linker.	 */
>  
> @@ -5157,9 +5163,7 @@ static const struct bfd_elf_special_section
>  #define elf_backend_gc_sweep_hook	    elf_x86_64_gc_sweep_hook
>  #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
>  #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
> -#ifdef CORE_HEADER
>  #define elf_backend_write_core_note	    elf_x86_64_write_core_note
> -#endif
>  #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
>  #define elf_backend_relocate_section	    elf_x86_64_relocate_section
>  #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
> diff --git a/bfd/hosts/x86-64linux.h b/bfd/hosts/x86-64linux.h
> index 78be09a..6070978 100644
> --- a/bfd/hosts/x86-64linux.h
> +++ b/bfd/hosts/x86-64linux.h
> @@ -43,11 +43,6 @@ typedef unsigned long long int uint64_t;
>  /* Unsigned 64-bit integer aligned to 8 bytes.  */
>  typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
>  
> -#undef HAVE_PRPSINFO32_T
> -#define HAVE_PRPSINFO32_T
> -#undef HAVE_PRPSINFO32_T_PR_PID
> -#define HAVE_PRPSINFO32_T_PR_PID
> -
>  #undef HAVE_PRSTATUS32_T
>  #define HAVE_PRSTATUS32_T
>  
> @@ -191,36 +186,6 @@ struct elf_prstatus64
>      int pr_fpvalid;			/* True if math copro being used.  */
>    };
>  
> -struct elf_prpsinfo32
> -  {
> -    char pr_state;			/* Numeric process state.  */
> -    char pr_sname;			/* Char for pr_state.  */
> -    char pr_zomb;			/* Zombie.  */
> -    char pr_nice;			/* Nice val.  */
> -    unsigned int pr_flag;		/* Flags.  */
> -    unsigned short int pr_uid;
> -    unsigned short int pr_gid;
> -    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
> -    /* Lots missing */
> -    char pr_fname[16];			/* Filename of executable.  */
> -    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
> -  };
> -
> -struct elf_prpsinfo64
> -  {
> -    char pr_state;			/* Numeric process state.  */
> -    char pr_sname;			/* Char for pr_state.  */
> -    char pr_zomb;			/* Zombie.  */
> -    char pr_nice;			/* Nice val.  */
> -    a8_uint64_t pr_flag;		/* Flags.  */
> -    unsigned int pr_uid;
> -    unsigned int pr_gid;
> -    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
> -    /* Lots missing */
> -    char pr_fname[16];			/* Filename of executable.  */
> -    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
> -  };
> -
>  /* The rest of this file provides the types for emulation of the
>     Solaris <proc_service.h> interfaces that should be implemented by
>     users of libthread_db.  */
> @@ -229,5 +194,3 @@ struct elf_prpsinfo64
>  typedef struct elf_prstatus32 prstatus32_t;
>  typedef struct elf_prstatusx32 prstatusx32_t;
>  typedef struct elf_prstatus64 prstatus64_t;
> -typedef struct elf_prpsinfo32 prpsinfo32_t;
> -typedef struct elf_prpsinfo64 prpsinfo64_t;
> -- 
> 1.7.7.6

-- 
Sergio

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2013-01-04  4:40                 ` Sergio Durigan Junior
  2013-01-09 20:49                   ` Sergio Durigan Junior
@ 2013-01-10 18:26                   ` Pedro Alves
  2013-01-10 19:47                     ` Sergio Durigan Junior
  1 sibling, 1 reply; 21+ messages in thread
From: Pedro Alves @ 2013-01-10 18:26 UTC (permalink / raw)
  To: Sergio Durigan Junior
  Cc: Jan Kratochvil, Binutils Development, GDB Patches, H.J. Lu

On 01/04/2013 04:39 AM, Sergio Durigan Junior wrote:> +++ b/bfd/elf-psinfo.h
> @@ -0,0 +1,124 @@
> +/* Definitions for PRPSINFO structures under ELF on GNU/Linux.

What about other OSs, like e.g., Solaris?

> +/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
> +   thus we choose to use char arrays here in order to avoid dealing with
> +   different types in different architectures.
> +
> +   Differently from the 32-bit version, the PowerPC guys made our lives better
> +   and used the same size as the other architectures.

In the current revision, this comment appears out of the blue.
Better would be to instead add a comment further up, above the
32-bit version stating that these are used by most architectures,
although some define their own versions (like e.g., PPC).

> +
> +   This structure will ultimately be written in the corefile's note section,
> +   as the PRPSINFO.  */
> +
> +struct elf_external_prpsinfo64

> +#define PRPSINFO32_COPY_FIELDS(abfd, from, to) \
> +  do \

Personally, I'd prefer calling these SWAP instead
of COPY, as you're not really doing straight
copying, and "swap" is what bfd calls this idiom
about everywhere.

...

> +/* Process info.  In the end we do provide typedefs for them.  */
> +
> +typedef struct elf_external_prpsinfo32 prpsinfo32;
> +typedef struct elf_external_prpsinfo64 prpsinfo64;

What's the point of these typedefs?  To me, they just
obscure things, and are easily confused with the host
types...

> @@ -8165,7 +8166,7 @@ elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
>  #if defined (HAVE_PRPSINFO_T)
>  typedef prpsinfo_t   elfcore_psinfo_t;
>  #if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
> -typedef prpsinfo32_t elfcore_psinfo32_t;
> +typedef prpsinfo32 elfcore_psinfo32_t;

... like here.  HAVE_PRPSINFO32_T/prpsinfo32_t were
about a host type.  prpsinfo32 is always defined (it's a
bfd type).  This in fact looks suspiciously wrong, and a
potential breakage if in fact Sparc32 has a different
psinfo32_t (what OS was that?), or in the other spots,
some other arcane port/OS/arch having a different psinfo32_t
than the Linux one.  Either the #ifdef can be removed and
this made unconditional, and host independent (the best),
or the type should remain the host type (until all ports
convert to implement elf_backend_write_core_note&co
host-independent hooks).

>  #endif
>  #endif
>

> +   The reason why we have a different structure only for PPC is because
> +   on this architecture (and *only* here!) the size of 32-bit structure

This "only here" bit of the comment should go away, because
it'll generate confusion whenever some other arch needs
its own structure, making this outdated, because nobody
will remember to update it.


> @@ -415,14 +417,13 @@ elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
>    return TRUE;
>  }
>  
> -#ifdef CORE_HEADER
>  static char *
>  elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  			    int note_type, ...)
>  {
...
>      case NT_PRSTATUS:
> +#ifdef CORE_HEADER
>        va_start (ap, note_type);
>        pid = va_arg (ap, long);
>        cursig = va_arg (ap, int);
> @@ -498,10 +501,13 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>  	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
>  				     &prstat, sizeof (prstat));
>  	}
> +#else
> +      return NULL;
> +#endif /* CORE_HEADER */
>      }
>    /* NOTREACHED */
>  }
> -#endif
> +

Do you plan on following up with similar treatment for prstatus?

Thanks for doing this,
-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2013-01-10 18:26                   ` Pedro Alves
@ 2013-01-10 19:47                     ` Sergio Durigan Junior
  2013-01-11 15:45                       ` Pedro Alves
  0 siblings, 1 reply; 21+ messages in thread
From: Sergio Durigan Junior @ 2013-01-10 19:47 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Jan Kratochvil, Binutils Development, GDB Patches, H.J. Lu

Thanks for the review.

On Thursday, January 10 2013, Pedro Alves wrote:

> On 01/04/2013 04:39 AM, Sergio Durigan Junior wrote:> +++ b/bfd/elf-psinfo.h
>> @@ -0,0 +1,124 @@
>> +/* Definitions for PRPSINFO structures under ELF on GNU/Linux.
>
> What about other OSs, like e.g., Solaris?

Since I took the definitions from the Linux kernel, I thought it'd be
better to explicitly mention that.  I'm afraid I don't know how Solaris
handle corefiles, do you think this comment should be expanded?

>> +/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
>> +   thus we choose to use char arrays here in order to avoid dealing with
>> +   different types in different architectures.
>> +
>> +   Differently from the 32-bit version, the PowerPC guys made our lives better
>> +   and used the same size as the other architectures.
>
> In the current revision, this comment appears out of the blue.
> Better would be to instead add a comment further up, above the
> 32-bit version stating that these are used by most architectures,
> although some define their own versions (like e.g., PPC).

You're right, the PowerPC note doesn't belong here, I will remove it, thanks.

>> +/* Process info.  In the end we do provide typedefs for them.  */
>> +
>> +typedef struct elf_external_prpsinfo32 prpsinfo32;
>> +typedef struct elf_external_prpsinfo64 prpsinfo64;
>
> What's the point of these typedefs?  To me, they just
> obscure things, and are easily confused with the host
> types...
>
>> @@ -8165,7 +8166,7 @@ elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
>>  #if defined (HAVE_PRPSINFO_T)
>>  typedef prpsinfo_t   elfcore_psinfo_t;
>>  #if defined (HAVE_PRPSINFO32_T)		/* Sparc64 cross Sparc32 */
>> -typedef prpsinfo32_t elfcore_psinfo32_t;
>> +typedef prpsinfo32 elfcore_psinfo32_t;
>
> ... like here.  HAVE_PRPSINFO32_T/prpsinfo32_t were
> about a host type.  prpsinfo32 is always defined (it's a
> bfd type).  This in fact looks suspiciously wrong, and a
> potential breakage if in fact Sparc32 has a different
> psinfo32_t (what OS was that?), or in the other spots,
> some other arcane port/OS/arch having a different psinfo32_t
> than the Linux one.  Either the #ifdef can be removed and
> this made unconditional, and host independent (the best),
> or the type should remain the host type (until all ports
> convert to implement elf_backend_write_core_note&co
> host-independent hooks).

Thanks for the explanation.  I confess this is an area which I don't
feel very confident, so I decided not to mess with anything and just
leave things as they were.

I will remove the typedef's from elf-psinfo.h.

>>  #endif
>>  #endif
>>
>
>> +   The reason why we have a different structure only for PPC is because
>> +   on this architecture (and *only* here!) the size of 32-bit structure
>
> This "only here" bit of the comment should go away, because
> it'll generate confusion whenever some other arch needs
> its own structure, making this outdated, because nobody
> will remember to update it.

Ops, sorry about it, I will remove.

>>      case NT_PRSTATUS:
>> +#ifdef CORE_HEADER
>>        va_start (ap, note_type);
>>        pid = va_arg (ap, long);
>>        cursig = va_arg (ap, int);
>> @@ -498,10 +501,13 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
>>  	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
>>  				     &prstat, sizeof (prstat));
>>  	}
>> +#else
>> +      return NULL;
>> +#endif /* CORE_HEADER */
>>      }
>>    /* NOTREACHED */
>>  }
>> -#endif
>> +
>
> Do you plan on following up with similar treatment for prstatus?

Yeah, I was actually talking about it yesterday on #gdb.  Since
PRPSTATUS is quite similar, I believe it could be easily done as well.
But first I am focusing on getting the PRPSINFO part upstream.

Here is the updated version of the patch.  Thanks.

-- 
Sergio

2013-01-10  Sergio Durigan Junior  <sergiodj@redhat.com>

	* Makefile.in (BUILD_CFILES): Add `elf-psinfo.h'.
	* elf-bfd.h (ELF_PRARGSZ): New conditional definition.
	(elf_internal_prpsinfo): New structure declaration.
	(elfcore_write_prpsinfo): Change prototype, accepting
	`elf_internal_prpsinfo' as argument.
	* elf-psinfo.h: New file.
	* elf.c	(elfcore_write_prpsinfo): Change prototype, accepting
	`elf_internal_prpsinfo' as argument.  Rewrite parts of the code to
	make use of the new argument.
	* elf32-arm.c: Include `elf-psinfo.h'.
	(elf32_arm_nabi_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf32-i386.c: Include `elf-bfd.h', `elf-psinfo.h' and `stdarg.h'.
	(elf_i386_write_core_note): New function.
	* elf32-ppc.c: Include `elf-psinfo.h'.
	(elf_external_ppc_prpsinfo32): New structure declaration.
	(ppc_elf_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf64-ppc.c: Include `elf-psinfo.h'.
	(ppc64_elf_write_core_note): Refactor `NT_PRPSINFO' case.
	* elf64-x86-64.c: Include `elf-psinfo.h'.  Include `stdarg.h'
	unconditionally.
	(elf_x86_64_write_core_note): Remove `#ifdef CORE_HEADER', making the
	function unconditionally available.  Refactor `NT_PRPSINFO' case.
	Refactor `NT_PRSTATUS' case, making it conditional to `CORE_HEADER'.
	* hosts/x86-64linux.h (HAVE_PRPSINFO32_T, HAVE_PRPSINFO32_T_PR_PID,
	elf_prpsinfo32, elf_prpsinfo64, prpsinfo32_t, prpsinfo64_t): Remove
	definitions.

---
 bfd/Makefile.in         |    2 +-
 bfd/elf-bfd.h           |   26 ++++++++++-
 bfd/elf-psinfo.h        |  119 +++++++++++++++++++++++++++++++++++++++++++++++
 bfd/elf.c               |   15 +++---
 bfd/elf32-arm.c         |   13 +++--
 bfd/elf32-i386.c        |   37 +++++++++++++++
 bfd/elf32-ppc.c         |   70 +++++++++++++++++++++++++--
 bfd/elf64-ppc.c         |   14 ++++--
 bfd/elf64-x86-64.c      |   40 +++++++++-------
 bfd/hosts/x86-64linux.h |   37 ---------------
 10 files changed, 294 insertions(+), 79 deletions(-)
 create mode 100644 bfd/elf-psinfo.h

diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index af4e5ed..f6c8857 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -1072,7 +1072,7 @@ BUILD_CFILES = \
 CFILES = $(SOURCE_CFILES) $(BUILD_CFILES)
 SOURCE_HFILES = \
 	aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
-	elf-bfd.h elf-hppa.h elf32-hppa.h \
+	elf-bfd.h elf-psinfo.h elf-hppa.h elf32-hppa.h \
 	elf64-hppa.h elfcode.h elfcore.h \
 	freebsd.h genlink.h go32stub.h \
 	libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 43a077c..c035c0f 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1723,6 +1723,30 @@ struct elf_obj_tdata
   (elf_known_obj_attributes (bfd) [OBJ_ATTR_PROC])
 #define elf_other_obj_attributes_proc(bfd) \
   (elf_other_obj_attributes (bfd) [OBJ_ATTR_PROC])
+
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of the corefile.
+
+   This is an "internal" structure in the sense that it should be used to
+   pass information to BFD (via the `elfcore_write_prpsinfo', for example),
+   so things like endianess shouldn't be an issue.  This structure will
+   eventually be converted in one of the `elf_external_*' structures
+   below.  */
+
+struct elf_internal_prpsinfo
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    unsigned long pr_flag;		/* Flags.  */
+    unsigned int pr_uid;
+    unsigned int pr_gid;
+    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+    char pr_fname[16 + 1];		/* Filename of executable.  */
+    char pr_psargs[80 + 1];		/* Initial part of arg list.  */
+  };
+
 \f
 extern void _bfd_elf_swap_verdef_in
   (bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
@@ -2239,7 +2263,7 @@ extern Elf_Internal_Phdr * _bfd_elf_find_segment_containing_section
 extern char *elfcore_write_note
   (bfd *, char *, int *, const char *, int, const void *, int);
 extern char *elfcore_write_prpsinfo
-  (bfd *, char *, int *, const char *, const char *);
+  (bfd *, char *, int *, const struct elf_internal_prpsinfo *);
 extern char *elfcore_write_prstatus
   (bfd *, char *, int *, long, int, const void *);
 extern char * elfcore_write_pstatus
diff --git a/bfd/elf-psinfo.h b/bfd/elf-psinfo.h
new file mode 100644
index 0000000..e241842
--- /dev/null
+++ b/bfd/elf-psinfo.h
@@ -0,0 +1,119 @@
+/* Definitions for PRPSINFO structures under ELF on GNU/Linux.
+   Copyright 2013 Free Software Foundation, Inc.
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+/* The PRPSINFO structures defined below are used by most architectures,
+   although some of them define their own versions (like e.g., PPC).  */
+
+/* External 32-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[2];
+    char pr_gid[2];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to swap (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_SWAP_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_16 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_16 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
+/* External 64-bit structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_prpsinfo64
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[8];			/* Flags.  */
+    char gap[4];
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to swap (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_prpsinfo64'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO64_SWAP_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_64 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
diff --git a/bfd/elf.c b/bfd/elf.c
index 9cd3542..444bb44 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -45,6 +45,7 @@ SECTION
 #include "elf-bfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
+#include "elf-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -9103,16 +9104,16 @@ char *
 elfcore_write_prpsinfo (bfd  *abfd,
 			char *buf,
 			int  *bufsiz,
-			const char *fname,
-			const char *psargs)
+			const struct elf_internal_prpsinfo *input)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (bed->elf_backend_write_core_note != NULL)
     {
       char *ret;
+
       ret = (*bed->elf_backend_write_core_note) (abfd, buf, bufsiz,
-						 NT_PRPSINFO, fname, psargs);
+						 NT_PRPSINFO, input);
       if (ret != NULL)
 	return ret;
     }
@@ -9130,8 +9131,8 @@ elfcore_write_prpsinfo (bfd  *abfd,
 #endif
 
       memset (&data, 0, sizeof (data));
-      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
@@ -9147,8 +9148,8 @@ elfcore_write_prpsinfo (bfd  *abfd,
 #endif
 
       memset (&data, 0, sizeof (data));
-      strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-      strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+      strncpy (data.pr_fname, input->pr_fname, sizeof (data.pr_fname));
+      strncpy (data.pr_psargs, input->pr_psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
 				 "CORE", note_type, &data, sizeof (data));
     }
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index e2f8a96..c9c3d15 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -30,6 +30,7 @@
 #include "elf-nacl.h"
 #include "elf-vxworks.h"
 #include "elf/arm.h"
+#include "elf-psinfo.h"
 
 /* Return the relocation section associated with NAME.  HTAB is the
    bfd's elf32_arm_link_hash_entry.  */
@@ -2004,17 +2005,19 @@ elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       {
-	char data[124];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 28, va_arg (ap, const char *), 16);
-	strncpy (data + 44, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
 
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index f76c7a7..b81b35b 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -31,6 +31,10 @@
 #include "objalloc.h"
 #include "hashtab.h"
 #include "dwarf2.h"
+#include "elf-bfd.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 /* 386 uses REL relocations instead of RELA.  */
 #define USE_REL	1
@@ -500,6 +504,38 @@ elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
   return TRUE;
 }
+
+static char *
+elf_i386_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+			  int note_type, ...)
+{
+  va_list ap;
+
+  switch (note_type)
+    {
+    default:
+      return NULL;
+
+    case NT_PRPSINFO:
+	{
+	  const struct elf_internal_prpsinfo *prpsinfo;
+	  struct elf_external_prpsinfo32 data;
+
+	  va_start (ap, note_type);
+	  prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
+	  va_end (ap);
+
+	  memset (&data, 0, sizeof (data));
+	  PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
+				     &data, sizeof (data));
+	}
+      /* NOTREACHED */
+    }
+  /* NOTREACHED */
+}
+
 \f
 /* Functions for the i386 ELF linker.
 
@@ -5042,6 +5078,7 @@ elf_i386_add_symbol_hook (bfd * abfd,
 #define elf_backend_gc_sweep_hook	      elf_i386_gc_sweep_hook
 #define elf_backend_grok_prstatus	      elf_i386_grok_prstatus
 #define elf_backend_grok_psinfo		      elf_i386_grok_psinfo
+#define elf_backend_write_core_note	      elf_i386_write_core_note
 #define elf_backend_reloc_type_class	      elf_i386_reloc_type_class
 #define elf_backend_relocate_section	      elf_i386_relocate_section
 #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 5241926..429ccb2 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -37,6 +37,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "elf-psinfo.h"
 
 typedef enum split16_format_type
 {
@@ -1777,6 +1778,62 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
 	 0xffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 };
+
+/* External 32-bit PPC structure for PRPSINFO.  This structure is ABI-defined,
+   thus we choose to use char arrays here in order to avoid dealing with
+   different types in different architectures.
+
+   The reason why we have a different structure only for PPC is because
+   on this architecture the size of 32-bit structure changes.  This is
+   due to the different sizes of `pr_uid' and `pr_gid', which on non-PPC
+   architectures are declared as `short int' and on PPC architectures are
+   declared as `int'.
+
+   This structure will ultimately be written in the corefile's note section,
+   as the PRPSINFO.  */
+
+struct elf_external_ppc_prpsinfo32
+  {
+    char pr_state;			/* Numeric process state.  */
+    char pr_sname;			/* Char for pr_state.  */
+    char pr_zomb;			/* Zombie.  */
+    char pr_nice;			/* Nice val.  */
+    char pr_flag[4];			/* Flags.  */
+    char pr_uid[4];
+    char pr_gid[4];
+    char pr_pid[4];
+    char pr_ppid[4];
+    char pr_pgrp[4];
+    char pr_sid[4];
+    /* Lots missing */
+    char pr_fname[16];			/* Filename of executable.  */
+    char pr_psargs[80];			/* Initial part of arg list.  */
+  };
+
+/* Helper macro to swap (properly handling endianess) things from the
+   `elf_internal_prpsinfo' structure to the `elf_external_ppc_prpsinfo32'
+   structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit type.  */
+
+#define PRPSINFO32_PPC_SWAP_FIELDS(abfd, from, to) \
+  do \
+    { \
+      H_PUT_8 (abfd, from->pr_state, &to.pr_state); \
+      H_PUT_8 (abfd, from->pr_sname, &to.pr_sname); \
+      H_PUT_8 (abfd, from->pr_zomb, &to.pr_zomb); \
+      H_PUT_8 (abfd, from->pr_nice, &to.pr_nice); \
+      H_PUT_32 (abfd, from->pr_flag, to.pr_flag); \
+      H_PUT_32 (abfd, from->pr_uid, to.pr_uid); \
+      H_PUT_32 (abfd, from->pr_gid, to.pr_gid); \
+      H_PUT_32 (abfd, from->pr_pid, to.pr_pid); \
+      H_PUT_32 (abfd, from->pr_ppid, to.pr_ppid); \
+      H_PUT_32 (abfd, from->pr_pgrp, to.pr_pgrp); \
+      H_PUT_32 (abfd, from->pr_sid, to.pr_sid); \
+      strncpy (to.pr_fname, from->pr_fname, sizeof (to.pr_fname)); \
+      strncpy (to.pr_psargs, from->pr_psargs, sizeof (to.pr_psargs)); \
+    } while (0)
+
 \f
 /* Initialize the ppc_elf_howto_table, so that linear accesses can be done.  */
 
@@ -2222,16 +2279,19 @@ ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 
     case NT_PRPSINFO:
       {
-	char data[128];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_ppc_prpsinfo32 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 32, va_arg (ap, const char *), 16);
-	strncpy (data + 48, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO32_PPC_SWAP_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 10b6f9d..937ef7f 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -34,6 +34,7 @@
 #include "elf-bfd.h"
 #include "elf/ppc64.h"
 #include "elf64-ppc.h"
+#include "elf-psinfo.h"
 #include "dwarf2.h"
 
 static bfd_reloc_status_type ppc64_elf_ha_reloc
@@ -2718,16 +2719,19 @@ ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
 
     case NT_PRPSINFO:
       {
-	char data[136];
+	const struct elf_internal_prpsinfo *prpsinfo;
+	struct elf_external_prpsinfo64 data;
 	va_list ap;
 
 	va_start (ap, note_type);
-	memset (data, 0, sizeof (data));
-	strncpy (data + 40, va_arg (ap, const char *), 16);
-	strncpy (data + 56, va_arg (ap, const char *), 80);
+	prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
 	va_end (ap);
+
+	memset (&data, 0, sizeof (data));
+	PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data);
+
 	return elfcore_write_note (abfd, buf, bufsiz,
-				   "CORE", note_type, data, sizeof (data));
+				   "CORE", note_type, &data, sizeof (data));
       }
 
     case NT_PRSTATUS:
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 92bf991..b0f6194 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -32,11 +32,13 @@
 #include "hashtab.h"
 #include "dwarf2.h"
 #include "libiberty.h"
+#include "elf-psinfo.h"
+
+#include <stdarg.h>
 
 #include "elf/x86-64.h"
 
 #ifdef CORE_HEADER
-#include <stdarg.h>
 #include CORE_HEADER
 #endif
 
@@ -415,14 +417,13 @@ elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
-#ifdef CORE_HEADER
 static char *
 elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 			    int note_type, ...)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   va_list ap;
-  const char *fname, *psargs;
+  const struct elf_internal_prpsinfo *prpsinfo;
   long pid;
   int cursig;
   const void *gregs;
@@ -434,31 +435,33 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 
     case NT_PRPSINFO:
       va_start (ap, note_type);
-      fname = va_arg (ap, const char *);
-      psargs = va_arg (ap, const char *);
+      prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
       va_end (ap);
 
       if (bed->s->elfclass == ELFCLASS32)
 	{
-	  prpsinfo32_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo32 data32;
+
+	  memset (&data32, 0, sizeof (data32));
+	  PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data32);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data32, sizeof (data32));
 	}
       else
 	{
-	  prpsinfo64_t data;
-	  memset (&data, 0, sizeof (data));
-	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
-	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
+	  struct elf_external_prpsinfo64 data64;
+
+	  memset (&data64, 0, sizeof (data64));
+	  PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data64);
+
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
-				     &data, sizeof (data));
+				     &data64, sizeof (data64));
 	}
       /* NOTREACHED */
 
     case NT_PRSTATUS:
+#ifdef CORE_HEADER
       va_start (ap, note_type);
       pid = va_arg (ap, long);
       cursig = va_arg (ap, int);
@@ -498,10 +501,13 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
 				     &prstat, sizeof (prstat));
 	}
+#else
+      return NULL;
+#endif /* CORE_HEADER */
     }
   /* NOTREACHED */
 }
-#endif
+
 \f
 /* Functions for the x86-64 ELF linker.	 */
 
@@ -5157,9 +5163,7 @@ static const struct bfd_elf_special_section
 #define elf_backend_gc_sweep_hook	    elf_x86_64_gc_sweep_hook
 #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
 #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
-#ifdef CORE_HEADER
 #define elf_backend_write_core_note	    elf_x86_64_write_core_note
-#endif
 #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
 #define elf_backend_relocate_section	    elf_x86_64_relocate_section
 #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
diff --git a/bfd/hosts/x86-64linux.h b/bfd/hosts/x86-64linux.h
index 78be09a..6070978 100644
--- a/bfd/hosts/x86-64linux.h
+++ b/bfd/hosts/x86-64linux.h
@@ -43,11 +43,6 @@ typedef unsigned long long int uint64_t;
 /* Unsigned 64-bit integer aligned to 8 bytes.  */
 typedef uint64_t __attribute__ ((__aligned__ (8))) a8_uint64_t;
 
-#undef HAVE_PRPSINFO32_T
-#define HAVE_PRPSINFO32_T
-#undef HAVE_PRPSINFO32_T_PR_PID
-#define HAVE_PRPSINFO32_T_PR_PID
-
 #undef HAVE_PRSTATUS32_T
 #define HAVE_PRSTATUS32_T
 
@@ -191,36 +186,6 @@ struct elf_prstatus64
     int pr_fpvalid;			/* True if math copro being used.  */
   };
 
-struct elf_prpsinfo32
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    unsigned int pr_flag;		/* Flags.  */
-    unsigned short int pr_uid;
-    unsigned short int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
-struct elf_prpsinfo64
-  {
-    char pr_state;			/* Numeric process state.  */
-    char pr_sname;			/* Char for pr_state.  */
-    char pr_zomb;			/* Zombie.  */
-    char pr_nice;			/* Nice val.  */
-    a8_uint64_t pr_flag;		/* Flags.  */
-    unsigned int pr_uid;
-    unsigned int pr_gid;
-    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
-    /* Lots missing */
-    char pr_fname[16];			/* Filename of executable.  */
-    char pr_psargs[ELF_PRARGSZ];	/* Initial part of arg list.  */
-  };
-
 /* The rest of this file provides the types for emulation of the
    Solaris <proc_service.h> interfaces that should be implemented by
    users of libthread_db.  */
@@ -229,5 +194,3 @@ struct elf_prpsinfo64
 typedef struct elf_prstatus32 prstatus32_t;
 typedef struct elf_prstatusx32 prstatusx32_t;
 typedef struct elf_prstatus64 prstatus64_t;
-typedef struct elf_prpsinfo32 prpsinfo32_t;
-typedef struct elf_prpsinfo64 prpsinfo64_t;
-- 
1.7.7.6

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils
  2013-01-10 19:47                     ` Sergio Durigan Junior
@ 2013-01-11 15:45                       ` Pedro Alves
  0 siblings, 0 replies; 21+ messages in thread
From: Pedro Alves @ 2013-01-11 15:45 UTC (permalink / raw)
  To: Sergio Durigan Junior
  Cc: Jan Kratochvil, Binutils Development, GDB Patches, H.J. Lu

On 01/10/2013 07:47 PM, Sergio Durigan Junior wrote:

>> On 01/04/2013 04:39 AM, Sergio Durigan Junior wrote:> +++ b/bfd/elf-psinfo.h
>>> @@ -0,0 +1,124 @@
>>> +/* Definitions for PRPSINFO structures under ELF on GNU/Linux.
>>
>> What about other OSs, like e.g., Solaris?
> 
> Since I took the definitions from the Linux kernel, I thought it'd be
> better to explicitly mention that.  I'm afraid I don't know how Solaris
> handle corefiles, do you think this comment should be expanded?

It's not that different on other Unixen, but the structures
may be different.  But I'm actually pondering about is whether we're
tying the whole new interface to Linux, causing problems for converting
other non-Linux ports.

E.g., a quick websearch for prpsinfo finds:

 http://bintree.net/freebsd/d0/ddc/sys_2procfs_8h_source.html

00075 typedef struct prpsinfo {
00076     int         pr_version;     /* Version number of struct (1) */
00077     size_t      pr_psinfosz;    /* sizeof(prpsinfo_t) (1) */
00078     char        pr_fname[PRFNAMESZ+1];  /* Command name, null terminated (1) */
00079     char        pr_psargs[PRARGSZ+1];   /* Arguments, null terminated (1) */
00080 } prpsinfo_t;

Other BSDs are probably similar, Solaris, IRIX, etc.,
will probably have a different structure in their own ways.

So indeed it looks like there's a problem here, and I think these
differences need to be contemplated.  How is the question.

One way would be for the hook to still take a "struct elf_internal_prpsinfo"
pointer, but make it so that "struct elf_internal_prpsinfo" itself is
opaque to the common code.  Both GDB's core generator code, and then
bfd's elf_backend_write_core_note hook would then have to agree on what
the type of "struct elf_internal_prpsinfo" really is, and either cast
appropriately (e.g., to/from struct elf_linux_internal_prpsinfo),
or including a file that has the proper definition of
"struct elf_internal_prpsinfo" for the target (I think that violates
C++'s ODR, so I tend to dislike it, although gdb/binutils do this
for other similar cases).

This is largely what the patch does already, except it takes
no consideration, either in naming or in comments that
"struct elf_internal_prpsinfo" is Linux specific, giving the
impression that it'd work for all ports.  But it doesn't
look like it would.  E.g., elf64-x86-64.c:elf_x86_64_write_core_note
with the patch is always using the Linux specific structure.
We need to instead have a Linux-specific version of that hook;
comments at the top of the file show it's used with FreeBSD and
Solaris too as well, and those will need their own versions
(could be the current pre-patch version).  Etc.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2013-01-11 15:45 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-17  3:10 [PATCH/RFC 01/02 v2] Refactor PRPSINFO handling on Binutils Sergio Durigan Junior
2012-12-17 15:43 ` H.J. Lu
2012-12-17 17:41   ` Sergio Durigan Junior
2012-12-17 17:44     ` H.J. Lu
2012-12-17 17:51       ` Sergio Durigan Junior
2012-12-17 22:01         ` H.J. Lu
2012-12-18  5:47           ` Sergio Durigan Junior
2012-12-18 15:43             ` H.J. Lu
2012-12-18 17:38 ` Jan Kratochvil
2012-12-18 19:19   ` Sergio Durigan Junior
2012-12-18 19:43     ` Jan Kratochvil
2012-12-30  1:50       ` Sergio Durigan Junior
2013-01-01 14:30         ` Jan Kratochvil
2013-01-02 23:32           ` Sergio Durigan Junior
2013-01-03 13:44             ` Jan Kratochvil
2013-01-03 15:46               ` Sergio Durigan Junior
2013-01-04  4:40                 ` Sergio Durigan Junior
2013-01-09 20:49                   ` Sergio Durigan Junior
2013-01-10 18:26                   ` Pedro Alves
2013-01-10 19:47                     ` Sergio Durigan Junior
2013-01-11 15:45                       ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).