load correct syscall table for s390 and s390x
[trinity.git] / random-address.c
blobc51a791e0f697773176242a7ea028cf400f920f1
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <sys/uio.h>
7 #include "trinity.h" // page_size
8 #include "arch.h" // KERNEL_ADDR etc
9 #include "log.h"
10 #include "random.h"
11 #include "sanitise.h"
12 #include "maps.h"
13 #include "shm.h"
14 #include "tables.h"
17 static bool within_page(void *addr, void *check)
19 if (addr == check)
20 return TRUE;
21 if ((addr > check) && (addr < (check + page_size)))
22 return TRUE;
23 return FALSE;
26 bool validate_address(void *addr)
28 if (within_page(addr, shm) == TRUE)
29 return FALSE;
30 if (within_page(addr, page_rand) == TRUE)
31 return FALSE;
32 if (within_page(addr, page_zeros) == TRUE)
33 return FALSE;
34 if (within_page(addr, page_0xff) == TRUE)
35 return FALSE;
36 if (within_page(addr, page_allocs) == TRUE)
37 return FALSE;
39 return TRUE;
43 static void * _get_address(unsigned char null_allowed)
45 int i;
46 struct map *map;
47 void *addr = NULL;
49 if (null_allowed == TRUE)
50 i = rand() % 10;
51 else
52 i = (rand() % 9) + 1;
55 switch (i) {
56 case 0: addr = NULL;
57 break;
58 case 1: addr = (void *) KERNEL_ADDR;
59 break;
60 case 2: addr = page_zeros;
61 break;
62 case 3: addr = page_0xff;
63 break;
64 case 4: addr = page_rand;
65 break;
66 case 5: addr = page_allocs;
67 break;
68 case 6: addr = (void *)(unsigned long)rand64();
69 break;
70 case 7: map = get_map();
71 addr = map->ptr;
72 break;
73 case 8: addr = malloc(page_size * 2);
74 // FIXME: We leak this. This is the address we need to store for later
75 // freeing, not the potentially munged version below.
76 // tricky. We want to hand the munged version out too, so we might end up
77 // having to split this into alloc_address / get_address.
78 break;
79 case 9: addr = page_maps;
80 break;
84 * Most of the time, we just return the address we got above unmunged.
85 * But sometimes, we return an address just before the end of the page.
86 * The idea here is that we might see some bugs that are caused by page boundary failures.
88 i = rand() % 100;
89 switch (i) {
90 case 0: addr += (page_size - sizeof(char));
91 break;
92 case 1: addr += (page_size - sizeof(int));
93 break;
94 case 2: addr += (page_size - sizeof(long));
95 break;
96 case 3: addr += (page_size / 2);
97 break;
98 case 4 ... 99:
99 break;
102 return addr;
105 void * get_address(void)
107 return _get_address(TRUE);
110 void * get_non_null_address(void)
112 return _get_address(FALSE);
116 unsigned long find_previous_arg_address(unsigned int argnum, unsigned int call, int childno)
118 struct syscallentry *entry;
119 unsigned long addr = 0;
121 entry = syscalls[call].entry;
123 if (argnum > 1)
124 if ((entry->arg1type == ARG_ADDRESS) ||
125 (entry->arg1type == ARG_NON_NULL_ADDRESS))
126 addr = shm->a1[childno];
128 if (argnum > 2)
129 if ((entry->arg2type == ARG_ADDRESS) ||
130 (entry->arg2type == ARG_NON_NULL_ADDRESS))
131 addr = shm->a2[childno];
133 if (argnum > 3)
134 if ((entry->arg3type == ARG_ADDRESS) ||
135 (entry->arg3type == ARG_NON_NULL_ADDRESS))
136 addr = shm->a3[childno];
138 if (argnum > 4)
139 if ((entry->arg4type == ARG_ADDRESS) ||
140 (entry->arg4type == ARG_NON_NULL_ADDRESS))
141 addr = shm->a4[childno];
143 if (argnum > 5)
144 if ((entry->arg5type == ARG_ADDRESS) ||
145 (entry->arg5type == ARG_NON_NULL_ADDRESS))
146 addr = shm->a5[childno];
148 return addr;
153 * iovec's are just special cases of the ARG_ADDRESS's
155 struct iovec * alloc_iovec(unsigned int num)
157 struct iovec *iov;
159 iov = malloc(num * sizeof(struct iovec));
160 if (iov != NULL) {
161 unsigned int i;
163 for (i = 0; i < num; i++) {
164 if (rand_bool()) {
165 iov[i].iov_base = malloc(page_size);
166 iov[i].iov_len = page_size;
167 } else {
168 struct map *map;
170 map = get_map();
171 iov[i].iov_base = map->ptr;
172 iov[i].iov_len = rand() % map->size;
176 return iov;