/* Copyright (C) 2007-2010 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/

/*
 * Contains implementation of routines related to process management in
 * memchecker framework.
 */

#include "elff/elff_api.h"
#include "android/qemu/memcheck/memcheck.h"
#include "android/qemu/memcheck/memcheck_proc_management.h"
#include "android/qemu/memcheck/memcheck_logging.h"
#include "android/qemu/memcheck/memcheck_util.h"

/* Current thread id.
 * This value is updated with each call to memcheck_switch, saving here
 * ID of the thread that becomes current. */
static uint32_t current_tid = 0;

/* Current thread descriptor.
 * This variable is used to cache current thread descriptor. This value gets
 * initialized on "as needed" basis, when descriptor for the current thread
 * is requested for the first time.
 * Note that every time memcheck_switch routine is called, this value gets
 * NULL'ed, since another thread becomes current. */
static ThreadDesc* current_thread = NULL;

/* Current process descriptor.
 * This variable is used to cache current process descriptor. This value gets
 * initialized on "as needed" basis, when descriptor for the current process
 * is requested for the first time.
 * Note that every time memcheck_switch routine is called, this value gets
 * NULL'ed, since new thread becomes current, thus process switch may have
 * occurred as well. */
static ProcDesc*    current_process = NULL;

/* List of running processes. */
static QLIST_HEAD(proc_list, ProcDesc) proc_list;

/* List of running threads. */
static QLIST_HEAD(thread_list, ThreadDesc) thread_list;

// =============================================================================
// Static routines
// =============================================================================

/* Creates and lists thread descriptor for a new thread.
 * This routine will allocate and initialize new thread descriptor. After that
 * this routine will insert the descriptor into the global list of running
 * threads, as well as thread list in the process descriptor of the process
 * in context of which this thread is created.
 * Param:
 *  proc - Process descriptor of the process, in context of which new thread
 *      is created.
 *  tid - Thread ID of the thread that's being created.
 * Return:
 *  New thread descriptor on success, or NULL on failure.
 */
static ThreadDesc*
create_new_thread(ProcDesc* proc, uint32_t tid)
{
    ThreadDesc* new_thread = (ThreadDesc*)g_malloc(sizeof(ThreadDesc));
    if (new_thread == NULL) {
        ME("memcheck: Unable to allocate new thread descriptor.");
        return NULL;
    }
    new_thread->tid = tid;
    new_thread->process = proc;
    new_thread->call_stack = NULL;
    new_thread->call_stack_count = 0;
    new_thread->call_stack_max = 0;
    QLIST_INSERT_HEAD(&thread_list, new_thread, global_entry);
    QLIST_INSERT_HEAD(&proc->threads, new_thread, proc_entry);
    return new_thread;
}

/* Creates and lists process descriptor for a new process.
 * This routine will allocate and initialize new process descriptor. After that
 * this routine will create main thread descriptor for the process (with the
 * thread ID equal to the new process ID), and then new process descriptor will
 * be inserted into the global list of running processes.
 * Param:
 *  pid - Process ID of the process that's being created.
 *  parent_pid - Process ID of the parent process.
 * Return:
 *  New process descriptor on success, or NULL on failure.
 */
