The parameter is not available for binutils older than 2.39. So move it to xcompile to provide backwards compatibility for a bit. Change-Id: I02982769ae2c356f037a747e85d155368bfcb730 Signed-off-by: Nico Huber <nico.h@gmx.de> Reviewed-on: https://review.coreboot.org/c/coreboot/+/83693 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Singer <service+coreboot-gerrit@felixsinger.de>
		
			
				
	
	
		
			557 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			557 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env bash
 | |
| #
 | |
| # SPDX-License-Identifier: GPL-2.0-only
 | |
| 
 | |
| # Usage: [--debug] [path to xgcc/bin directory]
 | |
| 
 | |
| # Enable debug output
 | |
| if [ "$1" = "--debug" ]; then
 | |
| 	shift
 | |
| 	set -x
 | |
| fi
 | |
| 
 | |
| # GENERIC_COMPILER_PREFIX defaults to empty but can be used to override
 | |
| # compiler search behavior
 | |
| TMPFILE=""
 | |
| XGCCPATH=$1
 | |
| 
 | |
| # payloads under payloads/external crossgcc path
 | |
| if [ -d "$(pwd)/../../../../util/crossgcc/xgcc/bin/" ]
 | |
| then
 | |
| 	XGCCPATH=${XGCCPATH:-"$(pwd)/../../../../util/crossgcc/xgcc/bin/"}
 | |
| fi
 | |
| 
 | |
| # libpayload crossgcc path
 | |
| if [ -d "$(pwd)/../../util/crossgcc/xgcc/bin/" ]
 | |
| then
 | |
| 	XGCCPATH=${XGCCPATH:-"$(pwd)/../../util/crossgcc/xgcc/bin/"}
 | |
| fi
 | |
| 
 | |
| # coreboot crossgcc path
 | |
| if [ -d "$(pwd)/util/crossgcc/xgcc/bin/" ]
 | |
| then
 | |
| 	XGCCPATH=${XGCCPATH:-"$(pwd)/util/crossgcc/xgcc/bin/"}
 | |
| fi
 | |
| 
 | |
| die() {
 | |
| 	echo "ERROR: $*" >&2
 | |
| 	exit 1
 | |
| }
 | |
| 
 | |
