diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2023-08-16 12:31:22 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-16 12:31:22 +0200 |
| commit | 3e228bdf457d8be0fcbb8e44a8fa7a0b09677972 (patch) | |
| tree | 197f5daa9b9cafadc5b4a047a29f23fea8e1fc6a /lib/std/coff.zig | |
| parent | 340a45683ca8e0b23e95f5fb86bd9c827970e6e8 (diff) | |
| parent | 8a5f331ec832201c6e4bdf211cdd37ca5eb4347b (diff) | |
| download | zig-3e228bdf457d8be0fcbb8e44a8fa7a0b09677972.tar.gz zig-3e228bdf457d8be0fcbb8e44a8fa7a0b09677972.zip | |
Merge pull request #16832 from kcbanner/coff_dwarf_and_pdb
Windows: Support loading debug symbols from both the PDB file and embedded DWARF information
Diffstat (limited to 'lib/std/coff.zig')
| -rw-r--r-- | lib/std/coff.zig | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/lib/std/coff.zig b/lib/std/coff.zig index c937baa18d..9db9f4d988 100644 --- a/lib/std/coff.zig +++ b/lib/std/coff.zig @@ -1059,6 +1059,8 @@ pub const CoffError = error{ // Official documentation of the format: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format pub const Coff = struct { data: []const u8, + // Set if `data` is backed by the image as loaded by the loader + is_loaded: bool, is_image: bool, coff_header_offset: usize, @@ -1066,7 +1068,7 @@ pub const Coff = struct { age: u32 = undefined, // The lifetime of `data` must be longer than the lifetime of the returned Coff - pub fn init(data: []const u8) !Coff { + pub fn init(data: []const u8, is_loaded: bool) !Coff { const pe_pointer_offset = 0x3C; const pe_magic = "PE\x00\x00"; @@ -1082,6 +1084,7 @@ pub const Coff = struct { var coff = @This(){ .data = data, .is_image = is_image, + .is_loaded = is_loaded, .coff_header_offset = coff_header_offset, }; @@ -1098,27 +1101,40 @@ pub const Coff = struct { return coff; } - pub fn getPdbPath(self: *Coff, buffer: []u8) !usize { + pub fn getPdbPath(self: *Coff, buffer: []u8) !?usize { assert(self.is_image); const data_dirs = self.getDataDirectories(); - const debug_dir = data_dirs[@intFromEnum(DirectoryEntry.DEBUG)]; + if (@intFromEnum(DirectoryEntry.DEBUG) >= data_dirs.len) return null; + const debug_dir = data_dirs[@intFromEnum(DirectoryEntry.DEBUG)]; var stream = std.io.fixedBufferStream(self.data); const reader = stream.reader(); - try stream.seekTo(debug_dir.virtual_address); + + if (self.is_loaded) { + try stream.seekTo(debug_dir.virtual_address); + } else { + // Find what section the debug_dir is in, in order to convert the RVA to a file offset + for (self.getSectionHeaders()) |*sect| { + if (debug_dir.virtual_address >= sect.virtual_address and debug_dir.virtual_address < sect.virtual_address + sect.virtual_size) { + try stream.seekTo(sect.pointer_to_raw_data + (debug_dir.virtual_address - sect.virtual_address)); + break; + } + } else return error.InvalidDebugDirectory; + } // Find the correct DebugDirectoryEntry, and where its data is stored. // It can be in any section. const debug_dir_entry_count = debug_dir.size / @sizeOf(DebugDirectoryEntry); var i: u32 = 0; - blk: while (i < debug_dir_entry_count) : (i += 1) { + while (i < debug_dir_entry_count) : (i += 1) { const debug_dir_entry = try reader.readStruct(DebugDirectoryEntry); if (debug_dir_entry.type == .CODEVIEW) { - try stream.seekTo(debug_dir_entry.address_of_raw_data); - break :blk; + const dir_offset = if (self.is_loaded) debug_dir_entry.address_of_raw_data else debug_dir_entry.pointer_to_raw_data; + try stream.seekTo(dir_offset); + break; } - } + } else return null; var cv_signature: [4]u8 = undefined; // CodeView signature try reader.readNoEof(cv_signature[0..]); @@ -1256,7 +1272,8 @@ pub const Coff = struct { } pub fn getSectionData(self: *const Coff, sec: *align(1) const SectionHeader) []const u8 { - return self.data[sec.pointer_to_raw_data..][0..sec.virtual_size]; + const offset = if (self.is_loaded) sec.virtual_address else sec.pointer_to_raw_data; + return self.data[offset..][0..sec.virtual_size]; } pub fn getSectionDataAlloc(self: *const Coff, sec: *align(1) const SectionHeader, allocator: mem.Allocator) ![]u8 { |
