1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifdef PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_OVERRIDE_GLIBC_WEAK_SYMBOLS_H_
6 #error This header is meant to be included only once by allocator_shim.cc
7 #endif
8
9 #ifndef PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_OVERRIDE_GLIBC_WEAK_SYMBOLS_H_
10 #define PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_OVERRIDE_GLIBC_WEAK_SYMBOLS_H_
11
12 // Alias the internal Glibc symbols to the shim entry points.
13 // This file is strongly inspired by tcmalloc's libc_override_glibc.h.
14 // Effectively this file does two things:
15 // 1) Re-define the __malloc_hook & co symbols. Those symbols are defined as
16 // weak in glibc and are meant to be defined strongly by client processes
17 // to hook calls initiated from within glibc.
18 // 2) Re-define Glibc-specific symbols (__libc_malloc). The historical reason
19 // is that in the past (in RedHat 9) we had instances of libraries that were
20 // allocating via malloc() and freeing using __libc_free().
21 // See tcmalloc's libc_override_glibc.h for more context.
22
23 #include "partition_alloc/partition_alloc_buildflags.h"
24
25 #if BUILDFLAG(USE_ALLOCATOR_SHIM)
26 #include <features.h> // for __GLIBC__
27 #include <malloc.h>
28 #include <unistd.h>
29
30 #include <new>
31
32 #include "partition_alloc/shim/allocator_shim_internals.h"
33
34 // __MALLOC_HOOK_VOLATILE not defined in all Glibc headers.
35 #if !defined(__MALLOC_HOOK_VOLATILE)
36 #define MALLOC_HOOK_MAYBE_VOLATILE /**/
37 #else
38 #define MALLOC_HOOK_MAYBE_VOLATILE __MALLOC_HOOK_VOLATILE
39 #endif
40
41 extern "C" {
42
43 // 1) Re-define malloc_hook weak symbols.
44 namespace {
45
GlibcMallocHook(size_t size,const void * caller)46 void* GlibcMallocHook(size_t size, const void* caller) {
47 return ShimMalloc(size, nullptr);
48 }
49
GlibcReallocHook(void * ptr,size_t size,const void * caller)50 void* GlibcReallocHook(void* ptr, size_t size, const void* caller) {
51 return ShimRealloc(ptr, size, nullptr);
52 }
53
GlibcFreeHook(void * ptr,const void * caller)54 void GlibcFreeHook(void* ptr, const void* caller) {
55 return ShimFree(ptr, nullptr);
56 }
57
GlibcMemalignHook(size_t align,size_t size,const void * caller)58 void* GlibcMemalignHook(size_t align, size_t size, const void* caller) {
59 return ShimMemalign(align, size, nullptr);
60 }
61
62 } // namespace
63
64 __attribute__((visibility("default"))) void* (
65 *MALLOC_HOOK_MAYBE_VOLATILE __malloc_hook)(size_t,
66 const void*) = &GlibcMallocHook;
67
68 __attribute__((visibility("default"))) void* (
69 *MALLOC_HOOK_MAYBE_VOLATILE __realloc_hook)(void*, size_t, const void*) =
70 &GlibcReallocHook;
71
72 __attribute__((visibility("default"))) void (
73 *MALLOC_HOOK_MAYBE_VOLATILE __free_hook)(void*,
74 const void*) = &GlibcFreeHook;
75
76 __attribute__((visibility("default"))) void* (
77 *MALLOC_HOOK_MAYBE_VOLATILE __memalign_hook)(size_t, size_t, const void*) =
78 &GlibcMemalignHook;
79
80 // 2) Redefine libc symbols themselves.
81
__libc_malloc(size_t size)82 SHIM_ALWAYS_EXPORT void* __libc_malloc(size_t size) {
83 return ShimMalloc(size, nullptr);
84 }
85
__libc_free(void * ptr)86 SHIM_ALWAYS_EXPORT void __libc_free(void* ptr) {
87 ShimFree(ptr, nullptr);
88 }
89
__libc_realloc(void * ptr,size_t size)90 SHIM_ALWAYS_EXPORT void* __libc_realloc(void* ptr, size_t size) {
91 return ShimRealloc(ptr, size, nullptr);
92 }
93
__libc_calloc(size_t n,size_t size)94 SHIM_ALWAYS_EXPORT void* __libc_calloc(size_t n, size_t size) {
95 return ShimCalloc(n, size, nullptr);
96 }
97
__libc_cfree(void * ptr)98 SHIM_ALWAYS_EXPORT void __libc_cfree(void* ptr) {
99 return ShimFree(ptr, nullptr);
100 }
101
__libc_memalign(size_t align,size_t s)102 SHIM_ALWAYS_EXPORT void* __libc_memalign(size_t align, size_t s) {
103 return ShimMemalign(align, s, nullptr);
104 }
105
__libc_valloc(size_t size)106 SHIM_ALWAYS_EXPORT void* __libc_valloc(size_t size) {
107 return ShimValloc(size, nullptr);
108 }
109
__libc_pvalloc(size_t size)110 SHIM_ALWAYS_EXPORT void* __libc_pvalloc(size_t size) {
111 return ShimPvalloc(size);
112 }
113
__posix_memalign(void ** r,size_t a,size_t s)114 SHIM_ALWAYS_EXPORT int __posix_memalign(void** r, size_t a, size_t s) {
115 return ShimPosixMemalign(r, a, s);
116 }
117
118 } // extern "C"
119
120 // Safety check.
121 #if !defined(__GLIBC__)
122 #error The target platform does not seem to use Glibc. Disable the allocator \
123 shim by setting use_allocator_shim=false in GN args.
124 #endif
125
126 #endif // BUILDFLAG(USE_ALLOCATOR_SHIM)
127
128 #endif // PARTITION_ALLOC_SHIM_ALLOCATOR_SHIM_OVERRIDE_GLIBC_WEAK_SYMBOLS_H_
129