static ProcDesc*
create_new_process(uint32_t pid, uint32_t parent_pid)
{
    // Create and init new process descriptor.
    ProcDesc* new_proc = (ProcDesc*)g_malloc(sizeof(ProcDesc));
    if (new_proc == NULL) {
        ME("memcheck: Unable to allocate new process descriptor");
        return NULL;
    }
    QLIST_INIT(&new_proc->threads);
    allocmap_init(&new_proc->alloc_map);
    mmrangemap_init(&new_proc->mmrange_map);
    new_proc->pid = pid;
    new_proc->parent_pid = parent_pid;
    new_proc->image_path = NULL;
    new_proc->flags = 0;

    if (parent_pid != 0) {
        /* If new process has been forked, it inherits a copy of parent's
         * process heap, as well as parent's mmaping of loaded modules. So, on
         * fork we're required to copy parent's allocation descriptors map, as
         * well as parent's mmapping map to the new process. */
        int failed;
        ProcDesc* parent = get_process_from_pid(parent_pid);
        if (parent == NULL) {
            ME("memcheck: Unable to get parent process pid=%u for new process pid=%u",
               parent_pid, pid);
            g_free(new_proc);
            return NULL;
        }

        /* Copy parent's allocation map, setting "inherited" flag, and clearing
         * parent's "transition" flag in the copied entries. */
        failed = allocmap_copy(&new_proc->alloc_map, &parent->alloc_map,
                               MDESC_FLAG_INHERITED_ON_FORK,
                               MDESC_FLAG_TRANSITION_ENTRY);
        if (failed) {
            ME("memcheck: Unable to copy process' %s[pid=%u] allocation map to new process pid=%u",
               parent->image_path, parent_pid, pid);
            allocmap_empty(&new_proc->alloc_map);
            g_free(new_proc);
            return NULL;
        }

        // Copy parent's memory mappings map.
        failed = mmrangemap_copy(&new_proc->mmrange_map, &parent->mmrange_map);
        if (failed) {
            ME("memcheck: Unable to copy process' %s[pid=%u] mmrange map to new process pid=%u",
               parent->image_path, parent_pid, pid);
            mmrangemap_empty(&new_proc->mmrange_map);
            allocmap_empty(&new_proc->alloc_map);
            g_free(new_proc);
            return NULL;
        }
    }

    // Create and register main thread descriptor for new process.
    if(create_new_thread(new_proc, pid) == NULL) {
        mmrangemap_empty(&new_proc->mmrange_map);
        allocmap_empty(&new_proc->alloc_map);
        g_free(new_proc);
        return NULL;
    }

    // List new process.
    QLIST_INSERT_HEAD(&proc_list, new_proc, global_entry);

    return new_proc;
}

/* Finds thread descriptor for a thread id in the global list of running
 * threads.
 * Param:
 *  tid - Thread ID to look up thread descriptor for.
 * Return:
 *  Found thread descriptor, or NULL if thread descriptor has not been found.
 */
static ThreadDesc*
get_thread_from_tid(uint32_t tid)
{
    ThreadDesc* thread;

    /* There is a pretty good chance that when this call is made, it's made
     * to get descriptor for the current thread. Lets see if it is so, so
     * we don't have to iterate through the entire list. */
    if (tid == current_tid && current_thread != NULL) {
        return current_thread;
    }

    QLIST_FOREACH(thread, &thread_list, global_entry) {
        if (tid == thread->tid) {
            if (tid == current_tid) {
                current_thread = thread;
            }
            return thread;
        }
    }
    return NULL;
}

/* Gets thread descriptor for the current thread.
 * Return:
 *  Found thread descriptor, or NULL if thread descriptor has not been found.
 */
ThreadDesc*
get_current_thread(void)
{
    // Lets see if current thread descriptor has been cached.
    if (current_thread == NULL) {
        /* Descriptor is not cached. Look it up in the list. Note that
         * get_thread_from_tid(current_tid) is not used here in order to
         * optimize this code for performance, as this routine is called from
         * the performance sensitive path. */
        ThreadDesc* thread;
        QLIST_FOREACH(thread, &thread_list, global_entry) {
            if (current_tid == thread->tid) {
                current_thread = thread;
                return current_thread;
            }
        }
    }
    return current_thread;
}

/* Finds process descriptor for a thread id.
 * Param:
 *  tid - Thread ID to look up process descriptor for.
 * Return:
 *  Process descriptor for the thread, or NULL, if process descriptor
 *  has not been found.
 */
static inline ProcDesc*
get_process_from_tid(uint32_t tid)
{
    const ThreadDesc* thread = get_thread_from_tid(tid);
    return (thread != NULL) ? thread->process : NULL;
}

