Verified Commit b356ddc3 authored by jD91mZM2's avatar jD91mZM2
Browse files

WIP(ptrace): Add test for singlesteps

parent 06344744
......@@ -4,6 +4,7 @@
name = "acid"
version = "0.1.0"
dependencies = [
"redox_syscall 0.1.54 (git+https://gitlab.redox-os.org/jD91mZM2/syscall.git?branch=ptrace)",
"x86 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -201,6 +202,11 @@ dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.54"
source = "git+https://gitlab.redox-os.org/jD91mZM2/syscall.git?branch=ptrace#a7aff4b60d537e6f336ff7e8affe8801a92c20f0"
[[package]]
name = "rustc-serialize"
version = "0.3.24"
......@@ -284,6 +290,7 @@ dependencies = [
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
"checksum raw-cpuid 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "13b844e4049605ff38fed943f5c7b2c691fad68d9d5bf074d2720554c4e48246"
"checksum redox_syscall 0.1.54 (git+https://gitlab.redox-os.org/jD91mZM2/syscall.git?branch=ptrace)" = "<none>"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum serde 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c97b18e9e53de541f11e497357d6c5eaeb39f0cb9c8734e274abe4935f6991fa"
"checksum serde_json 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5aaee47e038bf9552d30380d3973fff2593ee0a76d81ad4c581f267cdcadf36"
......
......@@ -5,3 +5,4 @@ authors = ["Jeremy Soller <jackpot51@gmail.com>"]
[dependencies]
x86 = "0.7"
redox_syscall = { git = "https://gitlab.redox-os.org/jD91mZM2/syscall.git", branch = "ptrace" }
//!Acid testing program
#![feature(thread_local)]
#![feature(thread_local, asm)]
extern crate x86;
......@@ -51,6 +51,83 @@ fn page_fault_test() -> Result<(), String> {
Ok(())
}
fn ptrace() -> Result<(), String> {
use std::{
fs::File,
io::prelude::*,
os::{raw::c_int, unix::io::{AsRawFd, FromRawFd}}
};
let pid = unsafe { syscall::clone(0).map_err(|e| format!("clone failed: {}", e))? };
if pid == 0 {
unsafe {
asm!("
mov rax, 20 // GETPID
syscall
mov rdi, rax
mov rax, 37 // SYS_KILL
mov rsi, 19 // SIGSTOP
syscall
// Start of body
mov rax, 1
push rax
mov rax, 2
push rax
mov rax, 3
pop rax
pop rax
// End of body
mov rax, 1 // SYS_EXIT
mov rdi, 0
syscall
"
: : : : "intel", "volatile"
);
}
}
// Wait until child is ready to be traced
let mut status = 0;
syscall::waitpid(pid, &mut status, syscall::WUNTRACED).map_err(|e| format!("waitpid failed: {}", e))?;
// Stop & attach process + get handle to registers
let mut proc_file = File::open(format!("proc:{}/trace", pid)).map_err(|e| format!("open failed: {}", e))?;
let mut regs_file = unsafe {
File::from_raw_fd(
syscall::dup(proc_file.as_raw_fd() as usize, b"regs/int")
.map_err(|e| format!("dup failed: {}", e))? as c_int
)
};
// Schedule restart of process when resumed
syscall::kill(pid, syscall::SIGCONT).map_err(|e| format!("kill failed: {}", e))?;
let mut next = move |op| -> Result<syscall::IntRegisters, String> {
proc_file.write(&[op]).map_err(|e| format!("ptrace operation failed: {}", e))?;
let mut regs: syscall::IntRegisters = syscall::IntRegisters::default();
regs_file.read(&mut regs).map_err(|e| format!("reading registers failed: {}", e))?;
Ok(regs)
};
// Step out of syscall down to the next instruction
let _ = next(syscall::PTRACE_SINGLESTEP)?;
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 1);
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 2);
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 2);
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 3);
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 2);
assert_eq!(next(syscall::PTRACE_SINGLESTEP)?.rax, 1);
assert_eq!(next(syscall::PTRACE_SYSCALL)?.rax, syscall::SYS_EXIT);
Ok(())
}
fn switch_test() -> Result<(), String> {
use std::thread;
use x86::time::rdtscp;
......@@ -181,6 +258,7 @@ fn main() {
let mut tests: BTreeMap<&'static str, fn() -> Result<(), String>> = BTreeMap::new();
tests.insert("create_test", create_test);
tests.insert("page_fault", page_fault_test);
tests.insert("ptrace", ptrace);
tests.insert("switch", switch_test);
tests.insert("tcp_fin", tcp_fin_test);
tests.insert("thread", thread_test);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment