• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 BASE_ALLOCATOR_PARTITION_ALLOCATOR_SHIM_ALLOCATOR_SHIM_OVERRIDE_LINKER_WRAPPED_SYMBOLS_H_
6 #error This header is meant to be included only once by allocator_shim.cc
7 #endif
8 
9 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_SHIM_ALLOCATOR_SHIM_OVERRIDE_LINKER_WRAPPED_SYMBOLS_H_
10 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_SHIM_ALLOCATOR_SHIM_OVERRIDE_LINKER_WRAPPED_SYMBOLS_H_
11 
12 // This header overrides the __wrap_X symbols when using the link-time
13 // -Wl,-wrap,malloc shim-layer approach (see README.md).
14 // All references to malloc, free, etc. within the linker unit that gets the
15 // -wrap linker flags (e.g., libchrome.so) will be rewritten to the
16 // linker as references to __wrap_malloc, __wrap_free, which are defined here.
17 
18 #include <algorithm>
19 #include <cstring>
20 
21 #include "base/allocator/partition_allocator/shim/allocator_shim_internals.h"
22 
23 extern "C" {
24 
__wrap_calloc(size_t n,size_t size)25 SHIM_ALWAYS_EXPORT void* __wrap_calloc(size_t n, size_t size) {
26   return ShimCalloc(n, size, nullptr);
27 }
28 
__wrap_free(void * ptr)29 SHIM_ALWAYS_EXPORT void __wrap_free(void* ptr) {
30   ShimFree(ptr, nullptr);
31 }
32 
__wrap_malloc(size_t size)33 SHIM_ALWAYS_EXPORT void* __wrap_malloc(size_t size) {
34   return ShimMalloc(size, nullptr);
35 }
36 
__wrap_memalign(size_t align,size_t size)37 SHIM_ALWAYS_EXPORT void* __wrap_memalign(size_t align, size_t size) {
38   return ShimMemalign(align, size, nullptr);
39 }
40 
__wrap_posix_memalign(void ** res,size_t align,size_t size)41 SHIM_ALWAYS_EXPORT int __wrap_posix_memalign(void** res,
42                                              size_t align,
43                                              size_t size) {
44   return ShimPosixMemalign(res, align, size);
45 }
46 
__wrap_pvalloc(size_t size)47 SHIM_ALWAYS_EXPORT void* __wrap_pvalloc(size_t size) {
48   return ShimPvalloc(size);
49 }
50 
__wrap_realloc(void * address,size_t size)51 SHIM_ALWAYS_EXPORT void* __wrap_realloc(void* address, size_t size) {
52   return ShimRealloc(address, size, nullptr);
53 }
54 
__wrap_valloc(size_t size)55 SHIM_ALWAYS_EXPORT void* __wrap_valloc(size_t size) {
56   return ShimValloc(size, nullptr);
57 }
58 
__wrap_malloc_usable_size(void * address)59 SHIM_ALWAYS_EXPORT size_t __wrap_malloc_usable_size(void* address) {
60   return ShimGetSizeEstimate(address, nullptr);
61 }
62 
63 const size_t kPathMaxSize = 8192;
64 static_assert(kPathMaxSize >= PATH_MAX, "");
65 
66 extern char* __wrap_strdup(const char* str);
67 
68 // Override <stdlib.h>
69 
70 extern char* __real_realpath(const char* path, char* resolved_path);
71 
__wrap_realpath(const char * path,char * resolved_path)72 SHIM_ALWAYS_EXPORT char* __wrap_realpath(const char* path,
73                                          char* resolved_path) {
74   if (resolved_path)
75     return __real_realpath(path, resolved_path);
76 
77   char buffer[kPathMaxSize];
78   if (!__real_realpath(path, buffer))
79     return nullptr;
80   return __wrap_strdup(buffer);
81 }
82 
83 // Override <string.h> functions
84 
__wrap_strdup(const char * str)85 SHIM_ALWAYS_EXPORT char* __wrap_strdup(const char* str) {
86   std::size_t length = std::strlen(str) + 1;
87   void* buffer = ShimMalloc(length, nullptr);
88   if (!buffer)
89     return nullptr;
90   return reinterpret_cast<char*>(std::memcpy(buffer, str, length));
91 }
92 
__wrap_strndup(const char * str,size_t n)93 SHIM_ALWAYS_EXPORT char* __wrap_strndup(const char* str, size_t n) {
94   std::size_t length = std::min(std::strlen(str), n);
95   char* buffer = reinterpret_cast<char*>(ShimMalloc(length + 1, nullptr));
96   if (!buffer)
97     return nullptr;
98   std::memcpy(buffer, str, length);
99   buffer[length] = '\0';
100   return buffer;
101 }
102 
103 // Override <unistd.h>
104 
105 extern char* __real_getcwd(char* buffer, size_t size);
106 
__wrap_getcwd(char * buffer,size_t size)107 SHIM_ALWAYS_EXPORT char* __wrap_getcwd(char* buffer, size_t size) {
108   if (buffer)
109     return __real_getcwd(buffer, size);
110 
111   if (!size)
112     size = kPathMaxSize;
113   char local_buffer[size];
114   if (!__real_getcwd(local_buffer, size))
115     return nullptr;
116   return __wrap_strdup(local_buffer);
117 }
118 
119 // Override stdio.h
120 
121 // This is non-standard (_GNU_SOURCE only), but implemented by Bionic on
122 // Android, and used by libc++.
__wrap_vasprintf(char ** strp,const char * fmt,va_list va_args)123 SHIM_ALWAYS_EXPORT int __wrap_vasprintf(char** strp,
124                                         const char* fmt,
125                                         va_list va_args) {
126   constexpr int kInitialSize = 128;
127   *strp = static_cast<char*>(
128       malloc(kInitialSize));  // Our malloc() doesn't return nullptr.
129 
130   int actual_size = vsnprintf(*strp, kInitialSize, fmt, va_args);
131   if (actual_size < 0)
132     return actual_size;
133   *strp =
134       static_cast<char*>(realloc(*strp, static_cast<size_t>(actual_size + 1)));
135 
136   // Now we know the size. This is not very efficient, but we cannot really do
137   // better without accessing internal libc functions, or reimplementing
138   // *printf().
139   //
140   // This is very lightly used in Chromium in practice, see crbug.com/116558 for
141   // details.
142   if (actual_size >= kInitialSize)
143     return vsnprintf(*strp, static_cast<size_t>(actual_size + 1), fmt, va_args);
144 
145   return actual_size;
146 }
147 
__wrap_asprintf(char ** strp,const char * fmt,...)148 SHIM_ALWAYS_EXPORT int __wrap_asprintf(char** strp, const char* fmt, ...) {
149   va_list va_args;
150   va_start(va_args, fmt);
151   int retval = vasprintf(strp, fmt, va_args);
152   va_end(va_args);
153   return retval;
154 }
155 
156 }  // extern "C"
157 
158 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_SHIM_ALLOCATOR_SHIM_OVERRIDE_LINKER_WRAPPED_SYMBOLS_H_
159