jasonwhite / jasonwhite/syscalls

Architecture-independent `syscall_map` macro

Open
#30 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement up for grabs
Dominant language
Rust
Stars
141
Forks
23
PR merge metrics
No merged PRs in 30d

Description

Among the syscall tables for each architecture, there is quite a lot of overlap. That is, many of the syscalls are used by all architectures. Relatively few syscalls only exist in one or several architectures.

There is a common pattern of wanting to create a mapping of all possible syscalls in all architectures to some type `T`, but we don't want to have to figure out which architectures a particular syscall is valid on.

`syscalls-gen` can programmatically figure out which syscalls are common among all architectures (even if they have different numbers) and which ones are architecture-specific.

## `syscall_map` macro

Using this information, we should be able to create a macro that is used like this:

```rust
static SYSCALL_DESCRIPTIONS: SysnoMap<&'static str> = syscall_map! {
pipe => "ceci n'est pas une pipe",
pipe2 => "ceci est une pipe",
};
```

In this example, `pipe` is not available on `aarch64`, but `pipe2` is available on all architectures, so the following code should be generated:
```rust
static SYSCALL_DESCRIPTIONS: SysnoMap<&'static str> = SysnoMap::from_slice(&[
#[cfg(not(any(target_arch = "aarch64")))]
(Sysno::pipe, "ceci n'est pas une pipe"),
(Sysno::pipe2, "ceci est une pipe"),
]);
```

## `syscall_map_for_arch` macro

To support architectures that are not for the current target architecture, then the following macro could also be created:
```rust
static SYSCALL_DESCRIPTIONS: SysnoMap<&'static str> = syscall_map_for_arch!(aarch64, {
pipe => "ceci n'est pas une pipe",
pipe2 => "ceci est une pipe",
});
```
Which would generate the following code:
```rust
static SYSCALL_DESCRIPTIONS: ::syscalls::aarch64::SysnoMap<&'static str> = ::syscalls::aarch64::SysnoMap::from_slice(&[
(::syscalls::aarch64::Sysno::pipe2, "ceci est une pipe"),
]);
```
Of course, this will require `SysnoMap` to be supported on all architectures simultaneously. See #21 for why this is tricky without `const fn` in traits.

## Implementation Details

These macros should probably be procedural macros because it will make the implementation easier.

The architecture metadata can be generated one time by `syscalls-gen`. The result could simply be a mapping like:
```rust
[
("pipe", ["x86", "x86_64", /* ... */]),
("pipe2", ["aarch64", "x86", "x86_64", /* ... */]),
// ...
]
```
The proc macro can then use this info to generate the `SysnoMap` that we want.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the architecture metadata generated by syscalls-gen and the existing SysnoMap support, then examine how procedural macros could consume it for current and non-current architectures. Done means syscall_map and syscall_map_for_arch generate architecture-aware SysnoMap entries for the pipe and pipe2 examples across supported architectures.

Written by the indexing model from the issue text.

Assessment

Tech stack
linux, rust
Domain
operating-systems, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.