I think this is a good discussion for Friday, but I wanted to send out an
advance email to give time for people to gather their thoughts in advance
The current set of return codes include a type. e.g. calls like allow/brk
currently return SyscallReturnU32U32 or SyscallReturnU32. Clearly this is
not true for 64-bit platforms. Or for CHERI where the size of an address is
not the size of a pointer.I think there are a few options:
1. 1) They should return different codes on different platforms:
SyscallReturnu32 on 32-bit, SyscallReturnu64on 64-bit,
SyscallReturnMetaPtr on CHERI etc with some meta constructors to help
choose. Userspace should expect the same and be If-Defed appropriately.
2. 2) They should return a new more specific code SyscallReturnPtr /
SyscallReturnUsize on all platforms, and user space should check for
just that one.e
3. 3) These calls are already made type safe because of the wrappers in
libtock-c / libtock-rs. Just use SyscallSuccess for these built in
syscalls. Wrappers know what they are getting.
4. 4) A true evil one. Option 3, but SyscallReturnu32 is the code for
legacy reasons. You know what you are actually getting.
What I actually did on my fork was just 3 (because all these different
codes were getting in the way), but this does break compatibility unless
there is a matching change in libtock-c/libtock-rs and it would probably be
better not to do so. In fact, both 2 and 3 are breaking API changes. This
means that possibly we should prefer (1), simply for backwards
compatibility? This is roughly what the consttructor I added for
SyscallReturnUsize does: selects one of SyscallReturnu32 or
SyscallReturnu64 as appropriate. But possibly we will need a few more as
soon as CHERI comes into play.As for types for commands:Currently in the
kernel commands are:fn command(&self, cmd_num: usize, arg1: usize, arg2:
usize, appid: ProcessId)
Which is already usize-ified.In libtock-c: syscall_return_t
command(uint32_t driver, uint32_t command, size_t arg1, size_t arg2);
There is clearly a mismatch there on command number. I am of the mind that
the driver/command being u32 is fine, and args should really be usize. For
instance, a command might realistically take an offset to a previously
allowed buffer. This is usize, not u32.Upcalls: in the kernel were all u32,
I changed most of the arguments usize apart from data/fn pointer which are
MetaPtr. i.e., the type in C should be:typedef void
(subscribe_upcall)(size_t, size_t, size_t, void*);where currently it istypedef
void (subscribe_upcall)(int, int, int, void*);And I think its worth some
discussion whether people are happy with this. It means nothing for 32-bit
libtock-c because the ABI for passing usize is the same as int on 32-bit
platforms. In libtock-rs I have the patches ready to go to define the
upcall trait on both u32 and usize so it won't break any code there.
Lawrence