• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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