0

I am starring at the ld.so manpage on my Debian stable system. It currently states:

$ man ld.so
[...]
NOTES
   Hardware capabilities
       Some shared objects are compiled using hardware-specific instructions which do not exist on every CPU.  Such objects should be installed in directories whose names define the required hardware ca‐
       pabilities, such as /usr/lib/sse2/.  The dynamic linker checks these directories against the hardware of the machine and selects the most suitable version of a given shared object.  Hardware capa‐
       bility directories can be cascaded to combine CPU features.  The list of supported hardware capability names depends on the CPU.  The following names are currently recognized:

What surprises me is the last sentence:

The following names are currently recognized

That is currently not true (or at least not anymore), since all I can find is this:

% cat /etc/ld.so.conf.d/*
/usr/lib/x86_64-linux-gnu/libfakeroot
# Multiarch support
/usr/local/lib/i386-linux-gnu
/lib/i386-linux-gnu
/usr/lib/i386-linux-gnu
/usr/local/lib/i686-linux-gnu
/lib/i686-linux-gnu
/usr/lib/i686-linux-gnu
# libc default configuration
/usr/local/lib
# Multiarch support
/usr/local/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
# Legacy biarch compatibility support
/lib32
/usr/lib32
# Legacy biarch compatibility support
/libx32
/usr/libx32

Is it true that ld.so will magically find a library in -say- /usr/lib/sse2/ on my machine ?

Reference:

% apt-cache policy manpages
manpages:
  Installed: 5.10-1
  Candidate: 5.10-1
  Version table:
 *** 5.10-1 500
        500 http://deb.debian.org/debian bullseye/main amd64 Packages
        500 http://deb.debian.org/debian bullseye/main i386 Packages
        100 /var/lib/dpkg/status

For completeness here is the same output from a bullseye 32bits chroot:

% cat /etc/ld.so.conf.d/*
/usr/lib/i386-linux-gnu/libfakeroot
# Multiarch support
/usr/local/lib/i386-linux-gnu
/lib/i386-linux-gnu
/usr/lib/i386-linux-gnu
/usr/local/lib/i686-linux-gnu
/lib/i686-linux-gnu
/usr/lib/i686-linux-gnu
# libc default configuration
/usr/local/lib
Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
malat
  • 2,708
  • 4
  • 27
  • 47
  • hmm, it says "The following names are currently recognized: x86 **(32-bit only)**: ..." and doesn't mention 64-bit systems at all. Also, I think some of that stuff (cmov, i686, sse2(?)) are always available on amd64. Then again, you do have `i386` mentioned in the output of `apt-cache`, but do you actually have 32-bit packages installed? – ilkkachu Jul 07 '22 at 14:46

2 Answers2

2

The following is based on glibc based system (before 2.37 release)

Yes, it will, but since you’re on x86, only for 32-bit binaries. See for example libspeex1 which ships its library in /usr/lib/i386-linux-gnu/ (for all 32-bit x86 systems) and /usr/lib/i386-linux-gnu/sse2/ (for SSE2-capable 32-bit x86 systems). Another example is libx264-160 which ships its library in /usr/lib/i386-linux-gnu/ and /usr/lib/i386-linux-gnu/i686/sse2/ (for SSE2-capable i686-compatible 32-bit x86 systems).

This doesn’t rely on listing the capability-related directories in ld.so.conf etc.; ld.so looks for subdirectories of directories on its search path. If you run

/sbin/ldconfig -v 2>/dev/null | grep -A3 hwcap

you’ll see the capability-related directories which are used on your system (i.e. they contain libraries and ldconfig knows about them).

Another trick (works with 2.37 glibc) to find the search paths is as follow:

% LD_DEBUG=libs LD_LIBRARY_PATH=. /bin/true
   3626040:     find library=libc.so.6 [0]; searching
   3626040:      search path=./glibc-hwcaps/x86-64-v3:./glibc-hwcaps/x86-64-v2:.                (LD_LIBRARY_PATH)
malat
  • 2,708
  • 4
  • 27
  • 47
Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
0

Thanks to the help from @stephen-kitt, I discover there are also some undocumented "subfolders" on x86_64.

Eg:

$ sudo mkdir /usr/lib/x86_64-linux-gnu/haswell
$ sudo mkdir /usr/lib/x86_64-linux-gnu/avx512_1
$ sudo cp /usr/lib/x86_64-linux-gnu/libx264.so.160 /usr/lib/x86_64-linux-gnu/haswell
$ sudo cp /usr/lib/x86_64-linux-gnu/libx264.so.160 /usr/lib/x86_64-linux-gnu/avx512_1
$ sudo ldconfig
% sudo ldconfig -p | grep hwcap
        libx264.so.160 (libc6,x86-64, hwcap: 0x0004000000000000) => /lib/x86_64-linux-gnu/haswell/libx264.so.160
        libx264.so.160 (libc6,x86-64, hwcap: 0x0000000000000004) => /lib/x86_64-linux-gnu/avx512_1/libx264.so.160

For reference:

% apt-get source libc-bin
% cat sysdeps/x86/dl-procinfo.c | grep haswe
    "i586", "i686", "haswell", "xeon_phi"
% cat sysdeps/x86/dl-procinfo.c | grep avx
    "sse2", "x86_64", "avx512_1"

I've filled in a bug report for anyone interested:

malat
  • 2,708
  • 4
  • 27
  • 47