2013-02-04 Sergio Durigan Junior <sergiodj@redhat.com>
authorSergio Durigan Junior <sergiodj@redhat.com>
Mon, 4 Feb 2013 18:26:34 +0000 (18:26 +0000)
committerSergio Durigan Junior <sergiodj@redhat.com>
Mon, 4 Feb 2013 18:26:34 +0000 (18:26 +0000)
    Pedro Alves  <palves@redhat.com>

* Makefile.in (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
* elf-bfd.h (elf_internal_linux_prpsinfo): New structure
declaration.
(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64)
(elfcore_write_ppc32_linux_prpsinfo32): New declarations.
* elf-linux-psinfo.h: New file.
* elf.c: Include elf-linux-psinfo.h.
(elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64):
New functions.
* elf32-ppc.c: Include `elf-linux-psinfo.h'.
(elf_external_ppc_linux_prpsinfo32): New structure declaration.
(PPC_LINUX_PRPSINFO32_SWAP_FIELDS): New macro.
(elfcore_write_ppc_linux_prpsinfo32): New function.

bfd/ChangeLog
bfd/Makefile.in
bfd/elf-bfd.h
bfd/elf-linux-psinfo.h [new file with mode: 0644]
bfd/elf.c
bfd/elf32-ppc.c

index ab40902..2571de3 100644 (file)
@@ -1,3 +1,20 @@
+2013-02-04  Sergio Durigan Junior  <sergiodj@redhat.com>
+           Pedro Alves  <palves@redhat.com>
+
+       * Makefile.in (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
+       * elf-bfd.h (elf_internal_linux_prpsinfo): New structure
+       declaration.
+       (elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64)
+       (elfcore_write_ppc32_linux_prpsinfo32): New declarations.
+       * elf-linux-psinfo.h: New file.
+       * elf.c: Include elf-linux-psinfo.h.
+       (elfcore_write_linux_prpsinfo32, elfcore_write_linux_prpsinfo64):
+       New functions.
+       * elf32-ppc.c: Include `elf-linux-psinfo.h'.
+       (elf_external_ppc_linux_prpsinfo32): New structure declaration.
+       (PPC_LINUX_PRPSINFO32_SWAP_FIELDS): New macro.
+       (elfcore_write_ppc_linux_prpsinfo32): New function.
+
 2013-02-04  Tristan Gingold  <gingold@adacore.com>
 
        * mach-o.c (bfd_mach_o_scan_start_address): Do not fail if no
index aaf6627..0a0fd40 100644 (file)
@@ -1070,7 +1070,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-linux-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 \
index faaf632..1fd73cf 100644 (file)
@@ -2285,6 +2285,42 @@ extern char *elfcore_write_lwpstatus
 extern char *elfcore_write_register_note
   (bfd *, char *, int *, const char *, const void *, int);
 
+/* Internal structure which holds information to be included in the
+   PRPSINFO section of Linux core files.
+
+   This is an "internal" structure in the sense that it should be used
+   to pass information to BFD (via the `elfcore_write_linux_prpsinfo'
+   function), so things like endianess shouldn't be an issue.  This
+   structure will eventually be converted in one of the
+   `elf_external_linux_*' structures and written out to an output bfd
+   by one of the functions declared below.  */
+
+struct elf_internal_linux_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.  */
+  };
+
+/* Linux/most 32-bit archs.  */
+extern char *elfcore_write_linux_prpsinfo32
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/most 64-bit archs.  */
+extern char *elfcore_write_linux_prpsinfo64
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
+/* Linux/PPC32 uses different layout compared to most archs.  */
+extern char *elfcore_write_ppc_linux_prpsinfo32
+  (bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+
 extern bfd *_bfd_elf32_bfd_from_remote_memory
   (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
    int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
diff --git a/bfd/elf-linux-psinfo.h b/bfd/elf-linux-psinfo.h
new file mode 100644 (file)
index 0000000..c965284
--- /dev/null
@@ -0,0 +1,127 @@
+/* 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.  */
+
+#ifndef ELF_LINUX_PSINFO_H
+#define ELF_LINUX_PSINFO_H
+
+/* 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_linux_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_linux_prpsinfo' structure to the
+   `elf_external_linux_prpsinfo32' structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit
+   type.  */
+
+#define LINUX_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_linux_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_linux_prpsinfo' structure to the
+   `elf_external_linux_prpsinfo64' structure.
+
+   Note that FROM should be a pointer, and TO should be the explicit
+   type.  */
+
+#define LINUX_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)
+
+#endif
index 9cd3542..7ab3683 100644 (file)
--- 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-linux-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -9159,6 +9160,34 @@ elfcore_write_prpsinfo (bfd  *abfd,
 }
 
 char *
+elfcore_write_linux_prpsinfo32
+  (bfd *abfd, char *buf, int *bufsiz,
+   const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_linux_prpsinfo32 data;
+
+  memset (&data, 0, sizeof (data));
+  LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
+                            &data, sizeof (data));
+}
+
+char *
+elfcore_write_linux_prpsinfo64
+  (bfd *abfd, char *buf, int *bufsiz,
+   const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_linux_prpsinfo64 data;
+
+  memset (&data, 0, sizeof (data));
+  LINUX_PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            "CORE", NT_PRPSINFO, &data, sizeof (data));
+}
+
+char *
 elfcore_write_prstatus (bfd *abfd,
                        char *buf,
                        int *bufsiz,
index 3f4e4bf..bf14206 100644 (file)
@@ -37,6 +37,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "elf-linux-psinfo.h"
 
 typedef enum split16_format_type
 {
@@ -1777,6 +1778,58 @@ 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 PPC 32-bit structure uses int for `pr_uid' and `pr_gid' while
+   most non-PPC architectures use `short int'.
+
+   This structure will ultimately be written in the corefile's note
+   section, as the PRPSINFO.  */
+
+struct elf_external_ppc_linux_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];
+    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 PPC_LINUX_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_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.  */
 
@@ -2212,6 +2265,19 @@ ppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
+char *
+elfcore_write_ppc_linux_prpsinfo32 (bfd *abfd, char *buf, int *bufsiz,
+                                     const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_ppc_linux_prpsinfo32 data;
+
+  memset (&data, 0, sizeof (data));
+  PPC_LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            "CORE", NT_PRPSINFO, &data, sizeof (data));
+}
+
 static char *
 ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
 {