| ... | @@ -65,9 +65,15 @@ pub fn deinit(self: *Pdb) void { | ... | @@ -65,9 +65,15 @@ pub fn deinit(self: *Pdb) void { |
| 65 | pub fn parseDbiStream(self: *Pdb) !void { | 65 | pub fn parseDbiStream(self: *Pdb) !void { |
| 66 | var stream = self.getStream(pdb.StreamType.dbi) orelse | 66 | var stream = self.getStream(pdb.StreamType.dbi) orelse |
| 67 | return error.InvalidDebugInfo; | 67 | return error.InvalidDebugInfo; |
| 68 | const reader = stream.reader(); | | |
| 69 | | 68 | |
| 70 | const header = try reader.readStruct(std.pdb.DbiStreamHeader); | 69 | const gpa = self.allocator; |
| | 70 | |
| | 71 | const deprecated_reader = stream.reader(); |
| | 72 | var adapted_buffer: [1024]u8 = undefined; |
| | 73 | var adapted_reader = deprecated_reader.adaptToNewApi(&adapted_buffer); |
| | 74 | const reader = &adapted_reader.new_interface; |
| | 75 | |
| | 76 | const header = try reader.takeStruct(std.pdb.DbiStreamHeader, .little); |
| 71 | if (header.version_header != 19990903) // V70, only value observed by LLVM team | 77 | if (header.version_header != 19990903) // V70, only value observed by LLVM team |
| 72 | return error.UnknownPDBVersion; | 78 | return error.UnknownPDBVersion; |
| 73 | // if (header.Age != age) | 79 | // if (header.Age != age) |
| ... | @@ -76,22 +82,24 @@ pub fn parseDbiStream(self: *Pdb) !void { | ... | @@ -76,22 +82,24 @@ pub fn parseDbiStream(self: *Pdb) !void { |
| 76 | const mod_info_size = header.mod_info_size; | 82 | const mod_info_size = header.mod_info_size; |
| 77 | const section_contrib_size = header.section_contribution_size; | 83 | const section_contrib_size = header.section_contribution_size; |
| 78 | | 84 | |
| 79 | var modules = std.array_list.Managed(Module).init(self.allocator); | 85 | var modules = std.array_list.Managed(Module).init(gpa); |
| 80 | errdefer modules.deinit(); | 86 | errdefer modules.deinit(); |
| 81 | | 87 | |
| 82 | // Module Info Substream | 88 | // Module Info Substream |
| 83 | var mod_info_offset: usize = 0; | 89 | var mod_info_offset: usize = 0; |
| 84 | while (mod_info_offset != mod_info_size) { | 90 | while (mod_info_offset != mod_info_size) { |
| 85 | const mod_info = try reader.readStruct(pdb.ModInfo); | 91 | const mod_info = try reader.takeStruct(pdb.ModInfo, .little); |
| 86 | var this_record_len: usize = @sizeOf(pdb.ModInfo); | 92 | var this_record_len: usize = @sizeOf(pdb.ModInfo); |
| 87 | | 93 | |
| 88 | const module_name = try reader.readUntilDelimiterAlloc(self.allocator, 0, 1024); | 94 | var module_name: std.Io.Writer.Allocating = .init(gpa); |
| 89 | errdefer self.allocator.free(module_name); | 95 | defer module_name.deinit(); |
| 90 | this_record_len += module_name.len + 1; | 96 | this_record_len += try reader.streamDelimiterLimit(&module_name.writer, 0, .limited(1024)); |
| | 97 | this_record_len += 1; |
| 91 | | 98 | |
| 92 | const obj_file_name = try reader.readUntilDelimiterAlloc(self.allocator, 0, 1024); | 99 | var obj_file_name: std.Io.Writer.Allocating = .init(gpa); |
| 93 | errdefer self.allocator.free(obj_file_name); | 100 | defer obj_file_name.deinit(); |
| 94 | this_record_len += obj_file_name.len + 1; | 101 | this_record_len += try reader.streamDelimiterLimit(&obj_file_name.writer, 0, .limited(1024)); |
| | 102 | this_record_len += 1; |
| 95 | | 103 | |
| 96 | if (this_record_len % 4 != 0) { | 104 | if (this_record_len % 4 != 0) { |
| 97 | const round_to_next_4 = (this_record_len | 0x3) + 1; | 105 | const round_to_next_4 = (this_record_len | 0x3) + 1; |
| ... | @@ -102,8 +110,8 @@ pub fn parseDbiStream(self: *Pdb) !void { | ... | @@ -102,8 +110,8 @@ pub fn parseDbiStream(self: *Pdb) !void { |
| 102 | | 110 | |
| 103 | try modules.append(Module{ | 111 | try modules.append(Module{ |
| 104 | .mod_info = mod_info, | 112 | .mod_info = mod_info, |
| 105 | .module_name = module_name, | 113 | .module_name = try module_name.toOwnedSlice(), |
| 106 | .obj_file_name = obj_file_name, | 114 | .obj_file_name = try obj_file_name.toOwnedSlice(), |
| 107 | | 115 | |
| 108 | .populated = false, | 116 | .populated = false, |
| 109 | .symbols = undefined, | 117 | .symbols = undefined, |
| ... | @@ -117,21 +125,21 @@ pub fn parseDbiStream(self: *Pdb) !void { | ... | @@ -117,21 +125,21 @@ pub fn parseDbiStream(self: *Pdb) !void { |
| 117 | } | 125 | } |
| 118 | | 126 | |
| 119 | // Section Contribution Substream | 127 | // Section Contribution Substream |
| 120 | var sect_contribs = std.array_list.Managed(pdb.SectionContribEntry).init(self.allocator); | 128 | var sect_contribs = std.array_list.Managed(pdb.SectionContribEntry).init(gpa); |
| 121 | errdefer sect_contribs.deinit(); | 129 | errdefer sect_contribs.deinit(); |
| 122 | | 130 | |
| 123 | var sect_cont_offset: usize = 0; | 131 | var sect_cont_offset: usize = 0; |
| 124 | if (section_contrib_size != 0) { | 132 | if (section_contrib_size != 0) { |
| 125 | const version = reader.readEnum(std.pdb.SectionContrSubstreamVersion, .little) catch |err| switch (err) { | 133 | const version = reader.takeEnum(std.pdb.SectionContrSubstreamVersion, .little) catch |err| switch (err) { |
| 126 | error.InvalidValue => return error.InvalidDebugInfo, | 134 | error.InvalidEnumTag, error.EndOfStream => return error.InvalidDebugInfo, |
| 127 | else => |e| return e, | 135 | error.ReadFailed => return error.ReadFailed, |
| 128 | }; | 136 | }; |
| 129 | _ = version; | 137 | _ = version; |
| 130 | sect_cont_offset += @sizeOf(u32); | 138 | sect_cont_offset += @sizeOf(u32); |
| 131 | } | 139 | } |
| 132 | while (sect_cont_offset != section_contrib_size) { | 140 | while (sect_cont_offset != section_contrib_size) { |
| 133 | const entry = try sect_contribs.addOne(); | 141 | const entry = try sect_contribs.addOne(); |
| 134 | entry.* = try reader.readStruct(pdb.SectionContribEntry); | 142 | entry.* = try reader.takeStruct(pdb.SectionContribEntry, .little); |
| 135 | sect_cont_offset += @sizeOf(pdb.SectionContribEntry); | 143 | sect_cont_offset += @sizeOf(pdb.SectionContribEntry); |
| 136 | | 144 | |
| 137 | if (sect_cont_offset > section_contrib_size) | 145 | if (sect_cont_offset > section_contrib_size) |
| ... | @@ -233,6 +241,7 @@ pub fn getSymbolName(self: *Pdb, module: *Module, address: u64) ?[]const u8 { | ... | @@ -233,6 +241,7 @@ pub fn getSymbolName(self: *Pdb, module: *Module, address: u64) ?[]const u8 { |
| 233 | pub fn getLineNumberInfo(self: *Pdb, module: *Module, address: u64) !std.debug.SourceLocation { | 241 | pub fn getLineNumberInfo(self: *Pdb, module: *Module, address: u64) !std.debug.SourceLocation { |
| 234 | std.debug.assert(module.populated); | 242 | std.debug.assert(module.populated); |
| 235 | const subsect_info = module.subsect_info; | 243 | const subsect_info = module.subsect_info; |
| | 244 | const gpa = self.allocator; |
| 236 | | 245 | |
| 237 | var sect_offset: usize = 0; | 246 | var sect_offset: usize = 0; |
| 238 | var skip_len: usize = undefined; | 247 | var skip_len: usize = undefined; |
| ... | @@ -287,7 +296,16 @@ pub fn getLineNumberInfo(self: *Pdb, module: *Module, address: u64) !std.debug.S | ... | @@ -287,7 +296,16 @@ pub fn getLineNumberInfo(self: *Pdb, module: *Module, address: u64) !std.debug.S |
| 287 | const chksum_hdr: *align(1) pdb.FileChecksumEntryHeader = @ptrCast(&module.subsect_info[subsect_index]); | 296 | const chksum_hdr: *align(1) pdb.FileChecksumEntryHeader = @ptrCast(&module.subsect_info[subsect_index]); |
| 288 | const strtab_offset = @sizeOf(pdb.StringTableHeader) + chksum_hdr.file_name_offset; | 297 | const strtab_offset = @sizeOf(pdb.StringTableHeader) + chksum_hdr.file_name_offset; |
| 289 | try self.string_table.?.seekTo(strtab_offset); | 298 | try self.string_table.?.seekTo(strtab_offset); |
| 290 | const source_file_name = try self.string_table.?.reader().readUntilDelimiterAlloc(self.allocator, 0, 1024); | 299 | const source_file_name = s: { |
| | 300 | const deprecated_reader = self.string_table.?.reader(); |
| | 301 | var adapted_buffer: [1024]u8 = undefined; |
| | 302 | var adapted_reader = deprecated_reader.adaptToNewApi(&adapted_buffer); |
| | 303 | var source_file_name: std.Io.Writer.Allocating = .init(gpa); |
| | 304 | defer source_file_name.deinit(); |
| | 305 | _ = try adapted_reader.new_interface.streamDelimiterLimit(&source_file_name.writer, 0, .limited(1024)); |
| | 306 | break :s try source_file_name.toOwnedSlice(); |
| | 307 | }; |
| | 308 | errdefer gpa.free(source_file_name); |
| 291 | | 309 | |
| 292 | const line_entry_idx = line_i - 1; | 310 | const line_entry_idx = line_i - 1; |
| 293 | | 311 | |