/* Sets, or replaces process image path in process descriptor.
 * Generally, new process' image path is unknown untill we calculate it in
 * the handler for TRACE_DEV_REG_CMDLINE event. This routine is called from
 * TRACE_DEV_REG_CMDLINE event handler to set, or replace process image path.
 * Param:
 *  proc - Descriptor of the process where to set, or replace image path.
 *  image_path - Image path to the process, transmitted with
 *      TRACE_DEV_REG_CMDLINE event.
 * set_flags_on_replace - Flags to be set when current image path for the
 *      process has been actually replaced with the new one.
 * Return:
 *  Zero on success, or -1 on failure.
 */
static int
procdesc_set_image_path(ProcDesc* proc,
                        const char* image_path,
                        uint32_t set_flags_on_replace)
{
    if (image_path == NULL || proc == NULL) {
        return 0;
    }

    if (proc->image_path != NULL) {
        /* Process could have been forked, and inherited image path of the
         * parent process. However, it seems that "fork" in terms of TRACE_XXX
         * is not necessarly a strict "fork", but rather new process creation
         * in general. So, if that's the case we need to override image path
         * inherited from the parent process. */
        if (!strcmp(proc->image_path, image_path)) {
            // Paths are the same. Just bail out.
            return 0;
        }
        g_free(proc->image_path);
        proc->image_path = NULL;
    }

    // Save new image path into process' descriptor.
    proc->image_path = g_malloc(strlen(image_path) + 1);
    if (proc->image_path == NULL) {
        ME("memcheck: Unable to allocate %u bytes for image path %s to set it for pid=%u",
           strlen(image_path) + 1, image_path, proc->pid);
        return -1;
    }
    strcpy(proc->image_path, image_path);
    proc->flags |= set_flags_on_replace;
    return 0;
}

/* Frees thread descriptor. */
static void
threaddesc_free(ThreadDesc* thread)
{
    uint32_t indx;

    if (thread == NULL) {
        return;
    }

    if (thread->call_stack != NULL) {
        for (indx = 0; indx < thread->call_stack_count; indx++) {
            if (thread->call_stack[indx].module_path != NULL) {
                g_free(thread->call_stack[indx].module_path);
            }
        }
        g_free(thread->call_stack);
    }
    g_free(thread);
}

// =============================================================================
// Process management API
// =============================================================================

void
memcheck_init_proc_management(void)
{
    QLIST_INIT(&proc_list);
    QLIST_INIT(&thread_list);
}

ProcDesc*
get_process_from_pid(uint32_t pid)
{
    ProcDesc* proc;

    /* Chances are that pid addresses the current process. Lets check this,
     * so we don't have to iterate through the entire project list. */
    if (current_thread != NULL && current_thread->process->pid == pid) {
        current_process = current_thread->process;
        return current_process;
    }

    QLIST_FOREACH(proc, &proc_list, global_entry) {
        if (pid == proc->pid) {
            break;
        }
    }
    return proc;
}

ProcDesc*
get_current_process(void)
{
    if (current_process == NULL) {
        const ThreadDesc* cur_thread = get_current_thread();
        if (cur_thread != NULL) {
            current_process = cur_thread->process;
        }
    }
    return current_process;
}

