xref: /llvm-project/compiler-rt/lib/memprof/memprof_malloc_linux.cpp (revision b07f1be92c1350d8d5b0952f49a2c3aeedcccb2f)
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