split up constants.h some
[trinity.git] / interesting-numbers.c
blob144f8dc8a2b0c8ab16311a167f6acddde623738a
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "arch.h"
4 #include "log.h" // for BUG
5 #include "random.h"
6 #include "sanitise.h"
8 static unsigned int plus_minus_two(unsigned int num)
10 /* Now munge it for off-by-ones. */
11 switch (rand() % 5) {
12 case 0: num -= 2;
13 break;
14 case 1: num -= 1;
15 break;
16 case 2: return num;
17 case 3: num += 1;
18 break;
19 case 4: num += 2;
20 break;
22 return num;
25 unsigned int get_interesting_32bit_value(void)
27 unsigned int num = 0;
29 switch (rand() % 10) {
30 case 0: num = 0x00000000;
31 break;
32 case 1: num = rand() % 256; // 00-0xff
33 break;
34 case 2: num = 1 << (rand() % 32); // set a single bit.
35 break;
36 case 3: num = 0x8fffffff;
37 break;
38 case 4: num = 0xff;
39 num = num << (rand() % 31);
40 break;
41 case 5: num = 0xffff0000;
42 break;
43 case 6: num = 0xffffe000;
44 break;
45 case 7: num = 0xffffff00 | (rand() % 256);
46 break;
47 case 8: num = 0xffffffff - page_size;
48 break;
49 case 9: num = 0xffffffff;
50 break;
53 num = plus_minus_two(num);
54 return num;
57 #if __WORDSIZE != 32
58 static unsigned long per_arch_interesting_addr(unsigned long low)
60 int i = 0;
62 #if defined(__x86_64__)
63 i = rand() % 4;
65 switch (i) {
66 case 0: return 0x00007fffffffffffUL; // x86-64 canonical addr end.
67 case 1: return 0x0000800000000000UL; // First x86-64 non-canonical addr
68 case 2: return 0xffff800000000000UL | (low << 4); // x86-64 canonical addr range 2 begin
69 case 3: return VDSO_ADDR | (low & 0x0fffff);
71 #endif
73 // FIXME: Add more arch specific addresses here.
75 return i | low;
77 #endif /* __WORDSIZE */
79 unsigned long get_interesting_value(void)
81 #if __WORDSIZE == 32
82 return get_interesting_32bit_value();
83 #else
84 unsigned long low = 0;
86 if (rand_bool())
87 low = get_interesting_32bit_value();
89 switch (rand() % 13) {
90 case 0: return 0;
91 case 1: return low;
92 case 2: return 0x0000000100000000UL | low;
93 case 3: return 0x7fffffff00000000UL | low;
94 case 4: return 0x8000000000000000UL | low;
95 case 5: return 0xffffffff00000000UL | low;
96 case 6: return 0xffffffffffffff00UL | (rand() % 256);
97 case 7: return 0xffffffffffffffffUL - page_size;
98 case 8: return PAGE_OFFSET | (low << 4);
99 case 9: return KERNEL_ADDR | (low & 0xffffff);
100 case 10: return MODULE_ADDR | (low & 0xffffff);
101 case 11: return per_arch_interesting_addr(low);
102 case 12: return (low << 32);
105 return low; // unreachable, but gcc is dumb.
106 #endif /* __WORDSIZE */