"arm64/binfmt_elf: Disable compat32 definitions for compat64" introduced a special path for compat64 in compat_binfmt_elf, avoiding most existing definitions. Subsequent commits partially reverted this by making more definitions common to compat32 and compat64. This commit completes this process by returning compat_binfmt_elf to its original state, except where definitions are strictly 32-bit specific (small CONFIG_COMPAT32 block at the top of the file).
This is made possible by recent commits that ensure that compat_elf_read_implies_exec and COMPAT_ELF_HWCAP2* are not defined in compat64. Additionally, struct compat_elf_prstatus_common in elfcore-compat.h is amended to use a 64-bit time format in compat64.
This change is mostly non-functional, with the following exceptions:
* copy_siginfo_to_external() was incorrectly used in compat64. copy_siginfo_to_external32() is now used instead, performing the appropriate layout conversion (despite its name, it is suitable to compat64 too).
* Symbols like elf_format are now renamed to e.g. compat_elf_format in compat64 too, easing debugging.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- fs/compat_binfmt_elf.c | 68 +++++++++++++++------------------- include/linux/elfcore-compat.h | 7 ++++ 2 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c index b3204b54af36..6f108d3e1278 100644 --- a/fs/compat_binfmt_elf.c +++ b/fs/compat_binfmt_elf.c @@ -14,16 +14,7 @@ * functions used in binfmt_elf.c to compat versions. */
-#ifdef CONFIG_COMPAT32 #include <linux/elfcore-compat.h> -#else -/* - * TODO [PCuABI] - The header linux/elfcore-compat.h needs some changes for - * complete compat64 support so for time being include minimum definitions - * from linux/elf.h. - */ -#include <linux/elf.h> -#endif /* CONFIG_COMPAT32 */ #include <linux/time.h>
#define ELF_COMPAT 1 @@ -45,6 +36,7 @@ #define elf_stack_put_user(val, ptr) put_user((elf_addr_t)(user_uintptr_t)(val), (ptr))
#ifdef CONFIG_COMPAT32 + /* * Rename the basic ELF layout types to refer to the 32-bit class of files. */ @@ -64,6 +56,11 @@ #define elf_addr_t Elf32_Addr #define ELF_GNU_PROPERTY_ALIGN ELF32_GNU_PROPERTY_ALIGN
+#undef ns_to_kernel_old_timeval +#define ns_to_kernel_old_timeval ns_to_old_timeval32 + +#endif /* CONFIG_COMPAT32 */ + /* * Some data types as stored in coredump. */ @@ -79,15 +76,15 @@ #define elf_prstatus_common compat_elf_prstatus_common #define elf_prpsinfo compat_elf_prpsinfo
-#undef ns_to_kernel_old_timeval -#define ns_to_kernel_old_timeval ns_to_old_timeval32 - /* * To use this file, asm/elf.h must define compat_elf_check_arch. * The other following macros can be defined if the compat versions * differ from the native ones, or omitted when they match. */
+#undef elf_check_arch +#define elf_check_arch compat_elf_check_arch + #ifdef COMPAT_ELF_PLATFORM #undef ELF_PLATFORM #define ELF_PLATFORM COMPAT_ELF_PLATFORM @@ -103,6 +100,11 @@ #define ELF_HWCAP2 COMPAT_ELF_HWCAP2 #endif
+#ifdef COMPAT_ARCH_DLINFO +#undef ARCH_DLINFO +#define ARCH_DLINFO COMPAT_ARCH_DLINFO +#endif + #ifdef COMPAT_ELF_ET_DYN_BASE #undef ELF_ET_DYN_BASE #define ELF_ET_DYN_BASE COMPAT_ELF_ET_DYN_BASE @@ -113,32 +115,6 @@ #define ELF_PLAT_INIT COMPAT_ELF_PLAT_INIT #endif
-#ifdef compat_elf_read_implies_exec -#undef elf_read_implies_exec -#define elf_read_implies_exec compat_elf_read_implies_exec -#endif - -/* - * Rename a few of the symbols that binfmt_elf.c will define. - * These are all local so the names don't really matter, but it - * might make some debugging less confusing not to duplicate them. - */ -#define elf_format compat_elf_format -#define init_elf_binfmt init_compat_elf_binfmt -#define exit_elf_binfmt exit_compat_elf_binfmt -#define binfmt_elf_test_cases compat_binfmt_elf_test_cases -#define binfmt_elf_test_suite compat_binfmt_elf_test_suite - -#endif /* CONFIG_COMPAT32 */ - -#undef elf_check_arch -#define elf_check_arch compat_elf_check_arch - -#ifdef COMPAT_ARCH_DLINFO -#undef ARCH_DLINFO -#define ARCH_DLINFO COMPAT_ARCH_DLINFO -#endif - #ifdef COMPAT_SET_PERSONALITY #undef SET_PERSONALITY #define SET_PERSONALITY COMPAT_SET_PERSONALITY @@ -170,6 +146,22 @@ #define ARCH_SETUP_ADDITIONAL_PAGES COMPAT_ARCH_SETUP_ADDITIONAL_PAGES #endif
+#ifdef compat_elf_read_implies_exec +#undef elf_read_implies_exec +#define elf_read_implies_exec compat_elf_read_implies_exec +#endif + +/* + * Rename a few of the symbols that binfmt_elf.c will define. + * These are all local so the names don't really matter, but it + * might make some debugging less confusing not to duplicate them. + */ +#define elf_format compat_elf_format +#define init_elf_binfmt init_compat_elf_binfmt +#define exit_elf_binfmt exit_compat_elf_binfmt +#define binfmt_elf_test_cases compat_binfmt_elf_test_cases +#define binfmt_elf_test_suite compat_binfmt_elf_test_suite + /* * We share all the actual code with the native (64-bit) version. */ diff --git a/include/linux/elfcore-compat.h b/include/linux/elfcore-compat.h index 54feb64e9b5d..db9029d69bd3 100644 --- a/include/linux/elfcore-compat.h +++ b/include/linux/elfcore-compat.h @@ -27,10 +27,17 @@ struct compat_elf_prstatus_common compat_pid_t pr_ppid; compat_pid_t pr_pgrp; compat_pid_t pr_sid; +#ifdef CONFIG_COMPAT64 + struct __kernel_old_timeval pr_utime; + struct __kernel_old_timeval pr_stime; + struct __kernel_old_timeval pr_cutime; + struct __kernel_old_timeval pr_cstime; +#else struct old_timeval32 pr_utime; struct old_timeval32 pr_stime; struct old_timeval32 pr_cutime; struct old_timeval32 pr_cstime; +#endif };
struct compat_elf_prpsinfo