Modules

Debug_Info

moduleSource

Available on macOS, Linux, Windows, Wasm

#import "Debug_Info";

Reads the debug information in a compiled program: DWARF (Linux and macOS) and CodeView in PDB files (Windows).

Example↗
info: Line_Info;
sequence: Line_Info_Sequence;
array_add(*sequence.addresses, 0x1000);
array_add(*sequence.addresses, 0x1010);
array_add(*sequence.mappings, .{ file_id = 1, line = 42 });
array_add(*sequence.mappings, .{ is_end = true });
array_add(*info.sequences, sequence);

mapping, found := get_line_mapping_for_address(info, 0x1004);
assert(found && mapping.line == 42);

Procedures#

DWARF frame#

CodeView lines#

CodeView symbol fields#

Debug int set#

DWARF line query#

MSF streams#

(file_content: string) -> bool

True if file_content starts with the MSF signature.

assert(!is_msf("not a pdb"));
↗
(file_content: string) -> bool

True if file_content starts with the MSF signature.

assert(!is_msf("not a pdb"));
↗
(file_content: string, path := "", verbose := false) -> (success: bool, Msf)

Reads the stream directory of an MSF file. file_content must stay alive as long as the result is used. Returns false, and logs why, for a file that is damaged or uses an unsupported layout. path is only used in that message.

(msf: Msf) -> bool

Re-reads the file and checks that msf's stream directory and free-page map agree with it.

(msf: Msf, stream_index: UNSN) -> s64

Returns the size in bytes of stream stream_index, or -1 if there is no such stream.

(msf: Msf, stream_index: UNSN) -> ([] u8, success: bool)

Returns a copy of the contents of stream stream_index, and whether it could be read. The caller frees the bytes.

msf: Msf;
data, ok := get_stream_data(msf, 1);
assert(!ok);
↗

MSF page bits#

DWARF model query#

CodeView string query#

DWARF public#

(debug_info_data: [] u8, abbrev: [] u8, line_programs: [] u8, debug_string_data: [] u8, verbose := false) -> (Debug_Info, success: bool)

Parses DWARF 4 data into a Debug_Info. Pass the contents of the .debug_info, .debug_abbrev, .debug_line and .debug_str sections. Returns false, and logs why, for data that is malformed or not DWARF 4. Set verbose to log what it reads.

info, ok := parse_dwarf_debug_info(.[], .[], .[], .[]);
assert(ok && info.compilation_units.count == 0);
↗
(info: Line_Info, file_info: File_Info) -> string

Returns the full path of file_info: its directory in info joined to its path, or the path alone when it is absolute.

CodeView types#

PDB parser#

(msf: Msf, stream_index: UNSN, verbose := false) -> ([] *Codeview_Type, success: bool)

Reads the type records of the type stream stream_index (stream 2 is the usual TPI stream, 4 the IPI stream).

(file_content: string, path := "", verbose := false) -> (success: bool, Pdb)

Opens a PDB file: its container, signature, name table and type records. Returns false, and logs why, if it cannot. file_content must stay alive as long as the result is used.

ok, pdb := parse_pdb("not a pdb");
assert(!ok);
↗

CodeView truncate#

CodeView inline#

CodeView symbol parser#

Types#

:: struct

The line table of one compilation unit: its directories and files, and the address sequences that map code to lines.

dirs: [..] string
files: [..] File_Info
sequences: [..] Line_Info_Sequence
:: struct

A source file in a Line_Info: its directory (an index into dirs, 0 for none) and its path.

dir_id: u64
path: string
:: struct

One run of the line program. addresses[i] starts the source position mappings[i]; the last mapping has is_end set and closes the run.

addresses: [..] u64
mappings: [..] Line_Mapping
:: struct

The source position of a code address: file, line and column, plus what kind of position it is (statement start, end of prologue, and so on).

file_id: Dwarf_File_Id
line: u32
column: u32
is_end: bool
flags: Flags
:: struct

The DWARF call frame information shared by a group of functions.

length: u64
id: u32
version: u8
augmentation: string
eh_data: u64
code_alignment_factor: u64
data_alignment_factor: s64
return_address_register: u64
augmentation_data: [] u8
initial_instructions: [] Call_Frame_Address_Instruction
offset: u64
:: enum

The operation of a Call_Frame_Address_Instruction: how to find the caller's registers at one point in a function.

