DoxigAlpha

getPdbPath

Function parameters

Parameters

#
self:*Coff

Type definitions in this namespace

Types

#
ImportHintNameEntry
Every name ends with a NULL byte.

Error sets in this namespace

Error Sets

#

= 0x10b

Values

#

Source

Implementation

#
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];
}