Function getPdbPath [src]

Prototype

pub fn getPdbPath(self: *Coff) !?[]const u8

Parameters

self: *Coff

Source

pub fn getPdbPath(self: *Coff) !?[]const u8 { assert(self.is_image); const data_dirs = self.getDataDirectories(); if (@intFromEnum(DirectoryEntry.DEBUG) >= data_dirs.len) return null; const debug_dir = data_dirs[@intFromEnum(DirectoryEntry.DEBUG)]; var reader: std.Io.Reader = .fixed(self.data); if (self.is_loaded) { reader.seek = 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) { reader.seek = 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; while (i < debug_dir_entry_count) : (i += 1) { const debug_dir_entry = try reader.takeStruct(DebugDirectoryEntry, .little); if (debug_dir_entry.type == .CODEVIEW) { const dir_offset = if (self.is_loaded) debug_dir_entry.address_of_raw_data else debug_dir_entry.pointer_to_raw_data; reader.seek = dir_offset; break; } } else return null; const code_view_signature = try reader.takeArray(4); // 'RSDS' indicates PDB70 format, used by lld. if (!mem.eql(u8, code_view_signature, "RSDS")) return error.InvalidPEMagic; try reader.readSliceAll(self.guid[0..]); self.age = try reader.takeInt(u32, .little); // Finally read the null-terminated string. const start = reader.seek; const len = std.mem.indexOfScalar(u8, self.data[start..], 0) orelse return null; return self.data[start .. start + len]; }