void
memcheck_on_call(target_ulong from, target_ulong ret)
{
    const uint32_t grow_by = 32;
    const uint32_t max_stack = grow_by;
    ThreadDesc* thread = get_current_thread();
    if (thread == NULL) {
        return;
    }

    /* We're not saving call stack until process starts execution. */
    if (!procdesc_is_executing(thread->process)) {
        return;
    }

    const MMRangeDesc* rdesc = procdesc_get_range_desc(thread->process, from);
    if (rdesc == NULL) {
        ME("memcheck: Unable to find mapping for guest PC 0x%08X in process %s[pid=%u]",
           from, thread->process->image_path, thread->process->pid);
        return;
    }

    /* Limit calling stack size. There are cases when calling stack can be
     * quite deep due to recursion (up to 4000 entries). */
    if (thread->call_stack_count >= max_stack) {
#if 0
        /* This happens quite often. */
        MD("memcheck: Thread stack for %s[pid=%u, tid=%u] is too big: %u",
           thread->process->image_path, thread->process->pid, thread->tid,
           thread->call_stack_count);
#endif
        return;
    }

    if (thread->call_stack_count >= thread->call_stack_max) {
        /* Expand calling stack array buffer. */
        thread->call_stack_max += grow_by;
        ThreadCallStackEntry* new_array =
            g_malloc(thread->call_stack_max * sizeof(ThreadCallStackEntry));
        if (new_array == NULL) {
            ME("memcheck: Unable to allocate %u bytes for calling stack.",
               thread->call_stack_max * sizeof(ThreadCallStackEntry));
            thread->call_stack_max -= grow_by;
            return;
        }
        if (thread->call_stack_count != 0) {
            memcpy(new_array, thread->call_stack,
                   thread->call_stack_count * sizeof(ThreadCallStackEntry));
        }
        if (thread->call_stack != NULL) {
            g_free(thread->call_stack);
        }
        thread->call_stack = new_array;
    }
    thread->call_stack[thread->call_stack_count].call_address = from;
    thread->call_stack[thread->call_stack_count].call_address_rel =
            mmrangedesc_get_module_offset(rdesc, from);
    thread->call_stack[thread->call_stack_count].ret_address = ret;
    thread->call_stack[thread->call_stack_count].ret_address_rel =
            mmrangedesc_get_module_offset(rdesc, ret);
    thread->call_stack[thread->call_stack_count].module_path =
            g_malloc(strlen(rdesc->path) + 1);
    if (thread->call_stack[thread->call_stack_count].module_path == NULL) {
        ME("memcheck: Unable to allocate %u bytes for module path in the thread calling stack.",
            strlen(rdesc->path) + 1);
        return;
    }
    strcpy(thread->call_stack[thread->call_stack_count].module_path,
           rdesc->path);
    thread->call_stack_count++;
}

void
memcheck_on_ret(target_ulong ret)
{
    ThreadDesc* thread = get_current_thread();
    if (thread == NULL) {
        return;
    }

    /* We're not saving call stack until process starts execution. */
    if (!procdesc_is_executing(thread->process)) {
        return;
    }

    if (thread->call_stack_count > 0) {
        int indx = (int)thread->call_stack_count - 1;
        for (; indx >= 0; indx--) {
            if (thread->call_stack[indx].ret_address == ret) {
                thread->call_stack_count = indx;
                return;
            }
        }
    }
}

// =============================================================================
// Handlers for events, generated by the kernel.
// =============================================================================

void
memcheck_init_pid(uint32_t new_pid)
{
    create_new_process(new_pid, 0);
    T(PROC_NEW_PID, "memcheck: init_pid(pid=%u) in current thread tid=%u\n",
      new_pid, current_tid);
}

void
memcheck_switch(uint32_t tid)
{
    /* Since new thread became active, we have to invalidate cached
     * descriptors for current thread and process. */
    current_thread = NULL;
    current_process = NULL;
    current_tid = tid;
}

void
memcheck_fork(uint32_t tgid, uint32_t new_pid)
{
    ProcDesc* parent_proc;
    ProcDesc* new_proc;

    /* tgid may match new_pid, in which case current process is the
     * one that's being forked, otherwise tgid identifies process
     * that's being forked. */
    if (new_pid == tgid) {
        parent_proc = get_current_process();
    } else {
        parent_proc = get_process_from_tid(tgid);
    }

    if (parent_proc == NULL) {
        ME("memcheck: FORK(%u, %u): Unable to look up parent process. Current tid=%u",
           tgid, new_pid, current_tid);
        return;
    }

    if (parent_proc->pid != get_current_process()->pid) {
        MD("memcheck: FORK(%u, %u): parent %s[pid=%u] is not the current process %s[pid=%u]",
           tgid, new_pid, parent_proc->image_path, parent_proc->pid,
           get_current_process()->image_path, get_current_process()->pid);
    }

    new_proc = create_new_process(new_pid, parent_proc->pid);
    if (new_proc == NULL) {
        return;
    }

    /* Since we're possibly forking parent process, we need to inherit
     * parent's image path in the forked process. */
    procdesc_set_image_path(new_proc, parent_proc->image_path, 0);

    T(PROC_FORK, "memcheck: FORK(tgid=%u, new_pid=%u) by %s[pid=%u] (tid=%u)\n",
      tgid, new_pid, parent_proc->image_path, parent_proc->pid, current_tid);
}

