First, why there are separate /lib
and /lib64
:
The Filesystem Hierarchy Standard
mentions that separate /lib
and /lib64
exist because:
10.1. There may be one or more variants of the /lib directory on systems which support more than one binary format requiring
separate libraries. (...) This is commonly used for 64-bit or 32-bit
support on systems which support multiple binary formats, but require
libraries of the same name. In this case, /lib32 and /lib64 might be
the library directories, and /lib a symlink to one of them.
On my Slackware 14.2 for example there are /lib
and /lib64
directories for 32-bit and 64-bit libraries respectively even though
/lib
is not as a symlink as the FHS snippet would suggest:
$ ls -l /lib/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11 2016 /lib/libc.so.6 -> libc-2.23.so
$ ls -l /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11 2016 /lib64/libc.so.6 -> libc-2.23.so
There are two libc.so.6
libraries in /lib
and /lib64
.
Each dynamically built
ELF binary
contains a hardcoded path to the interpreter, in this case either
/lib/ld-linux.so.2
or /lib64/ld-linux-x86-64.so.2
:
$ file main
main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not stripped
$ readelf -a main | grep 'Requesting program interpreter'
[Requesting program interpreter: /lib/ld-linux.so.2]
$ file ./main64
./main64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped
$ readelf -a main64 | grep 'Requesting program interpreter'
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
The job of the interpreter is to load necessary shared libraries. You
can ask a GNU interpreter what libraries it would load without even
running a binary using LD_TRACE_LOADED_OBJECTS=1
or a ldd
wrapper:
$ LD_TRACE_LOADED_OBJECTS=1 ./main
linux-gate.so.1 (0xf77a9000)
libc.so.6 => /lib/libc.so.6 (0xf760e000)
/lib/ld-linux.so.2 (0xf77aa000)
$ LD_TRACE_LOADED_OBJECTS=1 ./main64
linux-vdso.so.1 (0x00007ffd535b3000)
libc.so.6 => /lib64/libc.so.6 (0x00007f56830b3000)
/lib64/ld-linux-x86-64.so.2 (0x00007f568347c000)
As you can see a given interpreter knows exactly where to look for
libraries - 32-bit version looks for libraries in /lib
and 64-bit
version looks for libraries in /lib64
.
FHS standard says the following about /bin
:
/bin contains commands that may be used by both the system
administrator and by users, but which are required when no other
filesystems are mounted (e.g. in single user mode). It may also
contain commands which are used indirectly by scripts.
IMO the reason why there are no separate /bin
and /bin64
is that if we had
the file with the same name in both of these directories we couldn't call one of them
indirectly because we'd have to put /bin
or /bin64
first in
$PATH
.
However, notice that the above is just the convention - the Linux
kernel does not really care if you have separate /bin
and /bin64
.
If you want them, you can create them and setup your system accordingly.
You also mentioned Android - note that except for running a modified
Linux kernel it has nothing to do with GNU systems such as
Ubuntu - no glibc, no bash (by default, you can of course compile and deploy it manually), and also directory structure is
completely different.
/bin
and/sbin
there. What is the question? Are you asking about the difference between/lib
and/lib64
?x86_64
(neither for/bin
no for/sbin
)./bin64
.wine*32
andwine*64
).