forked from lmcad-unicamp/oi-dbt
-
Notifications
You must be signed in to change notification settings - Fork 1
/
syscall.cpp
134 lines (110 loc) · 3.34 KB
/
syscall.cpp
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
#include <syscall.hpp>
#include <iostream>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <ostream>
#include <ctime>
using namespace dbt;
static inline int64_t cpucycles(void) {
unsigned int hi, lo;
unsigned int eax = 0;
unsigned int ebx,ecx,edx;
asm volatile
( "cpuid"
: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
: "0"(0)
);
__asm__ volatile("rdtsc\n\t" : "=a"(lo), "=d"(hi));
return ((int64_t)lo) | (((int64_t)hi) << 32);
}
int LinuxSyscallManager::processSyscall(Machine& M) {
SyscallType SysTy = static_cast<SyscallType>(M.getRegister(4) - 4000);
switch (SysTy) {
case SyscallType::Exit:
ExitStatus = M.getRegister(2);
if(!ROIMode)
std::cerr << "Exiting with status " << (uint32_t) ExitStatus << " (" << M.getRegister(2) << ")\n";
return 1;
case SyscallType::Fstat: {
//int r = fstat(M.getRegister(5), (struct stat*) (M.getByteMemoryPtr() + (M.getRegister(6) - M.getDataMemOffset())));
//M.setRegister(2, r);
M.setRegister(2, -1);
return 0;
}
//GET/PUT right registers and memory locations
case SyscallType::Read:{
//fflush(stdin);
ssize_t r = read(M.getRegister(5), (M.getByteMemoryPtr() + (M.getRegister(6) - M.getDataMemOffset())), M.getRegister(7));
M.setRegister(2, r);
return 0;
}
case SyscallType::Write: {
size_t r;
if(ROIMode)
r = M.getRegister(7);
else
r = write(M.getRegister(5), (M.getByteMemoryPtr() + (M.getRegister(6) - M.getDataMemOffset())), M.getRegister(7));
M.setRegister(2, r);
return 0;
}
case SyscallType::Open: {
const char* filename = M.getByteMemoryPtr() + (M.getRegister(5) - M.getDataMemOffset());
const int flags = M.getRegister(6);
ssize_t r = -1;
if (flags == 0 || flags == 1 || flags == 2)
r = open(filename, flags);
else
r = open(filename, flags | O_CREAT, S_IRWXU);
M.setRegister(2, r);
#ifdef DEBUG
std::cerr << "Open file: " << filename << "; Flags:" << flags << " (r=" << r << ")" << std::endl;
assert(r >= 0 && "Error with file descriptor..");
#endif
return 0;
}
case SyscallType::Close: {
auto FD = M.getRegister(5);
if (FD > 2) {
ssize_t r = close(FD);
M.setRegister(2, r);
} else {
M.setRegister(2, 0);
}
return 0;
}
case SyscallType::Creat: {
const char* filename = M.getByteMemoryPtr() + (M.getRegister(5) - M.getDataMemOffset());
const int flags = M.getRegister(6);
ssize_t r = creat(filename, flags);
M.setRegister(2, r);
assert(r >= 0 && "Error with file descriptor..");
return 0;
}
//Hack for rtdsc instruction
case SyscallType::Stat: {
static int64_t cpuc = 0;
static uint32_t times = 0;
std::cout << "[" << times++ << "]: " << (cpucycles()-cpuc) << std::endl;
cpuc = cpucycles();
return 0;
}
case SyscallType::Lseek: {
//const char* filename = M.getByteMemoryPtr() + (M.getRegister(5) - M.getDataMemOffset());
//const int flags = M.getRegister(6);
ssize_t r = lseek(M.getRegister(5), M.getRegister(6), M.getRegister(7));
M.setRegister(2, r);
assert(r >= 0 && "Error with file descriptor..");
return 0;
}
default:
std::cerr << "Syscall (" << SysTy << ") not implemented!\n";
exit(2);
break;
}
return 0;
}