1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#include "syscall.h"
#include "object.h"
#include "handles.h"
#include "device/processor.h"
#include "print.h"
#include "error.h"
#include "lock.h"
#include "memory.h"
#include <stdint.h>
#include <stddef.h>
extern int _syscall_handler_arch(objdir_t *root_dir, objdir_entry_t *target, uint8_t *payload, size_t payload_at);
static inline int
s_invoke_release(
objdir_t *root_dir,
objdir_entry_t *target,
uint8_t *payload,
size_t payload_at,
int (*invoke)(objdir_t*, objdir_entry_t*, uint8_t*, size_t))
{
int e = invoke(root_dir, target, payload, payload_at);
return e;
}
static int
s_syscall_handle_invoke(objdir_t *root_dir, uint8_t *payload)
{
size_t payload_at = 0;
size_t target_pathw;
objdir_entry_t *target_entry;
SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, target_pathw, target_entry);
switch(target_entry->type) {
case KO_NONE:
return -KE_BADOBJ;
case KO_OBJECT_DIRECTORY:
return s_invoke_release(root_dir, target_entry, payload, payload_at, syscall_handle_invoke_objdir);
case KO_MEMORY_UNTYPED:
return s_invoke_release(root_dir, target_entry, payload, payload_at, syscall_handle_invoke_untyped);
case KO_MEMORY_MAPPING:
return s_invoke_release(root_dir, target_entry, payload, payload_at, syscall_handle_invoke_mapping);
default:
return _syscall_handler_arch(root_dir, target_entry, payload, payload_at);
}
}
int
_syscall_handler(uintmax_t argsi, int calli)
{
objdir_t *root_dir = ((processor_t*)processor_current())->odir;
objdir_entry_t *payload_entry = objdir_seek(root_dir, (uint8_t*)&argsi, sizeof(uintmax_t));
if(payload_entry->type != KO_MESSAGE) {
klogf("Tried to invoke syscall %i with invalid object %x\n", calli, argsi);
return -KE_BADMSG;
}
mtx_acquire(&payload_entry->lock);
uint8_t *payload = ko_entry_data(payload_entry);
switch(calli) {
case SYSCALL_INVOKE: {
int e = s_syscall_handle_invoke(root_dir, payload);
mtx_release(&payload_entry->lock);
return e;
}
case SYSCALL_DEBUG_PUTC:
kprintf("%c", (char)payload[0]);
mtx_release(&payload_entry->lock);
return 0;
default:
klogf("Invalid syscall %i caught! Failing.\n", calli);
mtx_release(&payload_entry->lock);
return -KE_BADCALL;
}
}
|