13d4bba30STeresa Johnson //===-- memprof_malloc_linux.cpp -----------------------------------------===// 23d4bba30STeresa Johnson // 33d4bba30STeresa Johnson // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43d4bba30STeresa Johnson // See https://llvm.org/LICENSE.txt for license information. 53d4bba30STeresa Johnson // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63d4bba30STeresa Johnson // 73d4bba30STeresa Johnson //===----------------------------------------------------------------------===// 83d4bba30STeresa Johnson // 93d4bba30STeresa Johnson // This file is a part of MemProfiler, a memory profiler. 103d4bba30STeresa Johnson // 113d4bba30STeresa Johnson // Linux-specific malloc interception. 123d4bba30STeresa Johnson // We simply define functions like malloc, free, realloc, etc. 133d4bba30STeresa Johnson // They will replace the corresponding libc functions automagically. 143d4bba30STeresa Johnson //===----------------------------------------------------------------------===// 153d4bba30STeresa Johnson 163d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_platform.h" 173d4bba30STeresa Johnson #if !SANITIZER_LINUX 183d4bba30STeresa Johnson #error Unsupported OS 193d4bba30STeresa Johnson #endif 203d4bba30STeresa Johnson 213d4bba30STeresa Johnson #include "memprof_allocator.h" 223d4bba30STeresa Johnson #include "memprof_interceptors.h" 233d4bba30STeresa Johnson #include "memprof_internal.h" 243d4bba30STeresa Johnson #include "memprof_stack.h" 253d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_allocator_checks.h" 26cb0e14ceSVitaly Buka #include "sanitizer_common/sanitizer_allocator_dlsym.h" 273d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_errno.h" 283d4bba30STeresa Johnson #include "sanitizer_common/sanitizer_tls_get_addr.h" 293d4bba30STeresa Johnson 303d4bba30STeresa Johnson // ---------------------- Replacement functions ---------------- {{{1 313d4bba30STeresa Johnson using namespace __memprof; 323d4bba30STeresa Johnson 33cb0e14ceSVitaly Buka struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> { 34cb0e14ceSVitaly Buka static bool UseImpl() { return memprof_init_is_running; } 35cb0e14ceSVitaly Buka }; 363d4bba30STeresa Johnson 373d4bba30STeresa Johnson INTERCEPTOR(void, free, void *ptr) { 38cb0e14ceSVitaly Buka if (DlsymAlloc::PointerIsMine(ptr)) 39cb0e14ceSVitaly Buka return DlsymAlloc::Free(ptr); 40651797f4SVitaly Buka GET_STACK_TRACE_FREE; 413d4bba30STeresa Johnson memprof_free(ptr, &stack, FROM_MALLOC); 423d4bba30STeresa Johnson } 433d4bba30STeresa Johnson 443d4bba30STeresa Johnson #if SANITIZER_INTERCEPT_CFREE 453d4bba30STeresa Johnson INTERCEPTOR(void, cfree, void *ptr) { 46cb0e14ceSVitaly Buka if (DlsymAlloc::PointerIsMine(ptr)) 47cb0e14ceSVitaly Buka return DlsymAlloc::Free(ptr); 48651797f4SVitaly Buka GET_STACK_TRACE_FREE; 493d4bba30STeresa Johnson memprof_free(ptr, &stack, FROM_MALLOC); 503d4bba30STeresa Johnson } 513d4bba30STeresa Johnson #endif // SANITIZER_INTERCEPT_CFREE 523d4bba30STeresa Johnson 533d4bba30STeresa Johnson INTERCEPTOR(void *, malloc, uptr size) { 54cb0e14ceSVitaly Buka if (DlsymAlloc::Use()) 55cb0e14ceSVitaly Buka return DlsymAlloc::Allocate(size); 563d4bba30STeresa Johnson ENSURE_MEMPROF_INITED(); 573d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 583d4bba30STeresa Johnson return memprof_malloc(size, &stack); 593d4bba30STeresa Johnson } 603d4bba30STeresa Johnson 613d4bba30STeresa Johnson INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) { 62cb0e14ceSVitaly Buka if (DlsymAlloc::Use()) 63cb0e14ceSVitaly Buka return DlsymAlloc::Callocate(nmemb, size); 643d4bba30STeresa Johnson ENSURE_MEMPROF_INITED(); 653d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 663d4bba30STeresa Johnson return memprof_calloc(nmemb, size, &stack); 673d4bba30STeresa Johnson } 683d4bba30STeresa Johnson 693d4bba30STeresa Johnson INTERCEPTOR(void *, realloc, void *ptr, uptr size) { 70cb0e14ceSVitaly Buka if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr)) 71cb0e14ceSVitaly Buka return DlsymAlloc::Realloc(ptr, size); 723d4bba30STeresa Johnson ENSURE_MEMPROF_INITED(); 733d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 743d4bba30STeresa Johnson return memprof_realloc(ptr, size, &stack); 753d4bba30STeresa Johnson } 763d4bba30STeresa Johnson 773d4bba30STeresa Johnson #if SANITIZER_INTERCEPT_REALLOCARRAY 783d4bba30STeresa Johnson INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) { 793d4bba30STeresa Johnson ENSURE_MEMPROF_INITED(); 803d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 813d4bba30STeresa Johnson return memprof_reallocarray(ptr, nmemb, size, &stack); 823d4bba30STeresa Johnson } 833d4bba30STeresa Johnson #endif // SANITIZER_INTERCEPT_REALLOCARRAY 843d4bba30STeresa Johnson 853d4bba30STeresa Johnson #if SANITIZER_INTERCEPT_MEMALIGN 863d4bba30STeresa Johnson INTERCEPTOR(void *, memalign, uptr boundary, uptr size) { 873d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 883d4bba30STeresa Johnson return memprof_memalign(boundary, size, &stack, FROM_MALLOC); 893d4bba30STeresa Johnson } 903d4bba30STeresa Johnson 913d4bba30STeresa Johnson INTERCEPTOR(void *, __libc_memalign, uptr boundary, uptr size) { 923d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 93*b07f1be9SVitaly Buka return memprof_memalign(boundary, size, &stack, FROM_MALLOC); 943d4bba30STeresa Johnson } 953d4bba30STeresa Johnson #endif // SANITIZER_INTERCEPT_MEMALIGN 963d4bba30STeresa Johnson 973d4bba30STeresa Johnson #if SANITIZER_INTERCEPT_ALIGNED_ALLOC 983d4bba30STeresa Johnson INTERCEPTOR(void *, aligned_alloc, uptr boundary, uptr size) { 993d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 1003d4bba30STeresa Johnson return memprof_aligned_alloc(boundary, size, &stack); 1013d4bba30STeresa Johnson } 1023d4bba30STeresa Johnson #endif // SANITIZER_INTERCEPT_ALIGNED_ALLOC 1033d4bba30STeresa Johnson 1043d4bba30STeresa Johnson INTERCEPTOR(uptr, malloc_usable_size, void *ptr) { 105bd132411SEnna1 return memprof_malloc_usable_size(ptr); 1063d4bba30STeresa Johnson } 1073d4bba30STeresa Johnson 1083d4bba30STeresa Johnson #if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO 1093d4bba30STeresa Johnson // We avoid including malloc.h for portability reasons. 1103d4bba30STeresa Johnson // man mallinfo says the fields are "long", but the implementation uses int. 1113d4bba30STeresa Johnson // It doesn't matter much -- we just need to make sure that the libc's mallinfo 1123d4bba30STeresa Johnson // is not called. 1133d4bba30STeresa Johnson struct fake_mallinfo { 1143d4bba30STeresa Johnson int x[10]; 1153d4bba30STeresa Johnson }; 1163d4bba30STeresa Johnson 1173d4bba30STeresa Johnson INTERCEPTOR(struct fake_mallinfo, mallinfo, void) { 1183d4bba30STeresa Johnson struct fake_mallinfo res; 1193d4bba30STeresa Johnson REAL(memset)(&res, 0, sizeof(res)); 1203d4bba30STeresa Johnson return res; 1213d4bba30STeresa Johnson } 1223d4bba30STeresa Johnson 1233d4bba30STeresa Johnson INTERCEPTOR(int, mallopt, int cmd, int value) { return 0; } 1243d4bba30STeresa Johnson #endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO 1253d4bba30STeresa Johnson 1263d4bba30STeresa Johnson INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) { 1273d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 1283d4bba30STeresa Johnson return memprof_posix_memalign(memptr, alignment, size, &stack); 1293d4bba30STeresa Johnson } 1303d4bba30STeresa Johnson 1313d4bba30STeresa Johnson INTERCEPTOR(void *, valloc, uptr size) { 1323d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 1333d4bba30STeresa Johnson return memprof_valloc(size, &stack); 1343d4bba30STeresa Johnson } 1353d4bba30STeresa Johnson 1363d4bba30STeresa Johnson #if SANITIZER_INTERCEPT_PVALLOC 1373d4bba30STeresa Johnson INTERCEPTOR(void *, pvalloc, uptr size) { 1383d4bba30STeresa Johnson GET_STACK_TRACE_MALLOC; 1393d4bba30STeresa Johnson return memprof_pvalloc(size, &stack); 1403d4bba30STeresa Johnson } 1413d4bba30STeresa Johnson #endif // SANITIZER_INTERCEPT_PVALLOC 1423d4bba30STeresa Johnson 1433d4bba30STeresa Johnson INTERCEPTOR(void, malloc_stats, void) { __memprof_print_accumulated_stats(); } 1443d4bba30STeresa Johnson 1453d4bba30STeresa Johnson namespace __memprof { 1463d4bba30STeresa Johnson void ReplaceSystemMalloc() {} 1473d4bba30STeresa Johnson } // namespace __memprof 148