-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkernel.cpp
More file actions
93 lines (81 loc) · 2.13 KB
/
kernel.cpp
File metadata and controls
93 lines (81 loc) · 2.13 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "kernel.h"
#include "process.h"
syscall_t LinuxKernel::m_syscalls[] =
{
#include "syscalltable.h"
};
LinuxKernel::LinuxKernel(Line* line) : Logger("LinuxKernel")
{
m_process = NULL;
m_line = line;
}
LinuxKernel::~LinuxKernel()
{
}
bool LinuxKernel::syscall(uint64_t syscall, ucontext_t* ucontext)
{
if (syscall >= (sizeof(m_syscalls) / sizeof(syscall_t)))
{
log("LinuxKernel::syscall: Invalid syscall: %lld at %p", syscall, (void*)ucontext->uc_mcontext->__ss.__rip);
m_process->printregs(ucontext);
exit(255);
}
#ifdef DEBUG
log("LinuxKernel::syscall: %lld, rip=%p", syscall, ucontext->uc_mcontext->__ss.__rip);
#endif
bool res = (this->*m_syscalls[syscall])(syscall, ucontext);
if (!res)
{
error("LinuxKernel::syscall: syscall failed: %lld at %p", syscall, (void*)ucontext->uc_mcontext->__ss.__rip);
exit(255);
}
return true;
}
SYSCALL_METHOD(notimplemented)
{
log("Unimplemented syscall: %llu", syscall);
return false;
}
void LinuxKernel::syscallErrnoResult(ucontext_t* ucontext, uint64_t res, bool success, int err)
{
#ifdef DEBUG_RESULT
log("syscallErrnoResult: res=%d, err=%d", res, err);
#endif
if (success)
{
ucontext->uc_mcontext->__ss.__rax = res;
}
else
{
int64_t linux_errno = err;
if (err == EAGAIN)
{
linux_errno = LINUX_EAGAIN;
}
if (err == ENOTEMPTY)
{
linux_errno = LINUX_ENOTEMPTY;
}
else if (err <= 34)
{
// Most of the first 34 errnos are the same
linux_errno = err;
}
else
{
error("syscallErrnoResult: Unhandled errno: %d", err);
exit(1);
}
ucontext->uc_mcontext->__ss.__rax = (uint64_t)(-linux_errno);
#ifdef DEBUG_RESULT
log("syscallErrnoResult: Returning: %d (%llx)", linux_errno, ucontext->uc_mcontext->__ss.__rax);
#endif
}
#ifdef DEBUG_RESULT
log("syscallErrnoResult: Returning: %d", ucontext->uc_mcontext->__ss.__rax);
#endif
}