reverie-rs / reverie

trace and intercept linux syscalls.
Other
14 stars 5 forks source link

tools_helper: granular means of overloading just a few syscalls in a type-safe way #43

Open rrnewton opened 5 years ago

rrnewton commented 5 years ago

This was mentioned in #41, but breaking it out here. This is not urgent, but I'd like to discuss the API / get suggested improvements.

Let's suppose the user only wants to override a couple syscalls, {read,write}. Rather than building their own switch statement inside captured_syscall, and having an essentially untyped argument list, wouldn't it be better if they instead created a trait impl and defined only the read/write we're interested in? Further, we would use more strongly typed signatures when doing so.

The idea is that trait-provided methods would provide defaults, including the big fat captured_syscall definition which would have a giant switch statement dispatching to all the specific methods of the trait.

trait SyscallInterceptor {
  fn read (&self, fd, buf, count) -> isize {  
    untraced_syscall(..)
  }
  ... 
  fn g_cap_syscall(self, no,a0,a1,a2,a3,a4,a5) -> i64 {
   // giant match...
    match from(_no) {
      SYS_read => { self.read(..); } 
      ...
    }
  }
}

Then, to define our own instrumentation tool that intercepts just read/write, we would have to impl the above trait and replace only those default read/write methods of interest.

impl SyscallInterceptor for MyType {
  fn read(..) { ... };
  fn write(..) { ... };
}

(Ideally, we would also configure the instrumentation at initialization so that it never traps on the other events we're not interested in anyway.)

To wire things up, we'd need to compile a cdylib that export captured_syscall as usual, but directly calls the generic g_cap_syscall above.