Message ID | 20180629113339.59102-1-christoph.muellner@theobroma-systems.com |
---|---|
State | Changes Requested |
Headers | show |
Series | [1/1] toolchain: Fix ld.so copying for multilib toolchains. | expand |
> On 29.06.2018, at 13:40, Thomas Petazzoni <thomas.petazzoni@bootlin.com> wrote: > > Hello Christoph, > > Thanks for this contribution! > > On Fri, 29 Jun 2018 13:33:39 +0200, Christoph Muellner wrote: >> 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. >> >> Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com> >> Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> > > 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 > 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 > -- > Thomas Petazzoni, CTO, Bootlin (formerly Free Electrons) > Embedded Linux and Kernel engineering > https://bootlin.com > _______________________________________________ > buildroot mailing list > buildroot@busybox.net > http://lists.busybox.net/mailman/listinfo/buildroot
Hello, El vie., 29 jun. 2018 a las 13:51, Christoph Muellner (<christoph.muellner@theobroma-systems.com>) escribió: > > 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. > > Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com> > Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com> > --- > 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. > > diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk > index 1792286add..62c0454be5 100644 > --- a/toolchain/helpers.mk > +++ b/toolchain/helpers.mk > @@ -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'. > + 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
diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk index 1792286add..62c0454be5 100644 --- a/toolchain/helpers.mk +++ b/toolchain/helpers.mk @@ -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 \