v0.6: state.stack, until(loc), finish(), prelude show.* helpers
- StackRegion from /proc/<pid>/maps, exposed as state.stack
({top, usable_base, guard_size} BigInts per spec)
- until(loc) one-shot bp wrapper that cleans up via try/finally,
works even if a different stop fires first
- finish() reads return address from [rbp+8] and uses until()
- updated js.rs module doc; allow(dead_code) on the kept-for-future
BreakpointSet::find_by_name
This commit is contained in:
@@ -1,15 +1,22 @@
|
||||
//! QuickJS REPL: persistent context, ptrace target lives behind an Rc<RefCell>,
|
||||
//! globals are installed once at construction.
|
||||
//!
|
||||
//! v0.1 surface:
|
||||
//! spawn(path, ...args) -> { pid, status }
|
||||
//! step(n=1) -> stop-reason string
|
||||
//! continue() -> stop-reason string (exposed as `continue` and `cont`)
|
||||
//! print(...args) -> writes to stdout
|
||||
//! ctx -> persistent plain object
|
||||
//! state.pc / .sp -> BigInt
|
||||
//! state.registers -> object of BigInts
|
||||
//! state.memory(addr) -> { u8(), u32(), u64(), i64(), bytes(n) }
|
||||
//! Native globals installed here:
|
||||
//! spawn(path, ...args) -> { pid, status }
|
||||
//! step(n=1) / cont() -> stop-reason string
|
||||
//! print(...args), ctx (persistent object)
|
||||
//! state.pc, state.sp -> BigInt (live ptrace)
|
||||
//! state.registers -> object of BigInts
|
||||
//! state.memory(addr) -> { u8/u32/u64/i64/bytes }
|
||||
//! state.disasm(n=8) -> [{addr, bytes, text, target?, target_sym?}]
|
||||
//! state.stack -> { top, usable_base, guard_size }
|
||||
//! prev -> register snapshot from before last resume
|
||||
//! sym(addr), addr(name), symbols()
|
||||
//! disasm(addr, n=8)
|
||||
//! breakpoint / bp: .set, .remove, .list
|
||||
//!
|
||||
//! JS-side helpers (in prelude.js): hex, unhex, dump, repr, addrstr, here,
|
||||
//! until, finish, show.{disasm,bp,regs}.
|
||||
|
||||
use crate::target::Target;
|
||||
use rquickjs::function::Rest;
|
||||
@@ -314,6 +321,24 @@ fn install_globals<'js>(
|
||||
state_obj.set("disasm", f)?;
|
||||
}
|
||||
|
||||
// state.stack — accessor returning {top, usable_base, guard_size} as BigInts
|
||||
{
|
||||
let target = target.clone();
|
||||
state_obj.prop(
|
||||
"stack",
|
||||
Accessor::from(move |c: Ctx<'js>| -> rquickjs::Result<Value<'js>> {
|
||||
let slot = target.borrow();
|
||||
let t = slot.as_ref().ok_or_else(|| throw(&c, "no target attached"))?;
|
||||
let s = t.stack().ok_or_else(|| throw(&c, "no stack info"))?;
|
||||
let obj = Object::new(c.clone())?;
|
||||
obj.set("top", u64_to_bigint(&c, s.high)?)?;
|
||||
obj.set("usable_base", u64_to_bigint(&c, s.low)?)?;
|
||||
obj.set("guard_size", u64_to_bigint(&c, s.guard_size)?)?;
|
||||
Ok(obj.into_value())
|
||||
}),
|
||||
)?;
|
||||
}
|
||||
|
||||
globals.set("state", state_obj)?;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user