A symbol names an address. LC_SYMTAB gives the file offsets of the
symbol table and the string table, and LC_DYSYMTAB, in a file for the
dynamic linker, says how the table is grouped and where a few related tables are.
nlist records
| 32-bit offset | 64-bit offset | Field | Meaning |
|---|---|---|---|
| 0 | 0 | n_strx | Offset of the name in the string table. 0 means no name. |
| 4 | 4 | n_type | Kind of symbol. |
| 5 | 5 | n_sect | Section number, counted from 1 across the whole file, or 0. |
| 6 | 6 | n_desc | Details: 2 bytes. |
| 8 | 8 | n_value | Its value: an address, the size of a common symbol, or a stab’s data. 4 bytes in 32-bit, 8 in 64-bit. |
The record is 12 bytes in a 32-bit file and 16 in a 64-bit one.
n_type
Bits: 0xE0 N_STAB, 0x10 N_PEXT (private external),
0x0E N_TYPE and 0x01 N_EXT (external). When any N_STAB bit
is set the record is a debugging record (a stab), and the whole byte says which:
| N_TYPE | Constant | Meaning |
|---|---|---|
| 0 | N_UNDF | Undefined; a common symbol if n_value is non-zero (its size). |
| 2 | N_ABS | Absolute, not in a section. |
0xE | N_SECT | Defined in section n_sect. |
0xC | N_PBUD | Prebound undefined (defined in a library). |
0xA | N_INDR | The same as another symbol; n_value is the other’s string offset. |
Stabs: 0x20 N_GSYM, 0x22 N_FNAME, 0x24 N_FUN, 0x26 N_STSYM, 0x28 N_LCSYM, 0x2E N_BNSYM, 0x30 N_PC, 0x32 N_AST, 0x3C N_OPT, 0x40 N_RSYM, 0x44 N_SLINE, 0x4E N_ENSYM, 0x60 N_SSYM, 0x64 N_SO, 0x66 N_OSO, 0x68 N_LIB, 0x80 N_LSYM, 0x82 N_BINCL, 0x84 N_SOL, 0x86 N_PARAMS, 0x88 N_VERSION, 0x8A N_OLEVEL, 0xA0 N_PSYM, 0xA2 N_EINCL, 0xA4 N_ENTRY, 0xC0 N_LBRAC, 0xC2 N_EXCL, 0xE0 N_RBRAC, 0xE2 N_BCOMM, 0xE4 N_ECOMM, 0xE8 N_ECOML and 0xFE N_LENG.
n_desc
| Mask | Applies to | Meaning |
|---|---|---|
0x0007 | undefined | Reference type: 0 non-lazy, 1 lazy, 2 defined, 3 private defined, 4 private undefined non-lazy, 5 private undefined lazy. |
0x0010 | defined | REFERENCED_DYNAMICALLY: keep it when stripping. |
0x0020 | object files | N_NO_DEAD_STRIP. |
0x0040 | undefined | N_WEAK_REF: allowed to be missing, and is then address 0. |
0x0080 | defined; undefined | N_WEAK_DEF: a weak definition; on an undefined symbol, N_REF_TO_WEAK. |
0x0008 | defined (ARM) | N_ARM_THUMB_DEF: a Thumb function. |
0x0100 | object files | N_SYMBOL_RESOLVER. |
0x0200 | defined | N_ALT_ENTRY: pinned to the content before it. |
0x0400 | defined | N_COLD_FUNC. |
0xFF00 | undefined, two-level | The library ordinal: which LC_LOAD_* command it comes from, from 1. 0 this image, 0xFE dynamic lookup, 0xFF the main executable. |
A common symbol’s n_desc gives its alignment as a power of 2 in bits 8 to 11.
String table
stroff and strsize locate a run of zero-terminated
strings, each found by its offset from the start of the table. The table starts with
a zero byte, so that offset 0 reads as an empty name.
dysymtab_command
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 8 | 4 each | ilocalsym, nlocalsym | First index and count of local symbols. |
| 16 | 4 each | iextdefsym, nextdefsym | Defined external symbols. |
| 24 | 4 each | iundefsym, nundefsym | Undefined external symbols. |
| 32 | 4 each | tocoff, ntoc | The table of contents, for libraries with several modules. |
| 40 | 4 each | modtaboff, nmodtab | The module table. |
| 48 | 4 each | extrefsymoff, nextrefsyms | The referenced symbol table. |
| 56 | 4 each | indirectsymoff, nindirectsyms | The indirect symbol table. |
| 64 | 4 each | extreloff, nextrel | External relocations. |
| 72 | 4 each | locreloff, nlocrel | Local relocations. |
The table of contents, module table and referenced symbol table apply to libraries built from several object modules. Almost all files built by current tools leave them empty.
Indirect symbol table
An array of 4-byte symbol indexes. A section of symbol pointers or stubs starts at
the entry numbered by its reserved1, and its first entry names its first
pointer or stub, its second the second, and so on.
An entry can also be 0x80000000 (INDIRECT_SYMBOL_LOCAL: the pointer is
to a defined symbol that was stripped) or 0x40000000
(INDIRECT_SYMBOL_ABS), or the two together.
Module tables and two-level hints
A table-of-contents entry is a pair of 4-byte indexes, symbol then module. A module table entry holds a module’s name (an offset in the string table), the index and count of its defined external symbols, its referenced symbols, its local symbols, its relocations and its initialisers, 13 words in all (the 64-bit form has one of them 8 bytes). A referenced symbol is a 24-bit symbol index and 8 bits of flags.
LC_TWOLEVEL_HINTS points at 4-byte hints: an 8-bit index of a sub-image and a 24-bit index into the table of contents, a starting point for looking up a symbol.