A COFF object file keeps its code, data and everything else in numbered sections, counted from 1. The section table comes straight after the file header, with one 40-byte entry for each section. The bytes of each section are elsewhere in the file, and the entry says where.
The section header
IMAGE_SECTION_HEADER, 40 bytes:
| Offset | Size | Field | Meaning in an object file |
|---|---|---|---|
| 0 | 8 | Name | The name, padded with zero bytes, with no terminator when it is 8 bytes long. See Names. |
| 8 | 4 | VirtualSize | 0 in an object file. |
| 12 | 4 | VirtualAddress | Usually 0. The linker chooses where the section goes. |
| 16 | 4 | SizeOfRawData | The size of the section’s bytes. For an uninitialised section, how much memory it needs. |
| 20 | 4 | PointerToRawData | The file offset of the section’s bytes, 0 when the file holds none. |
| 24 | 4 | PointerToRelocations | The file offset of its relocations, 0 when there are none. |
| 28 | 4 | PointerToLinenumbers | The file offset of its COFF line numbers, usually 0. |
| 32 | 2 | NumberOfRelocations | How many relocations it has. A section with more than 65,534 sets LNK_NRELOC_OVFL and writes 0xFFFF here; the real count is then in the first relocation. |
| 34 | 2 | NumberOfLinenumbers | How many line numbers it has. |
| 36 | 4 | Characteristics | Flags, and the alignment; see Flags. |
Names
A name of up to 8 bytes is stored in the header itself. A longer name is written as a
slash and a decimal number, such as /123: the number is an offset into the
string table. LLVM’s tools write
offsets too large for 7 digits as // followed by base-64 digits.
The part of a name after a $ groups sections for the linker:
.text$mn and .text$x both end up in .text,
ordered by what follows the $.
Flags
| Bits | Constant | Meaning |
|---|---|---|
0x00000008 | IMAGE_SCN_TYPE_NO_PAD | Obsolete: do not pad to the next boundary |
0x00000020 | IMAGE_SCN_CNT_CODE | Executable code |
0x00000040 | IMAGE_SCN_CNT_INITIALIZED_DATA | Initialised data |
0x00000080 | IMAGE_SCN_CNT_UNINITIALIZED_DATA | Uninitialised data (BSS): the file holds no bytes for it |
0x00000200 | IMAGE_SCN_LNK_INFO | Comments or other information, such as .drectve |
0x00000800 | IMAGE_SCN_LNK_REMOVE | Not linked into the image |
0x00001000 | IMAGE_SCN_LNK_COMDAT | A COMDAT section |
0x00008000 | IMAGE_SCN_GPREL | Referenced through the global pointer |
0x00100000–0x00E00000 | IMAGE_SCN_ALIGN_*BYTES | The alignment: a value n from 1 to 14 in these four bits means 2n−1 bytes, so 1 is 1 byte and 14 is 8,192 |
0x01000000 | IMAGE_SCN_LNK_NRELOC_OVFL | The relocation count overflowed; see the table above |
0x02000000 | IMAGE_SCN_MEM_DISCARDABLE | Can be discarded as needed |
0x04000000 | IMAGE_SCN_MEM_NOT_CACHED | Cannot be cached |
0x08000000 | IMAGE_SCN_MEM_NOT_PAGED | Cannot be paged |
0x10000000 | IMAGE_SCN_MEM_SHARED | Can be shared in memory |
0x20000000 | IMAGE_SCN_MEM_EXECUTE | Can be executed |
0x40000000 | IMAGE_SCN_MEM_READ | Can be read |
0x80000000 | IMAGE_SCN_MEM_WRITE | Can be written |
Section data
PointerToRawDatathe section’s bytesSizeOfRawDataPointerToRelocationsrelocations10 bytes eachPointerToLinenumbersline numbers6 bytes each
Microsoft’s compiler writes each section’s data followed by its relocations, but the
header’s offsets are what count. A .bss section, marked
CNT_UNINITIALIZED_DATA, has a size but a zero file offset.
COFF line numbers
These old records, deprecated in favour of CodeView, are 6 bytes each:
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 4 | Type | The symbol table index of a function when Linenumber is 0, otherwise an address in the section |
| 4 | 2 | Linenumber | The line number, counted from the start of the function; 0 for the first entry of a function |