/* 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 declarations of utility routines for memchecker framework. */ #ifndef QEMU_MEMCHECK_MEMCHECK_UTIL_H #define QEMU_MEMCHECK_MEMCHECK_UTIL_H #include "memcheck_common.h" #include "elff/elff_api.h" #include "exec.h" #ifdef __cplusplus extern "C" { #endif // ============================================================================= // Transfering data between guest and emulator address spaces. // ============================================================================= /* Copies buffer residing in the guest's virtual address space to a buffer * in the emulator's address space. * Param: * guest_address - Address of the bufer in guest's virtual address space. * qemu_address - Address of the bufer in the emulator's address space. * buffer_size - Byte size of the guest's buffer. */ void memcheck_get_guest_buffer(void* qemu_address, target_ulong guest_address, size_t buffer_size); /* Copies buffer residing in the emulator's address space to a buffer in the * guest's virtual address space. * Param: * qemu_address - Address of the bufer in the emulator's address space. * guest_address - Address of the bufer in guest's virtual address space. * buffer_size - Byte size of the emualtor's buffer. */ void memcheck_set_guest_buffer(target_ulong guest_address, const void* qemu_address, size_t buffer_size); /* Copies zero-terminated string residing in the guest's virtual address space * to a string buffer in emulator's address space. * Param: * qemu_str - Address of the string bufer in the emulator's address space. * guest_str - Address of the string in guest's virtual address space. * qemu_buffer_size - Size of the emulator's string buffer. * Return * Length of the string that has been copied. */ size_t memcheck_get_guest_string(char* qemu_str, target_ulong guest_str, size_t qemu_buffer_size); /* Copies zero-terminated string residing in the guest's kernel address space * to a string buffer in emulator's address space. * Param: * qemu_str - Address of the string bufer in the emulator's address space. * guest_str - Address of the string in guest's kernel address space. * qemu_buffer_size - Size of the emulator's string buffer. * Return * Length of the string that has been copied. */ size_t memcheck_get_guest_kernel_string(char* qemu_str, target_ulong guest_str, size_t qemu_buffer_size); // ============================================================================= // Helpers for transfering memory allocation information. // ============================================================================= /* Copies memory allocation descriptor from the guest's address space to the * emulator's memory. * Param: * qemu_address - Descriptor address in the emulator's address space where to * copy descriptor. * guest_address - Descriptor address in the guest's address space. */ static inline void memcheck_get_malloc_descriptor(MallocDesc* qemu_address, target_ulong guest_address) { memcheck_get_guest_buffer(qemu_address, guest_address, sizeof(MallocDesc)); } /* Copies memory allocation descriptor from the emulator's memory to the guest's * address space. * Param: * guest_address - Descriptor address in the guest's address space. * qemu_address - Descriptor address in the emulator's address space where to * copy descriptor. */ static inline void memcheck_set_malloc_descriptor(target_ulong guest_address, const MallocDesc* qemu_address) { memcheck_set_guest_buffer(guest_address, qemu_address, sizeof(MallocDesc)); } /* Copies memory free descriptor from the guest's address space to the * emulator's memory. * Param: * qemu_address - Descriptor address in the emulator's address space where to * copy descriptor. * guest_address - Descriptor address in the guest's address space. */ static inline void memcheck_get_free_descriptor(MallocFree* qemu_address, target_ulong guest_address) { memcheck_get_guest_buffer(qemu_address, guest_address, sizeof(MallocFree)); } /* Copies memory allocation query descriptor from the guest's address space to * the emulator's memory. * Param: * guest_address - Descriptor address in the guest's address space. * qemu_address - Descriptor address in the emulator's address space where to * copy descriptor. */ static inline void memcheck_get_query_descriptor(MallocDescQuery* qemu_address, target_ulong guest_address) { memcheck_get_guest_buffer(qemu_address, guest_address, sizeof(MallocDescQuery)); } /* Fails allocation request (TRACE_DEV_REG_MALLOC event). * Allocation request failure is reported by zeroing 'libc_pid' filed in the * allocation descriptor in the guest's address space. * Param: * guest_address - Allocation descriptor address in the guest's address space, * where to record failure. */ void memcheck_fail_alloc(target_ulong guest_address); /* Fails free request (TRACE_DEV_REG_FREE_PTR event). * Free request failure is reported by zeroing 'libc_pid' filed in the free * descriptor in the guest's address space. * Param: * guest_address - Free descriptor address in the guest's address space, where * to record failure. */ void memcheck_fail_free(target_ulong guest_address); /* Fails memory allocation query request (TRACE_DEV_REG_QUERY_MALLOC event). * Query request failure is reported by zeroing 'libc_pid' filed in the query * descriptor in the guest's address space. * Param: * guest_address - Query descriptor address in the guest's address space, where * to record failure. */ void memcheck_fail_query(target_ulong guest_address); // ============================================================================= // Misc. utility routines. // ============================================================================= /* Converts PC address in the translated block to a corresponded PC address in * the guest address space. * Param: * tb_pc - PC address in the translated block. * Return: * Corresponded PC address in the guest address space on success, or NULL if * conversion has failed. */ static inline target_ulong memcheck_tpc_to_gpc(target_ulong tb_pc) { const TranslationBlock* tb = tb_find_pc(tb_pc); return tb != NULL ? tb_search_guest_pc_from_tb_pc(tb, tb_pc) : 0; } /* Invalidates TLB table pages that contain given memory range. * This routine is called after new entry is inserted into allocation map, so * every access to the allocated block will cause __ld/__stx_mmu to be called. * Param: * start - Beginning of the allocated block to invalidate pages for. * end - End of (past one byte after) the allocated block to invalidate pages * for. */ void invalidate_tlb_cache(target_ulong start, target_ulong end); /* Gets routine, file path and line number information for a PC address in the * given module. * Param: * abs_pc - PC address. * rdesc - Mapped memory range descriptor for the module containing abs_pc. * info - Upon successful return will contain routine, file path and line * information for the given PC address in the given module. * NOTE: Pathnames, saved into this structure are contained in mapped * sections of the symbols file for the module addressed by module_path. * Thus, pathnames are accessible only while elff_handle returned from this * routine remains opened. * NOTE: each successful call to this routine requires the caller to call * elff_free_pc_address_info for Elf_AddressInfo structure. * elff_handle - Upon successful return will contain a handle to the ELFF API * that wraps symbols file for the module, addressed by module_path. The * handle must remain opened for as long as pathnames in the info structure * are accessed, and must be eventually closed via call to elff_close. * Return: * 0 on success, 1, if symbols file for the module has not been found, or -1 on * other failures. If a failure is returned from this routine content of info * and elff_handle parameters is undefined. */ int memcheck_get_address_info(target_ulong abs_pc, const MMRangeDesc* rdesc, Elf_AddressInfo* info, ELFF_HANDLE* elff_handle); /* Dumps content of an allocation descriptor to stdout. * Param desc - Allocation descriptor to dump. * print_flags - If 1, flags field of the descriptor will be dumped to stdout. * If 0, flags filed will not be dumped. * print_proc_info - If 1, allocator's process information for the descriptor * will be dumped to stdout. If 0, allocator's process information will * not be dumped. */ void memcheck_dump_malloc_desc(const MallocDescEx* desc, int print_flags, int print_proc_info); #ifdef __cplusplus }; /* end of extern "C" */ #endif #endif // QEMU_MEMCHECK_MEMCHECK_UTIL_H