0

The running process has nothing to do with the program headers but when we print the address(0x08048000) we can see the ELF header starting with "\x7fELF..". It looks like so much of page memory is wasted. Why program headers are stored along with the text, data segments in process memory?

#include <stdio.h>

int main() {
  write(1, (void*)0x8048000,100);
  return 0;
}

Output (x86)

ELF 4L4         (44  TTT
4
  • My guess: For an operating system to load an executable it must know certain information abou it such as the arrangement of data and instructions to, for example, know how to properly set write/read/exec permissions and also to know how to set the EIP so on. So why should the OS keep it anywhere in RAM but right next to the executable? As I said, that's my guess. If you asked, why not chuck the header later, my guess would be because the information may be needed again. – JamalS Aug 23 '14 at 14:27
  • As long as we are guessing, then also "because memory is cheaper than paying programmers to avoid using it". – Jongware Aug 23 '14 at 14:32
  • 1
    The headers of the shared libraries need to stay at least until the primary executable is fully loaded - so one can't just free them as soon as that lib is done initalizing but needs to keep track of that. More importantly the information in the header is useful for debugging (Maybe I want to look up something about a section and for that I need e_shoff & e_shnum). – user45891 Aug 23 '14 at 15:03
  • @user45891: an interesting point, that last one. To do something like that, you need a solid guarantee that headers remain in memory. Would it then be mentioned in the OS' executable loader specifications? (Which, incidentally, the OP did not mention. Is "ELF" per definition 'Linux et cousins'?) – Jongware Aug 24 '14 at 22:00
2

ELF headers are included in the process memory because the program asked for them.

The ELF file contains a number of "program headers" which specify how the program is to be loaded. The ELF loader on your computer (typically in the kernel or dynamic linker) will load the program into memory as specified by the program headers (with allowances for extra pieces due to page size limitations).

Therefore, if the program headers include the start of the executable file in any LOAD command, then the ELF header will be loaded into memory. It is definitely possible to create functional ELF files that don't load the ELF headers into the program memory; the ELF loader will usually load the headers into a temporary (scratch) area in order to figure out how to load the program.

Sample program headers from an Android executable (using readelf):

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x00008034 0x00008034 0x00100 0x00100 R   0x4
  INTERP         0x000134 0x00008134 0x00008134 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /system/bin/linker]
  LOAD           0x000000 0x00008000 0x00008000 0x00320 0x00320 R E 0x1000
  LOAD           0x000ee8 0x00009ee8 0x00009ee8 0x00118 0x0011c RW  0x1000
  DYNAMIC        0x000f08 0x00009f08 0x00009f08 0x000d0 0x000d0 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0
  EXIDX          0x000318 0x00008318 0x00008318 0x00008 0x00008 R   0x4
  GNU_RELRO      0x000ee8 0x00009ee8 0x00009ee8 0x00118 0x00118 RW  0x4

The first LOAD command starts at an offset of 0x0 from the start of the file and extends for 0x320 bytes, so it will include the ELF headers at address 0x8000 (assuming the executable isn't relocated due to ASLR).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.