The ELF (Executable and Linkable Format) object file format designed by the Unix System Laboratories is now firmly established as the most commonly used format in Linux. Whilst there is a slight performance overhead when compared with other object file formats such as ECOFF and a.out, ELF is felt to be more flexible. ELF executable files contain executable code, sometimes refered to as text, and data. Tables within the executable image describe how the program should be placed into the processes virtual memory. Statically linked images are built by the linker (ld ), or link editor, into one single image containing all of the code and data needed to run this image. The image also specifies the layout in memory of this image and the address in the image of the first code to execute.
Figure: ELF Executable File Format
Figure shows the layout of a statically linked ELF executable image.
It is a simple C program that prints ``hello world'' and then exits. The header describes it as an ELF image with two physical headers (e_phnum is 2) starting 52 bytes (e_phoff ) from the start of the image file. The first physical header describes the executable code in the image. It goes at virtual address 0x8048000 and there is 65532 bytes of it. This is because it is a statically linked image which contains all of the library code for the printf() call to output ``hello world''. The entry point for the image, the first instruction for the program, is not at the start of the image but at virtual address 0x8048090 (e_entry ). The code starts immediately after the second physical header. This physical header describes the data for the program and is to be loaded into virtual memory at address 0x8059BB8. This data is both readable and writeable. You will notice that the size fo the data in the file is 2200 bytes (p_filesz ) whereas its size in memory is 4248 bytes. This because the first 2200 bytes contain pre-initialized data and the next 2048 bytes contain data that will be initialized by the executing code.
When Linux loads an ELF executable image into the processes virtual address space, it does not actually load the image.
It sets up the virtual memory data structures, the processes vm_area_struct tree and its page tables. When the program is executed page faults will cause the program's code and data to be fetched into physical memory. Unused portions of the program will never be loaded into memory. Once the ELF binary format loader is satisfied that the image is a valid ELF executable image it flushes the processes current executable image from its virtual memory. As this process is a cloned image (all processes are) this, old, image is the program that the parent process was executing, for exampel the command interpretter shell such as bash. This flushing of the old executable image discards the old virtual memory data structures and resets the processes page tables. It also clears away any signal handlers that were set up and closes any files which are open. At the end of the flush the process is ready for the new executable image. No matter what format the executable image is, the same information gets set up in the processes mm_struct . There are pointers to the start and end of the images code and data. These values are found as the ELF executable images physical headers are read and the sections of the program that they describe are mapped into the processes virtual address space. That is also when the vm_area_struct data structures are set up and the processes page tables are modified. The mm_struct data structure also contains pointers to the parameters to be passed to the program and to this processes environment variables.