feat: implement software breakpoints

This commit is contained in:
2023-01-29 07:17:12 -06:00
parent 81ff227ea7
commit d7b8d7acb1
3 changed files with 153 additions and 57 deletions

View File

@@ -1,6 +1,62 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const ArrayList = std.ArrayList;
hw_bkpt: HwBkpt = .{},
sw_bkpt: SwBkpt,
pub fn init(allocator: Allocator) @This() {
return .{ .sw_bkpt = SwBkpt.init(allocator) };
}
pub fn deinit(self: *@This()) void {
self.sw_bkpt.deinit();
self.* = undefined;
}
const SwBkpt = struct {
const log = std.log.scoped(.SwBkpt);
list: std.ArrayList(Bkpt),
pub fn init(allocator: Allocator) @This() {
return .{ .list = ArrayList(Bkpt).init(allocator) };
}
pub fn deinit(self: *@This()) void {
self.deinit();
self.* = undefined;
}
pub fn isHit(self: *const @This(), addr: u32) bool {
for (self.list.items) |bkpt| {
if (bkpt.addr == addr) return true;
}
return false;
}
pub fn add(self: *@This(), addr: u32, kind: u32) !void {
for (self.list.items) |bkpt| {
if (bkpt.addr == addr) return; // indempotent
}
try self.list.append(.{ .addr = addr, .kind = try Bkpt.Kind.from(u32, kind) });
log.warn("Added Breakpoint at 0x{X:0>8}", .{addr});
}
pub fn remove(self: *@This(), addr: u32) void {
for (self.list.items) |bkpt, i| {
if (bkpt.addr == addr) {
_ = self.list.orderedRemove(i);
log.debug("Removed Breakpoint at 0x{X:0>8}", .{addr});
return;
}
}
}
};
const HwBkpt = struct {
const log = std.log.scoped(.HwBkpt);
@@ -9,9 +65,7 @@ const HwBkpt = struct {
pub fn isHit(self: *const @This(), addr: u32) bool {
for (self.list) |bkpt_opt| {
if (bkpt_opt == null) continue;
const bkpt = bkpt_opt.?;
const bkpt = bkpt_opt orelse continue;
if (bkpt.addr == addr) return true;
}
@@ -20,17 +74,14 @@ const HwBkpt = struct {
pub fn add(self: *@This(), addr: u32, kind: u32) !void {
for (self.list) |*bkpt_opt| {
if (bkpt_opt.* != null) {
const bkpt = bkpt_opt.*.?;
if (bkpt.addr == addr) return; // makes this fn indempotent
if (bkpt_opt.*) |bkpt| {
if (bkpt.addr == addr) return; // idempotent
} else {
bkpt_opt.* = .{ .addr = addr, .kind = try Bkpt.Kind.from(u32, kind) };
log.debug("Added Breakpoint at 0x{X:0>8}", .{addr});
continue;
return;
}
bkpt_opt.* = .{ .addr = addr, .kind = try Bkpt.Kind.from(u32, kind) };
log.debug("Added Breakpoint at 0x{X:0>8}", .{addr});
return;
}
return error.OutOfSpace;
@@ -38,11 +89,14 @@ const HwBkpt = struct {
pub fn remove(self: *@This(), addr: u32) void {
for (self.list) |*bkpt_opt| {
if (bkpt_opt.* == null) continue;
const bkpt = bkpt_opt.*.?; // FIXME: bkpt_opt.?.addr works though?
const bkpt = bkpt_opt.* orelse continue;
log.debug("Removed Breakpoint at 0x{X:0>8}", .{addr});
if (bkpt.addr == addr) bkpt_opt.* = null;
if (bkpt.addr == addr) {
bkpt_opt.* = null;
log.debug("Removed Breakpoint at 0x{X:0>8}", .{addr});
break;
}
}
}
};