[PATCH] sysroot.eclass: use correct dynamic linker for non-default ABI

James Le Cuirot <[email protected]>
Newsgroups gmane.linux.gentoo.devel
Message-ID <[email protected]>
From: Matt Whitlock <[email protected]>

The sysroot_make_run_prefixed function was assuming that all dynamically linked
executables that do not need QEMU can be executed via /usr/bin/ld.so, but this
is not true for non-default ABIs. For example, x86_32 binaries may need the
interpreter at /lib/ld-linux.so.2 despite that /usr/bin/ld.so may be a symlink
to /usr/lib64/ld-linux-x86-64.so.2.

Add a special case for non-default ABIs: compile and link a test executable
using $(tc-getCC) and examine its .interp section to find the actual dynamic
linker that it needs. Make the sysroot-run-prefixed script call that linker.

Signed-off-by: Matt Whitlock <[email protected]>
Part-of: https://github.com/gentoo/gentoo/pull/46067
Closes: https://github.com/gentoo/gentoo/pull/46067
Signed-off-by: James Le Cuirot <[email protected]>
---
 eclass/sysroot.eclass | 48 +++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 11 deletions(-)

diff --git a/eclass/sysroot.eclass b/eclass/sysroot.eclass
index 856aa3a9ec8f4..57e4a8b156c87 100644
--- a/eclass/sysroot.eclass
+++ b/eclass/sysroot.eclass
@@ -76,6 +76,22 @@ qemu_arch_if_needed() {
 	return 0
 }
 
+
+# @FUNCTION: _sysroot_compile_and_link_test_exe
+# @USAGE: <output-path-name>
+# @INTERNAL
+# @DESCRIPTION:
+# Compile and link a test executable that does nothing except to return success.
+# The executable is built for the *host* machine using $(tc-getCC), *not* for
+# the build machine using $(tc-getBUILD_CC).
+_sysroot_compile_and_link_test_exe() {
+	[[ -n "${1}" ]] || die 'Must specify test executable path name.'
+	local test="${1}"
+	echo 'int main(void) { return 0; }' > "${test}.c" || die "failed to write ${test##*/}.c"
+	$(tc-getCC) ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} -o "${test}" "${test}.c" || die "failed to build ${test##*/}"
+}
+
+
 # @FUNCTION: sysroot_make_run_prefixed
 # @DESCRIPTION:
 # Create a wrapper script for directly running executables within a (sys)root
@@ -135,15 +151,26 @@ sysroot_make_run_prefixed() {
 		einfo "Target is not Linux. Continuing without ${SCRIPT##*/} wrapper."
 		return 2
 	elif ! QEMU_ARCH=$(qemu_arch_if_needed); then
-		# glibc: ld.so is a symlink, ldd is a binary.
-		# musl: ld.so doesn't exist, ldd is a symlink.
-		local DLINKER candidate
-		for candidate in "${MYEROOT}"/usr/bin/{ld.so,ldd}; do
-			if [[ -L ${candidate} ]]; then
-				DLINKER=${candidate}
-				break
-			fi
-		done
+		local DLINKER
+		if [[ "${ABI-${DEFAULT_ABI}}" == "${DEFAULT_ABI}" ]]; then
+			# glibc: ld.so is a symlink, ldd is a binary.
+			# musl: ld.so doesn't exist, ldd is a symlink.
+			local candidate
+			for candidate in "${MYEROOT}"/usr/bin/{ld.so,ldd}; do
+				if [[ -L ${candidate} ]]; then
+					DLINKER=${candidate}
+					break
+				fi
+			done
+		else
+			# non-default ABI needs a non-default dynamic linker
+			SCRIPT+="-${ABI}"
+			local test="${SCRIPT}-test"
+			_sysroot_compile_and_link_test_exe "${test}"
+			read -d '' -r DLINKER < <($(tc-getOBJCOPY) -O binary -j .interp -- "${test}" /dev/stdout)
+			DLINKER="${DLINKER:+${MYEROOT}${DLINKER}}"
+			[[ -f ${DLINKER} && -x ${DLINKER} ]] || DLINKER=
+		fi
 		[[ -n ${DLINKER} ]] || die "failed to find dynamic linker"
 
 		# musl symlinks ldd to ld-musl.so to libc.so. We want the ld-musl.so
@@ -169,8 +196,7 @@ sysroot_make_run_prefixed() {
 		# and worse if QEMU does not support the architecture. We therefore need
 		# to perform our own test up front.
 		local test="${SCRIPT}-test"
-		echo 'int main(void) { return 0; }' > "${test}.c" || die "failed to write ${test##*/}"
-		$(tc-getCC) ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} "${test}.c" -o "${test}" || die "failed to build ${test##*/}"
+		_sysroot_compile_and_link_test_exe "${test}"
 
 		if ! "${SCRIPT}" "${test}" &>/dev/null; then
 			einfo "Failed to run ${test##*/}. Continuing without ${SCRIPT##*/} wrapper."
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.