This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 2/3] Reimplement PRPSINFO support on BFD
- From: Sergio Durigan Junior <sergiodj at redhat dot com>
- To: Binutils Development <binutils at sourceware dot org>
- Cc: GDB Patches <gdb-patches at sourceware dot org>, Pedro Alves <palves at redhat dot com>, Jan Kratochvil <jan dot kratochvil at redhat dot com>, "H. J. Lu" <hongjiu dot lu at intel dot com>
- Date: Wed, 30 Jan 2013 04:52:59 -0200
- Subject: [PATCH 2/3] Reimplement PRPSINFO support on BFD
Hi,
As a followup of my previous patch series, which can be found here:
<http://sourceware.org/ml/gdb-patches/2012-12/msg00534.html>
<http://sourceware.org/ml/gdb-patches/2012-12/msg00536.html>
I am now sending the patch which implements the BFD part of the support
for the PRPSINFO handling on corefiles for Linux targets.
This patch is basically the same, with few modifications except for the
creation of the new *_linux_* variant functions for corefile handling.
I have also addressed the comments made by Pedro here:
<http://sourceware.org/ml/gdb-patches/2013-01/msg00200.html>
(Other comments were addressed in previous postings).
I guess this patch has been reviewed many times, and I couldn't think of
anything else to hack here, but feel free to make further comments.
Ok to check-in?
--
Sergio
bfd/ChangeLog:
2013-01-30 Sergio Durigan Junior <sergiodj@redhat.com>
* Makefile.in (SOURCE_HFILES): Add `elf-linux-psinfo.h'.
* elf-bfd.h (elf_internal_prpsinfo): New structure declaration.
(elfcore_write_prpsinfo): Change prototype, accepting
`elf_internal_prpsinfo' as argument.
* elf-linux-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-linux-psinfo.h'.
(elf32_arm_nabi_write_core_note): Return NULL, move contents to...
(elf32_linux_arm_nabi_write_core_note): ...here, reimplementing the
`NT_PRPSINFO' case. Register this function as the one to be used for
targets running the Linux kernel.
* elf32-i386.c: Include `elf-bfd.h', `elf-linux-psinfo.h' and
`stdarg.h'.
(elf_i386_write_core_note): New function.
(elf_linux_i386_write_core_note): Likewise. Register this function
as the one to be used for targets running the Linux kernel.
* elf32-ppc.c: Include `elf-linux-psinfo.h'.
(elf_external_ppc_prpsinfo32): New structure declaration.
(PRPSINFO32_PPC_SWAP_FIELDS): New definition.
(ppc_elf_write_core_note): Return NULL, move contents to...
(ppc_linux_elf_write_core_note): ...here, reimplementing the
`NT_PRPSINFO' case. Register this function as the one to be used for
targets running the Linux kernel.
* elf64-ppc.c: Include `elf-linux-psinfo.h'.
(ppc64_elf_write_core_note): Return NULL, move contents to...
(ppc64_linux_elf_write_core_note): ...here, reimplementing the
`NT_PRPSINFO' case. Register this function as the one to be used for
targets running the Linux kernel.
* elf64-x86-64.c: Include `elf-linux-psinfo.h'. Include `stdarg.h'
unconditionally.
(elf_x86_64_write_core_note): Return NULL, moving contents to...
(elf_linux_x86_64_write_core_note): ...here, removing
`#ifdef CORE_HEADER', making the function unconditionally available.
Refactor `NT_PRPSINFO' case. Refactor `NT_PRSTATUS' case, making it
conditional to `CORE_HEADER'. Register this function as the one to be
used for targets running the Linux kernel.
* hosts/x86-64linux.h (HAVE_PRPSINFO32_T, HAVE_PRPSINFO32_T_PR_PID,
elf_prpsinfo32, elf_prpsinfo64, prpsinfo32_t, prpsinfo64_t): Remove
definitions.
---
bfd/elf-bfd.h | 26 +++++++-
bfd/elf-linux-psinfo.h | 119 +++++++++++++++++++++++++++++++
bfd/elf.c | 14 ++--
bfd/elf32-arm.c | 33 ++++++++--
bfd/elf32-i386.c | 57 +++++++++++++++
bfd/elf32-ppc.c | 92 +++++++++++++++++++++++--
bfd/elf64-ppc.c | 34 ++++++++--
bfd/elf64-x86-64.c | 178 +++++++++++++++++++++++++++++------------------
bfd/hosts/x86-64linux.h | 37 ----------
9 files changed, 460 insertions(+), 130 deletions(-)
create mode 100644 bfd/elf-linux-psinfo.h
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index af4e5ed..a92debf 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-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 \
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index faaf632..98964b4 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. */
+ };
+
extern void _bfd_elf_swap_verdef_in
(bfd *, const Elf_External_Verdef *, Elf_Internal_Verdef *);
@@ -2243,7 +2267,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-linux-psinfo.h b/bfd/elf-linux-psinfo.h
new file mode 100644
index 0000000..e241842
--- /dev/null
+++ b/bfd/elf-linux-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..5d8c0d1 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -9103,16 +9103,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 +9130,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 +9147,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 4dfd113..f297564 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-linux-psinfo.h"
/* Return the relocation section associated with NAME. HTAB is the
bfd's elf32_arm_link_hash_entry. */
@@ -1997,6 +1998,18 @@ static char *
elf32_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
int note_type, ...)
{
+ (void) abfd;
+ (void) buf;
+ (void) bufsiz;
+ (void) note_type;
+
+ return NULL;
+}
+
+static char *
+elf32_linux_arm_nabi_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+ int note_type, ...)
+{
switch (note_type)
{
default:
@@ -2004,17 +2017,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:
@@ -15745,8 +15760,16 @@ const struct elf_size_info elf32_arm_size_info =
#undef elf32_bed
#define elf32_bed elf32_arm_linux_bed
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note elf32_linux_arm_nabi_write_core_note
+
#include "elf32-target.h"
+/* Restoring defaults. */
+
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note elf32_arm_nabi_write_core_note
+
/* Native Client targets. */
#undef TARGET_LITTLE_SYM
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 5ef518e..cd86529 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-linux-psinfo.h"
+
+#include <stdarg.h>
/* 386 uses REL relocations instead of RELA. */
#define USE_REL 1
@@ -506,6 +510,50 @@ 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, ...)
+{
+ (void) abfd;
+ (void) buf;
+ (void) bufsiz;
+ (void) note_type;
+
+ return NULL;
+}
+
+static char *
+elf_linux_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 */
+}
+
/* Functions for the i386 ELF linker.
@@ -5090,6 +5138,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
@@ -5113,8 +5162,16 @@ elf_i386_add_symbol_hook (bfd * abfd,
#undef elf32_bed
#define elf32_bed elf32_i386_linux_bed
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note elf_linux_i386_write_core_note
+
#include "elf32-target.h"
+/* Reset to defaults. */
+
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note elf_i386_write_core_note
+
/* FreeBSD support. */
#undef TARGET_LITTLE_SYM
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 1272b5a..ef45fc2 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-linux-psinfo.h"
typedef enum split16_format_type
{
@@ -1777,6 +1778,61 @@ 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];
+ 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)
+
/* Initialize the ppc_elf_howto_table, so that linear accesses can be done. */
@@ -2213,7 +2269,20 @@ ppc_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
}
static char *
-ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type, ...)
+ppc_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+ int note_type, ...)
+{
+ (void) abfd;
+ (void) buf;
+ (void) bufsiz;
+ (void) note_type;
+
+ return NULL;
+}
+
+static char *
+ppc_linux_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+ int note_type, ...)
{
switch (note_type)
{
@@ -2222,16 +2291,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:
@@ -9819,8 +9891,16 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
#undef elf32_bed
#define elf32_bed elf32_powerpc_linux_bed
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note ppc_linux_elf_write_core_note
+
#include "elf32-target.h"
+/* Restore to defaults. */
+
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note ppc_elf_write_core_note
+
/* FreeBSD Target */
#undef TARGET_LITTLE_SYM
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index e4e9d44..1ddeb6e 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-linux-psinfo.h"
#include "dwarf2.h"
static bfd_reloc_status_type ppc64_elf_ha_reloc
@@ -2711,6 +2712,18 @@ static char *
ppc64_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
...)
{
+ (void) abfd;
+ (void) buf;
+ (void) bufsiz;
+ (void) note_type;
+
+ return NULL;
+}
+
+static char *
+ppc64_linux_elf_write_core_note (bfd *abfd, char *buf, int *bufsiz,
+ int note_type, ...)
+{
switch (note_type)
{
default:
@@ -2718,16 +2731,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:
@@ -14274,8 +14290,16 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
#undef elf64_bed
#define elf64_bed elf64_powerpc_linux_bed
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note ppc64_linux_elf_write_core_note
+
#include "elf64-target.h"
+/* Restore to defaults. */
+
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note ppc64_elf_write_core_note
+
/* FreeBSD support */
#undef TARGET_LITTLE_SYM
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 04d46a8..359eec3 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-linux-psinfo.h"
+
+#include <stdarg.h>
#include "elf/x86-64.h"
#ifdef CORE_HEADER
-#include <stdarg.h>
#include CORE_HEADER
#endif
@@ -421,17 +423,24 @@ 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, ...)
{
+ (void) abfd;
+ (void) buf;
+ (void) bufsiz;
+ (void) note_type;
+
+ return NULL;
+}
+
+static char *
+elf_linux_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;
- long pid;
- int cursig;
- const void *gregs;
switch (note_type)
{
@@ -439,75 +448,92 @@ elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
return NULL;
case NT_PRPSINFO:
- va_start (ap, note_type);
- fname = va_arg (ap, const char *);
- psargs = va_arg (ap, const char *);
- va_end (ap);
+ {
+ const struct elf_internal_prpsinfo *prpsinfo;
- 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));
- return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
- &data, sizeof (data));
- }
- 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));
- return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
- &data, sizeof (data));
- }
+ va_start (ap, note_type);
+ prpsinfo = va_arg (ap, const struct elf_internal_prpsinfo *);
+ va_end (ap);
+
+ if (bed->s->elfclass == ELFCLASS32)
+ {
+ 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,
+ &data32, sizeof (data32));
+ }
+ else
+ {
+ 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,
+ &data64, sizeof (data64));
+ }
+ }
/* 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);
+ {
+#ifdef CORE_HEADER
+ long pid;
+ int cursig;
+ const void *gregs;
- if (bed->s->elfclass == ELFCLASS32)
- {
- 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));
- }
- }
- else
- {
- prstatus64_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));
- }
+ 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->s->elfclass == ELFCLASS32)
+ {
+ 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));
+ }
+ }
+ else
+ {
+ prstatus64_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
+ return NULL;
+#endif /* CORE_HEADER */
}
/* NOTREACHED */
}
-#endif
+
/* Functions for the x86-64 ELF linker. */
@@ -5219,9 +5245,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
@@ -5266,11 +5290,19 @@ static const struct bfd_elf_special_section
#undef TARGET_LITTLE_NAME
#define TARGET_LITTLE_NAME "el64-x86-64-linux"
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note elf_linux_x86_64_write_core_note
+
#undef elf64_bed
#define elf64_bed elf64_x86_64_linux_bed
#include "elf64-target.h"
+/* Restore defaults. */
+
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note elf_x86_64_write_core_note
+
/* FreeBSD support. */
#undef TARGET_LITTLE_SYM
@@ -5621,8 +5653,16 @@ elf64_k1om_elf_object_p (bfd *abfd)
#undef ELF_OSABI
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note elf_linux_x86_64_write_core_note
+
#include "elf32-target.h"
+/* Restore defaults. */
+
+#undef elf_backend_write_core_note
+#define elf_backend_write_core_note elf_x86_64_write_core_note
+
/* 32bit x86-64 support. */
#undef TARGET_LITTLE_SYM
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