| clean_up() {
 | |
| 	if [ -n "$TMPFILE" ]; then
 | |
| 		rm -f "$TMPFILE" "$TMPFILE.c" "$TMPFILE.o"
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| trap clean_up EXIT
 | |
| 
 | |
| 
 | |
| program_exists() {
 | |
| 	type "$1" >/dev/null 2>&1
 | |
| }
 | |
| 
 | |
| 
 | |
| if [ "$("${XGCCPATH}/iasl" 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
 | |
| 	IASL=${XGCCPATH}/iasl
 | |
| elif [ "$(iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
 | |
| 	IASL=iasl
 | |
| fi
 | |
| 
 | |
| if program_exists "${XGCCPATH}/nasm" ; then
 | |
| 	NASM="${XGCCPATH}/nasm"
 | |
| elif program_exists nasm; then
 | |
| 	NASM=nasm
 | |
| fi
 | |
| 
 | |
| if program_exists "${XGCCPATH}/gcc"; then
 | |
| 	HOSTCC="${XGCCPATH}/gcc"
 | |
| elif program_exists gcc; then
 | |
| 	HOSTCC=gcc
 | |
| elif program_exists cc; then
 | |
| 	HOSTCC=cc
 | |
| else
 | |
| 	die "no host compiler found"
 | |
| fi
 | |
| 
 | |
| # Look for a C++ compiler (for kconfig's qconf), but don't fail if there is
 | |
| # none, just set the compiler to false(1) which will break early enough if
 | |
| # used while being less confusing than errors about "g not found" when
 | |
| # "$HOSTCXX -g" evaluates to "-g" and make drops the leading dash.
 | |
| if program_exists "${XGCCPATH}/g++"; then
 | |
| 	HOSTCXX="${XGCCPATH}/g++"
 | |
| elif program_exists g++; then
 | |
| 	HOSTCXX=g++
 | |
| elif program_exists c++; then
 | |
| 	HOSTCXX=c++
 | |
| else
 | |
| 	HOSTCXX=false
 | |
| fi
 | |
| 
 | |
| # try to find the core count using various methods
 | |
| CORES="$(getconf _NPROCESSORS_ONLN 2>/dev/null)"
 | |
| if [ -z "$CORES" ]; then
 | |
| 	NPROC=$(command -v nproc)
 | |
| 	if [ -n "$NPROC" ]; then
 | |
| 		CORES="$($NPROC)"
 | |
| 	fi
 | |
| fi
 | |
| if [ -z "$CORES" ]; then
 | |
| 	SYSCTL=$(command -v sysctl)
 | |
| 	if [ -n "$SYSCTL" ]; then
 | |
| 		CORES="$(${SYSCTL} -n hw.ncpu 2>/dev/null)"
 | |
| 	fi
 | |
| fi
 | |
| if [ -z "$CORES" ] && [ -f /proc/cpuinfo ]; then
 | |
| 	 CORES="$(grep 'processor' /proc/cpuinfo 2>/dev/null | wc -l)"
 | |
| fi
 | |
| 
 | |
| cat <<EOF
 | |
| # platform agnostic and host tools
 | |
| XGCCPATH:=${XGCCPATH}
 | |
| NASM:=${NASM}
 | |
| IASL:=${IASL}
 | |
| HOSTCC?=${HOSTCC}
 | |
| HOSTCXX?=${HOSTCXX}
 | |
| CPUS?=${CORES}
 | |
| 
 | |
| EOF
 | |
| 
 | |
| testcc() {
 | |
| 	local cc="$1"
 | |
| 	local cflags="$2"
 | |
| 	local tmp_c="$TMPFILE.c"
 | |
| 	local tmp_o="$TMPFILE.o"
 | |
| 	rm -f "$tmp_c" "$tmp_o"
 | |
| 	echo "void _start(void) {}" >"$tmp_c"
 | |
| 	"$cc" -nostdlib -Werror $cflags -c "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
 | |
| }
 | |
| 
 | |
| testld() {
 | |
| 	local gcc="$1"
 | |
| 	local cflags="$2"
 | |
| 	local ld="$3"
 | |
| 	local ldflags="$4"
 | |
| 	local tmp_o="$TMPFILE.o"
 | |
| 	local tmp_elf="$TMPFILE.elf"
 | |
| 	rm -f "$tmp_elf"
 | |
| 	testcc "$gcc" "$cflags" &&
 | |
| 	$ld -nostdlib -static $ldflags -o "$tmp_elf" "$tmp_o" >/dev/null 2>&1
 | |
| }
 | |
| 
 | |
| testas() {
 | |
| 	local gccprefix="$1"
 | |
| 	local twidth="$2"
 | |
| 	local arch="$3"
 | |
| 	local use_dash_twidth="$4"
 | |
| 	local endian="$5"
 | |
| 	local obj_file="$TMPFILE.o"
 | |
| 	local full_arch="elf$twidth-$arch"
 | |
| 
 | |
| 	rm -f "$obj_file"
 | |
| 	[ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth"
 | |
| 	[ -n "$endian" ] && endian="-$endian"
 | |
| 	"${gccprefix}as" $use_dash_twidth $endian -o "$obj_file" "$TMPFILE" \
 | |
| 		2>/dev/null || return 1
 | |
| 
 | |
| 	# Check output content type.
 | |
| 	local obj_type="$(LANG=C LC_ALL='' "${gccprefix}"objdump -p "$obj_file" 2>/dev/null)"
 | |
| 	local obj_arch="$(expr "$obj_type" : '.*format \(.[a-z0-9-]*\)')"
 | |
| 	[ "$obj_arch" = "$full_arch" ] || return 1
 | |
| 
 | |
| 	unset ASFLAGS LDFLAGS
 | |
| 	unset FLAGS_GCC CFLAGS_GCC CFLAGS_CLANG
 | |
| 
 | |
| 	if [ -n "$use_dash_twidth" ]; then
 | |
| 		ASFLAGS="--$twidth"
 | |
| 		FLAGS_GCC="-m$twidth"
 | |
| 		CFLAGS_CLANG="-m$twidth"
 | |
| 		LDFLAGS="-b $full_arch"
 | |
| 
 | |
| 	fi
 | |
| 
 | |
| 	# Special parameters only available in dash_twidth mode.
 | |
| 	[ -n "$use_dash_twidth" ] && case "$full_arch" in
 | |
| 		"elf32-i386" )
 | |
| 			LDFLAGS="$LDFLAGS -melf_i386"
 | |
| 			FLAGS_GCC="$FLAGS_GCC -Wl,-b,elf32-i386 -Wl,-melf_i386"
 | |
| 			CFLAGS_CLANG="$CFLAGS_CLANG -Wl,-b,elf32-i386 -Wl,-melf_i386"
 | |
| 			;;
 | |
| 	esac
 | |
| 
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| detect_special_flags() {
 | |
| 	local architecture="$1"
 | |
| 	# Check for an operational -m32/-m64
 | |
| 	testcc "$GCC"     "$FLAGS_GCC -m$TWIDTH " &&
 | |
| 		FLAGS_GCC="$FLAGS_GCC -m$TWIDTH "
 | |
| 
 | |
| 	# Use bfd linker instead of gold if available:
 | |
| 	testcc "$GCC"     "$FLAGS_GCC -fuse-ld=bfd" &&
 | |
| 		FLAGS_GCC="$FLAGS_GCC -fuse-ld=bfd" && LINKER_SUFFIX='.bfd'
 | |
| 
 | |
| 	testcc "$GCC"     "$FLAGS_GCC -fno-stack-protector" &&
 | |
| 		FLAGS_GCC="$FLAGS_GCC -fno-stack-protector"
 | |
| 	testcc "$GCC"     "$FLAGS_GCC -Wl,--build-id=none" &&
 | |
| 		FLAGS_GCC="$FLAGS_GCC -Wl,--build-id=none"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-address-of-packed-member $FLAGS_GCC" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-address-of-packed-member"
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC --param=min-pagesize=1024 $FLAGS_GCC" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC --param=min-pagesize=1024"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wflex-array-member-not-at-end" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wflex-array-member-not-at-end"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wcalloc-transposed-args" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wcalloc-transposed-args"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-unused-parameter" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-unused-parameter"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-sign-compare" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-sign-compare"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-empty-body" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-empty-body"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-missing-field-initializers" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-missing-field-initializers"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-override-init" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-override-init"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-ignored-qualifiers" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-ignored-qualifiers"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-shift-negative-value" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-shift-negative-value"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-unused-but-set-parameter" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-unused-but-set-parameter"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-type-limits" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-type-limits"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wno-cast-function-type" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wno-cast-function-type"
 | |
| 
 | |
| 	testcc "$GCC"      "$CFLAGS_GCC -Wextra" &&
 | |
| 		CFLAGS_GCC="$CFLAGS_GCC -Wextra"
 | |
| 
 | |
| 	# Disable warning on segments with RWX.
 | |
| 	# All loadable sections are placed in the same segment for simplicity.
 | |
| 	testld "$GCC" "$FLAGS_GCC" "${GCCPREFIX}ld${LINKER_SUFFIX}" \
 | |
| 		"$LDFLAGS --no-warn-rwx-segments" && \
 | |
| 		LDFLAGS="$LDFLAGS --no-warn-rwx-segments"
 | |
| 
 | |
| 	case "$architecture" in
 | |
| 	x86)
 | |
| 		;;
 | |
| 	x64)
 | |
| 		;;
 | |
| 	arm64)
 | |
| 		testld "$GCC" "$FLAGS_GCC" "${GCCPREFIX}ld${LINKER_SUFFIX}" \
 | |
| 		  "$LDFLAGS --fix-cortex-a53-843419" && \
 | |
| 		  LDFLAGS_ARM64_A53_ERRATUM_843419+=" --fix-cortex-a53-843419"
 | |
| 		;;
 | |
| 	riscv)
 | |
| 		testcc "$GCC" "$FLAGS_GCC -march=rv64iadc_zicsr_zifencei" &&
 | |
| 		  ARCH_SUFFIX="_zicsr_zifencei"
 | |
| 		;;
 | |
| 	esac
 | |
| }
 | |
