structstd.coff.Symtab[src]

Fields

buffer: []const u8

Functions

Functionlen[src]

pub fn len(self: Symtab) usize

Parameters

self: Symtab

Source Code

Source code
pub fn len(self: Symtab) usize {
    return @divExact(self.buffer.len, Symbol.sizeOf());
}

Functionat[src]

pub fn at(self: Symtab, index: usize, tag: Tag) Record

Lives as long as Symtab instance.

Parameters

self: Symtab
index: usize
tag: Tag

Source Code

Source code
pub fn at(self: Symtab, index: usize, tag: Tag) Record {
    const offset = index * Symbol.sizeOf();
    const raw = self.buffer[offset..][0..Symbol.sizeOf()];
    return switch (tag) {
        .symbol => .{ .symbol = asSymbol(raw) },
        .debug_info => .{ .debug_info = asDebugInfo(raw) },
        .func_def => .{ .func_def = asFuncDef(raw) },
        .weak_ext => .{ .weak_ext = asWeakExtDef(raw) },
        .file_def => .{ .file_def = asFileDef(raw) },
        .sect_def => .{ .sect_def = asSectDef(raw) },
    };
}

Functionslice[src]

pub fn slice(self: Symtab, start: usize, end: ?usize) Slice

Parameters

self: Symtab
start: usize
end: ?usize

Source Code

Source code
pub fn slice(self: Symtab, start: usize, end: ?usize) Slice {
    const offset = start * Symbol.sizeOf();
    const llen = if (end) |e| e * Symbol.sizeOf() else self.buffer.len;
    const num = @divExact(llen - offset, Symbol.sizeOf());
    return Slice{ .buffer = self.buffer[offset..][0..llen], .num = num };
}

Source Code

Source code
pub const Symtab = struct {
    buffer: []const u8,

    pub fn len(self: Symtab) usize {
        return @divExact(self.buffer.len, Symbol.sizeOf());
    }

    pub const Tag = enum {
        symbol,
        debug_info,
        func_def,
        weak_ext,
        file_def,
        sect_def,
    };

    pub const Record = union(Tag) {
        symbol: Symbol,
        debug_info: DebugInfoDefinition,
        func_def: FunctionDefinition,
        weak_ext: WeakExternalDefinition,
        file_def: FileDefinition,
        sect_def: SectionDefinition,
    };

    /// Lives as long as Symtab instance.
    pub fn at(self: Symtab, index: usize, tag: Tag) Record {
        const offset = index * Symbol.sizeOf();
        const raw = self.buffer[offset..][0..Symbol.sizeOf()];
        return switch (tag) {
            .symbol => .{ .symbol = asSymbol(raw) },
            .debug_info => .{ .debug_info = asDebugInfo(raw) },
            .func_def => .{ .func_def = asFuncDef(raw) },
            .weak_ext => .{ .weak_ext = asWeakExtDef(raw) },
            .file_def => .{ .file_def = asFileDef(raw) },
            .sect_def => .{ .sect_def = asSectDef(raw) },
        };
    }

    fn asSymbol(raw: []const u8) Symbol {
        return .{
            .name = raw[0..8].*,
            .value = mem.readInt(u32, raw[8..12], .little),
            .section_number = @as(SectionNumber, @enumFromInt(mem.readInt(u16, raw[12..14], .little))),
            .type = @as(SymType, @bitCast(mem.readInt(u16, raw[14..16], .little))),
            .storage_class = @as(StorageClass, @enumFromInt(raw[16])),
            .number_of_aux_symbols = raw[17],
        };
    }

    fn asDebugInfo(raw: []const u8) DebugInfoDefinition {
        return .{
            .unused_1 = raw[0..4].*,
            .linenumber = mem.readInt(u16, raw[4..6], .little),
            .unused_2 = raw[6..12].*,
            .pointer_to_next_function = mem.readInt(u32, raw[12..16], .little),
            .unused_3 = raw[16..18].*,
        };
    }

    fn asFuncDef(raw: []const u8) FunctionDefinition {
        return .{
            .tag_index = mem.readInt(u32, raw[0..4], .little),
            .total_size = mem.readInt(u32, raw[4..8], .little),
            .pointer_to_linenumber = mem.readInt(u32, raw[8..12], .little),
            .pointer_to_next_function = mem.readInt(u32, raw[12..16], .little),
            .unused = raw[16..18].*,
        };
    }

    fn asWeakExtDef(raw: []const u8) WeakExternalDefinition {
        return .{
            .tag_index = mem.readInt(u32, raw[0..4], .little),
            .flag = @as(WeakExternalFlag, @enumFromInt(mem.readInt(u32, raw[4..8], .little))),
            .unused = raw[8..18].*,
        };
    }

    fn asFileDef(raw: []const u8) FileDefinition {
        return .{
            .file_name = raw[0..18].*,
        };
    }

    fn asSectDef(raw: []const u8) SectionDefinition {
        return .{
            .length = mem.readInt(u32, raw[0..4], .little),
            .number_of_relocations = mem.readInt(u16, raw[4..6], .little),
            .number_of_linenumbers = mem.readInt(u16, raw[6..8], .little),
            .checksum = mem.readInt(u32, raw[8..12], .little),
            .number = mem.readInt(u16, raw[12..14], .little),
            .selection = @as(ComdatSelection, @enumFromInt(raw[14])),
            .unused = raw[15..18].*,
        };
    }

    pub const Slice = struct {
        buffer: []const u8,
        num: usize,
        count: usize = 0,

        /// Lives as long as Symtab instance.
        pub fn next(self: *Slice) ?Symbol {
            if (self.count >= self.num) return null;
            const sym = asSymbol(self.buffer[0..Symbol.sizeOf()]);
            self.count += 1;
            self.buffer = self.buffer[Symbol.sizeOf()..];
            return sym;
        }
    };

    pub fn slice(self: Symtab, start: usize, end: ?usize) Slice {
        const offset = start * Symbol.sizeOf();
        const llen = if (end) |e| e * Symbol.sizeOf() else self.buffer.len;
        const num = @divExact(llen - offset, Symbol.sizeOf());
        return Slice{ .buffer = self.buffer[offset..][0..llen], .num = num };
    }
}