ADVANCE_LOC
OFFSET
RESTORE
NOP
SET_LOC
ADVANCE_LOC1
ADVANCE_LOC2
ADVANCE_LOC4
OFFSET_EXTENDED
RESTORE_EXTENDED
UNDEFINED
SAME_VALUE
REGISTER
REMEMBER_STATE
RESTORE_STATE
DEF_CFA
DEF_CFA_REGISTER
DEF_CFA_OFFSET
DEF_CFA_EXPRESSION
OFFSET_EXTENDED_SF
DEF_CFA_SF
DEF_CFA_OFFSET_SF
VAL_OFFSET
VAL_OFFSET_SF
VAL_EXPRESSION
LO_USER
HI_USER
:: struct
iwMac: u32
iwRover: u32
cbPg: s32
fBigMsf: bool
rgw: [..] s64
wFill: s64
MsfstructSource
:: struct

A parsed MSF container, the file format PDB files are stored in: a set of numbered streams over fixed-size pages.

header: *Msf_Header_Big
parms: Msf_Parms
stream_table: Stream_Table
fpm_freed: Free_Page_Map
siPnList: Stream_Info
content: string
:: enum

How a DWARF base type encodes its values: signed or unsigned integer, float, boolean, character and so on.

ADDRESS
BOOLEAN
COMPLEX_FLOAT
DECIMAL_FLOAT
EDITED
FLOAT
HI_USER
IMAGINARY_FLOAT
LO_USER
NUMERIC_STRING
PACKED_DECIMAL
SIGNED
SIGNED_CHAR
SIGNED_FIXED
UNSIGNED
UNSIGNED_CHAR
UNSIGNED_FIXED
UTF
:: enum

The source language a DWARF compilation unit was written in.

ADA2005
ADA2012
ADA83
ADA95
ALGOL68
ASSEMBLY
BLISS
C
C11
C17
C23
C89
C99
COBOL74
COBOL85
CPP_FOR_OPEN_CL
CRYSTAL
C_PLUS_PLUS
C_PLUS_PLUS_03
C_PLUS_PLUS_11
C_PLUS_PLUS_14
C_PLUS_PLUS_17
C_PLUS_PLUS_20
C_PLUS_PLUS_23
C_SHARP
D
DYLAN
ELIXIR
ERLANG
FORTRAN03
FORTRAN08
FORTRAN18
FORTRAN23
FORTRAN77
FORTRAN90
FORTRAN95
GLEAM
GLSL
GLSL_ES
GO
HASKELL
HIP
HLSL
HYLO
JAVA
JULIA
KOTLIN
METAL
MODULA2
MODULA3
MOJO
MOVE
NIM
OBJ_C
OBJ_C_PLUS_PLUS
ODIN
OPEN_CL
OPEN_CL_CPP
O_CAML
P4
PASCAL83
PLI
PYTHON
RENDER_SCRIPT
RUBY
RUST
SWIFT
SYCL
UPC
V
ZIG
:: enum

What kind of entry a DWARF record is: a function, a variable, a type, a scope and so on.

ACCESS_DECLARATION
APPLE_PROPERTY
ARRAY_TYPE
ATOMIC_TYPE
BASE_TYPE
BORLAND_DELPHI_DYNAMIC_ARRAY
BORLAND_DELPHI_SET
BORLAND_DELPHI_STRING
BORLAND_DELPHI_VARIANT
BORLAND_PROPERTY
CALL_SITE
CALL_SITE_PARAMETER
CATCH_BLOCK
CLASS_TEMPLATE
CLASS_TYPE
COARRAY_TYPE
COMMON_BLOCK
COMMON_INCLUSION
COMPILE_UNIT
CONDITION
CONSTANT
CONST_TYPE
DWARF_PROCEDURE
DYNAMIC_TYPE
ENTRY_POINT
ENUMERATION_TYPE
ENUMERATOR
FILE_TYPE
FORMAL_PARAMETER
FORMAT_LABEL
FRIEND
FUNCTION_TEMPLATE
GENERIC_SUBRANGE
GNU_CALL_SITE
GNU_CALL_SITE_PARAMETER
GNU_FORMAL_PARAMETER_PACK
GNU_TEMPLATE_PARAMETER_PACK
GNU_TEMPLATE_TEMPLATE_PARAM
IMMUTABLE_TYPE
IMPORTED_DECLARATION
IMPORTED_MODULE
IMPORTED_UNIT
INHERITANCE
INLINED_SUBROUTINE
INTERFACE_TYPE
LABEL
LEXICAL_BLOCK
MEMBER
MIPS_LOOP
MODULE
NAMELIST
NAMELIST_ITEM
NAMESPACE
NULL
PACKED_TYPE
PARTIAL_UNIT
POINTER_TYPE
PTR_TO_MEMBER_TYPE
REFERENCE_TYPE
RESTRICT_TYPE
RVALUE_REFERENCE_TYPE
SET_TYPE
SHARED_TYPE
SKELETON_UNIT
STRING_TYPE
STRUCTURE_TYPE
SUBPROGRAM
SUBRANGE_TYPE
SUBROUTINE_TYPE
TEMPLATE_ALIAS
TEMPLATE_TYPE_PARAMETER
TEMPLATE_VALUE_PARAMETER
THROWN_TYPE
TRY_BLOCK
TYPEDEF
TYPE_UNIT
UNION_TYPE
UNSPECIFIED_PARAMETERS
UNSPECIFIED_TYPE
VARIABLE
VARIANT
VARIANT_PART
VOLATILE_TYPE
WITH_STMT
:: struct

