parisc: Switch to generic COMPAT_BINFMT_ELF
authorHelge Deller <deller@gmx.de>
Wed, 11 Apr 2018 07:09:53 +0000 (09:09 +0200)
committerHelge Deller <deller@gmx.de>
Wed, 11 Apr 2018 09:40:35 +0000 (11:40 +0200)
Drop our own compat binfmt implementation in
arch/parisc/kernel/binfmt_elf32.c in favour of the generic
implementation with CONFIG_COMPAT_BINFMT_ELF.

While cleaning up the dependencies, I noticed that ELF_PLATFORM was strangely
defined: On a 32-bit kernel, it was defined to "PARISC", while when running in
compat mode on a 64-bit kernel it was defined to "PARISC32". Since it doesn't
seem to be used in glibc yet, it's now defined in both cases to "PARISC". In
any case, it can be distinguished because it's either a 32-bit or a 64-bit ELF
file.

Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/Kconfig
arch/parisc/include/asm/compat.h
arch/parisc/include/asm/elf.h
arch/parisc/kernel/binfmt_elf32.c [deleted file]

index 7e0bb9836b58463acdd2c1a39764bfc0b6d0f3a8..fc5a574c348236e1695acdf55a33f61e9f9a292e 100644 (file)
@@ -338,6 +338,7 @@ source "mm/Kconfig"
 config COMPAT
        def_bool y
        depends on 64BIT
+       select COMPAT_BINFMT_ELF if BINFMT_ELF
 
 config SYSVIPC_COMPAT
        def_bool y
index c22db5323244668c5d9e51ad3f7d808c36f4d3cd..57b8b2a2fd4e0b0bb6fe6e5ea2279e525e986e78 100644 (file)
@@ -192,6 +192,12 @@ struct compat_shmid64_ds {
        compat_ulong_t __unused6;
 };
 
+/*
+ * The type of struct elf_prstatus.pr_reg in compatible core dumps.
+ */
+#define COMPAT_ELF_NGREG 80
+typedef compat_ulong_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
+
 /*
  * A pointer passed in from user mode. This should not
  * be used for syscall parameters, just declare them
index 382d75a2ee4f2fcdedca2e9f814af7ecf1ac9f65..f019d3ec0c1cd81f7361f30ddcf6af7b3f3bb9e0 100644 (file)
@@ -6,7 +6,7 @@
  * ELF register definitions..
  */
 
-#include <asm/ptrace.h>
+#include <linux/types.h>
 
 #define EM_PARISC 15
 
@@ -169,16 +169,12 @@ typedef struct elf64_fdesc {
        __u64   gp;
 } Elf64_Fdesc;
 
-#ifdef __KERNEL__
-
 #ifdef CONFIG_64BIT
 #define Elf_Fdesc      Elf64_Fdesc
 #else
 #define Elf_Fdesc      Elf32_Fdesc
 #endif /*CONFIG_64BIT*/
 
-#endif /*__KERNEL__*/
-
 /* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
 
 #define PT_HP_TLS              (PT_LOOS + 0x0)
@@ -212,45 +208,45 @@ typedef struct elf64_fdesc {
 #define PF_HP_LAZYSWAP         0x04000000
 #define PF_HP_SBP              0x08000000
 
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization.  This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ */
+
+#define ELF_PLATFORM  ("PARISC")
+
 /*
  * The following definitions are those for 32-bit ELF binaries on a 32-bit
  * kernel and for 64-bit binaries on a 64-bit kernel.  To run 32-bit binaries
- * on a 64-bit kernel, arch/parisc/kernel/binfmt_elf32.c defines these
- * macros appropriately and then #includes binfmt_elf.c, which then includes
- * this file.
+ * on a 64-bit kernel, fs/compat_binfmt_elf.c defines ELF_CLASS and then
+ * #includes binfmt_elf.c, which then includes this file.
  */
 #ifndef ELF_CLASS
 
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- *
- * Note that this header file is used by default in fs/binfmt_elf.c. So
- * the following macros are for the default case. However, for the 64
- * bit kernel we also support 32 bit parisc binaries. To do that
- * arch/parisc/kernel/binfmt_elf32.c defines its own set of these
- * macros, and then it includes fs/binfmt_elf.c to provide an alternate
- * elf binary handler for 32 bit binaries (on the 64 bit kernel).
- */
 #ifdef CONFIG_64BIT
-#define ELF_CLASS   ELFCLASS64
+#define ELF_CLASS      ELFCLASS64
 #else
 #define ELF_CLASS      ELFCLASS32
 #endif
 
 typedef unsigned long elf_greg_t;
 
-/*
- * This yields a string that ld.so will use to load implementation
- * specific libraries for optimization.  This is more specific in
- * intent than poking at uname or /proc/cpuinfo.
- */
-
-#define ELF_PLATFORM  ("PARISC\0")
-
 #define SET_PERSONALITY(ex) \
