update 'now' every pidslot walk instead of once per loop.
[trinity.git] / random-address.c
blob6c7d7b396141fe1bb7efc1adc453b8dc34e36416
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() % 9;
51 else
52 i = (rand() % 8) + 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 default:
80 BUG("unreachable!\n");
81 break;
85 * Most of the time, we just return the address we got above unmunged.
86 * But sometimes, we return an address just before the end of the page.
87 * The idea here is that we might see some bugs that are caused by page boundary failures.
89 i = rand() % 100;
90 switch (i) {
91 case 0: addr += (page_size - sizeof(char));
92 break;
93 case 1: addr += (page_size - sizeof(int));
94 break;
95 case 2: addr += (page_size - sizeof(long));
96 break;
97 case 3: addr += (page_size / 2);
98 break;
99 case 4 ... 99:
100 default: break;
103 return addr;
106 void * get_address(void)
108 return _get_address(TRUE);
111 void * get_non_null_address(void)
113 return _get_address(FALSE);
117 unsigned long find_previous_arg_address(unsigned int argnum, unsigned int call, int childno)
119 unsigned long addr = 0;
121 if (argnum > 1)
122 if ((syscalls[call].entry->arg1type == ARG_ADDRESS) ||
123 (syscalls[call].entry->arg1type == ARG_NON_NULL_ADDRESS))
124 addr = shm->a1[childno];
126 if (argnum > 2)
127 if ((syscalls[call].entry->arg2type == ARG_ADDRESS) ||
128 (syscalls[call].entry->arg2type == ARG_NON_NULL_ADDRESS))
129 addr = shm->a2[childno];
131 if (argnum > 3)
132 if ((syscalls[call].entry->arg3type == ARG_ADDRESS) ||
133 (syscalls[call].entry->arg3type == ARG_NON_NULL_ADDRESS))
134 addr = shm->a3[childno];
136 if (argnum > 4)
137 if ((syscalls[call].entry->arg4type == ARG_ADDRESS) ||
138 (syscalls[call].entry->arg4type == ARG_NON_NULL_ADDRESS))
139 addr = shm->a4[childno];
141 if (argnum > 5)
142 if ((syscalls[call].entry->arg5type == ARG_ADDRESS) ||
143 (syscalls[call].entry->arg5type == ARG_NON_NULL_ADDRESS))
144 addr = shm->a5[childno];
146 return addr;
151 * iovec's are just special cases of the ARG_ADDRESS's
153 struct iovec * alloc_iovec(unsigned int num)
155 struct iovec *iov;
156 unsigned int i;
158 iov = malloc(num * sizeof(struct iovec));
159 if (iov != NULL) {
160 for (i = 0; i < num; i++) {
161 iov[i].iov_base = malloc(page_size);
162 iov[i].iov_len = page_size;
165 return iov;