| ... | ... | @@ -455,33 +455,65 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo { |
| 455 | 455 | const name_bytes = try allocator.alloc(u8, name_bytes_len); |
| 456 | 456 | try pdb_stream.stream.readNoEof(name_bytes); |
| 457 | 457 | |
| 458 | | //const HashTableHeader = packed struct { |
| 459 | | // Size: u32, |
| 460 | | // Capacity: u32, |
| 461 | | |
| 462 | | // fn maxLoad(cap: u32) u32 { |
| 463 | | // return cap * 2 / 3 + 1; |
| 464 | | // } |
| 465 | | //}; |
| 466 | | //var hash_tbl_hdr: HashTableHeader = undefined; |
| 467 | | //try pdb_stream.stream.readStruct(Header, &hash_tbl_hdr); |
| 468 | | //if (hash_tbl_hdr.Capacity == 0) |
| 469 | | // return error.InvalidDebugInfo; |
| 470 | | |
| 471 | | //if (hash_tbl_hdr.Size > HashTableHeader.maxLoad(hash_tbl_hdr.Capacity)) |
| 472 | | // return error.InvalidDebugInfo; |
| 473 | | |
| 474 | | //std.debug.warn("{}\n", hash_tbl_hdr); |
| 475 | | |
| 476 | | //var more_buf: [100]u8 = undefined; |
| 477 | | //const more_len = try pdb_stream.stream.read(more_buf[0..]); |
| 478 | | //for (more_buf[0..more_len]) |x| { |
| 479 | | // std.debug.warn("{x2} {c}\n", x, x); |
| 480 | | //} |
| 458 | const HashTableHeader = packed struct { |
| 459 | Size: u32, |
| 460 | Capacity: u32, |
| 461 | |
| 462 | fn maxLoad(cap: u32) u32 { |
| 463 | return cap * 2 / 3 + 1; |
| 464 | } |
| 465 | }; |
| 466 | var hash_tbl_hdr: HashTableHeader = undefined; |
| 467 | try pdb_stream.stream.readStruct(HashTableHeader, &hash_tbl_hdr); |
| 468 | if (hash_tbl_hdr.Capacity == 0) |
| 469 | return error.InvalidDebugInfo; |
| 470 | |
| 471 | if (hash_tbl_hdr.Size > HashTableHeader.maxLoad(hash_tbl_hdr.Capacity)) |
| 472 | return error.InvalidDebugInfo; |
| 473 | |
| 474 | std.debug.warn("{}\n", hash_tbl_hdr); |
| 475 | |
| 476 | const present = try readSparseBitVector(&pdb_stream.stream, allocator); |
| 477 | if (present.len != hash_tbl_hdr.Size) |
| 478 | return error.InvalidDebugInfo; |
| 479 | const deleted = try readSparseBitVector(&pdb_stream.stream, allocator); |
| 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 | 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 | 517 | fn openSelfDebugInfoLinux(allocator: *mem.Allocator) !DebugInfo { |
| 486 | 518 | var di = DebugInfo{ |
| 487 | 519 | .self_exe_file = undefined, |