Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 7facdc42 f2485a2d

+46 -29
+3
arch/Kconfig
··· 1105 1105 config ARCH_SUPPORTS_DEBUG_PAGEALLOC 1106 1106 bool 1107 1107 1108 + config ARCH_HAS_ELFCORE_COMPAT 1109 + bool 1110 + 1108 1111 source "kernel/gcov/Kconfig" 1109 1112 1110 1113 source "scripts/gcc-plugins/Kconfig"
+1
arch/x86/Kconfig
··· 31 31 select MODULES_USE_ELF_RELA 32 32 select NEED_DMA_MAP_STATE 33 33 select SWIOTLB 34 + select ARCH_HAS_ELFCORE_COMPAT 34 35 35 36 config FORCE_DYNAMIC_FTRACE 36 37 def_bool y
-14
arch/x86/include/asm/compat.h
··· 159 159 compat_ulong_t __unused5; 160 160 }; 161 161 162 - /* 163 - * The type of struct elf_prstatus.pr_reg in compatible core dumps. 164 - */ 165 - typedef struct user_regs_struct compat_elf_gregset_t; 166 - 167 - /* Full regset -- prstatus on x32, otherwise on ia32 */ 168 - #define COMPAT_PRSTATUS_SIZE (user_64bit_mode(task_pt_regs(current)) \ 169 - ? sizeof(struct compat_elf_prstatus) \ 170 - : 144) 171 - #define COMPAT_SET_PR_FPVALID(S) \ 172 - (*(user_64bit_mode(task_pt_regs(current)) \ 173 - ? &(S)->pr_fpvalid \ 174 - : (int *)((void *)(S) + 140)) = 1) 175 - 176 162 #ifdef CONFIG_X86_X32_ABI 177 163 #define COMPAT_USE_64BIT_TIME \ 178 164 (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
+31
arch/x86/include/asm/elfcore-compat.h
··· 1 + #ifndef _ASM_X86_ELFCORE_COMPAT_H 2 + #define _ASM_X86_ELFCORE_COMPAT_H 3 + 4 + #include <asm/user32.h> 5 + 6 + /* 7 + * On amd64 we have two 32bit ABIs - i386 and x32. The latter 8 + * has bigger registers, so we use it for compat_elf_regset_t. 9 + * The former uses i386_elf_prstatus and PRSTATUS_SIZE/SET_PR_FPVALID 10 + * are used to choose the size and location of ->pr_fpvalid of 11 + * the layout actually used. 12 + */ 13 + typedef struct user_regs_struct compat_elf_gregset_t; 14 + 15 + struct i386_elf_prstatus 16 + { 17 + struct compat_elf_prstatus_common common; 18 + struct user_regs_struct32 pr_reg; 19 + compat_int_t pr_fpvalid; 20 + }; 21 + 22 + #define PRSTATUS_SIZE \ 23 + (user_64bit_mode(task_pt_regs(current)) \ 24 + ? sizeof(struct compat_elf_prstatus) \ 25 + : sizeof(struct i386_elf_prstatus)) 26 + #define SET_PR_FPVALID(S) \ 27 + (*(user_64bit_mode(task_pt_regs(current)) \ 28 + ? &(S)->pr_fpvalid \ 29 + : &((struct i386_elf_prstatus *)(S))->pr_fpvalid) = 1) 30 + 31 + #endif
-8
fs/compat_binfmt_elf.c
··· 96 96 #define ELF_EXEC_PAGESIZE COMPAT_ELF_EXEC_PAGESIZE 97 97 #endif 98 98 99 - #ifdef COMPAT_PRSTATUS_SIZE 100 - #define PRSTATUS_SIZE COMPAT_PRSTATUS_SIZE 101 - #endif 102 - 103 - #ifdef COMPAT_SET_PR_FPVALID 104 - #define SET_PR_FPVALID(S) COMPAT_SET_PR_FPVALID(S) 105 - #endif 106 - 107 99 #ifdef COMPAT_ELF_PLAT_INIT 108 100 #undef ELF_PLAT_INIT 109 101 #define ELF_PLAT_INIT COMPAT_ELF_PLAT_INIT
+11 -7
include/linux/elfcore-compat.h
··· 33 33 struct old_timeval32 pr_cstime; 34 34 }; 35 35 36 - struct compat_elf_prstatus 37 - { 38 - struct compat_elf_prstatus_common common; 39 - compat_elf_gregset_t pr_reg; 40 - compat_int_t pr_fpvalid; 41 - }; 42 - 43 36 struct compat_elf_prpsinfo 44 37 { 45 38 char pr_state; ··· 45 52 compat_pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; 46 53 char pr_fname[16]; 47 54 char pr_psargs[ELF_PRARGSZ]; 55 + }; 56 + 57 + #ifdef CONFIG_ARCH_HAS_ELFCORE_COMPAT 58 + #include <asm/elfcore-compat.h> 59 + #endif 60 + 61 + struct compat_elf_prstatus 62 + { 63 + struct compat_elf_prstatus_common common; 64 + compat_elf_gregset_t pr_reg; 65 + compat_int_t pr_fpvalid; 48 66 }; 49 67 50 68 #endif /* _LINUX_ELFCORE_COMPAT_H */