Executable File Formats: ELF, PE/COFF and Mach-O
How executables, libraries and object files are laid out on disk and mapped in memory. Each page walks through the structures with their offsets and annotates every byte of a small working program: hover the hex dump to see which field a byte belongs to.
ELF
7f 45 4c 46
Linux, BSD, Android, embedded. Header, program headers (segments), section headers, symbols, relocations for x86-64 and AArch64, dynamic section, what the Linux loader checks.
ELF reference
PE/COFF
4d 5a … 50 45 00 00
Windows and UEFI. DOS header, file and optional headers, data directories, sections, RVAs, imports, exports, base relocations, TLS callbacks, COFF objects.
PE/COFF reference
Mach-O
cf fa ed fe
Apple platforms. Universal binaries, header, load commands, segments and sections, symbols, chained fixups, code signature.
Mach-O reference
Side by side
| ELF | PE/COFF | Mach-O | |
|---|---|---|---|
| Used by | Linux, BSDs, Android, Solaris, firmware, game consoles | Windows, UEFI, Xbox, .NET assemblies | macOS, iOS, iPadOS, watchOS, tvOS, visionOS |
| Magic (first bytes) | 7f 45 4c 46 "\x7fELF" | 4d 5a "MZ", then "PE\0\0" at e_lfanew | cf fa ed fe (64-bit LE), ca fe ba be (universal) |
| 32 / 64-bit | EI_CLASS in e_ident | Optional header Magic: 0x10b / 0x20b | MH_MAGIC / MH_MAGIC_64 |
| Endianness | EI_DATA: either | Always little endian | Magic byte order; fat headers and code signatures are big endian |
| Multi-architecture file | No | ARM64X only (ARM64 + ARM64EC) | Universal binaries (fat_header) |
| Main header | Elf64_Ehdr, 64 bytes | DOS header + IMAGE_FILE_HEADER + IMAGE_OPTIONAL_HEADER64 | mach_header_64, 32 bytes |
| How the loader maps it | Program headers (PT_LOAD segments) | Section table | LC_SEGMENT_64 load commands |
| Linker / tool view | Section headers (optional at run time) | Same section table | Sections inside segment commands |
| Entry point | e_entry (VA) | AddressOfEntryPoint (RVA) | LC_MAIN entryoff (file offset), or LC_UNIXTHREAD |
| Address units in headers | Virtual addresses and file offsets | RVAs (relative to ImageBase) | VM addresses and file offsets |
| Libraries needed | DT_NEEDED in .dynamic | Import directory, one descriptor per DLL | LC_LOAD_DYLIB, referenced by ordinal |
| Symbol binding | Flat namespace: any library can provide a symbol | Two-level: each import names its DLL | Two-level: each import names its library ordinal |
| Imported function calls | PLT stub → .got.plt, lazy by default | call [IAT], resolved at load time | Stub in __stubs → __got, bound at load time |
| Run-time loader | PT_INTERP, e.g. /lib64/ld-linux-x86-64.so.2 | ntdll.dll (Ldr*) | LC_LOAD_DYLINKER: /usr/lib/dyld |
| Relocations at load | .rela.dyn (R_*_RELATIVE, GLOB_DAT...) | .reloc base relocations (delta only) | Chained fixups, in place |
| Exports | .dynsym + .gnu.hash | Export directory (names, ordinals) | Exports trie |
| Symbols | .symtab / .dynsym (Elf64_Sym) | None in images (debug info in a PDB) | LC_SYMTAB (nlist_64) |
| Thread-local storage | PT_TLS | TLS directory (+ callbacks) | __thread_vars descriptors |
| Constructors | .init_array | CRT tables; TLS callbacks run first | __mod_init_func / __init_offsets |
| Code signature | None in the format | Authenticode in the Security directory (optional) | LC_CODE_SIGNATURE, mandatory on arm64 |
| Debug information | DWARF in .debug_* or a separate file (build ID) | PDB file (path and GUID in the debug directory) | DWARF in a .dSYM bundle (matched by UUID) |
| Object files | ELF ET_REL | COFF (.obj) | Mach-O MH_OBJECT |
Identify a file by its first bytes
| Bytes | ASCII | Format |
|---|---|---|
| 7f 45 4c 46 | \x7fELF | ELF |
| 4d 5a | MZ | DOS / PE (check e_lfanew → "PE\0\0") |
| cf fa ed fe | Mach-O 64-bit, little endian | |
| ce fa ed fe | Mach-O 32-bit, little endian | |
| ca fe ba be | Universal Mach-O (or a Java class file) | |
| ca fe ba bf | Universal Mach-O with 64-bit offsets | |
| 64 86 / 4c 01 / 64 aa | COFF object (Machine field first: AMD64, I386, ARM64) | |
| 21 3c 61 72 63 68 3e 0a | !<arch>\n | Static library (.a, .lib) |
| 64 65 78 0a | dex\n | Android DEX |
| 00 61 73 6d | \0asm | WebAssembly |