/* 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 memory checking framework in the emulator.
 */

#include "qemu/queue.h"
#include "migration/qemu-file.h"
#include "elff_api.h"
#include "memcheck.h"
#include "memcheck_proc_management.h"
#include "memcheck_util.h"
#include "memcheck_logging.h"

// =============================================================================
// Global data
// =============================================================================

/* Controls what messages from the guest should be printed to emulator's
 * stdout. This variable holds a combinations of TRACE_LIBC_XXX flags. */
uint32_t trace_flags = 0;

/* Global flag, indicating whether or not memchecking has been enabled
 * for the current emulator session. 1 means that memchecking has been enabled,
 * 0 means that memchecking has not been enabled. */
int memcheck_enabled = 0;

/* Global flag, indicating whether or not __ld/__stx_mmu should be instrumented
 * for checking for access violations. If read / write access violation check
 * has been disabled by -memcheck flags, there is no need to instrument mmu
 * routines and waste performance.
 * 1 means that instrumenting is required, 0 means that instrumenting is not
 * required. */
int memcheck_instrument_mmu = 0;

/* Global flag, indicating whether or not memchecker is collecting call stack.
 * 1 - call stack is being collected, 0 means that stack is not being
 * collected. */
int memcheck_watch_call_stack = 1;

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

/* Prints invalid pointer access violation information.
 * Param:
 *  proc - Process that caused access violation.
 *  ptr - Pointer that caused access violation.
 *  routine - If 1, access violation has occurred in 'free' routine.
 *      If 2, access violation has occurred in 'realloc' routine.
 */
static void
av_invalid_pointer(ProcDesc* proc, target_ulong ptr, int routine)
{
    if (trace_flags & TRACE_CHECK_INVALID_PTR_ENABLED) {
        printf("memcheck: Access violation is detected in process %s[pid=%u]:\n"
          "  INVALID POINTER 0x%08X is used in '%s' operation.\n"
          "  Allocation descriptor for this pointer has not been found in the\n"
          "  allocation map for the process. Most likely, this is an attempt\n"
          "  to %s a pointer that has been freed.\n",
          proc->image_path, proc->pid, ptr, routine == 1 ? "free" : "realloc",
          routine == 1 ? "free" : "reallocate");
    }
}

/* Prints read / write access violation information.
 * Param:
 *  proc - Process that caused access violation.
 *  desc - Allocation descriptor for the violation.
 *  addr - Address at which vilation has occurred.
 *  data_size - Size of data accessed at the 'addr'.
 *  val - If access violation has occurred at write operation, this parameter
 *      contains value that's being written to 'addr'. For read violation this
 *      parameter is not used.
 *  retaddr - Code address (in TB) where access violation has occurred.
 *  is_read - If 1, access violation has occurred when memory at 'addr' has been
 *      read. If 0, access violation has occurred when memory was written.
 */
