blob: dfaea816181e05f7f7ea79e9f8f2ccaccc742e52 [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/*
76 * -fsanitize=<address|memory|leak|undefined>
77 * -fsanitize-coverage=trace-pc,indirect-calls,trace-cmp
78 */
79void __sanitizer_cov_trace_pc(void)
80{
81 register uintptr_t ret = (uintptr_t) __builtin_return_address(0) & _HF_PERF_BITMAP_BITSZ_MASK;
82 register uint8_t prev = ATOMIC_BTS(feedback->bbMapPc, ret);
83 if (!prev) {
84 ATOMIC_PRE_INC_RELAXED(feedback->pidFeedbackPc[my_thread_no]);
85 }
86}
87
88void __sanitizer_cov_trace_pc_indir(void *callee)
89{
90 register size_t pos =
91 (((uintptr_t) callee << 12) | ((uintptr_t) __builtin_return_address(0) & 0xFFF)) &
92 _HF_PERF_BITMAP_BITSZ_MASK;
93 register uint8_t prev = ATOMIC_BTS(feedback->bbMapPc, pos);
94 if (!prev) {
95 ATOMIC_PRE_INC_RELAXED(feedback->pidFeedbackPc[my_thread_no]);
96 }
97}
98
99void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2)
100{
101 uintptr_t pos = (uintptr_t) __builtin_return_address(0) % _HF_PERF_BITMAP_SIZE_16M;
102 register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2));
103 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
104 if (prev < v) {
105 ATOMIC_SET(feedback->bbMapCmp[pos], v);
106 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
107 }
108}
109
110void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2)
111{
112 uintptr_t pos = (uintptr_t) __builtin_return_address(0) % _HF_PERF_BITMAP_SIZE_16M;
113 register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2));
114 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
115 if (prev < v) {
116 ATOMIC_SET(feedback->bbMapCmp[pos], v);
117 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
118 }
119}
120
121void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2)
122{
123 uintptr_t pos = (uintptr_t) __builtin_return_address(0) % _HF_PERF_BITMAP_SIZE_16M;
124 register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2));
125 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
126 if (prev < v) {
127 ATOMIC_SET(feedback->bbMapCmp[pos], v);
128 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
129 }
130}
131
132void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2)
133{
134 uintptr_t pos = (uintptr_t) __builtin_return_address(0) % _HF_PERF_BITMAP_SIZE_16M;
135 register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcountll(Arg1 ^ Arg2));
136 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
137 if (prev < v) {
138 ATOMIC_SET(feedback->bbMapCmp[pos], v);
139 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
140 }
141}
142
143/*
144 * Cases[0] is number of comparison entries
145 * Cases[1] is length of Val in bytes
146 */
147void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t * Cases)
148{
149 for (uint64_t i = 0; i < Cases[0]; i++) {
150 uintptr_t pos = ((uintptr_t) __builtin_return_address(0) + i) % _HF_PERF_BITMAP_SIZE_16M;
Jaggere9606ce2016-09-14 02:50:22 +0200151 uint8_t v = ((8 * Cases[1]) - __builtin_popcountll(Val ^ Cases[i + 2]));
Jagger561b9792016-09-12 15:14:37 +0200152 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
153 if (prev < v) {
154 ATOMIC_SET(feedback->bbMapCmp[pos], v);
155 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
156 }
157 }
158}
159
160void libhfuzz_instrumentUpdateCmpMap(void *addr, unsigned int new)
161{
162 uintptr_t pos = (uintptr_t) addr % _HF_PERF_BITMAP_SIZE_16M;
Jaggere9606ce2016-09-14 02:50:22 +0200163 uint8_t v = new > 254 ? 254 : new;
Jagger561b9792016-09-12 15:14:37 +0200164 uint8_t prev = ATOMIC_GET(feedback->bbMapCmp[pos]);
165 if (prev < v) {
166 ATOMIC_SET(feedback->bbMapCmp[pos], v);
167 ATOMIC_POST_ADD(feedback->pidFeedbackCmp[my_thread_no], v - prev);
168 }
169}