A variable or parameter: its name, where it was declared and its type.

name: string
decl_file_id: Dwarf_File_Id
decl_line: u32
type_id: u32
kind: enum { PARAMETER; VARIABLE; }
:: struct

A scope inside a function: its code range, the declarations in it and the scopes nested in it.

low_pc: u64
high_pc: u64
declarations: [..] Declaration
children: [..] *Lexical_Block
:: struct

A function: its name, code range (low_pc to high_pc), declaration site and scope tree.

name: string
linkage_name: string
external: bool
decl_file_id: Dwarf_File_Id
decl_line: u32
type_id: u32
is_main: bool
calling_convention: u8
low_pc: u64
high_pc: u64
root_block: *Lexical_Block
:: struct

The fixed header at the start of a DWARF line program.

size: u32
version: u16
header_length: u32
minimum_instruction_length: u8
maximum_operations_per_instruction: u8
default_is_stmt: bool
line_base: s8
line_range: u8
opcode_base: u8
:: enum
ALIAS
ALIAS_ST
ARGLIST
ARGLIST_16T
ARRAY
ARRAY_16T
ARRAY_ST
BARRAY
BARRAY_16T
BCLASS
BCLASS_16T
BINTERFACE
BITFIELD
BITFIELD_16T
BUILDINFO
BUILTIN
CHAR
CLASS
CLASS_16T
CLASS_ST
COBOL0
COBOL0_16T
COBOL1
COMPLEX128
COMPLEX32
COMPLEX64
COMPLEX80
DATE
DECIMAL
DEFARG
DEFARG_16T
DEFARG_ST
DERIVED
DERIVED_16T
DIMARRAY
DIMARRAY_16T
DIMARRAY_ST
DIMCONLU
DIMCONLU_16T
DIMCONU
DIMCONU_16T
DIMVARLU
DIMVARLU_16T
DIMVARU
DIMVARU_16T
ENDOFLEAFRECORD
ENDPRECOMP
ENUM
ENUMERATE
ENUMERATE_ST
ENUM_16T
ENUM_ST
FIELDLIST
FIELDLIST_16T
FRIENDCLS
FRIENDCLS_16T
FRIENDFCN
FRIENDFCN_16T
FRIENDFCN_ST
FUNC_ID
HLSL
ID_LAST
ID_MAX
INDEX
INDEX_16T
INTERFACE
IVBCLASS
IVBCLASS_16T
LABEL
LIST
LONG
MANAGED
MANAGED_ST
MATRIX
MEMBER
MEMBERMODIFY
MEMBERMODIFY_ST
MEMBER_16T
MEMBER_ST
METHOD
METHODLIST
METHODLIST_16T
METHOD_16T
METHOD_ST
MFUNCTION
MFUNCTION_16T
MFUNC_ID
MODIFIER
MODIFIER_16T
MODIFIER_EX
NESTTYPE
NESTTYPEEX
NESTTYPEEX_ST
NESTTYPE_16T
NESTTYPE_ST
NOTTRAN
NULL
NUMERIC
OCTWORD
OEM
OEM2
OEM_16T
ONEMETHOD
ONEMETHOD_16T
ONEMETHOD_ST
PAD0
PAD1
PAD10
PAD11
PAD12
PAD13
PAD14
PAD15
PAD2
PAD3
PAD4
PAD5
PAD6
PAD7
PAD8
PAD9
POINTER
POINTER_16T
PRECOMP
PRECOMP_16T
PRECOMP_ST
PROCEDURE
PROCEDURE_16T
QUADWORD
REAL128
REAL16
REAL32
REAL48
REAL64
REAL80
REFSYM
SHORT
SKIP
SKIP_16T
STMEMBER
STMEMBER_16T
STMEMBER_ST
STRIDED_ARRAY
STRING_ID
STRUCTURE
STRUCTURE_16T
STRUCTURE_ST
ST_MAX
SUBSTR_LIST
TI16_MAX
TYPESERVER
TYPESERVER2
TYPESERVER_ST
TYPE_LAST
TYPE_MAX
UDT_MOD_SRC_LINE
UDT_SRC_LINE
ULONG
UNION
UNION_16T
UNION_ST
UOCTWORD
UQUADWORD
USHORT
UTF8STRING
VARSTRING
VBCLASS
VBCLASS_16T
VECTOR
VFTABLE
VFTPATH
VFTPATH_16T
VFUNCOFF
VFUNCOFF_16T
VFUNCTAB
VFUNCTAB_16T
VTSHAPE
:: enum
ALIGN
ANNOTATION
ANNOTATIONREF
ARMSWITCHTABLE
ATTR_FRAMEREL
ATTR_MANYREG
ATTR_REGISTER
ATTR_REGREL
BLOCK16
BLOCK32
BLOCK32_ST
BPREL16
BPREL32
BPREL32_16t
BPREL32_ST
BUILDINFO
CALLEES
CALLERS
CALLSITEINFO
CEXMODEL16
CEXMODEL32
COBOLUDT
COBOLUDT_16t
COBOLUDT_ST
COFFGROUP
COMPILE
COMPILE2
COMPILE2_ST
COMPILE3
CONSTANT
CONSTANT_16t
CONSTANT_ST
CVRESERVE
DATAREF
DATAREF_ST
DEFRANGE
DEFRANGE2_2005
DEFRANGE_2005
DEFRANGE_DPC_PTR_TAG
DEFRANGE_FRAMEPOINTER_REL
DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
DEFRANGE_HLSL
DEFRANGE_REGISTER
DEFRANGE_REGISTER_REL
DEFRANGE_SUBFIELD
DEFRANGE_SUBFIELD_REGISTER
DISCARDED
DPC_SYM_TAG_MAP
END
ENDARG
ENTRYTHIS
ENVBLOCK
EXPORT
FILESTATIC
FRAMECOOKIE
FRAMEPROC
GDATA16
GDATA32
GDATA32_16t
GDATA32_ST
GDATA_HLSL
GDATA_HLSL32
GDATA_HLSL32_EX
GMANDATA
GMANDATA_ST
GMANPROC
GMANPROC_ST
GPROC16
GPROC32
GPROC32_16t
GPROC32_ID
GPROC32_ST
GPROCIA64
GPROCIA64_ID
GPROCIA64_ST
GPROCMIPS
GPROCMIPS_16t
GPROCMIPS_ID
GPROCMIPS_ST
GTHREAD32
GTHREAD32_16t
GTHREAD32_ST
HEAPALLOCSITE
INLINEES
INLINESITE
INLINESITE2
INLINESITE_END
LABEL16
LABEL32
LABEL32_ST
LDATA16
LDATA32
LDATA32_16t
LDATA32_ST
LDATA_HLSL
LDATA_HLSL32
LDATA_HLSL32_EX
LMANDATA
LMANDATA_ST
LMANPROC
LMANPROC_ST
LOCAL
LOCALSLOT
LOCALSLOT_ST
LOCAL_2005
LOCAL_DPC_GROUPSHARED
LPROC16
LPROC32
LPROC32_16t
LPROC32_DPC
LPROC32_DPC_ID
LPROC32_ID
LPROC32_ST
LPROCIA64
LPROCIA64_ID
LPROCIA64_ST
LPROCMIPS
LPROCMIPS_16t
LPROCMIPS_ID
LPROCMIPS_ST
LPROCREF
LPROCREF_ST
LTHREAD32
LTHREAD32_16t
LTHREAD32_ST
MANCONSTANT
MANFRAMEREL
MANFRAMEREL_ST
MANMANYREG
MANMANYREG2
MANMANYREG2_ST
MANMANYREG_ST
MANREGISTER
MANREGISTER_ST
MANREGREL
MANREGREL_ST
MANSLOT
MANSLOT_ST
MANTYPREF
MANYREG
MANYREG2
MANYREG2_ST
MANYREG_16t
MANYREG_ST
MOD_TYPEREF
OBJNAME
OBJNAME_ST
OEM
PARAMSLOT
PARAMSLOT_ST
PDBMAP
POGODATA
PROCREF
PROCREF_ST
PROC_ID_END
PUB16
PUB32
PUB32_16t
PUB32_ST
RECTYPE_LAST
RECTYPE_MAX
RECTYPE_PAD
REF_MINIPDB
REGISTER
REGISTER_16t
REGISTER_ST
REGREL16
REGREL32
REGREL32_16t
REGREL32_ST
RESERVED1
RESERVED2
RESERVED3
RESERVED4
RETURN
SECTION
SEPCODE
SKIP
SLINK32
SLOT
SSEARCH
ST_MAX
THUNK16
THUNK32
THUNK32_ST
TI16_MAX
TOKENREF
TRAMPOLINE
UDT
UDT_16t
UDT_ST
UNAMESPACE
UNAMESPACE_ST
VFTABLE16
VFTABLE32
VFTABLE32_16t
WITH16
WITH32
WITH32_ST
:: enum_flags
PACKED
CTOR
OVLOPS
IS_NESTED
NESTED_TYPES
OP_ASSIGN
OP_CAST
FWDREF
SCOPED
UNIQUE_NAME
SEALED
HFA_OTHER
HFA_FLOAT
HFA_DOUBLE
INTRINSIC
MOCOM_UDT_INTERFACE
MOCOM_UDT_REF
MOCOM_UDT_VALUE
:: enum
NOTYPE
ABS
SEGMENT
VOID
HRESULT
CHAR
SHORT
LONG
QUAD
UCHAR
USHORT
ULONG
UQUAD
FLOAT32
FLOAT64
FLOAT16
S8
U8
RCHAR
WCHAR
CHAR16
CHAR32
S16
U16
S32
U32
S64
U64
BOOL8
BOOL16
BOOL32
BOOL64
:: enum
NEAR
FAR
HUGE
BASE_SEG
BASE_VAL
BASE_SEGVAL
BASE_ADDR
BASE_SEGADDR
BASE_TYPE
BASE_SELF
NEAR32
FAR32
_64
UNUSEDPTR
:: struct
data1: u32
data2: u16
data3: u16
data4: [8] u8
PdbstructSource
:: struct

