authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-08-28 21:32:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-08-28 22:41:06-07:00
log43fbc37a490442ffcecf9817877f542251fee664
treefab48f93c108fbab1544edc6cdc772c8a070b1d7
parent7da9e4b35e710d6b94114a21017630c5f15940bd

std.debug.Pdb: migrate more towards new Reader API

There was some bug in this branch, and rather than diagnosing it, I fully finished porting over to new Reader API. Did it fix the bug?

3 files changed, 189 insertions(+), 170 deletions(-)

lib/std/Io/Reader.zig+2-2
......@@ -143,8 +143,8 @@ pub const failing: Reader = .{
143143
144144/// This is generally safe to `@constCast` because it has an empty buffer, so
145145/// there is not really a way to accidentally attempt mutation of these fields.
146const ending_state: Reader = .fixed(&.{});
147pub const ending: *Reader = @constCast(&ending_state);
146pub const ending_instance: Reader = .fixed(&.{});
147pub const ending: *Reader = @constCast(&ending_instance);
148148
149149pub fn limited(r: *Reader, limit: Limit, buffer: []u8) Limited {
150150 return .init(r, limit, buffer);
lib/std/debug/Pdb.zig+153-151
......@@ -6,7 +6,7 @@ const assert = std.debug.assert;
66
77const Pdb = @This();
88
9in_file: File,
9file_reader: *File.Reader,
1010msf: Msf,
1111allocator: Allocator,
1212string_table: ?*MsfStream,
......@@ -36,31 +36,28 @@ pub const Module = struct {
3636 }
3737};
3838
39pub fn init(allocator: Allocator, path: []const u8) !Pdb {
40 const file = try std.fs.cwd().openFile(path, .{});
41 errdefer file.close();
42
39pub fn init(gpa: Allocator, file_reader: *File.Reader) !Pdb {
4340 return .{
44 .in_file = file,
45 .allocator = allocator,
41 .file_reader = file_reader,
42 .allocator = gpa,
4643 .string_table = null,
4744 .dbi = null,
48 .msf = try Msf.init(allocator, file),
49 .modules = &[_]Module{},
50 .sect_contribs = &[_]pdb.SectionContribEntry{},
45 .msf = try Msf.init(gpa, file_reader),
46 .modules = &.{},
47 .sect_contribs = &.{},
5148 .guid = undefined,
5249 .age = undefined,
5350 };
5451}
5552
5653pub fn deinit(self: *Pdb) void {
57 self.in_file.close();
58 self.msf.deinit(self.allocator);
54 const gpa = self.allocator;
55 self.msf.deinit(gpa);
5956 for (self.modules) |*module| {
60 module.deinit(self.allocator);
57 module.deinit(gpa);
6158 }
62 self.allocator.free(self.modules);
63 self.allocator.free(self.sect_contribs);
59 gpa.free(self.modules);
60 gpa.free(self.sect_contribs);
6461}
6562
6663pub fn parseDbiStream(self: *Pdb) !void {
......@@ -68,11 +65,7 @@ pub fn parseDbiStream(self: *Pdb) !void {
6865 return error.InvalidDebugInfo;
6966
7067 const gpa = self.allocator;
71
72 const deprecated_reader = stream.reader();
73 var adapted_buffer: [1024]u8 = undefined;
74 var adapted_reader = deprecated_reader.adaptToNewApi(&adapted_buffer);
75 const reader = &adapted_reader.new_interface;
68 const reader = &stream.interface;
7669
7770 const header = try reader.takeStruct(std.pdb.DbiStreamHeader, .little);
7871 if (header.version_header != 19990903) // V70, only value observed by LLVM team
......@@ -113,7 +106,7 @@ pub fn parseDbiStream(self: *Pdb) !void {
113106 this_record_len += march_forward_bytes;
114107 }
115108
116 try modules.append(Module{
109 try modules.append(.{
117110 .mod_info = mod_info,
118111 .module_name = try module_name.toOwnedSlice(),
119112 .obj_file_name = try obj_file_name.toOwnedSlice(),
......@@ -156,29 +149,28 @@ pub fn parseDbiStream(self: *Pdb) !void {
156149}
157150
158151pub fn parseInfoStream(self: *Pdb) !void {
159 var stream = self.getStream(pdb.StreamType.pdb) orelse
160 return error.InvalidDebugInfo;
161 const reader = stream.reader();
152 var stream = self.getStream(pdb.StreamType.pdb) orelse return error.InvalidDebugInfo;
153 const reader = &stream.interface;
162154
163155 // Parse the InfoStreamHeader.
164 const version = try reader.readInt(u32, .little);
165 const signature = try reader.readInt(u32, .little);
156 const version = try reader.takeInt(u32, .little);
157 const signature = try reader.takeInt(u32, .little);
166158 _ = signature;
167 const age = try reader.readInt(u32, .little);
168 const guid = try reader.readBytesNoEof(16);
159 const age = try reader.takeInt(u32, .little);
160 const guid = try reader.takeArray(16);
169161
170162 if (version != 20000404) // VC70, only value observed by LLVM team
171163 return error.UnknownPDBVersion;
172164
173 self.guid = guid;
165 self.guid = guid.*;
174166 self.age = age;
175167
168 const gpa = self.allocator;
169
176170 // Find the string table.
177171 const string_table_index = str_tab_index: {
178 const name_bytes_len = try reader.readInt(u32, .little);
179 const name_bytes = try self.allocator.alloc(u8, name_bytes_len);
180 defer self.allocator.free(name_bytes);
181 try reader.readNoEof(name_bytes);
172 const name_bytes_len = try reader.takeInt(u32, .little);
173 const name_bytes = try reader.readAlloc(gpa, name_bytes_len);
182174
183175 const HashTableHeader = extern struct {
184176 size: u32,
......@@ -188,23 +180,23 @@ pub fn parseInfoStream(self: *Pdb) !void {
188180 return cap * 2 / 3 + 1;
189181 }
190182 };
191 const hash_tbl_hdr = try reader.readStruct(HashTableHeader);
183 const hash_tbl_hdr = try reader.takeStruct(HashTableHeader, .little);
192184 if (hash_tbl_hdr.capacity == 0)
193185 return error.InvalidDebugInfo;
194186
195187 if (hash_tbl_hdr.size > HashTableHeader.maxLoad(hash_tbl_hdr.capacity))
196188 return error.InvalidDebugInfo;
197189
198 const present = try readSparseBitVector(&reader, self.allocator);
199 defer self.allocator.free(present);
190 const present = try readSparseBitVector(reader, gpa);
191 defer gpa.free(present);
200192 if (present.len != hash_tbl_hdr.size)
201193 return error.InvalidDebugInfo;
202 const deleted = try readSparseBitVector(&reader, self.allocator);
203 defer self.allocator.free(deleted);
194 const deleted = try readSparseBitVector(reader, gpa);
195 defer gpa.free(deleted);
204196
205197 for (present) |_| {
206 const name_offset = try reader.readInt(u32, .little);
207 const name_index = try reader.readInt(u32, .little);
198 const name_offset = try reader.takeInt(u32, .little);
199 const name_index = try reader.takeInt(u32, .little);
208200 if (name_offset > name_bytes.len)
209201 return error.InvalidDebugInfo;
210202 const name = std.mem.sliceTo(name_bytes[name_offset..], 0);
......@@ -302,14 +294,12 @@ pub fn getLineNumberInfo(self: *Pdb, module: *Module, address: u64) !std.debug.S
302294 const strtab_offset = @sizeOf(pdb.StringTableHeader) + chksum_hdr.file_name_offset;
303295 try self.string_table.?.seekTo(strtab_offset);
304296 const source_file_name = s: {
305 const deprecated_reader = self.string_table.?.reader();
306 var adapted_buffer: [1024]u8 = undefined;
307 var adapted_reader = deprecated_reader.adaptToNewApi(&adapted_buffer);
297 const string_reader = &self.string_table.?.interface;
308298 var source_file_name: std.Io.Writer.Allocating = .init(gpa);
309299 defer source_file_name.deinit();
310 _ = try adapted_reader.new_interface.streamDelimiterLimit(&source_file_name.writer, 0, .limited(1024));
311 assert(adapted_reader.new_interface.buffered()[0] == 0); // TODO change streamDelimiterLimit API
312 adapted_reader.new_interface.toss(1);
300 _ = try string_reader.streamDelimiterLimit(&source_file_name.writer, 0, .limited(1024));
301 assert(string_reader.buffered()[0] == 0); // TODO change streamDelimiterLimit API
302 string_reader.toss(1);
313303 break :s try source_file_name.toOwnedSlice();
314304 };
315305 errdefer gpa.free(source_file_name);
......@@ -366,19 +356,16 @@ pub fn getModule(self: *Pdb, index: usize) !?*Module {
366356
367357 const stream = self.getStreamById(mod.mod_info.module_sym_stream) orelse
368358 return error.MissingDebugInfo;
369 const reader = stream.reader();
359 const reader = &stream.interface;
370360
371 const signature = try reader.readInt(u32, .little);
361 const signature = try reader.takeInt(u32, .little);
372362 if (signature != 4)
373363 return error.InvalidDebugInfo;
374364
375 mod.symbols = try self.allocator.alloc(u8, mod.mod_info.sym_byte_size - 4);
376 errdefer self.allocator.free(mod.symbols);
377 try reader.readNoEof(mod.symbols);
365 const gpa = self.allocator;
378366
379 mod.subsect_info = try self.allocator.alloc(u8, mod.mod_info.c13_byte_size);
380 errdefer self.allocator.free(mod.subsect_info);
381 try reader.readNoEof(mod.subsect_info);
367 mod.symbols = try reader.readAlloc(gpa, mod.mod_info.sym_byte_size - 4);
368 mod.subsect_info = try reader.readAlloc(gpa, mod.mod_info.c13_byte_size);
382369
383370 var sect_offset: usize = 0;
384371 var skip_len: usize = undefined;
......@@ -404,8 +391,7 @@ pub fn getModule(self: *Pdb, index: usize) !?*Module {
404391}
405392
406393pub fn getStreamById(self: *Pdb, id: u32) ?*MsfStream {
407 if (id >= self.msf.streams.len)
408 return null;
394 if (id >= self.msf.streams.len) return null;
409395 return &self.msf.streams[id];
410396}
411397
......@@ -419,17 +405,14 @@ const Msf = struct {
419405 directory: MsfStream,
420406 streams: []MsfStream,
421407
422 fn init(allocator: Allocator, file: File) !Msf {
423 const in = file.deprecatedReader();
424
425 const superblock = try in.readStruct(pdb.SuperBlock);
408 fn init(gpa: Allocator, file_reader: *File.Reader) !Msf {
409 const superblock = try file_reader.interface.takeStruct(pdb.SuperBlock, .little);
426410
427 // Sanity checks
428411 if (!std.mem.eql(u8, &superblock.file_magic, pdb.SuperBlock.expect_magic))
429412 return error.InvalidDebugInfo;
430413 if (superblock.free_block_map_block != 1 and superblock.free_block_map_block != 2)
431414 return error.InvalidDebugInfo;
432 const file_len = try file.getEndPos();
415 const file_len = try file_reader.getSize();
433416 if (superblock.num_blocks * superblock.block_size != file_len)
434417 return error.InvalidDebugInfo;
435418 switch (superblock.block_size) {
......@@ -442,163 +425,182 @@ const Msf = struct {
442425 if (dir_block_count > superblock.block_size / @sizeOf(u32))
443426 return error.UnhandledBigDirectoryStream; // cf. BlockMapAddr comment.
444427
445 try file.seekTo(superblock.block_size * superblock.block_map_addr);
446 const dir_blocks = try allocator.alloc(u32, dir_block_count);
428 try file_reader.seekTo(superblock.block_size * superblock.block_map_addr);
429 const dir_blocks = try gpa.alloc(u32, dir_block_count);
447430 for (dir_blocks) |*b| {
448 b.* = try in.readInt(u32, .little);
431 b.* = try file_reader.interface.takeInt(u32, .little);
449432 }
450 var directory = MsfStream.init(
451 superblock.block_size,
452 file,
453 dir_blocks,
454 );
433 var directory_buffer: [64]u8 = undefined;
434 var directory = MsfStream.init(superblock.block_size, file_reader, dir_blocks, &directory_buffer);
455435
456 const begin = directory.pos;
457 const stream_count = try directory.reader().readInt(u32, .little);
458 const stream_sizes = try allocator.alloc(u32, stream_count);
459 defer allocator.free(stream_sizes);
436 const begin = directory.logicalPos();
437 const stream_count = try directory.interface.takeInt(u32, .little);
438 const stream_sizes = try gpa.alloc(u32, stream_count);
439 defer gpa.free(stream_sizes);
460440
461441 // Microsoft's implementation uses @as(u32, -1) for inexistent streams.
462442 // These streams are not used, but still participate in the file
463443 // and must be taken into account when resolving stream indices.
464 const Nil = 0xFFFFFFFF;
444 const nil_size = 0xFFFFFFFF;
465445 for (stream_sizes) |*s| {
466 const size = try directory.reader().readInt(u32, .little);
467 s.* = if (size == Nil) 0 else blockCountFromSize(size, superblock.block_size);
446 const size = try directory.interface.takeInt(u32, .little);
447 s.* = if (size == nil_size) 0 else blockCountFromSize(size, superblock.block_size);
468448 }
469449
470 const streams = try allocator.alloc(MsfStream, stream_count);
450 const streams = try gpa.alloc(MsfStream, stream_count);
451 errdefer gpa.free(streams);
452
471453 for (streams, 0..) |*stream, i| {
472454 const size = stream_sizes[i];
473455 if (size == 0) {
474 stream.* = MsfStream{
475 .blocks = &[_]u32{},
476 };
456 stream.* = .empty;
477457 } else {
478 var blocks = try allocator.alloc(u32, size);
479 var j: u32 = 0;
480 while (j < size) : (j += 1) {
481 const block_id = try directory.reader().readInt(u32, .little);
458 const blocks = try gpa.alloc(u32, size);
459 errdefer gpa.free(blocks);
460 for (blocks) |*block| {
461 const block_id = try directory.interface.takeInt(u32, .little);
482462 const n = (block_id % superblock.block_size);
483463 // 0 is for pdb.SuperBlock, 1 and 2 for FPMs.
484464 if (block_id == 0 or n == 1 or n == 2 or block_id * superblock.block_size > file_len)
485465 return error.InvalidBlockIndex;
486 blocks[j] = block_id;
466 block.* = block_id;
487467 }
488
489 stream.* = MsfStream.init(
490 superblock.block_size,
491 file,
492 blocks,
493 );
468 const buffer = try gpa.alloc(u8, 64);
469 errdefer gpa.free(buffer);
470 stream.* = .init(superblock.block_size, file_reader, blocks, buffer);
494471 }
495472 }
496473
497 const end = directory.pos;
474 const end = directory.logicalPos();
498475 if (end - begin != superblock.num_directory_bytes)
499476 return error.InvalidStreamDirectory;
500477
501 return Msf{
478 return .{
502479 .directory = directory,
503480 .streams = streams,
504481 };
505482 }
506483
507 fn deinit(self: *Msf, allocator: Allocator) void {
508 allocator.free(self.directory.blocks);
484 fn deinit(self: *Msf, gpa: Allocator) void {
485 gpa.free(self.directory.blocks);
509486 for (self.streams) |*stream| {
510 allocator.free(stream.blocks);
487 gpa.free(stream.interface.buffer);
488 gpa.free(stream.blocks);
511489 }
512 allocator.free(self.streams);
490 gpa.free(self.streams);
513491 }
514492};
515493
516494const MsfStream = struct {
517 in_file: File = undefined,
518 pos: u64 = undefined,
519 blocks: []u32 = undefined,
520 block_size: u32 = undefined,
521
522 pub const Error = @typeInfo(@typeInfo(@TypeOf(read)).@"fn".return_type.?).error_union.error_set;
495 file_reader: *File.Reader,
496 next_read_pos: u64,
497 blocks: []u32,
498 block_size: u32,
499 interface: std.Io.Reader,
500 err: ?Error,
501
502 const Error = File.Reader.SeekError;
503
504 const empty: MsfStream = .{
505 .file_reader = undefined,
506 .next_read_pos = 0,
507 .blocks = &.{},
508 .block_size = undefined,
509 .interface = .ending_instance,
510 .err = null,
511 };
523512
524 fn init(block_size: u32, file: File, blocks: []u32) MsfStream {
525 const stream = MsfStream{
526 .in_file = file,
527 .pos = 0,
513 fn init(block_size: u32, file_reader: *File.Reader, blocks: []u32, buffer: []u8) MsfStream {
514 return .{
515 .file_reader = file_reader,
516 .next_read_pos = 0,
528517 .blocks = blocks,
529518 .block_size = block_size,
519 .interface = .{
520 .vtable = &.{ .stream = stream },
521 .buffer = buffer,
522 .seek = 0,
523 .end = 0,
524 },
525 .err = null,
530526 };
531
532 return stream;
533527 }
534528
535 fn read(self: *MsfStream, buffer: []u8) !usize {
536 var block_id = @as(usize, @intCast(self.pos / self.block_size));
537 if (block_id >= self.blocks.len) return 0; // End of Stream
538 var block = self.blocks[block_id];
539 var offset = self.pos % self.block_size;
529 fn stream(r: *std.Io.Reader, w: *std.Io.Writer, limit: std.Io.Limit) std.Io.Reader.StreamError!usize {
530 const ms: *MsfStream = @alignCast(@fieldParentPtr("interface", r));
540531
541 try self.in_file.seekTo(block * self.block_size + offset);
542 const in = self.in_file.deprecatedReader();
532 var block_id: usize = @intCast(ms.next_read_pos / ms.block_size);
533 if (block_id >= ms.blocks.len) return error.EndOfStream;
534 var block = ms.blocks[block_id];
535 var offset = ms.next_read_pos % ms.block_size;
543536
544 var size: usize = 0;
545 var rem_buffer = buffer;
546 while (size < buffer.len) {
547 const size_to_read = @min(self.block_size - offset, rem_buffer.len);
548 size += try in.read(rem_buffer[0..size_to_read]);
549 rem_buffer = buffer[size..];
550 offset += size_to_read;
537 ms.file_reader.seekTo(block * ms.block_size + offset) catch |err| {
538 ms.err = err;
539 return error.ReadFailed;
540 };
541
542 var remaining = @intFromEnum(limit);
543 while (remaining != 0) {
544 const stream_len: usize = @min(remaining, ms.block_size - offset);
545 const n = try ms.file_reader.interface.stream(w, .limited(stream_len));
546 remaining -= n;
547 offset += n;
551548
552549 // If we're at the end of a block, go to the next one.
553 if (offset == self.block_size) {
550 if (offset == ms.block_size) {
554551 offset = 0;
555552 block_id += 1;
556 if (block_id >= self.blocks.len) break; // End of Stream
557 block = self.blocks[block_id];
558 try self.in_file.seekTo(block * self.block_size);
553 if (block_id >= ms.blocks.len) break; // End of Stream
554 block = ms.blocks[block_id];
555 ms.file_reader.seekTo(block * ms.block_size) catch |err| {
556 ms.err = err;
557 return error.ReadFailed;
558 };
559559 }
560560 }
561561
562 self.pos += buffer.len;
563 return buffer.len;
562 const total = @intFromEnum(limit) - remaining;
563 ms.next_read_pos += total;
564 return total;
564565 }
565566
566 pub fn seekBy(self: *MsfStream, len: i64) !void {
567 self.pos = @as(u64, @intCast(@as(i64, @intCast(self.pos)) + len));
568 if (self.pos >= self.blocks.len * self.block_size)
569 return error.EOF;
567 pub fn logicalPos(ms: *const MsfStream) u64 {
568 return ms.next_read_pos - ms.interface.bufferedLen();
570569 }
571570
572 pub fn seekTo(self: *MsfStream, len: u64) !void {
573 self.pos = len;
574 if (self.pos >= self.blocks.len * self.block_size)
575 return error.EOF;
571 pub fn seekBy(ms: *MsfStream, len: i64) !void {
572 ms.next_read_pos = @as(u64, @intCast(@as(i64, @intCast(ms.logicalPos())) + len));
573 if (ms.next_read_pos >= ms.blocks.len * ms.block_size) return error.EOF;
574 ms.interface.tossBuffered();
576575 }
577576
578 fn getSize(self: *const MsfStream) u64 {
579 return self.blocks.len * self.block_size;
577 pub fn seekTo(ms: *MsfStream, len: u64) !void {
578 ms.next_read_pos = len;
579 if (ms.next_read_pos >= ms.blocks.len * ms.block_size) return error.EOF;
580 ms.interface.tossBuffered();
580581 }
581582
582 fn getFilePos(self: MsfStream) u64 {
583 const block_id = self.pos / self.block_size;
584 const block = self.blocks[block_id];
585 const offset = self.pos % self.block_size;
586
587 return block * self.block_size + offset;
583 fn getSize(ms: *const MsfStream) u64 {
584 return ms.blocks.len * ms.block_size;
588585 }
589586
590 pub fn reader(self: *MsfStream) std.io.GenericReader(*MsfStream, Error, read) {
591 return .{ .context = self };
587 fn getFilePos(ms: *const MsfStream) u64 {
588 const pos = ms.logicalPos();
589 const block_id = pos / ms.block_size;
590 const block = ms.blocks[block_id];
591 const offset = pos % ms.block_size;
592
593 return block * ms.block_size + offset;
592594 }
593595};
594596
595fn readSparseBitVector(stream: anytype, allocator: Allocator) ![]u32 {
596 const num_words = try stream.readInt(u32, .little);
597fn readSparseBitVector(reader: *std.Io.Reader, allocator: Allocator) ![]u32 {
598 const num_words = try reader.takeInt(u32, .little);
597599 var list = std.array_list.Managed(u32).init(allocator);
598600 errdefer list.deinit();
599601 var word_i: u32 = 0;
600602 while (word_i != num_words) : (word_i += 1) {
601 const word = try stream.readInt(u32, .little);
603 const word = try reader.takeInt(u32, .little);
602604 var bit_i: u5 = 0;
603605 while (true) : (bit_i += 1) {
604606 if (word & (@as(u32, 1) << bit_i) != 0) {
lib/std/debug/SelfInfo.zig+34-17
......@@ -713,22 +713,26 @@ pub const Module = switch (native_os) {
713713 },
714714 .uefi, .windows => struct {
715715 base_address: usize,
716 pdb: ?Pdb = null,
717 dwarf: ?Dwarf = null,
716 pdb: ?Pdb,
717 dwarf: ?Dwarf,
718718 coff_image_base: u64,
719719
720720 /// Only used if pdb is non-null
721721 coff_section_headers: []coff.SectionHeader,
722722
723 pub fn deinit(self: *@This(), allocator: Allocator) void {
723 pub fn deinit(self: *@This(), gpa: Allocator) void {
724724 if (self.dwarf) |*dwarf| {
725 dwarf.deinit(allocator);
725 dwarf.deinit(gpa);
726726 }
727727
728728 if (self.pdb) |*p| {
729 gpa.free(p.file_reader.interface.buffer);
730 gpa.destroy(p.file_reader);
729731 p.deinit();
730 allocator.free(self.coff_section_headers);
732 gpa.free(self.coff_section_headers);
731733 }
734
735 self.* = undefined;
732736 }
733737
734738 fn getSymbolFromPdb(self: *@This(), relocated_address: usize) !?std.debug.Symbol {
......@@ -970,23 +974,25 @@ fn readMachODebugInfo(allocator: Allocator, macho_file: File) !Module {
970974 };
971975}
972976
973fn readCoffDebugInfo(allocator: Allocator, coff_obj: *coff.Coff) !Module {
977fn readCoffDebugInfo(gpa: Allocator, coff_obj: *coff.Coff) !Module {
974978 nosuspend {
975979 var di: Module = .{
976980 .base_address = undefined,
977981 .coff_image_base = coff_obj.getImageBase(),
978982 .coff_section_headers = undefined,
983 .pdb = null,
984 .dwarf = null,
979985 };
980986
981987 if (coff_obj.getSectionByName(".debug_info")) |_| {
982988 // This coff file has embedded DWARF debug info
983989 var sections: Dwarf.SectionArray = Dwarf.null_section_array;
984 errdefer for (sections) |section| if (section) |s| if (s.owned) allocator.free(s.data);
990 errdefer for (sections) |section| if (section) |s| if (s.owned) gpa.free(s.data);
985991
986992 inline for (@typeInfo(Dwarf.Section.Id).@"enum".fields, 0..) |section, i| {
987993 sections[i] = if (coff_obj.getSectionByName("." ++ section.name)) |section_header| blk: {
988994 break :blk .{
989 .data = try coff_obj.getSectionDataAlloc(section_header, allocator),
995 .data = try coff_obj.getSectionDataAlloc(section_header, gpa),
990996 .virtual_address = section_header.virtual_address,
991997 .owned = true,
992998 };
......@@ -999,7 +1005,7 @@ fn readCoffDebugInfo(allocator: Allocator, coff_obj: *coff.Coff) !Module {
9991005 .is_macho = false,
10001006 };
10011007
1002 try Dwarf.open(&dwarf, allocator);
1008 try Dwarf.open(&dwarf, gpa);
10031009 di.dwarf = dwarf;
10041010 }
10051011
......@@ -1008,20 +1014,31 @@ fn readCoffDebugInfo(allocator: Allocator, coff_obj: *coff.Coff) !Module {
10081014 if (fs.path.isAbsolute(raw_path)) {
10091015 break :blk raw_path;
10101016 } else {
1011 const self_dir = try fs.selfExeDirPathAlloc(allocator);
1012 defer allocator.free(self_dir);
1013 break :blk try fs.path.join(allocator, &.{ self_dir, raw_path });
1017 const self_dir = try fs.selfExeDirPathAlloc(gpa);
1018 defer gpa.free(self_dir);
1019 break :blk try fs.path.join(gpa, &.{ self_dir, raw_path });
10141020 }
10151021 };
1016 defer if (path.ptr != raw_path.ptr) allocator.free(path);
1022 defer if (path.ptr != raw_path.ptr) gpa.free(path);
10171023
1018 di.pdb = Pdb.init(allocator, path) catch |err| switch (err) {
1024 const pdb_file = std.fs.cwd().openFile(path, .{}) catch |err| switch (err) {
10191025 error.FileNotFound, error.IsDir => {
10201026 if (di.dwarf == null) return error.MissingDebugInfo;
10211027 return di;
10221028 },
1023 else => return err,
1029 else => |e| return e,
10241030 };
1031 errdefer pdb_file.close();
1032
1033 const pdb_file_reader_buffer = try gpa.alloc(u8, 4096);
1034 errdefer gpa.free(pdb_file_reader_buffer);
1035
1036 const pdb_file_reader = try gpa.create(File.Reader);
1037 errdefer gpa.destroy(pdb_file_reader);
1038
1039 pdb_file_reader.* = pdb_file.reader(pdb_file_reader_buffer);
1040
1041 di.pdb = try Pdb.init(gpa, pdb_file_reader);
10251042 try di.pdb.?.parseInfoStream();
10261043 try di.pdb.?.parseDbiStream();
10271044
......@@ -1029,8 +1046,8 @@ fn readCoffDebugInfo(allocator: Allocator, coff_obj: *coff.Coff) !Module {
10291046 return error.InvalidDebugInfo;
10301047
10311048 // Only used by the pdb path
1032 di.coff_section_headers = try coff_obj.getSectionHeadersAlloc(allocator);
1033 errdefer allocator.free(di.coff_section_headers);
1049 di.coff_section_headers = try coff_obj.getSectionHeadersAlloc(gpa);
1050 errdefer gpa.free(di.coff_section_headers);
10341051
10351052 return di;
10361053 }