mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
Merge branch 'work.elf-compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull ELF compat updates from Al Viro: "Sanitizing ELF compat support, especially for triarch architectures: - X32 handling cleaned up - MIPS64 uses compat_binfmt_elf.c both for O32 and N32 now - Kconfig side of things regularized Eventually I hope to have compat_binfmt_elf.c killed, with both native and compat built from fs/binfmt_elf.c, with -DELF_BITS={64,32} passed by kbuild, but that's a separate story - not included here" * 'work.elf-compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: get rid of COMPAT_ELF_EXEC_PAGESIZE compat_binfmt_elf: don't bother with undef of ELF_ARCH Kconfig: regularize selection of CONFIG_BINFMT_ELF mips compat: switch to compat_binfmt_elf.c mips: don't bother with ELF_CORE_EFLAGS mips compat: don't bother with ELF_ET_DYN_BASE mips: KVM_GUEST makes no sense for 64bit builds... mips: kill unused definitions in binfmt_elf[on]32.c mips binfmt_elf*32.c: use elfcore-compat.h x32: make X32, !IA32_EMULATION setups able to execute x32 binaries [amd64] clean PRSTATUS_SIZE/SET_PR_FPVALID up properly elf_prstatus: collect the common part (everything before pr_reg) into a struct binfmt_elf: partially sanitize PRSTATUS_SIZE and SET_PR_FPVALID
This commit is contained in:
commit
591fd30eee
@ -1111,6 +1111,9 @@ config ARCH_SPLIT_ARG64
|
||||
If a 32-bit architecture requires 64-bit arguments to be split into
|
||||
pairs of 32-bit arguments, select this option.
|
||||
|
||||
config ARCH_HAS_ELFCORE_COMPAT
|
||||
bool
|
||||
|
||||
source "kernel/gcov/Kconfig"
|
||||
|
||||
source "scripts/gcc-plugins/Kconfig"
|
||||
|
@ -1213,7 +1213,6 @@ config ARM64_TAGGED_ADDR_ABI
|
||||
menuconfig COMPAT
|
||||
bool "Kernel support for 32-bit EL0"
|
||||
depends on ARM64_4K_PAGES || EXPERT
|
||||
select COMPAT_BINFMT_ELF if BINFMT_ELF
|
||||
select HAVE_UID16
|
||||
select OLD_SIGSUSPEND3
|
||||
select COMPAT_OLD_SIGACTION
|
||||
|
@ -43,7 +43,7 @@ crash_save_this_cpu(void)
|
||||
|
||||
elf_greg_t *dst = (elf_greg_t *)&(prstatus->pr_reg);
|
||||
memset(prstatus, 0, sizeof(*prstatus));
|
||||
prstatus->pr_pid = current->pid;
|
||||
prstatus->common.pr_pid = current->pid;
|
||||
|
||||
ia64_dump_cpu_regs(dst);
|
||||
cfm = dst[43];
|
||||
|
@ -92,6 +92,7 @@ config MIPS
|
||||
select SET_FS
|
||||
select SYSCTL_EXCEPTION_TRACE
|
||||
select VIRT_TO_BUS
|
||||
select ARCH_HAS_ELFCORE_COMPAT
|
||||
|
||||
config MIPS_FIXUP_BIGPHYS_ADDR
|
||||
bool
|
||||
@ -2182,7 +2183,7 @@ endchoice
|
||||
config KVM_GUEST
|
||||
bool "KVM Guest Kernel"
|
||||
depends on CPU_MIPS32_R2
|
||||
depends on BROKEN_ON_SMP
|
||||
depends on !64BIT && BROKEN_ON_SMP
|
||||
help
|
||||
Select this option if building a guest kernel for KVM (Trap & Emulate)
|
||||
mode.
|
||||
@ -3300,11 +3301,6 @@ config MIPS32_N32
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config BINFMT_ELF32
|
||||
bool
|
||||
default y if MIPS32_O32 || MIPS32_N32
|
||||
select ELFCORE
|
||||
|
||||
menu "Power management options"
|
||||
|
||||
config ARCH_HIBERNATION_POSSIBLE
|
||||
|
@ -201,7 +201,6 @@ struct mips_elf_abiflags_v0 {
|
||||
uint32_t flags2;
|
||||
};
|
||||
|
||||
#ifndef ELF_ARCH
|
||||
/* ELF register definitions */
|
||||
#define ELF_NGREG 45
|
||||
#define ELF_NFPREG 33
|
||||
@ -219,7 +218,7 @@ void mips_dump_regs64(u64 *uregs, const struct pt_regs *regs);
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch elfo32_check_arch
|
||||
#define elf_check_arch elf32_check_arch
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
@ -235,7 +234,8 @@ void mips_dump_regs64(u64 *uregs, const struct pt_regs *regs);
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch elfn64_check_arch
|
||||
#define elf_check_arch elf64_check_arch
|
||||
#define compat_elf_check_arch elf32_check_arch
|
||||
|
||||
/*
|
||||
* These are used to set parameters in the core dumps.
|
||||
@ -257,8 +257,6 @@ void mips_dump_regs64(u64 *uregs, const struct pt_regs *regs);
|
||||
#endif
|
||||
#define ELF_ARCH EM_MIPS
|
||||
|
||||
#endif /* !defined(ELF_ARCH) */
|
||||
|
||||
/*
|
||||
* In order to be sure that we don't attempt to execute an O32 binary which
|
||||
* requires 64 bit FP (FR=1) on a system which does not support it we refuse
|
||||
@ -277,9 +275,9 @@ void mips_dump_regs64(u64 *uregs, const struct pt_regs *regs);
|
||||
#define vmcore_elf64_check_arch mips_elf_check_machine
|
||||
|
||||
/*
|
||||
* Return non-zero if HDR identifies an o32 ELF binary.
|
||||
* Return non-zero if HDR identifies an o32 or n32 ELF binary.
|
||||
*/
|
||||
#define elfo32_check_arch(hdr) \
|
||||
#define elf32_check_arch(hdr) \
|
||||
({ \
|
||||
int __res = 1; \
|
||||
struct elfhdr *__h = (hdr); \
|
||||
@ -288,21 +286,26 @@ void mips_dump_regs64(u64 *uregs, const struct pt_regs *regs);
|
||||
__res = 0; \
|
||||
if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
|
||||
__res = 0; \
|
||||
if ((__h->e_flags & EF_MIPS_ABI2) != 0) \
|
||||
__res = 0; \
|
||||
if (((__h->e_flags & EF_MIPS_ABI) != 0) && \
|
||||
((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \
|
||||
__res = 0; \
|
||||
if (__h->e_flags & __MIPS_O32_FP64_MUST_BE_ZERO) \
|
||||
__res = 0; \
|
||||
\
|
||||
if ((__h->e_flags & EF_MIPS_ABI2) != 0) { \
|
||||
if (!IS_ENABLED(CONFIG_MIPS32_N32) || \
|
||||
(__h->e_flags & EF_MIPS_ABI)) \
|
||||
__res = 0; \
|
||||
} else { \
|
||||
if (IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_MIPS32_O32)) \
|
||||
__res = 0; \
|
||||
if (((__h->e_flags & EF_MIPS_ABI) != 0) && \
|
||||
((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \
|
||||
__res = 0; \
|
||||
if (__h->e_flags & __MIPS_O32_FP64_MUST_BE_ZERO) \
|
||||
__res = 0; \
|
||||
} \
|
||||
__res; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Return non-zero if HDR identifies an n64 ELF binary.
|
||||
*/
|
||||
#define elfn64_check_arch(hdr) \
|
||||
#define elf64_check_arch(hdr) \
|
||||
({ \
|
||||
int __res = 1; \
|
||||
struct elfhdr *__h = (hdr); \
|
||||
@ -315,25 +318,6 @@ void mips_dump_regs64(u64 *uregs, const struct pt_regs *regs);
|
||||
__res; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Return non-zero if HDR identifies an n32 ELF binary.
|
||||
*/
|
||||
#define elfn32_check_arch(hdr) \
|
||||
({ \
|
||||
int __res = 1; \
|
||||
struct elfhdr *__h = (hdr); \
|
||||
\
|
||||
if (!mips_elf_check_machine(__h)) \
|
||||
__res = 0; \
|
||||
if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
|
||||
__res = 0; \
|
||||
if (((__h->e_flags & EF_MIPS_ABI2) == 0) || \
|
||||
((__h->e_flags & EF_MIPS_ABI) != 0)) \
|
||||
__res = 0; \
|
||||
\
|
||||
__res; \
|
||||
})
|
||||
|
||||
struct mips_abi;
|
||||
|
||||
extern struct mips_abi mips_abi;
|
||||
@ -469,9 +453,7 @@ extern const char *__elf_base_platform;
|
||||
the loader. We need to make sure that it is out of the way of the program
|
||||
that it will "exec", and that there is sufficient room for the brk. */
|
||||
|
||||
#ifndef ELF_ET_DYN_BASE
|
||||
#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
|
||||
#endif
|
||||
|
||||
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
|
||||
#define ARCH_DLINFO \
|
||||
|
29
arch/mips/include/asm/elfcore-compat.h
Normal file
29
arch/mips/include/asm/elfcore-compat.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef _ASM_MIPS_ELFCORE_COMPAT_H
|
||||
#define _ASM_MIPS_ELFCORE_COMPAT_H
|
||||
|
||||
/*
|
||||
* On mips we have two 32bit ABIs - o32 and n32. The latter
|
||||
* has bigger registers, so we use it for compat_elf_regset_t.
|
||||
* The former uses o32_elf_prstatus and PRSTATUS_SIZE/SET_PR_FPVALID
|
||||
* are used to choose the size and location of ->pr_fpvalid of
|
||||
* the layout actually used.
|
||||
*/
|
||||
typedef elf_gregset_t compat_elf_gregset_t;
|
||||
|
||||
struct o32_elf_prstatus
|
||||
{
|
||||
struct compat_elf_prstatus_common common;
|
||||
unsigned int pr_reg[ELF_NGREG];
|
||||
compat_int_t pr_fpvalid;
|
||||
};
|
||||
|
||||
#define PRSTATUS_SIZE \
|
||||
(!test_thread_flag(TIF_32BIT_REGS) \
|
||||
? sizeof(struct compat_elf_prstatus) \
|
||||
: sizeof(struct o32_elf_prstatus))
|
||||
#define SET_PR_FPVALID(S) \
|
||||
(*(!test_thread_flag(TIF_32BIT_REGS) \
|
||||
? &(S)->pr_fpvalid \
|
||||
: &((struct o32_elf_prstatus *)(S))->pr_fpvalid) = 1)
|
||||
|
||||
#endif
|
@ -80,8 +80,8 @@ obj-$(CONFIG_KPROBES) += kprobes.o
|
||||
obj-$(CONFIG_32BIT) += scall32-o32.o
|
||||
obj-$(CONFIG_64BIT) += scall64-n64.o
|
||||
obj-$(CONFIG_MIPS32_COMPAT) += linux32.o ptrace32.o signal32.o
|
||||
obj-$(CONFIG_MIPS32_N32) += binfmt_elfn32.o scall64-n32.o signal_n32.o
|
||||
obj-$(CONFIG_MIPS32_O32) += binfmt_elfo32.o scall64-o32.o signal_o32.o
|
||||
obj-$(CONFIG_MIPS32_N32) += scall64-n32.o signal_n32.o
|
||||
obj-$(CONFIG_MIPS32_O32) += scall64-o32.o signal_o32.o
|
||||
|
||||
obj-$(CONFIG_KGDB) += kgdb.o
|
||||
obj-$(CONFIG_PROC_FS) += proc.o
|
||||
|
@ -1,113 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Support for n32 Linux/MIPS ELF binaries.
|
||||
* Author: Ralf Baechle (ralf@linux-mips.org)
|
||||
*
|
||||
* Copyright (C) 1999, 2001 Ralf Baechle
|
||||
* Copyright (C) 1999, 2001 Silicon Graphics, Inc.
|
||||
*
|
||||
* Heavily inspired by the 32-bit Sparc compat code which is
|
||||
* Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
|
||||
* Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz)
|
||||
*/
|
||||
|
||||
#define ELF_ARCH EM_MIPS
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#ifdef __MIPSEB__
|
||||
#define ELF_DATA ELFDATA2MSB;
|
||||
#else /* __MIPSEL__ */
|
||||
#define ELF_DATA ELFDATA2LSB;
|
||||
#endif
|
||||
|
||||
/* ELF register definitions */
|
||||
#define ELF_NGREG 45
|
||||
#define ELF_NFPREG 33
|
||||
|
||||
typedef unsigned long elf_greg_t;
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef double elf_fpreg_t;
|
||||
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch elfn32_check_arch
|
||||
|
||||
#define TASK32_SIZE 0x7fff8000UL
|
||||
#undef ELF_ET_DYN_BASE
|
||||
#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <linux/elfcore.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/math64.h>
|
||||
|
||||
#define elf_prstatus elf_prstatus32
|
||||
struct elf_prstatus32
|
||||
{
|
||||
struct elf_siginfo pr_info; /* Info associated with signal */
|
||||
short pr_cursig; /* Current signal */
|
||||
unsigned int pr_sigpend; /* Set of pending signals */
|
||||
unsigned int pr_sighold; /* Set of held signals */
|
||||
pid_t pr_pid;
|
||||
pid_t pr_ppid;
|
||||
pid_t pr_pgrp;
|
||||
pid_t pr_sid;
|
||||
struct old_timeval32 pr_utime; /* User time */
|
||||
struct old_timeval32 pr_stime; /* System time */
|
||||
struct old_timeval32 pr_cutime;/* Cumulative user time */
|
||||
struct old_timeval32 pr_cstime;/* Cumulative system time */
|
||||
elf_gregset_t pr_reg; /* GP registers */
|
||||
int pr_fpvalid; /* True if math co-processor being used. */
|
||||
};
|
||||
|
||||
#define elf_prpsinfo elf_prpsinfo32
|
||||
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 */
|
||||
__kernel_uid_t pr_uid;
|
||||
__kernel_gid_t pr_gid;
|
||||
pid_t 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 */
|
||||
};
|
||||
|
||||
#define elf_caddr_t u32
|
||||
#define init_elf_binfmt init_elfn32_binfmt
|
||||
|
||||
#define jiffies_to_timeval jiffies_to_old_timeval32
|
||||
static __inline__ void
|
||||
jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value)
|
||||
{
|
||||
/*
|
||||
* Convert jiffies to nanoseconds and separate with
|
||||
* one divide.
|
||||
*/
|
||||
u64 nsec = (u64)jiffies * TICK_NSEC;
|
||||
u32 rem;
|
||||
value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
|
||||
value->tv_usec = rem / NSEC_PER_USEC;
|
||||
}
|
||||
|
||||
#define ELF_CORE_EFLAGS EF_MIPS_ABI2
|
||||
|
||||
#undef TASK_SIZE
|
||||
#define TASK_SIZE TASK_SIZE32
|
||||
|
||||
#undef ns_to_kernel_old_timeval
|
||||
#define ns_to_kernel_old_timeval ns_to_old_timeval32
|
||||
|
||||
/*
|
||||
* Some data types as stored in coredump.
|
||||
*/
|
||||
#define user_long_t compat_long_t
|
||||
#define user_siginfo_t compat_siginfo_t
|
||||
#define copy_siginfo_to_external copy_siginfo_to_external32
|
||||
|
||||
#include "../../../fs/binfmt_elf.c"
|
@ -1,116 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Support for o32 Linux/MIPS ELF binaries.
|
||||
* Author: Ralf Baechle (ralf@linux-mips.org)
|
||||
*
|
||||
* Copyright (C) 1999, 2001 Ralf Baechle
|
||||
* Copyright (C) 1999, 2001 Silicon Graphics, Inc.
|
||||
*
|
||||
* Heavily inspired by the 32-bit Sparc compat code which is
|
||||
* Copyright (C) 1995, 1996, 1997, 1998 David S. Miller (davem@redhat.com)
|
||||
* Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek (jj@ultra.linux.cz)
|
||||
*/
|
||||
|
||||
#define ELF_ARCH EM_MIPS
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#ifdef __MIPSEB__
|
||||
#define ELF_DATA ELFDATA2MSB;
|
||||
#else /* __MIPSEL__ */
|
||||
#define ELF_DATA ELFDATA2LSB;
|
||||
#endif
|
||||
|
||||
/* ELF register definitions */
|
||||
#define ELF_NGREG 45
|
||||
#define ELF_NFPREG 33
|
||||
|
||||
typedef unsigned int elf_greg_t;
|
||||
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
||||
|
||||
typedef double elf_fpreg_t;
|
||||
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
|
||||
|
||||
/*
|
||||
* This is used to ensure we don't load something for the wrong architecture.
|
||||
*/
|
||||
#define elf_check_arch elfo32_check_arch
|
||||
|
||||
#ifdef CONFIG_KVM_GUEST
|
||||
#define TASK32_SIZE 0x3fff8000UL
|
||||
#else
|
||||
#define TASK32_SIZE 0x7fff8000UL
|
||||
#endif
|
||||
#undef ELF_ET_DYN_BASE
|
||||
#define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
|
||||
|
||||
#include <asm/processor.h>
|
||||
|
||||
#include <linux/elfcore.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/math64.h>
|
||||
|
||||
#define elf_prstatus elf_prstatus32
|
||||
struct elf_prstatus32
|
||||
{
|
||||
struct elf_siginfo pr_info; /* Info associated with signal */
|
||||
short pr_cursig; /* Current signal */
|
||||
unsigned int pr_sigpend; /* Set of pending signals */
|
||||
unsigned int pr_sighold; /* Set of held signals */
|
||||
pid_t pr_pid;
|
||||
pid_t pr_ppid;
|
||||
pid_t pr_pgrp;
|
||||
pid_t pr_sid;
|
||||
struct old_timeval32 pr_utime; /* User time */
|
||||
struct old_timeval32 pr_stime; /* System time */
|
||||
struct old_timeval32 pr_cutime;/* Cumulative user time */
|
||||
struct old_timeval32 pr_cstime;/* Cumulative system time */
|
||||
elf_gregset_t pr_reg; /* GP registers */
|
||||
int pr_fpvalid; /* True if math co-processor being used. */
|
||||
};
|
||||
|
||||
#define elf_prpsinfo elf_prpsinfo32
|
||||
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 */
|
||||
__kernel_uid_t pr_uid;
|
||||
__kernel_gid_t pr_gid;
|
||||
pid_t 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 */
|
||||
};
|
||||
|
||||
#define elf_caddr_t u32
|
||||
#define init_elf_binfmt init_elf32_binfmt
|
||||
|
||||
#define jiffies_to_timeval jiffies_to_old_timeval32
|
||||
static inline void
|
||||
jiffies_to_old_timeval32(unsigned long jiffies, struct old_timeval32 *value)
|
||||
{
|
||||
/*
|
||||
* Convert jiffies to nanoseconds and separate with
|
||||
* one divide.
|
||||
*/
|
||||
u64 nsec = (u64)jiffies * TICK_NSEC;
|
||||
u32 rem;
|
||||
value->tv_sec = div_u64_rem(nsec, NSEC_PER_SEC, &rem);
|
||||
value->tv_usec = rem / NSEC_PER_USEC;
|
||||
}
|
||||
|
||||
#undef TASK_SIZE
|
||||
#define TASK_SIZE TASK_SIZE32
|
||||
|
||||
#undef ns_to_kernel_old_timeval
|
||||
#define ns_to_kernel_old_timeval ns_to_old_timeval32
|
||||
|
||||
/*
|
||||
* Some data types as stored in coredump.
|
||||
*/
|
||||
#define user_long_t compat_long_t
|
||||
#define user_siginfo_t compat_siginfo_t
|
||||
#define copy_siginfo_to_external copy_siginfo_to_external32
|
||||
|
||||
#include "../../../fs/binfmt_elf.c"
|
@ -20,7 +20,7 @@
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/war.h>
|
||||
|
||||
#ifndef CONFIG_BINFMT_ELF32
|
||||
#ifndef CONFIG_MIPS32_COMPAT
|
||||
/* Neither O32 nor N32, so define handle_sys here */
|
||||
#define handle_sys64 handle_sys
|
||||
#endif
|
||||
|
@ -335,7 +335,6 @@ source "kernel/Kconfig.hz"
|
||||
config COMPAT
|
||||
def_bool y
|
||||
depends on 64BIT
|
||||
select COMPAT_BINFMT_ELF if BINFMT_ELF
|
||||
|
||||
config SYSVIPC_COMPAT
|
||||
def_bool y
|
||||
|
@ -282,7 +282,6 @@ config COMPAT
|
||||
bool "Enable support for 32bit binaries"
|
||||
depends on PPC64
|
||||
default y if !CPU_LITTLE_ENDIAN
|
||||
select COMPAT_BINFMT_ELF
|
||||
select ARCH_WANT_OLD_COMPAT_IPC
|
||||
select COMPAT_OLD_SIGACTION
|
||||
|
||||
|
@ -119,8 +119,8 @@ static void fill_prstatus(struct elf_prstatus *prstatus, int pir,
|
||||
* As a PIR value could also be '0', add an offset of '100'
|
||||
* to every PIR to avoid misinterpretations in GDB.
|
||||
*/
|
||||
prstatus->pr_pid = cpu_to_be32(100 + pir);
|
||||
prstatus->pr_ppid = cpu_to_be32(1);
|
||||
prstatus->common.pr_pid = cpu_to_be32(100 + pir);
|
||||
prstatus->common.pr_ppid = cpu_to_be32(1);
|
||||
|
||||
/*
|
||||
* Indicate SIGUSR1 for crash initiated from kernel.
|
||||
@ -130,7 +130,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, int pir,
|
||||
short sig;
|
||||
|
||||
sig = kernel_initiated ? SIGUSR1 : SIGTERM;
|
||||
prstatus->pr_cursig = cpu_to_be16(sig);
|
||||
prstatus->common.pr_cursig = cpu_to_be16(sig);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,7 +426,6 @@ config 64BIT
|
||||
config COMPAT
|
||||
def_bool y
|
||||
prompt "Kernel support for 31 bit emulation"
|
||||
select COMPAT_BINFMT_ELF if BINFMT_ELF
|
||||
select ARCH_WANT_OLD_COMPAT_IPC
|
||||
select COMPAT_OLD_SIGACTION
|
||||
select HAVE_UID16
|
||||
|
@ -365,7 +365,7 @@ static void *fill_cpu_elf_notes(void *ptr, int cpu, struct save_area *sa)
|
||||
memcpy(&nt_prstatus.pr_reg.gprs, sa->gprs, sizeof(sa->gprs));
|
||||
memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw));
|
||||
memcpy(&nt_prstatus.pr_reg.acrs, sa->acrs, sizeof(sa->acrs));
|
||||
nt_prstatus.pr_pid = cpu;
|
||||
nt_prstatus.common.pr_pid = cpu;
|
||||
/* Prepare fpregset (floating point) note */
|
||||
memset(&nt_fpregset, 0, sizeof(nt_fpregset));
|
||||
memcpy(&nt_fpregset.fpc, &sa->fpc, sizeof(sa->fpc));
|
||||
|
@ -494,7 +494,6 @@ config COMPAT
|
||||
bool
|
||||
depends on SPARC64
|
||||
default y
|
||||
select COMPAT_BINFMT_ELF
|
||||
select HAVE_UID16
|
||||
select ARCH_WANT_OLD_COMPAT_IPC
|
||||
select COMPAT_OLD_SIGACTION
|
||||
|
@ -32,6 +32,7 @@ config X86_64
|
||||
select MODULES_USE_ELF_RELA
|
||||
select NEED_DMA_MAP_STATE
|
||||
select SWIOTLB
|
||||
select ARCH_HAS_ELFCORE_COMPAT
|
||||
|
||||
config FORCE_DYNAMIC_FTRACE
|
||||
def_bool y
|
||||
@ -2860,7 +2861,6 @@ config IA32_EMULATION
|
||||
depends on X86_64
|
||||
select ARCH_WANT_OLD_COMPAT_IPC
|
||||
select BINFMT_ELF
|
||||
select COMPAT_BINFMT_ELF
|
||||
select COMPAT_OLD_SIGACTION
|
||||
help
|
||||
Include code to run legacy 32-bit programs under a
|
||||
|
@ -159,17 +159,6 @@ struct compat_shmid64_ds {
|
||||
compat_ulong_t __unused5;
|
||||
};
|
||||
|
||||
/*
|
||||
* The type of struct elf_prstatus.pr_reg in compatible core dumps.
|
||||
*/
|
||||
typedef struct user_regs_struct compat_elf_gregset_t;
|
||||
|
||||
/* Full regset -- prstatus on x32, otherwise on ia32 */
|
||||
#define PRSTATUS_SIZE(S, R) (R != sizeof(S.pr_reg) ? 144 : 296)
|
||||
#define SET_PR_FPVALID(S, V, R) \
|
||||
do { *(int *) (((void *) &((S)->pr_reg)) + R) = (V); } \
|
||||
while (0)
|
||||
|
||||
#ifdef CONFIG_X86_X32_ABI
|
||||
#define COMPAT_USE_64BIT_TIME \
|
||||
(!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
|
||||
|
@ -364,7 +364,7 @@ do { \
|
||||
#define COMPAT_ARCH_DLINFO \
|
||||
if (exec->e_machine == EM_X86_64) \
|
||||
ARCH_DLINFO_X32; \
|
||||
else \
|
||||
else if (IS_ENABLED(CONFIG_IA32_EMULATION)) \
|
||||
ARCH_DLINFO_IA32
|
||||
|
||||
#define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
|
||||
|
31
arch/x86/include/asm/elfcore-compat.h
Normal file
31
arch/x86/include/asm/elfcore-compat.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef _ASM_X86_ELFCORE_COMPAT_H
|
||||
#define _ASM_X86_ELFCORE_COMPAT_H
|
||||
|
||||
#include <asm/user32.h>
|
||||
|
||||
/*
|
||||
* On amd64 we have two 32bit ABIs - i386 and x32. The latter
|
||||
* has bigger registers, so we use it for compat_elf_regset_t.
|
||||
* The former uses i386_elf_prstatus and PRSTATUS_SIZE/SET_PR_FPVALID
|
||||
* are used to choose the size and location of ->pr_fpvalid of
|
||||
* the layout actually used.
|
||||
*/
|
||||
typedef struct user_regs_struct compat_elf_gregset_t;
|
||||
|
||||
struct i386_elf_prstatus
|
||||
{
|
||||
struct compat_elf_prstatus_common common;
|
||||
struct user_regs_struct32 pr_reg;
|
||||
compat_int_t pr_fpvalid;
|
||||
};
|
||||
|
||||
#define PRSTATUS_SIZE \
|
||||
(user_64bit_mode(task_pt_regs(current)) \
|
||||
? sizeof(struct compat_elf_prstatus) \
|
||||
: sizeof(struct i386_elf_prstatus))
|
||||
#define SET_PR_FPVALID(S) \
|
||||
(*(user_64bit_mode(task_pt_regs(current)) \
|
||||
? &(S)->pr_fpvalid \
|
||||
: &((struct i386_elf_prstatus *)(S))->pr_fpvalid) = 1)
|
||||
|
||||
#endif
|
@ -29,7 +29,7 @@ config BINFMT_ELF
|
||||
latest version).
|
||||
|
||||
config COMPAT_BINFMT_ELF
|
||||
bool
|
||||
def_bool y
|
||||
depends on COMPAT && BINFMT_ELF
|
||||
select ELFCORE
|
||||
|
||||
|
@ -1495,7 +1495,7 @@ static void fill_note(struct memelfnote *note, const char *name, int type,
|
||||
* fill up all the fields in prstatus from the given task struct, except
|
||||
* registers which need to be filled up separately.
|
||||
*/
|
||||
static void fill_prstatus(struct elf_prstatus *prstatus,
|
||||
static void fill_prstatus(struct elf_prstatus_common *prstatus,
|
||||
struct task_struct *p, long signr)
|
||||
{
|
||||
prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
|
||||
@ -1717,11 +1717,11 @@ static void do_thread_regset_writeback(struct task_struct *task,
|
||||
}
|
||||
|
||||
#ifndef PRSTATUS_SIZE
|
||||
#define PRSTATUS_SIZE(S, R) sizeof(S)
|
||||
#define PRSTATUS_SIZE sizeof(struct elf_prstatus)
|
||||
#endif
|
||||
|
||||
#ifndef SET_PR_FPVALID
|
||||
#define SET_PR_FPVALID(S, V, R) ((S)->pr_fpvalid = (V))
|
||||
#define SET_PR_FPVALID(S) ((S)->pr_fpvalid = 1)
|
||||
#endif
|
||||
|
||||
static int fill_thread_core_info(struct elf_thread_core_info *t,
|
||||
@ -1729,7 +1729,6 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
|
||||
long signr, size_t *total)
|
||||
{
|
||||
unsigned int i;
|
||||
int regset0_size;
|
||||
|
||||
/*
|
||||
* NT_PRSTATUS is the one special case, because the regset data
|
||||
@ -1737,14 +1736,12 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
|
||||
* than being the whole note contents. We fill the reset in here.
|
||||
* We assume that regset 0 is NT_PRSTATUS.
|
||||
*/
|
||||
fill_prstatus(&t->prstatus, t->task, signr);
|
||||
regset0_size = regset_get(t->task, &view->regsets[0],
|
||||
fill_prstatus(&t->prstatus.common, t->task, signr);
|
||||
regset_get(t->task, &view->regsets[0],
|
||||
sizeof(t->prstatus.pr_reg), &t->prstatus.pr_reg);
|
||||
if (regset0_size < 0)
|
||||
return 0;
|
||||
|
||||
fill_note(&t->notes[0], "CORE", NT_PRSTATUS,
|
||||
PRSTATUS_SIZE(t->prstatus, regset0_size), &t->prstatus);
|
||||
PRSTATUS_SIZE, &t->prstatus);
|
||||
*total += notesize(&t->notes[0]);
|
||||
|
||||
do_thread_regset_writeback(t->task, &view->regsets[0]);
|
||||
@ -1772,7 +1769,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
|
||||
continue;
|
||||
|
||||
if (is_fpreg)
|
||||
SET_PR_FPVALID(&t->prstatus, 1, regset0_size);
|
||||
SET_PR_FPVALID(&t->prstatus);
|
||||
|
||||
fill_note(&t->notes[i], is_fpreg ? "CORE" : "LINUX",
|
||||
note_type, ret, data);
|
||||
@ -1961,7 +1958,7 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
|
||||
struct task_struct *p = t->thread;
|
||||
t->num_notes = 0;
|
||||
|
||||
fill_prstatus(&t->prstatus, p, signr);
|
||||
fill_prstatus(&t->prstatus.common, p, signr);
|
||||
elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
|
||||
|
||||
fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
|
||||
@ -2040,7 +2037,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
|
||||
}
|
||||
/* now collect the dump for the current */
|
||||
memset(info->prstatus, 0, sizeof(*info->prstatus));
|
||||
fill_prstatus(info->prstatus, current, siginfo->si_signo);
|
||||
fill_prstatus(&info->prstatus->common, current, siginfo->si_signo);
|
||||
elf_core_copy_regs(&info->prstatus->pr_reg, regs);
|
||||
|
||||
/* Set up header */
|
||||
|
@ -1191,18 +1191,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
|
||||
|
||||
struct elf_prstatus_fdpic
|
||||
{
|
||||
struct elf_siginfo pr_info; /* Info associated with signal */
|
||||
short pr_cursig; /* Current signal */
|
||||
unsigned long pr_sigpend; /* Set of pending signals */
|
||||
unsigned long pr_sighold; /* Set of held signals */
|
||||
pid_t pr_pid;
|
||||
pid_t pr_ppid;
|
||||
pid_t pr_pgrp;
|
||||
pid_t pr_sid;
|
||||
struct __kernel_old_timeval pr_utime; /* User time */
|
||||
struct __kernel_old_timeval pr_stime; /* System time */
|
||||
struct __kernel_old_timeval pr_cutime; /* Cumulative user time */
|
||||
struct __kernel_old_timeval pr_cstime; /* Cumulative system time */
|
||||
struct elf_prstatus_common common;
|
||||
elf_gregset_t pr_reg; /* GP registers */
|
||||
/* When using FDPIC, the loadmap addresses need to be communicated
|
||||
* to GDB in order for GDB to do the necessary relocations. The
|
||||
@ -1301,7 +1290,7 @@ static inline void fill_note(struct memelfnote *note, const char *name, int type
|
||||
* fill up all the fields in prstatus from the given task struct, except
|
||||
* registers which need to be filled up separately.
|
||||
*/
|
||||
static void fill_prstatus(struct elf_prstatus_fdpic *prstatus,
|
||||
static void fill_prstatus(struct elf_prstatus_common *prstatus,
|
||||
struct task_struct *p, long signr)
|
||||
{
|
||||
prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
|
||||
@ -1332,9 +1321,6 @@ static void fill_prstatus(struct elf_prstatus_fdpic *prstatus,
|
||||
}
|
||||
prstatus->pr_cutime = ns_to_kernel_old_timeval(p->signal->cutime);
|
||||
prstatus->pr_cstime = ns_to_kernel_old_timeval(p->signal->cstime);
|
||||
|
||||
prstatus->pr_exec_fdpic_loadmap = p->mm->context.exec_fdpic_loadmap;
|
||||
prstatus->pr_interp_fdpic_loadmap = p->mm->context.interp_fdpic_loadmap;
|
||||
}
|
||||
|
||||
static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
||||
@ -1405,7 +1391,9 @@ static struct elf_thread_status *elf_dump_thread_status(long signr, struct task_
|
||||
if (!t)
|
||||
return t;
|
||||
|
||||
fill_prstatus(&t->prstatus, p, signr);
|
||||
fill_prstatus(&t->prstatus.common, p, signr);
|
||||
t->prstatus.pr_exec_fdpic_loadmap = p->mm->context.exec_fdpic_loadmap;
|
||||
t->prstatus.pr_interp_fdpic_loadmap = p->mm->context.interp_fdpic_loadmap;
|
||||
regset_get(p, &view->regsets[0],
|
||||
sizeof(t->prstatus.pr_reg), &t->prstatus.pr_reg);
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
* which requires asm/elf.h to define compat_elf_gregset_t et al.
|
||||
*/
|
||||
#define elf_prstatus compat_elf_prstatus
|
||||
#define elf_prstatus_common compat_elf_prstatus_common
|
||||
#define elf_prpsinfo compat_elf_prpsinfo
|
||||
|
||||
#undef ns_to_kernel_old_timeval
|
||||
@ -61,7 +62,6 @@
|
||||
* differ from the native ones, or omitted when they match.
|
||||
*/
|
||||
|
||||
#undef ELF_ARCH
|
||||
#undef elf_check_arch
|
||||
#define elf_check_arch compat_elf_check_arch
|
||||
|
||||
@ -90,11 +90,6 @@
|
||||
#define ELF_ET_DYN_BASE COMPAT_ELF_ET_DYN_BASE
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_ELF_EXEC_PAGESIZE
|
||||
#undef ELF_EXEC_PAGESIZE
|
||||
#define ELF_EXEC_PAGESIZE COMPAT_ELF_EXEC_PAGESIZE
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_ELF_PLAT_INIT
|
||||
#undef ELF_PLAT_INIT
|
||||
#define ELF_PLAT_INIT COMPAT_ELF_PLAT_INIT
|
||||
|
@ -17,7 +17,7 @@ struct compat_elf_siginfo
|
||||
compat_int_t si_errno;
|
||||
};
|
||||
|
||||
struct compat_elf_prstatus
|
||||
struct compat_elf_prstatus_common
|
||||
{
|
||||
struct compat_elf_siginfo pr_info;
|
||||
short pr_cursig;
|
||||
@ -31,8 +31,6 @@ struct compat_elf_prstatus
|
||||
struct old_timeval32 pr_stime;
|
||||
struct old_timeval32 pr_cutime;
|
||||
struct old_timeval32 pr_cstime;
|
||||
compat_elf_gregset_t pr_reg;
|
||||
compat_int_t pr_fpvalid;
|
||||
};
|
||||
|
||||
struct compat_elf_prpsinfo
|
||||
@ -49,4 +47,15 @@ struct compat_elf_prpsinfo
|
||||
char pr_psargs[ELF_PRARGSZ];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ARCH_HAS_ELFCORE_COMPAT
|
||||
#include <asm/elfcore-compat.h>
|
||||
#endif
|
||||
|
||||
struct compat_elf_prstatus
|
||||
{
|
||||
struct compat_elf_prstatus_common common;
|
||||
compat_elf_gregset_t pr_reg;
|
||||
compat_int_t pr_fpvalid;
|
||||
};
|
||||
|
||||
#endif /* _LINUX_ELFCORE_COMPAT_H */
|
||||
|
@ -29,7 +29,7 @@ struct elf_siginfo
|
||||
* the SVR4 structure, but more Linuxy, with things that Linux does
|
||||
* not support and which gdb doesn't really use excluded.
|
||||
*/
|
||||
struct elf_prstatus
|
||||
struct elf_prstatus_common
|
||||
{
|
||||
struct elf_siginfo pr_info; /* Info associated with signal */
|
||||
short pr_cursig; /* Current signal */
|
||||
@ -43,6 +43,11 @@ struct elf_prstatus
|
||||
struct __kernel_old_timeval pr_stime; /* System time */
|
||||
struct __kernel_old_timeval pr_cutime; /* Cumulative user time */
|
||||
struct __kernel_old_timeval pr_cstime; /* Cumulative system time */
|
||||
};
|
||||
|
||||
struct elf_prstatus
|
||||
{
|
||||
struct elf_prstatus_common common;
|
||||
elf_gregset_t pr_reg; /* GP registers */
|
||||
int pr_fpvalid; /* True if math co-processor being used. */
|
||||
};
|
||||
|
@ -1076,7 +1076,7 @@ void crash_save_cpu(struct pt_regs *regs, int cpu)
|
||||
if (!buf)
|
||||
return;
|
||||
memset(&prstatus, 0, sizeof(prstatus));
|
||||
prstatus.pr_pid = current->pid;
|
||||
prstatus.common.pr_pid = current->pid;
|
||||
elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
|
||||
buf = append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
|
||||
&prstatus, sizeof(prstatus));
|
||||
|
Loading…
Reference in New Issue
Block a user