| ... | @@ -455,33 +455,65 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { | ... | @@ -455,33 +455,65 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { |
| 455 | const name_bytes = try allocator.alloc(u8, name_bytes_len); | 455 | const name_bytes = try allocator.alloc(u8, name_bytes_len); |
| 456 | try pdb_stream.stream.readNoEof(name_bytes); | 456 | try pdb_stream.stream.readNoEof(name_bytes); |
| 457 | | 457 | |
| 458 | //const HashTableHeader = packed struct { | 458 | const HashTableHeader = packed struct { |
| 459 | // Size: u32, | 459 | Size: u32, |
| 460 | // Capacity: u32, | 460 | Capacity: u32, |
| 461 | | 461 | |
| 462 | // fn maxLoad(cap: u32) u32 { | 462 | fn maxLoad(cap: u32) u32 { |
| 463 | // return cap * 2 / 3 + 1; | 463 | return cap * 2 / 3 + 1; |
| 464 | // } | 464 | } |
| 465 | //}; | 465 | }; |
| 466 | //var hash_tbl_hdr: HashTableHeader = undefined; | 466 | var hash_tbl_hdr: HashTableHeader = undefined; |
| 467 | //try pdb_stream.stream.readStruct(Header, &hash_tbl_hdr); | 467 | try pdb_stream.stream.readStruct(HashTableHeader, &hash_tbl_hdr); |
| 468 | //if (hash_tbl_hdr.Capacity == 0) | 468 | if (hash_tbl_hdr.Capacity == 0) |
| 469 | // return error.InvalidDebugInfo; | 469 | return error.InvalidDebugInfo; |
| 470 | | 470 | |
| 471 | //if (hash_tbl_hdr.Size > HashTableHeader.maxLoad(hash_tbl_hdr.Capacity)) | 471 | if (hash_tbl_hdr.Size > HashTableHeader.maxLoad(hash_tbl_hdr.Capacity)) |
| 472 | // return error.InvalidDebugInfo; | 472 | return error.InvalidDebugInfo; |
| 473 | | 473 | |
| 474 | //std.debug.warn("{}\n", hash_tbl_hdr); | 474 | std.debug.warn("{}\n", hash_tbl_hdr); |
| 475 | | 475 | |
| 476 | //var more_buf: [100]u8 = undefined; | 476 | const present = try readSparseBitVector(&pdb_stream.stream, allocator); |
| 477 | //const more_len = try pdb_stream.stream.read(more_buf[0..]); | 477 | if (present.len != hash_tbl_hdr.Size) |
| 478 | //for (more_buf[0..more_len]) |x| { | 478 | return error.InvalidDebugInfo; |
| 479 | // std.debug.warn("{x2} {c}\n", x, x); | 479 | const deleted = try readSparseBitVector(&pdb_stream.stream, allocator); |
| 480 | //} | 480 | |
| | 481 | const Bucket = struct { |
| | 482 | first: u32, |
| | 483 | second: u32, |
| | 484 | }; |
| | 485 | const bucket_list = try allocator.alloc(Bucket, present.len); |
| | 486 | const string_table_index = for (present) |_| { |
| | 487 | const name_offset = try pdb_stream.stream.readIntLe(u32); |
| | 488 | const name_index = try pdb_stream.stream.readIntLe(u32); |
| | 489 | const name = mem.toSlice(u8, name_bytes.ptr + name_offset); |
| | 490 | if (mem.eql(u8, name, "/names")) { |
| | 491 | break name_index; |
| | 492 | } |
| | 493 | } else return error.MissingDebugInfo; |
| | 494 | |
| | 495 | di.pdb.string_table = di.pdb.getStreamById(string_table_index) orelse return error.InvalidDebugInfo; |
| 481 | | 496 | |
| 482 | return di; | 497 | return di; |
| 483 | } | 498 | } |
| 484 | | 499 | |
| | 500 | fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize { |
| | 501 | const num_words = try stream.readIntLe(u32); |
| | 502 | var word_i: usize = 0; |
| | 503 | var list = ArrayList(usize).init(allocator); |
| | 504 | while (word_i != num_words) : (word_i += 1) { |
| | 505 | const word = try stream.readIntLe(u32); |
| | 506 | var bit_i: u5 = 0; |
| | 507 | while (true) : (bit_i += 1) { |
| | 508 | if (word & (u32(1) << bit_i) != 0) { |
| | 509 | try list.append(word_i * 32 + bit_i); |
| | 510 | } |
| | 511 | if (bit_i == @maxValue(u5)) break; |
| | 512 | } |
| | 513 | } |
| | 514 | return list.toOwnedSlice(); |
| | 515 | } |
| | 516 | |
| 485 | fn openSelfDebugInfoLinux(allocator: *mem.Allocator) !DebugInfo { | 517 | fn openSelfDebugInfoLinux(allocator: *mem.Allocator) !DebugInfo { |
| 486 | var di = DebugInfo{ | 518 | var di = DebugInfo{ |
| 487 | .self_exe_file = undefined, | 519 | .self_exe_file = undefined, |