#!/bin/sh • Binary ▫ a.out Don’t mess with the default compiler output! Very old and deprecated format ▫ COFF/ECOFF/XCOFF Superseded by ELF ▫ ELF • Almost all UNIX systems allow user to find out of what type a file is ▫ /usr/bin/file
compiled code ▫ Binary executable files ▫ Shared libraries (*.so ones) ▫ Object code • With ELF, there is only one difference between an executable file and shared library ▫ an executable file has an entry point – main()
pure C (and Fortran) programs ▫ Then, C++ arrived • Consider an example: ▫ How to put all these “main” functions in a single binary? class foo { void main(int); void main(int, char); }; int main(int, char **) {}
code fit into C libraries ▫ void main(char, int) -> void _Z1mainci(char, int) ▫ An underscore (or two) before the new name helps not to mess the generated names with manually chosen ones • Wikipedia has a perfect article on how different compilers mangle the same functions:
in /lib/ld.so ▫ On GNU/Linux: /lib/ld.so* for a.out files /lib/ld-linux.so* (currently .2) for ELF ▫ On HP-UX: /usr/lib/hpux{32,64}/{u,d}ld.so ▫ man pages: ld.so(8), dld.so(5) • There may be multiple BIs on the system! ▫ .interp ELF section ▫ On HP-UX, /usr/bin/ld has an +interp option
external function or library during compilation ▫ Runtime linker offers the dlopen() mechanism • Example: • Links: ▫ http://www.opengroup.org/onlinepubs/009695399/basedefs/dlf cn.h.html ▫ http://tldp.org/HOWTO/C++-dlopen/ /* open the needed object */ handle = dlopen("/usr/home/me/libfoo.so", RTLD_LOCAL); /* find the address of function objects */ *(void **)(&fptr) = dlsym(handle, "my_function"); /* invoke function, passing value of integer as a parameter */ (*fptr)(42);
during the start of a program ▫ By default, it looks at: /lib and /usr/lib /etc/ld.so.cache and /etc/ld.so.preload • The commonly used variables are: ▫ LD_LIBRARY_PATH ▫ LD_PRELOAD How /usr/bin/strace works? ▫ LD_TRACE_LOADED_OBJECTS /usr/bin/ldd
▫ Support for more binary formats ▫ The internal file representation of BFD is similar to the ELF one • Useful options: ▫ --demangle Kills the need in c++filt ▫ --disassemble-all