aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2018-04-11 03:09:53 -0400
committerHelge Deller <deller@gmx.de>2018-04-11 05:40:35 -0400
commit71d577db01a5177c7807a2f3d3df9bab9d21c500 (patch)
tree12293e0fc6a19226bce734e0826b2f4f95144e50
parent2a03bb9e7af2052ad6990bf417a3ba9ff7e8900e (diff)
parisc: Switch to generic COMPAT_BINFMT_ELF
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>
-rw-r--r--arch/parisc/Kconfig1
-rw-r--r--arch/parisc/include/asm/compat.h6
-rw-r--r--arch/parisc/include/asm/elf.h69
-rw-r--r--arch/parisc/kernel/binfmt_elf32.c98
4 files changed, 42 insertions, 132 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 7e0bb9836b58..fc5a574c3482 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -338,6 +338,7 @@ source "mm/Kconfig"
338config COMPAT 338config COMPAT
339 def_bool y 339 def_bool y
340 depends on 64BIT 340 depends on 64BIT
341 select COMPAT_BINFMT_ELF if BINFMT_ELF
341 342
342config SYSVIPC_COMPAT 343config SYSVIPC_COMPAT
343 def_bool y 344 def_bool y
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index c22db5323244..57b8b2a2fd4e 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -193,6 +193,12 @@ struct compat_shmid64_ds {
193}; 193};
194 194
195/* 195/*
196 * The type of struct elf_prstatus.pr_reg in compatible core dumps.
197 */
198#define COMPAT_ELF_NGREG 80
199typedef compat_ulong_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
200
201/*
196 * A pointer passed in from user mode. This should not 202 * A pointer passed in from user mode. This should not
197 * be used for syscall parameters, just declare them 203 * be used for syscall parameters, just declare them
198 * as pointers because the syscall entry code will have 204 * as pointers because the syscall entry code will have
diff --git a/arch/parisc/include/asm/elf.h b/arch/parisc/include/asm/elf.h
index 382d75a2ee4f..f019d3ec0c1c 100644
--- a/arch/parisc/include/asm/elf.h
+++ b/arch/parisc/include/asm/elf.h
@@ -6,7 +6,7 @@
6 * ELF register definitions.. 6 * ELF register definitions..
7 */ 7 */
8 8
9#include <asm/ptrace.h> 9#include <linux/types.h>
10 10
11#define EM_PARISC 15 11#define EM_PARISC 15
12 12
@@ -169,16 +169,12 @@ typedef struct elf64_fdesc {
169 __u64 gp; 169 __u64 gp;
170} Elf64_Fdesc; 170} Elf64_Fdesc;
171 171
172#ifdef __KERNEL__
173
174#ifdef CONFIG_64BIT 172#ifdef CONFIG_64BIT
175#define Elf_Fdesc Elf64_Fdesc 173#define Elf_Fdesc Elf64_Fdesc
176#else 174#else
177#define Elf_Fdesc Elf32_Fdesc 175#define Elf_Fdesc Elf32_Fdesc
178#endif /*CONFIG_64BIT*/ 176#endif /*CONFIG_64BIT*/
179 177
180#endif /*__KERNEL__*/
181
182/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ 178/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
183 179
184#define PT_HP_TLS (PT_LOOS + 0x0) 180#define PT_HP_TLS (PT_LOOS + 0x0)
@@ -213,44 +209,44 @@ typedef struct elf64_fdesc {
213#define PF_HP_SBP 0x08000000 209#define PF_HP_SBP 0x08000000
214 210
215/* 211/*
212 * This yields a string that ld.so will use to load implementation
213 * specific libraries for optimization. This is more specific in
214 * intent than poking at uname or /proc/cpuinfo.
215 */
216
217#define ELF_PLATFORM ("PARISC")
218
219/*
216 * The following definitions are those for 32-bit ELF binaries on a 32-bit 220 * The following definitions are those for 32-bit ELF binaries on a 32-bit
217 * kernel and for 64-bit binaries on a 64-bit kernel. To run 32-bit binaries 221 * kernel and for 64-bit binaries on a 64-bit kernel. To run 32-bit binaries
218 * on a 64-bit kernel, arch/parisc/kernel/binfmt_elf32.c defines these 222 * on a 64-bit kernel, fs/compat_binfmt_elf.c defines ELF_CLASS and then
219 * macros appropriately and then #includes binfmt_elf.c, which then includes 223 * #includes binfmt_elf.c, which then includes this file.
220 * this file.
221 */ 224 */
222#ifndef ELF_CLASS 225#ifndef ELF_CLASS
223 226
224/*
225 * This is used to ensure we don't load something for the wrong architecture.
226 *
227 * Note that this header file is used by default in fs/binfmt_elf.c. So
228 * the following macros are for the default case. However, for the 64
229 * bit kernel we also support 32 bit parisc binaries. To do that
230 * arch/parisc/kernel/binfmt_elf32.c defines its own set of these
231 * macros, and then it includes fs/binfmt_elf.c to provide an alternate
232 * elf binary handler for 32 bit binaries (on the 64 bit kernel).
233 */
234#ifdef CONFIG_64BIT 227#ifdef CONFIG_64BIT
235#define ELF_CLASS ELFCLASS64 228#define ELF_CLASS ELFCLASS64
236#else 229#else
237#define ELF_CLASS ELFCLASS32 230#define ELF_CLASS ELFCLASS32
238#endif 231#endif
239 232
240typedef unsigned long elf_greg_t; 233typedef unsigned long elf_greg_t;
241 234
242/*
243 * This yields a string that ld.so will use to load implementation
244 * specific libraries for optimization. This is more specific in
245 * intent than poking at uname or /proc/cpuinfo.
246 */
247
248#define ELF_PLATFORM ("PARISC\0")
249
250#define SET_PERSONALITY(ex) \ 235#define SET_PERSONALITY(ex) \
236({ \
251 set_personality((current->personality & ~PER_MASK) | PER_LINUX); \ 237 set_personality((current->personality & ~PER_MASK) | PER_LINUX); \
252 current->thread.map_base = DEFAULT_MAP_BASE; \ 238 current->thread.map_base = DEFAULT_MAP_BASE; \
253 current->thread.task_size = DEFAULT_TASK_SIZE \ 239 current->thread.task_size = DEFAULT_TASK_SIZE; \
240 })
241
242#endif /* ! ELF_CLASS */
243
244#define COMPAT_SET_PERSONALITY(ex) \
245({ \
246 set_thread_flag(TIF_32BIT); \
247 current->thread.map_base = DEFAULT_MAP_BASE32; \
248 current->thread.task_size = DEFAULT_TASK_SIZE32; \
249 })
254 250
255/* 251/*
256 * Fill in general registers in a core dump. This saves pretty 252 * Fill in general registers in a core dump. This saves pretty
@@ -277,10 +273,12 @@ typedef unsigned long elf_greg_t;
277 273
278#define ELF_CORE_COPY_REGS(dst, pt) \ 274#define ELF_CORE_COPY_REGS(dst, pt) \
279 memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \ 275 memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \
280 memcpy(dst + 0, pt->gr, 32 * sizeof(elf_greg_t)); \ 276 { int i; \
281 memcpy(dst + 32, pt->sr, 8 * sizeof(elf_greg_t)); \ 277 for (i = 0; i < 32; i++) dst[i] = pt->gr[i]; \
282 memcpy(dst + 40, pt->iaoq, 2 * sizeof(elf_greg_t)); \ 278 for (i = 0; i < 8; i++) dst[32 + i] = pt->sr[i]; \
283 memcpy(dst + 42, pt->iasq, 2 * sizeof(elf_greg_t)); \ 279 } \
280 dst[40] = pt->iaoq[0]; dst[41] = pt->iaoq[1]; \
281 dst[42] = pt->iasq[0]; dst[43] = pt->iasq[1]; \
284 dst[44] = pt->sar; dst[45] = pt->iir; \ 282 dst[44] = pt->sar; dst[45] = pt->iir; \
285 dst[46] = pt->isr; dst[47] = pt->ior; \ 283 dst[46] = pt->isr; dst[47] = pt->ior; \
286 dst[48] = mfctl(22); dst[49] = mfctl(0); \ 284 dst[48] = mfctl(22); dst[49] = mfctl(0); \
@@ -292,7 +290,7 @@ typedef unsigned long elf_greg_t;
292 dst[60] = mfctl(12); dst[61] = mfctl(13); \ 290 dst[60] = mfctl(12); dst[61] = mfctl(13); \
293 dst[62] = mfctl(10); dst[63] = mfctl(15); 291 dst[62] = mfctl(10); dst[63] = mfctl(15);
294 292
295#endif /* ! ELF_CLASS */ 293#define CORE_DUMP_USE_REGSET
296 294
297#define ELF_NGREG 80 /* We only need 64 at present, but leave space 295#define ELF_NGREG 80 /* We only need 64 at present, but leave space
298 for expansion. */ 296 for expansion. */
@@ -310,7 +308,10 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
310struct pt_regs; /* forward declaration... */ 308struct pt_regs; /* forward declaration... */
311 309
312 310
313#define elf_check_arch(x) ((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELF_CLASS) 311#define elf_check_arch(x) \
312 ((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELF_CLASS)
313#define compat_elf_check_arch(x) \
314 ((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELFCLASS32)
314 315
315/* 316/*
316 * These are used to set parameters in the core dumps. 317 * 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
index 20dfa081ed0b..000000000000
--- a/arch/parisc/kernel/binfmt_elf32.c
+++ /dev/null
@@ -1,98 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Support for 32-bit Linux/Parisc ELF binaries on 64 bit kernels
4 *
5 * Copyright (C) 2000 John Marvin
6 * Copyright (C) 2000 Hewlett Packard Co.
7 *
8 * Heavily inspired from various other efforts to do the same thing
9 * (ia64,sparc64/mips64)
10 */
11
12/* Make sure include/asm-parisc/elf.h does the right thing */
13
14#define ELF_CLASS ELFCLASS32
15
16#define ELF_CORE_COPY_REGS(dst, pt) \
17 memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \
18 { int i; \
19 for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \
20 for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \
21 } \
22 dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \
23 dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \
24 dst[44] = (elf_greg_t) pt->sar; dst[45] = (elf_greg_t) pt->iir; \
25 dst[46] = (elf_greg_t) pt->isr; dst[47] = (elf_greg_t) pt->ior; \
26 dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \
27 dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \
28 dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \
29 dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \
30 dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \
31 dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \
32 dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \
33 dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15);
34
35
36typedef unsigned int elf_greg_t;
37
38#include <linux/spinlock.h>
39#include <asm/processor.h>
40#include <linux/module.h>
41#include <linux/elfcore.h>
42#include <linux/compat.h> /* struct compat_timeval */
43
44#define elf_prstatus elf_prstatus32
45struct elf_prstatus32
46{
47 struct elf_siginfo pr_info; /* Info associated with signal */
48 short pr_cursig; /* Current signal */
49 unsigned int pr_sigpend; /* Set of pending signals */
50 unsigned int pr_sighold; /* Set of held signals */
51 pid_t pr_pid;
52 pid_t pr_ppid;
53 pid_t pr_pgrp;
54 pid_t pr_sid;
55 struct compat_timeval pr_utime; /* User time */
56 struct compat_timeval pr_stime; /* System time */
57 struct compat_timeval pr_cutime; /* Cumulative user time */
58 struct compat_timeval pr_cstime; /* Cumulative system time */
59 elf_gregset_t pr_reg; /* GP registers */
60 int pr_fpvalid; /* True if math co-processor being used. */
61};
62
63#define elf_prpsinfo elf_prpsinfo32
64struct elf_prpsinfo32
65{
66 char pr_state; /* numeric process state */
67 char pr_sname; /* char for pr_state */
68 char pr_zomb; /* zombie */
69 char pr_nice; /* nice val */
70 unsigned int pr_flag; /* flags */
71 u16 pr_uid;
72 u16 pr_gid;
73 pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
74 /* Lots missing */
75 char pr_fname[16]; /* filename of executable */
76 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
77};
78
79#define init_elf_binfmt init_elf32_binfmt
80
81#define ELF_PLATFORM ("PARISC32\0")
82
83/*
84 * We should probably use this macro to set a flag somewhere to indicate
85 * this is a 32 on 64 process. We could use PER_LINUX_32BIT, or we
86 * could set a processor dependent flag in the thread_struct.
87 */
88
89#undef SET_PERSONALITY
90#define SET_PERSONALITY(ex) \
91 set_thread_flag(TIF_32BIT); \
92 current->thread.map_base = DEFAULT_MAP_BASE32; \
93 current->thread.task_size = DEFAULT_TASK_SIZE32 \
94
95#undef ns_to_timeval
96#define ns_to_timeval ns_to_compat_timeval
97
98#include "../../../fs/binfmt_elf.c"