jasonwhite / jasonwhite/syscalls
Support for syscall metadata such as the argument map
- Dominant language
- Rust
- Stars
- 141
- Forks
- 23
- PR merge metrics
- No merged PRs in 30d
Description
I am working on improving [lurk](https://github.com/JakWai01/lurk) -- an `strace` Rust rewrite. At the moment, lurk's author @JakWai01 has created a big manual map for the x86_64 syscalls, but the approach is very [hard to maintain](https://github.com/JakWai01/lurk/blob/main/src/system_call_names.rs) and does not support any other architectures.
The required metadata would be:
* how many arguments each syscall has
* the types of each argument: `str`, `int`, `address`, ...?
* syscall return type: `Error(i32)`, `Success(i32)`, `Address(usize)`, ...?
* possibly some "group" that describe what each syscall belongs to: `File`, `IPC`, `Memory`, `Creds`, ...
The groups are a bit tricky as I am not certain if Linux officially describes each syscall in terms of which group(s) it belongs to - so this might be omitted.
We can use a `macro_rule!` (or even a proc macro) to improve `syscall_enum!` (adapting from [a table](https://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/))
```rust
syscall_enum! {
pub enum Sysno {
/// See [read(2)](https://man7.org/linux/man-pages/man2/read.2.html) for more info on this syscall.
#[params = "(fd: i32, buf: str, count: usize) -> isize", categories = ["desc"]]
read = 0,
/// See [write(2)](https://man7.org/linux/man-pages/man2/write.2.html) for more info on this syscall.
#[params = "(fd: i32, buf: str, count: usize) -> isize", categories = ["desc"]]
write = 1,
/// See [open(2)](https://man7.org/linux/man-pages/man2/open.2.html) for more info on this syscall.
#[params = "(pathname: str, flags: i32, mode: u32) -> isize", categories = ["desc", "file"]]
open = 2,
```
The actual syntax for the arguments could be different to simplify macro_rules processing (proc_macros are much harder to implement and maintain).
A macro could parse these params into a few extra functions:
```rust
// sequentially store all arguments for all syscalls
static ALL_ARGS: [ArgType; 2500] = [
ArgType {name: "fd", typ: i32},
ArgType {name: "buf", typ: str},
ArgType {name: "count", typ: usize},
ArgType {name: "fd", typ: i32},
ArgType {name: "buf", typ: str},
ArgType {name: "count", typ: usize},
ArgType {name: "pathname", typ: str},
ArgType {name: "flags", typ: i32},
ArgType {name: "mode", typ: u32},
...
];
lazy_static! {
static ref ARG_MAP: [&[ArgType]; 450] = [
ALL_ARGS[0..3], // read
ALL_ARGS[3..6], // write
ALL_ARGS[6..9], // open
...
];
}
/// Auto-generated function
pub fn get_arguments(syscall: usize) -> &[ArgType] {
ARG_MAP[syscall]
}
```
We would also generate lists for categories and return types - TBD of the exact format.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at the existing syscall_enum! definition and compare its current representation with lurk/src/system_call_names.rs and the linked x86_64 syscall table. Define the metadata representation and architecture scope before implementing macro-generated accessors for argument maps, return types, and optional categories; done means these are available for the supported syscall data and verified by tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- operating-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100