summary refs log tree commit diff
diff options
context:
space:
mode:
authoredef <edef@unfathomable.blue>2022-07-29 18:29:57 +0000
committeredef <edef@unfathomable.blue>2022-07-29 18:29:57 +0000
commit70720e1d46601069afb5fa1b6030c723c2cc492c (patch)
tree7faa32f881f53062764d2130c51b3ed724850fc4
parentd36576e49e45fd891ca5f86f13ea033224eedf3e (diff)
ripple/minitrace: implement and use SyscallArg for enums
Change-Id: Ia06d73ee49881d5db2fc57545e8040ce3976a584
-rw-r--r--ripple/minitrace/src/main.rs105
1 files changed, 80 insertions, 25 deletions
diff --git a/ripple/minitrace/src/main.rs b/ripple/minitrace/src/main.rs
index 567a3c6..4bd544f 100644
--- a/ripple/minitrace/src/main.rs
+++ b/ripple/minitrace/src/main.rs
@@ -178,6 +178,65 @@ macro_rules! syscall_bitflags {
 	};
 }
 
+macro_rules! syscall_enums {
+	(
+		$(
+			enum $Enum:ident: $T:ty {
+				$(
+					$VARIANT:ident = $value:literal $(=> $LIBC_VALUE:ident)?,
+				)*
+			}
+		)*
+	) => {
+		#[test]
+		fn verify_syscall_enums() {
+			$(
+				$Enum::verify();
+			)*
+		}
+
+		$(
+			#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+			#[allow(non_camel_case_types)]
+			enum $Enum {
+				$($VARIANT = $value),*
+			}
+
+			impl SyscallArg for $Enum {
+				fn try_from_reg(reg: u64) -> Option<Self> {
+					let reg = <$T as SyscallArg>::try_from_reg(reg)?;
+					Some(match reg {
+						$(
+							$value => $Enum::$VARIANT,
+						)*
+						_ => return None
+					})
+				}
+			}
+
+			impl $Enum {
+				#[cfg(test)]
+				fn verify() {
+					$(
+						$(
+							let libc_value = stringify!($LIBC_VALUE);
+							let variant = stringify!($VARIANT);
+							assert!(libc_value.ends_with(variant), "{libc_value} doesn't end with {variant}");
+
+							let left = Self::$VARIANT as $T;
+							let right = libc::$LIBC_VALUE;
+							assert!(
+								left == right,
+								"{}::{} ({left:#x}) != libc::{} ({right:#x})", stringify!($Enum), stringify!($VARIANT), stringify!($LIBC_VALUE),
+							);
+						)?
+					)*
+				}
+			}
+		)*
+	};
+}
+
 trait ProcessSyscallArg: Sized {
 	fn try_from_process_reg(process: &Process, reg: u64) -> Option<Self>;
 }
@@ -276,20 +335,20 @@ define_syscalls! {
 		fn mprotect(addr: u64, len: usize, prot: ProtFlags) -> i64 = 10;
 		fn brk(brk: u64) -> i64 = 12;
 		fn rt_sigaction(sig: i32, act: *const SigAction, oact: *mut SigAction, sigsetsize: usize) -> i64 = 13;
-		fn ioctl(fd: FileDesc, cmd: u32, arg: u64) -> i64 = 16;
+		fn ioctl(fd: FileDesc, cmd: Ioctl, arg: u64) -> i64 = 16;
 		fn pread64(fd: FileDesc, buf: *mut u8, count: usize, pos: u64) -> i64 = 17;
 		fn access(filename: CString, mode: i32) -> i64 = 21;
 		fn getcwd(buf: *mut u8, size: u64) -> i64 = 79;
 		fn readlink(path: CString, buf: *mut u8, bufsiz: i32) -> i64 = 89;
 		fn sysinfo(info: *mut SysInfo) -> i64 = 99;
 		fn times(tbuf: *mut Tms) -> i64 = 100;
-		fn arch_prctl(option: i32, arg2: u64) -> i64 = 158;
+		fn arch_prctl(option: ArchOption, arg2: u64) -> i64 = 158;
 		fn set_tid_address(tidptr: *mut i32) -> i64 = 218;
 		fn exit_group(error_code: i32) -> i64 = 231;
 		fn openat(dfd: FileDesc, filename: CString, flags: OpenFlags, mode: u16) -> i64 = 257;
 		fn newfstatat(dfd: FileDesc, filename: CString, statbuf: *mut Stat, flags: AtFlags) -> i64 = 262;
 		fn set_robust_list(head: *mut RobustListHead, len: usize) -> i64 = 273;
-		fn prlimit64(pid: i32, resource: u32, new_rlim: *const RLimit64, old_rlim: *mut RLimit64) -> i64 = 302;
+		fn prlimit64(pid: i32, resource: ResourceLimit, new_rlim: *const RLimit64, old_rlim: *mut RLimit64) -> i64 = 302;
 		fn getrandom(ubuf: *mut u8, len: usize, flags: GrndFlags) -> i64 = 318;
 	}
 }
@@ -402,15 +461,6 @@ fn check_syscall(entry: &SyscallEntry) -> bool {
 					== MapFlags::PRIVATE;
 			}
 		}
-		SyscallEntry::ioctl { fd: _, cmd, arg: _ } => {
-			match cmd {
-				// TCGETS
-				0x5401 => {}
-				// TIOCGWINSZ
-				0x5413 => {}
-				_ => return false,
-			}
-		}
 		SyscallEntry::access {
 			ref filename,
 			mode: _,
@@ -424,13 +474,6 @@ fn check_syscall(entry: &SyscallEntry) -> bool {
 		} => {
 			println!("readlink({path:?}, ..)");
 		}
-		SyscallEntry::arch_prctl { option, arg2: _ } => {
-			match option {
-				// ARCH_SET_FS
-				0x1002 => {}
-				_ => return false,
-			}
-		}
 		SyscallEntry::set_tid_address { tidptr: _ } => {
 			println!("set_tid_address(..)");
 		}
@@ -476,18 +519,13 @@ fn check_syscall(entry: &SyscallEntry) -> bool {
 		}
 		SyscallEntry::prlimit64 {
 			pid,
-			resource,
+			resource: _,
 			new_rlim: _,
 			old_rlim: _,
 		} => {
 			if pid != 0 {
 				return false;
 			}
-
-			match resource as u32 {
-				libc::RLIMIT_AS | libc::RLIMIT_STACK | libc::RLIMIT_RSS => {}
-				_ => return false,
-			}
 		}
 		SyscallEntry::getrandom {
 			ubuf: _,
@@ -532,3 +570,20 @@ syscall_bitflags! {
 		const EMPTY_PATH = 1 << 12 => AT_EMPTY_PATH;
 	}
 }
+
+syscall_enums! {
+	enum ResourceLimit: u32 {
+		STACK = 0x3 => RLIMIT_STACK,
+		RSS   = 0x5 => RLIMIT_RSS,
+		AS    = 0x9 => RLIMIT_AS,
+	}
+
+	enum ArchOption: i32 {
+		SET_FS = 0x1002,
+	}
+
+	enum Ioctl: u64 {
+		TCGETS     = 0x5401 => TCGETS,
+		TIOCGWINSZ = 0x5413 => TIOCGWINSZ,
+	}
+}