mirror of
https://github.com/facebookexperimental/reverie.git
synced 2025-01-23 13:10:04 +00:00
Add generalized stack pointer access
Reviewed By: VladimirMakaev Differential Revision: D40701834 fbshipit-source-id: 6cad4cedc0d22488117d3d991ae9a80b643ee037
This commit is contained in:
parent
4f9ce11c70
commit
caf0f12131
3 changed files with 57 additions and 4 deletions
|
@ -49,6 +49,7 @@ use crate::gdbstub::Inferior;
|
||||||
use crate::gdbstub::InferiorThreadId;
|
use crate::gdbstub::InferiorThreadId;
|
||||||
use crate::gdbstub::ResumeInferior;
|
use crate::gdbstub::ResumeInferior;
|
||||||
use crate::gdbstub::StoppedInferior;
|
use crate::gdbstub::StoppedInferior;
|
||||||
|
use crate::regs::RegAccess;
|
||||||
|
|
||||||
mod base;
|
mod base;
|
||||||
mod extended_mode;
|
mod extended_mode;
|
||||||
|
@ -363,9 +364,9 @@ pub struct ExpediatedRegs(BTreeMap<usize, u64>);
|
||||||
impl From<libc::user_regs_struct> for ExpediatedRegs {
|
impl From<libc::user_regs_struct> for ExpediatedRegs {
|
||||||
fn from(regs: libc::user_regs_struct) -> Self {
|
fn from(regs: libc::user_regs_struct) -> Self {
|
||||||
let mut exp_regs = BTreeMap::new();
|
let mut exp_regs = BTreeMap::new();
|
||||||
exp_regs.insert(6, regs.rbp);
|
exp_regs.insert(6, regs.frame_ptr());
|
||||||
exp_regs.insert(7, regs.rsp);
|
exp_regs.insert(7, regs.stack_ptr());
|
||||||
exp_regs.insert(0x10, regs.rip);
|
exp_regs.insert(0x10, regs.ip());
|
||||||
ExpediatedRegs(exp_regs)
|
ExpediatedRegs(exp_regs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,22 @@ pub trait RegAccess {
|
||||||
/// Mutable access to the instruction pointer (aka the program counter).
|
/// Mutable access to the instruction pointer (aka the program counter).
|
||||||
fn ip_mut(&mut self) -> &mut Reg;
|
fn ip_mut(&mut self) -> &mut Reg;
|
||||||
|
|
||||||
|
/// Returns the value of the stack pointer.
|
||||||
|
fn stack_ptr(&self) -> Reg;
|
||||||
|
|
||||||
|
/// Mutable access to the stack pointer.
|
||||||
|
fn stack_ptr_mut(&mut self) -> &mut Reg;
|
||||||
|
|
||||||
|
/// Returns the value of the stack frame pointer.
|
||||||
|
///
|
||||||
|
/// NOTE: The frame pointer is not guaranteed to be available. For example,
|
||||||
|
/// if `-fomit-frame-pointer` was used (often the default), this will not
|
||||||
|
/// return the correct address.
|
||||||
|
fn frame_ptr(&self) -> Reg;
|
||||||
|
|
||||||
|
/// Mutable access to the stack frame pointer.
|
||||||
|
fn frame_ptr_mut(&mut self) -> &mut Reg;
|
||||||
|
|
||||||
/// Returns the value of the register where the syscall number is stored.
|
/// Returns the value of the register where the syscall number is stored.
|
||||||
///
|
///
|
||||||
/// NOTE: Depending on the context, this may not actually be a syscall
|
/// NOTE: Depending on the context, this may not actually be a syscall
|
||||||
|
@ -76,6 +92,22 @@ impl RegAccess for libc::user_regs_struct {
|
||||||
&mut self.rip
|
&mut self.rip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stack_ptr(&self) -> Reg {
|
||||||
|
self.rsp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stack_ptr_mut(&mut self) -> &mut Reg {
|
||||||
|
&mut self.rsp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_ptr(&self) -> Reg {
|
||||||
|
self.rbp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_ptr_mut(&mut self) -> &mut Reg {
|
||||||
|
&mut self.rbp
|
||||||
|
}
|
||||||
|
|
||||||
fn syscall(&self) -> Reg {
|
fn syscall(&self) -> Reg {
|
||||||
self.rax
|
self.rax
|
||||||
}
|
}
|
||||||
|
@ -126,6 +158,24 @@ impl RegAccess for libc::user_regs_struct {
|
||||||
&mut self.pc
|
&mut self.pc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stack_ptr(&self) -> Reg {
|
||||||
|
self.sp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stack_ptr_mut(&mut self) -> &mut Reg {
|
||||||
|
&mut self.sp
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_ptr(&self) -> Reg {
|
||||||
|
// aarch64 uses x29 for the frame pointer (unless `-fomit-frame-pointer`
|
||||||
|
// is used).
|
||||||
|
self.regs[29]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_ptr_mut(&mut self) -> &mut Reg {
|
||||||
|
&mut self.regs[29]
|
||||||
|
}
|
||||||
|
|
||||||
fn syscall(&self) -> Reg {
|
fn syscall(&self) -> Reg {
|
||||||
self.regs[8]
|
self.regs[8]
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ use reverie::Stack;
|
||||||
use safeptrace::Error as TraceError;
|
use safeptrace::Error as TraceError;
|
||||||
use safeptrace::Stopped;
|
use safeptrace::Stopped;
|
||||||
|
|
||||||
|
use super::regs::RegAccess;
|
||||||
|
|
||||||
// NB: leaf function can use redzone without explicit stack allocation, as
|
// NB: leaf function can use redzone without explicit stack allocation, as
|
||||||
// a result it is not safe to just adjust stack pointer. 128B of stack
|
// a result it is not safe to just adjust stack pointer. 128B of stack
|
||||||
// space is mostly wasted -- to avoid the corner case when redzone is used.
|
// space is mostly wasted -- to avoid the corner case when redzone is used.
|
||||||
|
@ -49,7 +51,7 @@ impl GuestStack {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let task = Stopped::new_unchecked(pid);
|
let task = Stopped::new_unchecked(pid);
|
||||||
let rsp = task.getregs()?.rsp as usize;
|
let rsp = task.getregs()?.stack_ptr() as usize;
|
||||||
let top = rsp - REDZONE_SIZE as usize;
|
let top = rsp - REDZONE_SIZE as usize;
|
||||||
Ok(GuestStack {
|
Ok(GuestStack {
|
||||||
top,
|
top,
|
||||||
|
|
Loading…
Reference in a new issue