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 utility routines for memchecker framework.
155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "stdio.h"
185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "qemu-common.h"
195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "android/utils/path.h"
205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "cpu.h"
215285864985be9077e58e42235af6582dee72e841David 'Digit' Turner#include "memcheck_util.h"
225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck_proc_management.h"
235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck_logging.h"
245285864985be9077e58e42235af6582dee72e841David 'Digit' Turner//#include "softmmu_outside_jit.h"
255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Gets symblos file path for the given module.
275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  module_path - Path to the module to get sympath for.
295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  sym_path - Buffer, where to save path to the symbols file path for the givem
305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      module. NOTE: This buffer must be big enough to contain the largest
315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      path possible.
325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  max_char - Character size of the buffer addressed by sym_path parameter.
335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  0 on success, or -1 if symbols file has not been found, or sym_path buffer
355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  was too small to contain entire path.
365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic int
385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineget_sym_path(const char* module_path, char* sym_path, size_t max_char)
395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    const char* sym_path_root = getenv("ANDROID_PROJECT_OUT");
415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (sym_path_root == NULL || strlen(sym_path_root) >= max_char) {
425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return -1;
435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    strcpy(sym_path, sym_path_root);
465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    max_char -= strlen(sym_path_root);
475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (sym_path[strlen(sym_path)-1] != PATH_SEP_C) {
485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        strcat(sym_path, PATH_SEP);
495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        max_char--;
505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (strlen("symbols") >= max_char) {
525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return -1;
535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    strcat(sym_path, "symbols");
555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    max_char -= strlen("symbols");
565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (strlen(module_path) >= max_char) {
575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return -1;
585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    strcat(sym_path, module_path);
605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Sometimes symbol file for a module is placed into a parent symbols
625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * directory. Lets iterate through all parent sym dirs, until we find
635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * sym file, or reached symbols root. */
645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    while (!path_exists(sym_path)) {
655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* Select module name. */
665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        char* name = strrchr(sym_path, PATH_SEP_C);
675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        assert(name != NULL);
685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        *name = '\0';
695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* Parent directory. */
705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        char* parent = strrchr(sym_path, PATH_SEP_C);
715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        assert(parent != NULL);
725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        *parent = '\0';
735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (strcmp(sym_path, sym_path_root) == 0) {
745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            return -1;
755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        *parent = PATH_SEP_C;
775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memmove(parent+1, name + 1, strlen(name + 1) + 1);
785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return 0;
815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// Transfering data between guest and emulator address spaces.
855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_get_guest_buffer(void* qemu_address,
895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          target_ulong guest_address,
905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          size_t buffer_size)
915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Byte-by-byte copying back and forth between guest's and emulator's memory
935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * appears to be efficient enough (at least on small blocks used in
945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * memchecker), so there is no real need to optimize it by aligning guest
955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * buffer to 32 bits and use ld/stl_user instead of ld/stub_user to
965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * read / write guest's memory. */
975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    while (buffer_size) {
985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        *(uint8_t*)qemu_address = ldub_user(guest_address);
994e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner        qemu_address = (uint8_t*)qemu_address + 1;
1005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        guest_address++;
1015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        buffer_size--;
1025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
1065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_set_guest_buffer(target_ulong guest_address,
1075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          const void* qemu_address,
1085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          size_t buffer_size)
1095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    while (buffer_size) {
1115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        stb_user(guest_address, *(uint8_t*)qemu_address);
1125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        guest_address++;
1134e024bb4f5c8aa8b07459f7fbd65c35122127fd1David 'Digit' Turner        qemu_address = (uint8_t*)qemu_address + 1;
1145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        buffer_size--;
1155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinesize_t
1195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_get_guest_string(char* qemu_str,
1205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          target_ulong guest_str,
1215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          size_t qemu_buffer_size)
1225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    size_t copied = 0;
1245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (qemu_buffer_size > 1) {
1265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        for (copied = 0; copied < qemu_buffer_size - 1; copied++) {
1275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            qemu_str[copied] = ldub_user(guest_str + copied);
1285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            if (qemu_str[copied] == '\0') {
1295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                return copied;
1305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            }
1315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
1325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    qemu_str[copied] = '\0';
1345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return copied;
1355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinesize_t
1385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_get_guest_kernel_string(char* qemu_str,
1395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                                 target_ulong guest_str,
1405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                                 size_t qemu_buffer_size)
1415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    size_t copied = 0;
1435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (qemu_buffer_size > 1) {
1455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        for (copied = 0; copied < qemu_buffer_size - 1; copied++) {
1465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            qemu_str[copied] = ldub_kernel(guest_str + copied);
1475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            if (qemu_str[copied] == '\0') {
1485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                return copied;
1495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            }
1505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
1515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    qemu_str[copied] = '\0';
1535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return copied;
1545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
1575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// Helpers for transfering memory allocation information.
1585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
1595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
1615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_fail_alloc(target_ulong guest_address)
1625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    stl_user(ALLOC_RES_ADDRESS(guest_address), 0);
1645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
1675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_fail_free(target_ulong guest_address)
1685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    stl_user(FREE_RES_ADDRESS(guest_address), 0);
1705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
1735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_fail_query(target_ulong guest_address)
1745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    stl_user(QUERY_RES_ADDRESS(guest_address), 0);
1765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
1795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// Misc. utility routines.
1805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
1815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
1835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineinvalidate_tlb_cache(target_ulong start, target_ulong end)
1845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    target_ulong index = (start >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    const target_ulong to = ((end - 1) >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE-1);
1875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    for (; index <= to; index++, start += TARGET_PAGE_SIZE) {
1885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        target_ulong tlb_addr = cpu_single_env->tlb_table[1][index].addr_write;
1895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if ((start & TARGET_PAGE_MASK) ==
1905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            cpu_single_env->tlb_table[1][index].addr_write ^= TARGET_PAGE_MASK;
1925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
1935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        tlb_addr = cpu_single_env->tlb_table[1][index].addr_read;
1945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if ((start & TARGET_PAGE_MASK) ==
1955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
1965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            cpu_single_env->tlb_table[1][index].addr_read ^= TARGET_PAGE_MASK;
1975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
1985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
2005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
2025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_dump_malloc_desc(const MallocDescEx* desc_ex,
2035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          int print_flags,
2045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          int print_proc_info)
2055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
2065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    const MallocDesc* desc = &desc_ex->malloc_desc;
2075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    printf("            User range:             0x%08X - 0x%08X, %u bytes\n",
2085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           (uint32_t)mallocdesc_get_user_ptr(desc),
2095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            (uint32_t)mallocdesc_get_user_ptr(desc) + desc->requested_bytes,
2105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           desc->requested_bytes);
2115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    printf("            Prefix guarding area:   0x%08X - 0x%08X, %u bytes\n",
2125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           desc->ptr, desc->ptr + desc->prefix_size, desc->prefix_size);
2135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    printf("            Suffix guarding area:   0x%08X - 0x%08X, %u bytes\n",
2145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           mallocdesc_get_user_alloc_end(desc),
2155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           mallocdesc_get_user_alloc_end(desc) + desc->suffix_size,
2165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine           desc->suffix_size);
2175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (print_proc_info) {
2185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ProcDesc* proc = get_process_from_pid(desc->allocator_pid);
2195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (proc != NULL) {
2205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            printf("            Allocated by:           %s[pid=%u]\n",
2215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                   proc->image_path, proc->pid);
2225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
2235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (print_flags) {
2255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        printf("            Flags:                  0x%08X\n", desc_ex->flags);
2265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
2285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint
2305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinememcheck_get_address_info(target_ulong abs_pc,
2315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          const MMRangeDesc* rdesc,
2325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          Elf_AddressInfo* info,
2335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                          ELFF_HANDLE* elff_handle)
2345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
2355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    char sym_path[MAX_PATH];
2365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ELFF_HANDLE handle;
2375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (get_sym_path(rdesc->path, sym_path, MAX_PATH)) {
2395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 1;
2405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    handle = elff_init(sym_path);
2435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (handle == NULL) {
2445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return -1;
2455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (!elff_is_exec(handle)) {
2485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* Debug info for shared library is created for the relative address. */
2495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        target_ulong rel_pc = mmrangedesc_get_module_offset(rdesc, abs_pc);
2505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (elff_get_pc_address_info(handle, rel_pc, info)) {
2515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            elff_close(handle);
2525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            return -1;
2535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
2545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    } else {
2555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* Debug info for executables is created for the absoulte address. */
2565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (elff_get_pc_address_info(handle, abs_pc, info)) {
2575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            elff_close(handle);
2585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            return -1;
2595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
2605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    *elff_handle = handle;
2635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return 0;
2645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
265