1b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine/* 2b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * Copyright (C) 2009 The Android Open Source Project 3b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * All rights reserved. 4b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * 5b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * Redistribution and use in source and binary forms, with or without 6b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * modification, are permitted provided that the following conditions 7b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * are met: 8b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * * Redistributions of source code must retain the above copyright 9b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * notice, this list of conditions and the following disclaimer. 10b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * * Redistributions in binary form must reproduce the above copyright 11b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * notice, this list of conditions and the following disclaimer in 12b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * the documentation and/or other materials provided with the 13b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * distribution. 14b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * 15b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * SUCH DAMAGE. 27b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine */ 28b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 29b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine/* 3075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Contains implementation of memory allocation routines instrumented for 31b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * usage in the emulator to detect memory allocation violations, such as 32b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine * memory leaks, buffer overruns, etc. 3375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Code, implemented here is intended to run in the emulated environment only, 3475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * and serves simply as hooks into memory allocation routines. Main job of this 3575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * code is to notify the emulator about memory being allocated/deallocated, 3675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * providing information about each allocation. The idea is that emulator will 3775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * keep list of currently allocated blocks, and, knowing boundaries of each 3875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * block it will be able to verify that ld/st access to these blocks don't step 3975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * over boundaries set for the user. To enforce that, each memory block 4075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * allocated by this code is guarded with "prefix" and "suffix" areas, so 4175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * every time emulator detects access to any of these guarding areas, it can be 4275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * considered as access violation. 43b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine */ 44b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 45b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#include <stdlib.h> 4675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#include <stddef.h> 4775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#include <stdio.h> 4875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#include <fcntl.h> 4975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#include <sys/mman.h> 5003eebcb6e8762e668a0d3af6bb303cccb88c5b81Christopher Ferris#include <sys/param.h> 51b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#include <pthread.h> 52b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#include <unistd.h> 5375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#include <errno.h> 5475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#include "malloc_debug_common.h" 5503eebcb6e8762e668a0d3af6bb303cccb88c5b81Christopher Ferris#include "private/bionic_macros.h" 5603eebcb6e8762e668a0d3af6bb303cccb88c5b81Christopher Ferris#include "private/libc_logging.h" 57b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 5875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* This file should be included into the build only when 5975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * MALLOC_QEMU_INSTRUMENT macro is defined. */ 60b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#ifndef MALLOC_QEMU_INSTRUMENT 61b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine#error MALLOC_QEMU_INSTRUMENT is not defined. 6275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#endif // !MALLOC_QEMU_INSTRUMENT 6375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 6475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Controls access violation test performed to make sure that we catch AVs 6575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * all the time they occur. See test_access_violation for more info. This macro 6675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * is used for internal testing purposes and should always be set to zero for 6775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * the production builds. */ 6875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define TEST_ACCESS_VIOLATIONS 0 6975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 7075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 7175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// Communication structures 7275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 7375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 7475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Describes memory block allocated from the heap. This structure is passed 7575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * along with TRACE_DEV_REG_MALLOC event. This descriptor is used to inform 7675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * the emulator about new memory block being allocated from the heap. The entire 7775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * structure is initialized by the guest system before event is fired up. It is 7875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * important to remember that same structure (an exact copy, except for 7975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * replacing pointers with target_ulong) is also declared in the emulator's 8075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * sources (file memcheck/memcheck_common.h). So, every time a change is made to 8175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * any of these two declaration, another one must be also updated accordingly. 8275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 83c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstruct MallocDesc { 8475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Pointer to the memory block actually allocated from the heap. Note that 8575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * this is not the pointer that is returned to the malloc's caller. Pointer 8675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * returned to the caller is calculated by adding value stored in this field 8775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * to the value stored in prefix_size field of this structure. 8875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 8975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine void* ptr; 9075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 9175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Number of bytes requested by the malloc's caller. */ 9275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t requested_bytes; 9375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 9475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Byte size of the prefix data. Actual pointer returned to the malloc's 9575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * caller is calculated by adding value stored in this field to the value 9675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * stored in in the ptr field of this structure. 9775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 9875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t prefix_size; 9975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 10075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Byte size of the suffix data. */ 10175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t suffix_size; 10275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 10375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Id of the process that initialized libc instance, in which allocation 10475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * has occurred. This field is used by the emulator to report errors in 10575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * the course of TRACE_DEV_REG_MALLOC event handling. In case of an error, 10675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * emulator sets this field to zero (invalid value for a process ID). 10775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 10875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t libc_pid; 10975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 11075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Id of the process in context of which allocation has occurred. 11175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Value in this field may differ from libc_pid value, if process that 11275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * is doing allocation has been forked from the process that initialized 11375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * libc instance. 11475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 11575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t allocator_pid; 11675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 11775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Number of access violations detected on this allocation. */ 11875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t av_count; 119c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes}; 12075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 12175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Describes memory block info queried from emulator. This structure is passed 12275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * along with TRACE_DEV_REG_QUERY_MALLOC event. When handling free and realloc 12375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * calls, it is required that we have information about memory blocks that were 12475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * actually allocated in previous calls to malloc, calloc, memalign, or realloc. 12575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Since we don't keep this information directly in the allocated block, but 12675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * rather we keep it in the emulator, we need to query emulator for that 12775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * information with TRACE_DEV_REG_QUERY_MALLOC query. The entire structure is 12875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * initialized by the guest system before event is fired up. It is important to 12975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * remember that same structure (an exact copy, except for replacing pointers 13075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * with target_ulong) is also declared in the emulator's sources (file 13175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * memcheck/memecheck_common.h). So, every time a change is made to any of these 13275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * two declaration, another one must be also updated accordingly. 13375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 134c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstruct MallocDescQuery { 13575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Pointer, for which information is queried. Note that this pointer doesn't 13675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * have to be exact pointer returned to malloc's caller, but can point 13775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * anywhere inside an allocated block, including guarding areas. Emulator 13875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * will respond with information about allocated block that contains this 13975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * pointer. 14075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 141885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris const void* ptr; 14275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 14375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Id of the process that initialized libc instance, in which this query 14475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * is called. This field is used by the emulator to report errors in 14575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * the course of TRACE_DEV_REG_QUERY_MALLOC event handling. In case of an 14675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * error, emulator sets this field to zero (invalid value for a process ID). 14775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 14875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t libc_pid; 14975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 15075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Process ID in context of which query is made. */ 15175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t query_pid; 15275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 15375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Code of the allocation routine, in context of which query has been made: 15475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * 1 - free 15575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * 2 - realloc 15675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 15775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t routine; 15875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 15975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Address of memory allocation descriptor for the queried pointer. 16075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Descriptor, addressed by this field is initialized by the emulator in 16175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * response to the query. 16275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 16375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine MallocDesc* desc; 164c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes}; 16575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 16675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Describes memory block that is being freed back to the heap. This structure 16775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * is passed along with TRACE_DEV_REG_FREE_PTR event. The entire structure is 16875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * initialized by the guest system before event is fired up. It is important to 16975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * remember that same structure (an exact copy, except for replacing pointers 17075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * with target_ulong) is also declared in the emulator's sources (file 17175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * memcheck/memecheck_common.h). So, every time a change is made to any of these 17275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * two declaration, another one must be also updated accordingly. 17375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 174c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstruct MallocFree { 17575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Pointer to be freed. */ 17675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine void* ptr; 17775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 17875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Id of the process that initialized libc instance, in which this free 17975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * is called. This field is used by the emulator to report errors in 18075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * the course of TRACE_DEV_REG_FREE_PTR event handling. In case of an 18175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * error, emulator sets this field to zero (invalid value for a process ID). 18275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 18375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t libc_pid; 18475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 18575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Process ID in context of which memory is being freed. */ 18675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine uint32_t free_pid; 187c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes}; 188b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 189b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine// ============================================================================= 19075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// Communication events 191b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine// ============================================================================= 192b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 19375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Notifies the emulator that libc has been initialized for a process. 19475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Event's value parameter is PID for the process in context of which libc has 19575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * been initialized. 19675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 19775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define TRACE_DEV_REG_LIBC_INIT 1536 19875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 19975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Notifies the emulator about new memory block been allocated. 20075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Event's value parameter points to MallocDesc instance that contains 20175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * allocated block information. Note that 'libc_pid' field of the descriptor 20275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * is used by emulator to report failure in handling this event. In case 20375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * of a failure emulator will zero that field before completing this event. 20475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 20575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define TRACE_DEV_REG_MALLOC 1537 20675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 20775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Notifies the emulator about memory block being freed. 20875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Event's value parameter points to MallocFree descriptor that contains 20975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * information about block that's being freed. Note that 'libc_pid' field 21075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * of the descriptor is used by emulator to report failure in handling this 21175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * event. In case of a failure emulator will zero that field before completing 21275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * this event. 21375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 21475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define TRACE_DEV_REG_FREE_PTR 1538 21575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 21675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Queries the emulator about allocated memory block information. 21775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Event's value parameter points to MallocDescQuery descriptor that contains 21875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * query parameters. Note that 'libc_pid' field of the descriptor is used by 21975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * emulator to report failure in handling this event. In case of a failure 22075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * emulator will zero that field before completing this event. 22175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 22275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define TRACE_DEV_REG_QUERY_MALLOC 1539 22375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 22475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Queries the emulator to print a string to its stdout. 22575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Event's value parameter points to a zero-terminated string to be printed. 22675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 22775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define TRACE_DEV_REG_PRINT_USER_STR 1540 22875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 22975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkinestatic void notify_qemu_string(const char* str); 23075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkinestatic void qemu_log(int prio, const char* fmt, ...); 23175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkinestatic void dump_malloc_descriptor(char* str, 23275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine size_t str_buf_size, 23375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine const MallocDesc* desc); 23475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 23575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 23675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// Macros 23775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 23875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 23975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Defines default size of allocation prefix. 24075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Note that we make prefix area quite large in order to increase chances of 24175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * catching buffer overflow. */ 24275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define DEFAULT_PREFIX_SIZE (malloc_alignment * 4) 24375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 24475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Defines default size of allocation suffix. 24575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Note that we make suffix area quite large in order to increase chances of 24675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * catching buffer overflow. */ 24775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define DEFAULT_SUFFIX_SIZE (malloc_alignment * 4) 24875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 24975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Debug tracing has been enabled by the emulator. */ 25075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define DEBUG_TRACING_ENABLED 0x00000001 25175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Error tracing has been enabled by the emulator. */ 25275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define ERROR_TRACING_ENABLED 0x00000002 25375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Info tracing has been enabled by the emulator. */ 25475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define INFO_TRACING_ENABLED 0x00000004 25575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* All tracing flags combined. */ 25675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define ALL_TRACING_ENABLED (DEBUG_TRACING_ENABLED | \ 25775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine ERROR_TRACING_ENABLED | \ 25875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine INFO_TRACING_ENABLED) 25975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 26075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Prints a string to the emulator's stdout. 2611e980b6bc8315d00a07312b25486531247abd98cElliott Hughes * In early stages of system loading, logging messages to logcat 2621e980b6bc8315d00a07312b25486531247abd98cElliott Hughes * is not available, because ADB API has not been 26375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * hooked up yet. So, in order to see such messages we need to print them to 26475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * the emulator's stdout. 26575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Parameters passed to this macro are the same as parameters for printf 26675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * routine. 26775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 26875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define TR(...) \ 26975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine do { \ 27075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine char tr_str[4096]; \ 271c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes snprintf(tr_str, sizeof(tr_str), __VA_ARGS__); \ 27275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine tr_str[sizeof(tr_str) - 1] = '\0'; \ 27375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine notify_qemu_string(&tr_str[0]); \ 27475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } while (0) 27575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 27675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 27775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// Logging macros. Note that we simultaneously log messages to ADB and emulator. 27875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 279b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 28075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* 28175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Helper macros for checking if particular trace level is enabled. 28275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 28375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define debug_LOG_ENABLED ((tracing_flags & DEBUG_TRACING_ENABLED) != 0) 28475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define error_LOG_ENABLED ((tracing_flags & ERROR_TRACING_ENABLED) != 0) 28575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define info_LOG_ENABLED ((tracing_flags & INFO_TRACING_ENABLED) != 0) 28675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#define tracing_enabled(type) (type##_LOG_ENABLED) 28775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 28875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* 28975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Logging helper macros. 29075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 291e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev#define qemu_debug_log(format, ...) \ 29275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine do { \ 2931e980b6bc8315d00a07312b25486531247abd98cElliott Hughes __libc_format_log(ANDROID_LOG_DEBUG, "memcheck", (format), ##__VA_ARGS__); \ 29475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (tracing_flags & DEBUG_TRACING_ENABLED) { \ 295c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes qemu_log(ANDROID_LOG_DEBUG, (format), ##__VA_ARGS__); \ 29675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } \ 29775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } while (0) 29875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 299e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev#define qemu_error_log(format, ...) \ 30075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine do { \ 3011e980b6bc8315d00a07312b25486531247abd98cElliott Hughes __libc_format_log(ANDROID_LOG_ERROR, "memcheck", (format), ##__VA_ARGS__); \ 30275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (tracing_flags & ERROR_TRACING_ENABLED) { \ 303c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes qemu_log(ANDROID_LOG_ERROR, (format), ##__VA_ARGS__); \ 30475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } \ 30575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } while (0) 30675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 307e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev#define qemu_info_log(format, ...) \ 30875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine do { \ 3091e980b6bc8315d00a07312b25486531247abd98cElliott Hughes __libc_format_log(ANDROID_LOG_INFO, "memcheck", (format), ##__VA_ARGS__); \ 31075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (tracing_flags & INFO_TRACING_ENABLED) { \ 311c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes qemu_log(ANDROID_LOG_INFO, (format), ##__VA_ARGS__); \ 31275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } \ 31375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } while (0) 31475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 31575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Logs message dumping MallocDesc instance at the end of the message. 31675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 31775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * type - Message type: debug, error, or info 31875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * desc - MallocDesc instance to dump. 3191e980b6bc8315d00a07312b25486531247abd98cElliott Hughes * fmt + rest - Formats message preceding dumped descriptor. 32075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine*/ 3211e980b6bc8315d00a07312b25486531247abd98cElliott Hughes#define log_mdesc(type, desc, fmt, ...) \ 32275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine do { \ 32375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (tracing_enabled(type)) { \ 32475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine char log_str[4096]; \ 3251e980b6bc8315d00a07312b25486531247abd98cElliott Hughes __libc_format_buffer(log_str, sizeof(log_str), fmt, ##__VA_ARGS__); \ 32675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine log_str[sizeof(log_str) - 1] = '\0'; \ 3271e980b6bc8315d00a07312b25486531247abd98cElliott Hughes size_t str_len = strlen(log_str); \ 32875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine dump_malloc_descriptor(log_str + str_len, \ 32975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine sizeof(log_str) - str_len, \ 33075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine (desc)); \ 3311e980b6bc8315d00a07312b25486531247abd98cElliott Hughes type##_log("%s", log_str); \ 33275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } \ 33375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } while (0) 33475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 33575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 33675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// Static data 33775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 33875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 339dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris// The underlying malloc implementation to use to get memory. 340dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferrisstatic const MallocDebug* g_malloc_dispatch = NULL; 341dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris 34275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Emulator's magic page address. 34375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * This page (mapped on /dev/qemu_trace device) is used to fire up events 34475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * in the emulator. */ 34575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkinestatic volatile void* qtrace = NULL; 34675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 34775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Cached PID of the process in context of which this libc instance 34875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * has been initialized. */ 34975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkinestatic uint32_t malloc_pid = 0; 35075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 35172bbd423579bb971dc06cdd3c06201faf3fe95e6Christopher Ferris/* Memory allocation alignment that is used in the malloc implementation. 35275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * This variable is updated by memcheck_initialize routine. */ 35375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkinestatic uint32_t malloc_alignment = 8; 35475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 35575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Tracing flags. These flags control which types of logging messages are 35675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * enabled by the emulator. See XXX_TRACING_ENABLED for the values of flags 35775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * stored in this variable. This variable is updated by memcheck_initialize 35875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * routine. */ 35975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkinestatic uint32_t tracing_flags = 0; 36075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 36175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 36275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// Static routines 36375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 36475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 36575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Gets pointer, returned to malloc caller for the given allocation decriptor. 36675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 36775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * desc - Allocation descriptor. 36875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Return: 36975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Pointer to the allocated memory returned to the malloc caller. 37075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 371c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic inline void* mallocdesc_user_ptr(const MallocDesc* desc) { 372c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes return static_cast<char*>(desc->ptr) + desc->prefix_size; 37375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 37475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 37575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Gets size of memory block actually allocated from the heap for the given 37675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * allocation decriptor. 37775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 37875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * desc - Allocation descriptor. 37975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Return: 38075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Size of memory block actually allocated from the heap. 38175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 382c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic inline uint32_t mallocdesc_alloc_size(const MallocDesc* desc) { 38375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return desc->prefix_size + desc->requested_bytes + desc->suffix_size; 384b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine} 385b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 38675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Gets pointer to the end of the allocated block for the given descriptor. 38775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 38875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * desc - Descriptor for the memory block, allocated in malloc handler. 38975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Return: 39075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Pointer to the end of (one byte past) the allocated block. 39175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 392c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic inline void* mallocdesc_alloc_end(const MallocDesc* desc) { 393c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes return static_cast<char*>(desc->ptr) + mallocdesc_alloc_size(desc); 394b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine} 395b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 39675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Fires up an event in the emulator. 39775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 39875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * code - Event code (one of the TRACE_DEV_XXX). 39975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * val - Event's value parameter. 40075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 401ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughesstatic inline void notify_qemu(uint32_t code, uintptr_t val) { 40275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (NULL != qtrace) { 403ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes *(volatile uintptr_t*)((uintptr_t)qtrace + ((code - 1024) << 2)) = val; 40475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 405b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine} 406b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 40775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Prints a zero-terminated string to the emulator's stdout (fires up 40875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * TRACE_DEV_REG_PRINT_USER_STR event in the emulator). 40975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 41075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * str - Zero-terminated string to print. 41175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 412c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic void notify_qemu_string(const char* str) { 41375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (str != NULL) { 414ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes notify_qemu(TRACE_DEV_REG_PRINT_USER_STR, reinterpret_cast<uintptr_t>(str)); 41575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 416b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine} 417b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine 41875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Fires up TRACE_DEV_REG_LIBC_INIT event in the emulator. 41975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 42075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * pid - ID of the process that initialized libc. 42175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 422c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic void notify_qemu_libc_initialized(uint32_t pid) { 42375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine notify_qemu(TRACE_DEV_REG_LIBC_INIT, pid); 42475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 42575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 42675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Fires up TRACE_DEV_REG_MALLOC event in the emulator. 42775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 42875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * desc - Pointer to MallocDesc instance containing allocated block 42975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * information. 43075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Return: 43175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Zero on success, or -1 on failure. Note that on failure libc_pid field of 43275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * the desc parameter passed to this routine has been zeroed out by the 43375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * emulator. 43475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 435c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic inline int notify_qemu_malloc(volatile MallocDesc* desc) { 43675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc->libc_pid = malloc_pid; 43775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc->allocator_pid = getpid(); 43875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc->av_count = 0; 439ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes notify_qemu(TRACE_DEV_REG_MALLOC, reinterpret_cast<uintptr_t>(desc)); 44075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 44175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Emulator reports failure by zeroing libc_pid field of the 44275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * descriptor. */ 44375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return desc->libc_pid != 0 ? 0 : -1; 44475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 44575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 44675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Fires up TRACE_DEV_REG_FREE_PTR event in the emulator. 44775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 44875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * ptr - Pointer to the memory block that's being freed. 44975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Return: 45075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Zero on success, or -1 on failure. 45175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 452c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic inline int notify_qemu_free(void* ptr_to_free) { 45375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine volatile MallocFree free_desc; 45475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 45575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine free_desc.ptr = ptr_to_free; 45675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine free_desc.libc_pid = malloc_pid; 45775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine free_desc.free_pid = getpid(); 458ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes notify_qemu(TRACE_DEV_REG_FREE_PTR, reinterpret_cast<uintptr_t>(&free_desc)); 45975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 46075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Emulator reports failure by zeroing libc_pid field of the 46175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * descriptor. */ 46275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return free_desc.libc_pid != 0 ? 0 : -1; 46375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 46475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 46575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Fires up TRACE_DEV_REG_QUERY_MALLOC event in the emulator. 46675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 46775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * ptr - Pointer to request allocation information for. 46875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * desc - Pointer to MallocDesc instance that will receive allocation 46975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * information. 47075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * routine - Code of the allocation routine, in context of which query is made: 47175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * 1 - free 47275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * 2 - realloc 47375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Return: 47475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Zero on success, or -1 on failure. 47575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 476885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferrisstatic inline int query_qemu_malloc_info(const void* ptr, MallocDesc* desc, uint32_t routine) { 47775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine volatile MallocDescQuery query; 47875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 47975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine query.ptr = ptr; 48075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine query.libc_pid = malloc_pid; 48175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine query.query_pid = getpid(); 48275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine query.routine = routine; 48375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine query.desc = desc; 484ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes notify_qemu(TRACE_DEV_REG_QUERY_MALLOC, reinterpret_cast<uintptr_t>(&query)); 48575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 48675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Emulator reports failure by zeroing libc_pid field of the 48775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * descriptor. */ 48875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return query.libc_pid != 0 ? 0 : -1; 48975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 49075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 49175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Logs a message to emulator's stdout. 49275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 49375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * prio - Message priority (debug, info, or error) 49475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * fmt + rest - Message format and parameters. 49575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 496c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic void qemu_log(int prio, const char* fmt, ...) { 49775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine va_list ap; 49875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine char buf[4096]; 49975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine const char* prefix; 50075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 50175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Choose message prefix depending on the priority value. */ 50275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine switch (prio) { 50375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine case ANDROID_LOG_ERROR: 50475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (!tracing_enabled(error)) { 50575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return; 50675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 50775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine prefix = "E"; 50875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine break; 50975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine case ANDROID_LOG_INFO: 51075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (!tracing_enabled(info)) { 51175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return; 51275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 51375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine prefix = "I"; 51475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine break; 51575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine case ANDROID_LOG_DEBUG: 51675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine default: 51775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (!tracing_enabled(debug)) { 51875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return; 51975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 52075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine prefix = "D"; 52175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine break; 52275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 52375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 52475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine va_start(ap, fmt); 52575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine vsnprintf(buf, sizeof(buf), fmt, ap); 52675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine va_end(ap); 52775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine buf[sizeof(buf) - 1] = '\0'; 52875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 52975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine TR("%s/memcheck: %s\n", prefix, buf); 53075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 53175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 53275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Dumps content of memory allocation descriptor to a string. 53375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 53475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * str - String to dump descriptor to. 53575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * str_buf_size - Size of string's buffer. 53675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * desc - Descriptor to dump. 53775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 538c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic void dump_malloc_descriptor(char* str, size_t str_buf_size, const MallocDesc* desc) { 53975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (str_buf_size) { 54075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine snprintf(str, str_buf_size, 541ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes "MDesc: %p: %p <-> %p [%u + %u + %u] by pid=%03u in libc_pid=%03u", 542ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes mallocdesc_user_ptr(desc), desc->ptr, 543ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes mallocdesc_alloc_end(desc), desc->prefix_size, 544ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes desc->requested_bytes, desc->suffix_size, desc->allocator_pid, 545ef0696d46ac76b1a9eb9038027ef5872fe1f3507Elliott Hughes desc->libc_pid); 54675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine str[str_buf_size - 1] = '\0'; 54775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 54875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 54975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 55075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#if TEST_ACCESS_VIOLATIONS 55175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Causes an access violation on allocation descriptor, and verifies that 55275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * violation has been detected by memory checker in the emulator. 55375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 554c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughesstatic void test_access_violation(const MallocDesc* desc) { 55575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine MallocDesc desc_chk; 55675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine char ch; 55775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine volatile char* prefix = (volatile char*)desc->ptr; 55875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine volatile char* suffix = (volatile char*)mallocdesc_user_ptr(desc) + 55975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc->requested_bytes; 56075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* We're causing AV by reading from the prefix and suffix areas of the 56175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * allocated block. This should produce two access violations, so when we 56275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * get allocation descriptor from QEMU, av_counter should be bigger than 56375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * av_counter of the original descriptor by 2. */ 56475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine ch = *prefix; 56575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine ch = *suffix; 56675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (!query_qemu_malloc_info(mallocdesc_user_ptr(desc), &desc_chk, 2) && 56775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc_chk.av_count != (desc->av_count + 2)) { 56875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine log_mdesc(error, &desc_chk, 56975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine "<libc_pid=%03u, pid=%03u>: malloc: Access violation test failed:\n" 57075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine "Expected violations count %u is not equal to the actually reported %u", 57175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), desc->av_count + 2, 57275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc_chk.av_count); 57375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 57475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 57575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#endif // TEST_ACCESS_VIOLATIONS 57675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 57775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 57875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// API routines 57975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine// ============================================================================= 58075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 581a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" void* qemu_instrumented_calloc(size_t, size_t); 582a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" void qemu_instrumented_free(void*); 583a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" struct mallinfo qemu_instrumented_mallinfo(); 584a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" void* qemu_instrumented_malloc(size_t); 585a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" size_t qemu_instrumented_malloc_usable_size(const void*); 586a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" void* qemu_instrumented_memalign(size_t, size_t); 587a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" int qemu_instrumented_posix_memalign(void**, size_t, size_t); 588a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" void* qemu_instrumented_pvalloc(size_t); 589a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" void* qemu_instrumented_realloc(void*, size_t); 590a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" void* qemu_instrumented_valloc(size_t); 59175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 59275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Initializes malloc debugging instrumentation for the emulator. 59375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * This routine is called from malloc_init_impl routine implemented in 59475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * bionic/libc/bionic/malloc_debug_common.c when malloc debugging gets 59575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * initialized for a process. The way malloc debugging implementation is 59675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * done, it is guaranteed that this routine will be called just once per 59775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * process. 59875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Return: 59975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * 0 on success, or -1 on failure. 60075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine*/ 601dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferrisextern "C" bool malloc_debug_initialize(HashTable*, const MallocDebug* malloc_dispatch) { 602dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris g_malloc_dispatch = malloc_dispatch; 603dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris 60475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* We will be using emulator's magic page to report memory allocation 60575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * activities. In essence, what magic page does, it translates writes to 60675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * the memory mapped spaces into writes to an I/O port that emulator 60775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * "listens to" on the other end. Note that until we open and map that 60875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * device, logging to emulator's stdout will not be available. */ 60975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine int fd = open("/dev/qemu_trace", O_RDWR); 61075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (fd < 0) { 61175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine error_log("Unable to open /dev/qemu_trace"); 6128e52e8fe83632c667521c1c8e4f640e94c09baedElliott Hughes return false; 61375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } else { 6140d787c1fa18c6a1f29ef9840e28a68cf077be1deElliott Hughes qtrace = mmap(NULL, PAGESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 61575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine close(fd); 61675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 61775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (qtrace == MAP_FAILED) { 61875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine qtrace = NULL; 61975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine error_log("Unable to mmap /dev/qemu_trace"); 6208e52e8fe83632c667521c1c8e4f640e94c09baedElliott Hughes return false; 62175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 62275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 62375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 62475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Cache pid of the process this library has been initialized for. */ 62575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid = getpid(); 6268e52e8fe83632c667521c1c8e4f640e94c09baedElliott Hughes return true; 62775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 62875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 62975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* Completes malloc debugging instrumentation for the emulator. 63075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Note that this routine is called after successful return from 63175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * malloc_debug_initialize, which means that connection to the emulator via 63275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * "magic page" has been established. 63375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Param: 63475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * alignment - Alignment requirement set for memiry allocations. 63575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * memcheck_param - Emulator's -memcheck option parameters. This string 63675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * contains abbreviation for guest events that are enabled for tracing. 63775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Return: 63875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * 0 on success, or -1 on failure. 63975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine*/ 640885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferrisextern "C" int memcheck_initialize(int alignment, const char* memcheck_param) { 64175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_alignment = alignment; 64275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 64375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Parse -memcheck parameter for the guest tracing flags. */ 64475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine while (*memcheck_param != '\0') { 64575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine switch (*memcheck_param) { 64675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine case 'a': 64775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Enable all messages from the guest. 64875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine tracing_flags |= ALL_TRACING_ENABLED; 64975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine break; 65075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine case 'd': 65175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Enable debug messages from the guest. 65275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine tracing_flags |= DEBUG_TRACING_ENABLED; 65375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine break; 65475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine case 'e': 65575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Enable error messages from the guest. 65675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine tracing_flags |= ERROR_TRACING_ENABLED; 65775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine break; 65875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine case 'i': 65975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Enable info messages from the guest. 66075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine tracing_flags |= INFO_TRACING_ENABLED; 66175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine break; 66275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine default: 66375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine break; 66475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 66575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (tracing_flags == ALL_TRACING_ENABLED) { 66675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine break; 66775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 66875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine memcheck_param++; 66975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 67075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 67175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine notify_qemu_libc_initialized(malloc_pid); 67275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 673e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev qemu_debug_log("Instrumented for pid=%03u: malloc=%p, free=%p, calloc=%p, realloc=%p, memalign=%p", 67475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, qemu_instrumented_malloc, qemu_instrumented_free, 67575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine qemu_instrumented_calloc, qemu_instrumented_realloc, 67675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine qemu_instrumented_memalign); 67775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 67875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return 0; 67975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 68075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 68175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* This routine serves as entry point for 'malloc'. 68275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Primary responsibility of this routine is to allocate requested number of 68375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * bytes (plus prefix, and suffix guards), and report allocation to the 68475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * emulator. 68575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 686885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferrisextern "C" void* qemu_instrumented_malloc(size_t bytes) { 68775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine MallocDesc desc; 68875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 68972bbd423579bb971dc06cdd3c06201faf3fe95e6Christopher Ferris /* Initialize block descriptor and allocate memory. Note that malloc 69075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * returns a valid pointer on zero allocation. Lets mimic this behavior. */ 69175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.prefix_size = DEFAULT_PREFIX_SIZE; 69275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.requested_bytes = bytes; 69375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.suffix_size = DEFAULT_SUFFIX_SIZE; 694a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris size_t size = mallocdesc_alloc_size(&desc); 695a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris if (size < bytes) { // Overflow 696a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris qemu_error_log("<libc_pid=%03u, pid=%03u> malloc: malloc(%zu) overflow caused failure.", 697a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), bytes); 698a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 699a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris return NULL; 700a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris } 701dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris desc.ptr = g_malloc_dispatch->malloc(size); 70275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (desc.ptr == NULL) { 703580b6e09febc967b5039ef5d148be883089d0effChristopher Ferris qemu_error_log("<libc_pid=%03u, pid=%03u> malloc(%zu): malloc(%zu) failed.", 704a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), bytes, size); 70575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 70675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 70775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 70875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Fire up event in the emulator. 70975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (notify_qemu_malloc(&desc)) { 71075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: malloc: notify_malloc failed for ", 71175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid()); 712dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris g_malloc_dispatch->free(desc.ptr); 713a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 71475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 71575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } else { 71675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#if TEST_ACCESS_VIOLATIONS 71775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine test_access_violation(&desc); 71875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#endif // TEST_ACCESS_VIOLATIONS 719a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris log_mdesc(info, &desc, "+++ <libc_pid=%03u, pid=%03u> malloc(%zu) -> ", 72075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), bytes); 72175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return mallocdesc_user_ptr(&desc); 72275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 72375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 72475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 72575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* This routine serves as entry point for 'malloc'. 72675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * Primary responsibility of this routine is to free requested memory, and 72775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * report free block to the emulator. 72875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 729885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferrisextern "C" void qemu_instrumented_free(void* mem) { 73075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine MallocDesc desc; 73175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 73275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (mem == NULL) { 73375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Just let go NULL free 734dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris g_malloc_dispatch->free(mem); 73575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return; 73675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 73775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 73875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Query emulator for the freeing block information. 73975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (query_qemu_malloc_info(mem, &desc, 1)) { 74075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine error_log("<libc_pid=%03u, pid=%03u>: free(%p) query_info failed.", 74175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), mem); 74275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return; 74375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 74475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 74575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#if TEST_ACCESS_VIOLATIONS 74675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine test_access_violation(&desc); 74775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#endif // TEST_ACCESS_VIOLATIONS 74875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 74975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Make sure that pointer that's being freed matches what we expect 75075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * for this memory block. Note that this violation should be already 75175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * caught in the emulator. */ 75275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (mem != mallocdesc_user_ptr(&desc)) { 75375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) is invalid for ", 75475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), mem); 75575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return; 75675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 75775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 75875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Fire up event in the emulator and free block that was actually allocated. 75975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (notify_qemu_free(mem)) { 76075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: free(%p) notify_free failed for ", 76175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), mem); 76275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } else { 76375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine log_mdesc(info, &desc, "--- <libc_pid=%03u, pid=%03u> free(%p) -> ", 76475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), mem); 765dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris g_malloc_dispatch->free(desc.ptr); 76675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 76775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 76875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 76975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* This routine serves as entry point for 'calloc'. 77075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * This routine behaves similarly to qemu_instrumented_malloc. 77175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 772885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferrisextern "C" void* qemu_instrumented_calloc(size_t n_elements, size_t elem_size) { 77375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (n_elements == 0 || elem_size == 0) { 77475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Just let go zero bytes allocation. 775e1dd3c287ba836281de0197670018bd9bbfbd62bIliyan Malchev qemu_info_log("::: <libc_pid=%03u, pid=%03u>: Zero calloc redir to malloc", 776a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid()); 77775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return qemu_instrumented_malloc(0); 77875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 77975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 7808e52e8fe83632c667521c1c8e4f640e94c09baedElliott Hughes // Fail on overflow - just to be safe even though this code runs only 7818e52e8fe83632c667521c1c8e4f640e94c09baedElliott Hughes // within the debugging C library, not the production one. 7828e52e8fe83632c667521c1c8e4f640e94c09baedElliott Hughes if (n_elements && SIZE_MAX / n_elements < elem_size) { 783a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris qemu_error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu, %zu) overflow caused failure.", 784a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), n_elements, elem_size); 785a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 78675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 78775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 78875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 789c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes MallocDesc desc; 790c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes 79175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Calculating prefix size. The trick here is to make sure that 79275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * first element (returned to the caller) is properly aligned. */ 79375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (DEFAULT_PREFIX_SIZE >= elem_size) { 79475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* If default alignment is bigger than element size, we will 79575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * set our prefix size to the default alignment size. */ 79675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.prefix_size = DEFAULT_PREFIX_SIZE; 79775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* For the suffix we will use whatever bytes remain from the prefix 79875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * allocation size, aligned to the size of an element, plus the usual 79975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * default suffix size. */ 80075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.suffix_size = (DEFAULT_PREFIX_SIZE % elem_size) + 80175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine DEFAULT_SUFFIX_SIZE; 80275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } else { 80375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Make sure that prefix, and suffix sizes is at least elem_size, 80475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * and first element returned to the caller is properly aligned. */ 80575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.prefix_size = elem_size + DEFAULT_PREFIX_SIZE - 1; 80675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.prefix_size &= ~(malloc_alignment - 1); 80775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.suffix_size = DEFAULT_SUFFIX_SIZE; 80875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 80975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.requested_bytes = n_elements * elem_size; 810c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes size_t total_size = desc.requested_bytes + desc.prefix_size + desc.suffix_size; 811a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris if (total_size < desc.requested_bytes) { // Overflow 812a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris qemu_error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu, %zu) overflow caused failure.", 813a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), n_elements, elem_size); 814a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 815a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris return NULL; 816a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris } 817c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes size_t total_elements = total_size / elem_size; 81875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine total_size %= elem_size; 81975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (total_size != 0) { 82075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Add extra to the suffix area. 82175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine total_elements++; 82275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.suffix_size += (elem_size - total_size); 82375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 824dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris desc.ptr = g_malloc_dispatch->calloc(total_elements, elem_size); 82575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (desc.ptr == NULL) { 826a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris error_log("<libc_pid=%03u, pid=%03u> calloc: calloc(%zu(%zu), %zu) (prx=%u, sfx=%u) failed.", 82775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), n_elements, total_elements, elem_size, 82875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.prefix_size, desc.suffix_size); 82975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 83075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 83175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 83275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (notify_qemu_malloc(&desc)) { 833a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: calloc(%zu(%zu), %zu): notify_malloc failed for ", 83475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), n_elements, total_elements, elem_size); 835dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris g_malloc_dispatch->free(desc.ptr); 836a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 83775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 83875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } else { 83975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#if TEST_ACCESS_VIOLATIONS 84075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine test_access_violation(&desc); 84175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#endif // TEST_ACCESS_VIOLATIONS 842a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris log_mdesc(info, &desc, "### <libc_pid=%03u, pid=%03u> calloc(%zu(%zu), %zu) -> ", 84375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), n_elements, total_elements, elem_size); 84475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return mallocdesc_user_ptr(&desc); 84575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 84675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 84775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 84875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* This routine serves as entry point for 'realloc'. 84975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * This routine behaves similarly to qemu_instrumented_free + 85075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * qemu_instrumented_malloc. Note that this modifies behavior of "shrinking" an 85175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * allocation, but overall it doesn't seem to matter, as caller of realloc 85275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * should not expect that pointer returned after shrinking will remain the same. 85375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 854885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferrisextern "C" void* qemu_instrumented_realloc(void* mem, size_t bytes) { 85575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (mem == NULL) { 85675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Nothing to realloc. just do regular malloc. 857a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) redir to malloc", 858a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), mem, bytes); 85975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return qemu_instrumented_malloc(bytes); 86075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 86175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 86275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (bytes == 0) { 86375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // This is a "free" condition. 864a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris qemu_info_log("::: <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) redir to free and malloc", 865a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), mem, bytes); 86675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine qemu_instrumented_free(mem); 86775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 86872bbd423579bb971dc06cdd3c06201faf3fe95e6Christopher Ferris // This is what realloc does for a "free" realloc. 86975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 87075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 87175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 87275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Query emulator for the reallocating block information. 873a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris MallocDesc cur_desc; 87475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (query_qemu_malloc_info(mem, &cur_desc, 2)) { 87575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Note that this violation should be already caught in the emulator. 876a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris error_log("<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) query_info failed.", 87775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), mem, bytes); 878a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 87975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 88075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 88175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 88275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#if TEST_ACCESS_VIOLATIONS 88375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine test_access_violation(&cur_desc); 88475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#endif // TEST_ACCESS_VIOLATIONS 88575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 88675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Make sure that reallocating pointer value is what we would expect 88775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * for this memory block. Note that this violation should be already caught 88875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * in the emulator.*/ 88975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (mem != mallocdesc_user_ptr(&cur_desc)) { 890a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) is invalid for ", 89175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), mem, bytes); 892a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 89375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 89475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 89575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 89675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* TODO: We're a bit inefficient here, always allocating new block from 89775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * the heap. If this realloc shrinks current buffer, we can just do the 89875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * shrinking "in place", adjusting suffix_size in the allocation descriptor 89975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * for this block that is stored in the emulator. */ 90075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 90175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Initialize descriptor for the new block. 902a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris MallocDesc new_desc; 90375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine new_desc.prefix_size = DEFAULT_PREFIX_SIZE; 90475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine new_desc.requested_bytes = bytes; 90575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine new_desc.suffix_size = DEFAULT_SUFFIX_SIZE; 906a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris size_t new_size = mallocdesc_alloc_size(&new_desc); 907a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris if (new_size < bytes) { // Overflow 908580b6e09febc967b5039ef5d148be883089d0effChristopher Ferris qemu_error_log("<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed due to overflow", 909a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), mem, bytes, new_size); 910a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 911a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris return NULL; 912a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris } 913dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris new_desc.ptr = g_malloc_dispatch->malloc(new_size); 91475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (new_desc.ptr == NULL) { 915580b6e09febc967b5039ef5d148be883089d0effChristopher Ferris log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): malloc(%zu) failed on ", 916a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), mem, bytes, new_size); 91775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 91875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 919a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris void* new_mem = mallocdesc_user_ptr(&new_desc); 92075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 92175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Copy user data from old block to the new one. 922a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris size_t to_copy = bytes < cur_desc.requested_bytes ? bytes : cur_desc.requested_bytes; 92375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (to_copy != 0) { 924a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris memcpy(new_mem, mallocdesc_user_ptr(&cur_desc), to_copy); 92575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 92675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 92775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Register new block with emulator. 928c4d1fecc105063e68a5090a6900b63d1b9a24287Elliott Hughes if (notify_qemu_malloc(&new_desc)) { 929a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris log_mdesc(error, &new_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu) notify_malloc failed -> ", 93075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), mem, bytes); 93175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine log_mdesc(error, &cur_desc, " <- "); 932dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris g_malloc_dispatch->free(new_desc.ptr); 933a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 93475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 93575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 93675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 93775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#if TEST_ACCESS_VIOLATIONS 93875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine test_access_violation(&new_desc); 93975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#endif // TEST_ACCESS_VIOLATIONS 94075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 94175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Free old block. 94275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (notify_qemu_free(mem)) { 943a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: realloc(%p, %zu): notify_free failed for ", 94475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), mem, bytes); 94575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine /* Since we registered new decriptor with the emulator, we need 94675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * to unregister it before freeing newly allocated block. */ 94775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine notify_qemu_free(mallocdesc_user_ptr(&new_desc)); 948dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris g_malloc_dispatch->free(new_desc.ptr); 949a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = ENOMEM; 95075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 95175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 952dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris g_malloc_dispatch->free(cur_desc.ptr); 95375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 954a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris log_mdesc(info, &new_desc, "=== <libc_pid=%03u, pid=%03u>: realloc(%p, %zu) -> ", 95575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), mem, bytes); 95675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine log_mdesc(info, &cur_desc, " <- "); 95775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 958a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris return new_mem; 95975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine} 96075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 96175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine/* This routine serves as entry point for 'memalign'. 96275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine * This routine behaves similarly to qemu_instrumented_malloc. 96375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine */ 964885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferrisextern "C" void* qemu_instrumented_memalign(size_t alignment, size_t bytes) { 96575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine MallocDesc desc; 96675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 96775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (bytes == 0) { 96875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine // Just let go zero bytes allocation. 969a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris qemu_info_log("::: <libc_pid=%03u, pid=%03u>: memalign(%zx, %zu) redir to malloc", 97075fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), alignment, bytes); 97175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return qemu_instrumented_malloc(0); 97275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 97375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 974a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris // Prefix size for aligned allocation must be equal to the alignment used 975a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris // for allocation in order to ensure proper alignment of the returned 976a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris // pointer. in case that alignment requirement is greater than prefix 977a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris // size. 978a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris if (alignment < DEFAULT_PREFIX_SIZE) { 979a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris alignment = DEFAULT_PREFIX_SIZE; 98003eebcb6e8762e668a0d3af6bb303cccb88c5b81Christopher Ferris } else if (!powerof2(alignment)) { 98103eebcb6e8762e668a0d3af6bb303cccb88c5b81Christopher Ferris alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment); 982a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris } 983a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris desc.prefix_size = alignment; 98475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.requested_bytes = bytes; 98575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine desc.suffix_size = DEFAULT_SUFFIX_SIZE; 986a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris size_t size = mallocdesc_alloc_size(&desc); 987a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris if (size < bytes) { // Overflow 988580b6e09febc967b5039ef5d148be883089d0effChristopher Ferris qemu_error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed due to overflow.", 989a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), alignment, bytes, size); 990a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris 991a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris return NULL; 992a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris } 993dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris desc.ptr = g_malloc_dispatch->memalign(desc.prefix_size, size); 99475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (desc.ptr == NULL) { 995580b6e09febc967b5039ef5d148be883089d0effChristopher Ferris error_log("<libc_pid=%03u, pid=%03u> memalign(%zx, %zu): malloc(%zu) failed.", 996a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), alignment, bytes, size); 99775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 99875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 99975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine if (notify_qemu_malloc(&desc)) { 1000a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris log_mdesc(error, &desc, "<libc_pid=%03u, pid=%03u>: memalign(%zx, %zu): notify_malloc failed for ", 100175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), alignment, bytes); 1002dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris g_malloc_dispatch->free(desc.ptr); 100375fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return NULL; 100475fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine } 100575fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 100675fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#if TEST_ACCESS_VIOLATIONS 100775fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine test_access_violation(&desc); 100875fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine#endif // TEST_ACCESS_VIOLATIONS 100975fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine 1010a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris log_mdesc(info, &desc, "@@@ <libc_pid=%03u, pid=%03u> memalign(%zx, %zu) -> ", 101175fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine malloc_pid, getpid(), alignment, bytes); 101275fba6888a1e5738f8255f3511c4ad40cbcc0edaVladimir Chtchetkine return mallocdesc_user_ptr(&desc); 1013b74ceb25aae555570df64fa4d4076272733a9a20Vladimir Chtchetkine} 1014885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris 1015885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferrisextern "C" size_t qemu_instrumented_malloc_usable_size(const void* mem) { 1016885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris MallocDesc cur_desc; 1017885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris 1018885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris // Query emulator for the reallocating block information. 1019885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris if (query_qemu_malloc_info(mem, &cur_desc, 2)) { 1020885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris // Note that this violation should be already caught in the emulator. 1021885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris error_log("<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) query_info failed.", 1022885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris malloc_pid, getpid(), mem); 1023885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris return 0; 1024885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris } 1025885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris 1026885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris /* Make sure that reallocating pointer value is what we would expect 1027885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris * for this memory block. Note that this violation should be already caught 1028885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris * in the emulator.*/ 1029885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris if (mem != mallocdesc_user_ptr(&cur_desc)) { 1030885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris log_mdesc(error, &cur_desc, "<libc_pid=%03u, pid=%03u>: malloc_usable_size(%p) is invalid for ", 1031885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris malloc_pid, getpid(), mem); 1032885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris return 0; 1033885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris } 1034885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris 1035885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris /* during instrumentation, we can't really report anything more than requested_bytes */ 1036885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris return cur_desc.requested_bytes; 1037885f3b9cad01b8158aadc55c159c17dbf34f622cChristopher Ferris} 1038a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris 1039a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" struct mallinfo qemu_instrumented_mallinfo() { 1040dda1c6c466c4f31de31d76c8be7e46c16b4b4209Christopher Ferris return g_malloc_dispatch->mallinfo(); 1041a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris} 1042a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris 1043a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" int qemu_instrumented_posix_memalign(void** memptr, size_t alignment, size_t size) { 1044a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris if ((alignment & (alignment - 1)) != 0) { 1045a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris qemu_error_log("<libc_pid=%03u, pid=%03u> posix_memalign(%p, %zu, %zu): invalid alignment.", 1046a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), memptr, alignment, size); 1047a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris return EINVAL; 1048a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris } 1049a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris int saved_errno = errno; 1050a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris *memptr = qemu_instrumented_memalign(alignment, size); 1051a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris errno = saved_errno; 1052a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris return (*memptr != NULL) ? 0 : ENOMEM; 1053a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris} 1054a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris 1055a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" void* qemu_instrumented_pvalloc(size_t bytes) { 105691570ce987ef93f9ba2fa663a5fee1bd2525a2baElliott Hughes size_t pagesize = getpagesize(); 105703eebcb6e8762e668a0d3af6bb303cccb88c5b81Christopher Ferris size_t size = BIONIC_ALIGN(bytes, pagesize); 1058a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris if (size < bytes) { // Overflow 1059a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris qemu_error_log("<libc_pid=%03u, pid=%03u> pvalloc(%zu): overflow (%zu).", 1060a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris malloc_pid, getpid(), bytes, size); 1061a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris return NULL; 1062a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris } 1063a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris return qemu_instrumented_memalign(pagesize, size); 1064a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris} 1065a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris 1066a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferrisextern "C" void* qemu_instrumented_valloc(size_t size) { 106791570ce987ef93f9ba2fa663a5fee1bd2525a2baElliott Hughes return qemu_instrumented_memalign(getpagesize(), size); 1068a403780538ac9d1a260e064df6599663f8cc4166Christopher Ferris} 1069