syscalls icon indicating copy to clipboard operation
syscalls copied to clipboard

[Emulator] Not able to create SysnoMap for Multi Arch using Syscalls::arch::Sysno

Open umarfarook882 opened this issue 2 years ago • 1 comments

Sample Code

let mut map = SysnoMap::<fn() -> i32>::new();
let sys_no = syscalls::x86::Sysno::from(0x10);
map.insert(sys_no, || 1);

Error: expected enum `syscalls::Sysno`, found enum `syscalls::x86::Sysno

umarfarook882 avatar Mar 11 '24 10:03 umarfarook882

Yeah, this is unfortunate. The reason for this essentially boils down to Rust missing const fn in traits (as well as other restrictions around const).

Ideally, the SysnoSet and SysnoMap struct definitions would look something like this:

pub struct SysnoSet<S: SysnoExt = Sysno> {
    data: [usize; S::TABLE_SIZE],
}

pub struct SysnoMap<V, S: SysnoExt = Sysno> {
    // ...
}

the impl of this version of SysnoSet will need to have this vital function:

impl<S: SysnoExt> SysnoSet<S> {
    const fn get_idx_mask(sysno: S) -> (usize, usize) {
        let bit = (sysno.id() as usize) - (S::first().id() as usize);
        (bit / Self::WORD_WIDTH, 1 << (bit % Self::WORD_WIDTH))
    }
}

In order for this to work, we'd need to define SysnoExt like this:

trait SysnoExt {
    // [other stuff]...

    // Doesn't compile:
    const fn id(&self) -> u32;
}

but that doesn't work because Rust doesn't support const fn in traits. Efforts to support this also seem to be a long way off.

const fn in traits wouldn't be needed if SysnoSet and SysnoMap wasn't needed in const contexts, but it has been pretty useful to have (e.g., global static initialization).


An alternative implementation could be to use a macro to stamp out an implementation for each architecture, like this:

  • impl SysnoSet<syscalls::x86::Sysno>
  • impl SysnoSet<syscalls::x86_64::Sysno>
  • impl SysnoSet<syscalls::aarch64::Sysno>
  • etc.

I think this is acceptable until const fn in traits exists.

jasonwhite avatar Mar 13 '24 02:03 jasonwhite