https://access.redhat.com/articles/8167
Updated 2012年九月16日10:04 -
Here are a few details which should enable everybody to understand and investigate the issue of LD_ASSUME_KERNEL
closer by her/himself.
-
First,
LD_ASSUME_KERNEL
is handled by the dynamic linker. -
The behavior of a specific value of
LD_ASSUME_KERNEL
is not hardcoded in the dynamic linker. -
Every DSO (Dynamic Shared Object, aka shared library) can tell the dynamic linker in glibc which minimum OS ABI version is needed. Dynamic linkers other than glibc's do not have this feature. The information about the minimum OS ABI version is encoded in a ELF note section usually named
.note.ABI-tag
. This note section must be referenced by aPT_NOTE
entry in the DSO's program header.To examine the content of a DSO's note section use the
readelf
program fromelfutils
(the version frombinutils
is not capable enough). On Red Hat system the binary is calledeu-readelf
. Using it on a Fedora Core 2 system shows the following:$ eu-readelf -n /lib/tls/libc-2.3.3.so Note segment of 32 bytes at offset 0x174: Owner Data size Type GNU 16 VERSION OS: Linux, ABI: 2.4.20
This means the
/lib/tls/libc-2.3.3.so
DSO requires at least OS ABI version 2.4.20. -
The specific ABI version requirements on Red Hat Linux 9 and Fedora Core 1 and 2 system are as follows (this implies IA-32 is the architecture):
-
DSOs in
/lib/tls
need ABI version 2.4.20. -
DSOs in
/lib/i686
need ABI version 2.4.1. -
DSOs in
/lib
need ABI version 2.2.5.
-
This means no LD_ASSUME_KERNEL
setting requesting versions earlier than 2.2.5 will work at all. Versions from 2.2.5 to 2.4.0 will use the DSOs in /lib
, versions from 2.4.1 to 2.4.19 will use the DSOs in /lib/i686
, versions 2.4.20 and younger will use the DSOs in /lib/tls
.
For the Red Hat releases this layout was chosen to provide the maximum amount of backward compatibility for broken applications (correctly written applications have no problems anyway). The code in /lib
consists of the very early LinuxThreads code which had fixed size threads which could not be placed by the application. The version in /lib/i686
is the LinuxThreads code which does away with this limitation (aka floating stacks). The code in /lib/tls
is the new NPTL POSIX thread library.
-
The fact that a DSO has a more stringent version requirement does not mean it is automatically chosen. The dynamic only rejects loading DSOs based on the version information, it does not look for the best fit. The above description is true because the dynamic linker always looks in the directories
/lib/tls
,/lib/i686
, and/lib
in this order. Why this is the case is complicated and not explained here. Read the dynamic linker source code. -
For architectures other than IA-32 the situation is similar, but less complicated. In Red Hat Enterprise Linux version 3 only two versions of glibc are needed, one using LinuxThreads and one using NPTL. The very old LinuxThreads code is not needed.