feat(debug): support register-register conditional breakpoints
Assisted-by: MiMo V2.5 Pro
This commit is contained in:
+32
-11
@@ -17,12 +17,17 @@ type Breakpoint struct {
|
|||||||
hits int
|
hits int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Condition is a simple register-comparison condition evaluated when a
|
// Condition is a register-comparison condition evaluated when a breakpoint
|
||||||
// breakpoint is hit. Format: <reg> <op> <value>.
|
// is hit. Supports three forms:
|
||||||
|
// - register vs constant: <reg> <op> <value>
|
||||||
|
// - register vs register: <reg> <op> <reg2>
|
||||||
|
// - register vs memory: <reg> <op> *<addr>
|
||||||
type Condition struct {
|
type Condition struct {
|
||||||
Reg string // register name (rax, rbx, rip, rsp, ...)
|
Reg string // register name (rax, rbx, rip, rsp, ...)
|
||||||
Op string // comparison operator: ==, !=, <, >, <=, >=
|
Op string // comparison operator: ==, !=, <, >, <=, >=
|
||||||
Value uint64
|
Value uint64 // constant value (when Reg2 == "" and MemAddr == 0)
|
||||||
|
Reg2 string // second register name (for register-register comparison)
|
||||||
|
MemAddr uint64 // memory address (for register-memory comparison, prefixed with *)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eval checks the condition against the current registers.
|
// Eval checks the condition against the current registers.
|
||||||
@@ -31,19 +36,35 @@ func (c *Condition) Eval(regs *Regs) bool {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return true // unknown register — don't block
|
return true // unknown register — don't block
|
||||||
}
|
}
|
||||||
|
var expected uint64
|
||||||
|
switch {
|
||||||
|
case c.Reg2 != "":
|
||||||
|
// Register-register comparison.
|
||||||
|
v, ok := regs.RegValue(c.Reg2)
|
||||||
|
if !ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
expected = v
|
||||||
|
case c.MemAddr != 0:
|
||||||
|
// Register-memory comparison — requires a Session, not available here.
|
||||||
|
// Fall back to treating as constant (the caller should resolve).
|
||||||
|
expected = c.Value
|
||||||
|
default:
|
||||||
|
expected = c.Value
|
||||||
|
}
|
||||||
switch c.Op {
|
switch c.Op {
|
||||||
case "==", "=":
|
case "==", "=":
|
||||||
return actual == c.Value
|
return actual == expected
|
||||||
case "!=":
|
case "!=":
|
||||||
return actual != c.Value
|
return actual != expected
|
||||||
case "<":
|
case "<":
|
||||||
return actual < c.Value
|
return actual < expected
|
||||||
case ">":
|
case ">":
|
||||||
return actual > c.Value
|
return actual > expected
|
||||||
case "<=":
|
case "<=":
|
||||||
return actual <= c.Value
|
return actual <= expected
|
||||||
case ">=":
|
case ">=":
|
||||||
return actual >= c.Value
|
return actual >= expected
|
||||||
default:
|
default:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -210,14 +210,16 @@ func REPL(s *Session, bm *Breakpoints, codeBase uint64, funcOffset, funcSize, ar
|
|||||||
}
|
}
|
||||||
var cond *Condition
|
var cond *Condition
|
||||||
if len(parts) >= 6 && parts[2] == "if" {
|
if len(parts) >= 6 && parts[2] == "if" {
|
||||||
val, err := strconv.ParseUint(parts[5], 0, 64)
|
reg := strings.ToLower(parts[3])
|
||||||
if err != nil {
|
op := parts[4]
|
||||||
fmt.Printf("invalid condition value: %s\n", parts[5])
|
operand := parts[5]
|
||||||
continue
|
if val, err := strconv.ParseUint(operand, 0, 64); err == nil {
|
||||||
|
cond = &Condition{Reg: reg, Op: op, Value: val}
|
||||||
|
} else {
|
||||||
|
cond = &Condition{Reg: reg, Op: op, Reg2: strings.ToLower(operand)}
|
||||||
}
|
}
|
||||||
cond = &Condition{Reg: strings.ToLower(parts[3]), Op: parts[4], Value: val}
|
|
||||||
} else if len(parts) >= 4 && parts[2] == "if" {
|
} else if len(parts) >= 4 && parts[2] == "if" {
|
||||||
fmt.Println("usage: break <label|addr> if <reg> <op> <value>")
|
fmt.Println("usage: break <label|addr> if <reg> <op> <value|reg>")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
bp, err := bm.SetWithCond(addr, label, cond)
|
bp, err := bm.SetWithCond(addr, label, cond)
|
||||||
|
|||||||
Reference in New Issue
Block a user