| 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 | }; |