"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "libhfuzz/instrument.c" between
honggfuzz-2.1.tar.gz and honggfuzz-2.2.tar.gz

About: honggfuzz is a security oriented, feedback-driven, evolutionary, easy-to-use fuzzer with powerful analysis options.

instrument.c  (honggfuzz-2.1):instrument.c  (honggfuzz-2.2)
#include "instrument.h" #include "instrument.h"
#include <ctype.h> #include <ctype.h>
#include <dlfcn.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <inttypes.h> #include <inttypes.h>
#if defined(_HF_ARCH_LINUX)
#include <linux/mman.h>
#endif /* defined(_HF_ARCH_LINUX) */
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "honggfuzz.h" #include "honggfuzz.h"
#include "libhfcommon/common.h" #include "libhfcommon/common.h"
#include "libhfcommon/files.h" #include "libhfcommon/files.h"
#include "libhfcommon/log.h" #include "libhfcommon/log.h"
#include "libhfcommon/util.h" #include "libhfcommon/util.h"
__attribute__((visibility("default"))) __attribute__((used)) /* Cygwin doesn't support this */
const char* const LIBHFUZZ_module_instrument = "LIBHFUZZ_module_instrument"; #if !defined(__CYGWIN__)
__attribute__((visibility("hidden")))
#endif /* !defined(__CYGWIN__) */
__attribute__((used)) const char* const LIBHFUZZ_module_instrument = "LIBHFUZZ_m
odule_instrument";
/* /*
* We require SSE4.2 with x86-(32|64) for the 'popcnt', as it's much faster than the software * We require SSE4.2 with x86-(32|64) for the 'popcnt', as it's much faster than the software
* emulation of gcc/clang * emulation of gcc/clang
*/ */
#if defined(__x86_64__) || defined(__i386__) #if defined(__x86_64__) || defined(__i386__)
#define HF_REQUIRE_SSE42_POPCNT __attribute__((__target__("sse4.2,popcnt"))) #define HF_REQUIRE_SSE42_POPCNT __attribute__((__target__("sse4.2,popcnt")))
#else #else
#define HF_REQUIRE_SSE42_POPCNT #define HF_REQUIRE_SSE42_POPCNT
#endif /* defined(__x86_64__) || defined(__i386__) */ #endif /* defined(__x86_64__) || defined(__i386__) */
/* /*
* If there's no _HF_COV_BITMAP_FD available (running without the honggfuzz * If there's no _HF_COV_BITMAP_FD available (running without the honggfuzz
* supervisor), use a dummy bitmap and control structure located in the BSS * supervisor), use a dummy bitmap and control structure located in the BSS
*/ */
static feedback_t bbMapFb; static feedback_t bbMapFb;
feedback_t* covFeedback = &bbMapFb; feedback_t* globalCovFeedback = &bbMapFb;
cmpfeedback_t* cmpFeedback = NULL; feedback_t* localCovFeedback = &bbMapFb;
cmpfeedback_t* globalCmpFeedback = NULL;
uint32_t my_thread_no = 0; uint32_t my_thread_no = 0;
static int _memcmp(const void* m1, const void* m2, size_t n) {
const unsigned char* s1 = (const unsigned char*)m1;
const unsigned char* s2 = (const unsigned char*)m2;
for (size_t i = 0; i < n; i++) {
if (s1[i] != s2[i]) {
return (int)s1[i] - (int)s2[i];
}
}
return 0;
}
int (*libc_memcmp)(const void* s1, const void* s2, size_t n) = _memcmp;
static void* getsym(const char* sym) {
#if defined(RTLD_NEXT)
return dlsym(RTLD_NEXT, sym);
#else /* defined(RTLD_NEXT) */
void* dlh = dlopen(NULL, RTLD_LAZY);
if (!dlh) {
return NULL;
}
return dlsym(dlh, sym);
#endif /* defined(RTLD_NEXT) */
}
static void initializeLibcFunctions(void) {
libc_memcmp = (int (*)(const void* s1, const void* s2, size_t n))getsym("mem
cmp");
if (!libc_memcmp) {
LOG_W("dlsym(memcmp) failed: %s", dlerror());
libc_memcmp = _memcmp;
}
LOG_D("libc_memcmp=%p, (_memcmp=%p, memcmp=%p)", libc_memcmp, _memcmp, memcm
p);
}
static void* initialzeTryMapHugeTLB(int fd, size_t sz) {
int mflags = 0;
#if defined(_HF_ARCH_LINUX)
/*
* Try to map the local structure using HugeTLB. It'll be way fatser later t
o clean it with
* { ftruncate(fd, 0); ftruncate(fd, size); }
*/
mflags = files_getTmpMapFlags(MAP_SHARED | MAP_HUGE_2MB, /* nocore= */ true)
;
void* ret = mmap(NULL, sz, PROT_READ | PROT_WRITE, mflags, fd, 0);
#if defined(__x86_64__) || defined(__i386__)
if (ret == MAP_FAILED) {
PLOG_W("mmap(sz=%zu fd=%d flags=MAP_SHARED|MAP_HUGE_2MB) failed", sz, fd
);
}
#endif /* defined(__x86_64__) || defined(__i386__) */
if (ret != MAP_FAILED) {
return ret;
}
#endif /* defined(_HF_ARCH_LINUX) */
mflags = files_getTmpMapFlags(MAP_SHARED, /* nocore= */ true);
return mmap(NULL, sz, PROT_READ | PROT_WRITE, mflags, fd, 0);
}
static void initializeCmpFeedback(void) { static void initializeCmpFeedback(void) {
struct stat st; struct stat st;
if (fstat(_HF_CMP_BITMAP_FD, &st) == -1) { if (fstat(_HF_CMP_BITMAP_FD, &st) == -1) {
return; return;
} }
if (st.st_size != sizeof(cmpfeedback_t)) { if (st.st_size != sizeof(cmpfeedback_t)) {
LOG_W("Size of the cmpFeedback structure mismatch: st.size != sizeof(cmp LOG_W(
feedback_t) (%zu " "Size of the globalCmpFeedback structure mismatch: st.size != sizeof
"!= %zu). Link your fuzzed binaries with the newest honggfuzz and (cmpfeedback_t) "
hfuzz-clang(++)", "(%zu != %zu). Link your fuzzed binaries with the newest honggfuzz a
nd hfuzz-clang(++)",
(size_t)st.st_size, sizeof(cmpfeedback_t)); (size_t)st.st_size, sizeof(cmpfeedback_t));
return; return;
} }
int mflags = files_getTmpMapFlags(MAP_SHARED, /* nocore= */ true); void* ret = initialzeTryMapHugeTLB(_HF_CMP_BITMAP_FD, sizeof(cmpfeedback_t))
if ((cmpFeedback = mmap(NULL, sizeof(cmpfeedback_t), PROT_READ | PROT_WRITE, ;
mflags, if (ret == MAP_FAILED) {
_HF_CMP_BITMAP_FD, 0)) == MAP_FAILED) { PLOG_W("mmap(_HF_CMP_BITMAP_FD=%d, size=%zu) of the feedback structure f
PLOG_W("mmap(_HF_CMP_BITMAP_FD==%d, size=%zu) of the feedback structure ailed",
failed",
_HF_CMP_BITMAP_FD, sizeof(cmpfeedback_t)); _HF_CMP_BITMAP_FD, sizeof(cmpfeedback_t));
cmpFeedback = NULL;
return; return;
} }
ATOMIC_SET(globalCmpFeedback, ret);
} }
static bool initializeCovFeedback(void) { static bool initializeLocalCovFeedback(void) {
struct stat st;
if (fstat(_HF_PERTHREAD_BITMAP_FD, &st) == -1) {
return false;
}
if ((size_t)st.st_size < sizeof(feedback_t)) {
LOG_W("Size of the feedback structure mismatch: st.size < sizeof(feedbac
k_t) (%zu < "
"%zu). Build your honggfuzz binary from newer sources",
(size_t)st.st_size, sizeof(feedback_t));
return false;
}
localCovFeedback = initialzeTryMapHugeTLB(_HF_PERTHREAD_BITMAP_FD, sizeof(fe
edback_t));
if (localCovFeedback == MAP_FAILED) {
PLOG_W("mmap(_HF_PERTHREAD_BITMAP_FD=%d, size=%zu) of the local feedback
structure failed",
_HF_PERTHREAD_BITMAP_FD, sizeof(feedback_t));
return false;
}
return true;
}
static bool initializeGlobalCovFeedback(void) {
struct stat st; struct stat st;
if (fstat(_HF_COV_BITMAP_FD, &st) == -1) { if (fstat(_HF_COV_BITMAP_FD, &st) == -1) {
return false; return false;
} }
if (st.st_size != sizeof(feedback_t)) { if ((size_t)st.st_size < sizeof(feedback_t)) {
LOG_W("Size of the feedback structure mismatch: st.size != sizeof(feedba LOG_W("Size of the feedback structure mismatch: st.size < sizeof(feedbac
ck_t) (%zu != " k_t) (%zu < %zu). "
"%zu). Link your fuzzed binaries with the newest honggfuzz and hfu "Build your honggfuzz binary from newer sources",
zz-clang(++)",
(size_t)st.st_size, sizeof(feedback_t)); (size_t)st.st_size, sizeof(feedback_t));
return false; return false;
} }
int mflags = files_getTmpMapFlags(MAP_SHARED, /* nocore= */ true);
if ((covFeedback = mmap(NULL, sizeof(feedback_t), PROT_READ | PROT_WRITE, mf globalCovFeedback = initialzeTryMapHugeTLB(_HF_COV_BITMAP_FD, sizeof(feedbac
lags, k_t));
_HF_COV_BITMAP_FD, 0)) == MAP_FAILED) { if (globalCovFeedback == MAP_FAILED) {
PLOG_W("mmap(_HF_COV_BITMAP_FD=%d, size=%zu) of the feedback structure f ailed", PLOG_W("mmap(_HF_COV_BITMAP_FD=%d, size=%zu) of the feedback structure f ailed",
_HF_COV_BITMAP_FD, sizeof(feedback_t)); _HF_COV_BITMAP_FD, sizeof(feedback_t));
return false; return false;
} }
return true; return true;
} }
static void initializeInstrument(void) { static void initializeInstrument(void) {
if (fcntl(_HF_LOG_FD, F_GETFD) != -1) { if (fcntl(_HF_LOG_FD, F_GETFD) != -1) {
enum llevel_t ll = INFO; enum llevel_t ll = INFO;
const char* llstr = getenv(_HF_LOG_LEVEL_ENV); const char* llstr = getenv(_HF_LOG_LEVEL_ENV);
if (llstr) { if (llstr) {
ll = atoi(llstr); ll = atoi(llstr);
} }
logInitLogFile(NULL, _HF_LOG_FD, ll); logInitLogFile(NULL, _HF_LOG_FD, ll);
} }
LOG_D("Initializing pid=%d", (int)getpid());
char* my_thread_no_str = getenv(_HF_THREAD_NO_ENV); char* my_thread_no_str = getenv(_HF_THREAD_NO_ENV);
if (my_thread_no_str == NULL) { if (my_thread_no_str == NULL) {
LOG_D("The '%s' envvar is not set", _HF_THREAD_NO_ENV); LOG_D("The '%s' envvar is not set", _HF_THREAD_NO_ENV);
return; return;
} }
my_thread_no = atoi(my_thread_no_str); my_thread_no = atoi(my_thread_no_str);
if (my_thread_no >= _HF_THREAD_MAX) { if (my_thread_no >= _HF_THREAD_MAX) {
LOG_F("Received (via envvar) my_thread_no > _HF_THREAD_MAX (%" PRIu32 " > %d)\n", LOG_F("Received (via envvar) my_thread_no > _HF_THREAD_MAX (%" PRIu32 " > %d)\n",
my_thread_no, _HF_THREAD_MAX); my_thread_no, _HF_THREAD_MAX);
} }
if (!initializeCovFeedback()) { if (!initializeGlobalCovFeedback()) {
covFeedback = &bbMapFb; globalCovFeedback = &bbMapFb;
LOG_F("Could not intialize the coverage feedback map"); LOG_F("Could not intialize the global coverage feedback map");
}
if (!initializeLocalCovFeedback()) {
localCovFeedback = &bbMapFb;
LOG_F("Could not intialize the local coverage feedback map");
} }
initializeCmpFeedback(); initializeCmpFeedback();
/* Initialize native functions found in libc */
initializeLibcFunctions();
/* Reset coverage counters to their initial state */ /* Reset coverage counters to their initial state */
instrumentClearNewCov(); instrumentClearNewCov();
} }
static __thread pthread_once_t localInitOnce = PTHREAD_ONCE_INIT; static __thread pthread_once_t localInitOnce = PTHREAD_ONCE_INIT;
extern void hfuzzInstrumentInit(void); extern void hfuzzInstrumentInit(void);
__attribute__((constructor)) void hfuzzInstrumentInit(void) { __attribute__((constructor)) void hfuzzInstrumentInit(void) {
pthread_once(&localInitOnce, initializeInstrument); pthread_once(&localInitOnce, initializeInstrument);
} }
static int _memcmp(const uint8_t* m1, const uint8_t* m2, size_t n) { __attribute__((weak)) size_t instrumentReserveGuard(size_t cnt) {
for (size_t i = 0; i < n; i++) { static size_t guardCnt = 1;
if (m1[i] != m2[i]) { size_t base = guardCnt;
return ((int)m1[i] - (int)m2[i]); guardCnt += cnt;
if (guardCnt >= _HF_PC_GUARD_MAX) {
LOG_F(
"This process requested too many PC-guards, total:%zu, requested:%zu
)", guardCnt, cnt);
}
if (ATOMIC_GET(globalCovFeedback->guardNb) < guardCnt) {
ATOMIC_SET(globalCovFeedback->guardNb, guardCnt);
wmb();
}
return base;
}
void instrumentResetLocalCovFeedback(void) {
bzero(localCovFeedback->pcGuardMap, HF_MIN(instrumentReserveGuard(0), _HF_PC
_GUARD_MAX));
wmb();
}
/* Used to limit certain expensive actions, like adding values to dictionaries *
/
static inline bool instrumentLimitEvery(uint64_t step) {
static __thread uint64_t staticCnt = 0;
if (((staticCnt++) % step) == 0) {
return true;
}
return false;
}
static inline void instrumentAddConstMemInternal(const void* mem, size_t len) {
if (len == 0) {
return;
}
if (len > sizeof(globalCmpFeedback->valArr[0].val)) {
len = sizeof(globalCmpFeedback->valArr[0].val);
}
uint32_t curroff = ATOMIC_GET(globalCmpFeedback->cnt);
if (curroff >= ARRAYSIZE(globalCmpFeedback->valArr)) {
return;
}
for (uint32_t i = 0; i < curroff; i++) {
if ((len == ATOMIC_GET(globalCmpFeedback->valArr[i].len)) &&
libc_memcmp(globalCmpFeedback->valArr[i].val, mem, len) == 0) {
return;
} }
} }
return 0;
uint32_t newoff = ATOMIC_POST_INC(globalCmpFeedback->cnt);
if (newoff >= ARRAYSIZE(globalCmpFeedback->valArr)) {
ATOMIC_SET(globalCmpFeedback->cnt, ARRAYSIZE(globalCmpFeedback->valArr))
;
return;
}
memcpy(globalCmpFeedback->valArr[newoff].val, mem, len);
ATOMIC_SET(globalCmpFeedback->valArr[newoff].len, len);
wmb();
} }
/* /*
* -finstrument-functions * -finstrument-functions
*/ */
HF_REQUIRE_SSE42_POPCNT void __cyg_profile_func_enter(void* func, void* caller) { HF_REQUIRE_SSE42_POPCNT void __cyg_profile_func_enter(void* func, void* caller) {
register size_t pos = register size_t pos =
(((uintptr_t)func << 12) | ((uintptr_t)caller & 0xFFF)) & _HF_PERF_BITMA P_BITSZ_MASK; (((uintptr_t)func << 12) | ((uintptr_t)caller & 0xFFF)) & _HF_PERF_BITMA P_BITSZ_MASK;
register bool prev = ATOMIC_BITMAP_SET(covFeedback->bbMapPc, pos); register bool prev = ATOMIC_BITMAP_SET(globalCovFeedback->bbMapPc, pos);
if (!prev) { if (!prev) {
ATOMIC_PRE_INC_RELAXED(covFeedback->pidFeedbackPc[my_thread_no]); ATOMIC_PRE_INC(globalCovFeedback->pidNewPC[my_thread_no]);
wmb();
} }
} }
HF_REQUIRE_SSE42_POPCNT void __cyg_profile_func_exit( HF_REQUIRE_SSE42_POPCNT void __cyg_profile_func_exit(
void* func HF_ATTR_UNUSED, void* caller HF_ATTR_UNUSED) { void* func HF_ATTR_UNUSED, void* caller HF_ATTR_UNUSED) {
return; return;
} }
/* /*
* -fsanitize-coverage=trace-pc * -fsanitize-coverage=trace-pc
*/ */
HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_pc_internal(uintptr_t pc) { HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_pc_internal(uintptr_t pc) {
register uintptr_t ret = pc & _HF_PERF_BITMAP_BITSZ_MASK; register uintptr_t ret = pc & _HF_PERF_BITMAP_BITSZ_MASK;
register bool prev = ATOMIC_BITMAP_SET(covFeedback->bbMapPc, ret); register bool prev = ATOMIC_BITMAP_SET(globalCovFeedback->bbMapPc, ret);
if (!prev) { if (!prev) {
ATOMIC_PRE_INC_RELAXED(covFeedback->pidFeedbackPc[my_thread_no]); ATOMIC_PRE_INC(globalCovFeedback->pidNewPC[my_thread_no]);
wmb();
} }
} }
HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_pc(void) { HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_pc(void) {
hfuzz_trace_pc_internal((uintptr_t)__builtin_return_address(0)); hfuzz_trace_pc_internal((uintptr_t)__builtin_return_address(0));
} }
HF_REQUIRE_SSE42_POPCNT void hfuzz_trace_pc(uintptr_t pc) { HF_REQUIRE_SSE42_POPCNT void hfuzz_trace_pc(uintptr_t pc) {
hfuzz_trace_pc_internal(pc); hfuzz_trace_pc_internal(pc);
} }
/* /*
* -fsanitize-coverage=trace-cmp * -fsanitize-coverage=trace-cmp
*/ */
HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_cmp1_internal( HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_cmp1_internal(
uintptr_t pc, uint8_t Arg1, uint8_t Arg2) { uintptr_t pc, uint8_t Arg1, uint8_t Arg2) {
uintptr_t pos = pc % _HF_PERF_BITMAP_SIZE_16M; uintptr_t pos = pc % _HF_PERF_BITMAP_SIZE_16M;
register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2)); register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2));
uint8_t prev = ATOMIC_GET(covFeedback->bbMapCmp[pos]); uint8_t prev = ATOMIC_GET(globalCovFeedback->bbMapCmp[pos]);
if (prev < v) { if (prev < v) {
ATOMIC_SET(covFeedback->bbMapCmp[pos], v); ATOMIC_SET(globalCovFeedback->bbMapCmp[pos], v);
ATOMIC_POST_ADD(covFeedback->pidFeedbackCmp[my_thread_no], v - prev); ATOMIC_POST_ADD(globalCovFeedback->pidNewCmp[my_thread_no], v - prev);
wmb();
} }
} }
HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_cmp2_internal( HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_cmp2_internal(
uintptr_t pc, uint16_t Arg1, uint16_t Arg2) { uintptr_t pc, uint16_t Arg1, uint16_t Arg2) {
uintptr_t pos = pc % _HF_PERF_BITMAP_SIZE_16M; uintptr_t pos = pc % _HF_PERF_BITMAP_SIZE_16M;
register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2)); register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2));
uint8_t prev = ATOMIC_GET(covFeedback->bbMapCmp[pos]); uint8_t prev = ATOMIC_GET(globalCovFeedback->bbMapCmp[pos]);
if (prev < v) { if (prev < v) {
ATOMIC_SET(covFeedback->bbMapCmp[pos], v); ATOMIC_SET(globalCovFeedback->bbMapCmp[pos], v);
ATOMIC_POST_ADD(covFeedback->pidFeedbackCmp[my_thread_no], v - prev); ATOMIC_POST_ADD(globalCovFeedback->pidNewCmp[my_thread_no], v - prev);
wmb();
} }
} }
HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_cmp4_internal( HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_cmp4_internal(
uintptr_t pc, uint32_t Arg1, uint32_t Arg2) { uintptr_t pc, uint32_t Arg1, uint32_t Arg2) {
uintptr_t pos = pc % _HF_PERF_BITMAP_SIZE_16M; uintptr_t pos = pc % _HF_PERF_BITMAP_SIZE_16M;
register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2)); register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcount(Arg1 ^ Arg2));
uint8_t prev = ATOMIC_GET(covFeedback->bbMapCmp[pos]); uint8_t prev = ATOMIC_GET(globalCovFeedback->bbMapCmp[pos]);
if (prev < v) { if (prev < v) {
ATOMIC_SET(covFeedback->bbMapCmp[pos], v); ATOMIC_SET(globalCovFeedback->bbMapCmp[pos], v);
ATOMIC_POST_ADD(covFeedback->pidFeedbackCmp[my_thread_no], v - prev); ATOMIC_POST_ADD(globalCovFeedback->pidNewCmp[my_thread_no], v - prev);
wmb();
} }
} }
HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_cmp8_internal( HF_REQUIRE_SSE42_POPCNT static inline void hfuzz_trace_cmp8_internal(
uintptr_t pc, uint64_t Arg1, uint64_t Arg2) { uintptr_t pc, uint64_t Arg1, uint64_t Arg2) {
uintptr_t pos = pc % _HF_PERF_BITMAP_SIZE_16M; uintptr_t pos = pc % _HF_PERF_BITMAP_SIZE_16M;
register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcountll(Arg1 ^ Arg2) ); register uint8_t v = ((sizeof(Arg1) * 8) - __builtin_popcountll(Arg1 ^ Arg2) );
uint8_t prev = ATOMIC_GET(covFeedback->bbMapCmp[pos]); uint8_t prev = ATOMIC_GET(globalCovFeedback->bbMapCmp[pos]);
if (prev < v) { if (prev < v) {
ATOMIC_SET(covFeedback->bbMapCmp[pos], v); ATOMIC_SET(globalCovFeedback->bbMapCmp[pos], v);
ATOMIC_POST_ADD(covFeedback->pidFeedbackCmp[my_thread_no], v - prev); ATOMIC_POST_ADD(globalCovFeedback->pidNewCmp[my_thread_no], v - prev);
wmb();
} }
} }
/* Standard __sanitizer_cov_trace_cmp wrappers */ /* Standard __sanitizer_cov_trace_cmp wrappers */
void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) { void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) {
hfuzz_trace_cmp1_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 ); hfuzz_trace_cmp1_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 );
} }
void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) { void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) {
hfuzz_trace_cmp2_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 ); hfuzz_trace_cmp2_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 );
} }
void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) { void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) {
/* Add 4byte values to the const_dictionary if they exist within the binary
*/
if (globalCmpFeedback && instrumentLimitEvery(4095)) {
if (Arg1 > 0xffff) {
uint32_t bswp = __builtin_bswap32(Arg1);
if (util_32bitValInBinary(Arg1) || util_32bitValInBinary(bswp)) {
instrumentAddConstMemInternal(&Arg1, sizeof(Arg1));
instrumentAddConstMemInternal(&bswp, sizeof(bswp));
}
}
if (Arg2 > 0xffff) {
uint32_t bswp = __builtin_bswap32(Arg2);
if (util_32bitValInBinary(Arg2) || util_32bitValInBinary(bswp)) {
instrumentAddConstMemInternal(&Arg2, sizeof(Arg2));
instrumentAddConstMemInternal(&bswp, sizeof(bswp));
}
}
}
hfuzz_trace_cmp4_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 ); hfuzz_trace_cmp4_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 );
} }
void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) { void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) {
/* Add 8byte values to the const_dictionary if they exist within the binary
*/
if (globalCmpFeedback && instrumentLimitEvery(4095)) {
if (Arg1 > 0xffffff) {
uint64_t bswp = __builtin_bswap64(Arg1);
if (util_64bitValInBinary(Arg1) || util_64bitValInBinary(bswp)) {
instrumentAddConstMemInternal(&Arg1, sizeof(Arg1));
instrumentAddConstMemInternal(&bswp, sizeof(bswp));
}
}
if (Arg2 > 0xffffff) {
uint64_t bswp = __builtin_bswap64(Arg2);
if (util_64bitValInBinary(Arg2) || util_64bitValInBinary(bswp)) {
instrumentAddConstMemInternal(&Arg2, sizeof(Arg2));
instrumentAddConstMemInternal(&bswp, sizeof(bswp));
}
}
}
hfuzz_trace_cmp8_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 ); hfuzz_trace_cmp8_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 );
} }
/* Standard __sanitizer_cov_trace_const_cmp wrappers */ /* Standard __sanitizer_cov_trace_const_cmp wrappers */
void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2) { void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2) {
/* No need to report back 1 byte comparisons */ instrumentAddConstMem(&Arg1, sizeof(Arg1), /* check_if_ro= */ false);
hfuzz_trace_cmp1_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 ); hfuzz_trace_cmp1_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 );
} }
void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2) { void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2) {
instrumentAddConstMem(&Arg1, sizeof(Arg1), /* check_if_ro= */ false); if (Arg1) {
uint16_t bswp = __builtin_bswap16(Arg1);
instrumentAddConstMem(&bswp, sizeof(bswp), /* check_if_ro= */ false);
instrumentAddConstMem(&Arg1, sizeof(Arg1), /* check_if_ro= */ false);
}
hfuzz_trace_cmp2_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 ); hfuzz_trace_cmp2_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 );
} }
void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2) { void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2) {
instrumentAddConstMem(&Arg1, sizeof(Arg1), /* check_if_ro= */ false); if (Arg1) {
uint32_t bswp = __builtin_bswap32(Arg1);
instrumentAddConstMem(&bswp, sizeof(bswp), /* check_if_ro= */ false);
instrumentAddConstMem(&Arg1, sizeof(Arg1), /* check_if_ro= */ false);
}
hfuzz_trace_cmp4_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 ); hfuzz_trace_cmp4_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 );
} }
void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2) { void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2) {
instrumentAddConstMem(&Arg1, sizeof(Arg1), /* check_if_ro= */ false); if (Arg1) {
uint64_t bswp = __builtin_bswap64(Arg1);
instrumentAddConstMem(&bswp, sizeof(bswp), /* check_if_ro= */ false);
instrumentAddConstMem(&Arg1, sizeof(Arg1), /* check_if_ro= */ false);
}
hfuzz_trace_cmp8_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 ); hfuzz_trace_cmp8_internal((uintptr_t)__builtin_return_address(0), Arg1, Arg2 );
} }
/* Custom functions for e.g. the qemu-honggfuzz code */ /* Custom functions for e.g. the qemu-honggfuzz code */
void hfuzz_trace_cmp1(uintptr_t pc, uint8_t Arg1, uint8_t Arg2) { void hfuzz_trace_cmp1(uintptr_t pc, uint8_t Arg1, uint8_t Arg2) {
hfuzz_trace_cmp1_internal(pc, Arg1, Arg2); hfuzz_trace_cmp1_internal(pc, Arg1, Arg2);
} }
void hfuzz_trace_cmp2(uintptr_t pc, uint16_t Arg1, uint16_t Arg2) { void hfuzz_trace_cmp2(uintptr_t pc, uint16_t Arg1, uint16_t Arg2) {
hfuzz_trace_cmp2_internal(pc, Arg1, Arg2); hfuzz_trace_cmp2_internal(pc, Arg1, Arg2);
skipping to change at line 305 skipping to change at line 508
} }
/* /*
* Cases[0] is number of comparison entries * Cases[0] is number of comparison entries
* Cases[1] is length of Val in bits * Cases[1] is length of Val in bits
*/ */
HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t * Cases) { HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t * Cases) {
for (uint64_t i = 0; i < Cases[0]; i++) { for (uint64_t i = 0; i < Cases[0]; i++) {
uintptr_t pos = ((uintptr_t)__builtin_return_address(0) + i) % _HF_PERF_ BITMAP_SIZE_16M; uintptr_t pos = ((uintptr_t)__builtin_return_address(0) + i) % _HF_PERF_ BITMAP_SIZE_16M;
uint8_t v = (uint8_t)Cases[1] - __builtin_popcountll(Val ^ Cases[i + 2]) ; uint8_t v = (uint8_t)Cases[1] - __builtin_popcountll(Val ^ Cases[i + 2]) ;
uint8_t prev = ATOMIC_GET(covFeedback->bbMapCmp[pos]); uint8_t prev = ATOMIC_GET(globalCovFeedback->bbMapCmp[pos]);
if (prev < v) { if (prev < v) {
ATOMIC_SET(covFeedback->bbMapCmp[pos], v); ATOMIC_SET(globalCovFeedback->bbMapCmp[pos], v);
ATOMIC_POST_ADD(covFeedback->pidFeedbackCmp[my_thread_no], v - prev) ATOMIC_POST_ADD(globalCovFeedback->pidNewCmp[my_thread_no], v - prev
; );
wmb();
} }
} }
} }
/* /*
* gcc-8 -fsanitize-coverage=trace-cmp trace hooks * gcc-8 -fsanitize-coverage=trace-cmp trace hooks
* TODO: evaluate, whether it makes sense to implement them * TODO: evaluate, whether it makes sense to implement them
*/ */
HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_cmpf( HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_cmpf(
float Arg1 HF_ATTR_UNUSED, float Arg2 HF_ATTR_UNUSED) { float Arg1 HF_ATTR_UNUSED, float Arg2 HF_ATTR_UNUSED) {
skipping to change at line 330 skipping to change at line 534
HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_cmpd( HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_cmpd(
double Arg1 HF_ATTR_UNUSED, double Arg2 HF_ATTR_UNUSED) { double Arg1 HF_ATTR_UNUSED, double Arg2 HF_ATTR_UNUSED) {
} }
/* /*
* -fsanitize-coverage=trace-div * -fsanitize-coverage=trace-div
*/ */
HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_div8(uint64_t Val) { HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_div8(uint64_t Val) {
uintptr_t pos = (uintptr_t)__builtin_return_address(0) % _HF_PERF_BITMAP_SIZ E_16M; uintptr_t pos = (uintptr_t)__builtin_return_address(0) % _HF_PERF_BITMAP_SIZ E_16M;
uint8_t v = ((sizeof(Val) * 8) - __builtin_popcountll(Val)); uint8_t v = ((sizeof(Val) * 8) - __builtin_popcountll(Val));
uint8_t prev = ATOMIC_GET(covFeedback->bbMapCmp[pos]); uint8_t prev = ATOMIC_GET(globalCovFeedback->bbMapCmp[pos]);
if (prev < v) { if (prev < v) {
ATOMIC_SET(covFeedback->bbMapCmp[pos], v); ATOMIC_SET(globalCovFeedback->bbMapCmp[pos], v);
ATOMIC_POST_ADD(covFeedback->pidFeedbackCmp[my_thread_no], v - prev); ATOMIC_POST_ADD(globalCovFeedback->pidNewCmp[my_thread_no], v - prev);
wmb();
} }
} }
HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_div4(uint32_t Val) { HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_div4(uint32_t Val) {
uintptr_t pos = (uintptr_t)__builtin_return_address(0) % _HF_PERF_BITMAP_SIZ E_16M; uintptr_t pos = (uintptr_t)__builtin_return_address(0) % _HF_PERF_BITMAP_SIZ E_16M;
uint8_t v = ((sizeof(Val) * 8) - __builtin_popcount(Val)); uint8_t v = ((sizeof(Val) * 8) - __builtin_popcount(Val));
uint8_t prev = ATOMIC_GET(covFeedback->bbMapCmp[pos]); uint8_t prev = ATOMIC_GET(globalCovFeedback->bbMapCmp[pos]);
if (prev < v) { if (prev < v) {
ATOMIC_SET(covFeedback->bbMapCmp[pos], v); ATOMIC_SET(globalCovFeedback->bbMapCmp[pos], v);
ATOMIC_POST_ADD(covFeedback->pidFeedbackCmp[my_thread_no], v - prev); ATOMIC_POST_ADD(globalCovFeedback->pidNewCmp[my_thread_no], v - prev);
wmb();
} }
} }
/* /*
* -fsanitize-coverage=indirect-calls * -fsanitize-coverage=indirect-calls
*/ */
HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_pc_indir(uintptr_t callee) { HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_pc_indir(uintptr_t callee) {
register size_t pos1 = (uintptr_t)__builtin_return_address(0) << 12; register size_t pos1 = (uintptr_t)__builtin_return_address(0) << 12;
register size_t pos2 = callee & 0xFFF; register size_t pos2 = callee & 0xFFF;
register size_t pos = (pos1 | pos2) & _HF_PERF_BITMAP_BITSZ_MASK; register size_t pos = (pos1 | pos2) & _HF_PERF_BITMAP_BITSZ_MASK;
register bool prev = ATOMIC_BITMAP_SET(covFeedback->bbMapPc, pos); register bool prev = ATOMIC_BITMAP_SET(globalCovFeedback->bbMapPc, pos);
if (!prev) { if (!prev) {
ATOMIC_PRE_INC_RELAXED(covFeedback->pidFeedbackPc[my_thread_no]); ATOMIC_PRE_INC(globalCovFeedback->pidNewPC[my_thread_no]);
wmb();
} }
} }
/* /*
* In LLVM-4.0 it's marked (probably mistakenly) as non-weak symbol, so we need to mark it as weak * In LLVM-4.0 it's marked (probably mistakenly) as non-weak symbol, so we need to mark it as weak
* here * here
*/ */
__attribute__((weak)) HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_indir_call16( __attribute__((weak)) HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_indir_call16(
void* callee, void* callee_cache16[] HF_ATTR_UNUSED) { void* callee, void* callee_cache16[] HF_ATTR_UNUSED) {
register size_t pos1 = (uintptr_t)__builtin_return_address(0) << 12; register size_t pos1 = (uintptr_t)__builtin_return_address(0) << 12;
register size_t pos2 = (uintptr_t)callee & 0xFFF; register size_t pos2 = (uintptr_t)callee & 0xFFF;
register size_t pos = (pos1 | pos2) & _HF_PERF_BITMAP_BITSZ_MASK; register size_t pos = (pos1 | pos2) & _HF_PERF_BITMAP_BITSZ_MASK;
register bool prev = ATOMIC_BITMAP_SET(covFeedback->bbMapPc, pos); register bool prev = ATOMIC_BITMAP_SET(globalCovFeedback->bbMapPc, pos);
if (!prev) { if (!prev) {
ATOMIC_PRE_INC_RELAXED(covFeedback->pidFeedbackPc[my_thread_no]); ATOMIC_PRE_INC(globalCovFeedback->pidNewPC[my_thread_no]);
wmb();
} }
} }
/* /*
* -fsanitize-coverage=trace-pc-guard * -fsanitize-coverage=trace-pc-guard
*/ */
static bool guards_initialized = false; static bool guards_initialized = false;
HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_pc_guard_init(uint32_t* start , uint32_t* stop) { HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_pc_guard_init(uint32_t* start , uint32_t* stop) {
guards_initialized = true; guards_initialized = true;
static uint32_t n = 1U;
/* Make sure that the feedback struct is already mmap()'d */ /* Make sure that the feedback struct is already mmap()'d */
hfuzzInstrumentInit(); hfuzzInstrumentInit();
if ((uintptr_t)start == (uintptr_t)stop) {
return;
}
/* If this module was already initialized, skip it */ /* If this module was already initialized, skip it */
if (*start > 0) { if (*start > 0) {
LOG_D("Module %p-%p is already initialized", start, stop); LOG_D("Module %p-%p is already initialized", start, stop);
return; return;
} }
LOG_D("Module initialization: %p-%p at %" PRId32, start, stop, n); LOG_D("PC-Guard module initialization: %p-%p (count:%tu) at %zu", start, sto
for (uint32_t* x = start; x < stop; x++, n++) { p,
if (n >= _HF_PC_GUARD_MAX) { ((uintptr_t)stop - (uintptr_t)start) / sizeof(*start), instrumentReserve
LOG_F("This process has too many PC guards:%" PRIu32 Guard(0));
" (current module:%tu start:%p stop:%p)\n",
n, ((uintptr_t)stop - (uintptr_t)start) / sizeof(start), start,
stop);
}
/* If the corresponding PC was already hit, map this specific guard as u
ninteresting (0) */
*x = ATOMIC_GET(covFeedback->pcGuardMap[n]) ? 0U : n;
}
/* Store number of guards for statistical purposes */ for (uint32_t* x = start; x < stop; x++) {
if (ATOMIC_GET(covFeedback->guardNb) < n - 1) { uint32_t guardNo = instrumentReserveGuard(1);
ATOMIC_SET(covFeedback->guardNb, n - 1); *x = guardNo;
} }
}
wmb();
}
/* Map number of visits to an edge into buckets */
static uint8_t const instrumentCntMap[256] = {
[0] = 0,
[1] = 1U << 0,
[2] = 1U << 1,
[3] = 1U << 2,
[4 ... 5] = 1U << 3,
[6 ... 10] = 1U << 4,
[11 ... 32] = 1U << 5,
[33 ... 64] = 1U << 6,
[65 ... 255] = 1U << 7,
};
HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_pc_guard(uint32_t* guard) { HF_REQUIRE_SSE42_POPCNT void __sanitizer_cov_trace_pc_guard(uint32_t* guard_ptr) {
#if defined(__ANDROID__) #if defined(__ANDROID__)
// ANDROID: Bionic invokes routines that Honggfuzz wraps, before either /*
// *SAN or Honggfuzz have initialized. Check to see if Honggfuzz * ANDROID: Bionic invokes routines that Honggfuzz wraps, before either
// has initialized -- if not, force *SAN to initialize (otherwise * *SAN or Honggfuzz have initialized. Check to see if Honggfuzz
// _strcmp() will crash, as it is *SAN-instrumented). * has initialized -- if not, force *SAN to initialize (otherwise
// * _strcmp() will crash, as it is *SAN-instrumented).
// Defer all trace_pc_guard activity until trace_pc_guard_init is *
// invoked via sancov.module_ctor in the normal process of things. * Defer all trace_pc_guard activity until trace_pc_guard_init is
* invoked via sancov.module_ctor in the normal process of things.
*/
if (!guards_initialized) { if (!guards_initialized) {
void __asan_init(void) __attribute__((weak)); void __asan_init(void) __attribute__((weak));
if (__asan_init) { if (__asan_init) {
__asan_init(); __asan_init();
} }
void __msan_init(void) __attribute__((weak)); void __msan_init(void) __attribute__((weak));
if (__msan_init) { if (__msan_init) {
__msan_init(); __msan_init();
} }
void __ubsan_init(void) __attribute__((weak)); void __ubsan_init(void) __attribute__((weak));
if (__ubsan_init) { if (__ubsan_init) {
__ubsan_init(); __ubsan_init();
} }
void __tsan_init(void) __attribute__((weak)); void __tsan_init(void) __attribute__((weak));
if (__tsan_init) { if (__tsan_init) {
__tsan_init(); __tsan_init();
} }
return; return;
} }
#endif /* defined(__ANDROID__) */ #endif /* defined(__ANDROID__) */
if (!ATOMIC_GET(covFeedback->pcGuardMap[*guard])) {
bool prev = ATOMIC_XCHG(covFeedback->pcGuardMap[*guard], true); /* This guard is uninteresting, it was probably maxed out already */
if (prev == false) { const uint32_t guard = *guard_ptr;
ATOMIC_PRE_INC_RELAXED(covFeedback->pidFeedbackEdge[my_thread_no]); if (!guard) {
return;
}
if (ATOMIC_GET(localCovFeedback->pcGuardMap[guard]) > 100) {
/* This guard has been maxed out. Mark it as uninteresting */
ATOMIC_CLEAR(*guard_ptr);
}
/* Update the total/local counters */
const uint8_t v = ATOMIC_PRE_INC(localCovFeedback->pcGuardMap[guard]);
if (v == 1) {
ATOMIC_PRE_INC(globalCovFeedback->pidTotalEdge[my_thread_no]);
} else {
ATOMIC_PRE_INC(globalCovFeedback->pidTotalCmp[my_thread_no]);
}
/* Update the new/global counters */
const uint8_t newval = instrumentCntMap[v];
if (ATOMIC_GET(globalCovFeedback->pcGuardMap[guard]) < newval) {
const uint8_t oldval = ATOMIC_POST_OR(globalCovFeedback->pcGuardMap[guar
d], newval);
if (!oldval) {
ATOMIC_PRE_INC(globalCovFeedback->pidNewEdge[my_thread_no]);
} else if (oldval < newval) {
ATOMIC_PRE_INC(globalCovFeedback->pidNewCmp[my_thread_no]);
} }
} }
wmb();
} }
/* Support up to 256 DSO modules with separate 8bit counters */
static struct {
uint8_t* start;
size_t cnt;
size_t guard;
} hf8bitcounters[256] = {};
void instrument8BitCountersCount(void) {
rmb();
uint64_t totalEdge = 0;
uint64_t totalCmp = 0;
for (size_t i = 0; i < ARRAYSIZE(hf8bitcounters) && hf8bitcounters[i].start;
i++) {
for (size_t j = 0; j < hf8bitcounters[i].cnt; j++) {
const uint8_t v = hf8bitcounters[i].start[j];
hf8bitcounters[i].start[j] = 0;
if (!v) {
continue;
}
const uint8_t newval = instrumentCntMap[v];
const size_t guard = hf8bitcounters[i].guard + j;
/* New hits */
if (ATOMIC_GET(globalCovFeedback->pcGuardMap[guard]) < newval) {
const uint8_t oldval = ATOMIC_POST_OR(globalCovFeedback->pcGuard
Map[guard], newval);
if (!oldval) {
ATOMIC_PRE_INC(globalCovFeedback->pidNewEdge[my_thread_no]);
} else if (oldval < newval) {
ATOMIC_PRE_INC(globalCovFeedback->pidNewCmp[my_thread_no]);
}
}
/* Total hits */
{
totalEdge++;
if (v > 1) {
totalCmp += newval;
}
}
}
}
ATOMIC_POST_ADD(globalCovFeedback->pidTotalEdge[my_thread_no], totalEdge);
ATOMIC_POST_ADD(globalCovFeedback->pidTotalCmp[my_thread_no], totalCmp);
wmb();
}
void __sanitizer_cov_8bit_counters_init(char* start, char* end) {
/* Make sure that the feedback struct is already mmap()'d */
hfuzzInstrumentInit();
if ((uintptr_t)start == (uintptr_t)end) {
return;
}
for (size_t i = 0; i < ARRAYSIZE(hf8bitcounters); i++) {
if (hf8bitcounters[i].start == NULL) {
hf8bitcounters[i].start = (uint8_t*)start;
hf8bitcounters[i].cnt = (uintptr_t)end - (uintptr_t)start;
hf8bitcounters[i].guard = instrumentReserveGuard(hf8bitcounters[i].c
nt);
LOG_D("8-bit module initialization %p-%p (count:%zu) at guard %zu",
start, end,
hf8bitcounters[i].cnt, hf8bitcounters[i].guard);
break;
}
}
}
/* Not implemented yet */
void __sanitizer_cov_pcs_init(
const uintptr_t* pcs_beg HF_ATTR_UNUSED, const uintptr_t* pcs_end HF_ATTR_UN
USED) {
}
unsigned instrumentThreadNo(void) {
return my_thread_no;
}
/* Cygwin has problem with visibility of this symbol */
#if !defined(__CYGWIN__)
/* For some reason -fsanitize=fuzzer-no-link references this symbol */
__attribute__((tls_model("initial-exec")))
__attribute__((weak)) __thread uintptr_t __sancov_lowest_stack = 0;
#endif /* !defined(__CYGWIN__) */
bool instrumentUpdateCmpMap(uintptr_t addr, uint32_t v) { bool instrumentUpdateCmpMap(uintptr_t addr, uint32_t v) {
uintptr_t pos = addr % _HF_PERF_BITMAP_SIZE_16M; uintptr_t pos = addr % _HF_PERF_BITMAP_SIZE_16M;
uint32_t prev = ATOMIC_GET(covFeedback->bbMapCmp[pos]); uint32_t prev = ATOMIC_GET(globalCovFeedback->bbMapCmp[pos]);
if (prev < v) { if (prev < v) {
ATOMIC_SET(covFeedback->bbMapCmp[pos], v); ATOMIC_SET(globalCovFeedback->bbMapCmp[pos], v);
ATOMIC_POST_ADD(covFeedback->pidFeedbackCmp[my_thread_no], v - prev); ATOMIC_POST_ADD(globalCovFeedback->pidNewCmp[my_thread_no], v - prev);
wmb();
return true; return true;
} }
return false; return false;
} }
/* Reset the counters of newly discovered edges/pcs/features */ /* Reset the counters of newly discovered edges/pcs/features */
void instrumentClearNewCov() { void instrumentClearNewCov() {
covFeedback->pidFeedbackPc[my_thread_no] = 0U; ATOMIC_CLEAR(globalCovFeedback->pidNewPC[my_thread_no]);
covFeedback->pidFeedbackEdge[my_thread_no] = 0U; ATOMIC_CLEAR(globalCovFeedback->pidNewEdge[my_thread_no]);
covFeedback->pidFeedbackCmp[my_thread_no] = 0U; ATOMIC_CLEAR(globalCovFeedback->pidNewCmp[my_thread_no]);
ATOMIC_CLEAR(globalCovFeedback->pidTotalPC[my_thread_no]);
ATOMIC_CLEAR(globalCovFeedback->pidTotalEdge[my_thread_no]);
ATOMIC_CLEAR(globalCovFeedback->pidTotalCmp[my_thread_no]);
wmb();
} }
void instrumentAddConstMem(const void* mem, size_t len, bool check_if_ro) { void instrumentAddConstMem(const void* mem, size_t len, bool check_if_ro) {
if (!cmpFeedback) { if (!globalCmpFeedback) {
return; return;
} }
if (len > sizeof(cmpFeedback->valArr[0].val)) { if (len == 0) {
len = sizeof(cmpFeedback->valArr[0].val); return;
} }
uint32_t curroff = ATOMIC_GET(cmpFeedback->cnt); if (!instrumentLimitEvery(127)) {
if (curroff >= ARRAYSIZE(cmpFeedback->valArr)) {
return; return;
} }
if (check_if_ro && !util_isAddrRO(mem)) { if (check_if_ro && util_getProgAddr(mem) == LHFC_ADDR_NOTFOUND) {
return; return;
} }
instrumentAddConstMemInternal(mem, len);
}
for (uint32_t i = 0; i < curroff; i++) { void instrumentAddConstStr(const char* s) {
if ((len == cmpFeedback->valArr[i].len) && if (!globalCmpFeedback) {
_memcmp(cmpFeedback->valArr[i].val, mem, len) == 0) { return;
return; }
} if (!instrumentLimitEvery(127)) {
return;
}
if (util_getProgAddr(s) == LHFC_ADDR_NOTFOUND) {
return;
} }
instrumentAddConstMemInternal(s, strlen(s));
}
uint32_t newoff = ATOMIC_POST_INC(cmpFeedback->cnt); void instrumentAddConstStrN(const char* s, size_t n) {
if (newoff >= ARRAYSIZE(cmpFeedback->valArr)) { if (!globalCmpFeedback) {
ATOMIC_SET(cmpFeedback->cnt, ARRAYSIZE(cmpFeedback->valArr));
return; return;
} }
if (n == 0) {
return;
}
if (!instrumentLimitEvery(127)) {
return;
}
if (util_getProgAddr(s) == LHFC_ADDR_NOTFOUND) {
return;
}
instrumentAddConstMemInternal(s, strnlen(s, n));
}
memcpy(cmpFeedback->valArr[newoff].val, mem, len); bool instrumentConstAvail(void) {
ATOMIC_SET(cmpFeedback->valArr[newoff].len, len); return (ATOMIC_GET(globalCmpFeedback) != NULL);
} }
 End of changes. 69 change blocks. 
120 lines changed or deleted 492 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)