Skip to contentSkip to conversation

toolchain: Fix ld.so copying for multilib toolchains.

PATCH New Christoph Muellner 3 participants 4 messages Jun 29, 2018 – Feb 4, 2019

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 toolchain: Fix ld.so copying for multilib toolchains.

Multilib toolchains can have more than one ld.so files in lib/. Typically one for each lib* directory.
However the current copy_toolchain_sysroot implemenation does not support more than one ld.so.

This patch addresses this by iterating over all ld.so files in the lib/ directory and choose the one, which has a symlink into $ARCH_LIB_DIR/.

An example is a multilib toolchain for aarch64 (LP64 and ILP32), which includes the following entries in lib/:

$ ls -l lib/
lrwxrwxrwx 1 user group ld-linux-aarch64_ilp32.so.1 -> ../libilp32/ld-2.27.so
lrwxrwxrwx 1 user group ld-linux-aarch64.so.1 -> ../lib64/ld-2.27.so

$ARCH_LIB_DIR/ will be detected as lib64.
Without the patch no ld.so will be copied.
With the patch the second ld.so (the one for LP64) will be copied.

---
 toolchain/helpers.mk | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
toolchain/helpers.mk +8 -3
index 1792286add..62c0454be5 100644
@@ -136,9 +136,14 @@ copy_toolchain_sysroot = \
 		done ; \
 	fi ; \
 	if [ ! -e $(STAGING_DIR)/lib/ld*.so.* ]; then \
-		if [ -e $${ARCH_SYSROOT_DIR}/lib/ld*.so.* ]; then \
-			cp -a $${ARCH_SYSROOT_DIR}/lib/ld*.so.* $(STAGING_DIR)/lib/ ; \
-		fi ; \
+		find $${ARCH_SYSROOT_DIR}/lib/ -name ld*.so.* -print0 | while IFS= read -r -d '' LD_SO; do \
+			LINKTARGET=`realpath $${LD_SO}` ; \
+			LINKTARGETDIR=`dirname $${LINKTARGET}` ; \
+			LINKTARGETBASE=`basename $${LINKTARGETDIR}` ; \
+			if [ "$${LINKTARGETBASE}" = "$${ARCH_LIB_DIR}" ]; then \
+				cp -a $${LD_SO} $(STAGING_DIR)/lib/ ; \
+			fi ; \
+		done ; \
 	fi ; \
 	if [ `readlink -f $${SYSROOT_DIR}` != `readlink -f $${ARCH_SYSROOT_DIR}` ] ; then \
 		if [ ! -d $${ARCH_SYSROOT_DIR}/usr/include ] ; then \
Signature · 1 line
2.11.0
#1 lore raw

PATCH 1/1 toolchain: Fix ld.so copying for multilib toolchains.

Hello Christoph,

Thanks for this contribution!

Quoted 16 lines · Christoph Muellner

Multilib toolchains can have more than one ld.so files in lib/. Typically one for each lib* directory.
However the current copy_toolchain_sysroot implemenation does not support more than one ld.so.

This patch addresses this by iterating over all ld.so files in the lib/ directory and choose the one, which has a symlink into $ARCH_LIB_DIR/.

An example is a multilib toolchain for aarch64 (LP64 and ILP32), which includes the following entries in lib/:

$ ls -l lib/
lrwxrwxrwx 1 user group ld-linux-aarch64_ilp32.so.1 -> ../libilp32/ld-2.27.so
lrwxrwxrwx 1 user group ld-linux-aarch64.so.1 -> ../lib64/ld-2.27.so
Quoted 6 lines

$ARCH_LIB_DIR/ will be detected as lib64.
Without the patch no ld.so will be copied.
With the patch the second ld.so (the one for LP64) will be copied.

Is it possible to access the problematic toolchain ?

It would be useful to understand better the problem, and potentially add some test cases to verify that future changes in the external toolchain logic does not break this special situation.

Thanks,

Thomas

Signature · 3 lines
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
#2 lore raw

PATCH 1/1 toolchain: Fix ld.so copying for multilib toolchains.

Quoted 24 lines · Thomas Petazzoni

Hello Christoph,

Thanks for this contribution!

Quoted 16 lines · Christoph Muellner

Multilib toolchains can have more than one ld.so files in lib/. Typically one for each lib* directory.
However the current copy_toolchain_sysroot implemenation does not support more than one ld.so.

This patch addresses this by iterating over all ld.so files in the lib/ directory and choose the one, which has a symlink into $ARCH_LIB_DIR/.

An example is a multilib toolchain for aarch64 (LP64 and ILP32), which includes the following entries in lib/:

$ ls -l lib/
lrwxrwxrwx 1 user group ld-linux-aarch64_ilp32.so.1 -> ../libilp32/ld-2.27.so
lrwxrwxrwx 1 user group ld-linux-aarch64.so.1 -> ../lib64/ld-2.27.so
Quoted 8 lines
Quoted 6 lines

$ARCH_LIB_DIR/ will be detected as lib64.
Without the patch no ld.so will be copied.
With the patch the second ld.so (the one for LP64) will be copied.

Is it possible to access the problematic toolchain ?

Toolchain can be downloaded here:

https://www.theobroma-systems.com/go/amp-7.3.0

I've been building an aarch64 image on an x86_64 host with the amp-7.3.0-20180630-crosstools toolchain.

Among other things, this toolchain has LP64 and ILP32 support for aarch64. The LP64 loader can be found here: $sysroot/lib/ld-linux-aarch64.so.1 The ILP64 loader can be found here: $sysroot/lib/ld-linux-aarch64_ilp32.so.1

