Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
script3r
GitHub Repository: script3r/os161
Path: blob/master/user/testbin/crash/crash.c
734 views
1
/*
2
* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3
* The President and Fellows of Harvard College.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. Neither the name of the University nor the names of its contributors
14
* may be used to endorse or promote products derived from this software
15
* without specific prior written permission.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*/
29
30
/*
31
* crash.c
32
*
33
* Commit a variety of exceptions, primarily address faults.
34
*
35
* Once the basic system calls assignment is complete, none of these
36
* should crash the kernel.
37
*
38
* They should all, however, terminate this program, except for the
39
* one that writes to the code segment. (That one won't cause program
40
* termination until/unless you implement read-only segments in your
41
* VM system.)
42
*/
43
44
#include <stdio.h>
45
#include <stdint.h>
46
#include <unistd.h>
47
#include <err.h>
48
49
#if defined(__mips__)
50
#define KERNEL_ADDR 0x80000000
51
#define INVAL_ADDR 0x40000000
52
#define INSN_TYPE uint32_t
53
#define INVAL_INSN 0x0000003f
54
#else
55
#error "Please fix this"
56
#endif
57
58
typedef void (*func)(void);
59
60
static
61
void
62
read_from_null(void)
63
{
64
int *null = NULL;
65
volatile int x;
66
x = *null;
67
}
68
69
static
70
void
71
read_from_inval(void)
72
{
73
int *ptr = (int *) INVAL_ADDR;
74
volatile int x;
75
x = *ptr;
76
}
77
78
static
79
void
80
read_from_kernel(void)
81
{
82
int *ptr = (int *) KERNEL_ADDR;
83
volatile int x;
84
x = *ptr;
85
}
86
87
static
88
void
89
write_to_null(void)
90
{
91
int *null = NULL;
92
*null = 6;
93
}
94
95
static
96
void
97
write_to_inval(void)
98
{
99
int *ptr = (int *) INVAL_ADDR;
100
*ptr = 8;
101
}
102
103
static
104
void
105
write_to_code(void)
106
{
107
INSN_TYPE *x = (INSN_TYPE *)write_to_code;
108
*x = INVAL_INSN;
109
}
110
111
static
112
void
113
write_to_kernel(void)
114
{
115
int *ptr = (int *) KERNEL_ADDR;
116
*ptr = 8;
117
}
118
119
static
120
void
121
jump_to_null(void)
122
{
123
func f = NULL;
124
f();
125
}
126
127
static
128
void
129
jump_to_inval(void)
130
{
131
func f = (func) INVAL_ADDR;
132
f();
133
}
134
135
static
136
void
137
jump_to_kernel(void)
138
{
139
func f = (func) KERNEL_ADDR;
140
f();
141
}
142
143
144
static
145
void
146
illegal_instruction(void)
147
{
148
#if defined(__mips__)
149
asm(".long 0x0000003f");
150
#else
151
#error "Please fix this"
152
#endif
153
}
154
155
static
156
void
157
alignment_error(void)
158
{
159
int x;
160
int *ptr = &x;
161
int *badptr = (int *)(((char *)ptr)+1);
162
163
volatile int j;
164
j = *badptr;
165
}
166
167
static
168
void
169
divide_by_zero(void)
170
{
171
volatile int x = 6;
172
volatile int z = 0;
173
volatile int a;
174
175
a = x/z;
176
}
177
178
static
179
void
180
mod_by_zero(void)
181
{
182
volatile int x = 6;
183
volatile int z = 0;
184
volatile int a;
185
186
a = x%z;
187
}
188
189
static
190
void
191
recurse_inf(void)
192
{
193
volatile char buf[16];
194
buf[0] = 0;
195
recurse_inf();
196
buf[0] = 1;
197
}
198
199
200
static
201
struct {
202
int ch;
203
const char *name;
204
func f;
205
} ops[] = {
206
{ 'a', "read from NULL", read_from_null },
207
{ 'b', "read from invalid address", read_from_inval },
208
{ 'c', "read from kernel address", read_from_kernel },
209
{ 'd', "write to NULL", write_to_null },
210
{ 'e', "write to invalid address", write_to_inval },
211
{ 'f', "write to code segment", write_to_code },
212
{ 'g', "write to kernel address", write_to_kernel },
213
{ 'h', "jump to NULL", jump_to_null },
214
{ 'i', "jump to invalid address", jump_to_inval },
215
{ 'j', "jump to kernel address", jump_to_kernel },
216
{ 'k', "alignment error", alignment_error },
217
{ 'l', "illegal instruction", illegal_instruction },
218
{ 'm', "divide by zero", divide_by_zero },
219
{ 'n', "mod by zero", mod_by_zero },
220
{ 'o', "Recurse infinitely", recurse_inf },
221
{ 0, NULL, NULL }
222
};
223
224
int
225
main(int argc, char **argv)
226
{
227
int op, i, status;
228
pid_t pid;
229
230
if (argc == 2) {
231
op = argv[1][0];
232
}
233
else {
234
for (i=0; ops[i].name; i++) {
235
printf("[%c] %s\n", ops[i].ch, ops[i].name);
236
}
237
printf("[*] Run everything (in subprocesses)\n");
238
printf("Note: [f] may not cause an exception on some "
239
"platforms, in which\ncase it'll appear to fail.\n");
240
241
printf("Choose: ");
242
op = getchar();
243
}
244
245
if (op=='*') {
246
for (i=0; ops[i].name; i++) {
247
printf("Running: [%c] %s\n", ops[i].ch, ops[i].name);
248
pid = fork();
249
if (pid<0) {
250
/* error */
251
warn("fork");
252
}
253
else if (pid==0) {
254
/* child */
255
ops[i].f();
256
printf("I wasn't killed - test fails!\n");
257
_exit(1);
258
}
259
waitpid(pid, &status, 0);
260
if (WIFSIGNALED(status)) {
261
printf("Signal %d\n", WTERMSIG(status));
262
}
263
else {
264
printf("Exit %d\n", WEXITSTATUS(status));
265
}
266
}
267
}
268
else {
269
/* intentionally don't check if op is in bounds :) */
270
ops[op-'a'].f();
271
272
printf("I wasn't killed - test fails!\n");
273
}
274
275
return 0;
276
}
277
278