@@ -2435,6 +2435,35 @@ extern char *elfcore_write_linux_prpsinfo64
extern char *elfcore_write_ppc_linux_prpsinfo32
(bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
+struct elf_internal_linux_prstatus
+{
+ struct elf_internal_siginfo
+ {
+ int si_signo;
+ int si_code;
+ int si_errno;
+ } pr_info;
+ int pr_cursig;
+ bfd_uint64_t pr_sigpend, pr_sighold;
+ int pr_pid, pr_ppid, pr_pgrp, pr_sid;
+ struct elf_internal_timeval
+ {
+ long tv_sec;
+ long tv_usec;
+ } pr_utime, pr_stime, pr_cutime, pr_cstime;
+ void *pr_reg;
+ int pr_reg_size;
+ int pr_fpvalid;
+};
+
+/* Linux/most 32-bit archs. */
+extern char *elfcore_write_linux_prstatus32
+ (bfd *, char *, int *, const struct elf_internal_linux_prstatus *);
+
+/* Linux/most 64-bit archs. */
+extern char *elfcore_write_linux_prstatus64
+ (bfd *, char *, int *, const struct elf_internal_linux_prstatus *);
+
extern bfd *_bfd_elf32_bfd_from_remote_memory
(bfd *templ, bfd_vma ehdr_vma, bfd_size_type size, bfd_vma *loadbasep,
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
@@ -1,4 +1,4 @@
-/* Definitions for PRPSINFO structures under ELF on GNU/Linux.
+/* Definitions for PRPSINFO and PRSTATUS structures under ELF on GNU/Linux.
Copyright (C) 2013-2016 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -120,4 +120,116 @@ swap_linux_prpsinfo64_out (bfd *obfd,
strncpy (to->pr_psargs, from->pr_psargs, sizeof (to->pr_psargs));
}
+/* PRSTATUS structs. */
+
+struct elf_external_linux_prstatus32
+{
+ char pr_info[12];
+ char pr_cursig[2];
+ char pad[2];
+ char pr_sigpend[4];
+ char pr_sighold[4];
+ char pr_pid[4];
+ char pr_ppid[4];
+ char pr_pgrp[4];
+ char pr_sid[4];
+ char pr_utime[8];
+ char pr_stime[8];
+ char pr_cutime[8];
+ char pr_cstime[8];
+ /* Variable size "char pr_reg[]" goes here. */
+ char pr_fpvalid[4];
+};
+
+struct elf_external_linux_prstatus64
+{
+ char pr_info[12];
+ char pr_cursig[2];
+ char pad[2];
+ char pr_sigpend[8];
+ char pr_sighold[8];
+ char pr_pid[4];
+ char pr_ppid[4];
+ char pr_pgrp[4];
+ char pr_sid[4];
+ char pr_utime[16];
+ char pr_stime[16];
+ char pr_cutime[16];
+ char pr_cstime[16];
+ /* Variable size "char pr_reg[]" goes here. */
+ char pr_fpvalid[4];
+ char pad2[4];
+};
+
+/* Helper function to copy an elf_internal_linux_prpstatus
+ to an elf_external_linux_prpsinfo32 in target endian.
+ FROM->pr_reg is already in target endian. */
+
+static inline void
+swap_linux_prstatus32_out (bfd *obfd,
+ const struct elf_internal_linux_prstatus *from,
+ void *to)
+{
+ struct elf_external_linux_prstatus32 *dest;
+
+ dest = (struct elf_external_linux_prstatus32 *) to;
+ bfd_put_32 (obfd, from->pr_info.si_signo, dest->pr_info + 0);
+ bfd_put_32 (obfd, from->pr_info.si_code, dest->pr_info + 4);
+ bfd_put_32 (obfd, from->pr_info.si_errno, dest->pr_info + 8);
+ bfd_put_16 (obfd, from->pr_cursig, dest->pr_cursig);
+ memset (dest->pad, 0, sizeof (dest->pad));
+ bfd_put_32 (obfd, from->pr_sigpend, dest->pr_sigpend);
+ bfd_put_32 (obfd, from->pr_sighold, dest->pr_sighold);
+ bfd_put_32 (obfd, from->pr_pid, dest->pr_pid);
+ bfd_put_32 (obfd, from->pr_ppid, dest->pr_ppid);
+ bfd_put_32 (obfd, from->pr_pgrp, dest->pr_pgrp);
+ bfd_put_32 (obfd, from->pr_sid, dest->pr_sid);
+ bfd_put_32 (obfd, from->pr_utime.tv_sec, dest->pr_utime + 0);
+ bfd_put_32 (obfd, from->pr_utime.tv_usec, dest->pr_utime + 4);
+ bfd_put_32 (obfd, from->pr_stime.tv_sec, dest->pr_stime + 0);
+ bfd_put_32 (obfd, from->pr_stime.tv_usec, dest->pr_stime + 4);
+ bfd_put_32 (obfd, from->pr_cutime.tv_sec, dest->pr_cutime + 0);
+ bfd_put_32 (obfd, from->pr_cutime.tv_usec, dest->pr_cutime + 4);
+ bfd_put_32 (obfd, from->pr_cstime.tv_sec, dest->pr_cstime + 0);
+ bfd_put_32 (obfd, from->pr_cstime.tv_usec, dest->pr_cstime + 4);
+ memcpy (dest->pr_fpvalid, from->pr_reg, from->pr_reg_size);
+ bfd_put_32 (obfd, from->pr_fpvalid, dest->pr_fpvalid + from->pr_reg_size);
+}
+
+/* Helper function to copy an elf_internal_linux_prpstatus
+ to an elf_external_linux_prpsinfo64 in target endian.
+ FROM->pr_reg is already in target endian. */
+
+static inline void
+swap_linux_prstatus64_out (bfd *obfd,
+ const struct elf_internal_linux_prstatus *from,
+ void *to)
+{
+ struct elf_external_linux_prstatus64 *dest;
+
+ dest = (struct elf_external_linux_prstatus64 *) to;
+ bfd_put_32 (obfd, from->pr_info.si_signo, dest->pr_info + 0);
+ bfd_put_32 (obfd, from->pr_info.si_code, dest->pr_info + 4);
+ bfd_put_32 (obfd, from->pr_info.si_errno, dest->pr_info + 8);
+ bfd_put_16 (obfd, from->pr_cursig, dest->pr_cursig);
+ memset (dest->pad, 0, sizeof (dest->pad));
+ bfd_put_64 (obfd, from->pr_sigpend, dest->pr_sigpend);
+ bfd_put_64 (obfd, from->pr_sighold, dest->pr_sighold);
+ bfd_put_32 (obfd, from->pr_pid, dest->pr_pid);
+ bfd_put_32 (obfd, from->pr_ppid, dest->pr_ppid);
+ bfd_put_32 (obfd, from->pr_pgrp, dest->pr_pgrp);
+ bfd_put_32 (obfd, from->pr_sid, dest->pr_sid);
+ bfd_put_64 (obfd, from->pr_utime.tv_sec, dest->pr_utime + 0);
+ bfd_put_64 (obfd, from->pr_utime.tv_usec, dest->pr_utime + 8);
+ bfd_put_64 (obfd, from->pr_stime.tv_sec, dest->pr_stime + 0);
+ bfd_put_64 (obfd, from->pr_stime.tv_usec, dest->pr_stime + 8);
+ bfd_put_64 (obfd, from->pr_cutime.tv_sec, dest->pr_cutime + 0);
+ bfd_put_64 (obfd, from->pr_cutime.tv_usec, dest->pr_cutime + 8);
+ bfd_put_64 (obfd, from->pr_cstime.tv_sec, dest->pr_cstime + 0);
+ bfd_put_64 (obfd, from->pr_cstime.tv_usec, dest->pr_cstime + 8);
+ memcpy (dest->pr_fpvalid, from->pr_reg, from->pr_reg_size);
+ bfd_put_32 (obfd, from->pr_fpvalid, dest->pr_fpvalid + from->pr_reg_size);
+ memset (dest->pad2 + from->pr_reg_size, 0, sizeof (dest->pad2));
+}
+
#endif
@@ -9809,6 +9809,40 @@ elfcore_write_linux_prpsinfo64
}
char *
+elfcore_write_linux_prstatus32
+ (bfd *obfd,
+ char *buf,
+ int *bufsize,
+ const struct elf_internal_linux_prstatus *prstatus)
+{
+ size_t datasize = (prstatus->pr_reg_size
+ + sizeof (struct elf_external_linux_prstatus32));
+ char data[1144];
+
+ BFD_ASSERT (sizeof (data) >= datasize);
+ swap_linux_prstatus32_out (obfd, prstatus, data);
+ return elfcore_write_note (obfd, buf, bufsize,
+ "CORE", NT_PRSTATUS, data, datasize);
+}
+
+char *
+elfcore_write_linux_prstatus64
+ (bfd *obfd,
+ char *buf,
+ int *bufsize,
+ const struct elf_internal_linux_prstatus *prstatus)
+{
+ size_t datasize = (prstatus->pr_reg_size
+ + sizeof (struct elf_external_linux_prstatus64));
+ char data[1144]; /* Size of ia64 prstatus. */
+
+ BFD_ASSERT (sizeof (data) >= datasize);
+ swap_linux_prstatus64_out (obfd, prstatus, data);
+ return elfcore_write_note (obfd, buf, bufsize,
+ "CORE", NT_PRSTATUS, data, datasize);
+}
+
+char *
elfcore_write_prstatus (bfd *abfd,
char *buf,
int *bufsiz,