blob: 9b3bb5578f9e37cd7289c87b422f2a5bab9d28b2 [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>
48#include <fcntl.h>
49#include <sys/mman.h>
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080050#include <pthread.h>
51#include <unistd.h>
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080052#include <errno.h>
Elliott Hugheseb847bc2013-10-09 15:50:50 -070053#include "private/libc_logging.h"
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080054#include "malloc_debug_common.h"
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080055
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080056/* This file should be included into the build only when
57 * MALLOC_QEMU_INSTRUMENT macro is defined. */
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080058#ifndef MALLOC_QEMU_INSTRUMENT
59#error MALLOC_QEMU_INSTRUMENT is not defined.
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080060#endif // !MALLOC_QEMU_INSTRUMENT
61
62/* Controls access violation test performed to make sure that we catch AVs
63 * all the time they occur. See test_access_violation for more info. This macro
64 * is used for internal testing purposes and should always be set to zero for
65 * the production builds. */
66#define TEST_ACCESS_VIOLATIONS 0
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080067
68// =============================================================================
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080069// Communication structures
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080070// =============================================================================
71
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080072/* Describes memory block allocated from the heap. This structure is passed
73 * along with TRACE_DEV_REG_MALLOC event. This descriptor is used to inform
74 * the emulator about new memory block being allocated from the heap. The entire
75 * structure is initialized by the guest system before event is fired up. It is
76 * important to remember that same structure (an exact copy, except for
77 * replacing pointers with target_ulong) is also declared in the emulator's
78 * sources (file memcheck/memcheck_common.h). So, every time a change is made to
79 * any of these two declaration, another one must be also updated accordingly.
80 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -070081struct MallocDesc {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080082 /* Pointer to the memory block actually allocated from the heap. Note that
83 * this is not the pointer that is returned to the malloc's caller. Pointer
84 * returned to the caller is calculated by adding value stored in this field
85 * to the value stored in prefix_size field of this structure.
86 */
87 void* ptr;
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -080088
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -080089 /* Number of bytes requested by the malloc's caller. */
90 uint32_t requested_bytes;
91
92 /* Byte size of the prefix data. Actual pointer returned to the malloc's
93 * caller is calculated by adding value stored in this field to the value
94 * stored in in the ptr field of this structure.
95 */
96 uint32_t prefix_size;
97
98 /* Byte size of the suffix data. */
99 uint32_t suffix_size;
100
101 /* Id of the process that initialized libc instance, in which allocation
102 * has occurred. This field is used by the emulator to report errors in
103 * the course of TRACE_DEV_REG_MALLOC event handling. In case of an error,
104 * emulator sets this field to zero (invalid value for a process ID).
105 */
106 uint32_t libc_pid;
107
108 /* Id of the process in context of which allocation has occurred.
109 * Value in this field may differ from libc_pid value, if process that
110 * is doing allocation has been forked from the process that initialized
111 * libc instance.
112 */
113 uint32_t allocator_pid;
114
115 /* Number of access violations detected on this allocation. */
116 uint32_t av_count;
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700117};
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800118
119/* Describes memory block info queried from emulator. This structure is passed
120 * along with TRACE_DEV_REG_QUERY_MALLOC event. When handling free and realloc
121 * calls, it is required that we have information about memory blocks that were
122 * actually allocated in previous calls to malloc, calloc, memalign, or realloc.
123 * Since we don't keep this information directly in the allocated block, but
124 * rather we keep it in the emulator, we need to query emulator for that
125 * information with TRACE_DEV_REG_QUERY_MALLOC query. The entire structure is
126 * initialized by the guest system before event is fired up. It is important to
127 * remember that same structure (an exact copy, except for replacing pointers
128 * with target_ulong) is also declared in the emulator's sources (file
129 * memcheck/memecheck_common.h). So, every time a change is made to any of these
130 * two declaration, another one must be also updated accordingly.
131 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700132struct MallocDescQuery {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800133 /* Pointer, for which information is queried. Note that this pointer doesn't
134 * have to be exact pointer returned to malloc's caller, but can point
135 * anywhere inside an allocated block, including guarding areas. Emulator
136 * will respond with information about allocated block that contains this
137 * pointer.
138 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700139 const void* ptr;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800140
141 /* Id of the process that initialized libc instance, in which this query
142 * is called. This field is used by the emulator to report errors in
143 * the course of TRACE_DEV_REG_QUERY_MALLOC event handling. In case of an
144 * error, emulator sets this field to zero (invalid value for a process ID).
145 */
146 uint32_t libc_pid;
147
148 /* Process ID in context of which query is made. */
149 uint32_t query_pid;
150
151 /* Code of the allocation routine, in context of which query has been made:
152 * 1 - free
153 * 2 - realloc
154 */
155 uint32_t routine;
156
157 /* Address of memory allocation descriptor for the queried pointer.
158 * Descriptor, addressed by this field is initialized by the emulator in
159 * response to the query.
160 */
161 MallocDesc* desc;
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700162};
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800163
164/* Describes memory block that is being freed back to the heap. This structure
165 * is passed along with TRACE_DEV_REG_FREE_PTR event. The entire structure is
166 * initialized by the guest system before event is fired up. It is important to
167 * remember that same structure (an exact copy, except for replacing pointers
168 * with target_ulong) is also declared in the emulator's sources (file
169 * memcheck/memecheck_common.h). So, every time a change is made to any of these
170 * two declaration, another one must be also updated accordingly.
171 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700172struct MallocFree {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800173 /* Pointer to be freed. */
174 void* ptr;
175
176 /* Id of the process that initialized libc instance, in which this free
177 * is called. This field is used by the emulator to report errors in
178 * the course of TRACE_DEV_REG_FREE_PTR event handling. In case of an
179 * error, emulator sets this field to zero (invalid value for a process ID).
180 */
181 uint32_t libc_pid;
182
183 /* Process ID in context of which memory is being freed. */
184 uint32_t free_pid;
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700185};
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800186
187// =============================================================================
188// Communication events
189// =============================================================================
190
191/* Notifies the emulator that libc has been initialized for a process.
192 * Event's value parameter is PID for the process in context of which libc has
193 * been initialized.
194 */
195#define TRACE_DEV_REG_LIBC_INIT 1536
196
197/* Notifies the emulator about new memory block been allocated.
198 * Event's value parameter points to MallocDesc instance that contains
199 * allocated block information. Note that 'libc_pid' field of the descriptor
200 * is used by emulator to report failure in handling this event. In case
201 * of a failure emulator will zero that field before completing this event.
202 */
203#define TRACE_DEV_REG_MALLOC 1537
204
205/* Notifies the emulator about memory block being freed.
206 * Event's value parameter points to MallocFree descriptor that contains
207 * information about block that's being freed. Note that 'libc_pid' field
208 * of the descriptor is used by emulator to report failure in handling this
209 * event. In case of a failure emulator will zero that field before completing
210 * this event.
211 */
212#define TRACE_DEV_REG_FREE_PTR 1538
213
214/* Queries the emulator about allocated memory block information.
215 * Event's value parameter points to MallocDescQuery descriptor that contains
216 * query parameters. Note that 'libc_pid' field of the descriptor is used by
217 * emulator to report failure in handling this event. In case of a failure
218 * emulator will zero that field before completing this event.
219 */
220#define TRACE_DEV_REG_QUERY_MALLOC 1539
221
222/* Queries the emulator to print a string to its stdout.
223 * Event's value parameter points to a zero-terminated string to be printed.
224 */
225#define TRACE_DEV_REG_PRINT_USER_STR 1540
226
227static void notify_qemu_string(const char* str);
228static void qemu_log(int prio, const char* fmt, ...);
229static void dump_malloc_descriptor(char* str,
230 size_t str_buf_size,
231 const MallocDesc* desc);
232
233// =============================================================================
234// Macros
235// =============================================================================
236
237/* Defines default size of allocation prefix.
238 * Note that we make prefix area quite large in order to increase chances of
239 * catching buffer overflow. */
240#define DEFAULT_PREFIX_SIZE (malloc_alignment * 4)
241
242/* Defines default size of allocation suffix.
243 * Note that we make suffix area quite large in order to increase chances of
244 * catching buffer overflow. */
245#define DEFAULT_SUFFIX_SIZE (malloc_alignment * 4)
246
247/* Debug tracing has been enabled by the emulator. */
248#define DEBUG_TRACING_ENABLED 0x00000001
249/* Error tracing has been enabled by the emulator. */
250#define ERROR_TRACING_ENABLED 0x00000002
251/* Info tracing has been enabled by the emulator. */
252#define INFO_TRACING_ENABLED 0x00000004
253/* All tracing flags combined. */
254#define ALL_TRACING_ENABLED (DEBUG_TRACING_ENABLED | \
255 ERROR_TRACING_ENABLED | \
256 INFO_TRACING_ENABLED)
257
258/* Prints a string to the emulator's stdout.
Elliott Hughes1e980b62013-01-17 18:36:06 -0800259 * In early stages of system loading, logging messages to logcat
260 * is not available, because ADB API has not been
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800261 * hooked up yet. So, in order to see such messages we need to print them to
262 * the emulator's stdout.
263 * Parameters passed to this macro are the same as parameters for printf
264 * routine.
265 */
266#define TR(...) \
267 do { \
268 char tr_str[4096]; \
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700269 snprintf(tr_str, sizeof(tr_str), __VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800270 tr_str[sizeof(tr_str) - 1] = '\0'; \
271 notify_qemu_string(&tr_str[0]); \
272 } while (0)
273
274// =============================================================================
275// Logging macros. Note that we simultaneously log messages to ADB and emulator.
276// =============================================================================
277
278/*
279 * Helper macros for checking if particular trace level is enabled.
280 */
281#define debug_LOG_ENABLED ((tracing_flags & DEBUG_TRACING_ENABLED) != 0)
282#define error_LOG_ENABLED ((tracing_flags & ERROR_TRACING_ENABLED) != 0)
283#define info_LOG_ENABLED ((tracing_flags & INFO_TRACING_ENABLED) != 0)
284#define tracing_enabled(type) (type##_LOG_ENABLED)
285
286/*
287 * Logging helper macros.
288 */
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700289#define qemu_debug_log(format, ...) \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800290 do { \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800291 __libc_format_log(ANDROID_LOG_DEBUG, "memcheck", (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800292 if (tracing_flags & DEBUG_TRACING_ENABLED) { \
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700293 qemu_log(ANDROID_LOG_DEBUG, (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800294 } \
295 } while (0)
296
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700297#define qemu_error_log(format, ...) \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800298 do { \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800299 __libc_format_log(ANDROID_LOG_ERROR, "memcheck", (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800300 if (tracing_flags & ERROR_TRACING_ENABLED) { \
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700301 qemu_log(ANDROID_LOG_ERROR, (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800302 } \
303 } while (0)
304
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700305#define qemu_info_log(format, ...) \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800306 do { \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800307 __libc_format_log(ANDROID_LOG_INFO, "memcheck", (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800308 if (tracing_flags & INFO_TRACING_ENABLED) { \
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700309 qemu_log(ANDROID_LOG_INFO, (format), ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800310 } \
311 } while (0)
312
313/* Logs message dumping MallocDesc instance at the end of the message.
314 * Param:
315 * type - Message type: debug, error, or info
316 * desc - MallocDesc instance to dump.
Elliott Hughes1e980b62013-01-17 18:36:06 -0800317 * fmt + rest - Formats message preceding dumped descriptor.
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800318*/
Elliott Hughes1e980b62013-01-17 18:36:06 -0800319#define log_mdesc(type, desc, fmt, ...) \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800320 do { \
321 if (tracing_enabled(type)) { \
322 char log_str[4096]; \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800323 __libc_format_buffer(log_str, sizeof(log_str), fmt, ##__VA_ARGS__); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800324 log_str[sizeof(log_str) - 1] = '\0'; \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800325 size_t str_len = strlen(log_str); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800326 dump_malloc_descriptor(log_str + str_len, \
327 sizeof(log_str) - str_len, \
328 (desc)); \
Elliott Hughes1e980b62013-01-17 18:36:06 -0800329 type##_log("%s", log_str); \
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800330 } \
331 } while (0)
332
333// =============================================================================
334// Static data
335// =============================================================================
336
337/* Emulator's magic page address.
338 * This page (mapped on /dev/qemu_trace device) is used to fire up events
339 * in the emulator. */
340static volatile void* qtrace = NULL;
341
342/* Cached PID of the process in context of which this libc instance
343 * has been initialized. */
344static uint32_t malloc_pid = 0;
345
Christopher Ferris72bbd422014-05-08 11:14:03 -0700346/* Memory allocation alignment that is used in the malloc implementation.
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800347 * This variable is updated by memcheck_initialize routine. */
348static uint32_t malloc_alignment = 8;
349
350/* Tracing flags. These flags control which types of logging messages are
351 * enabled by the emulator. See XXX_TRACING_ENABLED for the values of flags
352 * stored in this variable. This variable is updated by memcheck_initialize
353 * routine. */
354static uint32_t tracing_flags = 0;
355
356// =============================================================================
357// Static routines
358// =============================================================================
359
360/* Gets pointer, returned to malloc caller for the given allocation decriptor.
361 * Param:
362 * desc - Allocation descriptor.
363 * Return:
364 * Pointer to the allocated memory returned to the malloc caller.
365 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700366static inline void* mallocdesc_user_ptr(const MallocDesc* desc) {
367 return static_cast<char*>(desc->ptr) + desc->prefix_size;
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -0800368}
369
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800370/* Gets size of memory block actually allocated from the heap for the given
371 * allocation decriptor.
372 * Param:
373 * desc - Allocation descriptor.
374 * Return:
375 * Size of memory block actually allocated from the heap.
376 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700377static inline uint32_t mallocdesc_alloc_size(const MallocDesc* desc) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800378 return desc->prefix_size + desc->requested_bytes + desc->suffix_size;
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -0800379}
380
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800381/* Gets pointer to the end of the allocated block for the given descriptor.
382 * Param:
383 * desc - Descriptor for the memory block, allocated in malloc handler.
384 * Return:
385 * Pointer to the end of (one byte past) the allocated block.
386 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700387static inline void* mallocdesc_alloc_end(const MallocDesc* desc) {
388 return static_cast<char*>(desc->ptr) + mallocdesc_alloc_size(desc);
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -0800389}
390
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800391/* Fires up an event in the emulator.
392 * Param:
393 * code - Event code (one of the TRACE_DEV_XXX).
394 * val - Event's value parameter.
395 */
Elliott Hughesef0696d2013-10-08 16:16:01 -0700396static inline void notify_qemu(uint32_t code, uintptr_t val) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800397 if (NULL != qtrace) {
Elliott Hughesef0696d2013-10-08 16:16:01 -0700398 *(volatile uintptr_t*)((uintptr_t)qtrace + ((code - 1024) << 2)) = val;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800399 }
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -0800400}
401
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800402/* Prints a zero-terminated string to the emulator's stdout (fires up
403 * TRACE_DEV_REG_PRINT_USER_STR event in the emulator).
404 * Param:
405 * str - Zero-terminated string to print.
406 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700407static void notify_qemu_string(const char* str) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800408 if (str != NULL) {
Elliott Hughesef0696d2013-10-08 16:16:01 -0700409 notify_qemu(TRACE_DEV_REG_PRINT_USER_STR, reinterpret_cast<uintptr_t>(str));
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800410 }
411}
412
413/* Fires up TRACE_DEV_REG_LIBC_INIT event in the emulator.
414 * Param:
415 * pid - ID of the process that initialized libc.
416 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700417static void notify_qemu_libc_initialized(uint32_t pid) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800418 notify_qemu(TRACE_DEV_REG_LIBC_INIT, pid);
419}
420
421/* Fires up TRACE_DEV_REG_MALLOC event in the emulator.
422 * Param:
423 * desc - Pointer to MallocDesc instance containing allocated block
424 * information.
425 * Return:
426 * Zero on success, or -1 on failure. Note that on failure libc_pid field of
427 * the desc parameter passed to this routine has been zeroed out by the
428 * emulator.
429 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700430static inline int notify_qemu_malloc(volatile MallocDesc* desc) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800431 desc->libc_pid = malloc_pid;
432 desc->allocator_pid = getpid();
433 desc->av_count = 0;
Elliott Hughesef0696d2013-10-08 16:16:01 -0700434 notify_qemu(TRACE_DEV_REG_MALLOC, reinterpret_cast<uintptr_t>(desc));
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800435
436 /* Emulator reports failure by zeroing libc_pid field of the
437 * descriptor. */
438 return desc->libc_pid != 0 ? 0 : -1;
439}
440
441/* Fires up TRACE_DEV_REG_FREE_PTR event in the emulator.
442 * Param:
443 * ptr - Pointer to the memory block that's being freed.
444 * Return:
445 * Zero on success, or -1 on failure.
446 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700447static inline int notify_qemu_free(void* ptr_to_free) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800448 volatile MallocFree free_desc;
449
450 free_desc.ptr = ptr_to_free;
451 free_desc.libc_pid = malloc_pid;
452 free_desc.free_pid = getpid();
Elliott Hughesef0696d2013-10-08 16:16:01 -0700453 notify_qemu(TRACE_DEV_REG_FREE_PTR, reinterpret_cast<uintptr_t>(&free_desc));
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800454
455 /* Emulator reports failure by zeroing libc_pid field of the
456 * descriptor. */
457 return free_desc.libc_pid != 0 ? 0 : -1;
458}
459
460/* Fires up TRACE_DEV_REG_QUERY_MALLOC event in the emulator.
461 * Param:
462 * ptr - Pointer to request allocation information for.
463 * desc - Pointer to MallocDesc instance that will receive allocation
464 * information.
465 * routine - Code of the allocation routine, in context of which query is made:
466 * 1 - free
467 * 2 - realloc
468 * Return:
469 * Zero on success, or -1 on failure.
470 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700471static inline int query_qemu_malloc_info(const void* ptr, MallocDesc* desc, uint32_t routine) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800472 volatile MallocDescQuery query;
473
474 query.ptr = ptr;
475 query.libc_pid = malloc_pid;
476 query.query_pid = getpid();
477 query.routine = routine;
478 query.desc = desc;
Elliott Hughesef0696d2013-10-08 16:16:01 -0700479 notify_qemu(TRACE_DEV_REG_QUERY_MALLOC, reinterpret_cast<uintptr_t>(&query));
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800480
481 /* Emulator reports failure by zeroing libc_pid field of the
482 * descriptor. */
483 return query.libc_pid != 0 ? 0 : -1;
484}
485
486/* Logs a message to emulator's stdout.
487 * Param:
488 * prio - Message priority (debug, info, or error)
489 * fmt + rest - Message format and parameters.
490 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700491static void qemu_log(int prio, const char* fmt, ...) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800492 va_list ap;
493 char buf[4096];
494 const char* prefix;
495
496 /* Choose message prefix depending on the priority value. */
497 switch (prio) {
498 case ANDROID_LOG_ERROR:
499 if (!tracing_enabled(error)) {
500 return;
501 }
502 prefix = "E";
503 break;
504 case ANDROID_LOG_INFO:
505 if (!tracing_enabled(info)) {
506 return;
507 }
508 prefix = "I";
509 break;
510 case ANDROID_LOG_DEBUG:
511 default:
512 if (!tracing_enabled(debug)) {
513 return;
514 }
515 prefix = "D";
516 break;
517 }
518
519 va_start(ap, fmt);
520 vsnprintf(buf, sizeof(buf), fmt, ap);
521 va_end(ap);
522 buf[sizeof(buf) - 1] = '\0';
523
524 TR("%s/memcheck: %s\n", prefix, buf);
525}
526
527/* Dumps content of memory allocation descriptor to a string.
528 * Param:
529 * str - String to dump descriptor to.
530 * str_buf_size - Size of string's buffer.
531 * desc - Descriptor to dump.
532 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700533static void dump_malloc_descriptor(char* str, size_t str_buf_size, const MallocDesc* desc) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800534 if (str_buf_size) {
535 snprintf(str, str_buf_size,
Elliott Hughesef0696d2013-10-08 16:16:01 -0700536 "MDesc: %p: %p <-> %p [%u + %u + %u] by pid=%03u in libc_pid=%03u",
537 mallocdesc_user_ptr(desc), desc->ptr,
538 mallocdesc_alloc_end(desc), desc->prefix_size,
539 desc->requested_bytes, desc->suffix_size, desc->allocator_pid,
540 desc->libc_pid);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800541 str[str_buf_size - 1] = '\0';
542 }
543}
544
545#if TEST_ACCESS_VIOLATIONS
546/* Causes an access violation on allocation descriptor, and verifies that
547 * violation has been detected by memory checker in the emulator.
548 */
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700549static void test_access_violation(const MallocDesc* desc) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800550 MallocDesc desc_chk;
551 char ch;
552 volatile char* prefix = (volatile char*)desc->ptr;
553 volatile char* suffix = (volatile char*)mallocdesc_user_ptr(desc) +
554 desc->requested_bytes;
555 /* We're causing AV by reading from the prefix and suffix areas of the
556 * allocated block. This should produce two access violations, so when we
557 * get allocation descriptor from QEMU, av_counter should be bigger than
558 * av_counter of the original descriptor by 2. */
559 ch = *prefix;
560 ch = *suffix;
561 if (!query_qemu_malloc_info(mallocdesc_user_ptr(desc), &desc_chk, 2) &&
562 desc_chk.av_count != (desc->av_count + 2)) {
563 log_mdesc(error, &desc_chk,
564 "<libc_pid=%03u, pid=%03u>: malloc: Access violation test failed:\n"
565 "Expected violations count %u is not equal to the actually reported %u",
566 malloc_pid, getpid(), desc->av_count + 2,
567 desc_chk.av_count);
568 }
569}
570#endif // TEST_ACCESS_VIOLATIONS
571
572// =============================================================================
573// API routines
574// =============================================================================
575
Christopher Ferrisa4037802014-06-09 19:14:11 -0700576extern "C" void* qemu_instrumented_calloc(size_t, size_t);
577extern "C" void qemu_instrumented_free(void*);
578extern "C" struct mallinfo qemu_instrumented_mallinfo();
579extern "C" void* qemu_instrumented_malloc(size_t);
580extern "C" size_t qemu_instrumented_malloc_usable_size(const void*);
581extern "C" void* qemu_instrumented_memalign(size_t, size_t);
582extern "C" int qemu_instrumented_posix_memalign(void**, size_t, size_t);
583extern "C" void* qemu_instrumented_pvalloc(size_t);
584extern "C" void* qemu_instrumented_realloc(void*, size_t);
585extern "C" void* qemu_instrumented_valloc(size_t);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800586
587/* Initializes malloc debugging instrumentation for the emulator.
588 * This routine is called from malloc_init_impl routine implemented in
589 * bionic/libc/bionic/malloc_debug_common.c when malloc debugging gets
590 * initialized for a process. The way malloc debugging implementation is
591 * done, it is guaranteed that this routine will be called just once per
592 * process.
593 * Return:
594 * 0 on success, or -1 on failure.
595*/
Elliott Hughes8e52e8f2014-06-04 12:07:11 -0700596extern "C" bool malloc_debug_initialize(HashTable*) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800597 /* We will be using emulator's magic page to report memory allocation
598 * activities. In essence, what magic page does, it translates writes to
599 * the memory mapped spaces into writes to an I/O port that emulator
600 * "listens to" on the other end. Note that until we open and map that
601 * device, logging to emulator's stdout will not be available. */
602 int fd = open("/dev/qemu_trace", O_RDWR);
603 if (fd < 0) {
604 error_log("Unable to open /dev/qemu_trace");
Elliott Hughes8e52e8f2014-06-04 12:07:11 -0700605 return false;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800606 } else {
Elliott Hughes0d787c12013-04-04 13:46:46 -0700607 qtrace = mmap(NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800608 close(fd);
609
610 if (qtrace == MAP_FAILED) {
611 qtrace = NULL;
612 error_log("Unable to mmap /dev/qemu_trace");
Elliott Hughes8e52e8f2014-06-04 12:07:11 -0700613 return false;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800614 }
615 }
616
617 /* Cache pid of the process this library has been initialized for. */
618 malloc_pid = getpid();
Elliott Hughes8e52e8f2014-06-04 12:07:11 -0700619 return true;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800620}
621
622/* Completes malloc debugging instrumentation for the emulator.
623 * Note that this routine is called after successful return from
624 * malloc_debug_initialize, which means that connection to the emulator via
625 * "magic page" has been established.
626 * Param:
627 * alignment - Alignment requirement set for memiry allocations.
628 * memcheck_param - Emulator's -memcheck option parameters. This string
629 * contains abbreviation for guest events that are enabled for tracing.
630 * Return:
631 * 0 on success, or -1 on failure.
632*/
Christopher Ferris885f3b92013-05-21 17:48:01 -0700633extern "C" int memcheck_initialize(int alignment, const char* memcheck_param) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800634 malloc_alignment = alignment;
635
636 /* Parse -memcheck parameter for the guest tracing flags. */
637 while (*memcheck_param != '\0') {
638 switch (*memcheck_param) {
639 case 'a':
640 // Enable all messages from the guest.
641 tracing_flags |= ALL_TRACING_ENABLED;
642 break;
643 case 'd':
644 // Enable debug messages from the guest.
645 tracing_flags |= DEBUG_TRACING_ENABLED;
646 break;
647 case 'e':
648 // Enable error messages from the guest.
649 tracing_flags |= ERROR_TRACING_ENABLED;
650 break;
651 case 'i':
652 // Enable info messages from the guest.
653 tracing_flags |= INFO_TRACING_ENABLED;
654 break;
655 default:
656 break;
657 }
658 if (tracing_flags == ALL_TRACING_ENABLED) {
659 break;
660 }
661 memcheck_param++;
662 }
663
664 notify_qemu_libc_initialized(malloc_pid);
665
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700666 qemu_debug_log("Instrumented for pid=%03u: malloc=%p, free=%p, calloc=%p, realloc=%p, memalign=%p",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800667 malloc_pid, qemu_instrumented_malloc, qemu_instrumented_free,
668 qemu_instrumented_calloc, qemu_instrumented_realloc,
669 qemu_instrumented_memalign);
670
671 return 0;
672}
673
674/* This routine serves as entry point for 'malloc'.
675 * Primary responsibility of this routine is to allocate requested number of
676 * bytes (plus prefix, and suffix guards), and report allocation to the
677 * emulator.
678 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700679extern "C" void* qemu_instrumented_malloc(size_t bytes) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800680 MallocDesc desc;
681
Christopher Ferris72bbd422014-05-08 11:14:03 -0700682 /* Initialize block descriptor and allocate memory. Note that malloc
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800683 * returns a valid pointer on zero allocation. Lets mimic this behavior. */
684 desc.prefix_size = DEFAULT_PREFIX_SIZE;
685 desc.requested_bytes = bytes;
686 desc.suffix_size = DEFAULT_SUFFIX_SIZE;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700687 size_t size = mallocdesc_alloc_size(&desc);
688 if (size < bytes) { // Overflow
689 qemu_error_log("<libc_pid=%03u, pid=%03u> malloc: malloc(%zu) overflow caused failure.",
690 malloc_pid, getpid(), bytes);
691 errno = ENOMEM;
692 return NULL;
693 }
694 desc.ptr = Malloc(malloc)(size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800695 if (desc.ptr == NULL) {
Christopher Ferris580b6e02014-06-12 18:20:44 -0700696 qemu_error_log("<libc_pid=%03u, pid=%03u> malloc(%zu): malloc(%zu) failed.",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700697 malloc_pid, getpid(), bytes, size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800698 return NULL;
699 }
700
701 // Fire up event in the emulator.
702 if (notify_qemu_malloc(&desc)) {
703 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: malloc: notify_malloc failed for ",
704 malloc_pid, getpid());
Christopher Ferris72bbd422014-05-08 11:14:03 -0700705 Malloc(free)(desc.ptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700706 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800707 return NULL;
708 } else {
709#if TEST_ACCESS_VIOLATIONS
710 test_access_violation(&desc);
711#endif // TEST_ACCESS_VIOLATIONS
Christopher Ferrisa4037802014-06-09 19:14:11 -0700712 log_mdesc(info, &desc, "+++ <libc_pid=%03u, pid=%03u> malloc(%zu) -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800713 malloc_pid, getpid(), bytes);
714 return mallocdesc_user_ptr(&desc);
715 }
716}
717
718/* This routine serves as entry point for 'malloc'.
719 * Primary responsibility of this routine is to free requested memory, and
720 * report free block to the emulator.
721 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700722extern "C" void qemu_instrumented_free(void* mem) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800723 MallocDesc desc;
724
725 if (mem == NULL) {
726 // Just let go NULL free
Christopher Ferris72bbd422014-05-08 11:14:03 -0700727 Malloc(free)(mem);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800728 return;
729 }
730
731 // Query emulator for the freeing block information.
732 if (query_qemu_malloc_info(mem, &desc, 1)) {
733 error_log("<libc_pid=%03u, pid=%03u>: free(%p) query_info failed.",
734 malloc_pid, getpid(), mem);
735 return;
736 }
737
738#if TEST_ACCESS_VIOLATIONS
739 test_access_violation(&desc);
740#endif // TEST_ACCESS_VIOLATIONS
741
742 /* Make sure that pointer that's being freed matches what we expect
743 * for this memory block. Note that this violation should be already
744 * caught in the emulator. */
745 if (mem != mallocdesc_user_ptr(&desc)) {
746 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) is invalid for ",
747 malloc_pid, getpid(), mem);
748 return;
749 }
750
751 // Fire up event in the emulator and free block that was actually allocated.
752 if (notify_qemu_free(mem)) {
753 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) notify_free failed for ",
754 malloc_pid, getpid(), mem);
755 } else {
756 log_mdesc(info, &desc, "--- <libc_pid=%03u, pid=%03u> free(%p) -> ",
757 malloc_pid, getpid(), mem);
Christopher Ferris72bbd422014-05-08 11:14:03 -0700758 Malloc(free)(desc.ptr);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800759 }
760}
761
762/* This routine serves as entry point for 'calloc'.
763 * This routine behaves similarly to qemu_instrumented_malloc.
764 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700765extern "C" void* qemu_instrumented_calloc(size_t n_elements, size_t elem_size) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800766 if (n_elements == 0 || elem_size == 0) {
767 // Just let go zero bytes allocation.
Iliyan Malcheve1dd3c22012-05-29 14:22:42 -0700768 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: Zero calloc redir to malloc",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700769 malloc_pid, getpid());
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800770 return qemu_instrumented_malloc(0);
771 }
772
Elliott Hughes8e52e8f2014-06-04 12:07:11 -0700773 // Fail on overflow - just to be safe even though this code runs only
774 // within the debugging C library, not the production one.
775 if (n_elements && SIZE_MAX / n_elements < elem_size) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700776 qemu_error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu, %zu) overflow caused failure.",
777 malloc_pid, getpid(), n_elements, elem_size);
778 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800779 return NULL;
780 }
781
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700782 MallocDesc desc;
783
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800784 /* Calculating prefix size. The trick here is to make sure that
785 * first element (returned to the caller) is properly aligned. */
786 if (DEFAULT_PREFIX_SIZE >= elem_size) {
787 /* If default alignment is bigger than element size, we will
788 * set our prefix size to the default alignment size. */
789 desc.prefix_size = DEFAULT_PREFIX_SIZE;
790 /* For the suffix we will use whatever bytes remain from the prefix
791 * allocation size, aligned to the size of an element, plus the usual
792 * default suffix size. */
793 desc.suffix_size = (DEFAULT_PREFIX_SIZE % elem_size) +
794 DEFAULT_SUFFIX_SIZE;
795 } else {
796 /* Make sure that prefix, and suffix sizes is at least elem_size,
797 * and first element returned to the caller is properly aligned. */
798 desc.prefix_size = elem_size + DEFAULT_PREFIX_SIZE - 1;
799 desc.prefix_size &= ~(malloc_alignment - 1);
800 desc.suffix_size = DEFAULT_SUFFIX_SIZE;
801 }
802 desc.requested_bytes = n_elements * elem_size;
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700803 size_t total_size = desc.requested_bytes + desc.prefix_size + desc.suffix_size;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700804 if (total_size < desc.requested_bytes) { // Overflow
805 qemu_error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu, %zu) overflow caused failure.",
806 malloc_pid, getpid(), n_elements, elem_size);
807 errno = ENOMEM;
808 return NULL;
809 }
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700810 size_t total_elements = total_size / elem_size;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800811 total_size %= elem_size;
812 if (total_size != 0) {
813 // Add extra to the suffix area.
814 total_elements++;
815 desc.suffix_size += (elem_size - total_size);
816 }
Christopher Ferris72bbd422014-05-08 11:14:03 -0700817 desc.ptr = Malloc(calloc)(total_elements, elem_size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800818 if (desc.ptr == NULL) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700819 error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu(%zu), %zu) (prx=%u, sfx=%u) failed.",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800820 malloc_pid, getpid(), n_elements, total_elements, elem_size,
821 desc.prefix_size, desc.suffix_size);
822 return NULL;
823 }
824
825 if (notify_qemu_malloc(&desc)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700826 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: calloc(%zu(%zu), %zu): notify_malloc failed for ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800827 malloc_pid, getpid(), n_elements, total_elements, elem_size);
Christopher Ferris72bbd422014-05-08 11:14:03 -0700828 Malloc(free)(desc.ptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700829 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800830 return NULL;
831 } else {
832#if TEST_ACCESS_VIOLATIONS
833 test_access_violation(&desc);
834#endif // TEST_ACCESS_VIOLATIONS
Christopher Ferrisa4037802014-06-09 19:14:11 -0700835 log_mdesc(info, &desc, "### <libc_pid=%03u, pid=%03u> calloc(%zu(%zu), %zu) -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800836 malloc_pid, getpid(), n_elements, total_elements, elem_size);
837 return mallocdesc_user_ptr(&desc);
838 }
839}
840
841/* This routine serves as entry point for 'realloc'.
842 * This routine behaves similarly to qemu_instrumented_free +
843 * qemu_instrumented_malloc. Note that this modifies behavior of "shrinking" an
844 * allocation, but overall it doesn't seem to matter, as caller of realloc
845 * should not expect that pointer returned after shrinking will remain the same.
846 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700847extern "C" void* qemu_instrumented_realloc(void* mem, size_t bytes) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800848 if (mem == NULL) {
849 // Nothing to realloc. just do regular malloc.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700850 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) redir to malloc",
851 malloc_pid, getpid(), mem, bytes);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800852 return qemu_instrumented_malloc(bytes);
853 }
854
855 if (bytes == 0) {
856 // This is a "free" condition.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700857 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) redir to free and malloc",
858 malloc_pid, getpid(), mem, bytes);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800859 qemu_instrumented_free(mem);
860
Christopher Ferris72bbd422014-05-08 11:14:03 -0700861 // This is what realloc does for a "free" realloc.
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800862 return NULL;
863 }
864
865 // Query emulator for the reallocating block information.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700866 MallocDesc cur_desc;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800867 if (query_qemu_malloc_info(mem, &cur_desc, 2)) {
868 // Note that this violation should be already caught in the emulator.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700869 error_log("<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) query_info failed.",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800870 malloc_pid, getpid(), mem, bytes);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700871 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800872 return NULL;
873 }
874
875#if TEST_ACCESS_VIOLATIONS
876 test_access_violation(&cur_desc);
877#endif // TEST_ACCESS_VIOLATIONS
878
879 /* Make sure that reallocating pointer value is what we would expect
880 * for this memory block. Note that this violation should be already caught
881 * in the emulator.*/
882 if (mem != mallocdesc_user_ptr(&cur_desc)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700883 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) is invalid for ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800884 malloc_pid, getpid(), mem, bytes);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700885 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800886 return NULL;
887 }
888
889 /* TODO: We're a bit inefficient here, always allocating new block from
890 * the heap. If this realloc shrinks current buffer, we can just do the
891 * shrinking "in place", adjusting suffix_size in the allocation descriptor
892 * for this block that is stored in the emulator. */
893
894 // Initialize descriptor for the new block.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700895 MallocDesc new_desc;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800896 new_desc.prefix_size = DEFAULT_PREFIX_SIZE;
897 new_desc.requested_bytes = bytes;
898 new_desc.suffix_size = DEFAULT_SUFFIX_SIZE;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700899 size_t new_size = mallocdesc_alloc_size(&new_desc);
900 if (new_size < bytes) { // Overflow
Christopher Ferris580b6e02014-06-12 18:20:44 -0700901 qemu_error_log("<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed due to overflow",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700902 malloc_pid, getpid(), mem, bytes, new_size);
903 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800904 return NULL;
905 }
Christopher Ferrisa4037802014-06-09 19:14:11 -0700906 new_desc.ptr = Malloc(malloc)(new_size);
907 if (new_desc.ptr == NULL) {
Christopher Ferris580b6e02014-06-12 18:20:44 -0700908 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed on ",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700909 malloc_pid, getpid(), mem, bytes, new_size);
910 return NULL;
911 }
912 void* new_mem = mallocdesc_user_ptr(&new_desc);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800913
914 // Copy user data from old block to the new one.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700915 size_t to_copy = bytes < cur_desc.requested_bytes ? bytes : cur_desc.requested_bytes;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800916 if (to_copy != 0) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700917 memcpy(new_mem, mallocdesc_user_ptr(&cur_desc), to_copy);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800918 }
919
920 // Register new block with emulator.
Elliott Hughesc4d1fec2012-08-28 14:15:04 -0700921 if (notify_qemu_malloc(&new_desc)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700922 log_mdesc(error, &new_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) notify_malloc failed -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800923 malloc_pid, getpid(), mem, bytes);
924 log_mdesc(error, &cur_desc, " <- ");
Christopher Ferris72bbd422014-05-08 11:14:03 -0700925 Malloc(free)(new_desc.ptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700926 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800927 return NULL;
928 }
929
930#if TEST_ACCESS_VIOLATIONS
931 test_access_violation(&new_desc);
932#endif // TEST_ACCESS_VIOLATIONS
933
934 // Free old block.
935 if (notify_qemu_free(mem)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700936 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): notify_free failed for ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800937 malloc_pid, getpid(), mem, bytes);
938 /* Since we registered new decriptor with the emulator, we need
939 * to unregister it before freeing newly allocated block. */
940 notify_qemu_free(mallocdesc_user_ptr(&new_desc));
Christopher Ferris72bbd422014-05-08 11:14:03 -0700941 Malloc(free)(new_desc.ptr);
Christopher Ferrisa4037802014-06-09 19:14:11 -0700942 errno = ENOMEM;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800943 return NULL;
944 }
Christopher Ferris72bbd422014-05-08 11:14:03 -0700945 Malloc(free)(cur_desc.ptr);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800946
Christopher Ferrisa4037802014-06-09 19:14:11 -0700947 log_mdesc(info, &new_desc, "=== <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800948 malloc_pid, getpid(), mem, bytes);
949 log_mdesc(info, &cur_desc, " <- ");
950
Christopher Ferrisa4037802014-06-09 19:14:11 -0700951 return new_mem;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800952}
953
954/* This routine serves as entry point for 'memalign'.
955 * This routine behaves similarly to qemu_instrumented_malloc.
956 */
Christopher Ferris885f3b92013-05-21 17:48:01 -0700957extern "C" void* qemu_instrumented_memalign(size_t alignment, size_t bytes) {
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800958 MallocDesc desc;
959
960 if (bytes == 0) {
961 // Just let go zero bytes allocation.
Christopher Ferrisa4037802014-06-09 19:14:11 -0700962 qemu_info_log("::: <libc_pid=%03u, pid=%03u>: memalign(%zx, %zu) redir to malloc",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800963 malloc_pid, getpid(), alignment, bytes);
964 return qemu_instrumented_malloc(0);
965 }
966
Christopher Ferrisa4037802014-06-09 19:14:11 -0700967 // Prefix size for aligned allocation must be equal to the alignment used
968 // for allocation in order to ensure proper alignment of the returned
969 // pointer. in case that alignment requirement is greater than prefix
970 // size.
971 if (alignment < DEFAULT_PREFIX_SIZE) {
972 alignment = DEFAULT_PREFIX_SIZE;
973 } else if (alignment & (alignment - 1)) {
974 alignment = 1L << (31 - __builtin_clz(alignment));
975 }
976 desc.prefix_size = alignment;
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800977 desc.requested_bytes = bytes;
978 desc.suffix_size = DEFAULT_SUFFIX_SIZE;
Christopher Ferrisa4037802014-06-09 19:14:11 -0700979 size_t size = mallocdesc_alloc_size(&desc);
980 if (size < bytes) { // Overflow
Christopher Ferris580b6e02014-06-12 18:20:44 -0700981 qemu_error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed due to overflow.",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700982 malloc_pid, getpid(), alignment, bytes, size);
983
984 return NULL;
985 }
986 desc.ptr = Malloc(memalign)(desc.prefix_size, size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800987 if (desc.ptr == NULL) {
Christopher Ferris580b6e02014-06-12 18:20:44 -0700988 error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed.",
Christopher Ferrisa4037802014-06-09 19:14:11 -0700989 malloc_pid, getpid(), alignment, bytes, size);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800990 return NULL;
991 }
992 if (notify_qemu_malloc(&desc)) {
Christopher Ferrisa4037802014-06-09 19:14:11 -0700993 log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: memalign(%zx, %zu): notify_malloc failed for ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800994 malloc_pid, getpid(), alignment, bytes);
Christopher Ferris72bbd422014-05-08 11:14:03 -0700995 Malloc(free)(desc.ptr);
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -0800996 return NULL;
997 }
998
999#if TEST_ACCESS_VIOLATIONS
1000 test_access_violation(&desc);
1001#endif // TEST_ACCESS_VIOLATIONS
1002
Christopher Ferrisa4037802014-06-09 19:14:11 -07001003 log_mdesc(info, &desc, "@@@ <libc_pid=%03u, pid=%03u> memalign(%zx, %zu) -> ",
Vladimir Chtchetkine75fba682010-02-12 08:59:58 -08001004 malloc_pid, getpid(), alignment, bytes);
1005 return mallocdesc_user_ptr(&desc);
Vladimir Chtchetkineb74ceb22009-11-17 14:13:38 -08001006}
Christopher Ferris885f3b92013-05-21 17:48:01 -07001007
1008extern "C" size_t qemu_instrumented_malloc_usable_size(const void* mem) {
1009 MallocDesc cur_desc;
1010
1011 // Query emulator for the reallocating block information.
1012 if (query_qemu_malloc_info(mem, &cur_desc, 2)) {
1013 // Note that this violation should be already caught in the emulator.
1014 error_log("<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) query_info failed.",
1015 malloc_pid, getpid(), mem);
1016 return 0;
1017 }
1018
1019 /* Make sure that reallocating pointer value is what we would expect
1020 * for this memory block. Note that this violation should be already caught
1021 * in the emulator.*/
1022 if (mem != mallocdesc_user_ptr(&cur_desc)) {
1023 log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) is invalid for ",
1024 malloc_pid, getpid(), mem);
1025 return 0;
1026 }
1027
1028 /* during instrumentation, we can't really report anything more than requested_bytes */
1029 return cur_desc.requested_bytes;
1030}
Christopher Ferrisa4037802014-06-09 19:14:11 -07001031
1032extern "C" struct mallinfo qemu_instrumented_mallinfo() {
1033 return Malloc(mallinfo)();
1034}
1035
1036extern "C" int qemu_instrumented_posix_memalign(void** memptr, size_t alignment, size_t size) {
1037 if ((alignment & (alignment - 1)) != 0) {
1038 qemu_error_log("<libc_pid=%03u, pid=%03u> posix_memalign(%p, %zu, %zu): invalid alignment.",
1039 malloc_pid, getpid(), memptr, alignment, size);
1040 return EINVAL;
1041 }
1042 int saved_errno = errno;
1043 *memptr = qemu_instrumented_memalign(alignment, size);
1044 errno = saved_errno;
1045 return (*memptr != NULL) ? 0 : ENOMEM;
1046}
1047
1048extern "C" void* qemu_instrumented_pvalloc(size_t bytes) {
1049 size_t pagesize = sysconf(_SC_PAGESIZE);
1050 size_t size = (bytes + pagesize - 1) & ~(pagesize - 1);
1051 if (size < bytes) { // Overflow
1052 qemu_error_log("<libc_pid=%03u, pid=%03u> pvalloc(%zu): overflow (%zu).",
1053 malloc_pid, getpid(), bytes, size);
1054 return NULL;
1055 }
1056 return qemu_instrumented_memalign(pagesize, size);
1057}
1058
1059extern "C" void* qemu_instrumented_valloc(size_t size) {
1060 return qemu_instrumented_memalign(sysconf(_SC_PAGESIZE), size);
1061}