aboutsummaryrefslogtreecommitdiffstats
path: root/memcheck/memcheck_proc_management.h
diff options
context:
space:
mode:
Diffstat (limited to 'memcheck/memcheck_proc_management.h')
-rw-r--r--memcheck/memcheck_proc_management.h327
1 files changed, 327 insertions, 0 deletions
diff --git a/memcheck/memcheck_proc_management.h b/memcheck/memcheck_proc_management.h
new file mode 100644
index 0000000..d5525b1
--- /dev/null
+++ b/memcheck/memcheck_proc_management.h
@@ -0,0 +1,327 @@
+/* Copyright (C) 2007-2010 The Android Open Source Project
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+*/
+
+/*
+ * Contains declarations of structures, routines, etc. related to process
+ * management in memchecker framework.
+ */
+
+#ifndef QEMU_MEMCHECK_MEMCHECK_PROC_MANAGEMENT_H
+#define QEMU_MEMCHECK_MEMCHECK_PROC_MANAGEMENT_H
+
+/* This file should compile iff qemu is built with memory checking
+ * configuration turned on. */
+#ifndef CONFIG_MEMCHECK
+#error CONFIG_MEMCHECK is not defined.
+#endif // CONFIG_MEMCHECK
+
+#include "sys-queue.h"
+#include "memcheck_common.h"
+#include "memcheck_malloc_map.h"
+#include "memcheck_mmrange_map.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// =============================================================================
+// Process management structures
+// =============================================================================
+
+/* Describes a process that is monitored by memchecker framework. */
+typedef struct ProcDesc {
+ /* Map of memory blocks allocated in context of this process. */
+ AllocMap alloc_map;
+
+ /* Map of memory mapped modules loaded in context of this process. */
+ MMRangeMap mmrange_map;
+
+ /* Descriptor's entry in the global process list. */
+ LIST_ENTRY(ProcDesc) global_entry;
+
+ /* List of threads running in context of this process. */
+ LIST_HEAD(threads, ThreadDesc) threads;
+
+ /* Path to the process' image file. */
+ char* image_path;
+
+ /* Process id. */
+ uint32_t pid;
+
+ /* Parent process id. */
+ uint32_t parent_pid;
+
+ /* Misc. process flags. See PROC_FLAG_XXX */
+ uint32_t flags;
+} ProcDesc;
+
+/* Process is executing. */
+#define PROC_FLAG_EXECUTING 0x00000001
+/* Process is exiting. */
+#define PROC_FLAG_EXITING 0x00000002
+/* ProcDesc->image_path has been replaced during process execution. */
+#define PROC_FLAG_IMAGE_PATH_REPLACED 0x00000004
+/* libc.so instance has been initialized for this process. */
+#define PROC_FLAG_LIBC_INITIALIZED 0x00000008
+
+/* Entry in the thread's calling stack array. */
+typedef struct ThreadCallStackEntry {
+ /* Guest PC where call has been made. */
+ target_ulong call_address;
+ /* Guest PC where call has been made, relative to the beginning of the
+ * mapped module that contains call_address. */
+ target_ulong call_address_rel;
+ /* Guest PC where call will return. */
+ target_ulong ret_address;
+ /* Guest PC where call will return, relative to the beginning of the
+ * mapped module that contains ret_address. */
+ target_ulong ret_address_rel;
+ /* Path to the image file of the module containing call_address. */
+ char* module_path;
+} ThreadCallStackEntry;
+
+/* Describes a thread that is monitored by memchecker framework. */
+typedef struct ThreadDesc {
+ /* Descriptor's entry in the global thread list. */
+ LIST_ENTRY(ThreadDesc) global_entry;
+
+ /* Descriptor's entry in the process' thread list. */
+ LIST_ENTRY(ThreadDesc) proc_entry;
+
+ /* Descriptor of the process this thread belongs to. */
+ ProcDesc* process;
+
+ /* Calling stack for this thread. */
+ ThreadCallStackEntry* call_stack;
+
+ /* Number of entries in the call_stack array. */
+ uint32_t call_stack_count;
+
+ /* Maximum number of entries that can fit into call_stack buffer. */
+ uint32_t call_stack_max;
+
+ /* Thread id. */
+ uint32_t tid;
+} ThreadDesc;
+
+// =============================================================================
+// Inlines
+// =============================================================================
+
+/* Checks if process has been forked, rather than created from a "fresh" PID.
+ * Param:
+ * proc - Descriptor for the process to check.
+ * Return:
+ * boolean: 1 if process has been forked, or 0 if it was
+ * created from a "fresh" PID.
+ */
+static inline int
+procdesc_is_forked(const ProcDesc* proc)
+{
+ return proc->parent_pid != 0;
+}
+
+/* Checks if process is executing.
+ * Param:
+ * proc - Descriptor for the process to check.
+ * Return:
+ * boolean: 1 if process is executing, or 0 if it is not executing.
+ */
+static inline int
+procdesc_is_executing(const ProcDesc* proc)
+{
+ return (proc->flags & PROC_FLAG_EXECUTING) != 0;
+}
+
+/* Checks if process is exiting.
+ * Param:
+ * proc - Descriptor for the process to check.
+ * Return:
+ * boolean: 1 if process is exiting, or 0 if it is still alive.
+ */
+static inline int
+procdesc_is_exiting(const ProcDesc* proc)
+{
+ return (proc->flags & PROC_FLAG_EXITING) != 0;
+}
+
+/* Checks if process has initialized its libc.so instance.
+ * Param:
+ * proc - Descriptor for the process to check.
+ * Return:
+ * boolean: 1 if process has initialized its libc.so instance, or 0 otherwise.
+ */
+static inline int
+procdesc_is_libc_initialized(const ProcDesc* proc)
+{
+ return (proc->flags & PROC_FLAG_LIBC_INITIALIZED) != 0;
+}
+
+/* Checks if process image path has been replaced.
+ * Param:
+ * proc - Descriptor for the process to check.
+ * Return:
+ * boolean: 1 if process image path has been replaced,
+ * or 0 if it was not replaced.
+ */
+static inline int
+procdesc_is_image_path_replaced(const ProcDesc* proc)
+{
+ return (proc->flags & PROC_FLAG_IMAGE_PATH_REPLACED) != 0;
+}
+
+// =============================================================================
+// Process management API
+// =============================================================================
+
+/* Gets thread descriptor for the current thread.
+ * Return:
+ * Found thread descriptor, or NULL if thread descriptor has not been found.
+ */
+ThreadDesc* get_current_thread(void);
+
+/* Initializes process management API. */
+void memcheck_init_proc_management(void);
+
+/* Gets process descriptor for the current process.
+ * Return:
+ * Process descriptor for the current process, or NULL, if process descriptor
+ * has not been found.
+ */
+ProcDesc* get_current_process(void);
+
+/* Finds process descriptor for a process id.
+ * Param:
+ * pid - Process ID to look up process descriptor for.
+ * Return:
+ * Process descriptor for the PID, or NULL, if process descriptor
+ * has not been found.
+ */
+ProcDesc* get_process_from_pid(uint32_t pid);
+
+/* Inserts new (or replaces existing) entry in the allocation descriptors map
+ * for the given process.
+ * See allocmap_insert for more information on this routine, its parameters
+ * and returning value.
+ * Param:
+ * proc - Process descriptor where to add new allocation entry info.
+ */
+static inline RBTMapResult
+procdesc_add_malloc(ProcDesc* proc,
+ const MallocDescEx* desc,
+ MallocDescEx* replaced)
+{
+ return allocmap_insert(&proc->alloc_map, desc, replaced);
+}
+
+/* Finds an entry in the allocation descriptors map for the given process,
+ * matching given address range.
+ * See allocmap_find for more information on this routine, its parameters
+ * and returning value.
+ * Param:
+ * proc - Process descriptor where to find an allocation entry.
+ */
+static inline MallocDescEx*
+procdesc_find_malloc_for_range(ProcDesc* proc,
+ target_ulong address,
+ uint32_t block_size)
+{
+ return allocmap_find(&proc->alloc_map, address, block_size);
+}
+
+/* Finds an entry in the allocation descriptors map for the given process,
+ * matching given address.
+ * See allocmap_find for more information on this routine, its parameters
+ * and returning value.
+ * Param:
+ * proc - Process descriptor where to find an allocation entry.
+ */
+static inline MallocDescEx*
+procdesc_find_malloc(ProcDesc* proc, target_ulong address)
+{
+ return procdesc_find_malloc_for_range(proc, address, 1);
+}
+
+/* Pulls (finds and removes) an entry from the allocation descriptors map for
+ * the given process, matching given address.
+ * See allocmap_pull for more information on this routine, its parameters
+ * and returning value.
+ * Param:
+ * proc - Process descriptor where to pull an allocation entry from.
+ */
+static inline int
+procdesc_pull_malloc(ProcDesc* proc, target_ulong address, MallocDescEx* pulled)
+{
+ return allocmap_pull(&proc->alloc_map, address, pulled);
+}
+
+/* Empties allocation descriptors map for the process.
+ * Param:
+ * proc - Process to empty allocation map for.
+ * Return:
+ * Number of entries deleted from the allocation map.
+ */
+static inline int
+procdesc_empty_alloc_map(ProcDesc* proc)
+{
+ return allocmap_empty(&proc->alloc_map);
+}
+
+/* Finds mmapping entry for the given address in the given process.
+ * Param:
+ * proc - Descriptor of the process where to look for an entry.
+ * addr - Address in the guest space for which to find an entry.
+ * Return:
+ * Mapped entry, or NULL if no mapping for teh given address exists in the
+ * process address space.
+ */
+static inline MMRangeDesc*
+procdesc_find_mapentry(const ProcDesc* proc, target_ulong addr)
+{
+ return mmrangemap_find(&proc->mmrange_map, addr, addr + 1);
+}
+
+/* Gets module descriptor for the given address.
+ * Param:
+ * proc - Descriptor of the process where to look for a module.
+ * addr - Address in the guest space for which to find a module descriptor.
+ * Return:
+ * module descriptor for the module containing the given address, or NULL if no
+ * such module has been found in the process' map of mmaped modules.
+ */
+static inline const MMRangeDesc*
+procdesc_get_range_desc(const ProcDesc* proc, target_ulong addr)
+{
+ return procdesc_find_mapentry(proc, addr);
+}
+
+/* Gets name of the module mmaped in context of the given process for the
+ * given address.
+ * Param:
+ * proc - Descriptor of the process where to look for a module.
+ * addr - Address in the guest space for which to find a module.
+ * Return:
+ * Image path to the module containing the given address, or NULL if no such
+ * module has been found in the process' map of mmaped modules.
+ */
+static inline const char*
+procdesc_get_module_path(const ProcDesc* proc, target_ulong addr)
+{
+ MMRangeDesc* rdesc = procdesc_find_mapentry(proc, addr);
+ return rdesc != NULL ? rdesc->path : NULL;
+}
+
+#ifdef __cplusplus
+}; /* end of extern "C" */
+#endif
+
+#endif // QEMU_MEMCHECK_MEMCHECK_PROC_MANAGEMENT_H