tock / libtock-rs

Rust userland library for Tock
Apache License 2.0
168 stars 109 forks source link

Initial memop syscall implementation + tests #554

Closed hudson-ayers closed 3 months ago

hudson-ayers commented 4 months ago

This PR adds memop syscalls corresponding to memop 0, 1, 2, 10, and 11 to libtock-rs. Any instances where the underlying raw system calls were being used to call memop are migrated to the safe higher level syscall APIs as possible. This PR also adds a function to libtock-runtime for retrieving the value of _heap_start as set by the linker.

This PR also builds out some initial infrastructure for unit tests to include the memop syscall, and some tests of the system call implementation itself. This was definitely the trickier part of this PR. Because many of these memop APIs need to accept pointers for argument0, and because the unit tests include Miri's strict provenance tests, I modified the expected syscall type and the syscall log type to use the "Register" type for memop argument0, enabling tests to pass pointers to actual buffers without Miri complaining or without tests failing on 64 bit systems. Another tricky aspect of getting these tests right is that memop is the only system call which uses two different underlying raw system calls (syscall1 and syscall2 in this case). That makes the system call logging etc. a little weird -- I chose to still use a single type, and just follow a convention where I always pass 0 as the second argument when testing any memop calls that will use syscall1 under the hood, but I am open to suggestions for improvement there as well.

This PR has not yet been tested on hardware, but I wanted to go ahead and open this PR so I could get feedback on the unit test infrastructure. I will test on hardware shortly when I am back in the bay area.

hudson-ayers commented 4 months ago

I tested this on nrf52840dk and the console example runs fine and the fault output looks right if I fault it using the process console:

 ╔═══════════╤══════════════════════════════════════════╗
 ║  Address  │ Region Name    Used | Allocated (bytes)  ║
 ╚0x20011000═╪══════════════════════════════════════════╝
             │ Grant Ptrs      120
             │ Upcalls         320
             │ Process         668
  0x20010BAC ┼───────────────────────────────────────────
             │ ▼ Grant          76
  0x20010B60 ┼───────────────────────────────────────────
             │ Unused
  0x20010100 ┼───────────────────────────────────────────
             │ ▲ Heap            0 |   2656               S
  0x20010100 ┼─────────────────────────────────────────── R
             │ Data              0 |      0               A
  0x20010100 ┼─────────────────────────────────────────── M
             │ ▼ Stack         184 |    256
  0x20010048 ┼───────────────────────────────────────────
             │ Unused
  0x20010000 ┴───────────────────────────────────────────
             .....
  0x00040800 ┬─────────────────────────────────────────── F
             │ App Flash      1920                        L
  0x00040080 ┼─────────────────────────────────────────── A
             │ Protected       128                        S
  0x00040000 ┴─────────────────────────────────────────── H
hudson-ayers commented 4 months ago

Given the safety requirements for memop_brk and sbrk, is there an argument to be made we should also have memop_pbrk (I don't know if p is good, but "positive" brk)? I know it's not conventional, but the existing conventions weren't designed for Rust. I'm not sure how brk is going to be used in libtock-rs, but we aren't linking with newlib, and it seems like we typically allocate and not deallocate.

Or could pbrk potentially be unsafe too?

I believe pbrk would be safe -- we had a similar function in libtock-rs 1.0. I think that is probably a good idea to add, actually, though maybe with a different name. I will get to that soon

hudson-ayers commented 4 months ago

Added a safe memop_increment_brk() and one test for it.