Reviewed public PDB aggregates; contextual map storage is independently designed.

header: Pdb_Header
signature: GUID
name_table: Name_Table
contains_id_stream: bool
no_type_merge: bool
minimal_debug_info: bool
tpi: [] *Codeview_Type
ipi: [] *Codeview_Type
msf: Msf
:: struct

The fixed header of a PDB type stream (TPI or IPI).

header_size: u32
type_index_begin: u32
type_index_end: u32
type_record_bytes: u32
hash_stream_index: u16
hash_aux_stream_index: u16
hash_key_size: u32
num_hash_buckets: u32
hash_value_buffer_offset: s32
hash_value_buffer_length: u32
index_offset_buffer_offset: s32
index_offset_buffer_length: u32
hash_adj_buffer_offset: s32
hash_adj_buffer_length: u32
:: enum
INVALID
CODE_OFFSET
CHANGE_CODE_OFFSET_BASE
CHANGE_CODE_OFFSET
CHANGE_CODE_LENGTH
CHANGE_FILE
CHANGE_LINE_OFFSET
CHANGE_LINE_END_DELTA
CHANGE_RANGE_KIND
CHANGE_COLUMN_START
CHANGE_COLUMN_END_DELTA
CHANGE_CODE_OFFSET_AND_LINE_OFFSET
CHANGE_CODE_LENGTH_AND_CODE_OFFSET
CHANGE_COLUMN_END
:: enum
SYMBOLS
LINES
STRING_TABLE
FILE_CHECKSUMS
FRAME_DATA
INLINEELINES
CROSS_SCOPE_IMPORTS
CROSS_SCOPE_EXPORTS
IL_LINES
FUNC_MDTOKEN_MAP
TYPE_MDTOKEN_MAP
MERGED_ASSEMBLYINPUT
COFF_SYMBOL_RVA
IGNORE

Constants#