Skip to content

Support for syscall metadata such as the argument map #27

@nyurik

Description

@nyurik

I am working on improving 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 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)

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:

// 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions