1*ef84fd3bSjoerg //===-- stats_client.cc ---------------------------------------------------===// 2*ef84fd3bSjoerg // 3*ef84fd3bSjoerg // The LLVM Compiler Infrastructure 4*ef84fd3bSjoerg // 5*ef84fd3bSjoerg // This file is distributed under the University of Illinois Open Source 6*ef84fd3bSjoerg // License. See LICENSE.TXT for details. 7*ef84fd3bSjoerg // 8*ef84fd3bSjoerg //===----------------------------------------------------------------------===// 9*ef84fd3bSjoerg // 10*ef84fd3bSjoerg // Sanitizer statistics gathering. Manages statistics for a module (executable 11*ef84fd3bSjoerg // or DSO) and registers statistics with the process. 12*ef84fd3bSjoerg // 13*ef84fd3bSjoerg // This is linked into each individual modle and cannot directly use functions 14*ef84fd3bSjoerg // declared in sanitizer_common. 15*ef84fd3bSjoerg // 16*ef84fd3bSjoerg //===----------------------------------------------------------------------===// 17*ef84fd3bSjoerg 18*ef84fd3bSjoerg #ifdef _WIN32 19*ef84fd3bSjoerg #include <windows.h> 20*ef84fd3bSjoerg #else 21*ef84fd3bSjoerg #include <dlfcn.h> 22*ef84fd3bSjoerg #endif 23*ef84fd3bSjoerg #include <stdint.h> 24*ef84fd3bSjoerg #include <stdio.h> 25*ef84fd3bSjoerg 26*ef84fd3bSjoerg #include "sanitizer_common/sanitizer_internal_defs.h" 27*ef84fd3bSjoerg #include "stats/stats.h" 28*ef84fd3bSjoerg 29*ef84fd3bSjoerg using namespace __sanitizer; 30*ef84fd3bSjoerg 31*ef84fd3bSjoerg namespace { 32*ef84fd3bSjoerg LookupSymbolFromMain(const char * name)33*ef84fd3bSjoergvoid *LookupSymbolFromMain(const char *name) { 34*ef84fd3bSjoerg #ifdef _WIN32 35*ef84fd3bSjoerg return reinterpret_cast<void *>(GetProcAddress(GetModuleHandle(0), name)); 36*ef84fd3bSjoerg #else 37*ef84fd3bSjoerg return dlsym(RTLD_DEFAULT, name); 38*ef84fd3bSjoerg #endif 39*ef84fd3bSjoerg } 40*ef84fd3bSjoerg 41*ef84fd3bSjoerg StatModule *list; 42*ef84fd3bSjoerg 43*ef84fd3bSjoerg struct RegisterSanStats { 44*ef84fd3bSjoerg unsigned module_id; 45*ef84fd3bSjoerg RegisterSanStats__anon183162d70111::RegisterSanStats46*ef84fd3bSjoerg RegisterSanStats() { 47*ef84fd3bSjoerg typedef unsigned (*reg_func_t)(StatModule **); 48*ef84fd3bSjoerg reg_func_t reg_func = reinterpret_cast<reg_func_t>( 49*ef84fd3bSjoerg LookupSymbolFromMain("__sanitizer_stats_register")); 50*ef84fd3bSjoerg if (reg_func) 51*ef84fd3bSjoerg module_id = reg_func(&list); 52*ef84fd3bSjoerg } 53*ef84fd3bSjoerg ~RegisterSanStats__anon183162d70111::RegisterSanStats54*ef84fd3bSjoerg ~RegisterSanStats() { 55*ef84fd3bSjoerg typedef void (*unreg_func_t)(unsigned); 56*ef84fd3bSjoerg unreg_func_t unreg_func = reinterpret_cast<unreg_func_t>( 57*ef84fd3bSjoerg LookupSymbolFromMain("__sanitizer_stats_unregister")); 58*ef84fd3bSjoerg if (unreg_func) 59*ef84fd3bSjoerg unreg_func(module_id); 60*ef84fd3bSjoerg } 61*ef84fd3bSjoerg } reg; 62*ef84fd3bSjoerg 63*ef84fd3bSjoerg } 64*ef84fd3bSjoerg __sanitizer_stat_init(StatModule * mod)65*ef84fd3bSjoergextern "C" void __sanitizer_stat_init(StatModule *mod) { 66*ef84fd3bSjoerg mod->next = list; 67*ef84fd3bSjoerg list = mod; 68*ef84fd3bSjoerg } 69*ef84fd3bSjoerg __sanitizer_stat_report(StatInfo * s)70*ef84fd3bSjoergextern "C" void __sanitizer_stat_report(StatInfo *s) { 71*ef84fd3bSjoerg s->addr = GET_CALLER_PC(); 72*ef84fd3bSjoerg #if defined(_WIN64) && !defined(__clang__) 73*ef84fd3bSjoerg uptr old_data = InterlockedIncrement64(reinterpret_cast<LONG64 *>(&s->data)); 74*ef84fd3bSjoerg #elif defined(_WIN32) && !defined(__clang__) 75*ef84fd3bSjoerg uptr old_data = InterlockedIncrement(&s->data); 76*ef84fd3bSjoerg #else 77*ef84fd3bSjoerg uptr old_data = __sync_fetch_and_add(&s->data, 1); 78*ef84fd3bSjoerg #endif 79*ef84fd3bSjoerg 80*ef84fd3bSjoerg // Overflow check. 81*ef84fd3bSjoerg if (CountFromData(old_data + 1) == 0) 82*ef84fd3bSjoerg Trap(); 83*ef84fd3bSjoerg } 84