Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,39 @@
include_directories(..)
add_custom_target(stats)
set_target_properties(stats PROPERTIES FOLDER "Compiler-RT Misc")
if(APPLE)
set(STATS_LIB_FLAVOR SHARED)
set(STATS_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS})
add_weak_symbols("asan" WEAK_SYMBOL_LINK_FLAGS)
add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
else()
set(STATS_LIB_FLAVOR STATIC)
set(WEAK_SYMBOL_LINK_FLAGS)
endif()
add_compiler_rt_runtime(clang_rt.stats
${STATS_LIB_FLAVOR}
ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
OS ${SANITIZER_COMMON_SUPPORTED_OS}
SOURCES stats.cc
OBJECT_LIBS RTSanitizerCommon
RTSanitizerCommonLibc
CFLAGS ${SANITIZER_COMMON_CFLAGS}
LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
LINK_LIBS ${STATS_LINK_LIBS}
PARENT_TARGET stats)
add_compiler_rt_runtime(clang_rt.stats_client
STATIC
ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
OS ${SANITIZER_COMMON_SUPPORTED_OS}
SOURCES stats_client.cc
CFLAGS ${SANITIZER_COMMON_CFLAGS}
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
PARENT_TARGET stats)

View File

@ -0,0 +1,137 @@
//===-- stats.cc ----------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Sanitizer statistics gathering. Manages statistics for a process and is
// responsible for writing the report file.
//
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_file.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
#if SANITIZER_POSIX
#include "sanitizer_common/sanitizer_posix.h"
#endif
#include "sanitizer_common/sanitizer_symbolizer.h"
#include "stats/stats.h"
#if SANITIZER_POSIX
#include <signal.h>
#endif
using namespace __sanitizer;
namespace {
InternalMmapVectorNoCtor<StatModule **> modules;
StaticSpinMutex modules_mutex;
fd_t stats_fd;
void WriteLE(fd_t fd, uptr val) {
char chars[sizeof(uptr)];
for (unsigned i = 0; i != sizeof(uptr); ++i) {
chars[i] = val >> (i * 8);
}
WriteToFile(fd, chars, sizeof(uptr));
}
void OpenStatsFile(const char *path_env) {
InternalScopedBuffer<char> path(kMaxPathLength);
SubstituteForFlagValue(path_env, path.data(), kMaxPathLength);
error_t err;
stats_fd = OpenFile(path.data(), WrOnly, &err);
if (stats_fd == kInvalidFd) {
Report("stats: failed to open %s for writing (reason: %d)\n", path.data(),
err);
return;
}
char sizeof_uptr = sizeof(uptr);
WriteToFile(stats_fd, &sizeof_uptr, 1);
}
void WriteModuleReport(StatModule **smodp) {
CHECK(smodp);
const char *path_env = GetEnv("SANITIZER_STATS_PATH");
if (!path_env || stats_fd == kInvalidFd)
return;
if (!stats_fd)
OpenStatsFile(path_env);
const LoadedModule *mod = Symbolizer::GetOrInit()->FindModuleForAddress(
reinterpret_cast<uptr>(smodp));
WriteToFile(stats_fd, mod->full_name(),
internal_strlen(mod->full_name()) + 1);
for (StatModule *smod = *smodp; smod; smod = smod->next) {
for (u32 i = 0; i != smod->size; ++i) {
StatInfo *s = &smod->infos[i];
if (!s->addr)
continue;
WriteLE(stats_fd, s->addr - mod->base_address());
WriteLE(stats_fd, s->data);
}
}
WriteLE(stats_fd, 0);
WriteLE(stats_fd, 0);
}
} // namespace
extern "C"
SANITIZER_INTERFACE_ATTRIBUTE
unsigned __sanitizer_stats_register(StatModule **mod) {
SpinMutexLock l(&modules_mutex);
modules.push_back(mod);
return modules.size() - 1;
}
extern "C"
SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_stats_unregister(unsigned index) {
SpinMutexLock l(&modules_mutex);
WriteModuleReport(modules[index]);
modules[index] = 0;
}
namespace {
void WriteFullReport() {
SpinMutexLock l(&modules_mutex);
for (StatModule **mod : modules) {
if (!mod)
continue;
WriteModuleReport(mod);
}
if (stats_fd != 0 && stats_fd != kInvalidFd) {
CloseFile(stats_fd);
stats_fd = kInvalidFd;
}
}
#if SANITIZER_POSIX
void USR2Handler(int sig) {
WriteFullReport();
}
#endif
struct WriteReportOnExitOrSignal {
WriteReportOnExitOrSignal() {
#if SANITIZER_POSIX
struct sigaction sigact;
internal_memset(&sigact, 0, sizeof(sigact));
sigact.sa_handler = USR2Handler;
internal_sigaction(SIGUSR2, &sigact, nullptr);
#endif
}
~WriteReportOnExitOrSignal() {
WriteFullReport();
}
} wr;
} // namespace

