ELF/BFD,GDB: Handle both variants of the 32-bit Linux core PRPSINFO note

Fix commit 70a38d42c5 ("New entry points for writing Linux NT_PRPSINFO
notes."), <https://sourceware.org/ml/binutils/2013-02/msg00023.html>,
and commit b3ac9c7756 ("Put more info in NT_PRPSINFO Linux notes"),
<https://sourceware.org/ml/binutils/2013-02/msg00024.html>, and handle
both variants of the 32-bit Linux core PRPSINFO note across all targets.

The 32-bit Linux core PRPSINFO note matches the 32-bit kernel structure,
defined as follows:

(gdb) ptype struct elf_prpsinfo
type = struct elf_prpsinfo {
    char pr_state;
    char pr_sname;
    char pr_zomb;
    char pr_nice;
    unsigned long pr_flag;
    __kernel_uid_t pr_uid;
    __kernel_gid_t pr_gid;
    pid_t pr_pid;
    pid_t pr_ppid;
    pid_t pr_pgrp;
    pid_t pr_sid;
    char pr_fname[16];
    char pr_psargs[80];
}
(gdb)

where the individual data types of most members are the same across all
32-bit Linux ports, with the exception of `__kernel_uid_t' and
`__kernel_gid_t'.  These are defined in <asm-generic/posix_types.h> as
32-bit `unsigned int' by default, however overridden as 16-bit `unsigned
short' in port-specific <asm/posix_types.h> for a few targets, mostly
earlier ports of Linux, specifically: ARM, CRIS, FR-V, M32R, m68k,
MN10300/AM33, s390, SuperH, SPARC and i386.

The default is the same as the PowerPC variant already handled, as from
the commits referred.  Make the special PowerPC case generic then,
removing the GDB part, and provide a backend flag to switch between the
two cases possible, with the 32-bit one being the default and the 16-bit
one explicitly selected.  Set the flag in the target backends affected.

	bfd/
	* elf-bfd.h (elf_backend_data): Add `linux_prpsinfo32_ugid16'
	member.
	(elfcore_write_ppc_linux_prpsinfo32): Remove prototype.
	* elf32-ppc.c (elfcore_write_ppc_linux_prpsinfo32): Remove.
	(elf_external_ppc_linux_prpsinfo32)
	(swap_ppc_linux_prpsinfo32_out): Move to...
	* elf-linux-core.h (elf_external_linux_prpsinfo32_ugid32)
	(swap_linux_prpsinfo32_ugid32_out): ... these.
	(elf_external_linux_prpsinfo32): Rename to...
	(elf_external_linux_prpsinfo32_ugid16): ... this.
	(swap_linux_prpsinfo32_out): Rename to...
	(swap_linux_prpsinfo32_ugid16_out): ... this.
	* elfxx-target.h [!elf_backend_linux_prpsinfo32_ugid16]
	(elf_backend_linux_prpsinfo32_ugid16): Define.
	(elfNN_bed): Initialize `linux_prpsinfo32_ugid16' member.
	* elf.c (elfcore_write_linux_prpsinfo32): Handle both variants
	of the 32-bit Linux core PRPSINFO note.
	* elf32-am33lin.c (elf_backend_linux_prpsinfo32_ugid16): Define.
	* elf32-arm.c (elf_backend_linux_prpsinfo32_ugid16): Define.
	* elf32-cris.c (elf_backend_linux_prpsinfo32_ugid16): Define.
	* elf32-frv.c (elf_backend_linux_prpsinfo32_ugid16): Define.
	* elf32-i386.c (elf_backend_linux_prpsinfo32_ugid16): Define.
	* elf32-m32r.c (elf_backend_linux_prpsinfo32_ugid16): Define.
	* elf32-m68k.c (elf_backend_linux_prpsinfo32_ugid16): Define.
	* elf32-s390.c (elf_backend_linux_prpsinfo32_ugid16): Define.
	* elf32-sh.c (elf_backend_linux_prpsinfo32_ugid16): Define.
	* elf32-sparc.c (elf_backend_linux_prpsinfo32_ugid16): Define.

	gdb/
	* ppc-linux-tdep.c (ppc_linux_init_abi): Remove call to
	`set_gdbarch_elfcore_write_linux_prpsinfo'.
This commit is contained in:
Maciej W. Rozycki 2017-10-11 15:01:40 +01:00
parent 72bc1bb934
commit a2f63b2e7a
18 changed files with 141 additions and 88 deletions

View File

@ -1,3 +1,33 @@
2017-10-11 Maciej W. Rozycki <macro@imgtec.com>
* elf-bfd.h (elf_backend_data): Add `linux_prpsinfo32_ugid16'
member.
(elfcore_write_ppc_linux_prpsinfo32): Remove prototype.
* elf32-ppc.c (elfcore_write_ppc_linux_prpsinfo32): Remove.
(elf_external_ppc_linux_prpsinfo32)
(swap_ppc_linux_prpsinfo32_out): Move to...
* elf-linux-core.h (elf_external_linux_prpsinfo32_ugid32)
(swap_linux_prpsinfo32_ugid32_out): ... these.
(elf_external_linux_prpsinfo32): Rename to...
(elf_external_linux_prpsinfo32_ugid16): ... this.
(swap_linux_prpsinfo32_out): Rename to...
(swap_linux_prpsinfo32_ugid16_out): ... this.
* elfxx-target.h [!elf_backend_linux_prpsinfo32_ugid16]
(elf_backend_linux_prpsinfo32_ugid16): Define.
(elfNN_bed): Initialize `linux_prpsinfo32_ugid16' member.
* elf.c (elfcore_write_linux_prpsinfo32): Handle both variants
of the 32-bit Linux core PRPSINFO note.
* elf32-am33lin.c (elf_backend_linux_prpsinfo32_ugid16): Define.
* elf32-arm.c (elf_backend_linux_prpsinfo32_ugid16): Define.
* elf32-cris.c (elf_backend_linux_prpsinfo32_ugid16): Define.
* elf32-frv.c (elf_backend_linux_prpsinfo32_ugid16): Define.
* elf32-i386.c (elf_backend_linux_prpsinfo32_ugid16): Define.
* elf32-m32r.c (elf_backend_linux_prpsinfo32_ugid16): Define.
* elf32-m68k.c (elf_backend_linux_prpsinfo32_ugid16): Define.
* elf32-s390.c (elf_backend_linux_prpsinfo32_ugid16): Define.
* elf32-sh.c (elf_backend_linux_prpsinfo32_ugid16): Define.
* elf32-sparc.c (elf_backend_linux_prpsinfo32_ugid16): Define.
2017-10-11 Maciej W. Rozycki <macro@imgtec.com>
* elf-linux-core.h (elf_external_linux_prpsinfo64): Move the

View File

@ -1557,6 +1557,10 @@ struct elf_backend_data
/* True if `_bfd_elf_link_renumber_dynsyms' must be called even for
static binaries. */
unsigned always_renumber_dynsyms : 1;
/* True if the 32-bit Linux PRPSINFO structure's `pr_uid' and `pr_gid'
members use a 16-bit data type. */
unsigned linux_prpsinfo32_ugid16 : 1;
};
/* Information about reloc sections associated with a bfd_elf_section_data
@ -2595,10 +2599,6 @@ extern char *elfcore_write_linux_prpsinfo32
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_size_type size, bfd_vma *loadbasep,
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));

View File

@ -21,18 +21,70 @@
#ifndef ELF_LINUX_CORE_H
#define ELF_LINUX_CORE_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 is the variant for targets which use a 32-bit data type for
UID and GID, as all modern Linux ports do. Some older ports use
a 16-bit data type instead; see below for the alternative variant.
This structure will ultimately be written in the corefile's note
section, as the PRPSINFO. */
struct elf_external_linux_prpsinfo32_ugid32
{
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 function to copy an elf_internal_linux_prpsinfo in host
endian to an elf_external_linux_prpsinfo32_ugid32 in target endian. */
static inline void
swap_linux_prpsinfo32_ugid32_out
(bfd *obfd,
const struct elf_internal_linux_prpsinfo *from,
struct elf_external_linux_prpsinfo32_ugid32 *to)
{
bfd_put_8 (obfd, from->pr_state, &to->pr_state);
bfd_put_8 (obfd, from->pr_sname, &to->pr_sname);
bfd_put_8 (obfd, from->pr_zomb, &to->pr_zomb);
bfd_put_8 (obfd, from->pr_nice, &to->pr_nice);
bfd_put_32 (obfd, from->pr_flag, to->pr_flag);
bfd_put_32 (obfd, from->pr_uid, to->pr_uid);
bfd_put_32 (obfd, from->pr_gid, to->pr_gid);
bfd_put_32 (obfd, from->pr_pid, to->pr_pid);
bfd_put_32 (obfd, from->pr_ppid, to->pr_ppid);
bfd_put_32 (obfd, from->pr_pgrp, to->pr_pgrp);
bfd_put_32 (obfd, 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));
}
/* 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 is the variant for targets which use a 16-bit data type for
UID and GID, as some older Linux ports do. All modern ports use
a 32-bit data type instead; see above for the alternative variant.
This structure will ultimately be written in the corefile's note
section, as the PRPSINFO. */
struct elf_external_linux_prpsinfo32
struct elf_external_linux_prpsinfo32_ugid16
{
char pr_state; /* Numeric process state. */
char pr_sname; /* Char for pr_state. */
@ -50,12 +102,13 @@ struct elf_external_linux_prpsinfo32
};
/* Helper function to copy an elf_internal_linux_prpsinfo in host
endian to an elf_external_linux_prpsinfo32 in target endian. */
endian to an elf_external_linux_prpsinfo32_ugid16 in target endian. */
static inline void
swap_linux_prpsinfo32_out (bfd *obfd,
const struct elf_internal_linux_prpsinfo *from,
struct elf_external_linux_prpsinfo32 *to)
swap_linux_prpsinfo32_ugid16_out
(bfd *obfd,
const struct elf_internal_linux_prpsinfo *from,
struct elf_external_linux_prpsinfo32_ugid16 *to)
{
bfd_put_8 (obfd, from->pr_state, &to->pr_state);
bfd_put_8 (obfd, from->pr_sname, &to->pr_sname);

View File

@ -10466,11 +10466,22 @@ elfcore_write_linux_prpsinfo32
(bfd *abfd, char *buf, int *bufsiz,
const struct elf_internal_linux_prpsinfo *prpsinfo)
{
struct elf_external_linux_prpsinfo32 data;
if (get_elf_backend_data (abfd)->linux_prpsinfo32_ugid16)
{
struct elf_external_linux_prpsinfo32_ugid16 data;
swap_linux_prpsinfo32_out (abfd, prpsinfo, &data);
return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
&data, sizeof (data));
swap_linux_prpsinfo32_ugid16_out (abfd, prpsinfo, &data);
return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
&data, sizeof (data));
}
else
{
struct elf_external_linux_prpsinfo32_ugid32 data;
swap_linux_prpsinfo32_ugid32_out (abfd, prpsinfo, &data);
return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
&data, sizeof (data));
}
}
char *

