Gravitational plate of three masses and a slashed discABC0Static engraved plate. Three-dimensional view is unavailable or reduced motion is requested.

← back to fieldarchive

archiveAug 16, 2020

ELF program headers

How ELF program headers describe loadable segments — PT_LOAD, PT_DYNAMIC, PT_NOTE, PT_INTERP, PT_PHDR — and what readelf -l shows for text versus data.

ELF program headers

#define EI_NIDENT 16
 
           typedef struct {
               unsigned char e_ident[EI_NIDENT];
               uint16_t      e_type;
               uint16_t      e_machine;
               uint32_t      e_version;
               ElfN_Addr     e_entry;
               ElfN_Off      e_phoff;
               ElfN_Off      e_shoff;
               uint32_t      e_flags;
               uint16_t      e_ehsize;
               uint16_t      e_phentsize;
               uint16_t      e_phnum;
               uint16_t      e_shentsize;
               uint16_t      e_shnum;
               uint16_t      e_shstrndx;
           } ElfN_Ehdr;

ELF program headers define the binary segments needed to load a program. A segment describes how an on-disk executable maps into memory when the kernel loads it. Reach the program header table through the ELF header's e_phoff field.

The five program header types you meet most often define segments for executables and shared libraries and say what kind of data or code each segment holds. Below is a walk through Elf32_Phdr for a 32-bit ELF.

PT_LOAD

An executable needs at least one PT_LOAD segment. That header marks a loadable segment that the loader maps into memory.

동적 링킹이 가능한 ELF 실행 파일에 두 가지 로드 가능한 세그먼트가(PT_LAOD)가 포함된다.
 
1. 프로그램 코드가 위치한 텍스트 세그먼트
 
2. 전역 변수와 동적 링킹 정보가 위치한 데이터 세그먼트

Dynamically linked ELF binaries typically carry two loadable segments: a text segment for code, and a data segment for globals and dynamic linking metadata. Both are aligned with p_align before mapping. The Linux ELF(5) man page is the right place to see how Phdr fields behave on disk versus in memory. Program headers describe the in-memory layout of a running program.

Code segment

  • Permissions: PF_X | PF_R (read + execute)

Data segment

  • Permissions: PF_W | PF_R (read + write)

PT_DYNAMIC

Program header used by the dynamic segment. Present in dynamically linked binaries; it holds what the dynamic linker needs.

Values commonly found via PT_DYNAMIC

  • Shared libraries linked at runtime
  • Address / location of the GOT
  • Relocation entry information

Common PT_DYNAMIC tags

The dynamic segment stores linking metadata. The d_tag member controls how you read d_un.

typedef struct
{
    Elf32_Sword d_tag;
    union {
        Elf32_Word d_val;
        Elf32_Addr d_ptr;
    } d_un;
} Elf32_Dyn;
extern Elf32_Dyn _DYNAMIC[];

PT_NOTE

Holds vendor- or system-specific extras. Builders can use SHT_NOTE sections and PT_NOTE headers to record compatibility information. Entries are sequences of 4-byte words and strings with no fixed size limit. Labels are optional.

PT_NOTE is for the OS; a process does not need it while it runs.

PT_INTERP

A small segment that points at a NUL-terminated path to the program interpreter (the dynamic linker), usually /lib/linux-ld.so.2.

/assets/elf_device_file5/0.png
/assets/elf_device_file5/0.png
{: width="70%" height="70%"}

PT_PHDR

Gives the address and size of the program header table itself — where that table sits in the file and in the memory image.

readelf -l <binary>

/assets/elf_device_file5/1.png
/assets/elf_device_file5/1.png
{: width="70%" height="70%"}

You see the entry point and the segment types discussed above. Looking at offsets and alignment on the two PT_LOAD segments: text is typically read+execute and data is read+write. Alignment offsets such as 0x600e10 / 0x600e28 match page size on 32-bit builds and are used while the program is loaded.

related

  1. Aug 16, 2020/archiveLinux Linker Environment Variables
  2. Aug 16, 2020/archiveDevice Files Useful for ELF Analysis
  3. Aug 16, 2020/archiveELF file format

graphfeed