v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
cov.cc
Go to the documentation of this file.
1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/fuzzilli/cov.h"
6
7#include <fcntl.h>
8#include <inttypes.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <sys/mman.h>
13#include <sys/stat.h>
14#include <sys/wait.h>
15#include <unistd.h>
16
18
19#define SHM_SIZE 0x100000
20#define MAX_EDGES ((SHM_SIZE - 4) * 8)
21
22struct shmem_data {
23 uint32_t num_edges;
24 unsigned char edges[];
25};
26
28
32
34 uint32_t N = 0;
35 for (uint32_t* x = edges_start; x < edges_stop && N < MAX_EDGES; x++)
36 *x = ++N;
37}
38
40 uint32_t* stop) {
41 // We should initialize the shared memory region only once. We can initialize
42 // it multiple times if it's the same region, which is something that appears
43 // to happen on e.g. macOS. If we ever see a different region, we will likely
44 // overwrite the previous one, which is probably not intended and as such we
45 // fail with an error.
46 if (shmem) {
47 if (!(edges_start == start && edges_stop == stop)) {
48 fprintf(stderr,
49 "[COV] Multiple initialization of shmem!"
50 " This is probably not intended! Currently only one edge"
51 " region is supported\n");
52 _exit(-1);
53 }
54 // Already initialized.
55 return;
56 }
57 // Map the shared memory region
58 const char* shm_key = getenv("SHM_ID");
59 if (!shm_key) {
60 fprintf(stderr, "[COV] no shared memory bitmap available, skipping\n");
62 } else {
63 int fd = shm_open(shm_key, O_RDWR, S_IREAD | S_IWRITE);
64 if (fd <= -1) {
65 fprintf(stderr, "[COV] Failed to open shared memory region\n");
66 _exit(-1);
67 }
68
69 shmem = (struct shmem_data*)mmap(0, SHM_SIZE, PROT_READ | PROT_WRITE,
70 MAP_SHARED, fd, 0);
71 if (shmem == MAP_FAILED) {
72 fprintf(stderr, "[COV] Failed to mmap shared memory region\n");
73 _exit(-1);
74 }
75 }
76
78 edges_stop = stop;
80
81 shmem->num_edges = static_cast<uint32_t>(stop - start);
83 fprintf(stderr,
84 "[COV] edge counters initialized. Shared memory: %s with %u edges\n",
85 shm_key, shmem->num_edges);
86}
87
89 uint32_t on_edges_counter = 0;
90 for (uint32_t i = 1; i < builtins_start; ++i) {
91 const uint32_t byteIndex = i >> 3; // Divide by 8 using a shift operation
92 const uint32_t bitIndex = i & 7; // Modulo 8 using a bitwise AND operation
93
94 if (shmem->edges[byteIndex] & (1 << bitIndex)) {
95 ++on_edges_counter;
96 }
97 }
98 return on_edges_counter;
99}
100
101extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t* guard) {
102 // There's a small race condition here: if this function executes in two
103 // threads for the same edge at the same time, the first thread might disable
104 // the edge (by setting the guard to zero) before the second thread fetches
105 // the guard value (and thus the index). However, our instrumentation ignores
106 // the first edge (see libcoverage.c) and so the race is unproblematic.
107 uint32_t index = *guard;
108 shmem->edges[index / 8] |= 1 << (index % 8);
109 *guard = 0;
110}
111
114 fprintf(stderr,
115 "[COV] Error: Insufficient amount of edges left for builtins "
116 "coverage.\n");
117 exit(-1);
118 }
122 fprintf(stderr, "[COV] Additional %d edges for builtins initialized.\n",
123 num_edges);
124}
125
126// This function is ran once per REPRL loop. In case of crash the coverage of
127// crash will not be stored in shared memory. Therefore, it would be useful, if
128// we could store these coverage information into shared memory in real time.
130 const std::vector<bool>& cov_map) {
131 if (cov_map.size() != builtins_edge_count) {
132 fprintf(stderr, "[COV] Error: Size of builtins cov map changed.\n");
133 exit(-1);
134 }
135 for (uint32_t i = 0; i < cov_map.size(); ++i) {
136 if (cov_map[i]) {
137 const uint32_t byteIndex = (i + builtins_start) >> 3;
138 const uint32_t bitIndex = (i + builtins_start) & 7;
139
140 shmem->edges[byteIndex] |= (1 << bitIndex);
141 }
142 }
143}
void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop)
Definition cov.cc:39
#define SHM_SIZE
Definition cov.cc:19
void sanitizer_cov_reset_edgeguards()
Definition cov.cc:33
#define MAX_EDGES
Definition cov.cc:20
uint32_t sanitizer_cov_count_discovered_edges()
Definition cov.cc:88
void cov_update_builtins_basic_block_coverage(const std::vector< bool > &cov_map)
Definition cov.cc:129
uint32_t * edges_stop
Definition cov.cc:29
struct shmem_data * shmem
Definition cov.cc:27
void __sanitizer_cov_trace_pc_guard(uint32_t *guard)
Definition cov.cc:101
void cov_init_builtins_edges(uint32_t num_edges)
Definition cov.cc:112
uint32_t builtins_start
Definition cov.cc:30
uint32_t builtins_edge_count
Definition cov.cc:31
uint32_t * edges_start
Definition cov.cc:29
int start
int x
void * Malloc(size_t size)
Definition memory.h:36
unsigned char edges[]
Definition cov.cc:24
uint32_t num_edges
Definition cov.cc:23