Archive for the ‘Ada’ Category

Ada System Calls: mmap and stat

Monday, December 24th, 2018

This release of Ada system calls vtree finally contains the code.

I followed diana_coman's advice on shaping the vtree: first vpatch in the tree after genesis (common_api.vpatch) adds common functionality: constant declarations are all initialized to zero, the type definitions are set to reasonable defaults for 64-bit platforms, functions that invoke system calls return zero1.

The branches for each platform are built on top of common_api node. The *_platform vpatches add correct values to each kernel-defined constants and provide code for the system call invocation functions. To pass arguments to these functions, I convert them to the form suitable for passing over system call interface in the To_Argument function.

Initially I tried to use Ada generics for system call invocation function, which would make To_Argument class of functions unnecessary. This approach did not work because the inline assembly code could not be made generic over the size of argument. Eventually I did solve the problem, but the result was rather ugly and worked only because of the way GCC works with inline assembly2. I have decided against this approach.

*_stat vpatches add 'struct stat' record, system call code, necessary types, and system call wrapper for each platform. The structure is defined as in C, making use of 'pragma Convention(C, Stat)' to force the record in C-prescribed layout. An alternative would be use record representation clause, but this would make the record definition more error-prone.

Some implementation details may cause complaints:

  • In the provided system call wrappers, I make use of Ada functions with output specifier for the Errno value. I can switch the wrappers to procedures rather than functions if people consider current code ugly.
  • Unchecked_Conversion in two of the From_Return functions. I can eliminate at the cost of more Ada code3.
  • I have changed types for flags argument from int to unsigned long where flags are 'or'ed together. Ada forbids bitwise operations on non-modular types, so I could not find a better way to handle it.

The functionality in the library so far is enough to create, mmap, and delete a file. Further functionality will be added later4.

The vpatches and seals are available here:

curl 'http://bvt-trace.net/vpatches/syscalls_genesis.vpatch' > syscalls_genesis.vpatch
curl 'http://bvt-trace.net/vpatches/common_api.vpatch' > common_api.vpatch
curl 'http://bvt-trace.net/vpatches/amd64_platform.vpatch' > amd64_platform.vpatch
curl 'http://bvt-trace.net/vpatches/amd64_stat.vpatch' > amd64_stat.vpatch
curl 'http://bvt-trace.net/vpatches/arm64_platform.vpatch' > arm64_platform.vpatch
curl 'http://bvt-trace.net/vpatches/arm64_stat.vpatch' > arm64_stat.vpatch
curl 'http://bvt-trace.net/vpatches/syscalls_genesis.vpatch.bvt.sig' > syscalls_genesis.vpatch.bvt.sig
curl 'http://bvt-trace.net/vpatches/common_api.vpatch.bvt.sig' > common_api.vpatch.bvt.sig
curl 'http://bvt-trace.net/vpatches/amd64_platform.vpatch.bvt.sig' > amd64_platform.vpatch.bvt.sig
curl 'http://bvt-trace.net/vpatches/amd64_stat.vpatch.bvt.sig' > amd64_stat.vpatch.bvt.sig
curl 'http://bvt-trace.net/vpatches/arm64_platform.vpatch.bvt.sig' > arm64_platform.vpatch.bvt.sig
curl 'http://bvt-trace.net/vpatches/arm64_stat.vpatch.bvt.sig' > arm64_stat.vpatch.bvt.sig
curl 'http://wot.deedbot.org/6CF3EFF892A7F23E7E798E5EBA6B8C054B962B68.asc' > bvt.asc
  1. It also adds a restrict.adc from FFA with one notable exception: Unchecked_Conversion is allowed. I make use of it to cast unsigned int/long to a signed type. []
  2. GCC internally compiles C/C++/Ada code to textual assembly representation. Inline assembly is passed to the assembler as-is. My code exploited dead code elimination to kill the branch which would make assembler error out. []
  3. I have checked that the assembly code would stay the same if I compute the signed value using arithmetic operations. []
  4. Including rather important msync/munmap system calls. []