static void
av_access_violation(ProcDesc* proc,
                    MallocDescEx* desc,
                    target_ulong addr,
                    uint32_t data_size,
                    uint64_t val,
                    target_ulong retaddr,
                    int is_read)
{
    target_ulong vaddr;
    Elf_AddressInfo elff_info;
    ELFF_HANDLE elff_handle = NULL;

    desc->malloc_desc.av_count++;
    if ((is_read && !(trace_flags & TRACE_CHECK_READ_VIOLATION_ENABLED)) ||
        (!is_read && !(trace_flags & TRACE_CHECK_WRITE_VIOLATION_ENABLED))) {
        return;
    }

    /* Convert host address to guest address. */
    vaddr = memcheck_tpc_to_gpc(retaddr);
    printf("memcheck: Access violation is detected in process %s[pid=%u]:\n",
           proc->image_path, proc->pid);

    /* Obtain routine, filename / line info for the address. */
    const MMRangeDesc* rdesc = procdesc_get_range_desc(proc, vaddr);
    if (rdesc != NULL) {
        int elff_res;
        printf("  In module %s at address 0x%08X\n", rdesc->path, vaddr);
        elff_res =
          memcheck_get_address_info(vaddr, rdesc, &elff_info, &elff_handle);
        if (elff_res == 0) {
            printf("  In routine %s in %s/%s:%u\n",
                   elff_info.routine_name, elff_info.dir_name,
                   elff_info.file_name, elff_info.line_number);
            if (elff_info.inline_stack != NULL) {
                const Elf_InlineInfo* inl = elff_info.inline_stack;
                int index = 0;
                for (; inl[index].routine_name != NULL; index++) {
                    char align[64];
                    size_t set_align = 4 + index * 2;
                    if (set_align >= sizeof(align)) {
                        set_align = sizeof(align) -1;
                    }
                    memset(align, ' ', set_align);
                    align[set_align] = '\0';
                    printf("%s", align);
                    if (inl[index].inlined_in_file == NULL) {
                        printf("inlined to %s in unknown location\n",
                               inl[index].routine_name);
                    } else {
                        printf("inlined to %s in %s/%s:%u\n",
                               inl[index].routine_name,
                               inl[index].inlined_in_file_dir,
                               inl[index].inlined_in_file,
                               inl[index].inlined_at_line);
                    }
                }
            }
            elff_free_pc_address_info(elff_handle, &elff_info);
            elff_close(elff_handle);
        } else if (elff_res == 1) {
            printf("  Unable to obtain routine information. Symbols file is not found.\n");
        } else {
            printf("  Unable to obtain routine information.\n"
                   "  Symbols file doesn't contain debugging information for address 0x%08X.\n",
                    mmrangedesc_get_module_offset(rdesc, vaddr));
        }
    } else {
        printf("  In unknown module at address 0x%08X\n", vaddr);
    }

    printf("  Process attempts to %s %u bytes %s address 0x%08X\n",
           is_read ? "read" : "write", data_size,
           is_read ? "from" : "to", addr);
    printf("  Accessed range belongs to the %s guarding area of allocated block.\n",
           addr < (target_ulong)mallocdesc_get_user_ptr(&desc->malloc_desc) ?
                "prefix" : "suffix");
    printf("  Allocation descriptor for this violation:\n");
    memcheck_dump_malloc_desc(desc, 1, 0);
}

/* Validates access to a guest address.
 * Param:
 *  addr - Virtual address in the guest space where memory is accessed.
 *  data_size - Size of the accessed data.
 *  proc_ptr - Upon exit from this routine contains pointer to the process
 *      descriptor for the current process, or NULL, if no such descriptor has
 *      been found.
 *  desc_ptr - Upon exit from this routine contains pointer to the allocation
 *      descriptor matching given address range, or NULL, if allocation
 *      descriptor for the validated memory range has not been found.
 * Return:
 *  0 if access to the given guest address range doesn't violate anything, or
 *  1 if given guest address range doesn't match any entry in the current
 *      process allocation descriptors map, or
 *  -1 if a violation has been detected.
 */