View File

@ -102,4 +102,6 @@ elf32_am33lin_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
#define elf_backend_grok_prstatus elf32_am33lin_grok_prstatus
#define elf_backend_grok_psinfo elf32_am33lin_grok_psinfo
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#include "elf-m10300.c"

View File

@ -19452,6 +19452,8 @@ elf32_arm_backend_symbol_processing (bfd *abfd, asymbol *sym)
#undef elf_backend_lookup_section_flags_hook
#define elf_backend_lookup_section_flags_hook elf32_arm_lookup_section_flags
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#include "elf32-target.h"
/* Native Client targets. */

View File

@ -4347,6 +4347,8 @@ elf_cris_got_elt_size (bfd *abfd ATTRIBUTE_UNUSED,
#define elf_backend_may_use_rela_p 1
#define elf_backend_rela_normal 1
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#include "elf32-target.h"
#undef TARGET_LITTLE_SYM

View File

@ -6810,6 +6810,8 @@ elf32_frv_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
#define elf_backend_grok_prstatus elf32_frv_grok_prstatus
#define elf_backend_grok_psinfo elf32_frv_grok_psinfo
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#include "elf32-target.h"
#undef ELF_MAXPAGESIZE

View File

@ -4587,6 +4587,8 @@ elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
#define elf_backend_relocate_section elf_i386_relocate_section
#define elf_backend_setup_gnu_properties elf_i386_link_setup_gnu_properties
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#include "elf32-target.h"
/* FreeBSD support. */

View File

@ -4015,6 +4015,8 @@ m32r_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
#define bfd_elf32_bfd_print_private_bfd_data m32r_elf_print_private_bfd_data
#define elf_backend_special_sections m32r_elf_special_sections
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#include "elf32-target.h"
#undef ELF_MAXPAGESIZE

View File

@ -4841,4 +4841,6 @@ elf_m68k_add_symbol_hook (bfd *abfd,
#define elf_backend_rela_normal 1
#define elf_backend_dtrel_excludes_plt 1
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#include "elf32-target.h"

View File

@ -1821,56 +1821,6 @@ 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 function to copy an elf_internal_linux_prpsinfo in host
endian to an elf_external_ppc_linux_prpsinfo32 in target endian. */
static inline void
swap_ppc_linux_prpsinfo32_out (bfd *obfd,
const struct elf_internal_linux_prpsinfo *from,
struct elf_external_ppc_linux_prpsinfo32 *to)
{
bfd_put_8 (obfd, from->pr_state, &to->pr_state);
bfd_put_8 (obfd, from->pr_sname, &to->pr_sname);
bfd_put_8 (obfd, from->pr_zomb, &to->pr_zomb);
bfd_put_8 (obfd, from->pr_nice, &to->pr_nice);
bfd_put_32 (obfd, from->pr_flag, to->pr_flag);
bfd_put_32 (obfd, from->pr_uid, to->pr_uid);
bfd_put_32 (obfd, from->pr_gid, to->pr_gid);
bfd_put_32 (obfd, from->pr_pid, to->pr_pid);
bfd_put_32 (obfd, from->pr_ppid, to->pr_ppid);
bfd_put_32 (obfd, from->pr_pgrp, to->pr_pgrp);
bfd_put_32 (obfd, 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));
}
/* Initialize the ppc_elf_howto_table, so that linear accesses can be done. */
@ -2408,20 +2358,6 @@ 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;
swap_ppc_linux_prpsinfo32_out (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, ...)
{

View File

@ -4219,4 +4219,6 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
#define bfd_elf32_mkobject elf_s390_mkobject
#define elf_backend_object_p elf_s390_object_p
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#include "elf32-target.h"

View File

@ -7308,6 +7308,8 @@ sh_elf_encode_eh_address (bfd *abfd,
#define elf_backend_got_header_size 12
#define elf_backend_dtrel_excludes_plt 1
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#if !defined INCLUDE_SHMEDIA && !defined SH_TARGET_ALREADY_DEFINED
#include "elf32-target.h"

View File

@ -252,6 +252,8 @@ elf32_sparc_add_symbol_hook (bfd * abfd,
#define elf_backend_add_symbol_hook elf32_sparc_add_symbol_hook
#define elf_backend_linux_prpsinfo32_ugid16 TRUE
#include "elf32-target.h"
/* Solaris 2. */

View File

@ -132,6 +132,9 @@
#ifndef elf_backend_always_renumber_dynsyms
#define elf_backend_always_renumber_dynsyms FALSE
#endif
#ifndef elf_backend_linux_prpsinfo32_ugid16
#define elf_backend_linux_prpsinfo32_ugid16 FALSE
#endif
#ifndef elf_backend_stack_align
#define elf_backend_stack_align 16
#endif
@ -895,7 +898,8 @@ static struct elf_backend_data elfNN_bed =
elf_backend_default_execstack,
elf_backend_caches_rawsize,
elf_backend_extern_protected_data,
elf_backend_always_renumber_dynsyms
elf_backend_always_renumber_dynsyms,
elf_backend_linux_prpsinfo32_ugid16
};
/* Forward declaration for use when initialising alternative_target field. */

View File

@ -1,3 +1,8 @@
2017-10-11 Maciej W. Rozycki <macro@imgtec.com>
* ppc-linux-tdep.c (ppc_linux_init_abi): Remove call to
`set_gdbarch_elfcore_write_linux_prpsinfo'.
2017-10-11 Pedro Alves <palves@redhat.com>
* breakpoint.c (reattach_breakpoints): Delete.

View File

@ -60,7 +60,7 @@
#include "parser-defs.h"
#include "user-regs.h"
#include <ctype.h>
#include "elf-bfd.h" /* for elfcore_write_* */
#include "elf-bfd.h"
#include "features/rs6000/powerpc-32l.c"
#include "features/rs6000/powerpc-altivec32l.c"
@ -1772,12 +1772,6 @@ ppc_linux_init_abi (struct gdbarch_info info,
set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
}
/* PPC32 uses a different prpsinfo32 compared to most other Linux
archs. */
if (tdep->wordsize == 4)
set_gdbarch_elfcore_write_linux_prpsinfo (gdbarch,
elfcore_write_ppc_linux_prpsinfo32);
set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
set_gdbarch_iterate_over_regset_sections (gdbarch,
ppc_linux_iterate_over_regset_sections);