aboutsummaryrefslogtreecommitdiff
blob: de32a3dab95cfc2e0e287babc8149cd1646e4587 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
--- qtwebengine/src/3rdparty/chromium/base/allocator/allocator_shim_default_dispatch_to_glibc.cc
--- qtwebengine/src/3rdparty/chromium/base/allocator/allocator_shim_default_dispatch_to_glibc.cc
@@ -6,6 +6,7 @@
 
 #include <malloc.h>
 
+#if defined(__GLIBC__)
 // This translation unit defines a default dispatch for the allocator shim which
 // routes allocations to libc functions.
 // The code here is strongly inspired from tcmalloc's libc_override_glibc.h.
@@ -73,3 +74,92 @@ const AllocatorDispatch AllocatorDispatch::default_dispatch = {
     nullptr,               /* free_definite_size_function */
     nullptr,               /* next */
 };
+
+#else // defined(__GLIBC__)
+
+#include <dlfcn.h>
+
+extern "C" {
+// Declare function pointers to the memory functions
+typedef void* (*t_libc_malloc)(size_t size);
+typedef void* (*t_libc_calloc)(size_t n, size_t size);
+typedef void* (*t_libc_realloc)(void* address, size_t size);
+typedef void* (*t_libc_memalign)(size_t alignment, size_t size);
+typedef void (*t_libc_free)(void* ptr);
+typedef size_t (*t_libc_malloc_usable_size)(void* ptr);
+
+// Static instances of pointers to libc.so dl symbols
+static t_libc_malloc libc_malloc = NULL;
+static t_libc_calloc libc_calloc = NULL;
+static t_libc_realloc libc_realloc = NULL;
+static t_libc_memalign libc_memalign = NULL;
+static t_libc_free libc_free = NULL;
+static t_libc_malloc_usable_size libc_malloc_usable_size = NULL;
+
+// resolve the symbols in libc.so
+void musl_libc_memory_init(void)
+{
+  libc_malloc = (t_libc_malloc) dlsym(RTLD_NEXT, "malloc");
+  libc_calloc = (t_libc_calloc) dlsym(RTLD_NEXT, "calloc");
+  libc_realloc = (t_libc_realloc) dlsym(RTLD_NEXT, "realloc");
+  libc_memalign = (t_libc_memalign) dlsym(RTLD_NEXT, "memalign");
+  libc_free = (t_libc_free) dlsym(RTLD_NEXT, "free");
+  libc_malloc_usable_size = (t_libc_malloc_usable_size) dlsym(RTLD_NEXT, "malloc_usable_size");
+}
+}  // extern "C"
+
+namespace {
+
+using base::allocator::AllocatorDispatch;
+
+void* MuslMalloc(const AllocatorDispatch*, size_t size, void* context) {
+  if (!libc_malloc)
+    musl_libc_memory_init();
+  return (*libc_malloc)(size);
+}
+
+void* MuslCalloc(const AllocatorDispatch*, size_t n, size_t size, void* context) {
+  if (!libc_calloc)
+    musl_libc_memory_init();
+  return (*libc_calloc)(n, size);
+}
+
+void* MuslRealloc(const AllocatorDispatch*, void* address, size_t size, void* context) {
+  if (!libc_realloc)
+    musl_libc_memory_init();
+  return (*libc_realloc)(address, size);
+}
+
+void* MuslMemalign(const AllocatorDispatch*, size_t alignment, size_t size, void* context) {
+  if (!libc_memalign)
+    musl_libc_memory_init();
+  return (*libc_memalign)(alignment, size);
+}
+
+void MuslFree(const AllocatorDispatch*, void* address, void* context) {
+  if (!libc_free)
+    musl_libc_memory_init();
+  (*libc_free)(address);
+}
+
+size_t MuslGetSizeEstimate(const AllocatorDispatch*, void* address, void* context) {
+  // TODO(siggi, primiano): malloc_usable_size may need redirection in the
+  //     presence of interposing shims that divert allocations.
+  if (!libc_malloc_usable_size)
+    musl_libc_memory_init();
+  return (*libc_malloc_usable_size)(address);
+}
+
+}  // namespace
+
+const AllocatorDispatch AllocatorDispatch::default_dispatch = {
+    &MuslMalloc,           /* alloc_function */
+    &MuslCalloc,           /* alloc_zero_initialized_function */
+    &MuslMemalign,         /* alloc_aligned_function */
+    &MuslRealloc,          /* realloc_function */
+    &MuslFree,             /* free_function */
+    &MuslGetSizeEstimate,  /* get_size_estimate_function */
+    nullptr,               /* next */
+};
+
+#endif