diff mbox series

[2/2] arch/arm: add support for FDPIC

Message ID 20220802133009.1282520-3-Ben.Wolsieffer@hefring.com
State Superseded
Headers show
Series Add support for FDPIC binaries on ARM | expand

Commit Message

Ben Wolsieffer Aug. 2, 2022, 1:30 p.m. UTC
Linux on ARM supports FDPIC binaries intended for use on no-MMU systems.
This patch enables support for building a toolchain that produces FDPIC
binaries.

Unfortunately, the target name for an FDPIC toolchain is a bit
idiosyncratic and must be arm-<vendor>-uclinuxfdpiceabi. This requires a
few special cases in the target construction code, since there is no
separate TARGET_OS field.

According to the kernel help for CONFIG_BINFMT_ELF_FDPIC, "It is also
possible to run FDPIC ELF binaries on MMU linux," so FDPIC support is
available on all ARM platforms, not just no-MMU.

Signed-off-by: Ben Wolsieffer <Ben.Wolsieffer@hefring.com>
---
 arch/Config.in      |  1 +
 package/Makefile.in | 30 +++++++++++++++++++++---------
 2 files changed, 22 insertions(+), 9 deletions(-)

Comments

Arnout Vandecappelle Aug. 2, 2022, 5:28 p.m. UTC | #1
On 02/08/2022 15:30, Ben Wolsieffer wrote:
> Linux on ARM supports FDPIC binaries intended for use on no-MMU systems.
> This patch enables support for building a toolchain that produces FDPIC
> binaries.
> 
> Unfortunately, the target name for an FDPIC toolchain is a bit
> idiosyncratic and must be arm-<vendor>-uclinuxfdpiceabi. This requires a
> few special cases in the target construction code, since there is no
> separate TARGET_OS field.
> 
> According to the kernel help for CONFIG_BINFMT_ELF_FDPIC, "It is also
> possible to run FDPIC ELF binaries on MMU linux," so FDPIC support is
> available on all ARM platforms, not just no-MMU.
> 
> Signed-off-by: Ben Wolsieffer <Ben.Wolsieffer@hefring.com>
> ---
>   arch/Config.in      |  1 +
>   package/Makefile.in | 30 +++++++++++++++++++++---------
>   2 files changed, 22 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/Config.in b/arch/Config.in
> index c5d481b9e5..8dab58cf04 100644
> --- a/arch/Config.in
> +++ b/arch/Config.in
> @@ -39,6 +39,7 @@ config BR2_arceb
>   
>   config BR2_arm
>   	bool "ARM (little endian)"
> +	select BR2_ARCH_HAS_FDPIC_SUPPORT
>   	# MMU support is set by the subarchitecture file, arch/Config.in.arm
>   	help
>   	  ARM is a 32-bit reduced instruction set computer (RISC)
> diff --git a/package/Makefile.in b/package/Makefile.in
> index ff60f85092..d75f620d82 100644
> --- a/package/Makefile.in
> +++ b/package/Makefile.in
> @@ -36,18 +36,21 @@ $(error BR2_TOOLCHAIN_BUILDROOT_VENDOR cannot be 'unknown'. \
>   	It might be confused with the native toolchain)
>   endif
>   
> -# Compute GNU_TARGET_NAME
> -GNU_TARGET_NAME = $(ARCH)-$(TARGET_VENDOR)-$(TARGET_OS)-$(LIBC)$(ABI)
> -
>   # FLAT binary format needs uclinux, except RISC-V 64-bits which needs
>   # the regular linux name.
>   ifeq ($(BR2_BINFMT_FLAT):$(BR2_RISCV_64),y:)
>   TARGET_OS = uclinux
> +# FDPIC binary format requires no OS field in target
> +else ifeq ($(BR2_BINFMT_FDPIC),y)
> +TARGET_OS =
>   else
>   TARGET_OS = linux
>   endif
>   
> -ifeq ($(BR2_TOOLCHAIN_USES_UCLIBC),y)
> +# FDPIC suffix must be -uclinuxfdpiceabi
> +ifeq ($(BR2_BINFMT_FDPIC),y)
> +LIBC = uclinux
> +else ifeq ($(BR2_TOOLCHAIN_USES_UCLIBC),y)
>   LIBC = uclibc
>   else ifeq ($(BR2_TOOLCHAIN_USES_MUSL),y)
>   LIBC = musl
> @@ -59,12 +62,14 @@ else
>   $(error No C library enabled, this is not possible.)
>   endif
>   
> -# The ABI suffix is a bit special on ARM, as it needs to be
> -# -uclibcgnueabi for uClibc EABI, and -gnueabi for glibc EABI.
> -# This means that the LIBC and ABI aren't strictly orthogonal,
> -# which explains why we need the test on LIBC below.
> +# The ABI suffix is a bit special on ARM, as it needs to be -uclibcgnueabi
> +# for uClibc EABI, -gnueabi for glibc EABI and -uclinuxfdpiceabi if FDPIC is
> +# used. This means that the LIBC and ABI aren't strictly orthogonal, which
> +# explains why we need the test on LIBC below.
>   ifeq ($(BR2_arm)$(BR2_armeb),y)
> -ifeq ($(LIBC),uclibc)
> +ifeq ($(BR2_BINFMT_FDPIC),y)
> +ABI = fdpiceabi
> +else ifeq ($(LIBC),uclibc)
>   ABI = gnueabi
>   else
>   ABI = eabi
> @@ -90,6 +95,13 @@ TARGET_ABI += -mabi=spe -mfloat-gprs=double -Wa,-me500mc
>   endif
>   endif
>   
> +# Compute GNU_TARGET_NAME
> +ifeq ($(TARGET_OS),)
> +GNU_TARGET_NAME = $(ARCH)-$(TARGET_VENDOR)-$(LIBC)$(ABI)
> +else
> +GNU_TARGET_NAME = $(ARCH)-$(TARGET_VENDOR)-$(TARGET_OS)-$(LIBC)$(ABI)
> +endif

  I think all the special-casing for TARGET_OS, LIBC and ABI are way too 
