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