diff mbox

[v6,11/21] arm64: ilp32: introduce binfmt_ilp32.c

Message ID 1452209679-19445-12-git-send-email-ynorov@caviumnetworks.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yury Norov Jan. 7, 2016, 11:34 p.m. UTC
to handle ILP32 binaries

Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
---
 arch/arm64/kernel/Makefile       |  1 +
 arch/arm64/kernel/binfmt_ilp32.c | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+)
 create mode 100644 arch/arm64/kernel/binfmt_ilp32.c

Comments

Yury Norov Jan. 7, 2016, 11:45 p.m. UTC | #1
On Fri, Jan 08, 2016 at 02:34:29AM +0300, Yury Norov wrote:
> to handle ILP32 binaries
> 
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> ---
[...]
> diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
> new file mode 100644
> index 0000000..02a7a6c
> --- /dev/null
> +++ b/arch/arm64/kernel/binfmt_ilp32.c
> @@ -0,0 +1,21 @@
> +/*
> + * Support for ILP32 Linux/aarch64 ELF binaries.
> + */
> +
> +/* AARCH64 ILP32 EABI. */
> +#define compat_elf_check_arch(x)	(((x)->e_machine == EM_AARCH64)	\
> +					&& (x)->e_ident[EI_CLASS] == ELFCLASS32)
> +

Not sure about this. Originally it was just:
        #define compat_elf_check_arch(x)	(((x)->e_machine == EM_AARCH64)	\

But how than distinguish aarch64 and aarch64/ilp32 elfs?
Arnd Bergmann Jan. 8, 2016, 9:08 a.m. UTC | #2
On Friday 08 January 2016 02:34:29 Yury Norov wrote:
> +
> +#include "../../../fs/compat_binfmt_elf.c"
> 

This is the wrong file, you have to include fs/binfmt_elf.c, otherwise
you pick up the same definitions that you have for the other one.

Alternatively, you can also change binfmt_elf32.c to include fs/binfmt_elf.c
and use fs/compat_binfmt_elf.c here if that makes the code nicer, you
just can use the compat file for both or things get ugly because of
the extra indirections.

	Arnd
Yury Norov Jan. 12, 2016, 4:46 p.m. UTC | #3
On Fri, Jan 08, 2016 at 10:08:44AM +0100, Arnd Bergmann wrote:
> On Friday 08 January 2016 02:34:29 Yury Norov wrote:
> > +
> > +#include "../../../fs/compat_binfmt_elf.c"
> > 
> 
> This is the wrong file, you have to include fs/binfmt_elf.c, otherwise
> you pick up the same definitions that you have for the other one.
> 

I chose compat as it's how it wokrs now. It redefines some types like
user_long_t, and I think it's neccessary for ILP32, as for aarch32.

> Alternatively, you can also change binfmt_elf32.c to include fs/binfmt_elf.c
> and use fs/compat_binfmt_elf.c here if that makes the code nicer, you
> just can use the compat file for both or things get ugly because of
> the extra indirections.
> 
> 	Arnd
Arnd Bergmann Jan. 12, 2016, 11:05 p.m. UTC | #4
On Tuesday 12 January 2016 19:46:41 Yury Norov wrote:
> On Fri, Jan 08, 2016 at 10:08:44AM +0100, Arnd Bergmann wrote:
> > On Friday 08 January 2016 02:34:29 Yury Norov wrote:
> > > +
> > > +#include "../../../fs/compat_binfmt_elf.c"
> > > 
> > 
> > This is the wrong file, you have to include fs/binfmt_elf.c, otherwise
> > you pick up the same definitions that you have for the other one.
> > 
> 
> I chose compat as it's how it wokrs now. It redefines some types like
> user_long_t, and I think it's neccessary for ILP32, as for aarch32.

I really think the double indirection adds way too much complexity
here, it makes it rather hard to understand what is going on, and
that leads to bugs.

fs/compat_binfmt_elf.c is not doing much at all, and most of it is not
actually needed if you just make a copy of that file and fill in the
data as needed. Some of the overrides (ELF_ARCH, ELF_PLATFORM, ELF_NREG,
ELF_HWCAP, ELF_HWCAP2) are identical between ilp32 and lp64 modes
for arm64, but are different for arm32 compat, so you don't even have
to override them at all.

	Arnd
diff mbox

Patch

diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index f1b798a..ad7158c 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -28,6 +28,7 @@  $(obj)/%.stub.o: $(obj)/%.o FORCE
 arm64-obj-$(CONFIG_AARCH32_EL0)		+= sys32.o kuser32.o signal32.o 	\
 					   sys_compat.o entry32.o		\
 					   ../../arm/kernel/opcodes.o binfmt_elf32.o
+arm64-obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o
 arm64-obj-$(CONFIG_FUNCTION_TRACER)	+= ftrace.o entry-ftrace.o
 arm64-obj-$(CONFIG_MODULES)		+= arm64ksyms.o module.o
 arm64-obj-$(CONFIG_PERF_EVENTS)		+= perf_regs.o perf_callchain.o
diff --git a/arch/arm64/kernel/binfmt_ilp32.c b/arch/arm64/kernel/binfmt_ilp32.c
new file mode 100644
index 0000000..02a7a6c
--- /dev/null
+++ b/arch/arm64/kernel/binfmt_ilp32.c
@@ -0,0 +1,21 @@ 
+/*
+ * Support for ILP32 Linux/aarch64 ELF binaries.
+ */
+
+/* AARCH64 ILP32 EABI. */
+#define compat_elf_check_arch(x)	(((x)->e_machine == EM_AARCH64)	\
+					&& (x)->e_ident[EI_CLASS] == ELFCLASS32)
+
+#define COMPAT_SET_PERSONALITY(ex)					\
+do {									\
+	set_thread_flag(TIF_32BIT_AARCH64);				\
+	clear_thread_flag(TIF_32BIT);					\
+} while (0)
+
+#define COMPAT_ARCH_DLINFO						\
+do {									\
+	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
+		    (elf_addr_t)(long)current->mm->context.vdso);	\
+} while (0)
+
+#include "../../../fs/compat_binfmt_elf.c"