static int
memcheck_common_access_validation(target_ulong addr,
                                  uint32_t data_size,
                                  ProcDesc** proc_ptr,
                                  MallocDescEx** desc_ptr)
{
    MallocDescEx* desc;
    target_ulong validating_range_end;
    target_ulong user_range_end;

    ProcDesc* proc = get_current_process();
    *proc_ptr = proc;
    if (proc == NULL) {
        *desc_ptr = NULL;
        return 1;
    }

    desc = procdesc_find_malloc_for_range(proc, addr, data_size);
    *desc_ptr = desc;
    if (desc == NULL) {
        return 1;
    }

    /* Verify that validating address range doesn't start before the address
     * available to the user. */
    if (addr < mallocdesc_get_user_ptr(&desc->malloc_desc)) {
        // Stepped on the prefix guarding area.
        return -1;
    }

    validating_range_end = addr + data_size;
    user_range_end = mallocdesc_get_user_alloc_end(&desc->malloc_desc);

    /* Verify that validating address range ends inside the user block.
     * We may step on the suffix guarding area because of alignment issue.
     * For example, the application code reads last byte in the allocated block
     * with something like this:
     *
     *      char last_byte_value = *(char*)last_byte_address;
     *
     * and this code got compiled into something like this:
     *
     *      mov eax, [last_byte_address];
     *      mov [last_byte_value], al;
     *
     * In this case we will catch a read from the suffix area, even though
     * there were no errors in the code. So, in order to prevent such "false
     * negative" alarms, lets "forgive" this violation.
     * There is one bad thing about this "forgivness" though, as it may very
     * well be, that in real life some of these "out of bound" bytes will cross
     * page boundaries, marching into a page that has not been mapped to the
     * process.
     */
    if (validating_range_end <= user_range_end) {
        // Validating address range is fully contained inside the user block.
        return 0;
    }

    /* Lets see if this AV is caused by an alignment issue.*/
    if ((validating_range_end - user_range_end) < data_size) {
        /* Could be an alignment. */
        return 0;
    }

    return -1;
}

/* Checks if process has allocation descriptors for pages defined by a buffer.
 * Param:
 *  addr - Starting address of a buffer.
 *  buf_size - Buffer size.
 * Return:
 *  1 if process has allocations descriptors for pages defined by a buffer, or
 *  0 if pages containing given buffer don't have any memory allocations in
 *  them.
 */
static inline int
procdesc_contains_allocs(ProcDesc* proc, target_ulong addr, uint32_t buf_size) {
    if (proc != NULL) {
        // Beginning of the page containing last byte in range.
        const target_ulong end_page = (addr + buf_size - 1) & TARGET_PAGE_MASK;
        // Adjust beginning of the range to the beginning of the page.
        addr &= TARGET_PAGE_MASK;
        // Total size of range to check for descriptors.
        buf_size = end_page - addr + TARGET_PAGE_SIZE + 1;
        return procdesc_find_malloc_for_range(proc, addr, buf_size) ? 1 : 0;
    } else {
        return 0;
    }
}

// =============================================================================
// Memchecker API.
// =============================================================================

void
memcheck_init(const char* tracing_flags)
{
    if (*tracing_flags == '0') {
        // Memchecker is disabled.
        return;
    } else if (*tracing_flags == '1') {
        // Set default tracing.
        trace_flags = TRACE_CHECK_LEAK_ENABLED             |
                      TRACE_CHECK_READ_VIOLATION_ENABLED   |
                      TRACE_CHECK_INVALID_PTR_ENABLED      |
                      TRACE_CHECK_WRITE_VIOLATION_ENABLED;
    }

    // Parse -memcheck option params, converting them into tracing flags.
    while (*tracing_flags) {
        switch (*tracing_flags) {
            case 'A':
                // Enable all emulator's tracing messages.
                trace_flags |= TRACE_ALL_ENABLED;
                break;
            case 'F':
                // Enable fork() tracing.
                trace_flags |= TRACE_PROC_FORK_ENABLED;
                break;
            case 'S':
                // Enable guest process staring tracing.
                trace_flags |= TRACE_PROC_START_ENABLED;
                break;
            case 'E':
                // Enable guest process exiting tracing.
                trace_flags |= TRACE_PROC_EXIT_ENABLED;
                break;
            case 'C':
                // Enable clone() tracing.
                trace_flags |= TRACE_PROC_CLONE_ENABLED;
                break;
            case 'N':
                // Enable new PID allocation tracing.
                trace_flags |= TRACE_PROC_NEW_PID_ENABLED;
                break;
            case 'B':
                // Enable libc.so initialization tracing.
                trace_flags |= TRACE_PROC_LIBC_INIT_ENABLED;
                break;
            case 'L':
                // Enable memory leaks tracing.
                trace_flags |= TRACE_CHECK_LEAK_ENABLED;
                break;
            case 'I':
                // Enable invalid free / realloc pointer tracing.
                trace_flags |= TRACE_CHECK_INVALID_PTR_ENABLED;
                break;
            case 'R':
                // Enable reading violations tracing.
                trace_flags |= TRACE_CHECK_READ_VIOLATION_ENABLED;
                break;
            case 'W':
                // Enable writing violations tracing.
                trace_flags |= TRACE_CHECK_WRITE_VIOLATION_ENABLED;
                break;
            case 'M':
                // Enable module mapping tracing.
                trace_flags |= TRACE_PROC_MMAP_ENABLED;
                break;
            default:
                break;
        }
        if (trace_flags == TRACE_ALL_ENABLED) {
            break;
        }
        tracing_flags++;
    }

    /* Lets see if we need to instrument MMU, injecting memory access checking.
     * We instrument MMU only if we monitor read, or write memory access. */
    if (trace_flags & (TRACE_CHECK_READ_VIOLATION_ENABLED |
                       TRACE_CHECK_WRITE_VIOLATION_ENABLED)) {
        memcheck_instrument_mmu = 1;
    } else {
        memcheck_instrument_mmu = 0;
    }

    memcheck_init_proc_management();

    /* Lets check env. variables needed for memory checking. */
    if (getenv("ANDROID_PROJECT_OUT") == NULL) {
        printf("memcheck: Missing ANDROID_PROJECT_OUT environment variable, that is used\n"
               "to calculate path to symbol files.\n");
    }

    // Always set this flag at the very end of the initialization!
    memcheck_enabled = 1;
}

