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