[Gllug] pimping my elf

Nix nix at esperi.org.uk
Wed Jun 21 18:53:39 UTC 2006

On Mon, 19 Jun 2006, Alex Sayle whispered secretively:
> On 18 Jun 2006, at 12:50BDT, Nix wrote:
>> On Wed, 14 Jun 2006, Alex Sayle stated:
>>> it looks a bit like <somepath>/bar/<version>/{lib,include,share} so
>>> we can have multiple libbar's co-existing.
>> I do this, roughly, using GNU stow. epkg, DEPOT, STORE and other  systems
>> do much the same (with ever-increasing degrees of flexibility and
>> byzantineness).
> I'm aware of stow and it works nicely when you have <somepath>/bar/
> where bar is your package, as we have version in the path this poses a
> problem :-/

Nah. Add a layer of indirection:

/usr/packages.bin/packages/{package} ->

As a benefit, installations of later versions now sort-of-work even
before a stow -R (if no new files turn up); installations of old
versions in parallel with new versions remains possible (cp -al the
package tree and delete most of the copy except for the stuff you want
to preserve, then symlink it to a name in the packages directory like
{package}-{version} or {package}-abi-break-preserve or whatever you want).

(This is actually exactly what I do: I clipped out that layer of
complexity for didactic purposes when explaining earlier.)

>> The first part should be a matter of course, with every active  thing in
>> the installed tree being symlinked into the stow tree (/usr/local or
>> whatever). Arrange for apps to look into the stow tree instead of the
>> installed tree for everything, and you're home free.
> True. this however does relay on only one version of each package
> being present in any given stow tree. One of the biggest reasons we
> have the full version in the library name is so that we can distinguish
> and allow co-habitation of minor revision changes in libraries.

*Minor*? Give up. They're not meant to be able to coexist, and there's
no reason they should be able to: later minor versions provide the same
functionality as earlier versions, and don't break the interface. The
ELF soname scheme provides for a way for *major* versions to coexist,
and that's all.

>> Note that at no point here are libraries hex-edited! The soname of a
>> library is part of its published ABI and should *not* be changed.  You
>> can rename the library all you like and ldconfig will create  appropriate
>> symlinks for you if they're missing (although because those symlinks
>> aren't stowed, I'd recommend against it; it'll cause you problems when
>> next you upgrade when the symlinks break).
> what I'm after is the explicitly and not the warm fuzzy feeling of  ldconfig.
> Two minor version needs to be linked against separately and  explicitly so
> ldconfig-ing them again doesn't work :-/

Well, ELF doesn't support what you're doing, and it's nearly impossible
to do. You'll have to hand-edit executables, or change the soname at the
time the library is generated (far preferred). Among other things this
involves maintaining patches to libtool, including to the horrible
ancient version of libtool that's used just to generate the shared
libraries used by GCC.

Have fun.

>> There's never a need to do this unless the library doesn't bother to
>> maintain its sonames properly (and virtually all of them do), and by
>> doing this you *destroy* any chance of interoperability with other  Linux
>> systems. ELF handles this stuff for you; don't make your life  difficult
>> by shooting it in the foot.
> correct. interoperability isn't, hasn't been and never will our goal  tho.
> As for shooting myself in the foot... well that's the great part about
> unix isn't it :) Its always got a bit rope for me to hang myself.

You'll need to start from a hemp factory and make your own rope in this
situation. Binary editing will work in *some* cases, but then if the length
differs, or the binary is signed (as some are in Mozilla/Thunderbird/Firefox)
you're stuffed unless you change the soname with which the library was
originally generated.

If you build everything yourself, that shouldn't be all that hard: you
just need to maintain several hundred to thousand separate patches. :/

> The entertaining bit about the environment I'm on is that this semi
> madness has so far prevailed and has flourished, somehow with out never
> having to link FOSS to FOSS. A lot of software has been written in-house
> which people write linker scripts for and thus are happy to link against
> the name changed version of libbar-<version>.so.


> As far as I can tell,this is the first time that there has been a  need to
> do build code that uses pkg-config and friends to determine linker flags
> (which of course spits out libbar.so.<version> which the originals  are called)

That's easy to fix: change the text files in ${prefix}/lib/pkgconfig/ :)

>> libelf, and pray. Hard.
> I was more thinking of libbed and objcopy to re-compose the libraries
> from its chunks. The field which hold the names in .dynstr section
> aren't long enough in many cases so that the elf header needs updating.

You'd have to take care: there are a lot of things in shared libraries
that are outside `chunks' yet must be conserved. Shared libraries aren't
just .a's with a different name. Other things you might need to preserve:

DT_NEEDED (dependency information)
Symbol versioning data
DT_FILTER et al (rarely used but critical when it's used)
DT_GROUP, global versus local, -Bdynamic et al (critical to proper
functioning of GCJ and G++-compiled programs for starters)

and much more: see the ELF spec.

`NB: Anyone suggesting that we should say "Tibibytes" instead of
 Terabytes there will be hunted down and brutally slain.
 That is all.' --- Matthew Wilcox
Gllug mailing list  -  Gllug at gllug.org.uk

More information about the GLLUG mailing list