Skip to content

Commit 7f085ad

Browse files
committed
aarch64 register mappings
1 parent e59469e commit 7f085ad

File tree

2 files changed

+55
-35
lines changed

2 files changed

+55
-35
lines changed

src/discrete_alloc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl MachineAlloc {
4242
let mut alloc = ALLOCATOR.lock().unwrap();
4343
alloc.enabled = true;
4444
// This needs to specifically be the system pagesize!
45-
alloc.page_size = unsafe {
45+
alloc.page_size = unsafe {
4646
let ret = libc::sysconf(libc::_SC_PAGE_SIZE);
4747
if ret > 0 {
4848
ret as _

src/shims/trace.rs

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,30 @@ use nix::unistd;
44

55
use crate::discrete_alloc;
66

7+
#[cfg(target_pointer_width = "64")]
8+
const BITS: u32 = 64;
9+
#[cfg(target_pointer_width = "32")]
10+
const BITS: u32 = 32;
11+
12+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
13+
const BREAKPT_INSTR: i64 = 0xCC;
14+
#[cfg(target_arch = "aarch64")]
15+
const BREAKPT_INSTR: i64 = 0xD420;
16+
717
// We do NOT ever want to block the child from accessing this!!
818
static SUPERVISOR: std::sync::Mutex<Option<Supervisor>> = std::sync::Mutex::new(None);
919
static mut PAGE_ADDR: *mut libc::c_void = std::ptr::null_mut();
1020
static mut PAGE_SIZE: usize = 4096;
1121
static mut CLICK_HERE_4_FREE_STACK: [u8; 1024] = [0; 1024];
1222

13-
#[cfg(target_pointer_width = "64")]
14-
const BITS: u32 = 64;
15-
#[cfg(target_pointer_width = "32")]
16-
const BITS: u32 = 32;
17-
1823
trait ArchIndependentRegs {
19-
fn ax(&self) -> usize;
20-
fn di(&self) -> usize;
21-
fn si(&self) -> usize;
24+
// see https://man7.org/linux/man-pages/man2/syscall.2.html
25+
fn retval(&self) -> usize;
26+
fn arg1(&self) -> usize;
27+
fn arg2(&self) -> usize;
28+
fn syscall_nr(&self) -> usize;
2229
fn ip(&self) -> usize;
2330
fn sp(&self) -> usize;
24-
fn orig_ax(&self) -> usize;
2531
fn set_ip(&mut self, ip: usize);
2632
fn set_sp(&mut self, sp: usize);
2733
}
@@ -30,12 +36,12 @@ trait ArchIndependentRegs {
3036
#[allow(clippy::cast_possible_truncation)]
3137
#[rustfmt::skip]
3238
impl ArchIndependentRegs for libc::user_regs_struct {
33-
fn ax(&self) -> usize { self.rax as _ }
34-
fn di(&self) -> usize { self.rdi as _ }
35-
fn si(&self) -> usize { self.rsi as _ }
39+
fn retval(&self) -> usize { self.rax as _ }
40+
fn arg1(&self) -> usize { self.rdi as _ }
41+
fn arg2(&self) -> usize { self.rsi as _ }
42+
fn syscall_nr(&self) -> usize { self.orig_rax as _ }
3643
fn ip(&self) -> usize { self.rip as _ }
3744
fn sp(&self) -> usize { self.rsp as _ }
38-
fn orig_ax(&self) -> usize { self.orig_rax as _ }
3945
fn set_ip(&mut self, ip: usize) { self.rip = ip as _ }
4046
fn set_sp(&mut self, sp: usize) { self.rsp = sp as _ }
4147
}
@@ -44,16 +50,30 @@ impl ArchIndependentRegs for libc::user_regs_struct {
4450
#[allow(clippy::cast_possible_truncation)]
4551
#[rustfmt::skip]
4652
impl ArchIndependentRegs for libc::user_regs_struct {
47-
fn ax(&self) -> usize { self.eax as _ }
48-
fn di(&self) -> usize { self.edi as _ }
49-
fn si(&self) -> usize { self.esi as _ }
53+
fn retval(&self) -> usize { self.eax as _ }
54+
fn arg1(&self) -> usize { self.edi as _ }
55+
fn arg2(&self) -> usize { self.esi as _ }
56+
fn syscall_nr(&self) -> usize { self.orig_eax as _ }
5057
fn ip(&self) -> usize { self.eip as _ }
5158
fn sp(&self) -> usize { self.esp as _ }
52-
fn orig_ax(&self) -> usize { self.orig_eax as _ }
5359
fn set_ip(&mut self, ip: usize) { self.eip = ip as _ }
5460
fn set_sp(&mut self, sp: usize) { self.esp = sp as _ }
5561
}
5662

63+
#[cfg(target_arch = "aarch64")]
64+
#[allow(clippy::cast_possible_truncation)]
65+
#[rustfmt::skip]
66+
impl ArchIndependentRegs for libc::user_regs_struct {
67+
fn retval(&self) -> usize { self.regs[0] as _ }
68+
fn arg1(&self) -> usize { self.regs[0] as _ }
69+
fn arg2(&self) -> usize { self.regs[1] as _ }
70+
fn syscall_nr(&self) -> usize { self.regs[8] as _ }
71+
fn ip(&self) -> usize { self.pc as _ }
72+
fn sp(&self) -> usize { self.sp as _ }
73+
fn set_ip(&mut self, ip: usize) { self.pc = ip as _ }
74+
fn set_sp(&mut self, sp: usize) { self.sp = sp as _ }
75+
}
76+
5777
pub struct Supervisor {
5878
t_message: ipc::IpcSender<TraceRequest>,
5979
r_event: ipc::IpcReceiver<MemEvents>,
@@ -295,16 +315,16 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
295315
}
296316
wait::WaitStatus::PtraceSyscall(pid) => {
297317
let regs = ptrace::getregs(pid).unwrap();
298-
let syscall_nr = regs.orig_ax();
318+
let syscall_nr = regs.syscall_nr();
299319
if enter {
300320
if syscall_nr as i64 == libc::SYS_mmap {
301-
let len = regs.si();
321+
let len = regs.arg2();
302322
flush_mapped = Some(len);
303323
} else if syscall_nr as i64 == libc::SYS_munmap {
304324
// The unmap call might hit multiple mappings we've saved,
305325
// or overlap with them partially (or both)
306-
let um_start = regs.di();
307-
let um_len = regs.si();
326+
let um_start = regs.arg1();
327+
let um_len = regs.arg2();
308328
let um_end = um_start + um_len;
309329
let mut idxes = vec![];
310330
for (idx, &(mp_start, len)) in mappings.iter().enumerate() {
@@ -326,9 +346,9 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
326346
} // TODO: handle brk/sbrk
327347
} else {
328348
if syscall_nr as i64 == libc::SYS_mmap {
329-
if regs.ax() as isize > 0 {
349+
if regs.retval() as isize > 0 {
330350
if let Some(len) = flush_mapped.take() {
331-
let addr = regs.ax();
351+
let addr = regs.retval();
332352
mappings.push((addr, len as _));
333353
} else {
334354
eprintln!(
@@ -338,7 +358,7 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
338358
}
339359
} else if syscall_nr as i64 == libc::SYS_munmap {
340360
if let Some((idxes, um_start, um_len)) = munmap_args.take() {
341-
if regs.ax() as isize > 0 {
361+
if regs.retval() as isize > 0 {
342362
// Unmap succeeded, so take out the mapping(s) from our list
343363
// but it may be only partial so we may readd some sections
344364
for idx in idxes {
@@ -373,9 +393,9 @@ fn sv_loop(listener: ChildListener, t_event: ipc::IpcSender<MemEvents>) -> ! {
373393
ptrace::seize(main_pid, ptrace::Options::PTRACE_O_TRACESYSGOOD).unwrap();
374394
let _ = wait::waitpid(main_pid, None).unwrap();
375395

376-
ptrace::write(main_pid, malloc_addr as _, 0xcc).unwrap();
377-
ptrace::write(main_pid, realloc_addr as _, 0xcc).unwrap();
378-
ptrace::write(main_pid, free_addr as _, 0xcc).unwrap();
396+
ptrace::write(main_pid, malloc_addr as _, BREAKPT_INSTR).unwrap();
397+
ptrace::write(main_pid, realloc_addr as _, BREAKPT_INSTR).unwrap();
398+
ptrace::write(main_pid, free_addr as _, BREAKPT_INSTR).unwrap();
379399

380400
ptrace::syscall(main_pid, None).unwrap();
381401
}
@@ -515,13 +535,13 @@ fn handle_sigtrap(
515535
let regs = ptrace::getregs(pid).unwrap();
516536
match regs.ip() - 1 {
517537
a if a == malloc_addr => {
518-
let size = regs.di(); // !
538+
let size = regs.arg1(); // !
519539
let ptr = intercept_retptr(pid, regs, malloc_addr, malloc_bytes);
520540
mappings.push((ptr as _, size));
521541
}
522542
a if a == realloc_addr => {
523-
let old_ptr = regs.di();
524-
let size = regs.si();
543+
let old_ptr = regs.arg1();
544+
let size = regs.arg2();
525545
let pos = mappings
526546
.iter()
527547
.position(|&(ptr, size)| ptr <= old_ptr as _ && (old_ptr as usize) < ptr + size);
@@ -532,7 +552,7 @@ fn handle_sigtrap(
532552
mappings.push((ptr as _, size as _));
533553
}
534554
a if a == free_addr => {
535-
let old_ptr = regs.di();
555+
let old_ptr = regs.arg1();
536556
//let size = regs.rdi;
537557
let pos =
538558
mappings.iter().position(|&(ptr, size)| ptr <= old_ptr && old_ptr < ptr + size);
@@ -565,7 +585,7 @@ fn intercept_retptr(
565585
regs.set_ip(regs.ip() - 1);
566586
let ret_addr = ptrace::read(pid, regs.sp() as _).unwrap();
567587
let ret_bytes = ptrace::read(pid, ret_addr as _).unwrap();
568-
ptrace::write(pid, ret_addr as _, 0xcc).unwrap();
588+
ptrace::write(pid, ret_addr as _, BREAKPT_INSTR).unwrap();
569589
ptrace::write(pid, fn_addr as _, fn_bytes).unwrap();
570590
ptrace::setregs(pid, regs).unwrap();
571591

@@ -574,9 +594,9 @@ fn intercept_retptr(
574594

575595
// now we're getting the return hopefully
576596
let mut regs = ptrace::getregs(pid).unwrap();
577-
let ptr = regs.ax(); // !
597+
let ptr = regs.retval(); // !
578598
regs.set_ip(regs.ip() - 1);
579-
ptrace::write(pid, fn_addr as _, 0xcc).unwrap();
599+
ptrace::write(pid, fn_addr as _, BREAKPT_INSTR).unwrap();
580600
ptrace::write(pid, ret_addr as _, ret_bytes).unwrap();
581601
ptrace::setregs(pid, regs).unwrap();
582602

0 commit comments

Comments
 (0)