Home | History | Annotate | Line # | Download | only in stats
      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