aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/inferiors.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2007-07-17 12:51:41 +0000
committerDaniel Jacobowitz <drow@false.org>2007-07-17 12:51:41 +0000
commit255e7678a93693bd4d16cc3246442a1b8e11064e (patch)
treee30bf1ce55c5475d65bb16a04e840be2d61b8ab7 /gdb/gdbserver/inferiors.c
parenta8c50c1f557c99062f17be4a7b9d1c596771e4c1 (diff)
downloadgdb-255e7678a93693bd4d16cc3246442a1b8e11064e.zip
gdb-255e7678a93693bd4d16cc3246442a1b8e11064e.tar.gz
gdb-255e7678a93693bd4d16cc3246442a1b8e11064e.tar.bz2
2007-07-17 Pedro Alves <pedro_alves@portugalmail.pt>
Daniel Jacobowitz <dan@codesourcery.com> * config/i386/cygwin.mt (TDEPFILES): Add solib-target.o. * coff-pe-read.c (read_pe_exported_syms): Delete verbose printf. * NEWS: Mention gdbserver DLL support. * gdb.base/unload.c (dlopen, dlsym, dlclose, dlerror): Define for __WIN32__. (SHLIB_NAME): Delete definition. Always pass dlerror to fprintf. * gdb.base/unload.exp: Use shared library test routines. * inferiors.c (all_dlls, dlls_changed, get_dll): New. (add_thread): Minor cleanups. (clear_inferiors): Move lower in the file. Clear the DLL list. (free_one_dll, match_dll, loaded_dll, unloaded_dll, clear_list): New. * remote-utils.c (prepare_resume_reply): Check dlls_changed. (xml_escape_text): New. * server.c (handle_query): Handle qXfer:libraries:read. Report it for qSupported. (handle_v_cont): Report errors. (gdbserver_version): Update. (main): Correct size of own_buf. Do not report initial DLL events. * server.h (struct dll_info, all_dlls, dlls_changed, loaded_dll) (unloaded_dll, xml_escape_text): New. * win32-low.c (enum target_waitkind): Update comments. (win32_add_one_solib, get_image_name, winapi_EnumProcessModules) (winapi_GetModuleInformation, winapi_GetModuleFileNameExA) (win32_EnumProcessModules, win32_GetModuleInformation) (win32_GetModuleFileNameExA, load_psapi, psapi_get_dll_name) (winapi_CreateToolhelp32Snapshot, winapi_Module32First) (winapi_Module32Next, win32_CreateToolhelp32Snapshot) (win32_Module32First, win32_Module32Next, load_toolhelp) (toolhelp_get_dll_name, handle_load_dll, handle_unload_dll): New. (get_child_debug_event): Handle DLL events. (win32_wait): Likewise.
Diffstat (limited to 'gdb/gdbserver/inferiors.c')
-rw-r--r--gdb/gdbserver/inferiors.c93
1 files changed, 82 insertions, 11 deletions
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 6262d7e..c73bf45 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -33,10 +33,13 @@ struct thread_info
};
struct inferior_list all_threads;
+struct inferior_list all_dlls;
+int dlls_changed;
struct thread_info *current_inferior;
#define get_thread(inf) ((struct thread_info *)(inf))
+#define get_dll(inf) ((struct dll_info *)(inf))
void
add_inferior_to_list (struct inferior_list *list,
@@ -109,15 +112,14 @@ remove_inferior (struct inferior_list *list,
void
add_thread (unsigned long thread_id, void *target_data, unsigned int gdb_id)
{
- struct thread_info *new_thread
- = (struct thread_info *) malloc (sizeof (*new_thread));
+ struct thread_info *new_thread = malloc (sizeof (*new_thread));
memset (new_thread, 0, sizeof (*new_thread));
new_thread->entry.id = thread_id;
add_inferior_to_list (&all_threads, & new_thread->entry);
-
+
if (current_inferior == NULL)
current_inferior = new_thread;
@@ -187,14 +189,6 @@ remove_thread (struct thread_info *thread)
free_one_thread (&thread->entry);
}
-void
-clear_inferiors (void)
-{
- for_each_inferior (&all_threads, free_one_thread);
-
- all_threads.head = all_threads.tail = NULL;
-}
-
struct inferior_list_entry *
find_inferior (struct inferior_list *list,
int (*func) (struct inferior_list_entry *, void *), void *arg)
@@ -249,3 +243,80 @@ set_inferior_regcache_data (struct thread_info *inferior, void *data)
{
inferior->regcache_data = data;
}
+
+static void
+free_one_dll (struct inferior_list_entry *inf)
+{
+ struct dll_info *dll = get_dll (inf);
+ if (dll->name != NULL)
+ free (dll->name);
+ free (dll);
+}
+
+/* Find a DLL with the same name and/or base address. A NULL name in
+ the key is ignored; so is an all-ones base address. */
+
+static int
+match_dll (struct inferior_list_entry *inf, void *arg)
+{
+ struct dll_info *iter = (void *) inf;
+ struct dll_info *key = arg;
+
+ if (key->base_addr != ~(CORE_ADDR) 0
+ && iter->base_addr == key->base_addr)
+ return 1;
+ else if (key->name != NULL
+ && iter->name != NULL
+ && strcmp (key->name, iter->name) == 0)
+ return 1;
+
+ return 0;
+}
+
+/* Record a newly loaded DLL at BASE_ADDR. */
+
+void
+loaded_dll (const char *name, CORE_ADDR base_addr)
+{
+ struct dll_info *new_dll = malloc (sizeof (*new_dll));
+ memset (new_dll, 0, sizeof (*new_dll));
+
+ new_dll->entry.id = -1;
+
+ new_dll->name = strdup (name);
+ new_dll->base_addr = base_addr;
+
+ add_inferior_to_list (&all_dlls, &new_dll->entry);
+ dlls_changed = 1;
+}
+
+/* Record that the DLL with NAME and BASE_ADDR has been unloaded. */
+
+void
+unloaded_dll (const char *name, CORE_ADDR base_addr)
+{
+ struct dll_info *dll;
+ struct dll_info key_dll;
+
+ /* Be careful not to put the key DLL in any list. */
+ key_dll.name = (char *) name;
+ key_dll.base_addr = base_addr;
+
+ dll = (void *) find_inferior (&all_dlls, match_dll, &key_dll);
+ remove_inferior (&all_dlls, &dll->entry);
+ free_one_dll (&dll->entry);
+ dlls_changed = 1;
+}
+
+#define clear_list(LIST) \
+ do { (LIST)->head = (LIST)->tail = NULL; } while (0)
+
+void
+clear_inferiors (void)
+{
+ for_each_inferior (&all_threads, free_one_thread);
+ for_each_inferior (&all_dlls, free_one_dll);
+
+ clear_list (&all_threads);
+ clear_list (&all_dlls);
+}