Home | History | Annotate | Download | only in memcheck
      1 /* Copyright (C) 2007-2010 The Android Open Source Project
      2 **
      3 ** This software is licensed under the terms of the GNU General Public
      4 ** License version 2, as published by the Free Software Foundation, and
      5 ** may be copied, distributed, and modified under those terms.
      6 **
      7 ** This program is distributed in the hope that it will be useful,
      8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 ** GNU General Public License for more details.
     11 */
     12 
     13 /*
     14  * Contains declarations of utility routines for memchecker framework.
     15  */
     16 
     17 #ifndef QEMU_MEMCHECK_MEMCHECK_UTIL_H
     18 #define QEMU_MEMCHECK_MEMCHECK_UTIL_H
     19 
     20 /* This file should compile iff qemu is built with memory checking
     21  * configuration turned on. */
     22 #ifndef CONFIG_MEMCHECK
     23 #error CONFIG_MEMCHECK is not defined.
     24 #endif  // CONFIG_MEMCHECK
     25 
     26 #include "memcheck_common.h"
     27 #include "elff_api.h"
     28 
     29 #ifdef __cplusplus
     30 extern "C" {
     31 #endif
     32 
     33 // =============================================================================
     34 // Transfering data between guest and emulator address spaces.
     35 // =============================================================================
     36 
     37 /* Copies buffer residing in the guest's virtual address space to a buffer
     38  * in the emulator's address space.
     39  * Param:
     40  *  guest_address - Address of the bufer in guest's virtual address space.
     41  *  qemu_address - Address of the bufer in the emulator's address space.
     42  *  buffer_size - Byte size of the guest's buffer.
     43  */
     44 void memcheck_get_guest_buffer(void* qemu_address,
     45                                target_ulong guest_address,
     46                                size_t buffer_size);
     47 
     48 /* Copies buffer residing in the emulator's address space to a buffer in the
     49  * guest's virtual address space.
     50  * Param:
     51  *  qemu_address - Address of the bufer in the emulator's address space.
     52  *  guest_address - Address of the bufer in guest's virtual address space.
     53  *  buffer_size - Byte size of the emualtor's buffer.
     54  */
     55 void memcheck_set_guest_buffer(target_ulong guest_address,
     56                                const void* qemu_address,
     57                                size_t buffer_size);
     58 
     59 /* Copies zero-terminated string residing in the guest's virtual address space
     60  * to a string buffer in emulator's address space.
     61  * Param:
     62  *  qemu_str - Address of the string bufer in the emulator's address space.
     63  *  guest_str - Address of the string in guest's virtual address space.
     64  *  qemu_buffer_size - Size of the emulator's string buffer.
     65  * Return
     66  *  Length of the string that has been copied.
     67  */
     68 size_t memcheck_get_guest_string(char* qemu_str,
     69                                  target_ulong guest_str,
     70                                  size_t qemu_buffer_size);
     71 
     72 /* Copies zero-terminated string residing in the guest's kernel address space
     73  * to a string buffer in emulator's address space.
     74  * Param:
     75  *  qemu_str - Address of the string bufer in the emulator's address space.
     76  *  guest_str - Address of the string in guest's kernel address space.
     77  *  qemu_buffer_size - Size of the emulator's string buffer.
     78  * Return
     79  *  Length of the string that has been copied.
     80  */
     81 size_t memcheck_get_guest_kernel_string(char* qemu_str,
     82                                         target_ulong guest_str,
     83                                         size_t qemu_buffer_size);
     84 
     85 // =============================================================================
     86 // Helpers for transfering memory allocation information.
     87 // =============================================================================
     88 
     89 /* Copies memory allocation descriptor from the guest's address space to the
     90  * emulator's memory.
     91  * Param:
     92  *  qemu_address - Descriptor address in the emulator's address space where to
     93  *      copy descriptor.
     94  *  guest_address - Descriptor address in the guest's address space.
     95  */
     96 static inline void
     97 memcheck_get_malloc_descriptor(MallocDesc* qemu_address,
     98                                target_ulong guest_address)
     99 {
    100     memcheck_get_guest_buffer(qemu_address, guest_address, sizeof(MallocDesc));
    101 }
    102 
    103 /* Copies memory allocation descriptor from the emulator's memory to the guest's
    104  * address space.
    105  * Param:
    106  *  guest_address - Descriptor address in the guest's address space.
    107  *  qemu_address - Descriptor address in the emulator's address space where to
    108  *  copy descriptor.
    109  */
    110 static inline void
    111 memcheck_set_malloc_descriptor(target_ulong guest_address,
    112                                const MallocDesc* qemu_address)
    113 {
    114     memcheck_set_guest_buffer(guest_address, qemu_address, sizeof(MallocDesc));
    115 }
    116 
    117 /* Copies memory free descriptor from the guest's address space to the
    118  * emulator's memory.
    119  * Param:
    120  *  qemu_address - Descriptor address in the emulator's address space where to
    121  *      copy descriptor.
    122  *  guest_address - Descriptor address in the guest's address space.
    123  */
    124 static inline void
    125 memcheck_get_free_descriptor(MallocFree* qemu_address,
    126                              target_ulong guest_address)
    127 {
    128     memcheck_get_guest_buffer(qemu_address, guest_address, sizeof(MallocFree));
    129 }
    130 
    131 /* Copies memory allocation query descriptor from the guest's address space to
    132  * the emulator's memory.
    133  * Param:
    134  *  guest_address - Descriptor address in the guest's address space.
    135  *  qemu_address - Descriptor address in the emulator's address space where to
    136  *      copy descriptor.
    137  */
    138 static inline void
    139 memcheck_get_query_descriptor(MallocDescQuery* qemu_address,
    140                               target_ulong guest_address)
    141 {
    142     memcheck_get_guest_buffer(qemu_address, guest_address,
    143                               sizeof(MallocDescQuery));
    144 }
    145 
    146 /* Fails allocation request (TRACE_DEV_REG_MALLOC event).
    147  * Allocation request failure is reported by zeroing 'libc_pid' filed in the
    148  * allocation descriptor in the guest's address space.
    149  * Param:
    150  *  guest_address - Allocation descriptor address in the guest's address space,
    151  *      where to record failure.
    152  */
    153 void memcheck_fail_alloc(target_ulong guest_address);
    154 
    155 /* Fails free request (TRACE_DEV_REG_FREE_PTR event).
    156  * Free request failure is reported by zeroing 'libc_pid' filed in the free
    157  * descriptor in the guest's address space.
    158  * Param:
    159  *  guest_address - Free descriptor address in the guest's address space, where
    160  *      to record failure.
    161  */
    162 void memcheck_fail_free(target_ulong guest_address);
    163 
    164 /* Fails memory allocation query request (TRACE_DEV_REG_QUERY_MALLOC event).
    165  * Query request failure is reported by zeroing 'libc_pid' filed in the query
    166  * descriptor in the guest's address space.
    167  * Param:
    168  *  guest_address - Query descriptor address in the guest's address space, where
    169  *      to record failure.
    170  */
    171 void memcheck_fail_query(target_ulong guest_address);
    172 
    173 // =============================================================================
    174 // Misc. utility routines.
    175 // =============================================================================
    176 
    177 /* Converts PC address in the translated block to a corresponded PC address in
    178  * the guest address space.
    179  * Param:
    180  *  tb_pc - PC address in the translated block.
    181  * Return:
    182  *  Corresponded PC address in the guest address space on success, or NULL if
    183  *  conversion has failed.
    184  */
    185 static inline target_ulong
    186 memcheck_tpc_to_gpc(target_ulong tb_pc)
    187 {
    188     const TranslationBlock* tb = tb_find_pc(tb_pc);
    189     return tb != NULL ? tb_search_guest_pc_from_tb_pc(tb, tb_pc) : 0;
    190 }
    191 
    192 /* Invalidates TLB table pages that contain given memory range.
    193  * This routine is called after new entry is inserted into allocation map, so
    194  * every access to the allocated block will cause __ld/__stx_mmu to be called.
    195  * Param:
    196  *  start - Beginning of the allocated block to invalidate pages for.
    197  *  end - End of (past one byte after) the allocated block to invalidate pages
    198  *      for.
    199  */
    200 void invalidate_tlb_cache(target_ulong start, target_ulong end);
    201 
    202 /* Gets routine, file path and line number information for a PC address in the
    203  * given module.
    204  * Param:
    205  *  abs_pc - PC address.
    206  *  rdesc - Mapped memory range descriptor for the module containing abs_pc.
    207  *  info - Upon successful return will contain routine, file path and line
    208  *      information for the given PC address in the given module.
    209  *      NOTE: Pathnames, saved into this structure are contained in mapped
    210  *      sections of the symbols file for the module addressed by module_path.
    211  *      Thus, pathnames are accessible only while elff_handle returned from this
    212  *      routine remains opened.
    213  *      NOTE: each successful call to this routine requires the caller to call
    214  *      elff_free_pc_address_info for Elf_AddressInfo structure.
    215  *  elff_handle - Upon successful return will contain a handle to the ELFF API
    216  *      that wraps symbols file for the module, addressed by module_path. The
    217  *      handle must remain opened for as long as pathnames in the info structure
    218  *      are accessed, and must be eventually closed via call to elff_close.
    219  * Return:
    220  *  0 on success, 1, if symbols file for the module has not been found, or -1 on
    221  *  other failures. If a failure is returned from this routine content of info
    222  *  and elff_handle parameters is undefined.
    223  */
    224 int memcheck_get_address_info(target_ulong abs_pc,
    225                               const MMRangeDesc* rdesc,
    226                               Elf_AddressInfo* info,
    227                               ELFF_HANDLE* elff_handle);
    228 
    229 /* Dumps content of an allocation descriptor to stdout.
    230  * Param desc - Allocation descriptor to dump.
    231  * print_flags - If 1, flags field of the descriptor will be dumped to stdout.
    232  *      If 0, flags filed will not be dumped.
    233  * print_proc_info - If 1, allocator's process information for the descriptor
    234  *      will be dumped to stdout. If 0, allocator's process information will
    235  *      not be dumped.
    236  */
    237 void memcheck_dump_malloc_desc(const MallocDescEx* desc,
    238                                int print_flags,
    239                                int print_proc_info);
    240 
    241 #ifdef __cplusplus
    242 };  /* end of extern "C" */
    243 #endif
    244 
    245 #endif  // QEMU_MEMCHECK_MEMCHECK_UTIL_H
    246