╭ pdb.zig ──────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
1 //! Program Data Base debugging information format. 2 //! 3 //! This namespace contains unopinionated types and data definitions only. For 4 //! an implementation of parsing and caching PDB information, see 5 //! `std.debug.Pdb`. 6 //! 7 //! Most of this is based on information gathered from LLVM source code, 8 //! documentation and/or contributors. 9 10 const std = @import("std.zig"); 11 const math = std.math; 12 const mem = std.mem; 13 const coff = std.coff; 14 const fs = std.fs; 15 const File = std.Io.File; 16 const debug = std.debug; 17 18 const ArrayList = std.ArrayList; 19 20 /// https://llvm.org/docs/PDB/DbiStream.html#stream-header 21 pub const DbiStreamHeader = extern struct { 22 version_signature: i32, 23 version_header: u32, 24 age: u32, 25 global_stream_index: u16, 26 build_number: u16, 27 public_stream_index: u16, 28 pdb_dll_version: u16, 29 sym_record_stream: u16, 30 pdb_dll_rbld: u16, 31 mod_info_size: u32, 32 section_contribution_size: u32, 33 section_map_size: u32, 34 source_info_size: i32, 35 type_server_size: i32, 36 mfc_type_server_index: u32, 37 optional_dbg_header_size: i32, 38 ec_substream_size: i32, 39 flags: u16, 40 machine: u16, 41 padding: u32, 42 }; 43 44 pub const SectionContribEntry = extern struct { 45 /// COFF Section index, 1-based 46 section: u16, 47 padding1: [2]u8, 48 offset: u32, 49 size: u32, 50 characteristics: u32, 51 module_index: u16, 52 padding2: [2]u8, 53 data_crc: u32, 54 reloc_crc: u32, 55 }; 56 57 pub const ModInfo = extern struct { 58 unused1: u32, 59 section_contr: SectionContribEntry, 60 flags: u16, 61 module_sym_stream: u16, 62 sym_byte_size: u32, 63 c11_byte_size: u32, 64 c13_byte_size: u32, 65 source_file_count: u16, 66 padding: [2]u8, 67 unused2: u32, 68 source_file_name_index: u32, 69 pdb_file_path_name_index: u32, 70 // These fields are variable length 71 //module_name: char[], 72 //obj_file_name: char[], 73 }; 74 75 pub const SectionMapHeader = extern struct { 76 /// Number of segment descriptors 77 count: u16, 78 79 /// Number of logical segment descriptors 80 log_count: u16, 81 }; 82 83 pub const SectionMapEntry = extern struct { 84 /// See the SectionMapEntryFlags enum below. 85 flags: u16, 86 87 /// Logical overlay number 88 ovl: u16, 89 90 /// Group index into descriptor array. 91 group: u16, 92 frame: u16, 93 94 /// Byte index of segment / group name in string table, or 0xFFFF. 95 section_name: u16, 96 97 /// Byte index of class in string table, or 0xFFFF. 98 class_name: u16, 99 100 /// Byte offset of the logical segment within physical segment. If group is set in flags, this is the offset of the group. 101 offset: u32, 102 103 /// Byte count of the segment or group. 104 section_length: u32, 105 }; 106 107 pub const StreamType = enum(u16) { 108 pdb = 1, 109 tpi = 2, 110 dbi = 3, 111 ipi = 4, 112 }; 113 114 /// Duplicate copy of SymbolRecordKind, but using the official CV names. Useful 115 /// for reference purposes and when dealing with unknown record types. 116 pub const SymbolKind = enum(u16) { 117 compile = 1, 118 register_16t = 2, 119 constant_16t = 3, 120 udt_16t = 4, 121 ssearch = 5, 122 skip = 7, 123 cvreserve = 8, 124 objname_st = 9, 125 endarg = 10, 126 coboludt_16t = 11, 127 manyreg_16t = 12, 128 @"return" = 13, 129 entrythis = 14, 130 bprel16 = 256, 131 ldata16 = 257, 132 gdata16 = 258, 133 pub16 = 259, 134 lproc16 = 260, 135 gproc16 = 261, 136 thunk16 = 262, 137 block16 = 263, 138 with16 = 264, 139 label16 = 265, 140 cexmodel16 = 266, 141 vftable16 = 267, 142 regrel16 = 268, 143 bprel32_16t = 512, 144 ldata32_16t = 513, 145 gdata32_16t = 514, 146 pub32_16t = 515, 147 lproc32_16t = 516, 148 gproc32_16t = 517, 149 thunk32_st = 518, 150 block32_st = 519, 151 with32_st = 520, 152 label32_st = 521, 153 cexmodel32 = 522, 154 vftable32_16t = 523, 155 regrel32_16t = 524, 156 lthread32_16t = 525, 157 gthread32_16t = 526, 158 slink32 = 527, 159 lprocmips_16t = 768, 160 gprocmips_16t = 769, 161 procref_st = 1024, 162 dataref_st = 1025, 163 @"align" = 1026, 164 lprocref_st = 1027, 165 oem = 1028, 166 ti16_max = 4096, 167 register_st = 4097, 168 constant_st = 4098, 169 udt_st = 4099, 170 coboludt_st = 4100, 171 manyreg_st = 4101, 172 bprel32_st = 4102, 173 ldata32_st = 4103, 174 gdata32_st = 4104, 175 pub32_st = 4105, 176 lproc32_st = 4106, 177 gproc32_st = 4107, 178 vftable32 = 4108, 179 regrel32_st = 4109, 180 lthread32_st = 4110, 181 gthread32_st = 4111, 182 lprocmips_st = 4112, 183 gprocmips_st = 4113, 184 compile2_st = 4115, 185 manyreg2_st = 4116, 186 lprocia64_st = 4117, 187 gprocia64_st = 4118, 188 localslot_st = 4119, 189 paramslot_st = 4120, 190 annotation = 4121, 191 gmanproc_st = 4122, 192 lmanproc_st = 4123, 193 reserved1 = 4124, 194 reserved2 = 4125, 195 reserved3 = 4126, 196 reserved4 = 4127, 197 lmandata_st = 4128, 198 gmandata_st = 4129, 199 manframerel_st = 4130, 200 manregister_st = 4131, 201 manslot_st = 4132, 202 manmanyreg_st = 4133, 203 manregrel_st = 4134, 204 manmanyreg2_st = 4135, 205 mantypref = 4136, 206 unamespace_st = 4137, 207 st_max = 4352, 208 with32 = 4356, 209 manyreg = 4362, 210 lprocmips = 4372, 211 gprocmips = 4373, 212 manyreg2 = 4375, 213 lprocia64 = 4376, 214 gprocia64 = 4377, 215 localslot = 4378, 216 paramslot = 4379, 217 manframerel = 4382, 218 manregister = 4383, 219 manslot = 4384, 220 manmanyreg = 4385, 221 manregrel = 4386, 222 manmanyreg2 = 4387, 223 unamespace = 4388, 224 dataref = 4390, 225 annotationref = 4392, 226 tokenref = 4393, 227 gmanproc = 4394, 228 lmanproc = 4395, 229 attr_framerel = 4398, 230 attr_register = 4399, 231 attr_regrel = 4400, 232 attr_manyreg = 4401, 233 sepcode = 4402, 234 local_2005 = 4403, 235 defrange_2005 = 4404, 236 defrange2_2005 = 4405, 237 discarded = 4411, 238 lprocmips_id = 4424, 239 gprocmips_id = 4425, 240 lprocia64_id = 4426, 241 gprocia64_id = 4427, 242 defrange_hlsl = 4432, 243 gdata_hlsl = 4433, 244 ldata_hlsl = 4434, 245 local_dpc_groupshared = 4436, 246 defrange_dpc_ptr_tag = 4439, 247 dpc_sym_tag_map = 4440, 248 armswitchtable = 4441, 249 pogodata = 4444, 250 inlinesite2 = 4445, 251 mod_typeref = 4447, 252 ref_minipdb = 4448, 253 pdbmap = 4449, 254 gdata_hlsl32 = 4450, 255 ldata_hlsl32 = 4451, 256 gdata_hlsl32_ex = 4452, 257 ldata_hlsl32_ex = 4453, 258 fastlink = 4455, 259 inlinees = 4456, 260 end = 6, 261 inlinesite_end = 4430, 262 proc_id_end = 4431, 263 thunk32 = 4354, 264 trampoline = 4396, 265 section = 4406, 266 coffgroup = 4407, 267 @"export" = 4408, 268 lproc32 = 4367, 269 gproc32 = 4368, 270 lproc32_id = 4422, 271 gproc32_id = 4423, 272 lproc32_dpc = 4437, 273 lproc32_dpc_id = 4438, 274 register = 4358, 275 pub32 = 4366, 276 procref = 4389, 277 lprocref = 4391, 278 envblock = 4413, 279 inlinesite = 4429, 280 local = 4414, 281 defrange = 4415, 282 defrange_subfield = 4416, 283 defrange_register = 4417, 284 defrange_framepointer_rel = 4418, 285 defrange_subfield_register = 4419, 286 defrange_framepointer_rel_full_scope = 4420, 287 defrange_register_rel = 4421, 288 block32 = 4355, 289 label32 = 4357, 290 objname = 4353, 291 compile2 = 4374, 292 compile3 = 4412, 293 frameproc = 4114, 294 callsiteinfo = 4409, 295 filestatic = 4435, 296 heapallocsite = 4446, 297 framecookie = 4410, 298 callees = 4442, 299 callers = 4443, 300 udt = 4360, 301 coboludt = 4361, 302 buildinfo = 4428, 303 bprel32 = 4363, 304 regrel32 = 4369, 305 constant = 4359, 306 manconstant = 4397, 307 ldata32 = 4364, 308 gdata32 = 4365, 309 lmandata = 4380, 310 gmandata = 4381, 311 lthread32 = 4370, 312 gthread32 = 4371, 313 }; 314 315 pub const TypeIndex = u32; 316 317 pub const ProcSym = extern struct { 318 record_len: u16, 319 record_kind: SymbolKind, 320 parent: u32, 321 end: u32, 322 next: u32, 323 code_size: u32, 324 dbg_start: u32, 325 dbg_end: u32, 326 function_type: TypeIndex, 327 code_offset: u32, 328 segment: u16, 329 flags: ProcSymFlags, 330 name: [1]u8, // null-terminated 331 }; 332 333 pub const ProcSymFlags = packed struct(u8) { 334 has_fp: bool, 335 has_iret: bool, 336 has_fret: bool, 337 is_no_return: bool, 338 is_unreachable: bool, 339 has_custom_calling_conv: bool, 340 is_no_inline: bool, 341 has_optimized_debug_info: bool, 342 }; 343 344 pub const SectionContrSubstreamVersion = enum(u32) { 345 Ver60 = 0xeffe0000 + 19970605, 346 V2 = 0xeffe0000 + 20140516, 347 _, 348 }; 349 350 pub const RecordPrefix = extern struct { 351 /// Record length, starting from &record_kind. 352 record_len: u16, 353 354 /// Record kind enum (SymRecordKind or TypeRecordKind) 355 record_kind: SymbolKind, 356 }; 357 358 /// The following variable length array appears immediately after the header. 359 /// The structure definition follows. 360 /// LineBlockFragmentHeader Blocks[] 361 /// Each `LineBlockFragmentHeader` as specified below. 362 pub const LineFragmentHeader = extern struct { 363 /// Code offset of line contribution. 364 reloc_offset: u32, 365 366 /// Code segment of line contribution. 367 reloc_segment: u16, 368 flags: LineFlags, 369 370 /// Code size of this line contribution. 371 code_size: u32, 372 }; 373 374 pub const LineFlags = packed struct(u16) { 375 /// CV_LINES_HAVE_COLUMNS 376 have_columns: bool, 377 unused: u15, 378 }; 379 380 /// The following two variable length arrays appear immediately after the 381 /// header. The structure definitions follow. 382 /// LineNumberEntry Lines[NumLines]; 383 /// ColumnNumberEntry Columns[NumLines]; 384 pub const LineBlockFragmentHeader = extern struct { 385 /// Offset of FileChecksum entry in File 386 /// checksums buffer. The checksum entry then 387 /// contains another offset into the string 388 /// table of the actual name. 389 name_index: u32, 390 num_lines: u32, 391 392 /// code size of block, in bytes 393 block_size: u32, 394 }; 395 396 pub const LineNumberEntry = extern struct { 397 /// Offset to start of code bytes for line number 398 offset: u32, 399 flags: Flags, 400 401 pub const Flags = packed struct(u32) { 402 /// Start line number 403 start: u24, 404 /// Delta of lines to the end of the expression. Still unclear. 405 // TODO figure out the point of this field. 406 end: u7, 407 is_statement: bool, 408 }; 409 }; 410 411 pub const ColumnNumberEntry = extern struct { 412 start_column: u16, 413 end_column: u16, 414 }; 415 416 /// Checksum bytes follow. 417 pub const FileChecksumEntryHeader = extern struct { 418 /// Byte offset of filename in global string table. 419 file_name_offset: u32, 420 /// Number of bytes of checksum. 421 checksum_size: u8, 422 /// FileChecksumKind 423 checksum_kind: u8, 424 }; 425 426 pub const DebugSubsectionKind = enum(u32) { 427 none = 0, 428 symbols = 0xf1, 429 lines = 0xf2, 430 string_table = 0xf3, 431 file_checksums = 0xf4, 432 frame_data = 0xf5, 433 inlinee_lines = 0xf6, 434 cross_scope_imports = 0xf7, 435 cross_scope_exports = 0xf8, 436 437 // These appear to relate to .Net assembly info. 438 il_lines = 0xf9, 439 func_md_token_map = 0xfa, 440 type_md_token_map = 0xfb, 441 merged_assembly_input = 0xfc, 442 443 coff_symbol_rva = 0xfd, 444 }; 445 446 pub const DebugSubsectionHeader = extern struct { 447 /// codeview::DebugSubsectionKind enum 448 kind: DebugSubsectionKind, 449 450 /// number of bytes occupied by this record. 451 length: u32, 452 }; 453 454 pub const StringTableHeader = extern struct { 455 /// PDBStringTableSignature 456 signature: u32, 457 /// 1 or 2 458 hash_version: u32, 459 /// Number of bytes of names buffer. 460 byte_size: u32, 461 }; 462 463 // https://llvm.org/docs/PDB/MsfFile.html#the-superblock 464 pub const SuperBlock = extern struct { 465 /// The LLVM docs list a space between C / C++ but empirically this is not the case. 466 pub const expect_magic = "Microsoft C/C++ MSF 7.00\r\n\x1a\x44\x53\x00\x00\x00"; 467 468 file_magic: [expect_magic.len]u8, 469 470 /// The block size of the internal file system. Valid values are 512, 1024, 471 /// 2048, and 4096 bytes. Certain aspects of the MSF file layout vary depending 472 /// on the block sizes. For the purposes of LLVM, we handle only block sizes of 473 /// 4KiB, and all further discussion assumes a block size of 4KiB. 474 block_size: u32, 475 476 /// The index of a block within the file, at which begins a bitfield representing 477 /// the set of all blocks within the file which are “free” (i.e. the data within 478 /// that block is not used). See The Free Block Map for more information. Important: 479 /// FreeBlockMapBlock can only be 1 or 2! 480 free_block_map_block: u32, 481 482 /// The total number of blocks in the file. NumBlocks * BlockSize should equal the 483 /// size of the file on disk. 484 num_blocks: u32, 485 486 /// The size of the stream directory, in bytes. The stream directory contains 487 /// information about each stream’s size and the set of blocks that it occupies. 488 /// It will be described in more detail later. 489 num_directory_bytes: u32, 490 491 unknown: u32, 492 /// The index of a block within the MSF file. At this block is an array of 493 /// ulittle32_t’s listing the blocks that the stream directory resides on. 494 /// For large MSF files, the stream directory (which describes the block 495 /// layout of each stream) may not fit entirely on a single block. As a 496 /// result, this extra layer of indirection is introduced, whereby this 497 /// block contains the list of blocks that the stream directory occupies, 498 /// and the stream directory itself can be stitched together accordingly. 499 /// The number of ulittle32_t’s in this array is given by 500 /// ceil(NumDirectoryBytes / BlockSize). 501 // Note: microsoft-pdb code actually suggests this is a variable-length 502 // array. If the indices of blocks occupied by the Stream Directory didn't 503 // fit in one page, there would be other u32 following it. 504 // This would mean the Stream Directory is bigger than BlockSize / sizeof(u32) 505 // blocks. We're not even close to this with a 1GB pdb file, and LLVM didn't 506 // implement it so we're kind of safe making this assumption for now. 507 block_map_addr: u32, 508 }; 509 510 pub const IpiStreamVersion = enum(u32) { 511 v40 = 19950410, 512 v41 = 19951122, 513 v50 = 19961031, 514 v70 = 19990903, 515 v80 = 20040203, 516 _, 517 }; 518 519 pub const IpiStreamHeader = extern struct { 520 version: IpiStreamVersion, 521 header_size: u32, 522 type_index_begin: u32, 523 type_index_end: u32, 524 type_record_bytes: u32, 525 hash_stream_index: u16, 526 hash_aux_stream_index: u16, 527 hash_key_size: u32, 528 num_hash_buckets: u32, 529 hash_value_buffer_offset: i32, 530 hash_value_buffer_length: u32, 531 index_offset_buffer_offset: i32, 532 index_offset_buffer_length: u32, 533 hash_adj_buffer_offset: i32, 534 hash_adj_buffer_length: u32, 535 }; 536 537 pub const LfRecordPrefix = extern struct { 538 len: u16, 539 kind: LfRecordKind, 540 }; 541 542 pub const LfRecordKind = enum(u16) { 543 pointer = 0x1002, 544 modifier = 0x1001, 545 procedure = 0x1008, 546 mfunction = 0x1009, 547 label = 0x000e, 548 arglist = 0x1201, 549 fieldlist = 0x1203, 550 array = 0x1503, 551 class = 0x1504, 552 structure = 0x1505, 553 interface = 0x1519, 554 @"union" = 0x1506, 555 @"enum" = 0x1507, 556 typeserver2 = 0x1515, 557 vftable = 0x151d, 558 vtshape = 0x000a, 559 bitfield = 0x1205, 560 func_id = 0x1601, 561 mfunc_id = 0x1602, 562 buildinfo = 0x1603, 563 substr_list = 0x1604, 564 string_id = 0x1605, 565 udt_src_line = 0x1606, 566 udt_mod_src_line = 0x1607, 567 methodlist = 0x1206, 568 precomp = 0x1509, 569 endprecomp = 0x0014, 570 bclass = 0x1400, 571 binterface = 0x151a, 572 vbclass = 0x1401, 573 ivbclass = 0x1402, 574 vfunctab = 0x1409, 575 stmember = 0x150e, 576 method = 0x150f, 577 member = 0x150d, 578 nesttype = 0x1510, 579 onemethod = 0x1511, 580 enumerate = 0x1502, 581 index = 0x1404, 582 pad0 = 0xf0, 583 _, 584 }; 585 586 pub const LfFuncId = extern struct { 587 len: u16, 588 kind: LfRecordKind, 589 scope_id: u32, 590 type: u32, 591 name: [1]u8, // null-terminated 592 }; 593 594 pub const LfMFuncId = extern struct { 595 len: u16, 596 kind: LfRecordKind, 597 parent_type: u32, 598 type: u32, 599 name: [1]u8, // null-terminated 600 }; 601 602 pub const InlineSiteSym = extern struct { 603 record_len: u16, 604 record_kind: SymbolKind, 605 parent: u32, 606 end: u32, 607 inlinee: u32, 608 }; 609 610 pub const InlineSiteSym2 = extern struct { 611 record_len: u16, 612 record_kind: SymbolKind, 613 parent: u32, 614 end: u32, 615 inlinee: u32, 616 invocations: u32, 617 }; 618 619 pub const InlineeSourceLineSignature = enum(u32) { normal = 0, ex = 1, _ }; 620 621 pub const InlineeSourceLine = extern struct { 622 inlinee: u32, 623 file_id: u32, 624 source_line_num: u32, 625 }; 626 627 pub const InlineeSourceLineEx = extern struct { 628 inlinee: u32, 629 file_id: u32, 630 source_line_num: u32, 631 count_of_extra_files: u32, 632 }; 633 634 pub const BinaryAnnotationOpcode = enum(u8) { 635 invalid = 0, 636 code_offset = 1, 637 change_code_offset_base = 2, 638 change_code_offset = 3, 639 change_code_length = 4, 640 change_file = 5, 641 change_line_offset = 6, 642 change_line_end_delta = 7, 643 change_range_kind = 8, 644 change_column_start = 9, 645 change_column_end_delta = 10, 646 change_code_offset_and_line_offset = 11, 647 change_code_length_and_code_offset = 12, 648 change_column_end = 13, 649 }; 650