summaryrefslogtreecommitdiff
path: root/arch/mips/include/asm/elf.h
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2020-06-14 07:18:12 +0300
committerAl Viro <viro@zeniv.linux.org.uk>2021-01-06 16:42:49 +0300
commit0bb87f051e4282afb5f472807c7244b21cf515c7 (patch)
tree89d3c3bbcd1f78a1a22303d79e931c7812abf29b /arch/mips/include/asm/elf.h
parent2fb33bec053b01e616fab921aab4d4775d374e8f (diff)
downloadlinux-0bb87f051e4282afb5f472807c7244b21cf515c7.tar.xz
mips compat: switch to compat_binfmt_elf.c
Like amd64, mips has two 32bit ABIs - o32 and n32. Unlike amd64, it does not use compat_binfmt_elf.c for either of those; each of those ABIs has a binfmt handler of its own, both very similar to fs/compat_binfmt_elf.c. And the same technics as we use on amd64 can be used to make fs/compat_binfmt_elf.c handle both. * merge elfo32_check_arch() with elfn32_check_arch(), make that serve as compat_elf_check_arch(). Note that SET_PERSONALITY2() is already the same for all ABI variants - it looks at the elf header to choose the flags to set. * add asm/elfcore-compat.h, using the bigger (n32) variant of elf32_prstatus as compat_elf_prstatus there. * make PRSTATUS_SIZE() and SET_PR_FPVALID() choose the right layout, same as done for amd64. test_thread_flag(TIF_32BIT_REGS) is used as the predicate. Voila - we are rid of binfmt_elf{n,o}32.c; fs/compat_binfmt_elf.c is used, same as for all other ELF-supporting 64bit architectures that need 32bit compat. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/mips/include/asm/elf.h')
-rw-r--r--arch/mips/include/asm/elf.h54
1 files changed, 19 insertions, 35 deletions
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index d29e43e4f9b1..dc8d2863752c 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -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;