merge newfstat variants
[trinity.git] / interesting-numbers.c
blob8c2171f74fd1e27fb46107462e3f0314659e952b
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"
7 #include "trinity.h" // page_size
9 static unsigned int plus_minus_two(unsigned int num)
11 /* Now munge it for off-by-ones. */
12 switch (rand() % 5) {
13 case 0: num -= 2;
14 break;
15 case 1: num -= 1;
16 break;
17 case 2: return num;
18 case 3: num += 1;
19 break;
20 case 4: num += 2;
21 break;
23 return num;
26 unsigned int get_interesting_32bit_value(void)
28 unsigned int num = 0;
30 switch (rand() % 10) {
31 case 0: num = 0x00000000;
32 break;
33 case 1: num = rand() % 256; // 00-0xff
34 break;
35 case 2: num = 1 << (rand() % 32); // set a single bit.
36 break;
37 case 3: num = 0x8fffffff;
38 break;
39 case 4: num = 0xff;
40 num = num << (rand() % 31);
41 break;
42 case 5: num = 0xffff0000;
43 break;
44 case 6: num = 0xffffe000;
45 break;
46 case 7: num = 0xffffff00 | (rand() % 256);
47 break;
48 case 8: num = 0xffffffff - page_size;
49 break;
50 case 9: num = 0xffffffff;
51 break;
54 num = plus_minus_two(num);
55 return num;
58 #if __WORDSIZE != 32
59 static unsigned long per_arch_interesting_addr(unsigned long low)
61 int i = 0;
63 #if defined(__x86_64__)
64 i = rand() % 4;
66 switch (i) {
67 case 0: return 0x00007fffffffffffUL; // x86-64 canonical addr end.
68 case 1: return 0x0000800000000000UL; // First x86-64 non-canonical addr
69 case 2: return 0xffff800000000000UL | (low << 4); // x86-64 canonical addr range 2 begin
70 case 3: return VDSO_ADDR | (low & 0x0fffff);
72 #endif
74 // FIXME: Add more arch specific addresses here.
76 return i | low;
78 #endif /* __WORDSIZE */
80 unsigned long get_interesting_value(void)
82 #if __WORDSIZE == 32
83 return get_interesting_32bit_value();
84 #else
85 unsigned long low = 0;
87 if (rand_bool())
88 low = get_interesting_32bit_value();
90 switch (rand() % 13) {
91 case 0: return 0;
92 case 1: return low;
93 case 2: return 0x0000000100000000UL | low;
94 case 3: return 0x7fffffff00000000UL | low;
95 case 4: return 0x8000000000000000UL | low;
96 case 5: return 0xffffffff00000000UL | low;
97 case 6: return 0xffffffffffffff00UL | (rand() % 256);
98 case 7: return 0xffffffffffffffffUL - page_size;
99 case 8: return PAGE_OFFSET | (low << 4);
100 case 9: return KERNEL_ADDR | (low & 0xffffff);
101 case 10: return MODULE_ADDR | (low & 0xffffff);
102 case 11: return per_arch_interesting_addr(low);
103 case 12: return (low << 32);
106 return low; // unreachable, but gcc is dumb.
107 #endif /* __WORDSIZE */