| /* 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 ANDROID_QEMU_MEMCHECK_MEMCHECK_UTIL_H |
| #define ANDROID_QEMU_MEMCHECK_MEMCHECK_UTIL_H |
| |
| #include "android/qemu/memcheck/memcheck_common.h" |
| #include "elff/elff_api.h" |
| #include "cpu.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 // ANDROID_QEMU_MEMCHECK_MEMCHECK_UTIL_H |