Runs the CIE instructions, then the FDE instructions. Execution halts
once the row that corresponds to pc is known, and the row is returned.
pub fn runTo(
vm: *VirtualMachine,
gpa: Allocator,
pc: u64,
cie: *const Unwind.CommonInformationEntry,
fde: *const Unwind.FrameDescriptionEntry,
addr_size_bytes: u8,
endian: std.builtin.Endian,
) !Row
pub fn runTo(
vm: *VirtualMachine,
gpa: Allocator,
pc: u64,
cie: *const Unwind.CommonInformationEntry,
fde: *const Unwind.FrameDescriptionEntry,
addr_size_bytes: u8,
endian: std.builtin.Endian,
) !Row {
assert(vm.cie_row == null);
const target_offset = pc - fde.pc_begin;
assert(target_offset < fde.pc_range);
const instruction_bytes: []const u8 = insts: {
if (target_offset < cie.last_row.?.offset) {
break :insts cie.initial_instructions;
}
// This is the more common case: start from the CIE's last row.
assert(vm.columns.items.len == 0);
vm.current_row = .{
.offset = cie.last_row.?.offset,
.cfa = cie.last_row.?.cfa,
.columns = .{
.start = 0,
.len = @intCast(cie.last_row.?.cols.len),
},
};
try vm.columns.appendSlice(gpa, cie.last_row.?.cols);
vm.cie_row = vm.current_row;
break :insts fde.instructions;
};
try vm.evalInstructions(
gpa,
cie,
target_offset,
instruction_bytes,
addr_size_bytes,
endian,
);
return vm.current_row;
}