Infos about aarch64 ILP32 can be found here:
https://wiki.linaro.org/Platform/arm64-ilp32

In my particular use case I'm building for LP64 (compiler default). Buildroot detects this correctly ($ARCH_LIB_DIR will be "$sysroot/lib64")

The $sysroot is located here: amp-7.3.0-20180630/aarch64-amp-linux-gnu/sysroot The loaders are in $sysroot/lib:

ld-linux-aarch64_ilp32.so.1 -> ../libilp32/ld-2.27.so #ILP32 ld-linux-aarch64.so.1 -> ../lib64/ld-2.27.so #LP64

Now the test "[ -e $${ARCH_SYSROOT_DIR}/lib/ld*.so.* ]" triggers a syntax error, because "[ -e ld1.so ld2.so ];" is invalid syntax.

What the patch does here is to iterate over all ld*.so* files in $sysroot/lib and checks if the given LD_SO is a symlink into $ARCH_LIB_DIR,
which is true for "ld-linux-aarch64.so.1 -> ../lib64/ld-2.27.so" in the LP64 case.

Thanks,
Christoph

Quoted 6 lines

It would be useful to understand better the problem, and potentially add some test cases to verify that future changes in the external toolchain logic does not break this special situation.

Thanks,

Quoted 9 lines

Thomas
--
Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons) Embedded Linux and Kernel engineering
https://bootlin.com
_______________________________________________
buildroot mailing list
buildroot at busybox.net
http://lists.busybox.net/mailman/listinfo/buildroot

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 874 bytes
Desc: Message signed with OpenPGP
URL: <http://lists.busybox.net/pipermail/buildroot/attachments/20180629/9f6c5af7/attachment.asc>

#3 lore raw

PATCH 1/1 toolchain: Fix ld.so copying for multilib toolchains.

In reply to Christoph Muellner

Hello,

El vie., 29 jun. 2018 a las 13:51, Christoph Muellner (<[email protected]>) escribi?:

Quoted 21 lines

Multilib toolchains can have more than one ld.so files in lib/. Typically one for each lib* directory.
However the current copy_toolchain_sysroot implemenation does not support more than one ld.so.

This patch addresses this by iterating over all ld.so files in the lib/ directory and choose the one, which has a symlink into $ARCH_LIB_DIR/.

An example is a multilib toolchain for aarch64 (LP64 and ILP32), which includes the following entries in lib/:

$ ls -l lib/
lrwxrwxrwx 1 user group ld-linux-aarch64_ilp32.so.1 -> ../libilp32/ld-2.27.so
lrwxrwxrwx 1 user group ld-linux-aarch64.so.1 -> ../lib64/ld-2.27.so

$ARCH_LIB_DIR/ will be detected as lib64.
Without the patch no ld.so will be copied.
With the patch the second ld.so (the one for LP64) will be copied.

Quoted 5 lines
---
 toolchain/helpers.mk | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

Please extend the commit message and refer to the toolchain in which you found this problem, with its link.
This will help future analysis when more rework in this area is needed.

Quoted 6 lines
toolchain/helpers.mk +0 -0
index 1792286add..62c0454be5 100644

toolchain/helpers.mk copy_toolchain_sysroot = \ · line 142

Quoted 10 lines
toolchain/helpers.mk +4 -3
@@ -136,9 +136,14 @@ copy_toolchain_sysroot = \
                done ; \
        fi ; \
        if [ ! -e $(STAGING_DIR)/lib/ld*.so.* ]; then \
-               if [ -e $${ARCH_SYSROOT_DIR}/lib/ld*.so.* ]; then \
-                       cp -a $${ARCH_SYSROOT_DIR}/lib/ld*.so.* $(STAGING_DIR)/lib/ ; \
-               fi ; \
+               find $${ARCH_SYSROOT_DIR}/lib/ -name ld*.so.* -print0 | while IFS= read -r -d '' LD_SO; do \
+                       LINKTARGET=`realpath $${LD_SO}` ; \
+                       LINKTARGETDIR=`dirname $${LINKTARGET}` ; \
+                       LINKTARGETBASE=`basename $${LINKTARGETDIR}` ; \

This is more correctly 'LINKTARGETDIRBASE' not 'LINKTARGETBASE', i.e. 'LINKTARGETBASE' would be 'ld.so.xxxx'.

toolchain/helpers.mk copy_toolchain_sysroot = \ · line 146

Quoted 4 lines
toolchain/helpers.mk +4 -0
+                       if [ "$${LINKTARGETBASE}" = "$${ARCH_LIB_DIR}" ]; then \
+                               cp -a $${LD_SO} $(STAGING_DIR)/lib/ ; \
+                       fi ; \
+               done ; \

I tested the changes both for the specified toolchain as for the Marvell-provided Octeon toolchain which is also multilib, and the expected ld.so files are indeed present on the target.

However, the new code assumes that the ld.so file matched with the find command is a symbolic link, and then assumes that it points to something identifyable with ARCH_LIB_DIR. I don't know whether it occurs in practice, but suppose:
a. a single file is found and it is a regular file
b. a single file is found, it is a symbolic link, but it points to something that is not containing ARCH_LIB_DIR as base. c. multiple files are found, they are not symbolic links.

Case a and b could be solved by falling back to a simple copy (of all matched files) if the link-comparing approach is not resulting in a match.
But case c is more complex. An alternative would be to actually inspect the architecture using readelf and compare it to the expected value, e.g. based on libc.a.

I don't know how far we should go...

Best regards,
Thomas