| 
 | |
| detect_compiler_runtime() {
 | |
| 	test -z "$GCC" || \
 | |
| 	CC_RT_GCC="$(${GCC} ${CFLAGS_GCC} ${FLAGS_GCC} -print-libgcc-file-name)"
 | |
| 	if [ ${CLANG_RUNTIME} = "libgcc" ]; then
 | |
| 		CC_RT_CLANG=${CC_RT_GCC}
 | |
| 	else
 | |
| 		test -z "$CLANG" || \
 | |
| 		  CC_RT_CLANG="$(${CLANG} ${CFLAGS_CLANG} -print-libgcc-file-name 2>/dev/null)"
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| report_arch_toolchain() {
 | |
| 	cat <<EOF
 | |
| # elf${TWIDTH}-${TBFDARCH} toolchain (${GCC})
 | |
| ARCH_SUPPORTED+=${TARCH}
 | |
| SUBARCH_SUPPORTED+=${TSUPP-${TARCH}}
 | |
| ARCH_SUFFIX_${TARCH}:=${ARCH_SUFFIX}
 | |
| 
 | |
| # GCC
 | |
| GCC_CC_${TARCH}:=${GCC}
 | |
| GCC_CFLAGS_${TARCH}:=${CFLAGS_GCC} ${FLAGS_GCC}
 | |
| # Generally available for GCC's cc1:
 | |
| GCC_CFLAGS_${TARCH}+=-fno-delete-null-pointer-checks -Wlogical-op
 | |
| GCC_ADAFLAGS_${TARCH}:=${FLAGS_GCC}
 | |
| GCC_COMPILER_RT_${TARCH}:=${CC_RT_GCC}
 | |
| GCC_COMPILER_RT_FLAGS_${TARCH}:=${CC_RT_EXTRA_GCC}
 | |
| EOF
 | |
| if [ "${TARCH}" = "x86_64" ]; then
 | |
| cat <<EOF
 | |
| 	GCC_CFLAGS_${TARCH} += -malign-data=abi
 | |
| EOF
 | |
| fi
 | |
| cat <<EOF
 | |
| 
 | |
| # Clang
 | |
| CLANG_CC_${TARCH} := ${CLANG}
 | |
| CLANG_CFLAGS_${TARCH} := ${CFLAGS_CLANG}
 | |
| CLANG_CFLAGS_${TARCH} += -Qunused-arguments
 | |
| CLANG_CFLAGS_${TARCH} += -m${TWIDTH}
 | |
| # tone down clang compiler warnings
 | |
| CLANG_CFLAGS_${TARCH} += -Wno-unused-variable
 | |
| CLANG_CFLAGS_${TARCH} += -Wno-unused-function
 | |
| CLANG_CFLAGS_${TARCH} += -Wno-tautological-compare
 | |
| CLANG_CFLAGS_${TARCH} += -Wno-shift-overflow
 | |
| CLANG_CFLAGS_${TARCH} += -Wno-address-of-packed-member
 | |
| CLANG_CFLAGS_${TARCH} += -Wno-initializer-overrides
 | |
| CLANG_CFLAGS_${TARCH} += -fbracket-depth=2048
 | |
| CLANG_CFLAGS_${TARCH} += -mllvm
 | |
| CLANG_CFLAGS_${TARCH} += -asm-macro-max-nesting-depth=1000
 | |
| CLANG_COMPILER_RT_${TARCH}:=${CC_RT_CLANG}
 | |
| CLANG_COMPILER_RT_FLAGS_${TARCH}:=${CC_RT_EXTRA_CLANG}
 | |
| # Leak the target arch into the preprocessor flags with clang.
 | |
| # This is needed to preprocess linker scripts
 | |
| CLANG_CPPFLAGS_${TARCH}:=${CPPFLAGS_CLANG}
 | |
| 
 | |
| # GCC/Clang Common
 | |
| ifeq (\$(CONFIG_COMPILER_GCC)\$(CONFIG_LP_COMPILER_GCC),y)
 | |
| 	CC_${TARCH}:=\$(GCC_CC_${TARCH})
 | |
| 	CFLAGS_${TARCH}:=\$(GCC_CFLAGS_${TARCH})
 | |
| 	COMPILER_RT_${TARCH}:=\$(GCC_COMPILER_RT_${TARCH})
 | |
| 	COMPILER_RT_FLAGS_${TARCH}:=\$(GCC_COMPILER_RT_FLAGS_${TARCH})
 | |
| else
 | |
| 	CC_${TARCH}:=\$(CLANG_CC_${TARCH})
 | |
| 	CFLAGS_${TARCH}:=\$(CLANG_CFLAGS_${TARCH})
 | |
| 	CPPFLAGS_${TARCH}:=\$(CLANG_CPPFLAGS_${TARCH})
 | |
| 	COMPILER_RT_${TARCH}:=\$(CLANG_COMPILER_RT_${TARCH})
 | |
| 	COMPILER_RT_FLAGS_${TARCH}:=\$(CLANG_COMPILER_RT_FLAGS_${TARCH})
 | |
| endif
 | |
| EOF
 | |
| 
 | |
| # Generally the x86 should build for i686 -- no sse/mmx
 | |
| # instructions since SMM modules are compiled using these
 | |
| # flags. Note that this doesn't prevent a project using
 | |
| # xcompile to explicitly specify -mmsse, etc flags.
 | |
| # The Quark processor doesn't support the instructions
 | |
| # introduced with the Pentium 6 architecture, so allow it
 | |
| # to use i586 instead.
 | |
| if [ "${TARCH}" = "x86_64" ]; then
 | |
| cat <<EOF
 | |
| 	CFLAGS_${TARCH} += -march=nocona
 | |
| EOF
 | |
| fi
 | |
| 
 | |
| if [ "${TARCH}" = "x86_32" ]; then
 | |
| cat <<EOF
 | |
| 
 | |
| CFLAGS_${TARCH} += -march=i686
 | |
| EOF
 | |
| fi
 | |
| 
 | |
| cat <<EOF
 | |
| 
 | |
| CPP_${TARCH}:=${GCCPREFIX}cpp
 | |
| AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS}
 | |
| LD_${TARCH}:=${GCCPREFIX}ld${LINKER_SUFFIX} ${LDFLAGS}
 | |
| GCOV_${TARCH}:=${GCCPREFIX}gcov
 | |
| EOF
 | |
| 
 | |
| 	if [ "${TARCH}" = "arm64" ] && \
 | |
| 			[ -n "${LDFLAGS_ARM64_A53_ERRATUM_843419}" ]; then
 | |
| 		cat <<EOF
 | |
| 
 | |
| ifeq (\$(CONFIG_ARM64_A53_ERRATUM_843419),y)
 | |
| 	LD_${TARCH}+=${LDFLAGS_ARM64_A53_ERRATUM_843419}
 | |
| endif
 | |
| 
 | |
| EOF
 | |
| 	fi # if [ "${TARCH}" = "arm64" ]...
 | |
| 
 | |
| 	cat <<EOF
 | |
| ifeq (\$(CONFIG_COMPILER_GCC)\$(CONFIG_LP_COMPILER_GCC),y)
 | |
| 	NM_${TARCH}:=${GCCPREFIX}gcc-nm
 | |
| 	AR_${TARCH}:=${GCCPREFIX}gcc-ar
 | |
| else
 | |
| 	NM_${TARCH}:=${GCCPREFIX}nm
 | |
| 	AR_${TARCH}:=${GCCPREFIX}ar
 | |
| endif
 | |
| OBJCOPY_${TARCH}:=${GCCPREFIX}objcopy
 | |
| OBJDUMP_${TARCH}:=${GCCPREFIX}objdump
 | |
| READELF_${TARCH}:=${GCCPREFIX}readelf
 | |
| STRIP_${TARCH}:=${GCCPREFIX}strip
 | |
| GNATBIND_${TARCH}:=${GCCPREFIX}gnatbind
 | |
| CROSS_COMPILE_${TARCH}:=${GCCPREFIX}
 | |
| 
 | |
| 
 | |
| EOF
 | |
| #The two blank lines above are intentional separators
 | |
| }
 | |
