blob: bdb26efce6b404bcddf5f2f8139dde95aec69892 [file] [log] [blame]
Jagger561b9792016-09-12 15:14:37 +02001#include <unistd.h>
2
3#include "../common.h"
4
5#include <ctype.h>
6#include <errno.h>
7#include <inttypes.h>
8#include <stdbool.h>
9#include <stdint.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <sys/mman.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <unistd.h>
17
18#include "../util.h"
19
20static feedback_t bbMapFb;
21static feedback_t *feedback = &bbMapFb;
22static uint32_t my_thread_no = 0;
23
24__attribute__ ((constructor))
25static void mapBB(void)
26{
27 char *my_thread_no_str = getenv(_HF_THREAD_NO_ENV);
28 if (my_thread_no_str == NULL) {
29 return;
30 }
31 my_thread_no = atoi(my_thread_no_str);
32
33 if (my_thread_no >= _HF_THREAD_MAX) {
34 fprintf(stderr, "my_thread_no > _HF_THREAD_MAX (%" PRIu32 " > %d)\n", my_thread_no,
35 _HF_THREAD_MAX);
36 _exit(1);
37 }
38 struct stat st;
39 if (fstat(_HF_BITMAP_FD, &st) == -1) {
40 return;
41 }
42 if (st.st_size != sizeof(feedback_t)) {
43 fprintf(stderr, "st.size != sizeof(feedback_t) (%zu != %zu)\n", (size_t) st.st_size,
44 sizeof(feedback_t));
45 _exit(1);
46 }
47 if ((feedback =
48 mmap(NULL, sizeof(feedback_t), PROT_READ | PROT_WRITE, MAP_SHARED, _HF_BITMAP_FD,
49 0)) == MAP_FAILED) {
50 fprintf(stderr, "mmap: %s\n", strerror(errno));
51 _exit(1);
52 }
53 feedback->pidFeedbackPc[my_thread_no] = 0U;
54 feedback->pidFeedbackCmp[my_thread_no] = 0U;
55}
56
57/*
58 * -finstrument-functions
59 */
60void __cyg_profile_func_enter(void *func, void *caller)
61{
62 register size_t pos =
63 (((uintptr_t) func << 12) | ((uintptr_t) caller & 0xFFF)) & _HF_PERF_BITMAP_BITSZ_MASK;
64 register uint8_t prev = ATOMIC_BTS(feedback->bbMapPc, pos);
65 if (!prev) {
66 ATOMIC_PRE_INC_RELAXED(feedback->pidFeedbackPc[my_thread_no]);
67 }
68}
69
70void __cyg_profile_func_exit(void *func UNUSED, void *caller UNUSED)
71{
72 return;
73}
74
75/*
Jagger561b9792016-09-12 15:14:37 +020076 * -fsanitize-coverage=trace-pc,indirect-calls,trace-cmp
77 */
78void __sanitizer_cov_trace_pc(void)
79{
80 register uintptr_t ret = (uintptr_t) __builtin_return_address(0) & _HF_PERF_BITMAP_BITSZ_MASK;
81 register uint8_t prev = ATOMIC_BTS(feedback->bbMapPc, ret);
82 if (!prev) {
83 ATOMIC_PRE_INC_RELAXED(feedback->pidFeedbackPc[my_thread_no]);
84 }
85}
86
87void __sanitizer_cov_trace_pc_indir(void *callee)
88{
89 register size_t pos =
90 (((uintptr_t) callee << 12) | ((uintptr_t) __builtin_return_address(0) & 0xFFF)) &
91 _HF_PERF_BITMAP_BITSZ_MASK;
92 register uint8_t prev = ATOMIC_BTS(feedback->bbMapPc, pos);
93 if (!prev) {
94 ATOMIC_PRE_INC_RELAXED(feedback->pidFeedbackPc[my_thread_no]);
95 }
96}
97
98void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2)
99{
100 uintptr_t pos = (uintptr_t) __builtin_return_address(0) % _HF_PERF_BITMAP_SIZE_16M;
101 register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2));
102 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
103 if (prev < v) {
104 ATOMIC_SET(feedback->bbMapCmp[pos], v);
105 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
106 }
107}
108
109void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2)
110{
111 uintptr_t pos = (uintptr_t) __builtin_return_address(0) % _HF_PERF_BITMAP_SIZE_16M;
112 register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2));
113 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
114 if (prev < v) {
115 ATOMIC_SET(feedback->bbMapCmp[pos], v);
116 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
117 }
118}
119
120void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2)
121{
122 uintptr_t pos = (uintptr_t) __builtin_return_address(0) % _HF_PERF_BITMAP_SIZE_16M;
123 register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2));
124 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
125 if (prev < v) {
126 ATOMIC_SET(feedback->bbMapCmp[pos], v);
127 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
128 }
129}
130
131void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2)
132{
133 uintptr_t pos = (uintptr_t) __builtin_return_address(0) % _HF_PERF_BITMAP_SIZE_16M;
134 register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcountll(Arg1 ^ Arg2));
135 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
136 if (prev < v) {
137 ATOMIC_SET(feedback->bbMapCmp[pos], v);
138 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
139 }
140}
141
142/*
143 * Cases[0] is number of comparison entries
144 * Cases[1] is length of Val in bytes
145 */
146void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t * Cases)
147{
148 for (uint64_t i = 0; i < Cases[0]; i++) {
149 uintptr_t pos = ((uintptr_t) __builtin_return_address(0) + i) % _HF_PERF_BITMAP_SIZE_16M;
Jaggere9606ce2016-09-14 02:50:22 +0200150 uint8_t v = ((8 * Cases[1]) - __builtin_popcountll(Val ^ Cases[i + 2]));
Jagger561b9792016-09-12 15:14:37 +0200151 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
152 if (prev < v) {
153 ATOMIC_SET(feedback->bbMapCmp[pos], v);
154 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
155 }
156 }
157}
158
Robert Swieckiab288152016-10-03 03:42:20 +0200159/*
160 * -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp
161 */
Robert Swiecki574b0392016-10-03 03:32:19 +0200162void __sanitizer_cov_trace_pc_guard_init(uint32_t * start, uint32_t * stop)
163{
Robert Swiecki3eee4b52016-10-03 03:44:54 +0200164 static bool inited = false;
165 if (inited == true) {
166 return;
167 }
168 inited = true;
Robert Swiecki7c2c90c2016-10-04 02:47:38 +0200169 uint32_t n = 1U;
170 for (uint32_t * x = start; x < stop; x++, n++) {
171 if (n >= _HF_PC_GUARD_MAX) {
172 fprintf(stderr, "This process has too many PC guards\n");
173 exit(1);
174 }
175 *x = n;
Robert Swiecki574b0392016-10-03 03:32:19 +0200176 }
177}
178
Robert Swiecki9f4cd092016-10-04 23:09:42 +0200179void __sanitizer_cov_trace_pc_guard(uint32_t * guard)
Robert Swiecki574b0392016-10-03 03:32:19 +0200180{
Robert Swiecki7c2c90c2016-10-04 02:47:38 +0200181 bool prev = ATOMIC_XCHG(feedback->pcGuardMap[*guard], true);
182 if (prev == false) {
183 ATOMIC_PRE_INC_RELAXED(feedback->pidFeedbackPc[my_thread_no]);
184 }
Robert Swiecki574b0392016-10-03 03:32:19 +0200185 *guard = 0U;
Robert Swiecki574b0392016-10-03 03:32:19 +0200186}
Robert Swieckiab288152016-10-03 03:42:20 +0200187
188void libhfuzz_instrumentUpdateCmpMap(void *addr, unsigned int new)
189{
190 uintptr_t pos = (uintptr_t) addr % _HF_PERF_BITMAP_SIZE_16M;
191 uint8_t v = new > 254 ? 254 : new;
192 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
193 if (prev < v) {
194 ATOMIC_SET(feedback->bbMapCmp[pos], v);
195 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
196 }
197}