Skip to content

Understanding ELF64 text/data segment layout/padding

I’m trying to brush up on UNIX viruses and one text I’m reading mentions that parasitic code can be inserted in the padding between the text and the data segment, supposedly up to 2MB in size on x86-64 systems. But when I compile a simple hello world program with gcc -no-pie

#include <stdio.h>

int main()
  printf("hello worldn");

…and inspect its segment headers with readelf -W -l I get:

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000400040 0x0000000000400040 0x0002d8 0x0002d8 R   0x8
  INTERP         0x000318 0x0000000000400318 0x0000000000400318 0x00001c 0x00001c R   0x1
      [Requesting program interpreter: /lib64/]
  LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x000588 0x000588 R   0x1000
  LOAD           0x001000 0x0000000000401000 0x0000000000401000 0x0001c5 0x0001c5 R E 0x1000
  LOAD           0x002000 0x0000000000402000 0x0000000000402000 0x000138 0x000138 R   0x1000
  LOAD           0x002e00 0x0000000000403e00 0x0000000000403e00 0x000230 0x000238 RW  0x1000
  DYNAMIC        0x002e10 0x0000000000403e10 0x0000000000403e10 0x0001d0 0x0001d0 RW  0x8

I assume the segment starting at virtual address 0x401000 is the text segment and the one starting at 0x430e00 is the data segment. But what are the other two read-only LOAD segment? And how precisely does padding work here? There’s no padding to 2MB boundaries to be seen and even assuming padding to 4KB boundaries, why does the data segment not start at address 0x403000?



But what are the other two read-only LOAD segment?

See this answer.

There’s no padding to 2MB boundaries

The BFD linker used to align segments on 2MiB boundary because that’s the maximum page size an x86_64 system can be configured with.

It no longer does this (not sure when the change was made).
The text you are reading is probably out of date.