Example: If the PT_INTERP
of an executable a.elf is /2.2.4-24/rtldi (instead of /lib/ld-linux.so.2), then the
executable runs effectively as if it were invoked via
/2.2.4-24/ld-linux.so.2 --library-path
/2.2.4-24:$LD_LIBRARY_PATH /path/of/execve/a.elf args...
and will use /2.2.4-24/libc.so.6
for its glibc6. rtldi
uses its own path prefix in PT_INTERP
as the prefix for ld-linux.so.2,
and as the first directory path in the colon-separated list argument
following --library-path.
The --library-path
argument replaces LD_LIBRARY_PATH for a.elf only, without modifying
LD_LIBRARY_PATH for a.elf
or for any children that a.elf
may invoke. (This is a feature of ld-linux.so.2.) Also, the
process name remains "a.elf".
New ELF executables can specify the runtime loader by building with -Wl,--dynamic-linker=/path/to/rtldi. Old executables that specify /lib/ld-linux.so.2 for their PT_INTERP can be modified by using a binary file editor. Find the Offset of the INTERP string by using readelf --program-headers a.elf. The replacement string cannot be longer, and must be terminated by '\0'; thus the limit is 18 bytes.
Strategy for old executables: Choose a naming convention. The examples above use the version string of the glibc6 distribution .rpm file. The final component name of the PT_INTERP does not matter; choosing a one-character name such as ',' [comma: "/path/,"] allows using more characters elsewhere in the path.
Version 0.94 of rtldi sets argv[0] to the complete path that was specified to execve(), unless argv[0] already contains a '/'. ld-linux.so.2 needs this because it does not search $PATH. As a result, rtldi does not work for programs that interpret argv[0] as something else. There is a race in the double interpretation of the path to the executable (once by execve and once by ld-linux.so.2), so don't move, remove or modify the executable while using rtldi.
Version 0.93 of rtldi works better with gdb than previous versions. (gdb) set stop-on-solib-events 1 appears to work, although some versions of gdb give complaints which should be ignored. The next and step commands of gdb-5.3post-0.20021129.18rh do not work; use explicit breakpoints instead. This bug in gdb is fixed in gdb-5.3.90-0.20030710.41rh. Version 0.93 of rtldi manages to preserve a good symlink /proc/pid/exe most of the time.
Note: the full glibc6 environment includes many .so files. The safest is
to include a copy or link to each file in the glibc package that
normally lives in /lib.
For example, rpm -ql
glibc-2.3.2-27.9.7 shows these files:
tls/libc-2.3.2.so | i686/libc-2.3.2.so | ld-2.3.2.so |
tls/libc.so.6 | i686/libc.so.6 | ld-linux.so.2 |
tls/libm-2.3.2.so | i686/libm-2.3.2.so | libc-2.3.2.so |
tls/libm.so.6 | i686/libm.so.6 | libc.so.6 |
tls/libpthread-0.34.so | i686/libpthread-0.10.so | libpthread-0.10.so |
tls/libpthread.so.0 | i686/libpthread.so.0 | libpthread.so.0 |
tls/librt-2.3.2.so | i686/librt-2.3.2.so | librt-2.3.2.so |
tls/librt.so.1 | i686/librt.so.1 | librt.so.1 |
tls/libthread_db-1.0.so | libthread_db-1.0.so | |
tls/libthread_db.so.1 | libthread_db.so.1 | |
libm-2.3.2.so | ||
libm.so.6 | ||
|
libnsl-2.3.2.so | |
libnsl.so.1 | ||
libdl-2.3.2.so | ||
libdl.so.2 | ||
libutil-2.3.2.so | ||
libutil.so.1 | ||
libresolv-2.3.2.so | ||
libresolv.so.2 | ||
libBrokenLocale-2.3.2.so | ||
libBrokenLocale.so.1 | ||
libNoVersion-2.3.2.so | ||
libNoVersion.so.1 | ||
libSegFault.so | ||
libanl-2.3.2.so | ||
libanl.so.1 | ||
libcrypt-2.3.2.so | ||
libcrypt.so.1 |