PowerPC: incorrect library search order?
Commit Message
Hi,
The problem below resulted in failures of some PowerPC sample toolchains
in crosstool-ng.
As far as I understand, the code in ld/emulparams/elf32ppccommon.sh
attempts to use /lib32 or /lib64 if the endianness of the selected
emulation matches the endianness of the machine, and use the directories
with explicit endianness (such as /lib32le, /lib32be, /lib64le,
/lib64be) otherwise. However, there are two issues with that code:
First, it checks for *host's* triplet, not target. The host may not be
using 'le' suffix to designate its endianness - for example, it may be
little-endian by default. It also doesn't seem to make much sense to
check the host for default layout - why would the expected sysroot
layout on a big-endian host differ from that on a little-endian host?
Second, the check itself is flawed: it should be checking just the CPU
part of the triplet, not the whole string. In its current form, the
check compares $host against "*le-*" pattern - which matches
"x86_64-apple-darwin16.0".
This results in ld configured for powerpc64le-unknown-linux target on
x86_64-unknown-linux host behaving as follows:
- without -m, or with -melf64lppc it searches /lib64le first
- with '-melf64ppc' it searches /lib64 first - which seems to run
counter to the intended purpose of that code, as the target is
configured as little-endian!
'ld' works ok with libraries in /lib (which is always searched as the
last fallback, regardless of the host and selected emulation). Once the
libraries are placed in /lib64 (default gcc's directory for this
target), ld fails to find them.
This erroneous code first appeared in binutils 2.24.
Patch attached.
Regards,
Alexey.
Comments
Sorry, sent to wrong list. Will resend to binutils@
Alexey.
On 03/12/2017 08:26 PM, Alexey Neyman wrote:
> Hi,
>
> The problem below resulted in failures of some PowerPC sample
> toolchains in crosstool-ng.
>
> As far as I understand, the code in ld/emulparams/elf32ppccommon.sh
> attempts to use /lib32 or /lib64 if the endianness of the selected
> emulation matches the endianness of the machine, and use the
> directories with explicit endianness (such as /lib32le, /lib32be,
> /lib64le, /lib64be) otherwise. However, there are two issues with that
> code:
>
> First, it checks for *host's* triplet, not target. The host may not be
> using 'le' suffix to designate its endianness - for example, it may be
> little-endian by default. It also doesn't seem to make much sense to
> check the host for default layout - why would the expected sysroot
> layout on a big-endian host differ from that on a little-endian host?
>
> Second, the check itself is flawed: it should be checking just the CPU
> part of the triplet, not the whole string. In its current form, the
> check compares $host against "*le-*" pattern - which matches
> "x86_64-apple-darwin16.0".
>
> This results in ld configured for powerpc64le-unknown-linux target on
> x86_64-unknown-linux host behaving as follows:
> - without -m, or with -melf64lppc it searches /lib64le first
> - with '-melf64ppc' it searches /lib64 first - which seems to run
> counter to the intended purpose of that code, as the target is
> configured as little-endian!
>
> 'ld' works ok with libraries in /lib (which is always searched as the
> last fallback, regardless of the host and selected emulation). Once
> the libraries are placed in /lib64 (default gcc's directory for this
> target), ld fails to find them.
>
> This erroneous code first appeared in binutils 2.24.
>
> Patch attached.
>
> Regards,
> Alexey.
>
>
From cf2cf4ea661b8527d0fe48a9ffda1b02154d0c67 Mon Sep 17 00:00:00 2001
From: Alexey Neyman <stilor@att.net>
Date: Sat, 11 Mar 2017 17:27:09 -0800
Subject: [PATCH] Fix library paths on PowerPC
First, need to match against just the CPU name, not the whole triplet.
Otherwise, the test picks up "*le-*" pattern from x86_64-apple-darwin
triplet.
Second, it should be testing for $target, not $host. Host may be
little endian by default, and the sysroot directory layout shouldn't
depend on whether it is built on LE or BE machine.
Signed-off-by: Alexey Neyman <stilor@att.net>
---
ld/emulparams/elf32ppccommon.sh | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
@@ -44,11 +44,11 @@ fi
# Look for 64 bit target libraries in /lib64, /usr/lib64 etc., first.
# Similarly, look for 32 bit libraries in /lib32, /usr/lib32 etc.
-case "$host":"$EMULATION_NAME" in
- *le-*:*64lppc*) LIBPATH_SUFFIX=64 ;;
- *le-*:*32lppc*) LIBPATH_SUFFIX=32 ;;
- *le-*:*64*) LIBPATH_SUFFIX=64be ;;
- *le-*:*32*) LIBPATH_SUFFIX=32be ;;
+case `echo "$target" | sed -e 's/-.*//'`:"$EMULATION_NAME" in
+ *le:*64lppc*) LIBPATH_SUFFIX=64 ;;
+ *le:*32lppc*) LIBPATH_SUFFIX=32 ;;
+ *le:*64*) LIBPATH_SUFFIX=64be ;;
+ *le:*32*) LIBPATH_SUFFIX=32be ;;
*:*64lppc*) LIBPATH_SUFFIX=64le ;;
*:*32lppc*) LIBPATH_SUFFIX=32le ;;
*:*64*) LIBPATH_SUFFIX=64 ;;
--
2.9.3