15389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Copyright (C) 2007-2010 The Android Open Source Project
25389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine**
35389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** This software is licensed under the terms of the GNU General Public
45389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** License version 2, as published by the Free Software Foundation, and
55389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** may be copied, distributed, and modified under those terms.
65389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine**
75389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** This program is distributed in the hope that it will be useful,
85389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** but WITHOUT ANY WARRANTY; without even the implied warranty of
95389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** GNU General Public License for more details.
115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine*/
125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/*
145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Contains implementation of memory checking framework in the emulator.
155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
17a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner#include "qemu-queue.h"
185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "qemu_file.h"
195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "elff_api.h"
205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck.h"
215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck_proc_management.h"
225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck_util.h"
235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck_logging.h"
245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// Global data
275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Controls what messages from the guest should be printed to emulator's
305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * stdout. This variable holds a combinations of TRACE_LIBC_XXX flags. */
315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineuint32_t trace_flags = 0;
325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Global flag, indicating whether or not memchecking has been enabled
345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * for the current emulator session. 1 means that memchecking has been enabled,
355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * 0 means that memchecking has not been enabled. */
365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint memcheck_enabled = 0;
375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Global flag, indicating whether or not __ld/__stx_mmu should be instrumented
395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * for checking for access violations. If read / write access violation check
405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * has been disabled by -memcheck flags, there is no need to instrument mmu
415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * routines and waste performance.
425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * 1 means that instrumenting is required, 0 means that instrumenting is not
435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * required. */
445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint memcheck_instrument_mmu = 0;
455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Global flag, indicating whether or not memchecker is collecting call stack.
475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * 1 - call stack is being collected, 0 means that stack is not being
485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * collected. */
495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint memcheck_watch_call_stack = 1;
505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// Static routines.
535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Prints invalid pointer access violation information.
565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  proc - Process that caused access violation.
585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  ptr - Pointer that caused access violation.
595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  routine - If 1, access violation has occurred in 'free' routine.
605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      If 2, access violation has occurred in 'realloc' routine.
615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic void
635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineav_invalid_pointer(ProcDesc* proc, target_ulong ptr, int routine)
645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (trace_flags & TRACE_CHECK_INVALID_PTR_ENABLED) {
665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        printf("memcheck: Access violation is detected in process %s[pid=%u]:\n"
675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine          "  INVALID POINTER 0x%08X is used in '%s' operation.\n"
685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine          "  Allocation descriptor for this pointer has not been found in the\n"
695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine          "  allocation map for the process. Most likely, this is an attempt\n"
705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine          "  to %s a pointer that has been freed.\n",
715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine          proc->image_path, proc->pid, ptr, routine == 1 ? "free" : "realloc",
725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine          routine == 1 ? "free" : "reallocate");
735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Prints read / write access violation information.
775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  proc - Process that caused access violation.
795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  desc - Allocation descriptor for the violation.
805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  addr - Address at which vilation has occurred.
815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  data_size - Size of data accessed at the 'addr'.
825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  val - If access violation has occurred at write operation, this parameter
835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      contains value that's being written to 'addr'. For read violation this
845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      parameter is not used.
855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  retaddr - Code address (in TB) where access violation has occurred.
865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  is_read - If 1, access violation has occurred when memory at 'addr' has been
875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      read. If 0, access violation has occurred when memory was written.
885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic void
905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineav_access_violation(ProcDesc* proc,
915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    MallocDescEx* desc,
925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    target_ulong addr,
935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    uint32_t data_size,
945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    uint64_t val,
955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    target_ulong retaddr,
965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    int is_read)
975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    target_ulong vaddr;
995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    Elf_AddressInfo elff_info;
1005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ELFF_HANDLE elff_handle = NULL;
1015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    desc->malloc_desc.av_count++;
1035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if ((is_read && !(trace_flags & TRACE_CHECK_READ_VIOLATION_ENABLED)) ||
1045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        (!is_read && !(trace_flags & TRACE_CHECK_WRITE_VIOLATION_ENABLED))) {
1055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return;
1065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Convert host address to guest address. */
1095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    vaddr = memcheck_tpc_to_gpc(retaddr);
1105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    printf("memcheck: Access violation is detected in process %s[pid=%u]:\n",
1115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           proc->image_path, proc->pid);
1125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Obtain routine, filename / line info for the address. */
1145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    const MMRangeDesc* rdesc = procdesc_get_range_desc(proc, vaddr);
1155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (rdesc != NULL) {
1165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        int elff_res;
1175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        printf("  In module %s at address 0x%08X\n", rdesc->path, vaddr);
1185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        elff_res =
1195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine          memcheck_get_address_info(vaddr, rdesc, &elff_info, &elff_handle);
1205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (elff_res == 0) {
1215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("  In routine %s in %s/%s:%u\n",
1225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   elff_info.routine_name, elff_info.dir_name,
1235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   elff_info.file_name, elff_info.line_number);
1245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            if (elff_info.inline_stack != NULL) {
1255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                const Elf_InlineInfo* inl = elff_info.inline_stack;
1265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                int index = 0;
1275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                for (; inl[index].routine_name != NULL; index++) {
1285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    char align[64];
1295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    size_t set_align = 4 + index * 2;
1305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    if (set_align >= sizeof(align)) {
1315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                        set_align = sizeof(align) -1;
1325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    }
1335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    memset(align, ' ', set_align);
1345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    align[set_align] = '\0';
1354e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner                    printf("%s", align);
1365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    if (inl[index].inlined_in_file == NULL) {
1375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                        printf("inlined to %s in unknown location\n",
1385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                               inl[index].routine_name);
1395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    } else {
1405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                        printf("inlined to %s in %s/%s:%u\n",
1415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                               inl[index].routine_name,
1425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                               inl[index].inlined_in_file_dir,
1435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                               inl[index].inlined_in_file,
1445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                               inl[index].inlined_at_line);
1455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    }
1465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                }
1475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            }
1485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            elff_free_pc_address_info(elff_handle, &elff_info);
1495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            elff_close(elff_handle);
1505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        } else if (elff_res == 1) {
1515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("  Unable to obtain routine information. Symbols file is not found.\n");
1525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        } else {
1535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("  Unable to obtain routine information.\n"
1545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   "  Symbols file doesn't contain debugging information for address 0x%08X.\n",
1555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                    mmrangedesc_get_module_offset(rdesc, vaddr));
1565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
1575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    } else {
1585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        printf("  In unknown module at address 0x%08X\n", vaddr);
1595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    printf("  Process attempts to %s %u bytes %s address 0x%08X\n",
1625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           is_read ? "read" : "write", data_size,
1635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           is_read ? "from" : "to", addr);
1645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    printf("  Accessed range belongs to the %s guarding area of allocated block.\n",
1655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           addr < (target_ulong)mallocdesc_get_user_ptr(&desc->malloc_desc) ?
1665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                "prefix" : "suffix");
1675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    printf("  Allocation descriptor for this violation:\n");
1685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_dump_malloc_desc(desc, 1, 0);
1695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Validates access to a guest address.
1725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
1735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  addr - Virtual address in the guest space where memory is accessed.
1745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  data_size - Size of the accessed data.
1755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  proc_ptr - Upon exit from this routine contains pointer to the process
1765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      descriptor for the current process, or NULL, if no such descriptor has
1775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      been found.
1785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  desc_ptr - Upon exit from this routine contains pointer to the allocation
1795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      descriptor matching given address range, or NULL, if allocation
1805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      descriptor for the validated memory range has not been found.
1815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
1825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  0 if access to the given guest address range doesn't violate anything, or
1835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  1 if given guest address range doesn't match any entry in the current
1845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      process allocation descriptors map, or
1855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  -1 if a violation has been detected.
1865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
1875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic int
1885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_common_access_validation(target_ulong addr,
1895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                                  uint32_t data_size,
1905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                                  ProcDesc** proc_ptr,
1915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                                  MallocDescEx** desc_ptr)
1925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MallocDescEx* desc;
1945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    target_ulong validating_range_end;
1955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    target_ulong user_range_end;
1965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ProcDesc* proc = get_current_process();
1985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    *proc_ptr = proc;
1995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (proc == NULL) {
2005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        *desc_ptr = NULL;
2015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 1;
2025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    desc = procdesc_find_malloc_for_range(proc, addr, data_size);
2055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    *desc_ptr = desc;
2065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (desc == NULL) {
2075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 1;
2085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Verify that validating address range doesn't start before the address
2115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * available to the user. */
2125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (addr < mallocdesc_get_user_ptr(&desc->malloc_desc)) {
2135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        // Stepped on the prefix guarding area.
2145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return -1;
2155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    validating_range_end = addr + data_size;
2185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    user_range_end = mallocdesc_get_user_alloc_end(&desc->malloc_desc);
2195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Verify that validating address range ends inside the user block.
2215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * We may step on the suffix guarding area because of alignment issue.
2225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * For example, the application code reads last byte in the allocated block
2235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * with something like this:
2245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     *
2255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     *      char last_byte_value = *(char*)last_byte_address;
2265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     *
2275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * and this code got compiled into something like this:
2285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     *
2295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     *      mov eax, [last_byte_address];
2305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     *      mov [last_byte_value], al;
2315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     *
2325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * In this case we will catch a read from the suffix area, even though
2335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * there were no errors in the code. So, in order to prevent such "false
2345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * negative" alarms, lets "forgive" this violation.
2355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * There is one bad thing about this "forgivness" though, as it may very
2365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * well be, that in real life some of these "out of bound" bytes will cross
2375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * page boundaries, marching into a page that has not been mapped to the
2385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * process.
2395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     */
2405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (validating_range_end <= user_range_end) {
2415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        // Validating address range is fully contained inside the user block.
2425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 0;
2435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Lets see if this AV is caused by an alignment issue.*/
2465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if ((validating_range_end - user_range_end) < data_size) {
2475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* Could be an alignment. */
2485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 0;
2495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return -1;
2525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
2535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Checks if process has allocation descriptors for pages defined by a buffer.
2555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
2565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  addr - Starting address of a buffer.
2575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  buf_size - Buffer size.
2585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
2595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  1 if process has allocations descriptors for pages defined by a buffer, or
2605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  0 if pages containing given buffer don't have any memory allocations in
2615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  them.
2625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
2635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic inline int
2645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineprocdesc_contains_allocs(ProcDesc* proc, target_ulong addr, uint32_t buf_size) {
2655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (proc != NULL) {
2665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        // Beginning of the page containing last byte in range.
2675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        const target_ulong end_page = (addr + buf_size - 1) & TARGET_PAGE_MASK;
2685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        // Adjust beginning of the range to the beginning of the page.
2695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        addr &= TARGET_PAGE_MASK;
2705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        // Total size of range to check for descriptors.
2715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        buf_size = end_page - addr + TARGET_PAGE_SIZE + 1;
2725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return procdesc_find_malloc_for_range(proc, addr, buf_size) ? 1 : 0;
2735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    } else {
2745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 0;
2755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
2775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
2795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// Memchecker API.
2805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
2815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
2835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_init(const char* tracing_flags)
2845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
2855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (*tracing_flags == '0') {
2865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        // Memchecker is disabled.
2875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return;
2885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    } else if (*tracing_flags == '1') {
2895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        // Set default tracing.
2905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        trace_flags = TRACE_CHECK_LEAK_ENABLED             |
2915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                      TRACE_CHECK_READ_VIOLATION_ENABLED   |
2925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                      TRACE_CHECK_INVALID_PTR_ENABLED      |
2935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                      TRACE_CHECK_WRITE_VIOLATION_ENABLED;
2945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Parse -memcheck option params, converting them into tracing flags.
2975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    while (*tracing_flags) {
2985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        switch (*tracing_flags) {
2995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'A':
3005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable all emulator's tracing messages.
3015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_ALL_ENABLED;
3025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'F':
3045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable fork() tracing.
3055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_PROC_FORK_ENABLED;
3065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'S':
3085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable guest process staring tracing.
3095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_PROC_START_ENABLED;
3105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'E':
3125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable guest process exiting tracing.
3135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_PROC_EXIT_ENABLED;
3145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'C':
3165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable clone() tracing.
3175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_PROC_CLONE_ENABLED;
3185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'N':
3205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable new PID allocation tracing.
3215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_PROC_NEW_PID_ENABLED;
3225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'B':
3245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable libc.so initialization tracing.
3255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_PROC_LIBC_INIT_ENABLED;
3265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'L':
3285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable memory leaks tracing.
3295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_CHECK_LEAK_ENABLED;
3305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'I':
3325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable invalid free / realloc pointer tracing.
3335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_CHECK_INVALID_PTR_ENABLED;
3345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'R':
3365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable reading violations tracing.
3375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_CHECK_READ_VIOLATION_ENABLED;
3385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'W':
3405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable writing violations tracing.
3415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_CHECK_WRITE_VIOLATION_ENABLED;
3425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            case 'M':
3445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                // Enable module mapping tracing.
3455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                trace_flags |= TRACE_PROC_MMAP_ENABLED;
3465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            default:
3485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                break;
3495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
3505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_flags == TRACE_ALL_ENABLED) {
3515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            break;
3525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
3535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        tracing_flags++;
3545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
3555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
3565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Lets see if we need to instrument MMU, injecting memory access checking.
3575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * We instrument MMU only if we monitor read, or write memory access. */
3585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (trace_flags & (TRACE_CHECK_READ_VIOLATION_ENABLED |
3595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                       TRACE_CHECK_WRITE_VIOLATION_ENABLED)) {
3605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcheck_instrument_mmu = 1;
3615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    } else {
3625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcheck_instrument_mmu = 0;
3635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
3645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
3655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_init_proc_management();
3665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
3675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Lets check env. variables needed for memory checking. */
3685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (getenv("ANDROID_PROJECT_OUT") == NULL) {
3695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        printf("memcheck: Missing ANDROID_PROJECT_OUT environment variable, that is used\n"
3705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine               "to calculate path to symbol files.\n");
3715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
3725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
3735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Always set this flag at the very end of the initialization!
3745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_enabled = 1;
3755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
3765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
3775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
3785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_guest_libc_initialized(uint32_t pid)
3795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
3805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ProcDesc* proc = get_process_from_pid(pid);
3815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (proc == NULL) {
3825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ME("memcheck: Unable to obtain process for libc_init pid=%u", pid);
3835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return;
3845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
3855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    proc->flags |= PROC_FLAG_LIBC_INITIALIZED;
3865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
3875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* When process initializes its own libc.so instance, it means that now
3885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * it has fresh heap. So, at this point we must get rid of all entries
3895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * (inherited and transition) that were collected in this process'
3905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * allocation descriptors map. */
3915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    procdesc_empty_alloc_map(proc);
3925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    T(PROC_LIBC_INIT, "memcheck: libc.so has been initialized for %s[pid=%u]\n",
3935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine      proc->image_path, proc->pid);
3945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
3955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
3965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
3975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_guest_alloc(target_ulong guest_address)
3985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
3995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MallocDescEx desc;
4005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MallocDescEx replaced;
4015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    RBTMapResult insert_res;
4025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ProcDesc* proc;
4035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ThreadDesc* thread;
4045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    uint32_t indx;
4055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Copy allocation descriptor from guest to emulator.
4075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_get_malloc_descriptor(&desc.malloc_desc, guest_address);
4085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    desc.flags = 0;
4095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    desc.call_stack = NULL;
4105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    desc.call_stack_count = 0;
4115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    proc = get_process_from_pid(desc.malloc_desc.allocator_pid);
4135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (proc == NULL) {
4145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ME("memcheck: Unable to obtain process for allocation pid=%u",
4155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           desc.malloc_desc.allocator_pid);
4165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcheck_fail_alloc(guest_address);
4175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return;
4185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
4195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (!procdesc_is_executing(proc)) {
4215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        desc.flags |= MDESC_FLAG_TRANSITION_ENTRY;
4225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
4235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Copy thread's calling stack to the allocation descriptor. */
4255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    thread = get_current_thread();
4265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    desc.call_stack_count = thread->call_stack_count;
4275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (desc.call_stack_count) {
4285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        desc.call_stack = qemu_malloc(desc.call_stack_count * sizeof(target_ulong));
4295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (desc.call_stack == NULL) {
4305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            ME("memcheck: Unable to allocate %u bytes for the calling stack",
4315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine               desc.call_stack_count * sizeof(target_ulong));
4325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            return;
4335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
4345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
4355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Thread's calling stack is in descending order (i.e. first entry in the
4375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * thread's stack is the most distant routine from the current one). On the
4385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * other hand, we keep calling stack entries in allocation descriptor in
4395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * assending order. */
4405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    for (indx = 0; indx < thread->call_stack_count; indx++) {
4415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        desc.call_stack[indx] =
4425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           thread->call_stack[thread->call_stack_count - 1 - indx].call_address;
4435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
4445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Save malloc descriptor in the map.
4465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    insert_res = procdesc_add_malloc(proc, &desc, &replaced);
4475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (insert_res == RBT_MAP_RESULT_ENTRY_INSERTED) {
4485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        // Invalidate TLB cache for the allocated block.
4495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (memcheck_instrument_mmu) {
4505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            invalidate_tlb_cache(desc.malloc_desc.ptr,
4515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                                mallocdesc_get_alloc_end(&desc.malloc_desc));
4525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
4535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    } else if (insert_res == RBT_MAP_RESULT_ENTRY_REPLACED) {
4545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* We don't expect to have another entry in the map that matches
4555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * inserting entry. This is an error condition for us, indicating
4565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * that we somehow lost track of memory allocations. */
4575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ME("memcheck: Duplicate allocation blocks:");
4585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (VERBOSE_CHECK(memcheck)) {
4595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("   New block:\n");
4605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            memcheck_dump_malloc_desc(&desc, 1, 1);
4615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("   Replaced block:\n");
4625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            memcheck_dump_malloc_desc(&replaced, 1, 1);
4635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
4645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (replaced.call_stack != NULL) {
4655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            qemu_free(replaced.call_stack);
4665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
4675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    } else {
4685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ME("memcheck: Unable to insert an entry to the allocation map:");
4695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (VERBOSE_CHECK(memcheck)) {
4705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            memcheck_dump_malloc_desc(&desc, 1, 1);
4715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
4725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcheck_fail_alloc(guest_address);
4735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return;
4745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
4755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
4765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
4785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_guest_free(target_ulong guest_address)
4795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
4805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MallocFree desc;
4815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MallocDescEx pulled;
4825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    int pull_res;
4835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ProcDesc* proc;
4845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Copy free descriptor from guest to emulator.
4865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_get_free_descriptor(&desc, guest_address);
4875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    proc = get_process_from_pid(desc.free_pid);
4895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (proc == NULL) {
4905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ME("memcheck: Unable to obtain process for pid=%u on free",
4915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           desc.free_pid);
4925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcheck_fail_free(guest_address);
4935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return;
4945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
4955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
4965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Pull matching entry from the map.
4975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    pull_res = procdesc_pull_malloc(proc, desc.ptr, &pulled);
4985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (pull_res) {
4995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        av_invalid_pointer(proc, desc.ptr, 1);
5005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcheck_fail_free(guest_address);
5015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return;
5025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
5035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Make sure that ptr has expected value
5055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (desc.ptr != mallocdesc_get_user_ptr(&pulled.malloc_desc)) {
5065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (trace_flags & TRACE_CHECK_INVALID_PTR_ENABLED) {
5075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("memcheck: Access violation is detected in process %s[pid=%u]:\n",
5085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   proc->image_path, proc->pid);
5095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("  INVALID POINTER 0x%08X is used in 'free' operation.\n"
5105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   "  This pointer is unexpected for 'free' operation, as allocation\n"
5115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   "  descriptor found for this pointer in the process' allocation map\n"
5125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   "  suggests that 0x%08X is the pointer to be used to free this block.\n"
5135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   "  Allocation descriptor matching the pointer:\n",
5145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   desc.ptr,
5155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   (uint32_t)mallocdesc_get_user_ptr(&pulled.malloc_desc));
5165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            memcheck_dump_malloc_desc(&pulled, 1, 0);
5175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
5185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
5195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (pulled.call_stack != NULL) {
5205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        qemu_free(pulled.call_stack);
5215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
5225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
5235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
5255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_guest_query_malloc(target_ulong guest_address)
5265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
5275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MallocDescQuery qdesc;
5285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MallocDescEx* found;
5295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ProcDesc* proc;
5305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Copy free descriptor from guest to emulator.
5325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_get_query_descriptor(&qdesc, guest_address);
5335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    proc = get_process_from_pid(qdesc.query_pid);
5355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (proc == NULL) {
5365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ME("memcheck: Unable to obtain process for pid=%u on query_%s",
5375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           qdesc.query_pid, qdesc.routine == 1 ? "free" : "realloc");
5385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcheck_fail_query(guest_address);
5395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return;
5405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
5415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Find allocation entry for the given address.
5435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    found = procdesc_find_malloc(proc, qdesc.ptr);
5445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (found == NULL) {
5455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        av_invalid_pointer(proc, qdesc.ptr, qdesc.routine);
5465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcheck_fail_query(guest_address);
5475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return;
5485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
5495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Copy allocation descriptor back to the guest's space.
5515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_set_malloc_descriptor(qdesc.desc, &found->malloc_desc);
5525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
5535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
5555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_guest_print_str(target_ulong str) {
5565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    char str_copy[4096];
5575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcheck_get_guest_string(str_copy, str, sizeof(str_copy));
5584e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner    printf("%s", str_copy);
5595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
5605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Validates read operations, detected in __ldx_mmu routine.
5625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * This routine is called from __ldx_mmu wrapper implemented in
5635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * softmmu_template.h on condition that loading is occurring from user memory.
5645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
5655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  addr - Virtual address in the guest space where memory is read.
5665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  data_size - Size of the read.
5675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  retaddr - Code address (in TB) that accesses memory.
5685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
5695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  1 if TLB record for the accessed page should be invalidated in order to
5705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  ensure that subsequent attempts to access data in this page will cause
5715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  __ld/stx_mmu to be used. If memchecker is no longer interested in monitoring
5725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * access to this page, this routine returns 0.
5735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
5745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint
5755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_validate_ld(target_ulong addr,
5765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                     uint32_t data_size,
5775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                     target_ulong retaddr)
5785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
5795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ProcDesc* proc;
5805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MallocDescEx* desc;
5815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    int res = memcheck_common_access_validation(addr, data_size, &proc, &desc);
5835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (res == -1) {
5845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        av_access_violation(proc, desc, addr, data_size, 0, retaddr, 1);
5855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 1;
5865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
5875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Even though descriptor for the given address range has not been found,
5895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * we need to make sure that pages containing the given address range
5905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * don't contain other descriptors. */
5915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return res ? procdesc_contains_allocs(proc, addr, data_size) : 0;
5925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
5935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
5945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Validates write operations, detected in __stx_mmu routine.
5955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * This routine is called from __stx_mmu wrapper implemented in
5965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * softmmu_template.h on condition that storing is occurring from user memory.
5975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
5985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  addr - Virtual address in the guest space where memory is written.
5995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  data_size - Size of the write.
6005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  value - Value to be written. Note that we typecast all values to 64 bits,
6015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      since this will fit all data sizes.
6025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  retaddr - Code address (in TB) that accesses memory.
6035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
6045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  1 if TLB record for the accessed page should be invalidated in order to
6055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  ensure that subsequent attempts to access data in this page will cause
6065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  __ld/stx_mmu to be used. If memchecker is no longer interested in monitoring
6075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * access to this page, this routine returns 0.
6085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
6095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint
6105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_validate_st(target_ulong addr,
6115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                     uint32_t data_size,
6125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                     uint64_t value,
6135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                     target_ulong retaddr)
6145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
6155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MallocDescEx* desc;
6165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ProcDesc* proc;
6175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
6185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    int res = memcheck_common_access_validation(addr, data_size, &proc, &desc);
6195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (res == -1) {
6205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        av_access_violation(proc, desc, addr, data_size, value, retaddr, 0);
6215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 1;
6225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
6235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
6245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Even though descriptor for the given address range has not been found,
6255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * we need to make sure that pages containing the given address range
6265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * don't contain other descriptors. */
6275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return res ? procdesc_contains_allocs(proc, addr, data_size) : 0;
6285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
6295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
6305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Checks if given address range in the context of the current process is under
6315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * surveillance.
6325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
6335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  addr - Starting address of a range.
6345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  size - Range size.
6355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
6365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  boolean: 1 if address range contains memory that require access violation
6375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  detection, or 0 if given address range is in no interest to the memchecker.
6385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
6395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint
6405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_is_checked(target_ulong addr, uint32_t size) {
6415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return procdesc_contains_allocs(get_current_process(), addr, size) ? 1 : 0;
6425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
643