coff: move Symtab and Strtab out of coff.Coff

This should ease interfacing with different std.coff functionalities.
This commit is contained in:
Jakub Konka 2022-08-30 15:51:46 +02:00
parent 7ef0c9d298
commit aa5568beb6

View file

@ -1100,132 +1100,132 @@ pub const Coff = struct {
mem.copy(u8, out_buff, self.data[sec.pointer_to_raw_data..][0..sec.virtual_size]);
return out_buff;
}
};
pub const Symtab = struct {
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,
func_def,
debug_info,
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.readIntLittle(u32, raw[8..12]),
.section_number = @intToEnum(SectionNumber, mem.readIntLittle(u16, raw[12..14])),
.@"type" = @bitCast(SymType, mem.readIntLittle(u16, raw[14..16])),
.storage_class = @intToEnum(StorageClass, raw[16]),
.number_of_aux_symbols = raw[17],
};
}
fn asDebugInfo(raw: []const u8) DebugInfoDefinition {
return .{
.unused_1 = raw[0..4].*,
.linenumber = mem.readIntLittle(u16, raw[4..6]),
.unused_2 = raw[6..12].*,
.pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]),
.unused_3 = raw[16..18].*,
};
}
fn asFuncDef(raw: []const u8) FunctionDefinition {
return .{
.tag_index = mem.readIntLittle(u32, raw[0..4]),
.total_size = mem.readIntLittle(u32, raw[4..8]),
.pointer_to_linenumber = mem.readIntLittle(u32, raw[8..12]),
.pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]),
.unused = raw[16..18].*,
};
}
fn asWeakExtDef(raw: []const u8) WeakExternalDefinition {
return .{
.tag_index = mem.readIntLittle(u32, raw[0..4]),
.flag = @intToEnum(WeakExternalFlag, mem.readIntLittle(u32, raw[4..8])),
.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.readIntLittle(u32, raw[0..4]),
.number_of_relocations = mem.readIntLittle(u16, raw[4..6]),
.number_of_linenumbers = mem.readIntLittle(u16, raw[6..8]),
.checksum = mem.readIntLittle(u32, raw[8..12]),
.number = mem.readIntLittle(u16, raw[12..14]),
.selection = @intToEnum(ComdatSelection, raw[14]),
.unused = raw[15..18].*,
};
}
pub const Slice = struct {
buffer: []const u8,
fn len(self: Symtab) usize {
return @divExact(self.buffer.len, Symbol.sizeOf());
}
const Tag = enum {
symbol,
func_def,
debug_info,
weak_ext,
file_def,
sect_def,
};
const Record = union(Tag) {
symbol: Symbol,
debug_info: DebugInfoDefinition,
func_def: FunctionDefinition,
weak_ext: WeakExternalDefinition,
file_def: FileDefinition,
sect_def: SectionDefinition,
};
num: usize,
count: usize = 0,
/// Lives as long as Symtab instance.
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.readIntLittle(u32, raw[8..12]),
.section_number = @intToEnum(SectionNumber, mem.readIntLittle(u16, raw[12..14])),
.@"type" = @bitCast(SymType, mem.readIntLittle(u16, raw[14..16])),
.storage_class = @intToEnum(StorageClass, raw[16]),
.number_of_aux_symbols = raw[17],
};
}
fn asDebugInfo(raw: []const u8) DebugInfoDefinition {
return .{
.unused_1 = raw[0..4].*,
.linenumber = mem.readIntLittle(u16, raw[4..6]),
.unused_2 = raw[6..12].*,
.pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]),
.unused_3 = raw[16..18].*,
};
}
fn asFuncDef(raw: []const u8) FunctionDefinition {
return .{
.tag_index = mem.readIntLittle(u32, raw[0..4]),
.total_size = mem.readIntLittle(u32, raw[4..8]),
.pointer_to_linenumber = mem.readIntLittle(u32, raw[8..12]),
.pointer_to_next_function = mem.readIntLittle(u32, raw[12..16]),
.unused = raw[16..18].*,
};
}
fn asWeakExtDef(raw: []const u8) WeakExternalDefinition {
return .{
.tag_index = mem.readIntLittle(u32, raw[0..4]),
.flag = @intToEnum(WeakExternalFlag, mem.readIntLittle(u32, raw[4..8])),
.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.readIntLittle(u32, raw[0..4]),
.number_of_relocations = mem.readIntLittle(u16, raw[4..6]),
.number_of_linenumbers = mem.readIntLittle(u16, raw[6..8]),
.checksum = mem.readIntLittle(u32, raw[8..12]),
.number = mem.readIntLittle(u16, raw[12..14]),
.selection = @intToEnum(ComdatSelection, raw[14]),
.unused = raw[15..18].*,
};
}
const Slice = struct {
buffer: []const u8,
num: usize,
count: usize = 0,
/// Lives as long as Symtab instance.
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;
}
};
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 };
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 const Strtab = struct {
buffer: []const u8,
fn get(self: Strtab, off: u32) []const u8 {
assert(off < self.buffer.len);
return mem.sliceTo(@ptrCast([*:0]const u8, self.buffer.ptr + off), 0);
}
};
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 };
}
};
pub const Strtab = struct {
buffer: []const u8,
pub fn get(self: Strtab, off: u32) []const u8 {
assert(off < self.buffer.len);
return mem.sliceTo(@ptrCast([*:0]const u8, self.buffer.ptr + off), 0);
}
};