This kernel implementation of RPC mechanism.
Data Structures | |
struct | RPC_Service_t_ |
Basic structure of any RPC object. More... | |
Macros | |
#define | E_VTABLE_UNKNOWN 0xFF |
Constant denoting unknown owning process ID of VTable. | |
Typedefs | |
typedef struct RPC_Service_t_ | RPC_Service_t |
typedef int(* | RPC_Method_t) (RPC_Service_t *service, unsigned arg0, unsigned arg1, unsigned arg2, unsigned arg3) |
Calling signature of a RPC call. | |
typedef RPC_Method_t * | VTable_t |
Type definition of VTable. | |
Functions | |
Process_t | get_vtable_process (VTable_t *vtable) |
Identify process which owns the VTable. | |
bool | rpc_stack_push (Process_t process_id) |
Add new process ID to the stack of RPC calls. | |
int | rpc_stack_pop () |
Remove the last entry in the RPC stack. | |
Process_t | rpc_stack_top () |
Retrieve the topmost process ID in thread's RPC call stack. | |
int | os_rpc_call (uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3) |
Kernel implementation of rpc_call syscall. | |
int | os_rpc_return (uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3) |
Kernel implementation of rpc_return syscall. | |
#define E_VTABLE_UNKNOWN 0xFF |
Constant denoting unknown owning process ID of VTable.
typedef int(* RPC_Method_t) (RPC_Service_t *service, unsigned arg0, unsigned arg1, unsigned arg2, unsigned arg3) |
Calling signature of a RPC call.
Any function that wants to implement a RPC call has to have this signature. If function won't have use for any of arg0
, arg1
, arg2
, arg3
, they can be omitted right-to-left. The argument service
cannot be omitted and its position as the first argument has to be maintained. RPC calls are limited to use the general purpose registers only. Floating point registers cannot be used as it might not be possible to determine which registers were actually used to pass the arguments. This restricts the use of floating-point types to perform RPC calls.
service | Address of RPC object which was used to perform this RPC call. Works like self` variable in Python. |
arg0 | optional argument to RPC call. Can only be of integral 32-bit large type |
arg1 | optional argument to RPC call. Can only be of integral 32-bit large type |
arg2 | optional argument to RPC call. Can only be of integral 32-bit large type |
arg3 | optional argument to RPC call. Can only be of integral 32-bit large type |
typedef struct RPC_Service_t_ RPC_Service_t |
typedef RPC_Method_t* VTable_t |
Type definition of VTable.
VTable is technically just an array of pointers to functions. To make things more user friendly, in real world cases, VTables are usually a structures whose members are pointers to functions. The memory layout of both cases is the same but structures allows for named members.
Identify process which owns the VTable.
This function will find the process which defined this vtable.
vtable | address of the vtable retrieved from the RPC object. |
int os_rpc_call | ( | uint32_t | arg0, |
uint32_t | arg1, | ||
uint32_t | arg2, | ||
uint32_t | arg3 | ||
) |
Kernel implementation of rpc_call syscall.
This routine performs remote procedure call. It digs for 5th and 6th argument passed to _rpc_call() on thread stack. Retrieves address of called method from service VMT and synthesizes stack frame for jumping into this method. Arguments used to call _rpc_call() are passed to callee.
This syscall has to validate the RPC service and method IDs, determine the address of RPC method and owning process. Then it has to transfer the control to RPC method in a manner that:
int os_rpc_return | ( | uint32_t | arg0, |
uint32_t | arg1, | ||
uint32_t | arg2, | ||
uint32_t | arg3 | ||
) |
Kernel implementation of rpc_return syscall.
This routine unwinds stack frame used to call RPC method and passes return value from RPC to the caller.
This syscall has to return the control back to the code which called rpc_call. This has to be done in a way that the calling code will be able to access the return value of the RPC method.
int rpc_stack_pop | ( | ) |
Remove the last entry in the RPC stack.
Removes the most recently added entry from thread's stack of RPC call owning processes. Will do nothing if stack is already empty.
bool rpc_stack_push | ( | Process_t | process_id | ) |
Add new process ID to the stack of RPC calls.
Registers new process ID in thread's stack of RPC call owning processes. This stack records which process is "owning" this thread while RPC call is in effect. While RPC call can technically perform another RPC call, this is a stack rather than plain field. New member is always added on top of the stack unless stack is full.
process_id | ID of the process owning the RPC method |
Process_t rpc_stack_top | ( | ) |
Retrieve the topmost process ID in thread's RPC call stack.
Returns the process ID of the most recently added entry in thread's stack of RPC call owning processes.