union Instruction [src]
Fields
advance_loc: struct {
delta: u8,
}
offset: struct {
register: u8,
offset: u64,
}
restore: struct {
register: u8,
}
nop: void
set_loc: struct {
address: u64,
}
advance_loc1: struct {
delta: u8,
}
advance_loc2: struct {
delta: u16,
}
advance_loc4: struct {
delta: u32,
}
offset_extended: struct {
register: u8,
offset: u64,
}
restore_extended: struct {
register: u8,
}
undefined: struct {
register: u8,
}
same_value: struct {
register: u8,
}
register: struct {
register: u8,
target_register: u8,
}
remember_state: void
restore_state: void
def_cfa: struct {
register: u8,
offset: u64,
}
def_cfa_register: struct {
register: u8,
}
def_cfa_offset: struct {
offset: u64,
}
def_cfa_expression: struct {
block: []const u8,
}
expression: struct {
register: u8,
block: []const u8,
}
offset_extended_sf: struct {
register: u8,
offset: i64,
}
def_cfa_sf: struct {
register: u8,
offset: i64,
}
def_cfa_offset_sf: struct {
offset: i64,
}
val_offset: struct {
register: u8,
offset: u64,
}
val_offset_sf: struct {
register: u8,
offset: i64,
}
val_expression: struct {
register: u8,
block: []const u8,
}
Members
- read (Function)
Source
pub const Instruction = union(Opcode) {
advance_loc: struct {
delta: u8,
},
offset: struct {
register: u8,
offset: u64,
},
restore: struct {
register: u8,
},
nop: void,
set_loc: struct {
address: u64,
},
advance_loc1: struct {
delta: u8,
},
advance_loc2: struct {
delta: u16,
},
advance_loc4: struct {
delta: u32,
},
offset_extended: struct {
register: u8,
offset: u64,
},
restore_extended: struct {
register: u8,
},
undefined: struct {
register: u8,
},
same_value: struct {
register: u8,
},
register: struct {
register: u8,
target_register: u8,
},
remember_state: void,
restore_state: void,
def_cfa: struct {
register: u8,
offset: u64,
},
def_cfa_register: struct {
register: u8,
},
def_cfa_offset: struct {
offset: u64,
},
def_cfa_expression: struct {
block: []const u8,
},
expression: struct {
register: u8,
block: []const u8,
},
offset_extended_sf: struct {
register: u8,
offset: i64,
},
def_cfa_sf: struct {
register: u8,
offset: i64,
},
def_cfa_offset_sf: struct {
offset: i64,
},
val_offset: struct {
register: u8,
offset: u64,
},
val_offset_sf: struct {
register: u8,
offset: i64,
},
val_expression: struct {
register: u8,
block: []const u8,
},
pub fn read(
stream: *std.io.FixedBufferStream([]const u8),
addr_size_bytes: u8,
endian: std.builtin.Endian,
) !Instruction {
const reader = stream.reader();
switch (try reader.readByte()) {
Opcode.lo_inline...Opcode.hi_inline => |opcode| {
const e: Opcode = @enumFromInt(opcode & 0b11000000);
const value: u6 = @intCast(opcode & 0b111111);
return switch (e) {
.advance_loc => .{
.advance_loc = .{ .delta = value },
},
.offset => .{
.offset = .{
.register = value,
.offset = try leb.readUleb128(u64, reader),
},
},
.restore => .{
.restore = .{ .register = value },
},
else => unreachable,
};
},
Opcode.lo_reserved...Opcode.hi_reserved => |opcode| {
const e: Opcode = @enumFromInt(opcode);
return switch (e) {
.advance_loc,
.offset,
.restore,
=> unreachable,
.nop => .{ .nop = {} },
.set_loc => .{
.set_loc = .{
.address = switch (addr_size_bytes) {
2 => try reader.readInt(u16, endian),
4 => try reader.readInt(u32, endian),
8 => try reader.readInt(u64, endian),
else => return error.InvalidAddrSize,
},
},
},
.advance_loc1 => .{
.advance_loc1 = .{ .delta = try reader.readByte() },
},
.advance_loc2 => .{
.advance_loc2 = .{ .delta = try reader.readInt(u16, endian) },
},
.advance_loc4 => .{
.advance_loc4 = .{ .delta = try reader.readInt(u32, endian) },
},
.offset_extended => .{
.offset_extended = .{
.register = try leb.readUleb128(u8, reader),
.offset = try leb.readUleb128(u64, reader),
},
},
.restore_extended => .{
.restore_extended = .{
.register = try leb.readUleb128(u8, reader),
},
},
.undefined => .{
.undefined = .{
.register = try leb.readUleb128(u8, reader),
},
},
.same_value => .{
.same_value = .{
.register = try leb.readUleb128(u8, reader),
},
},
.register => .{
.register = .{
.register = try leb.readUleb128(u8, reader),
.target_register = try leb.readUleb128(u8, reader),
},
},
.remember_state => .{ .remember_state = {} },
.restore_state => .{ .restore_state = {} },
.def_cfa => .{
.def_cfa = .{
.register = try leb.readUleb128(u8, reader),
.offset = try leb.readUleb128(u64, reader),
},
},
.def_cfa_register => .{
.def_cfa_register = .{
.register = try leb.readUleb128(u8, reader),
},
},
.def_cfa_offset => .{
.def_cfa_offset = .{
.offset = try leb.readUleb128(u64, reader),
},
},
.def_cfa_expression => .{
.def_cfa_expression = .{
.block = try readBlock(stream),
},
},
.expression => .{
.expression = .{
.register = try leb.readUleb128(u8, reader),
.block = try readBlock(stream),
},
},
.offset_extended_sf => .{
.offset_extended_sf = .{
.register = try leb.readUleb128(u8, reader),
.offset = try leb.readIleb128(i64, reader),
},
},
.def_cfa_sf => .{
.def_cfa_sf = .{
.register = try leb.readUleb128(u8, reader),
.offset = try leb.readIleb128(i64, reader),
},
},
.def_cfa_offset_sf => .{
.def_cfa_offset_sf = .{
.offset = try leb.readIleb128(i64, reader),
},
},
.val_offset => .{
.val_offset = .{
.register = try leb.readUleb128(u8, reader),
.offset = try leb.readUleb128(u64, reader),
},
},
.val_offset_sf => .{
.val_offset_sf = .{
.register = try leb.readUleb128(u8, reader),
.offset = try leb.readIleb128(i64, reader),
},
},
.val_expression => .{
.val_expression = .{
.register = try leb.readUleb128(u8, reader),
.block = try readBlock(stream),
},
},
};
},
Opcode.lo_user...Opcode.hi_user => return error.UnimplementedUserOpcode,
else => return error.InvalidOpcode,
}
}
}