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 structures, routines, etc. related to process 15 * management in memchecker framework. 16 */ 17 18 #ifndef QEMU_MEMCHECK_MEMCHECK_PROC_MANAGEMENT_H 19 #define QEMU_MEMCHECK_MEMCHECK_PROC_MANAGEMENT_H 20 21 #include "qemu-queue.h" 22 #include "memcheck_common.h" 23 #include "memcheck_malloc_map.h" 24 #include "memcheck_mmrange_map.h" 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 // ============================================================================= 31 // Process management structures 32 // ============================================================================= 33 34 /* Describes a process that is monitored by memchecker framework. */ 35 typedef struct ProcDesc { 36 /* Map of memory blocks allocated in context of this process. */ 37 AllocMap alloc_map; 38 39 /* Map of memory mapped modules loaded in context of this process. */ 40 MMRangeMap mmrange_map; 41 42 /* Descriptor's entry in the global process list. */ 43 QLIST_ENTRY(ProcDesc) global_entry; 44 45 /* List of threads running in context of this process. */ 46 QLIST_HEAD(threads, ThreadDesc) threads; 47 48 /* Path to the process' image file. */ 49 char* image_path; 50 51 /* Process id. */ 52 uint32_t pid; 53 54 /* Parent process id. */ 55 uint32_t parent_pid; 56 57 /* Misc. process flags. See PROC_FLAG_XXX */ 58 uint32_t flags; 59 } ProcDesc; 60 61 /* Process is executing. */ 62 #define PROC_FLAG_EXECUTING 0x00000001 63 /* Process is exiting. */ 64 #define PROC_FLAG_EXITING 0x00000002 65 /* ProcDesc->image_path has been replaced during process execution. */ 66 #define PROC_FLAG_IMAGE_PATH_REPLACED 0x00000004 67 /* libc.so instance has been initialized for this process. */ 68 #define PROC_FLAG_LIBC_INITIALIZED 0x00000008 69 70 /* Entry in the thread's calling stack array. */ 71 typedef struct ThreadCallStackEntry { 72 /* Guest PC where call has been made. */ 73 target_ulong call_address; 74 /* Guest PC where call has been made, relative to the beginning of the 75 * mapped module that contains call_address. */ 76 target_ulong call_address_rel; 77 /* Guest PC where call will return. */ 78 target_ulong ret_address; 79 /* Guest PC where call will return, relative to the beginning of the 80 * mapped module that contains ret_address. */ 81 target_ulong ret_address_rel; 82 /* Path to the image file of the module containing call_address. */ 83 char* module_path; 84 } ThreadCallStackEntry; 85 86 /* Describes a thread that is monitored by memchecker framework. */ 87 typedef struct ThreadDesc { 88 /* Descriptor's entry in the global thread list. */ 89 QLIST_ENTRY(ThreadDesc) global_entry; 90 91 /* Descriptor's entry in the process' thread list. */ 92 QLIST_ENTRY(ThreadDesc) proc_entry; 93 94 /* Descriptor of the process this thread belongs to. */ 95 ProcDesc* process; 96 97 /* Calling stack for this thread. */ 98 ThreadCallStackEntry* call_stack; 99 100 /* Number of entries in the call_stack array. */ 101 uint32_t call_stack_count; 102 103 /* Maximum number of entries that can fit into call_stack buffer. */ 104 uint32_t call_stack_max; 105 106 /* Thread id. */ 107 uint32_t tid; 108 } ThreadDesc; 109 110 // ============================================================================= 111 // Inlines 112 // ============================================================================= 113 114 /* Checks if process has been forked, rather than created from a "fresh" PID. 115 * Param: 116 * proc - Descriptor for the process to check. 117 * Return: 118 * boolean: 1 if process has been forked, or 0 if it was 119 * created from a "fresh" PID. 120 */ 121 static inline int 122 procdesc_is_forked(const ProcDesc* proc) 123 { 124 return proc->parent_pid != 0; 125 } 126 127 /* Checks if process is executing. 128 * Param: 129 * proc - Descriptor for the process to check. 130 * Return: 131 * boolean: 1 if process is executing, or 0 if it is not executing. 132 */ 133 static inline int 134 procdesc_is_executing(const ProcDesc* proc) 135 { 136 return (proc->flags & PROC_FLAG_EXECUTING) != 0; 137 } 138 139 /* Checks if process is exiting. 140 * Param: 141 * proc - Descriptor for the process to check. 142 * Return: 143 * boolean: 1 if process is exiting, or 0 if it is still alive. 144 */ 145 static inline int 146 procdesc_is_exiting(const ProcDesc* proc) 147 { 148 return (proc->flags & PROC_FLAG_EXITING) != 0; 149 } 150 151 /* Checks if process has initialized its libc.so instance. 152 * Param: 153 * proc - Descriptor for the process to check. 154 * Return: 155 * boolean: 1 if process has initialized its libc.so instance, or 0 otherwise. 156 */ 157 static inline int 158 procdesc_is_libc_initialized(const ProcDesc* proc) 159 { 160 return (proc->flags & PROC_FLAG_LIBC_INITIALIZED) != 0; 161 } 162 163 /* Checks if process image path has been replaced. 164 * Param: 165 * proc - Descriptor for the process to check. 166 * Return: 167 * boolean: 1 if process image path has been replaced, 168 * or 0 if it was not replaced. 169 */ 170 static inline int 171 procdesc_is_image_path_replaced(const ProcDesc* proc) 172 { 173 return (proc->flags & PROC_FLAG_IMAGE_PATH_REPLACED) != 0; 174 } 175 176 // ============================================================================= 177 // Process management API 178 // ============================================================================= 179 180 /* Gets thread descriptor for the current thread. 181 * Return: 182 * Found thread descriptor, or NULL if thread descriptor has not been found. 183 */ 184 ThreadDesc* get_current_thread(void); 185 186 /* Initializes process management API. */ 187 void memcheck_init_proc_management(void); 188 189 /* Gets process descriptor for the current process. 190 * Return: 191 * Process descriptor for the current process, or NULL, if process descriptor 192 * has not been found. 193 */ 194 ProcDesc* get_current_process(void); 195 196 /* Finds process descriptor for a process id. 197 * Param: 198 * pid - Process ID to look up process descriptor for. 199 * Return: 200 * Process descriptor for the PID, or NULL, if process descriptor 201 * has not been found. 202 */ 203 ProcDesc* get_process_from_pid(uint32_t pid); 204 205 /* Inserts new (or replaces existing) entry in the allocation descriptors map 206 * for the given process. 207 * See allocmap_insert for more information on this routine, its parameters 208 * and returning value. 209 * Param: 210 * proc - Process descriptor where to add new allocation entry info. 211 */ 212 static inline RBTMapResult 213 procdesc_add_malloc(ProcDesc* proc, 214 const MallocDescEx* desc, 215 MallocDescEx* replaced) 216 { 217 return allocmap_insert(&proc->alloc_map, desc, replaced); 218 } 219 220 /* Finds an entry in the allocation descriptors map for the given process, 221 * matching given address range. 222 * See allocmap_find for more information on this routine, its parameters 223 * and returning value. 224 * Param: 225 * proc - Process descriptor where to find an allocation entry. 226 */ 227 static inline MallocDescEx* 228 procdesc_find_malloc_for_range(ProcDesc* proc, 229 target_ulong address, 230 uint32_t block_size) 231 { 232 return allocmap_find(&proc->alloc_map, address, block_size); 233 } 234 235 /* Finds an entry in the allocation descriptors map for the given process, 236 * matching given address. 237 * See allocmap_find for more information on this routine, its parameters 238 * and returning value. 239 * Param: 240 * proc - Process descriptor where to find an allocation entry. 241 */ 242 static inline MallocDescEx* 243 procdesc_find_malloc(ProcDesc* proc, target_ulong address) 244 { 245 return procdesc_find_malloc_for_range(proc, address, 1); 246 } 247 248 /* Pulls (finds and removes) an entry from the allocation descriptors map for 249 * the given process, matching given address. 250 * See allocmap_pull for more information on this routine, its parameters 251 * and returning value. 252 * Param: 253 * proc - Process descriptor where to pull an allocation entry from. 254 */ 255 static inline int 256 procdesc_pull_malloc(ProcDesc* proc, target_ulong address, MallocDescEx* pulled) 257 { 258 return allocmap_pull(&proc->alloc_map, address, pulled); 259 } 260 261 /* Empties allocation descriptors map for the process. 262 * Param: 263 * proc - Process to empty allocation map for. 264 * Return: 265 * Number of entries deleted from the allocation map. 266 */ 267 static inline int 268 procdesc_empty_alloc_map(ProcDesc* proc) 269 { 270 return allocmap_empty(&proc->alloc_map); 271 } 272 273 /* Finds mmapping entry for the given address in the given process. 274 * Param: 275 * proc - Descriptor of the process where to look for an entry. 276 * addr - Address in the guest space for which to find an entry. 277 * Return: 278 * Mapped entry, or NULL if no mapping for teh given address exists in the 279 * process address space. 280 */ 281 static inline MMRangeDesc* 282 procdesc_find_mapentry(const ProcDesc* proc, target_ulong addr) 283 { 284 return mmrangemap_find(&proc->mmrange_map, addr, addr + 1); 285 } 286 287 /* Gets module descriptor for the given address. 288 * Param: 289 * proc - Descriptor of the process where to look for a module. 290 * addr - Address in the guest space for which to find a module descriptor. 291 * Return: 292 * module descriptor for the module containing the given address, or NULL if no 293 * such module has been found in the process' map of mmaped modules. 294 */ 295 static inline const MMRangeDesc* 296 procdesc_get_range_desc(const ProcDesc* proc, target_ulong addr) 297 { 298 return procdesc_find_mapentry(proc, addr); 299 } 300 301 /* Gets name of the module mmaped in context of the given process for the 302 * given address. 303 * Param: 304 * proc - Descriptor of the process where to look for a module. 305 * addr - Address in the guest space for which to find a module. 306 * Return: 307 * Image path to the module containing the given address, or NULL if no such 308 * module has been found in the process' map of mmaped modules. 309 */ 310 static inline const char* 311 procdesc_get_module_path(const ProcDesc* proc, target_ulong addr) 312 { 313 MMRangeDesc* rdesc = procdesc_find_mapentry(proc, addr); 314 return rdesc != NULL ? rdesc->path : NULL; 315 } 316 317 #ifdef __cplusplus 318 }; /* end of extern "C" */ 319 #endif 320 321 #endif // QEMU_MEMCHECK_MEMCHECK_PROC_MANAGEMENT_H 322