From bf4c19f73effc1808b4093463e68a7c161b9503a Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Thu, 16 Feb 2012 10:38:15 +0000 Subject: [PATCH] gdb/gdbserver/ * inferiors.c: Move code to ... * dll.c: .... here. New. * server.h: Declare clear_dlls. * Makefile.in (SFILES): Add dll.c. (OBS): Add dll.o (dll.o): New rule. --- gdb/gdbserver/ChangeLog | 9 ++++ gdb/gdbserver/Makefile.in | 4 +- gdb/gdbserver/dll.c | 110 ++++++++++++++++++++++++++++++++++++++ gdb/gdbserver/inferiors.c | 88 +----------------------------- gdb/gdbserver/server.h | 1 + 5 files changed, 125 insertions(+), 87 deletions(-) create mode 100644 gdb/gdbserver/dll.c diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 0d5e6b43a2..3208e3152d 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,12 @@ +2012-02-16 Yao Qi + + * inferiors.c: Move code to ... + * dll.c: .... here. New. + * server.h: Declare clear_dlls. + * Makefile.in (SFILES): Add dll.c. + (OBS): Add dll.o + (dll.o): New rule. + 2012-02-11 Yao Qi * server.c: (handle_monitor_command): Add a new parameter diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 6ccf5ae15a..c6a8bff7cb 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -104,7 +104,7 @@ INTERNAL_LDFLAGS = $(LDFLAGS) @RDYNAMIC@ # All source files that go into linking GDB remote server. -SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c \ +SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \ $(srcdir)/mem-break.c $(srcdir)/proc-service.c \ $(srcdir)/proc-service.list $(srcdir)/regcache.c \ $(srcdir)/remote-utils.c $(srcdir)/server.c $(srcdir)/target.c \ @@ -138,6 +138,7 @@ OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \ utils.o version.o \ mem-break.o hostio.o event-loop.o tracepoint.o \ xml-utils.o common-utils.o ptid.o buffer.o \ + dll.o \ $(XML_BUILTIN) \ $(DEPFILES) $(LIBOBJS) GDBREPLAY_OBS = gdbreplay.o version.o @@ -401,6 +402,7 @@ thread-db.o: thread-db.c $(server_h) $(linux_low_h) $(gdb_proc_service_h) \ tracepoint.o: tracepoint.c $(server_h) $(srcdir)/../common/ax.def utils.o: utils.c $(server_h) gdbreplay.o: gdbreplay.c config.h +dll.o: dll.c $(server_h) signals.o: ../common/signals.c $(server_h) $(signals_def) $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER diff --git a/gdb/gdbserver/dll.c b/gdb/gdbserver/dll.c new file mode 100644 index 0000000000..cb6fb43d01 --- /dev/null +++ b/gdb/gdbserver/dll.c @@ -0,0 +1,110 @@ +/* Copyright (C) 2002, 2005, 2007-2012 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + 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. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "server.h" + +#define get_dll(inf) ((struct dll_info *)(inf)) + +struct inferior_list all_dlls; +int dlls_changed; + +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 = xmalloc (sizeof (*new_dll)); + memset (new_dll, 0, sizeof (*new_dll)); + + new_dll->entry.id = minus_one_ptid; + + new_dll->name = xstrdup (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); + + if (dll == NULL) + /* For some inferiors we might get unloaded_dll events without having + a corresponding loaded_dll. In that case, the dll cannot be found + in ALL_DLL, and there is nothing further for us to do. + + This has been observed when running 32bit executables on Windows64 + (i.e. through WOW64, the interface between the 32bits and 64bits + worlds). In that case, the inferior always does some strange + unloading of unnamed dll. */ + return; + else + { + /* DLL has been found so remove the entry and free associated + resources. */ + remove_inferior (&all_dlls, &dll->entry); + free_one_dll (&dll->entry); + dlls_changed = 1; + } +} + +void +clear_dlls (void) +{ + for_each_inferior (&all_dlls, free_one_dll); + all_dlls.head = all_dlls.tail = NULL; +} diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c index cac9878e93..ba5cb10c29 100644 --- a/gdb/gdbserver/inferiors.c +++ b/gdb/gdbserver/inferiors.c @@ -24,13 +24,10 @@ struct inferior_list all_processes; 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, @@ -228,86 +225,6 @@ 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 = xmalloc (sizeof (*new_dll)); - memset (new_dll, 0, sizeof (*new_dll)); - - new_dll->entry.id = minus_one_ptid; - - new_dll->name = xstrdup (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); - - if (dll == NULL) - /* For some inferiors we might get unloaded_dll events without having - a corresponding loaded_dll. In that case, the dll cannot be found - in ALL_DLL, and there is nothing further for us to do. - - This has been observed when running 32bit executables on Windows64 - (i.e. through WOW64, the interface between the 32bits and 64bits - worlds). In that case, the inferior always does some strange - unloading of unnamed dll. */ - return; - else - { - /* DLL has been found so remove the entry and free associated - resources. */ - 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) @@ -315,10 +232,9 @@ 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); + + clear_dlls (); current_inferior = NULL; } diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index 5c798c85a4..d3b4463a2a 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -236,6 +236,7 @@ extern struct inferior_list all_processes; extern struct inferior_list all_threads; extern struct inferior_list all_dlls; extern int dlls_changed; +extern void clear_dlls (void); void add_inferior_to_list (struct inferior_list *list, struct inferior_list_entry *new_inferior); -- 2.34.1