Symbol records describe functions, variables, scopes and the compiler. Each module stream holds its module’s symbols, followed by its C13 debug subsections; the symbol record stream named in the DBI header holds the global and public symbols. Numbers are little-endian; “type” fields are 4-byte type indexes, and names are null-terminated.
Records
| Offset | Size | Name | Meaning |
|---|---|---|---|
| 0 | 2 | reclen | Length of the record, not counting this field. |
| 2 | 2 | rectyp | The symbol kind, an S_ value (below). |
| 4 | – | Fields | Depend on the kind (layouts). |
Scopes nest: a procedure or block record is followed by the records inside it and
closed by S_END (or S_INLINESITE_END /
S_PROC_ID_END); pParent, pEnd and pNext
fields hold the offsets of the enclosing, closing and next records in the same
stream.
Symbol kinds
Current kinds
| Value | Name | Value | Name |
|---|---|---|---|
0x0006 | S_END | 0x1136 | S_SECTION |
0x1012 | S_FRAMEPROC | 0x1137 | S_COFFGROUP |
0x1019 | S_ANNOTATION | 0x1138 | S_EXPORT |
0x1101 | S_OBJNAME | 0x1139 | S_CALLSITEINFO |
0x1102 | S_THUNK32 | 0x113A | S_FRAMECOOKIE |
0x1103 | S_BLOCK32 | 0x113B | S_DISCARDED |
0x1104 | S_WITH32 | 0x113C | S_COMPILE3 |
0x1105 | S_LABEL32 | 0x113D | S_ENVBLOCK |
0x1106 | S_REGISTER | 0x113E | S_LOCAL |
0x1107 | S_CONSTANT | 0x113F | S_DEFRANGE |
0x1108 | S_UDT | 0x1140 | S_DEFRANGE_SUBFIELD |
0x1109 | S_COBOLUDT | 0x1141 | S_DEFRANGE_REGISTER |
0x110A | S_MANYREG | 0x1142 | S_DEFRANGE_FRAMEPOINTER_REL |
0x110B | S_BPREL32 | 0x1143 | S_DEFRANGE_SUBFIELD_REGISTER |
0x110C | S_LDATA32 | 0x1144 | S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE |
0x110D | S_GDATA32 | 0x1145 | S_DEFRANGE_REGISTER_REL |
0x110E | S_PUB32 | 0x1146 | S_LPROC32_ID |
0x110F | S_LPROC32 | 0x1147 | S_GPROC32_ID |
0x1110 | S_GPROC32 | 0x1148 | S_LPROCMIPS_ID |
0x1111 | S_REGREL32 | 0x1149 | S_GPROCMIPS_ID |
0x1112 | S_LTHREAD32 | 0x114A | S_LPROCIA64_ID |
0x1113 | S_GTHREAD32 | 0x114B | S_GPROCIA64_ID |
0x1114 | S_LPROCMIPS | 0x114C | S_BUILDINFO |
0x1115 | S_GPROCMIPS | 0x114D | S_INLINESITE |
0x1116 | S_COMPILE2 | 0x114E | S_INLINESITE_END |
0x1117 | S_MANYREG2 | 0x114F | S_PROC_ID_END |
0x1118 | S_LPROCIA64 | 0x1150 | S_DEFRANGE_HLSL |
0x1119 | S_GPROCIA64 | 0x1151 | S_GDATA_HLSL |
0x111A | S_LOCALSLOT | 0x1152 | S_LDATA_HLSL |
0x111B | S_PARAMSLOT | 0x1153 | S_FILESTATIC |
0x111C | S_LMANDATA | 0x1154 | S_LOCAL_DPC_GROUPSHARED |
0x111D | S_GMANDATA | 0x1155 | S_LPROC32_DPC |
0x111E | S_MANFRAMEREL | 0x1156 | S_LPROC32_DPC_ID |
0x111F | S_MANREGISTER | 0x1157 | S_DEFRANGE_DPC_PTR_TAG |
0x1120 | S_MANSLOT | 0x1158 | S_DPC_SYM_TAG_MAP |
0x1121 | S_MANMANYREG | 0x1159 | S_ARMSWITCHTABLE |
0x1122 | S_MANREGREL | 0x115A | S_CALLEES |
0x1123 | S_MANMANYREG2 | 0x115B | S_CALLERS |
0x1124 | S_UNAMESPACE | 0x115C | S_POGODATA |
0x1125 | S_PROCREF | 0x115D | S_INLINESITE2 |
0x1126 | S_DATAREF | 0x115E | S_HEAPALLOCSITE |
0x1127 | S_LPROCREF | 0x115F | S_MOD_TYPEREF |
0x1128 | S_ANNOTATIONREF | 0x1160 | S_REF_MINIPDB |
0x1129 | S_TOKENREF | 0x1161 | S_PDBMAP |
0x112A | S_GMANPROC | 0x1162 | S_GDATA_HLSL32 |
0x112B | S_LMANPROC | 0x1163 | S_LDATA_HLSL32 |
0x112C | S_TRAMPOLINE | 0x1164 | S_GDATA_HLSL32_EX |
0x112D | S_MANCONSTANT | 0x1165 | S_LDATA_HLSL32_EX |
0x112E | S_ATTR_FRAMEREL | 0x1166 | S_FRAMEREG |
0x112F | S_ATTR_REGISTER | 0x1167 | S_FASTLINK |
0x1130 | S_ATTR_REGREL | 0x1168 | S_INLINEES |
0x1131 | S_ATTR_MANYREG | 0x1169 | S_HOTPATCHFUNC |
0x1132 | S_SEPCODE | 0x1170 | S_BPREL32_INDIR |
0x1133 | S_LOCAL_2005 | 0x1171 | S_REGREL32_INDIR |
0x1134 | S_DEFRANGE_2005 | 0x1172 | S_GPROC32EX |
0x1135 | S_DEFRANGE2_2005 | 0x1173 | S_LPROC32EX |
0x1174 | S_GPROC32EX_ID | ||
0x1175 | S_LPROC32EX_ID | ||
0x1176 | S_STATICLOCAL | ||
0x1177 | S_DEFRANGE_REGISTER_REL_INDIR | ||
0x1178 | S_BPREL32_ENCTMP | ||
0x1179 | S_REGREL32_ENCTMP | ||
0x117A | S_BPREL32_INDIR_ENCTMP | ||
0x117B | S_REGREL32_INDIR_ENCTMP | ||
0x117C | S_ASSOCIATION | ||
0x117E | S_SOURCELINK | ||
0x117F | S_DEFRANGE_CONSTVAL_ON_ENTRY | ||
0x1180 | S_DEFRANGE_GLOBALSYM_ON_ENTRY | ||
0x1181 | S_ALTOBJNAME |
Older kinds
Kinds that LLVM’s list defines for older formats (16-bit, MIPS, “_ST” and
“_16t” forms): 0x0001 S_COMPILE, 0x0002 S_REGISTER_16t,
0x0003 S_CONSTANT_16t, 0x0004 S_UDT_16t, 0x0005
S_SSEARCH, 0x0007 S_SKIP, 0x0008 S_CVRESERVE,
0x0009 S_OBJNAME_ST, 0x000A S_ENDARG, 0x000B
S_COBOLUDT_16t, 0x000C S_MANYREG_16t, 0x000D S_RETURN,
0x000E S_ENTRYTHIS, 0x0100–0x010C S_BPREL16,
S_LDATA16, S_GDATA16, S_PUB16, S_LPROC16, S_GPROC16, S_THUNK16, S_BLOCK16, S_WITH16,
S_LABEL16, S_CEXMODEL16, S_VFTABLE16, S_REGREL16; 0x0200–0x020F
S_BPREL32_16t, S_LDATA32_16t, S_GDATA32_16t, S_PUB32_16t, S_LPROC32_16t,
S_GPROC32_16t, S_THUNK32_ST, S_BLOCK32_ST, S_WITH32_ST, S_LABEL32_ST, S_CEXMODEL32,
S_VFTABLE32_16t, S_REGREL32_16t, S_LTHREAD32_16t, S_GTHREAD32_16t, S_SLINK32;
0x0300 S_LPROCMIPS_16t, 0x0301 S_GPROCMIPS_16t;
0x0400 S_PROCREF_ST, 0x0401 S_DATAREF_ST,
0x0402 S_ALIGN, 0x0403 S_LPROCREF_ST, 0x0404
S_OEM; 0x1000 S_TI16_MAX; 0x1001–0x1011
S_REGISTER_ST, S_CONSTANT_ST, S_UDT_ST, S_COBOLUDT_ST, S_MANYREG_ST, S_BPREL32_ST,
S_LDATA32_ST, S_GDATA32_ST, S_PUB32_ST, S_LPROC32_ST, S_GPROC32_ST, S_VFTABLE32,
S_REGREL32_ST, S_LTHREAD32_ST, S_GTHREAD32_ST, S_LPROCMIPS_ST, S_GPROCMIPS_ST;
0x1013 S_COMPILE2_ST, 0x1014 S_MANYREG2_ST,
0x1015 S_LPROCIA64_ST, 0x1016 S_GPROCIA64_ST,
0x1017 S_LOCALSLOT_ST, 0x1018 S_PARAMSLOT_ST,
0x101A S_GMANPROC_ST, 0x101B S_LMANPROC_ST,
0x101C–0x101F S_RESERVED1–4, 0x1020–0x1027
S_LMANDATA_ST, S_GMANDATA_ST, S_MANFRAMEREL_ST, S_MANREGISTER_ST, S_MANSLOT_ST,
S_MANMANYREG_ST, S_MANREGREL_ST, S_MANMANYREG2_ST; 0x1028 S_MANTYPREF,
0x1029 S_UNAMESPACE_ST, 0x1100 S_ST_MAX.
Record layouts
Fields after the 4-byte header, in order (size in bytes in brackets).
Procedures: S_GPROC32, S_LPROC32 and their _ID and _DPC forms
| Field | Size | Meaning |
|---|---|---|
| pParent | 4 | Offset of the enclosing scope’s record, or 0. |
| pEnd | 4 | Offset of the closing S_END. |
| pNext | 4 | Offset of the next record at this level. |
| len | 4 | Length of the code. |
| DbgStart | 4 | Offset where the prologue ends. |
| DbgEnd | 4 | Offset where the epilogue starts. |
| typind | 4 | The function’s type (in the _ID forms, an IPI ID). |
| off | 4 | Offset of the code in its section. |
| seg | 2 | Section number. |
| flags | 1 | Bit 0 has frame pointer, 1 interrupt return, 2 far return, 3 never returns, 4 unreachable, 5 custom calling convention, 6 no inlining, 7 optimised debug information. |
| name | – | The function’s name. |
Data: S_GDATA32, S_LDATA32, S_GMANDATA, S_LMANDATA; S_UDT; S_CONSTANT
| Record | Fields |
|---|---|
| Data | typind (4); off (4); seg (2); name. |
S_UDT | typind (4) a user-defined type; name (a typedef or type name). |
S_CONSTANT | typind (4); value (a numeric leaf); name. |
S_PUB32
| Field | Size | Meaning |
|---|---|---|
| pubsymflags | 4 | Bit 0 code, bit 1 function, bit 2 managed code, bit 3 MSIL. |
| off | 4 | Offset in its section. |
| seg | 2 | Section number. |
| name | – | The decorated (linker) name. |
S_PROCREF and S_LPROCREF
| Field | Size | Meaning |
|---|---|---|
| sumName | 4 | A checksum of the name. |
| ibSym | 4 | Offset of the actual procedure record in its module’s symbols. |
| imod | 2 | The module, numbered from 1. |
| name | – | The procedure’s name. |
S_OBJNAME
signature (4); name (the object file’s path).
S_COMPILE3
| Field | Size | Meaning |
|---|---|---|
| flags | 4 | Bits 0–7 source language (below); bit 8 Edit and Continue; 9 no debug information; 10 link-time code generation; 11 no data alignment; 12 managed code present; 13 security checks (/GS); 14 hot-patchable; 15 converted with CVTCIL; 16 MSIL module; 17 SDL checks; 18 profile-guided optimisation; 19 .exp module; 20–31 unused. |
| machine | 2 | Target processor (below). |
| verFEMajor, verFEMinor, verFEBuild, verFEQFE | 2 each | Front-end version. |
| verMajor, verMinor, verBuild, verQFE | 2 each | Back-end version. |
| verSz | – | Compiler name and version as text. |
Languages
0x00 C, 0x01 C++, 0x02 Fortran,
0x03 MASM, 0x04 Pascal, 0x05 Basic,
0x06 COBOL, 0x07 Link, 0x08 CVTRES,
0x09 CVTPGD, 0x0A C#, 0x0B Visual Basic,
0x0C ILASM, 0x0D Java, 0x0E JScript,
0x0F MSIL, 0x10 HLSL, 0x11 Objective-C,
0x12 Objective-C++, 0x13 Swift, 0x14 AliasObj,
0x15 Rust, 0x16 Go, 0x44 (D) D,
0x53 (S) old Swift.
Machines
0x00 Intel 8080, 0x01 8086, 0x02 80286,
0x03 80386, 0x04 80486, 0x05 Pentium,
0x06 Pentium Pro, 0x07 Pentium III; 0x10–0x18
MIPS, MIPS16, MIPS32, MIPS64, MIPS I, II, III, IV, V; 0x20–0x24
68000, 68010, 68020, 68030, 68040; 0x30–0x34 Alpha, 21164,
21164A, 21264, 21364; 0x40–0x45 PPC601, PPC603, PPC604, PPC620,
PPCFP, PPCBE; 0x50–0x54 SH3, SH3E, SH3DSP, SH4, SHMedia;
0x60–0x68 ARM3, ARM4, ARM4T, ARM5, ARM5T, ARM6, ARM_XMAC,
ARM_WMMX, ARM7; 0x70 Omni; 0x80 IA-64, 0x81
IA-64 2; 0x90 CEE; 0xA0 AM33; 0xB0 M32R;
0xC0 TriCore; 0xD0 x64; 0xE0 EBC;
0xF0 Thumb; 0xF4 ARMNT; 0xF6 ARM64;
0xF7 HybridX86ARM64; 0xF8 ARM64EC; 0xF9 ARM64X;
0xFF unknown; 0x100 D3D11 shader.
S_FRAMEPROC
| Field | Size | Meaning |
|---|---|---|
| cbFrame | 4 | Size of the frame. |
| cbPad | 4 | Padding bytes in the frame. |
| offPad | 4 | Offset of the padding. |
| cbSaveRegs | 4 | Bytes of saved registers. |
| offExHdlr | 4 | Offset of the exception handler. |
| sectExHdlr | 2 | Its section. |
| flags | 4 | Bit 0 uses alloca, 1 setjmp, 2 longjmp, 3 inline assembly, 4 C++ exception handling, 5 declared inline, 6 structured exception handling, 7 naked, 8 security checks, 9 asynchronous exception handling, 10 no stack ordering for security checks, 11 was inlined, 12 strict security checks, 13 safe buffers, 14–15 encoded local base pointer, 16–17 encoded parameter base pointer, 18 profile-guided optimisation on, 19 valid profile counts, 20 optimised for speed, 21 Control Flow Guard, 22 CFG write checks, 23–31 unused. |
Locals: S_REGREL32, S_BPREL32, S_LOCAL
| Record | Fields |
|---|---|
S_REGREL32 | off (4) from the register; typind (4); reg (2) register number; name. |
S_BPREL32 | off (4, signed) from the frame pointer; typind (4); name. |
S_LOCAL | typind (4); flags (2): bit 0 parameter, 1 address taken, 2 compiler-generated, 3 aggregate, 4 part of an aggregate, 5 aliased, 6 alias, 7 return value, 8 optimised out, 9 enregistered global, 10 enregistered static; name. |
S_INLINESITE
pParent (4); pEnd (4); inlinee (4) the inlined function’s IPI ID; then binary annotations, a compressed program describing the inlined code’s ranges and lines. The annotation opcodes:
| Value | Name | Value | Name |
|---|---|---|---|
| 0 | BA_OP_Invalid | 7 | BA_OP_ChangeLineEndDelta |
| 1 | BA_OP_CodeOffset | 8 | BA_OP_ChangeRangeKind |
| 2 | BA_OP_ChangeCodeOffsetBase | 9 | BA_OP_ChangeColumnStart |
| 3 | BA_OP_ChangeCodeOffset | 10 | BA_OP_ChangeColumnEndDelta |
| 4 | BA_OP_ChangeCodeLength | 11 | BA_OP_ChangeCodeOffsetAndLineOffset |
| 5 | BA_OP_ChangeFile | 12 | BA_OP_ChangeCodeLengthAndCodeOffset |
| 6 | BA_OP_ChangeLineOffset | 13 | BA_OP_ChangeColumnEnd |
Other records
| Record | Fields |
|---|---|
S_BLOCK32 | pParent (4); pEnd (4); len (4); off (4); seg (2); name. |
S_THUNK32 | pParent (4); pEnd (4); pNext (4); off (4); seg (2); len (2); ord (1) thunk kind; name; variant data. |
S_LABEL32 | off (4); seg (2); flags (1, as for procedures); name. |
S_SECTION | isec (2) section number; align (1); reserved (1); rva (4); cb (4) size; characteristics (4); name. |
S_COFFGROUP | cb (4); characteristics (4); off (4); seg (2); name (e.g. .text$mn). |
S_EXPORT | ordinal (2); flags (2): bit 0 constant, 1 data, 2 private, 3 no name, 4 ordinal given explicitly, 5 forwarder; name. |
S_BUILDINFO | id (4) an LF_BUILDINFO in the IPI stream. |
C13 debug subsections
After a module’s symbols come its C13 subsections, each with an 8-byte header and its data, padded to a multiple of 4 bytes.
| Field | Size | Meaning |
|---|---|---|
| type | 4 | Kind of subsection (below). |
| cbLen | 4 | Length of the data. |
| Value | Kind | Value | Kind |
|---|---|---|---|
0xF1 | Symbols | 0xF9 | IL lines |
0xF2 | Lines | 0xFA | Function metadata-token map |
0xF3 | String table | 0xFB | Type metadata-token map |
0xF4 | File checksums | 0xFC | Merged assembly input |
0xF5 | Frame data | 0xFD | COFF symbol RVAs |
0xF6 | Inlinee lines | 0xFF | XFG hash (type) |
0xF7 | Cross-scope imports | 0x100 | XFG hash (virtual) |
0xF8 | Cross-scope exports |
Lines (0xF2)
A header for one contribution of code, then one block per source file.
| Field | Size | Meaning |
|---|---|---|
| offCon | 4 | Offset of the code in its section. |
| segCon | 2 | Section number. |
| flags | 2 | Bit 0: column entries follow the line entries. |
| cbCon | 4 | Length of the code. |
Each file block:
| Field | Size | Meaning |
|---|---|---|
| offFile | 4 | Offset of the file’s entry in the file checksums subsection. |
| nLines | 4 | Number of line entries. |
| cbBlock | 4 | Size of the block, including this header. |
| lines | 8 each | offset (4) from offCon; then 4 bytes of bits: 0–23 line number, 24–30 end-line delta, 31 is a statement. |
| columns | 4 each | If flagged: start column (2) and end column (2) per line. |
File checksums (0xF4)
A list of entries, each padded to a multiple of 4 bytes:
| Field | Size | Meaning |
|---|---|---|
| FileNameOffset | 4 | Offset of the file name in the /names string table. |
| ChecksumSize | 1 | Bytes of checksum. |
| ChecksumKind | 1 | 0 none, 1 MD5, 2 SHA-1, 3 SHA-256. |
| Checksum | ChecksumSize | The checksum of the source file. |
Inlinee lines (0xF6)
A 4-byte signature, 0 (normal) or 1 (with extra files), then entries of inlinee (4) the function’s ID, FileID (4) its file checksum offset and SourceLineNum (4); with signature 1 each entry is followed by a 4-byte count and that many extra file IDs.
Sources
LLVM source: CodeViewSymbols.def (every symbol kind),
CodeView.h (procedure, public, compile and frame flags, processor types,
subsection kinds, checksum kinds, line flags), CodeViewLanguages.def
(languages), DebugChecksumsSubsection.cpp,
DebugSubsectionRecord.cpp and
DebugInlineeLinesSubsection.h/.cpp. Microsoft’s
cvinfo.h in
microsoft-pdb (the field order
and types of each record, local and export flags, line and column entries, binary
annotation opcodes). LLVM, The
Module Information Stream. The meaning given for some fields is read from their
names in cvinfo.h and is unconfirmed: the scope links
(pParent, pEnd, pNext) and how S_END
closes a scope, DbgStart/DbgEnd, sumName,
imod counting from 1, line entries’ offsets being relative to
offCon, cbBlock including its header, and
offFile pointing into the checksums. The thunk kinds in ord, the
thread-local data layout and the S_DEFRANGE* records are not
covered.