blob: fa40b358570256a682e91e2d71e6b09e3e5c0250 [file] [log] [blame]
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -08001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29/*
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080030 * Contains implementation of memory allocation routines instrumented for
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080031 * usage in the emulator to detect memory allocation violations, such as
32 * memory leaks, buffer overruns, etc.
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080033 * Code, implemented here is intended to run in the emulated environment only,
34 * and serves simply as hooks into memory allocation routines. Main job of this
35 * code is to notify the emulator about memory being allocated/deallocated,
36 * providing information about each allocation. The idea is that emulator will
37 * keep list of currently allocated blocks, and, knowing boundaries of each
38 * block it will be able to verify that ld/st access to these blocks don't step
39 * over boundaries set for the user. To enforce that, each memory block
40 * allocated by this code is guarded with "prefix" and "suffix" areas, so
41 * every time emulator detects access to any of these guarding areas, it can be
42 * considered as access violation.
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080043 */
44
45#include <stdlib.h>
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080046#include <stddef.h>
47#include <stdio.h>
Elliott Hughes05fc1d72015-01-28 18:02:33 -080048#include <string.h>
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080049#include <fcntl.h>
50#include <sys/mman.h>
Christopher Ferris03eebcb2014-06-13 13:57:51 -070051#include <sys/param.h>
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080052#include <pthread.h>
53#include <unistd.h>
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080054#include <errno.h>
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080055#include "malloc_debug_common.h"
Christopher Ferris03eebcb2014-06-13 13:57:51 -070056#include "private/bionic_macros.h"
57#include "private/libc_logging.h"
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080058
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080059/* This file should be included into the build only when
60 * MALLOC_QEMU_INSTRUMENT macro is defined. */
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080061#ifndef MALLOC_QEMU_INSTRUMENT
62#error MALLOC_QEMU_INSTRUMENT is not defined.
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080063#endif // !MALLOC_QEMU_INSTRUMENT
64
65/* Controls access violation test performed to make sure that we catch AVs
66 * all the time they occur. See test_access_violation for more info. This macro
67 * is used for internal testing purposes and should always be set to zero for
68 * the production builds. */
69#define TEST_ACCESS_VIOLATIONS 0
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080070
71// =============================================================================
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080072// Communication structures
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080073// =============================================================================
74
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080075/* Describes memory block allocated from the heap. This structure is passed
76 * along with TRACE_DEV_REG_MALLOC event. This descriptor is used to inform
77 * the emulator about new memory block being allocated from the heap. The entire
78 * structure is initialized by the guest system before event is fired up. It is
79 * important to remember that same structure (an exact copy, except for
80 * replacing pointers with target_ulong) is also declared in the emulator's
81 * sources (file memcheck/memcheck_common.h). So, every time a change is made to
82 * any of these two declaration, another one must be also updated accordingly.
83 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -070084struct MallocDesc {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080085 /* Pointer to the memory block actually allocated from the heap. Note that
86 * this is not the pointer that is returned to the malloc's caller. Pointer
87 * returned to the caller is calculated by adding value stored in this field
88 * to the value stored in prefix_size field of this structure.
89 */
90 void* ptr;
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080091
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080092 /* Number of bytes requested by the malloc's caller. */
93 uint32_t requested_bytes;
94
95 /* Byte size of the prefix data. Actual pointer returned to the malloc's
96 * caller is calculated by adding value stored in this field to the value
97 * stored in in the ptr field of this structure.
98 */
99 uint32_t prefix_size;
100
101 /* Byte size of the suffix data. */
102 uint32_t suffix_size;
103
104 /* Id of the process that initialized libc instance, in which allocation
105 * has occurred. This field is used by the emulator to report errors in
106 * the course of TRACE_DEV_REG_MALLOC event handling. In case of an error,
107 * emulator sets this field to zero (invalid value for a process ID).
108 */
109 uint32_t libc_pid;
110
111 /* Id of the process in context of which allocation has occurred.
112 * Value in this field may differ from libc_pid value, if process that
113 * is doing allocation has been forked from the process that initialized
114 * libc instance.
115 */
116 uint32_t allocator_pid;
117
118 /* Number of access violations detected on this allocation. */
119 uint32_t av_count;
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700120};
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800121
122/* Describes memory block info queried from emulator. This structure is passed
123 * along with TRACE_DEV_REG_QUERY_MALLOC event. When handling free and realloc
124 * calls, it is required that we have information about memory blocks that were
125 * actually allocated in previous calls to malloc, calloc, memalign, or realloc.
126 * Since we don't keep this information directly in the allocated block, but
127 * rather we keep it in the emulator, we need to query emulator for that
128 * information with TRACE_DEV_REG_QUERY_MALLOC query. The entire structure is
129 * initialized by the guest system before event is fired up. It is important to
130 * remember that same structure (an exact copy, except for replacing pointers
131 * with target_ulong) is also declared in the emulator's sources (file
132 * memcheck/memecheck_common.h). So, every time a change is made to any of these
133 * two declaration, another one must be also updated accordingly.
134 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700135struct MallocDescQuery {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800136 /* Pointer, for which information is queried. Note that this pointer doesn't
137 * have to be exact pointer returned to malloc's caller, but can point
138 * anywhere inside an allocated block, including guarding areas. Emulator
139 * will respond with information about allocated block that contains this
140 * pointer.
141 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700142 const void* ptr;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800143
144 /* Id of the process that initialized libc instance, in which this query
145 * is called. This field is used by the emulator to report errors in
146 * the course of TRACE_DEV_REG_QUERY_MALLOC event handling. In case of an
147 * error, emulator sets this field to zero (invalid value for a process ID).
148 */
149 uint32_t libc_pid;
150
151 /* Process ID in context of which query is made. */
152 uint32_t query_pid;
153
154 /* Code of the allocation routine, in context of which query has been made:
155 * 1 - free
156 * 2 - realloc
157 */
158 uint32_t routine;
159
160 /* Address of memory allocation descriptor for the queried pointer.
161 * Descriptor, addressed by this field is initialized by the emulator in
162 * response to the query.
163 */
164 MallocDesc* desc;
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700165};
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800166
167/* Describes memory block that is being freed back to the heap. This structure
168 * is passed along with TRACE_DEV_REG_FREE_PTR event. The entire structure is
169 * initialized by the guest system before event is fired up. It is important to
170 * remember that same structure (an exact copy, except for replacing pointers
171 * with target_ulong) is also declared in the emulator's sources (file
172 * memcheck/memecheck_common.h). So, every time a change is made to any of these
173 * two declaration, another one must be also updated accordingly.
174 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700175struct MallocFree {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800176 /* Pointer to be freed. */
177 void* ptr;
178
179 /* Id of the process that initialized libc instance, in which this free
180 * is called. This field is used by the emulator to report errors in
181 * the course of TRACE_DEV_REG_FREE_PTR event handling. In case of an
182 * error, emulator sets this field to zero (invalid value for a process ID).
183 */
184 uint32_t libc_pid;
185
186 /* Process ID in context of which memory is being freed. */
187 uint32_t free_pid;
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700188};
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800189
190// =============================================================================
191// Communication events
192// =============================================================================
193
194/* Notifies the emulator that libc has been initialized for a process.
195 * Event's value parameter is PID for the process in context of which libc has
196 * been initialized.
197 */
198#define TRACE_DEV_REG_LIBC_INIT 1536
199
200/* Notifies the emulator about new memory block been allocated.
201 * Event's value parameter points to MallocDesc instance that contains
202 * allocated block information. Note that 'libc_pid' field of the descriptor
203 * is used by emulator to report failure in handling this event. In case
204 * of a failure emulator will zero that field before completing this event.
205 */
206#define TRACE_DEV_REG_MALLOC 1537
207
208/* Notifies the emulator about memory block being freed.
209 * Event's value parameter points to MallocFree descriptor that contains
210 * information about block that's being freed. Note that 'libc_pid' field
211 * of the descriptor is used by emulator to report failure in handling this
212 * event. In case of a failure emulator will zero that field before completing
213 * this event.
214 */
215#define TRACE_DEV_REG_FREE_PTR 1538
216
217/* Queries the emulator about allocated memory block information.
218 * Event's value parameter points to MallocDescQuery descriptor that contains
219 * query parameters. Note that 'libc_pid' field of the descriptor is used by
220 * emulator to report failure in handling this event. In case of a failure
221 * emulator will zero that field before completing this event.
222 */
223#define TRACE_DEV_REG_QUERY_MALLOC 1539
224
225/* Queries the emulator to print a string to its stdout.
226 * Event's value parameter points to a zero-terminated string to be printed.
227 */
228#define TRACE_DEV_REG_PRINT_USER_STR 1540
229
230static void notify_qemu_string(const char* str);
231static void qemu_log(int prio, const char* fmt, ...);
232static void dump_malloc_descriptor(char* str,
233 size_t str_buf_size,
234 const MallocDesc* desc);
235
236// =============================================================================
237// Macros
238// =============================================================================
239
240/* Defines default size of allocation prefix.
241 * Note that we make prefix area quite large in order to increase chances of
242 * catching buffer overflow. */
243#define DEFAULT_PREFIX_SIZE (malloc_alignment * 4)
244
245/* Defines default size of allocation suffix.
246 * Note that we make suffix area quite large in order to increase chances of
247 * catching buffer overflow. */
248#define DEFAULT_SUFFIX_SIZE (malloc_alignment * 4)
249
250/* Debug tracing has been enabled by the emulator. */
251#define DEBUG_TRACING_ENABLED 0x00000001
252/* Error tracing has been enabled by the emulator. */
253#define ERROR_TRACING_ENABLED 0x00000002
254/* Info tracing has been enabled by the emulator. */
255#define INFO_TRACING_ENABLED 0x00000004
256/* All tracing flags combined. */
257#define ALL_TRACING_ENABLED (DEBUG_TRACING_ENABLED | \
258 ERROR_TRACING_ENABLED | \
259 INFO_TRACING_ENABLED)
260
261/* Prints a string to the emulator's stdout.
Elliott Hughes1e980b62013-01-17 18:36:06 -0800262 * In early stages of system loading, logging messages to logcat
263 * is not available, because ADB API has not been
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800264 * hooked up yet. So, in order to see such messages we need to print them to
265 * the emulator's stdout.
266 * Parameters passed to this macro are the same as parameters for printf
267 * routine.
268 */
269#define TR(...) \
270 do { \
271 char tr_str[4096]; \
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700272 snprintf(tr_str, sizeof(tr_str), __VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800273 tr_str[sizeof(tr_str) - 1] = '\0'; \
274 notify_qemu_string(&tr_str[0]); \
275 } while (0)
276
277// =============================================================================
278// Logging macros. Note that we simultaneously log messages to ADB and emulator.
279// =============================================================================
280
281/*
282 * Helper macros for checking if particular trace level is enabled.
283 */
284#define debug_LOG_ENABLED ((tracing_flags & DEBUG_TRACING_ENABLED) != 0)
285#define error_LOG_ENABLED ((tracing_flags & ERROR_TRACING_ENABLED) != 0)
286#define info_LOG_ENABLED ((tracing_flags & INFO_TRACING_ENABLED) != 0)
287#define tracing_enabled(type) (type##_LOG_ENABLED)
288
289/*
290 * Logging helper macros.
291 */
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700292#define qemu_debug_log(format, ...) \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800293 do { \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800294 __libc_format_log(ANDROID_LOG_DEBUG, "memcheck", (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800295 if (tracing_flags & DEBUG_TRACING_ENABLED) { \
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700296 qemu_log(ANDROID_LOG_DEBUG, (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800297 } \
298 } while (0)
299
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700300#define qemu_error_log(format, ...) \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800301 do { \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800302 __libc_format_log(ANDROID_LOG_ERROR, "memcheck", (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800303 if (tracing_flags & ERROR_TRACING_ENABLED) { \
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700304 qemu_log(ANDROID_LOG_ERROR, (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800305 } \
306 } while (0)
307
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700308#define qemu_info_log(format, ...) \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800309 do { \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800310 __libc_format_log(ANDROID_LOG_INFO, "memcheck", (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800311 if (tracing_flags & INFO_TRACING_ENABLED) { \
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700312 qemu_log(ANDROID_LOG_INFO, (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800313 } \
314 } while (0)
315
316/* Logs message dumping MallocDesc instance at the end of the message.
317 * Param:
318 * type - Message type: debug, error, or info
319 * desc - MallocDesc instance to dump.
Elliott Hughes1e980b62013-01-17 18:36:06 -0800320 * fmt + rest - Formats message preceding dumped descriptor.
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800321*/
Elliott Hughes1e980b62013-01-17 18:36:06 -0800322#define log_mdesc(type, desc, fmt, ...) \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800323 do { \
324 if (tracing_enabled(type)) { \
325 char log_str[4096]; \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800326 __libc_format_buffer(log_str, sizeof(log_str), fmt, ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800327 log_str[sizeof(log_str) - 1] = '\0'; \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800328 size_t str_len = strlen(log_str); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800329 dump_malloc_descriptor(log_str + str_len, \
330 sizeof(log_str) - str_len, \
331 (desc)); \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800332 type##_log("%s", log_str); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800333 } \
334 } while (0)
335
336// =============================================================================
337// Static data
338// =============================================================================
339
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700340// The underlying malloc implementation to use to get memory.
341static const MallocDebug* g_malloc_dispatch = NULL;
342
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800343/* Emulator's magic page address.
344 * This page (mapped on /dev/qemu_trace device) is used to fire up events
345 * in the emulator. */
346static volatile void* qtrace = NULL;
347
348/* Cached PID of the process in context of which this libc instance
349 * has been initialized. */
350static uint32_t malloc_pid = 0;
351
Christopher Ferris72bbd422014-05-08 11:14:03 -0700352/* Memory allocation alignment that is used in the malloc implementation.
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800353 * This variable is updated by memcheck_initialize routine. */
354static uint32_t malloc_alignment = 8;
355
356/* Tracing flags. These flags control which types of logging messages are
357 * enabled by the emulator. See XXX_TRACING_ENABLED for the values of flags
358 * stored in this variable. This variable is updated by memcheck_initialize
359 * routine. */
360static uint32_t tracing_flags = 0;
361
362// =============================================================================
363// Static routines
364// =============================================================================
365
366/* Gets pointer, returned to malloc caller for the given allocation decriptor.
367 * Param:
368 * desc - Allocation descriptor.
369 * Return:
370 * Pointer to the allocated memory returned to the malloc caller.
371 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700372static inline void* mallocdesc_user_ptr(const MallocDesc* desc) {
373 return static_cast<char*>(desc->ptr) + desc->prefix_size;
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -0800374}
375
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800376/* Gets size of memory block actually allocated from the heap for the given
377 * allocation decriptor.
378 * Param:
379 * desc - Allocation descriptor.
380 * Return:
381 * Size of memory block actually allocated from the heap.
382 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700383static inline uint32_t mallocdesc_alloc_size(const MallocDesc* desc) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800384 return desc->prefix_size + desc->requested_bytes + desc->suffix_size;
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -0800385}
386
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800387/* Gets pointer to the end of the allocated block for the given descriptor.
388 * Param:
389 * desc - Descriptor for the memory block, allocated in malloc handler.
390 * Return:
391 * Pointer to the end of (one byte past) the allocated block.
392 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700393static inline void* mallocdesc_alloc_end(const MallocDesc* desc) {
394 return static_cast<char*>(desc->ptr) + mallocdesc_alloc_size(desc);
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -0800395}
396
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800397/* Fires up an event in the emulator.
398 * Param:
399 * code - Event code (one of the TRACE_DEV_XXX).
400 * val - Event's value parameter.
401 */
Elliott Hughesef0696d2013-10-08 16:16:01 -0700402static inline void notify_qemu(uint32_t code, uintptr_t val) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800403 if (NULL != qtrace) {
Elliott Hughesef0696d2013-10-08 16:16:01 -0700404 *(volatile uintptr_t*)((uintptr_t)qtrace + ((code - 1024) << 2)) = val;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800405 }
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -0800406}
407
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800408/* Prints a zero-terminated string to the emulator's stdout (fires up
409 * TRACE_DEV_REG_PRINT_USER_STR event in the emulator).
410 * Param:
411 * str - Zero-terminated string to print.
412 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700413static void notify_qemu_string(const char* str) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800414 if (str != NULL) {
Elliott Hughesef0696d2013-10-08 16:16:01 -0700415 notify_qemu(TRACE_DEV_REG_PRINT_USER_STR, reinterpret_cast<uintptr_t>(str));
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800416 }
417}
418
419/* Fires up TRACE_DEV_REG_LIBC_INIT event in the emulator.
420 * Param:
421 * pid - ID of the process that initialized libc.
422 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700423static void notify_qemu_libc_initialized(uint32_t pid) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800424 notify_qemu(TRACE_DEV_REG_LIBC_INIT, pid);
425}
426
427/* Fires up TRACE_DEV_REG_MALLOC event in the emulator.
428 * Param:
429 * desc - Pointer to MallocDesc instance containing allocated block
430 * information.
431 * Return:
432 * Zero on success, or -1 on failure. Note that on failure libc_pid field of
433 * the desc parameter passed to this routine has been zeroed out by the
434 * emulator.
435 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700436static inline int notify_qemu_malloc(volatile MallocDesc* desc) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800437 desc->libc_pid = malloc_pid;
438 desc->allocator_pid = getpid();
439 desc->av_count = 0;
Elliott Hughesef0696d2013-10-08 16:16:01 -0700440 notify_qemu(TRACE_DEV_REG_MALLOC, reinterpret_cast<uintptr_t>(desc));
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800441
442 /* Emulator reports failure by zeroing libc_pid field of the
443 * descriptor. */
444 return desc->libc_pid != 0 ? 0 : -1;
445}
446
447/* Fires up TRACE_DEV_REG_FREE_PTR event in the emulator.
448 * Param:
449 * ptr - Pointer to the memory block that's being freed.
450 * Return:
451 * Zero on success, or -1 on failure.
452 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700453static inline int notify_qemu_free(void* ptr_to_free) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800454 volatile MallocFree free_desc;
455
456 free_desc.ptr = ptr_to_free;
457 free_desc.libc_pid = malloc_pid;
458 free_desc.free_pid = getpid();
Elliott Hughesef0696d2013-10-08 16:16:01 -0700459 notify_qemu(TRACE_DEV_REG_FREE_PTR, reinterpret_cast<uintptr_t>(&free_desc));
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800460
461 /* Emulator reports failure by zeroing libc_pid field of the
462 * descriptor. */
463 return free_desc.libc_pid != 0 ? 0 : -1;
464}
465
466/* Fires up TRACE_DEV_REG_QUERY_MALLOC event in the emulator.
467 * Param:
468 * ptr - Pointer to request allocation information for.
469 * desc - Pointer to MallocDesc instance that will receive allocation
470 * information.
471 * routine - Code of the allocation routine, in context of which query is made:
472 * 1 - free
473 * 2 - realloc
474 * Return:
475 * Zero on success, or -1 on failure.
476 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700477static inline int query_qemu_malloc_info(const void* ptr, MallocDesc* desc, uint32_t routine) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800478 volatile MallocDescQuery query;
479
480 query.ptr = ptr;
481 query.libc_pid = malloc_pid;
482 query.query_pid = getpid();
483 query.routine = routine;
484 query.desc = desc;
Elliott Hughesef0696d2013-10-08 16:16:01 -0700485 notify_qemu(TRACE_DEV_REG_QUERY_MALLOC, reinterpret_cast<uintptr_t>(&query));
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800486
487 /* Emulator reports failure by zeroing libc_pid field of the
488 * descriptor. */
489 return query.libc_pid != 0 ? 0 : -1;
490}
491
492/* Logs a message to emulator's stdout.
493 * Param:
494 * prio - Message priority (debug, info, or error)
495 * fmt + rest - Message format and parameters.
496 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700497static void qemu_log(int prio, const char* fmt, ...) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800498 va_list ap;
499 char buf[4096];
500 const char* prefix;
501
502 /* Choose message prefix depending on the priority value. */
503 switch (prio) {
504 case ANDROID_LOG_ERROR:
505 if (!tracing_enabled(error)) {
506 return;
507 }
508 prefix = "E";
509 break;
510 case ANDROID_LOG_INFO:
511 if (!tracing_enabled(info)) {
512 return;
513 }
514 prefix = "I";
515 break;
516 case ANDROID_LOG_DEBUG:
517 default:
518 if (!tracing_enabled(debug)) {
519 return;
520 }
521 prefix = "D";
522 break;
523 }
524
525 va_start(ap, fmt);
526 vsnprintf(buf, sizeof(buf), fmt, ap);
527 va_end(ap);
528 buf[sizeof(buf) - 1] = '\0';
529
530 TR("%s/memcheck: %s\n", prefix, buf);
531}
532
533/* Dumps content of memory allocation descriptor to a string.
534 * Param:
535 * str - String to dump descriptor to.
536 * str_buf_size - Size of string's buffer.
537 * desc - Descriptor to dump.
538 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700539static void dump_malloc_descriptor(char* str, size_t str_buf_size, const MallocDesc* desc) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800540 if (str_buf_size) {
541 snprintf(str, str_buf_size,
Elliott Hughesef0696d2013-10-08 16:16:01 -0700542 "MDesc: %p: %p <-> %p [%u + %u + %u] by pid=%03u in libc_pid=%03u",
543 mallocdesc_user_ptr(desc), desc->ptr,
544 mallocdesc_alloc_end(desc), desc->prefix_size,
545 desc->requested_bytes, desc->suffix_size, desc->allocator_pid,
546 desc->libc_pid);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800547 str[str_buf_size - 1] = '\0';
548 }
549}
550
551#if TEST_ACCESS_VIOLATIONS
552/* Causes an access violation on allocation descriptor, and verifies that
553 * violation has been detected by memory checker in the emulator.
554 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700555static void test_access_violation(const MallocDesc* desc) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800556 MallocDesc desc_chk;
557 char ch;
558 volatile char* prefix = (volatile char*)desc->ptr;
559 volatile char* suffix = (volatile char*)mallocdesc_user_ptr(desc) +
560 desc->requested_bytes;
561 /* We're causing AV by reading from the prefix and suffix areas of the
562 * allocated block. This should produce two access violations, so when we
563 * get allocation descriptor from QEMU, av_counter should be bigger than
564 * av_counter of the original descriptor by 2. */
565 ch = *prefix;
566 ch = *suffix;
567 if (!query_qemu_malloc_info(mallocdesc_user_ptr(desc), &desc_chk, 2) &&
568 desc_chk.av_count != (desc->av_count + 2)) {
569 log_mdesc(error, &desc_chk,
570 "<libc_pid=%03u, pid=%03u>: malloc: Access violation test failed:\n"
571 "Expected violations count %u is not equal to the actually reported %u",
572 malloc_pid, getpid(), desc->av_count + 2,
573 desc_chk.av_count);
574 }
575}
576#endif // TEST_ACCESS_VIOLATIONS
577
578// =============================================================================
579// API routines
580// =============================================================================
581
Christopher Ferrisa4037802014-06-09 19:14:11 -0700582extern "C" void* qemu_instrumented_calloc(size_t, size_t);
583extern "C" void qemu_instrumented_free(void*);
584extern "C" struct mallinfo qemu_instrumented_mallinfo();
585extern "C" void* qemu_instrumented_malloc(size_t);
586extern "C" size_t qemu_instrumented_malloc_usable_size(const void*);
587extern "C" void* qemu_instrumented_memalign(size_t, size_t);
588extern "C" int qemu_instrumented_posix_memalign(void**, size_t, size_t);
589extern "C" void* qemu_instrumented_pvalloc(size_t);
590extern "C" void* qemu_instrumented_realloc(void*, size_t);
591extern "C" void* qemu_instrumented_valloc(size_t);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800592
593/* Initializes malloc debugging instrumentation for the emulator.
594 * This routine is called from malloc_init_impl routine implemented in
595 * bionic/libc/bionic/malloc_debug_common.c when malloc debugging gets
596 * initialized for a process. The way malloc debugging implementation is
597 * done, it is guaranteed that this routine will be called just once per
598 * process.
599 * Return:
600 * 0 on success, or -1 on failure.
601*/
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700602extern "C" bool malloc_debug_initialize(HashTable*, const MallocDebug* malloc_dispatch) {
603 g_malloc_dispatch = malloc_dispatch;
604
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800605 /* We will be using emulator's magic page to report memory allocation
606 * activities. In essence, what magic page does, it translates writes to
607 * the memory mapped spaces into writes to an I/O port that emulator
608 * "listens to" on the other end. Note that until we open and map that
609 * device, logging to emulator's stdout will not be available. */
Elliott Hughesf73183f2014-08-26 16:20:59 -0700610 int fd = open("/dev/qemu_trace", O_CLOEXEC | O_RDWR);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800611 if (fd < 0) {
612 error_log("Unable to open /dev/qemu_trace");
Elliott Hughes8e52e8f2014-06-04 12:07:11 -0700613 return false;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800614 } else {
Elliott Hughes0d787c12013-04-04 13:46:46 -0700615 qtrace = mmap(NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800616 close(fd);
617
618 if (qtrace == MAP_FAILED) {
619 qtrace = NULL;
620 error_log("Unable to mmap /dev/qemu_trace");
Elliott Hughes8e52e8f2014-06-04 12:07:11 -0700621 return false;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800622 }
623 }
624
625 /* Cache pid of the process this library has been initialized for. */
626 malloc_pid = getpid();
Elliott Hughes8e52e8f2014-06-04 12:07:11 -0700627 return true;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800628}
629
630/* Completes malloc debugging instrumentation for the emulator.
631 * Note that this routine is called after successful return from
632 * malloc_debug_initialize, which means that connection to the emulator via
633 * "magic page" has been established.
634 * Param:
635 * alignment - Alignment requirement set for memiry allocations.
636 * memcheck_param - Emulator's -memcheck option parameters. This string
637 * contains abbreviation for guest events that are enabled for tracing.
638 * Return:
639 * 0 on success, or -1 on failure.
640*/
Christopher Ferris885f3b92013-05-21 17:48:01 -0700641extern "C" int memcheck_initialize(int alignment, const char* memcheck_param) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800642 malloc_alignment = alignment;
643
644 /* Parse -memcheck parameter for the guest tracing flags. */
645 while (*memcheck_param != '\0') {
646 switch (*memcheck_param) {
647 case 'a':
648 // Enable all messages from the guest.
649 tracing_flags |= ALL_TRACING_ENABLED;
650 break;
651 case 'd':
652 // Enable debug messages from the guest.
653 tracing_flags |= DEBUG_TRACING_ENABLED;
654 break;
655 case 'e':
656 // Enable error messages from the guest.
657 tracing_flags |= ERROR_TRACING_ENABLED;
658 break;
659 case 'i':
660 // Enable info messages from the guest.
661 tracing_flags |= INFO_TRACING_ENABLED;
662 break;
663 default:
664 break;
665 }
666 if (tracing_flags == ALL_TRACING_ENABLED) {
667 break;
668 }
669 memcheck_param++;
670 }
671
672 notify_qemu_libc_initialized(malloc_pid);
673
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700674 qemu_debug_log("Instrumented for pid=%03u: malloc=%p, free=%p, calloc=%p, realloc=%p, memalign=%p",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800675 malloc_pid, qemu_instrumented_malloc, qemu_instrumented_free,
676 qemu_instrumented_calloc, qemu_instrumented_realloc,
677 qemu_instrumented_memalign);
678
679 return 0;
680}
681
682/* This routine serves as entry point for 'malloc'.
683 * Primary responsibility of this routine is to allocate requested number of
684 * bytes (plus prefix, and suffix guards), and report allocation to the
685 * emulator.
686 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700687extern "C" void* qemu_instrumented_malloc(size_t bytes) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800688 MallocDesc desc;
689
Christopher Ferris72bbd422014-05-08 11:14:03 -0700690 /* Initialize block descriptor and allocate memory. Note that malloc
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800691 * returns a valid pointer on zero allocation. Lets mimic this behavior. */
692 desc.prefix_size = DEFAULT_PREFIX_SIZE;
693 desc.requested_bytes = bytes;
694 desc.suffix_size = DEFAULT_SUFFIX_SIZE;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700695 size_t size = mallocdesc_alloc_size(&desc);
696 if (size < bytes) { // Overflow
697 qemu_error_log("<libc_pid=%03u, pid=%03u> malloc: malloc(%zu) overflow caused failure.",
698 malloc_pid, getpid(), bytes);
699 errno = ENOMEM;
700 return NULL;
701 }
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700702 desc.ptr = g_malloc_dispatch->malloc(size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800703 if (desc.ptr == NULL) {
Christopher Ferris580b6e02014-06-12 18:20:44 -0700704 qemu_error_log("<libc_pid=%03u, pid=%03u> malloc(%zu): malloc(%zu) failed.",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700705 malloc_pid, getpid(), bytes, size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800706 return NULL;
707 }
708
709 // Fire up event in the emulator.
710 if (notify_qemu_malloc(&desc)) {
711 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: malloc: notify_malloc failed for ",
712 malloc_pid, getpid());
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700713 g_malloc_dispatch->free(desc.ptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700714 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800715 return NULL;
716 } else {
717#if TEST_ACCESS_VIOLATIONS
718 test_access_violation(&desc);
719#endif // TEST_ACCESS_VIOLATIONS
Christopher Ferrisa4037802014-06-09 19:14:11 -0700720 log_mdesc(info, &desc, "+++ <libc_pid=%03u, pid=%03u> malloc(%zu) -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800721 malloc_pid, getpid(), bytes);
722 return mallocdesc_user_ptr(&desc);
723 }
724}
725
726/* This routine serves as entry point for 'malloc'.
727 * Primary responsibility of this routine is to free requested memory, and
728 * report free block to the emulator.
729 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700730extern "C" void qemu_instrumented_free(void* mem) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800731 MallocDesc desc;
732
733 if (mem == NULL) {
734 // Just let go NULL free
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700735 g_malloc_dispatch->free(mem);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800736 return;
737 }
738
739 // Query emulator for the freeing block information.
740 if (query_qemu_malloc_info(mem, &desc, 1)) {
741 error_log("<libc_pid=%03u, pid=%03u>: free(%p) query_info failed.",
742 malloc_pid, getpid(), mem);
743 return;
744 }
745
746#if TEST_ACCESS_VIOLATIONS
747 test_access_violation(&desc);
748#endif // TEST_ACCESS_VIOLATIONS
749
750 /* Make sure that pointer that's being freed matches what we expect
751 * for this memory block. Note that this violation should be already
752 * caught in the emulator. */
753 if (mem != mallocdesc_user_ptr(&desc)) {
754 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) is invalid for ",
755 malloc_pid, getpid(), mem);
756 return;
757 }
758
759 // Fire up event in the emulator and free block that was actually allocated.
760 if (notify_qemu_free(mem)) {
761 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) notify_free failed for ",
762 malloc_pid, getpid(), mem);
763 } else {
764 log_mdesc(info, &desc, "--- <libc_pid=%03u, pid=%03u> free(%p) -> ",
765 malloc_pid, getpid(), mem);
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700766 g_malloc_dispatch->free(desc.ptr);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800767 }
768}
769
770/* This routine serves as entry point for 'calloc'.
771 * This routine behaves similarly to qemu_instrumented_malloc.
772 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700773extern "C" void* qemu_instrumented_calloc(size_t n_elements, size_t elem_size) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800774 if (n_elements == 0 || elem_size == 0) {
775 // Just let go zero bytes allocation.
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700776 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: Zero calloc redir to malloc",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700777 malloc_pid, getpid());
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800778 return qemu_instrumented_malloc(0);
779 }
780
Elliott Hughes8e52e8f2014-06-04 12:07:11 -0700781 // Fail on overflow - just to be safe even though this code runs only
782 // within the debugging C library, not the production one.
783 if (n_elements && SIZE_MAX / n_elements < elem_size) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700784 qemu_error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu, %zu) overflow caused failure.",
785 malloc_pid, getpid(), n_elements, elem_size);
786 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800787 return NULL;
788 }
789
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700790 MallocDesc desc;
791
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800792 /* Calculating prefix size. The trick here is to make sure that
793 * first element (returned to the caller) is properly aligned. */
794 if (DEFAULT_PREFIX_SIZE >= elem_size) {
795 /* If default alignment is bigger than element size, we will
796 * set our prefix size to the default alignment size. */
797 desc.prefix_size = DEFAULT_PREFIX_SIZE;
798 /* For the suffix we will use whatever bytes remain from the prefix
799 * allocation size, aligned to the size of an element, plus the usual
800 * default suffix size. */
801 desc.suffix_size = (DEFAULT_PREFIX_SIZE % elem_size) +
802 DEFAULT_SUFFIX_SIZE;
803 } else {
804 /* Make sure that prefix, and suffix sizes is at least elem_size,
805 * and first element returned to the caller is properly aligned. */
806 desc.prefix_size = elem_size + DEFAULT_PREFIX_SIZE - 1;
807 desc.prefix_size &= ~(malloc_alignment - 1);
808 desc.suffix_size = DEFAULT_SUFFIX_SIZE;
809 }
810 desc.requested_bytes = n_elements * elem_size;
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700811 size_t total_size = desc.requested_bytes + desc.prefix_size + desc.suffix_size;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700812 if (total_size < desc.requested_bytes) { // Overflow
813 qemu_error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu, %zu) overflow caused failure.",
814 malloc_pid, getpid(), n_elements, elem_size);
815 errno = ENOMEM;
816 return NULL;
817 }
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700818 size_t total_elements = total_size / elem_size;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800819 total_size %= elem_size;
820 if (total_size != 0) {
821 // Add extra to the suffix area.
822 total_elements++;
823 desc.suffix_size += (elem_size - total_size);
824 }
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700825 desc.ptr = g_malloc_dispatch->calloc(total_elements, elem_size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800826 if (desc.ptr == NULL) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700827 error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu(%zu), %zu) (prx=%u, sfx=%u) failed.",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800828 malloc_pid, getpid(), n_elements, total_elements, elem_size,
829 desc.prefix_size, desc.suffix_size);
830 return NULL;
831 }
832
833 if (notify_qemu_malloc(&desc)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700834 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: calloc(%zu(%zu), %zu): notify_malloc failed for ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800835 malloc_pid, getpid(), n_elements, total_elements, elem_size);
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700836 g_malloc_dispatch->free(desc.ptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700837 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800838 return NULL;
839 } else {
840#if TEST_ACCESS_VIOLATIONS
841 test_access_violation(&desc);
842#endif // TEST_ACCESS_VIOLATIONS
Christopher Ferrisa4037802014-06-09 19:14:11 -0700843 log_mdesc(info, &desc, "### <libc_pid=%03u, pid=%03u> calloc(%zu(%zu), %zu) -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800844 malloc_pid, getpid(), n_elements, total_elements, elem_size);
845 return mallocdesc_user_ptr(&desc);
846 }
847}
848
849/* This routine serves as entry point for 'realloc'.
850 * This routine behaves similarly to qemu_instrumented_free +
851 * qemu_instrumented_malloc. Note that this modifies behavior of "shrinking" an
852 * allocation, but overall it doesn't seem to matter, as caller of realloc
853 * should not expect that pointer returned after shrinking will remain the same.
854 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700855extern "C" void* qemu_instrumented_realloc(void* mem, size_t bytes) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800856 if (mem == NULL) {
857 // Nothing to realloc. just do regular malloc.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700858 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) redir to malloc",
859 malloc_pid, getpid(), mem, bytes);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800860 return qemu_instrumented_malloc(bytes);
861 }
862
863 if (bytes == 0) {
864 // This is a "free" condition.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700865 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) redir to free and malloc",
866 malloc_pid, getpid(), mem, bytes);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800867 qemu_instrumented_free(mem);
868
Christopher Ferris72bbd422014-05-08 11:14:03 -0700869 // This is what realloc does for a "free" realloc.
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800870 return NULL;
871 }
872
873 // Query emulator for the reallocating block information.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700874 MallocDesc cur_desc;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800875 if (query_qemu_malloc_info(mem, &cur_desc, 2)) {
876 // Note that this violation should be already caught in the emulator.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700877 error_log("<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) query_info failed.",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800878 malloc_pid, getpid(), mem, bytes);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700879 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800880 return NULL;
881 }
882
883#if TEST_ACCESS_VIOLATIONS
884 test_access_violation(&cur_desc);
885#endif // TEST_ACCESS_VIOLATIONS
886
887 /* Make sure that reallocating pointer value is what we would expect
888 * for this memory block. Note that this violation should be already caught
889 * in the emulator.*/
890 if (mem != mallocdesc_user_ptr(&cur_desc)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700891 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) is invalid for ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800892 malloc_pid, getpid(), mem, bytes);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700893 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800894 return NULL;
895 }
896
897 /* TODO: We're a bit inefficient here, always allocating new block from
898 * the heap. If this realloc shrinks current buffer, we can just do the
899 * shrinking "in place", adjusting suffix_size in the allocation descriptor
900 * for this block that is stored in the emulator. */
901
902 // Initialize descriptor for the new block.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700903 MallocDesc new_desc;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800904 new_desc.prefix_size = DEFAULT_PREFIX_SIZE;
905 new_desc.requested_bytes = bytes;
906 new_desc.suffix_size = DEFAULT_SUFFIX_SIZE;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700907 size_t new_size = mallocdesc_alloc_size(&new_desc);
908 if (new_size < bytes) { // Overflow
Christopher Ferris580b6e02014-06-12 18:20:44 -0700909 qemu_error_log("<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed due to overflow",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700910 malloc_pid, getpid(), mem, bytes, new_size);
911 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800912 return NULL;
913 }
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700914 new_desc.ptr = g_malloc_dispatch->malloc(new_size);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700915 if (new_desc.ptr == NULL) {
Christopher Ferris580b6e02014-06-12 18:20:44 -0700916 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed on ",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700917 malloc_pid, getpid(), mem, bytes, new_size);
918 return NULL;
919 }
920 void* new_mem = mallocdesc_user_ptr(&new_desc);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800921
922 // Copy user data from old block to the new one.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700923 size_t to_copy = bytes < cur_desc.requested_bytes ? bytes : cur_desc.requested_bytes;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800924 if (to_copy != 0) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700925 memcpy(new_mem, mallocdesc_user_ptr(&cur_desc), to_copy);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800926 }
927
928 // Register new block with emulator.
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700929 if (notify_qemu_malloc(&new_desc)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700930 log_mdesc(error, &new_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) notify_malloc failed -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800931 malloc_pid, getpid(), mem, bytes);
932 log_mdesc(error, &cur_desc, " <- ");
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700933 g_malloc_dispatch->free(new_desc.ptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700934 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800935 return NULL;
936 }
937
938#if TEST_ACCESS_VIOLATIONS
939 test_access_violation(&new_desc);
940#endif // TEST_ACCESS_VIOLATIONS
941
942 // Free old block.
943 if (notify_qemu_free(mem)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700944 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): notify_free failed for ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800945 malloc_pid, getpid(), mem, bytes);
946 /* Since we registered new decriptor with the emulator, we need
947 * to unregister it before freeing newly allocated block. */
948 notify_qemu_free(mallocdesc_user_ptr(&new_desc));
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700949 g_malloc_dispatch->free(new_desc.ptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700950 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800951 return NULL;
952 }
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700953 g_malloc_dispatch->free(cur_desc.ptr);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800954
Christopher Ferrisa4037802014-06-09 19:14:11 -0700955 log_mdesc(info, &new_desc, "=== <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800956 malloc_pid, getpid(), mem, bytes);
957 log_mdesc(info, &cur_desc, " <- ");
958
Christopher Ferrisa4037802014-06-09 19:14:11 -0700959 return new_mem;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800960}
961
962/* This routine serves as entry point for 'memalign'.
963 * This routine behaves similarly to qemu_instrumented_malloc.
964 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700965extern "C" void* qemu_instrumented_memalign(size_t alignment, size_t bytes) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800966 MallocDesc desc;
967
968 if (bytes == 0) {
969 // Just let go zero bytes allocation.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700970 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: memalign(%zx, %zu) redir to malloc",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800971 malloc_pid, getpid(), alignment, bytes);
972 return qemu_instrumented_malloc(0);
973 }
974
Christopher Ferrisa4037802014-06-09 19:14:11 -0700975 // Prefix size for aligned allocation must be equal to the alignment used
976 // for allocation in order to ensure proper alignment of the returned
977 // pointer. in case that alignment requirement is greater than prefix
978 // size.
979 if (alignment < DEFAULT_PREFIX_SIZE) {
980 alignment = DEFAULT_PREFIX_SIZE;
Christopher Ferris03eebcb2014-06-13 13:57:51 -0700981 } else if (!powerof2(alignment)) {
982 alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700983 }
984 desc.prefix_size = alignment;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800985 desc.requested_bytes = bytes;
986 desc.suffix_size = DEFAULT_SUFFIX_SIZE;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700987 size_t size = mallocdesc_alloc_size(&desc);
988 if (size < bytes) { // Overflow
Christopher Ferris580b6e02014-06-12 18:20:44 -0700989 qemu_error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed due to overflow.",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700990 malloc_pid, getpid(), alignment, bytes, size);
991
992 return NULL;
993 }
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -0700994 desc.ptr = g_malloc_dispatch->memalign(desc.prefix_size, size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800995 if (desc.ptr == NULL) {
Christopher Ferris580b6e02014-06-12 18:20:44 -0700996 error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed.",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700997 malloc_pid, getpid(), alignment, bytes, size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800998 return NULL;
999 }
1000 if (notify_qemu_malloc(&desc)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -07001001 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: memalign(%zx, %zu): notify_malloc failed for ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -08001002 malloc_pid, getpid(), alignment, bytes);
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -07001003 g_malloc_dispatch->free(desc.ptr);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -08001004 return NULL;
1005 }
1006
1007#if TEST_ACCESS_VIOLATIONS
1008 test_access_violation(&desc);
1009#endif // TEST_ACCESS_VIOLATIONS
1010
Christopher Ferrisa4037802014-06-09 19:14:11 -07001011 log_mdesc(info, &desc, "@@@ <libc_pid=%03u, pid=%03u> memalign(%zx, %zu) -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -08001012 malloc_pid, getpid(), alignment, bytes);
1013 return mallocdesc_user_ptr(&desc);
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -08001014}
Christopher Ferris885f3b92013-05-21 17:48:01 -07001015
1016extern "C" size_t qemu_instrumented_malloc_usable_size(const void* mem) {
1017 MallocDesc cur_desc;
1018
1019 // Query emulator for the reallocating block information.
1020 if (query_qemu_malloc_info(mem, &cur_desc, 2)) {
1021 // Note that this violation should be already caught in the emulator.
1022 error_log("<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) query_info failed.",
1023 malloc_pid, getpid(), mem);
1024 return 0;
1025 }
1026
1027 /* Make sure that reallocating pointer value is what we would expect
1028 * for this memory block. Note that this violation should be already caught
1029 * in the emulator.*/
1030 if (mem != mallocdesc_user_ptr(&cur_desc)) {
1031 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) is invalid for ",
1032 malloc_pid, getpid(), mem);
1033 return 0;
1034 }
1035
1036 /* during instrumentation, we can't really report anything more than requested_bytes */
1037 return cur_desc.requested_bytes;
1038}
Christopher Ferrisa4037802014-06-09 19:14:11 -07001039
1040extern "C" struct mallinfo qemu_instrumented_mallinfo() {
Christopher Ferrisdda1c6c2014-07-09 17:16:07 -07001041 return g_malloc_dispatch->mallinfo();
Christopher Ferrisa4037802014-06-09 19:14:11 -07001042}
1043
1044extern "C" int qemu_instrumented_posix_memalign(void** memptr, size_t alignment, size_t size) {
1045 if ((alignment & (alignment - 1)) != 0) {
1046 qemu_error_log("<libc_pid=%03u, pid=%03u> posix_memalign(%p, %zu, %zu): invalid alignment.",
1047 malloc_pid, getpid(), memptr, alignment, size);
1048 return EINVAL;
1049 }
1050 int saved_errno = errno;
1051 *memptr = qemu_instrumented_memalign(alignment, size);
1052 errno = saved_errno;
1053 return (*memptr != NULL) ? 0 : ENOMEM;
1054}
1055
1056extern "C" void* qemu_instrumented_pvalloc(size_t bytes) {
Elliott Hughes91570ce2014-07-10 12:34:23 -07001057 size_t pagesize = getpagesize();
Christopher Ferris03eebcb2014-06-13 13:57:51 -07001058 size_t size = BIONIC_ALIGN(bytes, pagesize);
Christopher Ferrisa4037802014-06-09 19:14:11 -07001059 if (size < bytes) { // Overflow
1060 qemu_error_log("<libc_pid=%03u, pid=%03u> pvalloc(%zu): overflow (%zu).",
1061 malloc_pid, getpid(), bytes, size);
1062 return NULL;
1063 }
1064 return qemu_instrumented_memalign(pagesize, size);
1065}
1066
1067extern "C" void* qemu_instrumented_valloc(size_t size) {
Elliott Hughes91570ce2014-07-10 12:34:23 -07001068 return qemu_instrumented_memalign(getpagesize(), size);
Christopher Ferrisa4037802014-06-09 19:14:11 -07001069}