The largest component of the Linux API/ABI that must be supported is the set of system call interfaces. For true ABI compatibility this must be supported by performing system call trap reflections from the code making the Linux system call to the implementation of the system call. In K42, the functions that implement system calls reside within exec.so, a pre-loaded library within the process described in Section 4.2.
Support for the trap reflection mechanism is intended for strict compatibility. We have designed but not yet implemented this mechanism. In general, we expect applications running on K42 to use a version of the GNU C Library (glibc) targeted for K42 to obtain access to the Linux system call interface without using trap reflection. Most applications gain access to Linux system call interfaces via glibc wrapper functions that present a C interface thereby hiding the architecture specific details of making a system call. Glibc provides a mechanism that allows different architecture targets to define how these wrapper functions work. This is accomplished by providing the assembly-level mechanisms for making system calls. Except for this low-level assembly system call interface level, K42 reuses all of glibc. We have developed a glibc targeted for K42 that efficiently accesses the implementations of system calls within a process. We use the system call number as an index into a system-call transfer-table. This table is at a well-known location and contains the address of the function that implements a particular system call. In effect, we short-circuit the normal trap-reflection and simply jump to the correct function.
The system-call transfer-table permits us to handle Linux system calls within an application, but at the same time avoids the need for us to explicitly link applications against K42 code. As a result, dynamically linked PowerPC64 Linux binaries that use glibc wrappers to make system calls run without modification. Applications linked against a static non-K42 glibc still require trap reflection.
As previously noted, in K42 we have moved kernel functionality into the application's address space. This includes some of the processing for system calls. Moving this code into the application's address space does not sacrifice security. The portion of the system call that is handled in the user's address space is the part that is allowed by the Linux credentials the user had. The model enforces calling privileged servers to perform requests where the user credentials are insufficient. Under either model, users can cause incorrect behavior (e.g., if an application has read/write access to a file one thread may remove the file another thread is attempting to write). This model does introduce additional places where the user may "shoot themselves in the foot", but it does not sacrifice security.
When a thread makes a Linux system call, a wrapper object in our Linux emulation layer is invoked. At this point, the thread is marked as being in a system call. This code is re-entrant allowing additional calls from within the process. If a signal is delivered to a thread in this state, it is deferred until the return from the outermost level of system call. The thread will not block when it is in this state, but instead will return out of the system call layer and then block.