| 
 | |
| # Architecture definitions
 | |
| SUPPORTED_ARCHITECTURES="arm arm64 riscv x64 x86 ppc64"
 | |
| 
 | |
| # TARCH: local name for the architecture
 | |
| # (used as CC_${TARCH} in the build system)
 | |
| # TBFDARCHS: architecture name in binutils (eg elf32-${TBFDARCH})
 | |
| # TCLIST: first part of the compiler triplet (eg i386 in i386-elf)
 | |
| # TWIDTH: numerical argument for cpu mode: gcc -m${TWIDTH}
 | |
| # TSUPP: supported subarchs (for -mcpu=...)
 | |
| # TABI: typically elf, eabi or linux
 | |
| 
 | |
| arch_config_arm() {
 | |
| 	TARCH="arm"
 | |
| 	TBFDARCHS="littlearm"
 | |
| 	TCLIST="armv7-a armv7a arm"
 | |
| 	TWIDTH="32"
 | |
| 	TSUPP="arm armv4 armv7 armv7_m armv7_r"
 | |
| 	TABI="eabi"
 | |
| }
 | |
| 
 | |
| arch_config_arm64() {
 | |
| 	TARCH="arm64"
 | |
| 	TBFDARCHS="littleaarch64"
 | |
| 	TCLIST="aarch64"
 | |
| 	TWIDTH="64"
 | |
| 	TSUPP="arm64 armv8_64"
 | |
| 	TABI="elf"
 | |
| }
 | |
