[compiler-rt] r272943 - [sanitizers] introduce yet another API function: __sanitizer_install_malloc_and_free_hooks
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 16 13:06:08 PDT 2016
Author: kcc
Date: Thu Jun 16 15:06:06 2016
New Revision: 272943
URL: http://llvm.org/viewvc/llvm-project?rev=272943&view=rev
Log:
[sanitizers] introduce yet another API function: __sanitizer_install_malloc_and_free_hooks
Modified:
compiler-rt/trunk/include/sanitizer/allocator_interface.h
compiler-rt/trunk/lib/asan/asan_internal.h
compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
compiler-rt/trunk/lib/lsan/lsan_allocator.cc
compiler-rt/trunk/lib/msan/msan.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc
Modified: compiler-rt/trunk/include/sanitizer/allocator_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/allocator_interface.h?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/allocator_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/allocator_interface.h Thu Jun 16 15:06:06 2016
@@ -59,6 +59,23 @@ extern "C" {
deallocation of "ptr". */
void __sanitizer_malloc_hook(const volatile void *ptr, size_t size);
void __sanitizer_free_hook(const volatile void *ptr);
+
+ /* Installs a pair of hooks for malloc/free.
+ Several (currently, 5) hook pairs may be installed, they are executed
+ in the order they were installed and after calling
+ __sanitizer_malloc_hook/__sanitizer_free_hook.
+ Unlike __sanitizer_malloc_hook/__sanitizer_free_hook these hooks can be
+ chained and do not rely on weak symbols working on the platform, but
+ require __sanitizer_install_malloc_and_free_hooks to be called at startup
+ and thus will not be called on malloc/free very early in the process.
+ Returns the number of hooks currently installed or 0 on failure.
+ Not thread-safe, should be called in the main thread before starting
+ other threads.
+ */
+ int __sanitizer_install_malloc_and_free_hooks(
+ void (*malloc_hook)(const volatile void *, size_t),
+ void (*free_hook)(const volatile void *));
+
#ifdef __cplusplus
} // extern "C"
#endif
Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Thu Jun 16 15:06:06 2016
@@ -110,10 +110,16 @@ bool PlatformHasDifferentMemcpyAndMemmov
// Add convenient macro for interface functions that may be represented as
// weak hooks.
-#define ASAN_MALLOC_HOOK(ptr, size) \
- if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)
-#define ASAN_FREE_HOOK(ptr) \
- if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)
+#define ASAN_MALLOC_HOOK(ptr, size) \
+ do { \
+ if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size); \
+ RunMallocHooks(ptr, size); \
+ } while (false)
+#define ASAN_FREE_HOOK(ptr) \
+ do { \
+ if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr); \
+ RunFreeHooks(ptr); \
+ } while (false)
#define ASAN_ON_ERROR() \
if (&__asan_on_error) __asan_on_error()
Modified: compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc Thu Jun 16 15:06:06 2016
@@ -343,6 +343,7 @@ INTERFACE_FUNCTION(__sanitizer_unaligned
INTERFACE_FUNCTION(__sanitizer_unaligned_store32)
INTERFACE_FUNCTION(__sanitizer_unaligned_store64)
INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container)
+INTERFACE_FUNCTION(__sanitizer_install_malloc_and_free_hooks)
// TODO(timurrrr): Add more interface functions on the as-needed basis.
Modified: compiler-rt/trunk/lib/lsan/lsan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_allocator.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_allocator.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_allocator.cc Thu Jun 16 15:06:06 2016
@@ -99,11 +99,13 @@ void *Allocate(const StackTrace &stack,
memset(p, 0, size);
RegisterAllocation(stack, p, size);
if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(p, size);
+ RunMallocHooks(p, size);
return p;
}
void Deallocate(void *p) {
if (&__sanitizer_free_hook) __sanitizer_free_hook(p);
+ RunFreeHooks(p);
RegisterDeallocation(p);
allocator.Deallocate(&cache, p);
}
Modified: compiler-rt/trunk/lib/msan/msan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.h?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.h (original)
+++ compiler-rt/trunk/lib/msan/msan.h Thu Jun 16 15:06:06 2016
@@ -309,15 +309,21 @@ void MsanTSDDtor(void *tsd);
} // namespace __msan
-#define MSAN_MALLOC_HOOK(ptr, size) \
- if (&__sanitizer_malloc_hook) { \
- UnpoisonParam(2); \
- __sanitizer_malloc_hook(ptr, size); \
- }
-#define MSAN_FREE_HOOK(ptr) \
- if (&__sanitizer_free_hook) { \
- UnpoisonParam(1); \
- __sanitizer_free_hook(ptr); \
- }
+#define MSAN_MALLOC_HOOK(ptr, size) \
+ do { \
+ if (&__sanitizer_malloc_hook) { \
+ UnpoisonParam(2); \
+ __sanitizer_malloc_hook(ptr, size); \
+ } \
+ RunMallocHooks(ptr, size); \
+ } while (false)
+#define MSAN_FREE_HOOK(ptr) \
+ do { \
+ if (&__sanitizer_free_hook) { \
+ UnpoisonParam(1); \
+ __sanitizer_free_hook(ptr); \
+ } \
+ RunFreeHooks(ptr); \
+ } while (false)
#endif // MSAN_H
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h Thu Jun 16 15:06:06 2016
@@ -29,6 +29,10 @@ SANITIZER_INTERFACE_ATTRIBUTE uptr __san
SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_free_bytes();
SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_unmapped_bytes();
+SANITIZER_INTERFACE_ATTRIBUTE int __sanitizer_install_malloc_and_free_hooks(
+ void (*malloc_hook)(const void *, uptr),
+ void (*free_hook)(const void *));
+
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
/* OPTIONAL */ void __sanitizer_malloc_hook(void *ptr, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Thu Jun 16 15:06:06 2016
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_common.h"
+#include "sanitizer_allocator_interface.h"
#include "sanitizer_allocator_internal.h"
#include "sanitizer_flags.h"
#include "sanitizer_libc.h"
@@ -421,6 +422,44 @@ void PrintCmdline() {
Printf("\n\n");
}
+// Malloc hooks.
+static const int kMaxMallocFreeHooks = 5;
+struct MallocFreeHook {
+ void (*malloc_hook)(const void *, uptr);
+ void (*free_hook)(const void *);
+};
+
+static MallocFreeHook MFHooks[kMaxMallocFreeHooks];
+
+void RunMallocHooks(const void *ptr, uptr size) {
+ for (int i = 0; i < kMaxMallocFreeHooks; i++) {
+ auto hook = MFHooks[i].malloc_hook;
+ if (!hook) return;
+ hook(ptr, size);
+ }
+}
+
+void RunFreeHooks(const void *ptr) {
+ for (int i = 0; i < kMaxMallocFreeHooks; i++) {
+ auto hook = MFHooks[i].free_hook;
+ if (!hook) return;
+ hook(ptr);
+ }
+}
+
+static int InstallMallocFreeHooks(void (*malloc_hook)(const void *, uptr),
+ void (*free_hook)(const void *)) {
+ if (!malloc_hook || !free_hook) return 0;
+ for (int i = 0; i < kMaxMallocFreeHooks; i++) {
+ if (MFHooks[i].malloc_hook == nullptr) {
+ MFHooks[i].malloc_hook = malloc_hook;
+ MFHooks[i].free_hook = free_hook;
+ return i + 1;
+ }
+ }
+ return 0;
+}
+
} // namespace __sanitizer
using namespace __sanitizer; // NOLINT
@@ -443,4 +482,11 @@ SANITIZER_INTERFACE_ATTRIBUTE
void __sanitizer_set_death_callback(void (*callback)(void)) {
SetUserDieCallback(callback);
}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+int __sanitizer_install_malloc_and_free_hooks(void (*malloc_hook)(const void *,
+ uptr),
+ void (*free_hook)(const void *)) {
+ return InstallMallocFreeHooks(malloc_hook, free_hook);
+}
} // extern "C"
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Thu Jun 16 15:06:06 2016
@@ -103,6 +103,8 @@ void NoHugePagesInRegion(uptr addr, uptr
void DontDumpShadowMemory(uptr addr, uptr length);
// Check if the built VMA size matches the runtime one.
void CheckVMASize();
+void RunMallocHooks(const void *ptr, uptr size);
+void RunFreeHooks(const void *ptr);
// InternalScopedBuffer can be used instead of large stack arrays to
// keep frame size low.
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc Thu Jun 16 15:06:06 2016
@@ -228,6 +228,7 @@ void invoke_malloc_hook(void *ptr, uptr
if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors)
return;
__sanitizer_malloc_hook(ptr, size);
+ RunMallocHooks(ptr, size);
}
void invoke_free_hook(void *ptr) {
@@ -235,6 +236,7 @@ void invoke_free_hook(void *ptr) {
if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors)
return;
__sanitizer_free_hook(ptr);
+ RunFreeHooks(ptr);
}
void *internal_alloc(MBlockType typ, uptr sz) {
Modified: compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc (original)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc Thu Jun 16 15:06:06 2016
@@ -10,22 +10,28 @@
extern "C" {
const volatile void *global_ptr;
+#define WRITE(s) write(1, s, sizeof(s))
+
// Note: avoid calling functions that allocate memory in malloc/free
// to avoid infinite recursion.
void __sanitizer_malloc_hook(const volatile void *ptr, size_t sz) {
if (__sanitizer_get_ownership(ptr) && sz == 4) {
- write(1, "MallocHook\n", sizeof("MallocHook\n"));
+ WRITE("MallocHook\n");
global_ptr = ptr;
}
}
void __sanitizer_free_hook(const volatile void *ptr) {
if (__sanitizer_get_ownership(ptr) && ptr == global_ptr)
- write(1, "FreeHook\n", sizeof("FreeHook\n"));
+ WRITE("FreeHook\n");
}
} // extern "C"
volatile int *x;
+void MallocHook1(const volatile void *ptr, size_t sz) { WRITE("MH1\n"); }
+void MallocHook2(const volatile void *ptr, size_t sz) { WRITE("MH2\n"); }
+void FreeHook1(const volatile void *ptr) { WRITE("FH1\n"); }
+void FreeHook2(const volatile void *ptr) { WRITE("FH2\n"); }
// Call this function with uninitialized arguments to poison
// TLS shadow for function parameters before calling operator
// new and, eventually, user-provided hook.
@@ -34,9 +40,13 @@ __attribute__((noinline)) void allocate(
}
int main() {
+ __sanitizer_install_malloc_and_free_hooks(MallocHook1, FreeHook1);
+ __sanitizer_install_malloc_and_free_hooks(MallocHook2, FreeHook2);
int *undef1, *undef2;
allocate(undef1, undef2);
// CHECK: MallocHook
+ // CHECK: MH1
+ // CHECK: MH2
// Check that malloc hook was called with correct argument.
if (global_ptr != (void*)x) {
_exit(1);
@@ -44,5 +54,7 @@ int main() {
*x = 0;
delete x;
// CHECK: FreeHook
+ // CHECK: FH1
+ // CHECK: FH2
return 0;
}
More information about the llvm-commits
mailing list