Commit 7facdc42 authored by Al Viro's avatar Al Viro
Browse files

[amd64] clean PRSTATUS_SIZE/SET_PR_FPVALID up properly



To get rid of hardcoded size/offset in those macros we need to have
a definition of i386 variant of struct elf_prstatus.  However, we can't
do that in asm/compat.h - the types needed for that are not there and
adding an include of asm/user32.h into asm/compat.h would cause a lot
of mess.

That could be conveniently done in elfcore-compat.h, but currently there
is nowhere to put arch-dependent parts of it - no asm/elfcore-compat.h.
So we introduce a new file (asm/elfcore-compat.h, present on architectures
that have CONFIG_ARCH_HAS_ELFCORE_COMPAT set, currently only on x86),
have it pulled by linux/elfcore-compat.h and move the definitions there.

As a side benefit, we don't need to worry about accidental inclusion of
that file into binfmt_elf.c itself, so we don't need the dance with
COMPAT_PRSTATUS_SIZE, etc. - only fs/compat_binfmt_elf.c will see
that header.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent f2485a2d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1105,6 +1105,9 @@ config HAVE_ARCH_PFN_VALID
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
	bool

config ARCH_HAS_ELFCORE_COMPAT
	bool

source "kernel/gcov/Kconfig"

source "scripts/gcc-plugins/Kconfig"
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,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
+0 −14
Original line number Diff line number Diff line
@@ -159,20 +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 COMPAT_PRSTATUS_SIZE (user_64bit_mode(task_pt_regs(current)) \
	? sizeof(struct compat_elf_prstatus) \
	: 144)
#define COMPAT_SET_PR_FPVALID(S) \
	(*(user_64bit_mode(task_pt_regs(current)) \
	       ? &(S)->pr_fpvalid	\
               : (int *)((void *)(S) + 140)) = 1)

#ifdef CONFIG_X86_X32_ABI
#define COMPAT_USE_64BIT_TIME \
	(!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
+31 −0
Original line number Diff line number Diff line
#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
+0 −8
Original line number Diff line number Diff line
@@ -96,14 +96,6 @@
#define	ELF_EXEC_PAGESIZE	COMPAT_ELF_EXEC_PAGESIZE
#endif

#ifdef	COMPAT_PRSTATUS_SIZE
#define	PRSTATUS_SIZE COMPAT_PRSTATUS_SIZE
#endif

#ifdef	COMPAT_SET_PR_FPVALID
#define	SET_PR_FPVALID(S) COMPAT_SET_PR_FPVALID(S)
#endif

#ifdef	COMPAT_ELF_PLAT_INIT
#undef	ELF_PLAT_INIT
#define	ELF_PLAT_INIT		COMPAT_ELF_PLAT_INIT
Loading