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