void
memcheck_guest_libc_initialized(uint32_t pid)
{
    ProcDesc* proc = get_process_from_pid(pid);
    if (proc == NULL) {
        ME("memcheck: Unable to obtain process for libc_init pid=%u", pid);
        return;
    }
    proc->flags |= PROC_FLAG_LIBC_INITIALIZED;

    /* When process initializes its own libc.so instance, it means that now
     * it has fresh heap. So, at this point we must get rid of all entries
     * (inherited and transition) that were collected in this process'
     * allocation descriptors map. */
    procdesc_empty_alloc_map(proc);
    T(PROC_LIBC_INIT, "memcheck: libc.so has been initialized for %s[pid=%u]\n",
      proc->image_path, proc->pid);
}

void
memcheck_guest_alloc(target_ulong guest_address)
{
    MallocDescEx desc;
    MallocDescEx replaced;
    RBTMapResult insert_res;
    ProcDesc* proc;
    ThreadDesc* thread;
    uint32_t indx;

    // Copy allocation descriptor from guest to emulator.
    memcheck_get_malloc_descriptor(&desc.malloc_desc, guest_address);
    desc.flags = 0;
    desc.call_stack = NULL;
    desc.call_stack_count = 0;

    proc = get_process_from_pid(desc.malloc_desc.allocator_pid);
    if (proc == NULL) {
        ME("memcheck: Unable to obtain process for allocation pid=%u",
           desc.malloc_desc.allocator_pid);
        memcheck_fail_alloc(guest_address);
        return;
    }

    if (!procdesc_is_executing(proc)) {
        desc.flags |= MDESC_FLAG_TRANSITION_ENTRY;
    }

    /* Copy thread's calling stack to the allocation descriptor. */
    thread = get_current_thread();
    desc.call_stack_count = thread->call_stack_count;
    if (desc.call_stack_count) {
        desc.call_stack = g_malloc(desc.call_stack_count * sizeof(target_ulong));
        if (desc.call_stack == NULL) {
            ME("memcheck: Unable to allocate %u bytes for the calling stack",
               desc.call_stack_count * sizeof(target_ulong));
            return;
        }
    }

    /* Thread's calling stack is in descending order (i.e. first entry in the
     * thread's stack is the most distant routine from the current one). On the
     * other hand, we keep calling stack entries in allocation descriptor in
     * assending order. */
    for (indx = 0; indx < thread->call_stack_count; indx++) {
        desc.call_stack[indx] =
           thread->call_stack[thread->call_stack_count - 1 - indx].call_address;
    }

    // Save malloc descriptor in the map.
    insert_res = procdesc_add_malloc(proc, &desc, &replaced);
    if (insert_res == RBT_MAP_RESULT_ENTRY_INSERTED) {
        // Invalidate TLB cache for the allocated block.
        if (memcheck_instrument_mmu) {
            invalidate_tlb_cache(desc.malloc_desc.ptr,
                                mallocdesc_get_alloc_end(&desc.malloc_desc));
        }
    } else if (insert_res == RBT_MAP_RESULT_ENTRY_REPLACED) {
        /* We don't expect to have another entry in the map that matches
         * inserting entry. This is an error condition for us, indicating
         * that we somehow lost track of memory allocations. */
        ME("memcheck: Duplicate allocation blocks:");
        if (VERBOSE_CHECK(memcheck)) {
            printf("   New block:\n");
            memcheck_dump_malloc_desc(&desc, 1, 1);
            printf("   Replaced block:\n");
            memcheck_dump_malloc_desc(&replaced, 1, 1);
        }
        if (replaced.call_stack != NULL) {
            g_free(replaced.call_stack);
        }
    } else {
        ME("memcheck: Unable to insert an entry to the allocation map:");
        if (VERBOSE_CHECK(memcheck)) {
            memcheck_dump_malloc_desc(&desc, 1, 1);
        }
        memcheck_fail_alloc(guest_address);
        return;
    }
}

