1515#include <assert.h>
1616#include <errno.h>
1717#include <fcntl.h>
18+ #include <stddef.h>
1819#include <stdint.h>
1920#include <stdio.h>
2021#include <stdlib.h>
@@ -157,8 +158,10 @@ void cov_shutdown(struct cov_context* context)
157158
158159static uint32_t internal_evaluate (struct cov_context * context , uint8_t * virgin_bits , struct edge_set * new_edges )
159160{
160- uint64_t * current = (uint64_t * )context -> shmem -> edges ;
161- uint64_t * end = (uint64_t * )(context -> shmem -> edges + context -> bitmap_size );
161+ // Calculate offset to edges array (after feedback nexus data)
162+ unsigned char * edges_ptr = (unsigned char * )context -> shmem + offsetof(struct shmem_data , edges );
163+ uint64_t * current = (uint64_t * )edges_ptr ;
164+ uint64_t * end = (uint64_t * )(edges_ptr + context -> bitmap_size );
162165 uint64_t * virgin = (uint64_t * )virgin_bits ;
163166 new_edges -> count = 0 ;
164167 new_edges -> edge_indices = NULL ;
@@ -168,9 +171,9 @@ static uint32_t internal_evaluate(struct cov_context* context, uint8_t* virgin_b
168171 if (* current && unlikely (* current & * virgin )) {
169172 // New edge(s) found!
170173 // We know that we have <= UINT32_MAX edges, so every index can safely be truncated to 32 bits.
171- uint32_t index = (uint32_t )((uintptr_t )current - (uintptr_t )context -> shmem -> edges ) * 8 ;
174+ uint32_t index = (uint32_t )((uintptr_t )current - (uintptr_t )edges_ptr ) * 8 ;
172175 for (uint32_t i = index ; i < index + 64 ; i ++ ) {
173- if (edge (context -> shmem -> edges , i ) == 1 && edge (virgin_bits , i ) == 1 ) {
176+ if (edge (edges_ptr , i ) == 1 && edge (virgin_bits , i ) == 1 ) {
174177 clear_edge (virgin_bits , i );
175178 new_edges -> count += 1 ;
176179 size_t new_num_entries = new_edges -> count ;
@@ -188,11 +191,11 @@ static uint32_t internal_evaluate(struct cov_context* context, uint8_t* virgin_b
188191 // This is in a separate block to increase readability, with a negligible performance penalty in practice,
189192 // as this pass takes 10-20x as long as the first pass
190193 if (context -> should_track_edges ) {
191- current = (uint64_t * )context -> shmem -> edges ;
194+ current = (uint64_t * )edges_ptr ;
192195 while (current < end ) {
193- uint64_t index = ((uintptr_t )current - (uintptr_t )context -> shmem -> edges ) * 8 ;
196+ uint64_t index = ((uintptr_t )current - (uintptr_t )edges_ptr ) * 8 ;
194197 for (uint64_t i = index ; i < index + 64 ; i ++ ) {
195- if (edge (context -> shmem -> edges , i ) == 1 ) {
198+ if (edge (edges_ptr , i ) == 1 ) {
196199 context -> edge_count [i ]++ ;
197200 }
198201 }
@@ -228,9 +231,12 @@ int cov_evaluate_crash(struct cov_context* context)
228231
229232int cov_compare_equal (struct cov_context * context , uint32_t * edges , uint32_t num_edges )
230233{
234+ // Calculate offset to edges array (after feedback nexus data)
235+ unsigned char * edges_ptr = (unsigned char * )context -> shmem + offsetof(struct shmem_data , edges );
236+
231237 for (int i = 0 ; i < num_edges ; i ++ ) {
232238 int idx = edges [i ];
233- if (edge (context -> shmem -> edges , idx ) == 0 )
239+ if (edge (edges_ptr , idx ) == 0 )
234240 return 0 ;
235241 }
236242
@@ -239,7 +245,9 @@ int cov_compare_equal(struct cov_context* context, uint32_t* edges, uint32_t num
239245
240246void cov_clear_bitmap (struct cov_context * context )
241247{
242- memset (context -> shmem -> edges , 0 , context -> bitmap_size );
248+ // Calculate offset to edges array (after feedback nexus data)
249+ unsigned char * edges_ptr = (unsigned char * )context -> shmem + offsetof(struct shmem_data , edges );
250+ memset (edges_ptr , 0 , context -> bitmap_size );
243251 clear_feedback_nexus (context );
244252}
245253
0 commit comments