CRiSP Newsletter
Testimonials
| ELF Format files |
|
|
|
|
Its been an interesting couple of weeks trying to get the ELF converter to create a universal binary for Linux. With later GLIBC releases, the .hash section was replaced with a .gnu.hash section, and the /lib/ld-linux.so runtime linker understands this new section. (The new section is smaller and faster to link, especially with C++ apps which have long mangled names, and potentially hundreds or thousands of dynamic symbols, as is typical for GUI applications). What I have uncovered is redundancy in the ELF specification. There is a Program Header section which is used to bootstrap the executable into memory. Heres an example program header:
The LOAD sections are used to mmap the two key sections (code and data) into the memory image. Note the offset field: this specifies the byte offset into the ELF file where the segment resides. The runtime linker wants this to be on a page boundary. The VirtAddr and PhysAddr control how the app can address these sections whilst it is running. (I dont know why both fields are present or what happens if they are different - I think one is redundant). In addition to the Program headers, we have the section table. Think of the Program header as what the runtime linker needs to mmap the data into memory, and the section table as what the application uses internally, although much of the sections are irrelevant to a running program - the act of linker resolves addresses and so there is little need to use the sections. (The runtime linker will use some of the sections, e.g. to resolve dynamic symbols). Then we have the DYNAMIC section (.dynamic) which is an array of values - some are pointers, some are integers, used to list things like shared lib dependencies or pointers to the hash table.
So, we now have *three* places with similar information, and these can disagree. Here are some things to contemplate when they agree/disagree: 1. The kernel will refuse to load the executable of kill -9 on startup if the LOAD program header segments are not well formed (eg not on a 4K boundary). 2. The executable may run, but gdb may core dump. Older gdb's, e.g. 6.8, will core dump on a malformed executable, despite it running correctly. 3. gdb may run, but core dump on hitting a breakpoint. Even the gdb 7.2 release on Ubuntu 10.10 does this. Combine the above with Ubuntu 10.10 vs Centos 4.7 (RedHat AS4) and the permutations are a bit unwieldy. Also, because the runtime linker on the earlier Linux's is using different fields, highlights the redundancy and problems in getting this to work. So, at present I have an executable compiled on Ubuntu 10.10 which runs fine on Centos 4.7, but I now need to determine why the gdb on both systems is core dumping. Post created by CRiSP v10.0.2c-b5917 Read more http://crtags.blogspot.com/2010/12/elf-format-files.html |