void
memcheck_guest_free(target_ulong guest_address)
{
    MallocFree desc;
    MallocDescEx pulled;
    int pull_res;
    ProcDesc* proc;

    // Copy free descriptor from guest to emulator.
    memcheck_get_free_descriptor(&desc, guest_address);

    proc = get_process_from_pid(desc.free_pid);
    if (proc == NULL) {
        ME("memcheck: Unable to obtain process for pid=%u on free",
           desc.free_pid);
        memcheck_fail_free(guest_address);
        return;
    }

    // Pull matching entry from the map.
    pull_res = procdesc_pull_malloc(proc, desc.ptr, &pulled);
    if (pull_res) {
        av_invalid_pointer(proc, desc.ptr, 1);
        memcheck_fail_free(guest_address);
        return;
    }

    // Make sure that ptr has expected value
    if (desc.ptr != mallocdesc_get_user_ptr(&pulled.malloc_desc)) {
        if (trace_flags & TRACE_CHECK_INVALID_PTR_ENABLED) {
            printf("memcheck: Access violation is detected in process %s[pid=%u]:\n",
                   proc->image_path, proc->pid);
            printf("  INVALID POINTER 0x%08X is used in 'free' operation.\n"
                   "  This pointer is unexpected for 'free' operation, as allocation\n"
                   "  descriptor found for this pointer in the process' allocation map\n"
                   "  suggests that 0x%08X is the pointer to be used to free this block.\n"
                   "  Allocation descriptor matching the pointer:\n",
                   desc.ptr,
                   (uint32_t)mallocdesc_get_user_ptr(&pulled.malloc_desc));
            memcheck_dump_malloc_desc(&pulled, 1, 0);
        }
    }
    if (pulled.call_stack != NULL) {
        g_free(pulled.call_stack);
    }
}