complicated. None of these are used anywhere else (except LIBC which is also 
used in rust.mk - but Rust won't support FDPIC ever I think). So I think you 
should just put the special-casing here in GNU_TARGET_NAME itself:

# The tuple for FDPIC on ARM is very special: it doesn't have the OS part, and
# it must end with -uclinuxfdpiceabi
ifeq ($(BR2_BINFMT_FDPIC),y)
GNU_TARGET_NAME = $(ARCH)-$(TARGET_VENDOR)-uclinuxfdpiceabi
else
GNU_TARGET_NAME = $(ARCH)-$(TARGET_VENDOR)-$(TARGET_OS)-$(LIBC)$(ABI)
endif

  If we ever add other architectures with FDPIC (RISC-V is a likely candidate), 
we may revisit that again, but for now this is sufficient.

  Regards,
  Arnout

> +
>   # Use longcalls option for Xtensa globally.
>   # The 'longcalls' option allows calls across a greater range of addresses,
>   # and is required for some packages. While this option can degrade both
diff mbox series

Patch

diff --git a/arch/Config.in b/arch/Config.in
index c5d481b9e5..8dab58cf04 100644
--- a/arch/Config.in
+++ b/arch/Config.in
@@ -39,6 +39,7 @@  config BR2_arceb
 
 config BR2_arm
 	bool "ARM (little endian)"
+	select BR2_ARCH_HAS_FDPIC_SUPPORT
 	# MMU support is set by the subarchitecture file, arch/Config.in.arm
 	help
 	  ARM is a 32-bit reduced instruction set computer (RISC)
diff --git a/package/Makefile.in b/package/Makefile.in
index ff60f85092..d75f620d82 100644
--- a/package/Makefile.in
+++ b/package/Makefile.in
@@ -36,18 +36,21 @@  $(error BR2_TOOLCHAIN_BUILDROOT_VENDOR cannot be 'unknown'. \
 	It might be confused with the native toolchain)
 endif
 
-# Compute GNU_TARGET_NAME
-GNU_TARGET_NAME = $(ARCH)-$(TARGET_VENDOR)-$(TARGET_OS)-$(LIBC)$(ABI)
-
 # FLAT binary format needs uclinux, except RISC-V 64-bits which needs
 # the regular linux name.
 ifeq ($(BR2_BINFMT_FLAT):$(BR2_RISCV_64),y:)
 TARGET_OS = uclinux
+# FDPIC binary format requires no OS field in target
+else ifeq ($(BR2_BINFMT_FDPIC),y)
+TARGET_OS =
 else
 TARGET_OS = linux
 endif
 
-ifeq ($(BR2_TOOLCHAIN_USES_UCLIBC),y)
+# FDPIC suffix must be -uclinuxfdpiceabi
+ifeq ($(BR2_BINFMT_FDPIC),y)
+LIBC = uclinux
+else ifeq ($(BR2_TOOLCHAIN_USES_UCLIBC),y)
 LIBC = uclibc
 else ifeq ($(BR2_TOOLCHAIN_USES_MUSL),y)
 LIBC = musl
@@ -59,12 +62,14 @@  else
 $(error No C library enabled, this is not possible.)
 endif
 
-# The ABI suffix is a bit special on ARM, as it needs to be
-# -uclibcgnueabi for uClibc EABI, and -gnueabi for glibc EABI.
-# This means that the LIBC and ABI aren't strictly orthogonal,
-# which explains why we need the test on LIBC below.
+# The ABI suffix is a bit special on ARM, as it needs to be -uclibcgnueabi
+# for uClibc EABI, -gnueabi for glibc EABI and -uclinuxfdpiceabi if FDPIC is
+# used. This means that the LIBC and ABI aren't strictly orthogonal, which
+# explains why we need the test on LIBC below.
 ifeq ($(BR2_arm)$(BR2_armeb),y)
-ifeq ($(LIBC),uclibc)
+ifeq ($(BR2_BINFMT_FDPIC),y)
+ABI = fdpiceabi
+else ifeq ($(LIBC),uclibc)
 ABI = gnueabi
 else
 ABI = eabi
@@ -90,6 +95,13 @@  TARGET_ABI += -mabi=spe -mfloat-gprs=double -Wa,-me500mc
 endif
 endif
 
+# Compute GNU_TARGET_NAME
+ifeq ($(TARGET_OS),)
+GNU_TARGET_NAME = $(ARCH)-$(TARGET_VENDOR)-$(LIBC)$(ABI)
+else
+GNU_TARGET_NAME = $(ARCH)-$(TARGET_VENDOR)-$(TARGET_OS)-$(LIBC)$(ABI)
+endif
+
 # Use longcalls option for Xtensa globally.
 # The 'longcalls' option allows calls across a greater range of addresses,
 # and is required for some packages. While this option can degrade both