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