struct Symtab [src]

Fields

buffer: []const u8

Members

Source

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