[esan] Initialize runtime during early interceptors

Summary:
Adds initialization of esan's runtime library during any early interceptors
that are sometimes called prior to the official __esan_init() invocation
(we see this with apps using tcmalloc).

Adds handling of interceptors called during interceptor initialization.

Reviewers: aizatsky

Subscribers: vitalybuka, zhaoqin, kcc, eugenis, llvm-commits, kubabrecka

Differential Revision: http://reviews.llvm.org/D20976

llvm-svn: 271744
This commit is contained in:
Derek Bruening 2016-06-03 22:30:10 +00:00
parent 9ef5772154
commit c1c67d651d
3 changed files with 18 additions and 4 deletions

View File

@ -30,6 +30,7 @@ extern void __cxa_atexit(void (*function)(void));
namespace __esan {
bool EsanIsInitialized;
bool EsanDuringInit;
ShadowMapping Mapping;
// Different tools use different scales within the same shadow mapping scheme.
@ -173,11 +174,13 @@ static void initializeShadow() {
}
void initializeLibrary(ToolType Tool) {
// We assume there is only one thread during init.
if (EsanIsInitialized) {
CHECK(Tool == __esan_which_tool);
// We assume there is only one thread during init, but we need to
// guard against double-init when we're (re-)called from an
// early interceptor.
if (EsanIsInitialized || EsanDuringInit)
return;
}
EsanDuringInit = true;
CHECK(Tool == __esan_which_tool);
SanitizerToolName = "EfficiencySanitizer";
CacheBinaryName();
initializeFlags();
@ -203,6 +206,7 @@ void initializeLibrary(ToolType Tool) {
}
EsanIsInitialized = true;
EsanDuringInit = false;
}
int finalizeLibrary() {

View File

@ -33,6 +33,7 @@
namespace __esan {
extern bool EsanIsInitialized;
extern bool EsanDuringInit;
void initializeLibrary(ToolType Tool);
int finalizeLibrary();

View File

@ -47,10 +47,15 @@ using namespace __esan; // NOLINT
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
INTERCEPT_FUNCTION_VER(name, ver)
// We must initialize during early interceptors, to support tcmalloc.
// This means that for some apps we fully initialize prior to
// __esan_init() being called.
// We currently do not use ctx.
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
do { \
if (UNLIKELY(COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)) { \
if (!UNLIKELY(EsanDuringInit)) \
initializeLibrary(__esan_which_tool); \
return REAL(func)(__VA_ARGS__); \
} \
ctx = nullptr; \
@ -332,6 +337,8 @@ INTERCEPTOR(int, rmdir, char *path) {
INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags,
int fd, OFF_T off) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off);
if (!fixMmapAddr(&addr, sz, flags))
return (void *)-1;
void *result = REAL(mmap)(addr, sz, prot, flags, fd, off);
@ -341,6 +348,8 @@ INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags,
#if SANITIZER_LINUX
INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags,
int fd, OFF64_T off) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off);
if (!fixMmapAddr(&addr, sz, flags))
return (void *)-1;
void *result = REAL(mmap64)(addr, sz, prot, flags, fd, off);