void
memcheck_clone(uint32_t tgid, uint32_t new_tid)
{
    ProcDesc* parent_proc;

    /* tgid may match new_pid, in which case current process is the
     * one that creates thread, otherwise tgid identifies process
     * that creates thread. */
    if (new_tid == tgid) {
        parent_proc = get_current_process();
    } else {
        parent_proc = get_process_from_tid(tgid);
    }

    if (parent_proc == NULL) {
        ME("memcheck: CLONE(%u, %u) Unable to look up parent process. Current tid=%u",
           tgid, new_tid, current_tid);
        return;
    }

    if (parent_proc->pid != get_current_process()->pid) {
        ME("memcheck: CLONE(%u, %u): parent %s[pid=%u] is not the current process %s[pid=%u]",
           tgid, new_tid, parent_proc->image_path, parent_proc->pid,
           get_current_process()->image_path, get_current_process()->pid);
    }

    create_new_thread(parent_proc, new_tid);

    T(PROC_CLONE, "memcheck: CLONE(tgid=%u, new_tid=%u) by %s[pid=%u] (tid=%u)\n",
      tgid, new_tid, parent_proc->image_path, parent_proc->pid, current_tid);
}

void
memcheck_set_cmd_line(const char* cmd_arg, unsigned cmdlen)
{
    char parsed[4096];
    int n;

    ProcDesc* current_proc = get_current_process();
    if (current_proc == NULL) {
        ME("memcheck: CMDL(%s, %u): Unable to look up process for current tid=%3u",
           cmd_arg, cmdlen, current_tid);
        return;
    }

    /* Image path is the first agrument in cmd line. Note that due to
     * limitations of TRACE_XXX cmdlen can never exceed CLIENT_PAGE_SIZE */
    memcpy(parsed, cmd_arg, cmdlen);

    // Cut first argument off the entire command line.
    for (n = 0; n < cmdlen; n++) {
        if (parsed[n] == ' ') {
            break;
        }
    }
    parsed[n] = '\0';

    // Save process' image path into descriptor.
    procdesc_set_image_path(current_proc, parsed,
                            PROC_FLAG_IMAGE_PATH_REPLACED);
    current_proc->flags |= PROC_FLAG_EXECUTING;

    /* At this point we need to discard memory mappings inherited from
     * the parent process, since this process has become "independent" from
     * its parent. */
    mmrangemap_empty(&current_proc->mmrange_map);
    T(PROC_START, "memcheck: Executing process %s[pid=%u]\n",
      current_proc->image_path, current_proc->pid);
}

