1*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
2*08b48e0bSAndroid Build Coastguard Worker #include "types.h"
3*08b48e0bSAndroid Build Coastguard Worker
4*08b48e0bSAndroid Build Coastguard Worker u32 skim(const u32 *virgin, const u32 *current, const u32 *current_end);
5*08b48e0bSAndroid Build Coastguard Worker u32 classify_word(u32 word);
6*08b48e0bSAndroid Build Coastguard Worker
classify_word(u32 word)7*08b48e0bSAndroid Build Coastguard Worker inline u32 classify_word(u32 word) {
8*08b48e0bSAndroid Build Coastguard Worker
9*08b48e0bSAndroid Build Coastguard Worker u16 mem16[2];
10*08b48e0bSAndroid Build Coastguard Worker memcpy(mem16, &word, sizeof(mem16));
11*08b48e0bSAndroid Build Coastguard Worker
12*08b48e0bSAndroid Build Coastguard Worker mem16[0] = count_class_lookup16[mem16[0]];
13*08b48e0bSAndroid Build Coastguard Worker mem16[1] = count_class_lookup16[mem16[1]];
14*08b48e0bSAndroid Build Coastguard Worker
15*08b48e0bSAndroid Build Coastguard Worker memcpy(&word, mem16, sizeof(mem16));
16*08b48e0bSAndroid Build Coastguard Worker return word;
17*08b48e0bSAndroid Build Coastguard Worker
18*08b48e0bSAndroid Build Coastguard Worker }
19*08b48e0bSAndroid Build Coastguard Worker
simplify_trace(afl_state_t * afl,u8 * bytes)20*08b48e0bSAndroid Build Coastguard Worker void simplify_trace(afl_state_t *afl, u8 *bytes) {
21*08b48e0bSAndroid Build Coastguard Worker
22*08b48e0bSAndroid Build Coastguard Worker u32 *mem = (u32 *)bytes;
23*08b48e0bSAndroid Build Coastguard Worker u32 i = (afl->fsrv.map_size >> 2);
24*08b48e0bSAndroid Build Coastguard Worker
25*08b48e0bSAndroid Build Coastguard Worker while (i--) {
26*08b48e0bSAndroid Build Coastguard Worker
27*08b48e0bSAndroid Build Coastguard Worker /* Optimize for sparse bitmaps. */
28*08b48e0bSAndroid Build Coastguard Worker
29*08b48e0bSAndroid Build Coastguard Worker if (unlikely(*mem)) {
30*08b48e0bSAndroid Build Coastguard Worker
31*08b48e0bSAndroid Build Coastguard Worker u8 *mem8 = (u8 *)mem;
32*08b48e0bSAndroid Build Coastguard Worker
33*08b48e0bSAndroid Build Coastguard Worker mem8[0] = simplify_lookup[mem8[0]];
34*08b48e0bSAndroid Build Coastguard Worker mem8[1] = simplify_lookup[mem8[1]];
35*08b48e0bSAndroid Build Coastguard Worker mem8[2] = simplify_lookup[mem8[2]];
36*08b48e0bSAndroid Build Coastguard Worker mem8[3] = simplify_lookup[mem8[3]];
37*08b48e0bSAndroid Build Coastguard Worker
38*08b48e0bSAndroid Build Coastguard Worker } else
39*08b48e0bSAndroid Build Coastguard Worker
40*08b48e0bSAndroid Build Coastguard Worker *mem = 0x01010101;
41*08b48e0bSAndroid Build Coastguard Worker
42*08b48e0bSAndroid Build Coastguard Worker mem++;
43*08b48e0bSAndroid Build Coastguard Worker
44*08b48e0bSAndroid Build Coastguard Worker }
45*08b48e0bSAndroid Build Coastguard Worker
46*08b48e0bSAndroid Build Coastguard Worker }
47*08b48e0bSAndroid Build Coastguard Worker
classify_counts(afl_forkserver_t * fsrv)48*08b48e0bSAndroid Build Coastguard Worker inline void classify_counts(afl_forkserver_t *fsrv) {
49*08b48e0bSAndroid Build Coastguard Worker
50*08b48e0bSAndroid Build Coastguard Worker u32 *mem = (u32 *)fsrv->trace_bits;
51*08b48e0bSAndroid Build Coastguard Worker u32 i = (fsrv->map_size >> 2);
52*08b48e0bSAndroid Build Coastguard Worker
53*08b48e0bSAndroid Build Coastguard Worker while (i--) {
54*08b48e0bSAndroid Build Coastguard Worker
55*08b48e0bSAndroid Build Coastguard Worker /* Optimize for sparse bitmaps. */
56*08b48e0bSAndroid Build Coastguard Worker
57*08b48e0bSAndroid Build Coastguard Worker if (unlikely(*mem)) { *mem = classify_word(*mem); }
58*08b48e0bSAndroid Build Coastguard Worker
59*08b48e0bSAndroid Build Coastguard Worker mem++;
60*08b48e0bSAndroid Build Coastguard Worker
61*08b48e0bSAndroid Build Coastguard Worker }
62*08b48e0bSAndroid Build Coastguard Worker
63*08b48e0bSAndroid Build Coastguard Worker }
64*08b48e0bSAndroid Build Coastguard Worker
65*08b48e0bSAndroid Build Coastguard Worker /* Updates the virgin bits, then reflects whether a new count or a new tuple is
66*08b48e0bSAndroid Build Coastguard Worker * seen in ret. */
discover_word(u8 * ret,u32 * current,u32 * virgin)67*08b48e0bSAndroid Build Coastguard Worker inline void discover_word(u8 *ret, u32 *current, u32 *virgin) {
68*08b48e0bSAndroid Build Coastguard Worker
69*08b48e0bSAndroid Build Coastguard Worker /* Optimize for (*current & *virgin) == 0 - i.e., no bits in current bitmap
70*08b48e0bSAndroid Build Coastguard Worker that have not been already cleared from the virgin map - since this will
71*08b48e0bSAndroid Build Coastguard Worker almost always be the case. */
72*08b48e0bSAndroid Build Coastguard Worker
73*08b48e0bSAndroid Build Coastguard Worker if (unlikely(*current & *virgin)) {
74*08b48e0bSAndroid Build Coastguard Worker
75*08b48e0bSAndroid Build Coastguard Worker if (likely(*ret < 2)) {
76*08b48e0bSAndroid Build Coastguard Worker
77*08b48e0bSAndroid Build Coastguard Worker u8 *cur = (u8 *)current;
78*08b48e0bSAndroid Build Coastguard Worker u8 *vir = (u8 *)virgin;
79*08b48e0bSAndroid Build Coastguard Worker
80*08b48e0bSAndroid Build Coastguard Worker /* Looks like we have not found any new bytes yet; see if any non-zero
81*08b48e0bSAndroid Build Coastguard Worker bytes in current[] are pristine in virgin[]. */
82*08b48e0bSAndroid Build Coastguard Worker
83*08b48e0bSAndroid Build Coastguard Worker if (unlikely((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) ||
84*08b48e0bSAndroid Build Coastguard Worker (cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff)))
85*08b48e0bSAndroid Build Coastguard Worker *ret = 2;
86*08b48e0bSAndroid Build Coastguard Worker else
87*08b48e0bSAndroid Build Coastguard Worker *ret = 1;
88*08b48e0bSAndroid Build Coastguard Worker
89*08b48e0bSAndroid Build Coastguard Worker }
90*08b48e0bSAndroid Build Coastguard Worker
91*08b48e0bSAndroid Build Coastguard Worker *virgin &= ~*current;
92*08b48e0bSAndroid Build Coastguard Worker
93*08b48e0bSAndroid Build Coastguard Worker }
94*08b48e0bSAndroid Build Coastguard Worker
95*08b48e0bSAndroid Build Coastguard Worker }
96*08b48e0bSAndroid Build Coastguard Worker
97*08b48e0bSAndroid Build Coastguard Worker #define PACK_SIZE 16
skim(const u32 * virgin,const u32 * current,const u32 * current_end)98*08b48e0bSAndroid Build Coastguard Worker inline u32 skim(const u32 *virgin, const u32 *current, const u32 *current_end) {
99*08b48e0bSAndroid Build Coastguard Worker
100*08b48e0bSAndroid Build Coastguard Worker for (; current < current_end; virgin += 4, current += 4) {
101*08b48e0bSAndroid Build Coastguard Worker
102*08b48e0bSAndroid Build Coastguard Worker if (unlikely(current[0] && classify_word(current[0]) & virgin[0])) return 1;
103*08b48e0bSAndroid Build Coastguard Worker if (unlikely(current[1] && classify_word(current[1]) & virgin[1])) return 1;
104*08b48e0bSAndroid Build Coastguard Worker if (unlikely(current[2] && classify_word(current[2]) & virgin[2])) return 1;
105*08b48e0bSAndroid Build Coastguard Worker if (unlikely(current[3] && classify_word(current[3]) & virgin[3])) return 1;
106*08b48e0bSAndroid Build Coastguard Worker
107*08b48e0bSAndroid Build Coastguard Worker }
108*08b48e0bSAndroid Build Coastguard Worker
109*08b48e0bSAndroid Build Coastguard Worker return 0;
110*08b48e0bSAndroid Build Coastguard Worker
111*08b48e0bSAndroid Build Coastguard Worker }
112*08b48e0bSAndroid Build Coastguard Worker
113