View File

@ -0,0 +1,43 @@
//===-- stats.h -------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Data definitions for sanitizer statistics gathering.
//
//===----------------------------------------------------------------------===//
#ifndef SANITIZER_STATS_STATS_H
#define SANITIZER_STATS_STATS_H
#include "sanitizer_common/sanitizer_internal_defs.h"
namespace __sanitizer {
// Number of bits in data that are used for the sanitizer kind. Needs to match
// llvm::kSanitizerStatKindBits in
// llvm/include/llvm/Transforms/Utils/SanitizerStats.h
enum { kKindBits = 3 };
struct StatInfo {
uptr addr;
uptr data;
};
struct StatModule {
StatModule *next;
u32 size;
StatInfo infos[1];
};
inline uptr CountFromData(uptr data) {
return data & ((1ull << (sizeof(uptr) * 8 - kKindBits)) - 1);
}
}
#endif

View File

@ -0,0 +1,84 @@
//===-- stats_client.cc ---------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Sanitizer statistics gathering. Manages statistics for a module (executable
// or DSO) and registers statistics with the process.
//
// This is linked into each individual modle and cannot directly use functions
// declared in sanitizer_common.
//
//===----------------------------------------------------------------------===//
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <dlfcn.h>
#endif
#include <stdint.h>
#include <stdio.h>
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "stats/stats.h"
using namespace __sanitizer;
namespace {
void *LookupSymbolFromMain(const char *name) {
#ifdef _WIN32
return reinterpret_cast<void *>(GetProcAddress(GetModuleHandle(0), name));
#else
return dlsym(RTLD_DEFAULT, name);
#endif
}
StatModule *list;
struct RegisterSanStats {
unsigned module_id;
RegisterSanStats() {
typedef unsigned (*reg_func_t)(StatModule **);
reg_func_t reg_func = reinterpret_cast<reg_func_t>(
LookupSymbolFromMain("__sanitizer_stats_register"));
if (reg_func)
module_id = reg_func(&list);
}
~RegisterSanStats() {
typedef void (*unreg_func_t)(unsigned);
unreg_func_t unreg_func = reinterpret_cast<unreg_func_t>(
LookupSymbolFromMain("__sanitizer_stats_unregister"));
if (unreg_func)
unreg_func(module_id);
}
} reg;
}
extern "C" void __sanitizer_stat_init(StatModule *mod) {
mod->next = list;
list = mod;
}
extern "C" void __sanitizer_stat_report(StatInfo *s) {
s->addr = GET_CALLER_PC();
#if defined(_WIN64) && !defined(__clang__)
uptr old_data = InterlockedIncrement64(reinterpret_cast<LONG64 *>(&s->data));
#elif defined(_WIN32) && !defined(__clang__)
uptr old_data = InterlockedIncrement(&s->data);
#else
uptr old_data = __sync_fetch_and_add(&s->data, 1);
#endif
// Overflow check.
if (CountFromData(old_data + 1) == 0)
Trap();
}