diff --git a/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/include/hooked-functions.h b/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/include/hooked-functions.h index 901d8d2e..d2769d2c 100644 --- a/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/include/hooked-functions.h +++ b/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/include/hooked-functions.h @@ -16,6 +16,9 @@ #define HOOKED_FREE #include +#if __APPLE__ +# include +#endif void *replacement_malloc(size_t size); void replacement_free(void *ptr); @@ -25,4 +28,13 @@ void *replacement_reallocf(void *ptr, size_t size); void *replacement_valloc(size_t size); int replacement_posix_memalign(void **memptr, size_t alignment, size_t size); +#if __APPLE__ +void *replacement_malloc_zone_malloc(malloc_zone_t *zone, size_t size); +void *replacement_malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size); +void *replacement_malloc_zone_valloc(malloc_zone_t *zone, size_t size); +void *replacement_malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size); +void *replacement_malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size); +void replacement_malloc_zone_free(malloc_zone_t *zone, void *ptr); +#endif + #endif diff --git a/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/src/hooked-functions-darwin.c b/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/src/hooked-functions-darwin.c new file mode 100644 index 00000000..004456bc --- /dev/null +++ b/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/src/hooked-functions-darwin.c @@ -0,0 +1,164 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if __APPLE__ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DYLD_INTERPOSE(_replacement,_replacee) \ + __attribute__((used)) static struct { const void *replacement; const void *replacee; } _interpose_##_replacee \ + __attribute__ ((section("__DATA,__interpose"))) = { (const void *)(unsigned long)&_replacement, (const void *)(unsigned long)&_replacee }; + +/* on Darwin calling the original function is super easy, just call it, done. */ +#define JUMP_INTO_LIBC_FUN(_fun, ...) /* \ +*/ do { /* \ +*/ return _fun(__VA_ARGS__); /* \ +*/ } while(0) + +void replacement_free(void *ptr) { + if (ptr) { + inc_free_counter(); + JUMP_INTO_LIBC_FUN(free, ptr); + } +} + +void *replacement_malloc(size_t size) { + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t) size); + + JUMP_INTO_LIBC_FUN(malloc, size); +} + +void *replacement_realloc(void *ptr, size_t size) { + if (0 == size) { + replacement_free(ptr); + return NULL; + } + if (!ptr) { + return replacement_malloc(size); + } + inc_free_counter(); + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t) size); + + JUMP_INTO_LIBC_FUN(realloc, ptr, size); +} + +void *replacement_calloc(size_t count, size_t size) { + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t)(count * size)); + + JUMP_INTO_LIBC_FUN(calloc, count, size); +} + +void *replacement_malloc_zone_malloc(malloc_zone_t *zone, size_t size) { + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t)size); + + JUMP_INTO_LIBC_FUN(malloc_zone_malloc, zone, size); +} + +void *replacement_malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) { + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t)(size * num_items)); + + JUMP_INTO_LIBC_FUN(malloc_zone_calloc, zone, num_items, size); +} + +void *replacement_malloc_zone_valloc(malloc_zone_t *zone, size_t size) { + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t)size); + + JUMP_INTO_LIBC_FUN(malloc_zone_valloc, zone, size); +} + +void *replacement_malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) { + if (0 == size) { + replacement_free(ptr); + return NULL; + } + if (!ptr) { + return replacement_malloc(size); + } + inc_free_counter(); + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t)size); + + JUMP_INTO_LIBC_FUN(realloc, ptr, size); +} + +void *replacement_malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) { + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t)size); + + JUMP_INTO_LIBC_FUN(malloc_zone_memalign, zone, alignment, size); +} + +void replacement_malloc_zone_free(malloc_zone_t *zone, void *ptr) { + inc_free_counter(); + + JUMP_INTO_LIBC_FUN(malloc_zone_free, zone, ptr); +} + +void *replacement_reallocf(void *ptr, size_t size) { + void *new_ptr = replacement_realloc(ptr, size); + if (!new_ptr) { + replacement_free(new_ptr); + } + return new_ptr; +} + +void *replacement_valloc(size_t size) { + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t)size); + + JUMP_INTO_LIBC_FUN(valloc, size); +} + +int replacement_posix_memalign(void **memptr, size_t alignment, size_t size) { + inc_malloc_counter(); + add_malloc_bytes_counter((intptr_t)size); + + JUMP_INTO_LIBC_FUN(posix_memalign, memptr, alignment, size); +} + +DYLD_INTERPOSE(replacement_free, free) +DYLD_INTERPOSE(replacement_malloc, malloc) +DYLD_INTERPOSE(replacement_realloc, realloc) +DYLD_INTERPOSE(replacement_calloc, calloc) +DYLD_INTERPOSE(replacement_reallocf, reallocf) +DYLD_INTERPOSE(replacement_valloc, valloc) +DYLD_INTERPOSE(replacement_posix_memalign, posix_memalign) +DYLD_INTERPOSE(replacement_malloc_zone_malloc, malloc_zone_malloc) +DYLD_INTERPOSE(replacement_malloc_zone_calloc, malloc_zone_calloc) +DYLD_INTERPOSE(replacement_malloc_zone_valloc, malloc_zone_valloc) +DYLD_INTERPOSE(replacement_malloc_zone_realloc, malloc_zone_realloc) +DYLD_INTERPOSE(replacement_malloc_zone_memalign, malloc_zone_memalign) +DYLD_INTERPOSE(replacement_malloc_zone_free, malloc_zone_free) +#endif diff --git a/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/src/hooked-functions.c b/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/src/hooked-functions-unix.c similarity index 85% rename from IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/src/hooked-functions.c rename to IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/src/hooked-functions-unix.c index 2fdf7722..e73d6010 100644 --- a/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/src/hooked-functions.c +++ b/IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Sources/HookedFunctions/src/hooked-functions-unix.c @@ -12,6 +12,8 @@ // //===----------------------------------------------------------------------===// +#ifndef __APPLE__ + #define _GNU_SOURCE #include #include @@ -33,9 +35,6 @@ static char g_recursive_malloc_mem[10 * 1024 * 1024] = {0}; /* the index of the first free byte */ static _Atomic ptrdiff_t g_recursive_malloc_next_free_ptr = ATOMIC_VAR_INIT(0); -#define DYLD_INTERPOSE(_replacement,_replacee) \ - __attribute__((used)) static struct { const void *replacement; const void *replacee; } _interpose_##_replacee \ - __attribute__ ((section("__DATA,__interpose"))) = { (const void *)(unsigned long)&_replacement, (const void *)(unsigned long)&_replacee }; #define LIBC_SYMBOL(_fun) "" # _fun static __thread bool g_in_malloc = false; @@ -86,16 +85,6 @@ static void recursive_free(void *ptr) { abort(); } -#if __APPLE__ - -/* on Darwin calling the original function is super easy, just call it, done. */ -#define JUMP_INTO_LIBC_FUN(_fun, ...) /* \ -*/ do { /* \ -*/ return _fun(__VA_ARGS__); /* \ -*/ } while(0) - -#else - /* on other UNIX systems this is slightly harder. Basically we see if we already * have a thread local variable that is a pointer to the original libc function. * If yes, easy, call it. If no, we need to resolve it which we do by using @@ -117,8 +106,6 @@ static void recursive_free(void *ptr) { */ return g_libc_ ## _fun (__VA_ARGS__); /* */ } while(0) -#endif - void replacement_free(void *ptr) { if (ptr) { inc_free_counter(); @@ -180,12 +167,4 @@ int replacement_posix_memalign(void **memptr, size_t alignment, size_t size) { } } -#if __APPLE__ -DYLD_INTERPOSE(replacement_free, free) -DYLD_INTERPOSE(replacement_malloc, malloc) -DYLD_INTERPOSE(replacement_realloc, realloc) -DYLD_INTERPOSE(replacement_calloc, calloc) -DYLD_INTERPOSE(replacement_reallocf, reallocf) -DYLD_INTERPOSE(replacement_valloc, valloc) -DYLD_INTERPOSE(replacement_posix_memalign, posix_memalign) #endif diff --git a/dev/malloc-aggregation.d b/dev/malloc-aggregation.d index 530b9486..a0c2f3aa 100755 --- a/dev/malloc-aggregation.d +++ b/dev/malloc-aggregation.d @@ -28,7 +28,17 @@ printf("=====\n"); } -pid$target::malloc:entry, pid$target::posix_memalign:entry, pid$target::realloc:entry, pid$target::reallocf:entry, pid$target::calloc:entry, pid$target::valloc:entry, pid$target::posix_memalign:entry { +pid$target::malloc:entry, +pid$target::posix_memalign:entry, +pid$target::realloc:entry, +pid$target::reallocf:entry, +pid$target::calloc:entry, +pid$target::valloc:entry, +pid$target::malloc_zone_malloc:entry, +pid$target::malloc_zone_realloc:entry, +pid$target::malloc_zone_calloc:entry, +pid$target::malloc_zone_valloc:entry, +pid$target::malloc_zone_memalign:entry { @malloc_calls[ustack()] = count(); }