+({     \
        set_personality((current->personality & ~PER_MASK) | PER_LINUX); \
        current->thread.map_base = DEFAULT_MAP_BASE; \
-       current->thread.task_size = DEFAULT_TASK_SIZE \
+       current->thread.task_size = DEFAULT_TASK_SIZE; \
+ })
+
+#endif /* ! ELF_CLASS */
+
+#define COMPAT_SET_PERSONALITY(ex) \
+({     \
+       set_thread_flag(TIF_32BIT); \
+       current->thread.map_base = DEFAULT_MAP_BASE32; \
+       current->thread.task_size = DEFAULT_TASK_SIZE32; \
+ })
 
 /*
  * Fill in general registers in a core dump.  This saves pretty
@@ -277,10 +273,12 @@ typedef unsigned long elf_greg_t;
 
 #define ELF_CORE_COPY_REGS(dst, pt)    \
        memset(dst, 0, sizeof(dst));    /* don't leak any "random" bits */ \
-       memcpy(dst + 0, pt->gr, 32 * sizeof(elf_greg_t)); \
-       memcpy(dst + 32, pt->sr, 8 * sizeof(elf_greg_t)); \
-       memcpy(dst + 40, pt->iaoq, 2 * sizeof(elf_greg_t)); \
-       memcpy(dst + 42, pt->iasq, 2 * sizeof(elf_greg_t)); \
+       {       int i; \
+               for (i = 0; i < 32; i++) dst[i] = pt->gr[i]; \
+               for (i = 0; i < 8; i++) dst[32 + i] = pt->sr[i]; \
+       } \
+       dst[40] = pt->iaoq[0]; dst[41] = pt->iaoq[1]; \
+       dst[42] = pt->iasq[0]; dst[43] = pt->iasq[1]; \
        dst[44] = pt->sar;   dst[45] = pt->iir; \
        dst[46] = pt->isr;   dst[47] = pt->ior; \
        dst[48] = mfctl(22); dst[49] = mfctl(0); \
@@ -292,7 +290,7 @@ typedef unsigned long elf_greg_t;
        dst[60] = mfctl(12); dst[61] = mfctl(13); \
        dst[62] = mfctl(10); dst[63] = mfctl(15);
 
-#endif /* ! ELF_CLASS */
+#define CORE_DUMP_USE_REGSET
 
 #define ELF_NGREG 80   /* We only need 64 at present, but leave space
                           for expansion. */
@@ -310,7 +308,10 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 struct pt_regs;        /* forward declaration... */
 
 
-#define elf_check_arch(x) ((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELF_CLASS)
+#define elf_check_arch(x)              \
+       ((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELF_CLASS)
+#define compat_elf_check_arch(x)       \
+       ((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELFCLASS32)
 
 /*
  * These are used to set parameters in the core dumps.
diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
deleted file mode 100644 (file)
index 20dfa08..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Support for 32-bit Linux/Parisc ELF binaries on 64 bit kernels
- *
- * Copyright (C) 2000 John Marvin
- * Copyright (C) 2000 Hewlett Packard Co.
- *
- * Heavily inspired from various other efforts to do the same thing
- * (ia64,sparc64/mips64)
- */
-
-/* Make sure include/asm-parisc/elf.h does the right thing */
-
-#define ELF_CLASS      ELFCLASS32
-
-#define ELF_CORE_COPY_REGS(dst, pt)    \
-       memset(dst, 0, sizeof(dst));    /* don't leak any "random" bits */ \
-       {       int i; \
-               for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \
-               for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \
-       } \
-       dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \
-       dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \
-       dst[44] = (elf_greg_t) pt->sar;   dst[45] = (elf_greg_t) pt->iir; \
-       dst[46] = (elf_greg_t) pt->isr;   dst[47] = (elf_greg_t) pt->ior; \
-       dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \
-       dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \
-       dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \
-       dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \
-       dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \
-       dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \
-       dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \
-       dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15);
-
-
-typedef unsigned int elf_greg_t;
-
-#include <linux/spinlock.h>
-#include <asm/processor.h>
-#include <linux/module.h>
-#include <linux/elfcore.h>
-#include <linux/compat.h>              /* struct compat_timeval */
-
-#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 compat_timeval pr_utime;         /* User time */
-       struct compat_timeval pr_stime;         /* System time */
-       struct compat_timeval pr_cutime;        /* Cumulative user time */
-       struct compat_timeval 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 */
-       u16     pr_uid;
-       u16     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 init_elf_binfmt init_elf32_binfmt
-
-#define ELF_PLATFORM  ("PARISC32\0")
-
-/*
- * We should probably use this macro to set a flag somewhere to indicate
- * this is a 32 on 64 process. We could use PER_LINUX_32BIT, or we
- * could set a processor dependent flag in the thread_struct.
- */
-
-#undef SET_PERSONALITY
-#define SET_PERSONALITY(ex) \
-       set_thread_flag(TIF_32BIT); \
-       current->thread.map_base = DEFAULT_MAP_BASE32; \
-       current->thread.task_size = DEFAULT_TASK_SIZE32 \
-
-#undef ns_to_timeval
-#define ns_to_timeval ns_to_compat_timeval
-
-#include "../../../fs/binfmt_elf.c"