void
memcheck_exit(uint32_t exit_code)
{
    ProcDesc* proc;
    int leaks_reported = 0;
    MallocDescEx leaked_alloc;

    // Exiting thread descriptor.
    ThreadDesc* thread = get_current_thread();
    if (thread == NULL) {
        ME("memcheck: EXIT(%u): Unable to look up thread for current tid=%u",
           exit_code, current_tid);
        return;
    }
    proc = thread->process;

    // Since current thread is exiting, we need to NULL its cached descriptor.
    current_thread = NULL;

    // Unlist the thread from its process as well as global lists.
    QLIST_REMOVE(thread, proc_entry);
    QLIST_REMOVE(thread, global_entry);
    threaddesc_free(thread);

    /* Lets see if this was last process thread, which would indicate
     * process termination. */
    if (!QLIST_EMPTY(&proc->threads)) {
        return;
    }

    // Process is terminating. Report leaks and free resources.
    proc->flags |= PROC_FLAG_EXITING;

    /* Empty allocation descriptors map for the exiting process,
     * reporting leaking blocks in the process. */
    while (!allocmap_pull_first(&proc->alloc_map, &leaked_alloc)) {
        /* We should "forgive" blocks that were inherited from the
         * parent process on fork, or were allocated while process was
         * in "transition" state. */
        if (!mallocdescex_is_inherited_on_fork(&leaked_alloc) &&
            !mallocdescex_is_transition_entry(&leaked_alloc)) {
            if (!leaks_reported) {
                // First leak detected. Print report's header.
                T(CHECK_LEAK, "memcheck: Process %s[pid=%u] is exiting leaking allocated blocks:\n",
                  proc->image_path, proc->pid);
            }
            if (trace_flags & TRACE_CHECK_LEAK_ENABLED) {
                // Dump leaked block information.
                printf("   Leaked block %u:\n", leaks_reported + 1);
                memcheck_dump_malloc_desc(&leaked_alloc, 0, 0);
                if (leaked_alloc.call_stack != NULL) {
                    const int max_stack = 24;
                    if (max_stack >= leaked_alloc.call_stack_count) {
                        printf("      Call stack:\n");
                    } else {
                        printf("      Call stack (first %u of %u entries):\n",
                               max_stack, leaked_alloc.call_stack_count);
                    }
                    uint32_t stk;
                    for (stk = 0;
                         stk < leaked_alloc.call_stack_count && stk < max_stack;
                         stk++) {
                        const MMRangeDesc* rdesc =
                           procdesc_find_mapentry(proc,
                                                  leaked_alloc.call_stack[stk]);
                        if (rdesc != NULL) {
                            Elf_AddressInfo elff_info;
                            ELFF_HANDLE elff_handle = NULL;
                            uint32_t rel =
                                mmrangedesc_get_module_offset(rdesc,
                                                  leaked_alloc.call_stack[stk]);
                            printf("         Frame %u: PC=" TARGET_FMT_lx " (relative %llx) in module %s\n",
                                   stk, leaked_alloc.call_stack[stk], (long long)rel,
                                   rdesc->path);
                            if (memcheck_get_address_info(leaked_alloc.call_stack[stk],
                                                          rdesc, &elff_info,
                                                          &elff_handle) == 0) {
                                printf("            Routine %s @ %s/%s:%u\n",
                                       elff_info.routine_name,
                                       elff_info.dir_name,
                                       elff_info.file_name,
                                       elff_info.line_number);
                                elff_free_pc_address_info(elff_handle,
                                                          &elff_info);
                                elff_close(elff_handle);
                            }
                        } else {
                            printf("         Frame %u: PC=" TARGET_FMT_lx " in module <unknown>\n",
                                   stk, leaked_alloc.call_stack[stk]);

                        }
                    }
                }
            }
            leaks_reported++;
        }
    }

    if (leaks_reported) {
        T(CHECK_LEAK, "memcheck: Process %s[pid=%u] is leaking %u allocated blocks.\n",
          proc->image_path, proc->pid, leaks_reported);
    }

    T(PROC_EXIT, "memcheck: Exiting process %s[pid=%u] in thread %u. Memory leaks detected: %u\n",
      proc->image_path, proc->pid, current_tid, leaks_reported);

    /* Since current process is exiting, we need to NULL its cached descriptor,
     * and unlist it from the list of running processes. */
    current_process = NULL;
    QLIST_REMOVE(proc, global_entry);

    // Empty process' mmapings map.
    mmrangemap_empty(&proc->mmrange_map);
    if (proc->image_path != NULL) {
        g_free(proc->image_path);
    }
    g_free(proc);
}

