@@ -460,7 +460,11 @@ $(BUILD_DIR) $(TARGET_DIR) $(HOST_DIR) $(BINARIES_DIR) $(LEGAL_INFO_DIR) $(REDIS
# We make a symlink lib32->lib or lib64->lib as appropriate
# MIPS64/n32 requires lib32 even though it's a 64-bit arch.
ifeq ($(BR2_ARCH_IS_64)$(BR2_MIPS_NABI32),y)
+ifeq ($(BR2_X86_64_ABI_X32),y)
+LIB_SYMLINK = libx32
+else
LIB_SYMLINK = lib64
+endif
else
LIB_SYMLINK = lib32
endif
@@ -281,3 +281,35 @@ config BR2_GCC_TARGET_ARCH
default "c3" if BR2_x86_c3
default "c3-2" if BR2_x86_c32
default "geode" if BR2_x86_geode
+
+choice
+ prompt "Target ABI"
+ depends on BR2_x86_64
+ default BR2_X86_64_ABI_SYSV
+ help
+ Application Binary Interface to use. The Application Binary
+ Interface describes the calling conventions (how arguments
+ are passed to functions, how the return value is passed, how
+ system calls are made, etc.).
+
+config BR2_X86_64_ABI_SYSV
+ bool "sysv"
+ help
+ This is the gnu ABI for x86-64 which has 64-bits wide
+ pointers. You probably want to use this unless you know what
+ you are doing.
+
+config BR2_X86_64_ABI_X32
+ bool "x32 (experimental)"
+ help
+ The X32 ABI is x86-64 with 32 bit pointers. It runs in x86-64
+ mode but as it has 32-bit pointers only 4 GB of RAM can be
+ addressed.
+
+ https://en.wikipedia.org/wiki/X32_ABI
+endchoice
+
+# The ABI is only explicitly needed for x32
+config BR2_GCC_TARGET_ABI
+ default "" if BR2_X86_64_ABI_SYSV
+ default "x32" if BR2_X86_64_ABI_X32
@@ -70,6 +70,11 @@ ABI := $(ABI)hf
endif
endif
+# Only set the ABI for x86-64 x32.
+ifeq ($(BR2_X86_64_ABI_X32),y)
+ABI = x32
+endif
+
# For FSL PowerPC there's SPE
ifeq ($(BR2_powerpc_SPE),y)
ABI = spe
@@ -29,6 +29,8 @@ choice
depends on !BR2_sparc_leon3
# Broken or unsupported X86 cores
depends on !BR2_x86_corei7 && !BR2_x86_jaguar && !BR2_x86_steamroller
+ # x32 ABI support added in gcc 4.7
+ depends on !BR2_X86_64_ABI_X32
# ARM EABIhf support appeared in gcc 4.6
depends on !BR2_ARM_EABIHF
# Unsupported for MIPS R6
@@ -52,6 +54,8 @@ choice
depends on !BR2_sparc_leon3
# Broken or unsupported x86 cores
depends on !BR2_x86_jaguar && !BR2_x86_steamroller
+ # Broken or not recommended with x32 ABI
+ depends on !BR2_X86_64_ABI_X32
# Unsupported for MIPS R6
depends on !BR2_mips_32r6 && !BR2_mips_64r6
select BR2_GCC_NEEDS_MPC
@@ -14,11 +14,14 @@ choice
config BR2_KERNEL_HEADERS_3_2
bool "Linux 3.2.x kernel headers"
depends on !BR2_arc && !BR2_nios2
+ depends on !BR2_X86_64_ABI_X32 # not supported
select BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_2
config BR2_KERNEL_HEADERS_3_4
bool "Linux 3.4.x kernel headers"
depends on !BR2_arc && !BR2_nios2
+ # kernel headers >= 3.6 are recommended for x32 ABI
+ depends on !BR2_X86_64_ABI_X32
select BR2_TOOLCHAIN_HEADERS_AT_LEAST_3_4
config BR2_KERNEL_HEADERS_3_10
@@ -125,7 +125,7 @@ copy_toolchain_lib_root = \
# $1: main sysroot directory of the toolchain
# $2: arch specific sysroot directory of the toolchain
# $3: arch specific subdirectory in the sysroot
-# $4: directory of libraries ('lib', 'lib32' or 'lib64')
+# $4: directory of libraries ('lib', 'lib32', 'libx32' or 'lib64')
# $5: support lib directories (for toolchains storing libgcc_s,
# libstdc++ and other gcc support libraries outside of the
# sysroot)
@@ -138,7 +138,8 @@ copy_toolchain_sysroot = \
for i in etc $${ARCH_LIB_DIR} sbin usr usr/$${ARCH_LIB_DIR}; do \
if [ -d $${ARCH_SYSROOT_DIR}/$$i ] ; then \
rsync -au --chmod=u=rwX,go=rX --exclude 'usr/lib/locale' \
- --exclude lib --exclude lib32 --exclude lib64 \
+ --exclude lib --exclude lib32 --exclude libx32 \
+ --exclude lib64 \
$${ARCH_SYSROOT_DIR}/$$i/ $(STAGING_DIR)/$$i/ ; \
fi ; \
done ; \
@@ -346,6 +347,21 @@ check_arm_abi = \
rm -f $(BUILD_DIR)/.br-toolchain-test.tmp*
#
+# Check that the Buildroot configuration of the ABI matches the
+# configuration of the external toolchain.
+#
+# $1: cross-gcc path
+#
+check_x86_64_x32_abi = \
+ __CROSS_CC=$(strip $1) ; \
+ if ! echo 'int main(void) {}' | $${__CROSS_CC} -mx32 -x c -o $(BUILD_DIR)/.br-toolchain-test.tmp - ; then \
+ rm -f $(BUILD_DIR)/.br-toolchain-test.tmp*; \
+ echo "Incorrect ABI setting: BR2_X86_64_ABI_X32 selected, but toolchain is incompatible"; \
+ exit 1 ; \
+ fi ; \
+ rm -f $(BUILD_DIR)/.br-toolchain-test.tmp*
+
+#
# Check that the external toolchain supports C++
#
# $1: cross-g++ path
@@ -33,7 +33,7 @@ config BR2_TOOLCHAIN_BUILDROOT_UCLIBC
BR2_bfin || BR2_i386 || BR2_m68k || \
BR2_mips || BR2_mipsel || BR2_mips64 || BR2_mips64el || \
BR2_powerpc || BR2_sh2a || BR2_sh4 || BR2_sh4eb || \
- BR2_sparc || BR2_xtensa || BR2_x86_64
+ BR2_sparc || BR2_xtensa || (BR2_x86_64 && BR2_X86_64_ABI_SYSV)
# Unsupported for MIPS R6
depends on !BR2_mips_32r6 && !BR2_mips_64r6
help
@@ -367,6 +367,7 @@ config BR2_TOOLCHAIN_EXTERNAL_CODESOURCERY_AMD64
depends on BR2_HOSTARCH = "x86_64" || BR2_HOSTARCH = "x86"
depends on !BR2_STATIC_LIBS
depends on BR2_x86_jaguar || BR2_x86_steamroller
+ depends on !BR2_X86_64_ABI_X32
select BR2_TOOLCHAIN_EXTERNAL_GLIBC
select BR2_TOOLCHAIN_HAS_NATIVE_RPC
select BR2_INSTALL_LIBSTDCPP
@@ -392,6 +393,7 @@ config BR2_TOOLCHAIN_EXTERNAL_CODESOURCERY_X86
depends on !BR2_STATIC_LIBS
depends on !BR2_x86_jaguar
depends on !BR2_x86_steamroller
+ depends on !BR2_X86_64_ABI_X32
select BR2_TOOLCHAIN_EXTERNAL_GLIBC
select BR2_TOOLCHAIN_HAS_NATIVE_RPC
select BR2_INSTALL_LIBSTDCPP
@@ -183,9 +183,13 @@ CC_TARGET_FPU_ := $(call qstrip,$(BR2_GCC_TARGET_FPU))
CC_TARGET_FLOAT_ABI_ := $(call qstrip,$(BR2_GCC_TARGET_FLOAT_ABI))
CC_TARGET_MODE_ := $(call qstrip,$(BR2_GCC_TARGET_MODE))
+ifeq ($(BR2_X86_64_ABI_X32),y)
+TOOLCHAIN_EXTERNAL_CFLAGS += -mx32
+TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_X32
+endif
# march/mtune/floating point mode needs to be passed to the external toolchain
# to select the right multilib variant
-ifeq ($(BR2_x86_64),y)
+ifeq ($(BR2_X86_64_ABI_SYSV),y)
TOOLCHAIN_EXTERNAL_CFLAGS += -m64
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_64
endif
@@ -198,9 +202,11 @@ TOOLCHAIN_EXTERNAL_CFLAGS += -mcpu=$(CC_TARGET_CPU_)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_CPU='"$(CC_TARGET_CPU_)"'
endif
ifneq ($(CC_TARGET_ABI_),)
+ifeq ($(BR2_X86_64_ABI_SYSV),y)
TOOLCHAIN_EXTERNAL_CFLAGS += -mabi=$(CC_TARGET_ABI_)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_ABI='"$(CC_TARGET_ABI_)"'
endif
+endif
ifneq ($(CC_TARGET_FPU_),)
TOOLCHAIN_EXTERNAL_CFLAGS += -mfpu=$(CC_TARGET_FPU_)
TOOLCHAIN_EXTERNAL_TOOLCHAIN_WRAPPER_ARGS += -DBR_FPU='"$(CC_TARGET_FPU_)"'
@@ -443,19 +449,20 @@ endef
# - usr/lib/
# - lib32/
# - lib64/
+# - libx32/ (x86_64 x32 toolchain)
# - lib32-fp/ (Cavium toolchain)
# - lib64-fp/ (Cavium toolchain)
# - usr/lib/<tuple>/ (Linaro toolchain)
#
# And variations on these.
define toolchain_find_sysroot
-$$(printf $(call toolchain_find_libc_a,$(1)) | sed -r -e 's:(usr/)?lib(32|64)?([^/]*)?/([^/]*/)?libc\.a::')
+$$(printf $(call toolchain_find_libc_a,$(1)) | sed -r -e 's:(usr/)?lib(32|x32|64)?([^/]*)?/([^/]*/)?libc\.a::')
endef
# Returns the lib subdirectory for the given compiler + flags (i.e
# typically lib32 or lib64 for some toolchains)
define toolchain_find_libdir
-$$(printf $(call toolchain_find_libc_a,$(1)) | sed -r -e 's:.*/(usr/)?(lib(32|64)?([^/]*)?)/([^/]*/)?libc.a:\2:')
+$$(printf $(call toolchain_find_libc_a,$(1)) | sed -r -e 's:.*/(usr/)?(lib(32|x32|64)?([^/]*)?)/([^/]*/)?libc.a:\2:')
endef
# Checks for an already installed toolchain: check the toolchain
@@ -480,6 +487,10 @@ define TOOLCHAIN_EXTERNAL_CONFIGURE_CMDS
"$(TOOLCHAIN_EXTERNAL_CC) $(TOOLCHAIN_EXTERNAL_CFLAGS)",\
$(TOOLCHAIN_EXTERNAL_READELF)) ; \
fi ; \
+ if test "$(BR2_X86_64_ABI_X32)" = "y" ; then \
+ $(call check_x86_64_x32_abi,\
+ "$(TOOLCHAIN_EXTERNAL_CC) $(TOOLCHAIN_EXTERNAL_CFLAGS)") ; \
+ fi ; \
if test "$(BR2_INSTALL_LIBSTDCPP)" = "y" ; then \
$(call check_cplusplus,$(TOOLCHAIN_EXTERNAL_CXX)) ; \
fi ; \
@@ -63,6 +63,9 @@ static char *predef_args[] = {
#ifdef BR_64
"-m64",
#endif
+#ifdef BR_X32
+ "-mx32",
+#endif
#ifdef BR_OMIT_LOCK_PREFIX
"-Wa,-momit-lock-prefix=yes",
#endif