Statifier, static link and Ermine
Why use Ermine? What's wrong with good old static linking and statifier ?
This is the oldest and most obvious method to make applications portable across systems. And it works to some degree. But there are certain disadvantages:
- Library availability
Static linking needs static libraries. While shared libraries are
either already installed or easily available, Static libraries are much
harder to get.
- Linkage dependencies
With shared libraries all dependent libraries are searched for the unresolved symbols.
Static linking leaves it to the developer to chase all those additional libraries.
- Linkage order
Shared libraries may be specified to the linker in any order, but with static libraries
the order is important. And it's not easy to find the correct order manually.
All the above can be overcome given enough time and effort.
But problems start to get serious when we deal with Plugins.
When an application uses dlopen to load some functionality at run-time you cannot avoid shared libraries any longer. An executable can be statically linked, but our main objective is not a statically linked executable, but a truly portable executable.
How widespread are plugin architectures? Let's see:
- Any Qt application
- Any KDE application
- Any GTK application
- Any GNOME application
- Any application using NSS (Network Switch Service) libraries. This included apparently simple applications such as ls.
- Any application using gconv libraries for encoding
- many more!
So while it's usually possible to create statically linked executables this doesn't guarantee the runtime portability of the executable.
These executable may be copied to similar systems and will work there. But when they are copied to a slightly different system (e.g. a different distribution or a different version of the same distribution) a segfault and other undefined behaviors are likely.
Statifier is another approach to creating portable executables, and it's quite different from static linking.
Statifier uses as input already built dynamically linked executables. It allows for the kernel and dynamic linker (ld-linux.so) to do all the work of loading the executable and all its shared libraries.
At this point Statifier creates a snapshot of the process memory image. This snapshot is saved as an ELF executable, with all the needed shared libraries inside.
More details about statifier can be found here:
Simple and easy, and no messing around with static linking! And it works, too!
Or to be more precise it used to work.
Recent Linux kernels introduced VDSO (Virtual Dynamic Shared Object) and stack randomization. Those things, while valuable features, don't play well with Statifier.
Ermine works in a fashion similar to Statifier, creating self-contained executables from dynamically-linked applications. But Ermine-packed applications are not snapshots: instead they can be thought of as small virtual machines.
And because of this an Ermine-packed application does not suffer from the problems created by VDSO/stack randomization.