| ... | @@ -225,14 +225,13 @@ pub fn parseInfoStream(self: *Pdb) !void { | ... | @@ -225,14 +225,13 @@ pub fn parseInfoStream(self: *Pdb) !void { |
| 225 | | 225 | |
| 226 | pub fn getProcSym(self: *Pdb, module: *Module, address: u64) ?*align(1) pdb.ProcSym { | 226 | pub fn getProcSym(self: *Pdb, module: *Module, address: u64) ?*align(1) pdb.ProcSym { |
| 227 | _ = self; | 227 | _ = self; |
| 228 | | | |
| 229 | std.debug.assert(module.populated); | 228 | std.debug.assert(module.populated); |
| 230 | | 229 | var reader: Io.Reader = .fixed(module.symbols); |
| 231 | var symbol_i: usize = 0; | 230 | while (true) { |
| 232 | while (symbol_i != module.symbols.len) { | 231 | const prefix = reader.takeStructPointer(pdb.RecordPrefix) catch return null; |
| 233 | const prefix: *align(1) pdb.RecordPrefix = @ptrCast(&module.symbols[symbol_i]); | | |
| 234 | if (prefix.record_len < 2) | 232 | if (prefix.record_len < 2) |
| 235 | return null; | 233 | return null; |
| | 234 | reader.discardAll(prefix.record_len - @sizeOf(u16)) catch return null; |
| 236 | switch (prefix.record_kind) { | 235 | switch (prefix.record_kind) { |
| 237 | .lproc32, .gproc32 => { | 236 | .lproc32, .gproc32 => { |
| 238 | const proc_sym: *align(1) pdb.ProcSym = @ptrCast(prefix); | 237 | const proc_sym: *align(1) pdb.ProcSym = @ptrCast(prefix); |
| ... | @@ -242,9 +241,7 @@ pub fn getProcSym(self: *Pdb, module: *Module, address: u64) ?*align(1) pdb.Proc | ... | @@ -242,9 +241,7 @@ pub fn getProcSym(self: *Pdb, module: *Module, address: u64) ?*align(1) pdb.Proc |
| 242 | }, | 241 | }, |
| 243 | else => {}, | 242 | else => {}, |
| 244 | } | 243 | } |
| 245 | symbol_i += prefix.record_len + @sizeOf(u16); | | |
| 246 | } | 244 | } |
| 247 | | | |
| 248 | return null; | 245 | return null; |
| 249 | } | 246 | } |
| 250 | | 247 | |
| ... | @@ -253,12 +250,17 @@ pub const InlineSiteSymIterator = struct { | ... | @@ -253,12 +250,17 @@ pub const InlineSiteSymIterator = struct { |
| 253 | offset: usize, | 250 | offset: usize, |
| 254 | end: usize, | 251 | end: usize, |
| 255 | | 252 | |
| | 253 | const empty: InlineSiteSymIterator = .{ |
| | 254 | .module_index = 0, |
| | 255 | .offset = 0, |
| | 256 | .end = 0, |
| | 257 | }; |
| | 258 | |
| 256 | pub fn next(iter: *InlineSiteSymIterator, module: *Module) ?*align(1) pdb.InlineSiteSym { | 259 | pub fn next(iter: *InlineSiteSymIterator, module: *Module) ?*align(1) pdb.InlineSiteSym { |
| 257 | while (iter.offset < iter.end) { | 260 | while (iter.offset < iter.end) { |
| 258 | const inline_prefix: *align(1) pdb.RecordPrefix = @ptrCast(&module.symbols[iter.offset]); | 261 | const inline_prefix: *align(1) pdb.RecordPrefix = @ptrCast(&module.symbols[iter.offset]); |
| 259 | if (inline_prefix.record_len < 2) | | |
| 260 | return null; | | |
| 261 | const end = iter.offset + inline_prefix.record_len + @sizeOf(u16); | 262 | const end = iter.offset + inline_prefix.record_len + @sizeOf(u16); |
| | 263 | if (end > iter.end) return null; |
| 262 | defer iter.offset = end; | 264 | defer iter.offset = end; |
| 263 | switch (inline_prefix.record_kind) { | 265 | switch (inline_prefix.record_kind) { |
| 264 | // Skip nested procedures | 266 | // Skip nested procedures |
| ... | @@ -556,7 +558,8 @@ pub fn findInlineeName(self: *const Pdb, inlinee: u32) ?[]const u8 { | ... | @@ -556,7 +558,8 @@ pub fn findInlineeName(self: *const Pdb, inlinee: u32) ?[]const u8 { |
| 556 | const header = reader.takeStructPointer(pdb.IpiStreamHeader) catch return null; | 558 | const header = reader.takeStructPointer(pdb.IpiStreamHeader) catch return null; |
| 557 | for (header.type_index_begin..header.type_index_end) |curr_type_index| { | 559 | for (header.type_index_begin..header.type_index_end) |curr_type_index| { |
| 558 | const prefix = reader.takeStructPointer(pdb.LfRecordPrefix) catch return null; | 560 | const prefix = reader.takeStructPointer(pdb.LfRecordPrefix) catch return null; |
| 559 | reader.discardAll(prefix.len - @sizeOf(@FieldType(pdb.LfRecordPrefix, "len"))) catch return null; | 561 | if (prefix.len < 2) return null; |
| | 562 | reader.discardAll(prefix.len - @sizeOf(u16)) catch return null; |
| 560 | | 563 | |
| 561 | if (curr_type_index == type_index) { | 564 | if (curr_type_index == type_index) { |
| 562 | switch (prefix.kind) { | 565 | switch (prefix.kind) { |
| ... | @@ -580,7 +583,9 @@ pub fn getInlinees(self: *Pdb, module: *Module, proc_sym: *align(1) const pdb.Pr | ... | @@ -580,7 +583,9 @@ pub fn getInlinees(self: *Pdb, module: *Module, proc_sym: *align(1) const pdb.Pr |
| 580 | const offset = @intFromPtr(proc_sym) - | 583 | const offset = @intFromPtr(proc_sym) - |
| 581 | @intFromPtr(module.symbols.ptr) + | 584 | @intFromPtr(module.symbols.ptr) + |
| 582 | proc_sym.record_len + | 585 | proc_sym.record_len + |
| 583 | @sizeOf(@FieldType(pdb.ProcSym, "record_len")); | 586 | @sizeOf(u16); |
| | 587 | const symbols_end = @intFromPtr(module.symbols.ptr) + module.symbols.len; |
| | 588 | if (offset > symbols_end or proc_sym.end > symbols_end) return .empty; |
| 584 | return .{ | 589 | return .{ |
| 585 | .module_index = module_index, | 590 | .module_index = module_index, |
| 586 | .offset = offset, | 591 | .offset = offset, |
| ... | @@ -588,17 +593,19 @@ pub fn getInlinees(self: *Pdb, module: *Module, proc_sym: *align(1) const pdb.Pr | ... | @@ -588,17 +593,19 @@ pub fn getInlinees(self: *Pdb, module: *Module, proc_sym: *align(1) const pdb.Pr |
| 588 | }; | 593 | }; |
| 589 | } | 594 | } |
| 590 | | 595 | |
| 591 | pub fn getBinaryAnnotations(self: *Pdb, site: *align(1) const pdb.InlineSiteSym) BinaryAnnotation.Iterator { | 596 | pub fn getBinaryAnnotations(self: *Pdb, module: *Module, site: *align(1) const pdb.InlineSiteSym) BinaryAnnotation.Iterator { |
| 592 | _ = self; | 597 | _ = self; |
| 593 | var start: usize = @intFromPtr(site) + @sizeOf(pdb.InlineSiteSym); | 598 | var start: usize = @intFromPtr(site) + @sizeOf(pdb.InlineSiteSym); |
| 594 | var end = start + site.record_len + @sizeOf(@FieldType(pdb.InlineSiteSym, "record_len")) - @sizeOf(pdb.InlineSiteSym); | 599 | var end = start + site.record_len + @sizeOf(u16) - @sizeOf(pdb.InlineSiteSym); |
| 595 | switch (site.record_kind) { | 600 | switch (site.record_kind) { |
| 596 | .inlinesite => {}, | 601 | .inlinesite => {}, |
| 597 | .inlinesite2 => start += @sizeOf(pdb.InlineSiteSym2) - @sizeOf(pdb.InlineSiteSym), | 602 | .inlinesite2 => start += @sizeOf(pdb.InlineSiteSym2) - @sizeOf(pdb.InlineSiteSym), |
| 598 | else => end = start, | 603 | else => end = start, |
| 599 | } | 604 | } |
| | 605 | if (start < @intFromPtr(module.symbols.ptr) or end > @intFromPtr(module.symbols.ptr) + module.symbols.len) return .empty; |
| | 606 | const len = end - start; |
| 600 | const ptr: [*]const u8 = @ptrFromInt(start); | 607 | const ptr: [*]const u8 = @ptrFromInt(start); |
| 601 | const slice = ptr[0..end - start]; | 608 | const slice = ptr[0..len]; |
| 602 | return .{ .reader = Io.Reader.fixed(slice) }; | 609 | return .{ .reader = Io.Reader.fixed(slice) }; |
| 603 | } | 610 | } |
| 604 | | 611 | |
| ... | @@ -609,7 +616,7 @@ pub fn getInlineSiteSourceLocation( | ... | @@ -609,7 +616,7 @@ pub fn getInlineSiteSourceLocation( |
| 609 | inlinee_src_line: *align(1) const pdb.InlineeSourceLine, | 616 | inlinee_src_line: *align(1) const pdb.InlineeSourceLine, |
| 610 | offset_in_func: usize, | 617 | offset_in_func: usize, |
| 611 | ) !?std.debug.SourceLocation { | 618 | ) !?std.debug.SourceLocation { |
| 612 | var ranges: BinaryAnnotation.RangeIterator = .init(self.getBinaryAnnotations(site)); | 619 | var ranges: BinaryAnnotation.RangeIterator = .init(self.getBinaryAnnotations(mod, site)); |
| 613 | while (try ranges.next()) |range| { | 620 | while (try ranges.next()) |range| { |
| 614 | if (!range.contains(offset_in_func)) continue; | 621 | if (!range.contains(offset_in_func)) continue; |
| 615 | | 622 | |
| ... | @@ -658,36 +665,26 @@ pub fn getInlineeSourceLine( | ... | @@ -658,36 +665,26 @@ pub fn getInlineeSourceLine( |
| 658 | inlinee: u32, | 665 | inlinee: u32, |
| 659 | ) ?InlineeSourceLine { | 666 | ) ?InlineeSourceLine { |
| 660 | _ = self; | 667 | _ = self; |
| 661 | var sect_offset: usize = 0; | 668 | var subsects: Io.Reader = .fixed(mod.subsect_info); |
| 662 | var skip_len: usize = undefined; | 669 | while (subsects.takeStructPointer(pdb.DebugSubsectionHeader) catch null) |subsect_hdr| { |
| 663 | while (sect_offset < mod.subsect_info.len) : (sect_offset += skip_len) { | 670 | var subsect: Io.Reader = .fixed(subsects.take(subsect_hdr.length) catch return null); |
| 664 | const subsect_hdr: *align(1) pdb.DebugSubsectionHeader = @ptrCast(&mod.subsect_info[sect_offset]); | | |
| 665 | skip_len = subsect_hdr.length; | | |
| 666 | sect_offset += @sizeOf(pdb.DebugSubsectionHeader); | | |
| 667 | | | |
| 668 | if (subsect_hdr.kind == .inlinee_lines) { | 671 | if (subsect_hdr.kind == .inlinee_lines) { |
| 669 | var offset = sect_offset; | 672 | const signature = subsect.takeEnum(pdb.InlineeSourceLineSignature, .little) catch return null; |
| 670 | const signature: *const align(1) pdb.InlineeSourceLineSignature = @ptrCast(&mod.subsect_info[offset]); | 673 | const has_extra_files = switch (signature) { |
| 671 | offset += @sizeOf(pdb.InlineeSourceLineSignature); | | |
| 672 | | | |
| 673 | const has_extra_files = switch (signature.*) { | | |
| 674 | .normal => false, | 674 | .normal => false, |
| 675 | .ex => true, | 675 | .ex => true, |
| 676 | else => continue, | 676 | else => continue, |
| 677 | }; | 677 | }; |
| 678 | | 678 | |
| 679 | while (offset < sect_offset + subsect_hdr.length) { | 679 | while (subsect.takeStructPointer(pdb.InlineeSourceLine) catch null) |inlinee_src_line| { |
| 680 | const inlinee_src_line: *const align(1) pdb.InlineeSourceLine = @ptrCast(&mod.subsect_info[offset]); | | |
| 681 | offset += @sizeOf(pdb.InlineeSourceLine); | | |
| 682 | | | |
| 683 | if (has_extra_files) { | 680 | if (has_extra_files) { |
| 684 | const file_count: *const align(1) u32 = @ptrCast(&mod.subsect_info[offset]); | 681 | const file_count = subsect.takeInt(u32, .little) catch return null; |
| 685 | offset += @sizeOf(u32); | 682 | const file_bytes = std.math.mul(usize, file_count, @sizeOf(u32)) catch return null; |
| 686 | offset += file_count.* * @sizeOf(u32); | 683 | subsect.discardAll(file_bytes) catch return null; |
| 687 | } | 684 | } |
| 688 | | 685 | |
| 689 | if (inlinee_src_line.inlinee == inlinee) return .{ | 686 | if (inlinee_src_line.inlinee == inlinee) return .{ |
| 690 | .signature = signature.*, | 687 | .signature = signature, |
| 691 | .info = inlinee_src_line, | 688 | .info = inlinee_src_line, |
| 692 | }; | 689 | }; |
| 693 | } | 690 | } |