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 stream = std.io.fixedBufferStream(self.data); const reader = stream.reader(); 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; while (i < debug_dir_entry_count) : (i += 1) { const debug_dir_entry = try reader.readStruct(DebugDirectoryEntry); 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; try stream.seekTo(dir_offset); break; } } else return null; var cv_signature: [4]u8 = undefined; // CodeView signature try reader.readNoEof(cv_signature[0..]); // 'RSDS' indicates PDB70 format, used by lld. if (!mem.eql(u8, &cv_signature, "RSDS")) return error.InvalidPEMagic; try reader.readNoEof(self.guid[0..]); self.age = try reader.readInt(u32, .little); // Finally read the null-terminated string. const start = reader.context.pos; const len = std.mem.indexOfScalar(u8, self.data[start..], 0) orelse return null; return self.data[start .. start + len]; }