| 
 | |
| arch_config_riscv() {
 | |
| 	TARCH="riscv"
 | |
| 	TBFDARCHS="littleriscv"
 | |
| 	TCLIST="riscv64 riscv"
 | |
| 	TWIDTH="64"
 | |
| 	TABI="elf"
 | |
| }
 | |
| 
 | |
| arch_config_x64() {
 | |
| 	TARCH="x86_64"
 | |
| 	TBFDARCHS="x86-64"
 | |
| 	TCLIST="x86_64"
 | |
| 	TWIDTH="64"
 | |
| 	TABI="elf"
 | |
| }
 | |
| 
 | |
| arch_config_x86() {
 | |
| 	TARCH="x86_32"
 | |
| 	TBFDARCHS="i386"
 | |
| 	TCLIST="i386 x86_64"
 | |
| 	TWIDTH="32"
 | |
| 	TABI="elf"
 | |
| 	CC_RT_EXTRA_GCC="--wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3"
 | |
| }
 | |
| 
 | |
| arch_config_ppc64() {
 | |
| 	TARCH="ppc64"
 | |
| 	TBFDARCHS="powerpc"
 | |
| 	TCLIST="powerpc64"
 | |
| 	TWIDTH="64"
 | |
| 	TSUPP="ppc64"
 | |
| 	TABI="linux-gnu" # there is no generic ABI on ppc64
 | |
| }
 | |
