Skip to content

Commit

Permalink
Loads segment selector for debugger (#1046)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Oct 19, 2024
1 parent 9849e5f commit ae78fd2
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 21 deletions.
52 changes: 31 additions & 21 deletions gui/src/vmm/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,37 +271,47 @@ impl<H: Hypervisor, S: Screen> CpuManager<H, S> {

#[cfg(target_arch = "x86_64")]
fn get_debug_regs<C: CpuStates>(states: &mut C) -> Result<GdbRegs, RustError> {
let mut load = |name: &str, func: fn(&mut C) -> Result<usize, C::Err>| {
use gdbstub_arch::x86::reg::X86SegmentRegs;

let error = |n: &str, e: C::Err| RustError::with_source(format!("couldn't get {n}"), e);
let mut load_greg = |name: &str, func: fn(&mut C) -> Result<usize, C::Err>| {
func(states)
.map(|v| TryInto::<u64>::try_into(v).unwrap())
.map_err(|e| RustError::with_source(format_args!("couldn't get {name}"), e))
.map_err(|e| error(name, e))
};

Ok(GdbRegs {
regs: [
load("rax", |s| s.get_rax())?,
load("rbx", |s| s.get_rbx())?,
load("rcx", |s| s.get_rcx())?,
load("rdx", |s| s.get_rdx())?,
load("rsi", |s| s.get_rsi())?,
load("rdi", |s| s.get_rdi())?,
load("rbp", |s| s.get_rbp())?,
load("rsp", |s| s.get_rsp())?,
load("r8", |s| s.get_r8())?,
load("r9", |s| s.get_r9())?,
load("r10", |s| s.get_r10())?,
load("r11", |s| s.get_r11())?,
load("r12", |s| s.get_r12())?,
load("r13", |s| s.get_r13())?,
load("r14", |s| s.get_r14())?,
load("r15", |s| s.get_r15())?,
load_greg("rax", |s| s.get_rax())?,
load_greg("rbx", |s| s.get_rbx())?,
load_greg("rcx", |s| s.get_rcx())?,
load_greg("rdx", |s| s.get_rdx())?,
load_greg("rsi", |s| s.get_rsi())?,
load_greg("rdi", |s| s.get_rdi())?,
load_greg("rbp", |s| s.get_rbp())?,
load_greg("rsp", |s| s.get_rsp())?,
load_greg("r8", |s| s.get_r8())?,
load_greg("r9", |s| s.get_r9())?,
load_greg("r10", |s| s.get_r10())?,
load_greg("r11", |s| s.get_r11())?,
load_greg("r12", |s| s.get_r12())?,
load_greg("r13", |s| s.get_r13())?,
load_greg("r14", |s| s.get_r14())?,
load_greg("r15", |s| s.get_r15())?,
],
rip: load("rip", |s| s.get_rip())?,
rip: load_greg("rip", |s| s.get_rip())?,
eflags: states
.get_rflags()
.map(|v| v.into_bits().try_into().unwrap())
.map_err(|e| RustError::with_source("couldn't get rflags", e))?,
segments: todo!(),
.map_err(|e| error("rflags", e))?,
segments: X86SegmentRegs {
cs: states.get_cs().map_err(|e| error("cs", e))?.into(),
ss: states.get_ss().map_err(|e| error("ss", e))?.into(),
ds: states.get_ds().map_err(|e| error("ds", e))?.into(),
es: states.get_es().map_err(|e| error("es", e))?.into(),
fs: states.get_fs().map_err(|e| error("fs", e))?.into(),
gs: states.get_gs().map_err(|e| error("gs", e))?.into(),
},
st: todo!(),
fpu: todo!(),
xmm: todo!(),
Expand Down
24 changes: 24 additions & 0 deletions gui/src/vmm/hv/linux/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ impl<'a> CpuStates for KvmStates<'a> {
self.sdirty = true;
}

fn get_cs(&mut self) -> Result<u16, Self::Err> {
Ok(self.sregs.cs.selector)
}

fn set_cs(&mut self, ty: u8, dpl: u8, p: bool, l: bool, d: bool) {
self.sregs.cs.ty = ty;
self.sregs.cs.dpl = dpl;
Expand All @@ -169,26 +173,46 @@ impl<'a> CpuStates for KvmStates<'a> {
self.sdirty = true;
}

fn get_ds(&mut self) -> Result<u16, Self::Err> {
Ok(self.sregs.ds.selector)
}

fn set_ds(&mut self, p: bool) {
self.sregs.ds.present = p.into();
self.sdirty = true;
}

fn get_es(&mut self) -> Result<u16, Self::Err> {
Ok(self.sregs.es.selector)
}

fn set_es(&mut self, p: bool) {
self.sregs.es.present = p.into();
self.sdirty = true;
}

fn get_fs(&mut self) -> Result<u16, Self::Err> {
Ok(self.sregs.fs.selector)
}

fn set_fs(&mut self, p: bool) {
self.sregs.fs.present = p.into();
self.sdirty = true;
}

fn get_gs(&mut self) -> Result<u16, Self::Err> {
Ok(self.sregs.gs.selector)
}

fn set_gs(&mut self, p: bool) {
self.sregs.gs.present = p.into();
self.sdirty = true;
}

fn get_ss(&mut self) -> Result<u16, Self::Err> {
Ok(self.sregs.ss.selector)
}

fn set_ss(&mut self, p: bool) {
self.sregs.ss.present = p.into();
self.sdirty = true;
Expand Down
24 changes: 24 additions & 0 deletions gui/src/vmm/hv/windows/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ impl<'a, 'b> CpuStates for WhpStates<'a, 'b> {
self.dirty = true;
}

fn get_cs(&mut self) -> Result<u16, Self::Err> {
todo!()
}

fn set_cs(&mut self, ty: u8, dpl: u8, p: bool, l: bool, d: bool) {
// Rust binding does not provides a way to set bit fields so we need to do this manually.
// See https://learn.microsoft.com/en-us/virtualization/api/hypervisor-platform/funcs/whvvirtualprocessordatatypes
Expand All @@ -256,6 +260,10 @@ impl<'a, 'b> CpuStates for WhpStates<'a, 'b> {
self.dirty = true;
}

fn get_ds(&mut self) -> Result<u16, Self::Err> {
todo!()
}

fn set_ds(&mut self, p: bool) {
let v = unsafe { &mut self.values[7].Segment.Anonymous.Attributes };
let p: u16 = p.into();
Expand All @@ -265,6 +273,10 @@ impl<'a, 'b> CpuStates for WhpStates<'a, 'b> {
self.dirty = true;
}

fn get_es(&mut self) -> Result<u16, Self::Err> {
todo!()
}

fn set_es(&mut self, p: bool) {
let v = unsafe { &mut self.values[8].Segment.Anonymous.Attributes };
let p: u16 = p.into();
Expand All @@ -274,6 +286,10 @@ impl<'a, 'b> CpuStates for WhpStates<'a, 'b> {
self.dirty = true;
}

fn get_fs(&mut self) -> Result<u16, Self::Err> {
todo!()
}

fn set_fs(&mut self, p: bool) {
let v = unsafe { &mut self.values[9].Segment.Anonymous.Attributes };
let p: u16 = p.into();
Expand All @@ -283,6 +299,10 @@ impl<'a, 'b> CpuStates for WhpStates<'a, 'b> {
self.dirty = true;
}

fn get_gs(&mut self) -> Result<u16, Self::Err> {
todo!()
}

fn set_gs(&mut self, p: bool) {
let v = unsafe { &mut self.values[10].Segment.Anonymous.Attributes };
let p: u16 = p.into();
Expand All @@ -292,6 +312,10 @@ impl<'a, 'b> CpuStates for WhpStates<'a, 'b> {
self.dirty = true;
}

fn get_ss(&mut self) -> Result<u16, Self::Err> {
todo!()
}

fn set_ss(&mut self, p: bool) {
let v = unsafe { &mut self.values[11].Segment.Anonymous.Attributes };
let p: u16 = p.into();
Expand Down
6 changes: 6 additions & 0 deletions gui/src/vmm/hv/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,17 @@ pub trait CpuStates {
fn set_cr4(&mut self, v: usize);
fn get_rflags(&mut self) -> Result<Rflags, Self::Err>;
fn set_efer(&mut self, v: usize);
fn get_cs(&mut self) -> Result<u16, Self::Err>;
fn set_cs(&mut self, ty: u8, dpl: u8, p: bool, l: bool, d: bool);
fn get_ds(&mut self) -> Result<u16, Self::Err>;
fn set_ds(&mut self, p: bool);
fn get_es(&mut self) -> Result<u16, Self::Err>;
fn set_es(&mut self, p: bool);
fn get_fs(&mut self) -> Result<u16, Self::Err>;
fn set_fs(&mut self, p: bool);
fn get_gs(&mut self) -> Result<u16, Self::Err>;
fn set_gs(&mut self, p: bool);
fn get_ss(&mut self) -> Result<u16, Self::Err>;
fn set_ss(&mut self, p: bool);
}

Expand Down

0 comments on commit ae78fd2

Please sign in to comment.