@@ -21,24 +21,25 @@ extern unsigned int afl_forksrv_pid;
21
21
22
22
abi_ulong chatkey_entry_point; /* ELF entry point (_start) */
23
23
24
- #define MODE_COUNT_NEW 0 // Count newly covered nodes , along with path hash.
25
- #define MODE_HASH 1 // Calculate node set hash.
26
- #define MODE_SET 2 // Return the set of the visited nodes .
24
+ #define MODE_COUNT_NEW 0 // Count newly covered edges , along with path hash.
25
+ #define MODE_HASH 1 // Calculate edge set hash.
26
+ #define MODE_SET 2 // Return the set of the visited edges .
27
27
int chatkey_mode = -1 ;
28
28
29
- static uint32_t new_node_cnt = 0 ; // # of new nodes visited in this execution
30
- static abi_ulong node_set_hash = 5381 ; // djb2 hash
29
+ static uint32_t new_edge_cnt = 0 ; // # of new edges visited in this execution
30
+ static abi_ulong edge_set_hash = 5381 ; // djb2 hash
31
31
static abi_ulong path_hash = 5381 ; // djb2 hash
32
+ static abi_ulong prev_node = 0 ;
32
33
/* Global file pointers */
33
34
static FILE* coverage_fp;
34
35
static FILE* dbg_fp;
35
36
36
37
static int is_fp_closed = 0 ;
37
38
38
- static unsigned char * accum_node_bitmap ;
39
- static unsigned char node_bitmap [0x10000 ];
40
- // Holds nodes visited in this exec (will be dumped into a file)
41
- static dense_hash_set<abi_ulong> node_set ;
39
+ static unsigned char * accum_edge_bitmap ;
40
+ static unsigned char edge_bitmap [0x10000 ];
41
+ // Holds edges visited in this exec (will be dumped into a file)
42
+ static dense_hash_set<abi_ulong> edge_set ;
42
43
43
44
static void dump_set (dense_hash_set<abi_ulong> * set, FILE* output_fp)
44
45
{
@@ -57,10 +58,10 @@ extern "C" void chatkey_setup_before_forkserver(void) {
57
58
58
59
shm_id = getenv (" CK_SHM_ID" );
59
60
assert (shm_id != NULL );
60
- accum_node_bitmap = (unsigned char *) shmat (atoi (shm_id), NULL , 0 );
61
- assert (accum_node_bitmap != (void *) -1 );
61
+ accum_edge_bitmap = (unsigned char *) shmat (atoi (shm_id), NULL , 0 );
62
+ assert (accum_edge_bitmap != (void *) -1 );
62
63
63
- node_set .set_empty_key (0 );
64
+ edge_set .set_empty_key (0 );
64
65
}
65
66
66
67
extern " C" void chatkey_setup_after_forkserver (void ) {
@@ -121,28 +122,28 @@ extern "C" void chatkey_exit(void) {
121
122
122
123
if (chatkey_mode == MODE_COUNT_NEW) {
123
124
124
- /* Output new node # and path hash. */
125
- fprintf (coverage_fp, " %d\n " , new_node_cnt );
125
+ /* Output new edge # and path hash. */
126
+ fprintf (coverage_fp, " %d\n " , new_edge_cnt );
126
127
#ifdef TARGET_X86_64
127
128
fprintf (coverage_fp, " %lu\n " , path_hash);
128
- fprintf (coverage_fp, " %lu\n " , node_set_hash );
129
+ fprintf (coverage_fp, " %lu\n " , edge_set_hash );
129
130
#else
130
131
fprintf (coverage_fp, " %u\n " , path_hash);
131
- fprintf (coverage_fp, " %u\n " , node_set_hash );
132
+ fprintf (coverage_fp, " %u\n " , edge_set_hash );
132
133
#endif
133
134
134
135
fclose (coverage_fp);
135
136
} else if (chatkey_mode == MODE_HASH) {
136
- /* Output path hash and node hash */
137
+ /* Output path hash and edge hash */
137
138
#ifdef TARGET_X86_64
138
- fprintf (coverage_fp, " %lu\n " , node_set_hash );
139
+ fprintf (coverage_fp, " %lu\n " , edge_set_hash );
139
140
#else
140
- fprintf (coverage_fp, " %u\n " , node_set_hash );
141
+ fprintf (coverage_fp, " %u\n " , edge_set_hash );
141
142
#endif
142
143
fclose (coverage_fp);
143
144
} else if (chatkey_mode == MODE_SET) {
144
- /* Dump visited node set */
145
- dump_set (&node_set , coverage_fp);
145
+ /* Dump visited edge set */
146
+ dump_set (&edge_set , coverage_fp);
146
147
fclose (coverage_fp);
147
148
} else {
148
149
assert (false );
@@ -158,35 +159,41 @@ static inline void chatkey_update_path_hash(register abi_ulong addr) {
158
159
path_hash = ((path_hash << 5 ) + path_hash) + ((addr >> (i<<3 )) & 0xff );
159
160
}
160
161
161
- static inline void update_node_set_hash (register abi_ulong node_hash ) {
162
- node_set_hash = node_set_hash ^ node_hash ;
162
+ static inline void update_edge_set_hash (register abi_ulong edge_hash ) {
163
+ edge_set_hash = edge_set_hash ^ edge_hash ;
163
164
}
164
165
165
166
extern " C" void chatkey_log_bb (abi_ulong addr, abi_ulong callsite) {
166
- abi_ulong node , hash;
167
+ abi_ulong edge , hash;
167
168
unsigned int byte_idx, byte_mask;
168
169
unsigned char old_byte, new_byte;
169
170
170
171
chatkey_update_path_hash (addr);
171
- node = addr;
172
+ edge = addr;
173
+ #ifdef TARGET_X86_64
174
+ edge = (prev_node << 16 ) ^ addr;
175
+ #else
176
+ edge = (prev_node << 8 ) ^ addr;
177
+ #endif
178
+ prev_node = addr;
172
179
173
180
if (chatkey_mode == MODE_COUNT_NEW) {
174
- // Check and update both node_bitmap and accumulative bitmap
175
- hash = (node >> 4 ) ^ (node << 8 );
181
+ // Check and update both edge_bitmap and accumulative bitmap
182
+ hash = (edge >> 4 ) ^ (edge << 8 );
176
183
byte_idx = (hash >> 3 ) & 0xffff ;
177
184
byte_mask = 1 << (hash & 0x7 ); // Use the lowest 3 bits to shift
178
- old_byte = node_bitmap [byte_idx];
185
+ old_byte = edge_bitmap [byte_idx];
179
186
new_byte = old_byte | byte_mask;
180
187
if (old_byte != new_byte) {
181
- node_bitmap [byte_idx] = new_byte;
182
- // If it's a new node , update node hash and also add to accumulative map
183
- update_node_set_hash (hash);
184
- old_byte = accum_node_bitmap [byte_idx];
188
+ edge_bitmap [byte_idx] = new_byte;
189
+ // If it's a new edge , update edge hash and also add to accumulative map
190
+ update_edge_set_hash (hash);
191
+ old_byte = accum_edge_bitmap [byte_idx];
185
192
new_byte = old_byte | byte_mask;
186
193
if (old_byte != new_byte) {
187
- new_node_cnt ++;
188
- accum_node_bitmap [byte_idx] = new_byte;
189
- /* Log newly found nodes if dbg_fp is not NULL */
194
+ new_edge_cnt ++;
195
+ accum_edge_bitmap [byte_idx] = new_byte;
196
+ /* Log visited addrs if dbg_fp is not NULL */
190
197
if (dbg_fp) {
191
198
#ifdef TARGET_X86_64
192
199
fprintf (dbg_fp, " (0x%lx, 0x%lx)\n " , addr, callsite);
@@ -197,20 +204,20 @@ extern "C" void chatkey_log_bb(abi_ulong addr, abi_ulong callsite) {
197
204
}
198
205
}
199
206
} else if (chatkey_mode == MODE_HASH) {
200
- // Check and update node_bitmap only
201
- hash = (node >> 4 ) ^ (node << 8 );
207
+ // Check and update edge_bitmap only
208
+ hash = (edge >> 4 ) ^ (edge << 8 );
202
209
byte_idx = (hash >> 3 ) & 0xffff ;
203
210
byte_mask = 1 << (hash & 0x7 ); // Lowest 3 bits
204
- old_byte = node_bitmap [byte_idx];
211
+ old_byte = edge_bitmap [byte_idx];
205
212
new_byte = old_byte | byte_mask;
206
213
if (old_byte != new_byte) {
207
- node_bitmap [byte_idx] = new_byte;
208
- // If it's a new node , update node hash and also add to accumulative map
209
- update_node_set_hash (hash);
214
+ edge_bitmap [byte_idx] = new_byte;
215
+ // If it's a new edge , update edge hash and also add to accumulative map
216
+ update_edge_set_hash (hash);
210
217
}
211
218
} else if (chatkey_mode == MODE_SET ) {
212
- // Just insert currently covered node to the node set
213
- node_set .insert (node );
219
+ // Just insert currently covered edge to the edge set
220
+ edge_set .insert (edge );
214
221
} else if (chatkey_mode != -1 ) {
215
222
/* If chatkey_mode is -1, it means that chatkey_setup() is not called yet
216
223
* This happens when QEMU is executing a dynamically linked program. Other
0 commit comments