CRiSP Newsletter
Testimonials
| ELF. ELF. ELF. Dont do it! |
|
|
|
|
This is interesting...to me at least. How to create a "universal" Linux binary. A universal binary is one which can be created on one kernel/glibc distro but run on all prior and future releases (or as many as I have or can catalog). Its common to want the latest/greatest distro on your main machine. (I currently run Ubuntu 10.10). But if I build software (such as CRiSP) on that host, I want it to run on all prior Ubuntu/RedHat/whatever systems. Building on each one when there is close to zero difference is a waste of energy and time. I experimented a while back and found that glibc makes judicious incompatible changes to the headers and libc, enticing applications to only run on the glibc it was built on or later. On investigating what was triggering this, I found it was things I didnt care about. E.g. <ctype.h> which has always been implemented as #defines and bitmap indexing into an array (isdigit(), isalpha(), etc) was replaced by libc calls (to handle Unicode or widechar types). Since I dont use these, I dont need that headache. After trying to run my binary on a failing older glibc, I worked out the headers to avoid, and wrote a tool to patch the ELF executable to patch the GLIBC version requirements. This works well. At least it did. But Ubuntu 10.10 is running glibc 12.1. Here, when I create my universal binary, I find it doesnt work on an earlier glibc. Instead I get a cryptic "error loading shared library: glibc 2.5 or later dynamic linker" is required. What on earth happened? Where is this "information" telling the /lib/ld-linux.so.2 that my binary needs such a thing? Heres a good link from Ali Bahrami: http://blogs.sun.com/ali/entry/gnu_hash_elf_sections. The binutils people have decided to break ELF backwards compatibility (or is that forward compatibility?). Instead of a ".hash" ELF section - required by the rt.ld dynamic linker (/lib/ld-linux.so.2), they create a new style of hash table, as described in that link above. Now consider an older dynamic linker. It is expecting a ".hash" section. But executables on glibc 12.1 (could be earlier releases too - it may have existed on Ubuntu 10.04, but I havent verified when this occurred yet), dont have a ".hash" section. Instead we have a ".gnu.hash" section.
So, I am asserting by doing this, the older runtime linker gets confused, and refuses to run the executable. You are really SOL here, as its not as if you can use LD_LIBRARY_PATH or LD_PRELOAD to bypass /lib/ld-linux.so.2. You could do this with a chroot/jail, but that gets fiddly and may require root access - or any number of things to send your customers scurry for the Windows installation disks. So - for my next trick, lets trying patching in an ELF conformant ".hash" section and see if we can get an older glibc to "like" my executables. I'll post an update if I am successful or not. Post created by CRiSP v10.0.2c-b5917 Read more http://crtags.blogspot.com/2010/11/elf-elf-elf-dont-do-it.html |