void
memcheck_guest_query_malloc(target_ulong guest_address)
{
    MallocDescQuery qdesc;
    MallocDescEx* found;
    ProcDesc* proc;

    // Copy free descriptor from guest to emulator.
    memcheck_get_query_descriptor(&qdesc, guest_address);

    proc = get_process_from_pid(qdesc.query_pid);
    if (proc == NULL) {
        ME("memcheck: Unable to obtain process for pid=%u on query_%s",
           qdesc.query_pid, qdesc.routine == 1 ? "free" : "realloc");
        memcheck_fail_query(guest_address);
        return;
    }

    // Find allocation entry for the given address.
    found = procdesc_find_malloc(proc, qdesc.ptr);
    if (found == NULL) {
        av_invalid_pointer(proc, qdesc.ptr, qdesc.routine);
        memcheck_fail_query(guest_address);
        return;
    }

    // Copy allocation descriptor back to the guest's space.
    memcheck_set_malloc_descriptor(qdesc.desc, &found->malloc_desc);
}

void
memcheck_guest_print_str(target_ulong str) {
    char str_copy[4096];
    memcheck_get_guest_string(str_copy, str, sizeof(str_copy));
    printf("%s", str_copy);
}

/* Validates read operations, detected in __ldx_mmu routine.
 * This routine is called from __ldx_mmu wrapper implemented in
 * softmmu_template.h on condition that loading is occurring from user memory.
 * Param:
 *  addr - Virtual address in the guest space where memory is read.
 *  data_size - Size of the read.
 *  retaddr - Code address (in TB) that accesses memory.
 * Return:
 *  1 if TLB record for the accessed page should be invalidated in order to
 *  ensure that subsequent attempts to access data in this page will cause
 *  __ld/stx_mmu to be used. If memchecker is no longer interested in monitoring
 * access to this page, this routine returns 0.
 */
int
memcheck_validate_ld(target_ulong addr,
                     uint32_t data_size,
                     target_ulong retaddr)
{
    ProcDesc* proc;
    MallocDescEx* desc;

    int res = memcheck_common_access_validation(addr, data_size, &proc, &desc);
    if (res == -1) {
        av_access_violation(proc, desc, addr, data_size, 0, retaddr, 1);
        return 1;
    }

    /* Even though descriptor for the given address range has not been found,
     * we need to make sure that pages containing the given address range
     * don't contain other descriptors. */
    return res ? procdesc_contains_allocs(proc, addr, data_size) : 0;
}

/* Validates write operations, detected in __stx_mmu routine.
 * This routine is called from __stx_mmu wrapper implemented in
 * softmmu_template.h on condition that storing is occurring from user memory.
 * Param:
 *  addr - Virtual address in the guest space where memory is written.
 *  data_size - Size of the write.
 *  value - Value to be written. Note that we typecast all values to 64 bits,
 *      since this will fit all data sizes.
 *  retaddr - Code address (in TB) that accesses memory.
 * Return:
 *  1 if TLB record for the accessed page should be invalidated in order to
 *  ensure that subsequent attempts to access data in this page will cause
 *  __ld/stx_mmu to be used. If memchecker is no longer interested in monitoring
 * access to this page, this routine returns 0.
 */
int
memcheck_validate_st(target_ulong addr,
                     uint32_t data_size,
                     uint64_t value,
                     target_ulong retaddr)
{
    MallocDescEx* desc;
    ProcDesc* proc;

    int res = memcheck_common_access_validation(addr, data_size, &proc, &desc);
    if (res == -1) {
        av_access_violation(proc, desc, addr, data_size, value, retaddr, 0);
        return 1;
    }

    /* Even though descriptor for the given address range has not been found,
     * we need to make sure that pages containing the given address range
     * don't contain other descriptors. */
    return res ? procdesc_contains_allocs(proc, addr, data_size) : 0;
}

/* Checks if given address range in the context of the current process is under
 * surveillance.
 * Param:
 *  addr - Starting address of a range.
 *  size - Range size.
 * Return:
 *  boolean: 1 if address range contains memory that require access violation
 *  detection, or 0 if given address range is in no interest to the memchecker.
 */
int
memcheck_is_checked(target_ulong addr, uint32_t size) {
    return procdesc_contains_allocs(get_current_process(), addr, size) ? 1 : 0;
}