void
memcheck_mmap_exepath(target_ulong vstart,
                      target_ulong vend,
                      target_ulong exec_offset,
                      const char* path)
{
    MMRangeDesc desc;
    MMRangeDesc replaced;
    RBTMapResult ins_res;

    ProcDesc* proc = get_current_process();
    if (proc == NULL) {
        ME("memcheck: MMAP(0x%08X, 0x%08X, 0x%08X, %s) Unable to look up current process. Current tid=%u",
           vstart, vend, exec_offset, path, current_tid);
        return;
    }

    /* First, unmap an overlapped section */
    memcheck_unmap(vstart, vend);

    /* Add new mapping. */
    desc.map_start = vstart;
    desc.map_end = vend;
    desc.exec_offset = exec_offset;
    desc.path = g_malloc(strlen(path) + 1);
    if (desc.path == NULL) {
        ME("memcheck: MMAP(0x%08X, 0x%08X, 0x%08X, %s) Unable to allocate path for the entry.",
           vstart, vend, exec_offset, path);
        return;
    }
    strcpy(desc.path, path);

    ins_res = mmrangemap_insert(&proc->mmrange_map, &desc, &replaced);
    if (ins_res == RBT_MAP_RESULT_ERROR) {
        ME("memcheck: %s[pid=%u] unable to insert memory mapping entry: 0x%08X - 0x%08X",
           proc->image_path, proc->pid, vstart, vend);
        g_free(desc.path);
        return;
    }

    if (ins_res == RBT_MAP_RESULT_ENTRY_REPLACED) {
        MD("memcheck: %s[pid=%u] MMRANGE %s[0x%08X - 0x%08X] is replaced with %s[0x%08X - 0x%08X]",
           proc->image_path, proc->pid, replaced.path, replaced.map_start,
           replaced.map_end, desc.path, desc.map_start, desc.map_end);
        g_free(replaced.path);
    }

    T(PROC_MMAP, "memcheck: %s[pid=%u] %s is mapped: " TARGET_FMT_lx " - " TARGET_FMT_lx " + " TARGET_FMT_lx "\n",
      proc->image_path, proc->pid, path, vstart, vend, exec_offset);
}

void
memcheck_unmap(target_ulong vstart, target_ulong vend)
{
    MMRangeDesc desc;
    ProcDesc* proc = get_current_process();
    if (proc == NULL) {
        ME("memcheck: UNMAP(0x%08X, 0x%08X) Unable to look up current process. Current tid=%u",
           vstart, vend, current_tid);
        return;
    }

    if (mmrangemap_pull(&proc->mmrange_map, vstart, vend, &desc)) {
        return;
    }

    if (desc.map_start >= vstart && desc.map_end <= vend) {
        /* Entire mapping has been deleted. */
        T(PROC_MMAP, "memcheck: %s[pid=%u] %s is unmapped: [" TARGET_FMT_lx " - " TARGET_FMT_lx " + " TARGET_FMT_lx "]\n",
          proc->image_path, proc->pid, desc.path, vstart, vend, desc.exec_offset);
        g_free(desc.path);
        return;
    }

    /* This can be first stage of "remap" request, when part of the existing
     * mapping has been unmapped. If that's so, lets cut unmapped part from the
     * block that we just pulled, and add whatever's left back to the map. */
    T(PROC_MMAP, "memcheck: REMAP(" TARGET_FMT_lx ", " TARGET_FMT_lx " + " TARGET_FMT_lx ") -> (" TARGET_FMT_lx ", " TARGET_FMT_lx ")\n",
       desc.map_start, desc.map_end, desc.exec_offset, vstart, vend);
    if (desc.map_start == vstart) {
        /* We cut part from the beginning. Add the tail back. */
        desc.exec_offset += vend - desc.map_start;
        desc.map_start = vend;
        mmrangemap_insert(&proc->mmrange_map, &desc, NULL);
    } else if (desc.map_end == vend) {
        /* We cut part from the tail. Add the beginning back. */
        desc.map_end = vstart;
        mmrangemap_insert(&proc->mmrange_map, &desc, NULL);
    } else {
        /* We cut piece in the middle. */
        MMRangeDesc tail;
        tail.map_start = vend;
        tail.map_end = desc.map_end;
        tail.exec_offset = vend - desc.map_start + desc.exec_offset;
        tail.path = g_malloc(strlen(desc.path) + 1);
        strcpy(tail.path, desc.path);
        mmrangemap_insert(&proc->mmrange_map, &tail, NULL);
        desc.map_end = vstart;
        mmrangemap_insert(&proc->mmrange_map, &desc, NULL);
    }
}
