forked from includeos/IncludeOS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsyscalls.cpp
More file actions
227 lines (188 loc) · 5.02 KB
/
syscalls.cpp
File metadata and controls
227 lines (188 loc) · 5.02 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <fcntl.h> // open()
#include <string.h>
#include <signal.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <kernel/os.hpp>
#include <kernel/syscalls.hpp>
#include <kernel/rtc.hpp>
#include <hw/acpi.hpp>
#include <statman>
char* __env[1] {nullptr};
char** environ {__env};
extern "C" {
uintptr_t heap_begin;
uintptr_t heap_end;
}
static const int syscall_fd {999};
static bool debug_syscalls {true};
static uint32_t& sbrk_called {Statman::get().create(Stat::UINT32, "syscalls.sbrk").get_uint32()};
void _exit(int) {
default_exit();
}
int close(int) {
panic("SYSCALL CLOSE NOT SUPPORTED");
return -1;
}
int execve(const char*,
char* const*,
char* const*)
{
panic("SYSCALL EXECVE NOT SUPPORTED");
return -1;
}
int fork() {
panic("SYSCALL FORK NOT SUPPORTED");
return -1;
}
int fstat(int, struct stat* st) {
debug("SYSCALL FSTAT Dummy, returning OK 0");
st->st_mode = S_IFCHR;
return 0;
}
int getpid() {
debug("SYSCALL GETPID Dummy, returning 1");
return 1;
}
int isatty(int file) {
if (file == 1 || file == 2 || file == 3) {
debug("SYSCALL ISATTY Dummy returning 1");
return 1;
}
// Not stdxxx, error out
panic("SYSCALL ISATTY Unknown descriptor ");
errno = EBADF;
return 0;
}
int link(const char*, const char*) {
panic("SYSCALL LINK unsupported");
return -1;
}
int unlink(const char*) {
panic("SYSCALL UNLINK unsupported");
return -1;
}
off_t lseek(int, off_t, int) {
panic("SYSCALL LSEEK returning 0");
return 0;
}
int open(const char*, int, ...) {
panic("SYSCALL OPEN unsupported");
return -1;
}
int read(int, void*, size_t) {
panic("SYSCALL READ unsupported");
return 0;
}
int write(int file, const void* ptr, size_t len) {
if (file == syscall_fd and not debug_syscalls) {
return len;
}
return OS::print((const char*) ptr, len);
}
void* sbrk(ptrdiff_t incr) {
// Stat increment syscall sbrk called
sbrk_called++;
if (UNLIKELY(heap_end + incr > OS::heap_max())) {
errno = ENOMEM;
return (void*)-1;
}
auto prev_heap_end = heap_end;
heap_end += incr;
return (void*) prev_heap_end;
}
int stat(const char*, struct stat *st) {
debug("SYSCALL STAT Dummy");
st->st_mode = S_IFCHR;
return 0;
}
clock_t times(struct tms*) {
panic("SYSCALL TIMES Dummy, returning -1");
return -1;
}
int wait(int*) {
debug((char*)"SYSCALL WAIT Dummy, returning -1");
return -1;
}
int gettimeofday(struct timeval* p, void*) {
p->tv_sec = RTC::now();
p->tv_usec = 0;
return 0;
}
int kill(pid_t pid, int sig) {
printf("!!! Kill PID: %i, SIG: %i - %s ", pid, sig, strsignal(sig));
if (sig == 6ul) {
printf("/ ABORT\n");
}
panic("\tKilling a process doesn't make sense in IncludeOS. Panic.");
errno = ESRCH;
return -1;
}
static const size_t CONTEXT_BUFFER_LENGTH = 0x1000;
static char _crash_context_buffer[CONTEXT_BUFFER_LENGTH] __attribute__((aligned(0x1000)));
size_t get_crash_context_length()
{
return CONTEXT_BUFFER_LENGTH;
}
char* get_crash_context_buffer()
{
return _crash_context_buffer;
}
// No continuation from here
void panic(const char* why) {
printf("\n\t**** PANIC: ****\n %s\n", why);
// the crash context buffer can help determine cause of crash
int len = strnlen(get_crash_context_buffer(), CONTEXT_BUFFER_LENGTH);
if (len > 0) {
printf("\n\t**** CONTEXT: ****\n %*s\n\n",
len, get_crash_context_buffer());
}
// heap and backtrace info
extern char _end;
printf("\tHeap end: %#x (heap %u Kb, max %u Kb)\n",
heap_end, (uintptr_t) (heap_end - heap_begin) / 1024, (uintptr_t) heap_end / 1024);
print_backtrace();
// shutdown the machine
hw::ACPI::shutdown();
while (1) asm("cli; hlt");
}
// Shutdown the machine when one of the exit functions are called
void default_exit() {
hw::ACPI::shutdown();
while (1) asm("cli; hlt");
}
// To keep our sanity, we need a reason for the abort
void abort_ex(const char* why) {
panic(why);
}
// Basic second-resolution implementation - using CMOS directly for now.
int clock_gettime(clockid_t clk_id, struct timespec* tp) {
if (clk_id == CLOCK_REALTIME) {
tp->tv_sec = RTC::now();
tp->tv_nsec = 0;
return 0;
}
return -1;
}
extern "C" void _init_syscalls();
void _init_syscalls()
{
// make sure that the buffers length is zero so it won't always show up in crashes
_crash_context_buffer[0] = 0;
}