help-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to use a different ld-linux.so?


From: John Reiser
Subject: Re: How to use a different ld-linux.so?
Date: Mon, 28 Jun 2004 15:01:31 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20030225

The rtldi tool looks interesting, but I'm not sure it will work in our
environment: we really need a way of choosing at runtime, not link time,
what the pathname to the linker will be.

rtldi chooses which ld-linux.so.2 at runtime, after the main executable
has been invoked by execve().  rtldi just happens to base its choice on
the contents of the PT_INTERP, something that was known at the time of
execve(); but it is obvious that a modified rtldi could consult time(),
read(), etc., [or even getenv()] to make its choice "more dynamically."

I'm curious, since you need to specify which runtime linker you want at
link time anyway, what's the advantage of rtldi over just specifying the
alternative linker directly with -Wl,--dynamic-linker at link time
IOW, in your example on the web page, why not just say:

    ... -Wl,--dynamic-linker=/2.2.4-24/ld-linux.so.2 ...

instead of invoking /2.2.4-24/rtldi ?

If you have an old a.elf main executable program that was linked
to run with libc.so.6, and you want to run that a.elf on a machine
whose libc.so.6 differs from the one which a.elf was linked against,
and you want a reasonable guarantee that it will work, then it may
be necessary to use something like rtldi to choose the matching
ld-linux.so.2 and libc.so.6 and other libraries as of the time of
static binding of a.elf.  In theory, libc.so.6 is backwards compatibile
(a given a.elf should run the same under any subsequent libc.so.6),
but in practice there have been too many bugs in {ld-linux.so.2,
libc.so.6, ...}.  For example, many programs linked for libc.so.6
under RedHat Linux 7.2 and earlier won't run under glibc-2.3.2.
The most effective way to run such a program may be to install the
old glibc-x.y.z[.rpm] in a different location, binary edit the PT_INTERP
string of the a.elf, and use rtldi.  This makes the old [edited] a.elf
simultaneously interoperable with other programs from different
libc.so.6 generations, and only the "oddball" program has to know.

I see that the latter sets up the
library path properly so you don't have to set LD_LIBRARY_PATH, but are
there other differences as well?

ld-linux.so.2, libc.so.6, libdl.so, libnss*.so, and _many_ other shared
libraries of a given released version, are a matched set.  They must be
used together, all from the same release, or not at all.  Mixing and
matching pieces from different glibc-x.y.z need not work.  In order to
use a consistent set that differs from the default set, you must invoke
the ld-linux.so.2 using "--library-path PATH" to specify the location
of the rest of the set.  Using --library-path supersedes LD_LIBRARY_PATH
for one execve() only, and does not interfere with chilren, execve()
with no fork(), or other processes.


  >> * Debugging: I can't debug because I can't find a way to convince GDB
  >> to invoke the program-to-be-debugged using an alternative runtime
  >> linker.

  jr>        $ gdb /lib/ld-linux.so.2
  jr>        (gdb) run --library-path /lib /bin/date
  jr> If you want to set breakpoints then put one near the end of
  jr> _dl_start_user where it invokes _dl_init_internal.  Inspect
  jr> /proc/<pid>/maps to find out what has been mapped, then use the
  jr> add-symbol-file command of gdb.  Find the offset from "objdump
  jr> --section-headers a.elf | grep text" then add the base from the
  jr> map of the address space.

Oy!  I need something simpler than that.  This is going to be a commonly
used environment.  We could look into doing that through a GDB init
script or something I guess.

Unless you modify execve() or ld-linux.so.2, or allow chroot, then
this is as close as you can get.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]