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