| 
 | |
| # Right now, the clang reference toolchain is not building compiler-rt builtins
 | |
| # for any of the cross compile architectures. Hence we use libgcc for now,
 | |
| # because that is available and lets us proceed with getting coreboot clang
 | |
| # ready. Toggle CLANG_RUNTIME if you want to experiment with compiler-rt.
 | |
| 
 | |
| CLANG_RUNTIME="libgcc"
 | |
| # CLANG_RUNTIME="compiler-rt"
 | |
| 
 | |
| test_architecture() {
 | |
| 	local architecture=$1
 | |
| 	local endian gccprefix search
 | |
| 
 | |
| 	GCCPREFIX="invalid"
 | |
| 	unset TABI TARCH TBFDARCH TCLIST TENDIAN TSUPP TWIDTH
 | |
| 	unset CC_RT_EXTRA_GCC CC_RT_EXTRA_CLANG
 | |
| 	unset GCC CLANG
 | |
| 	unset ARCH_SUFFIX
 | |
| 	if type "arch_config_$architecture" > /dev/null; then
 | |
| 		"arch_config_$architecture"
 | |
| 	else
 | |
| 		die "no architecture definition for $architecture"
 | |
| 	fi
 | |
| 
 | |
| 	# To override toolchain, define CROSS_COMPILE_$arch or CROSS_COMPILE as
 | |
| 	# environment variable.
 | |
| 	# Ex: CROSS_COMPILE_arm="armv7a-cros-linux-gnueabi-"
 | |
| 	#     CROSS_COMPILE_x86="i686-pc-linux-gnu-"
 | |
| 	search="$(eval echo "\$CROSS_COMPILE_$architecture" 2>/dev/null)"
 | |
| 	search="$search $CROSS_COMPILE"
 | |
| 	for toolchain in $TCLIST; do
 | |
| 		search="$search $XGCCPATH$toolchain-$TABI-"
 | |
| 		search="$search $toolchain-$TABI-"
 | |
| 		search="$search $toolchain-linux-gnu-"
 | |
| 		search="$search $toolchain-linux-"
 | |
| 		search="$search $toolchain-"
 | |
| 		search="$search $toolchain-linux-gnueabi-"
 | |
| 	done
 | |
| 	echo "###########################################################################"
 | |
| 	echo "# $architecture"
 | |
| 	echo "# TARCH_SEARCH=$search"
 | |
| 
 | |
| 	# Search toolchain by checking assembler capability.
 | |
| 	for TBFDARCH in $TBFDARCHS; do
 | |
| 		for gccprefix in $search "$GENERIC_COMPILER_PREFIX"; do
 | |
| 			program_exists "${gccprefix}as" || continue
 | |
| 			for endian in $TENDIAN ""; do
 | |
| 				{ testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \
 | |
| 					"" "$endian" ||
 | |
| 				testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \
 | |
| 					"TRUE" "$endian" ; } && \
 | |
| 				testcc "${gccprefix}gcc" "$CFLAGS_GCC" "$FLAGS_GCC" && \
 | |
| 				GCCPREFIX="$gccprefix" && \
 | |
| 				break 3
 | |
| 			done
 | |
| 		done
 | |
| 	done
 | |
| 	if [ "invalid" != "$GCCPREFIX" ]; then
 | |
| 		GCC="${GCCPREFIX}gcc"
 | |
| 	fi
 | |
| 
 | |
| 	for clang_arch in $TCLIST invalid; do
 | |
| 		for clang_prefix in $search $XGCCPATH "$GENERIC_COMPILER_PREFIX"; do
 | |
| 			testcc "${clang_prefix}clang" "-target ${clang_arch}-none-unknown-${TABI} -c" && break 2
 | |
| 		done
 | |
| 	done
 | |
| 
 | |
| 	if [ "invalid" != "$clang_arch" ]; then
 | |
| 		# FIXME: this may break in a clang && !gcc configuration,
 | |
| 		# but that's more of a clang limitation. Let's be optimistic
 | |
| 		# that this will change in the future.
 | |
| 		CLANG="${clang_prefix}clang"
 | |
| 		CLANG_TARGET="-target ${clang_arch}-none-unknown-${TABI}"
 | |
| 		CFLAGS_CLANG="$CLANG_TARGET $CFLAGS_CLANG"
 | |
| 		CPPFLAGS_CLANG="$CLANG_TARGET $CPPFLAGS_CLANG"
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| OUT="$(mktemp /tmp/temp.XXXXXX 2>/dev/null || echo /tmp/temp.coreboot.$RANDOM)"
 | |
| rm -f $OUT
 | |
| 
 | |
| for architecture in $SUPPORTED_ARCHITECTURES; do
 | |
| 	(
 | |
| 	TMPFILE="$(mktemp /tmp/temp.XXXXXX 2>/dev/null || echo /tmp/temp.coreboot.$RANDOM)"
 | |
| 	touch $TMPFILE
 | |
| 	test_architecture "$architecture"
 | |
| 	detect_special_flags "$architecture"
 | |
| 	detect_compiler_runtime "$architecture"
 | |
| 	report_arch_toolchain
 | |
| 	clean_up
 | |
| 	) > $OUT.$architecture &
 | |
| done
 | |
| wait
 | |
| 
 | |
| for architecture in $SUPPORTED_ARCHITECTURES; do
 | |
| 	cat $OUT.$architecture
 | |
| 	rm -f $OUT.$architecture
 | |
| done
 | |
| echo XCOMPILE_COMPLETE:=1
 |