]> git.proxmox.com Git - rustc.git/blame - src/compiler-rt/lib/stats/stats_client.cc
New upstream version 1.19.0+dfsg1
[rustc.git] / src / compiler-rt / lib / stats / stats_client.cc
CommitLineData
5bcae85e
SL
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
7cac9316 19#define WIN32_LEAN_AND_MEAN
5bcae85e
SL
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
30using namespace __sanitizer;
31
32namespace {
33
34void *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
42StatModule *list;
43
44struct 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
66extern "C" void __sanitizer_stat_init(StatModule *mod) {
67 mod->next = list;
68 list = mod;
69}
70
71extern "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}