| OLD | NEW |
| 1 /* Inferior process information for the remote server for GDB. | 1 /* Inferior process information for the remote server for GDB. |
| 2 Copyright (C) 2002, 2005, 2007-2012 Free Software Foundation, Inc. | 2 Copyright (C) 2002, 2005, 2007-2012 Free Software Foundation, Inc. |
| 3 | 3 |
| 4 Contributed by MontaVista Software. | 4 Contributed by MontaVista Software. |
| 5 | 5 |
| 6 This file is part of GDB. | 6 This file is part of GDB. |
| 7 | 7 |
| 8 This program is free software; you can redistribute it and/or modify | 8 This program is free software; you can redistribute it and/or modify |
| 9 it under the terms of the GNU General Public License as published by | 9 it under the terms of the GNU General Public License as published by |
| 10 the Free Software Foundation; either version 3 of the License, or | 10 the Free Software Foundation; either version 3 of the License, or |
| 11 (at your option) any later version. | 11 (at your option) any later version. |
| 12 | 12 |
| 13 This program is distributed in the hope that it will be useful, | 13 This program is distributed in the hope that it will be useful, |
| 14 but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 GNU General Public License for more details. | 16 GNU General Public License for more details. |
| 17 | 17 |
| 18 You should have received a copy of the GNU General Public License | 18 You should have received a copy of the GNU General Public License |
| 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 20 | 20 |
| 21 #include <stdlib.h> | 21 #include <stdlib.h> |
| 22 | 22 |
| 23 #include "server.h" | 23 #include "server.h" |
| 24 #include "gdbthread.h" |
| 24 | 25 |
| 25 struct inferior_list all_processes; | 26 struct inferior_list all_processes; |
| 26 struct inferior_list all_threads; | 27 struct inferior_list all_threads; |
| 27 struct inferior_list all_dlls; | |
| 28 int dlls_changed; | |
| 29 | 28 |
| 30 struct thread_info *current_inferior; | 29 struct thread_info *current_inferior; |
| 31 | 30 |
| 32 #define get_thread(inf) ((struct thread_info *)(inf)) | 31 #define get_thread(inf) ((struct thread_info *)(inf)) |
| 33 #define get_dll(inf) ((struct dll_info *)(inf)) | |
| 34 | 32 |
| 35 void | 33 void |
| 36 add_inferior_to_list (struct inferior_list *list, | 34 add_inferior_to_list (struct inferior_list *list, |
| 37 struct inferior_list_entry *new_inferior) | 35 struct inferior_list_entry *new_inferior) |
| 38 { | 36 { |
| 39 new_inferior->next = NULL; | 37 new_inferior->next = NULL; |
| 40 if (list->tail != NULL) | 38 if (list->tail != NULL) |
| 41 list->tail->next = new_inferior; | 39 list->tail->next = new_inferior; |
| 42 else | 40 else |
| 43 list->head = new_inferior; | 41 list->head = new_inferior; |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 { | 219 { |
| 222 return inferior->regcache_data; | 220 return inferior->regcache_data; |
| 223 } | 221 } |
| 224 | 222 |
| 225 void | 223 void |
| 226 set_inferior_regcache_data (struct thread_info *inferior, void *data) | 224 set_inferior_regcache_data (struct thread_info *inferior, void *data) |
| 227 { | 225 { |
| 228 inferior->regcache_data = data; | 226 inferior->regcache_data = data; |
| 229 } | 227 } |
| 230 | 228 |
| 231 static void | |
| 232 free_one_dll (struct inferior_list_entry *inf) | |
| 233 { | |
| 234 struct dll_info *dll = get_dll (inf); | |
| 235 if (dll->name != NULL) | |
| 236 free (dll->name); | |
| 237 free (dll); | |
| 238 } | |
| 239 | |
| 240 /* Find a DLL with the same name and/or base address. A NULL name in | |
| 241 the key is ignored; so is an all-ones base address. */ | |
| 242 | |
| 243 static int | |
| 244 match_dll (struct inferior_list_entry *inf, void *arg) | |
| 245 { | |
| 246 struct dll_info *iter = (void *) inf; | |
| 247 struct dll_info *key = arg; | |
| 248 | |
| 249 if (key->base_addr != ~(CORE_ADDR) 0 | |
| 250 && iter->base_addr == key->base_addr) | |
| 251 return 1; | |
| 252 else if (key->name != NULL | |
| 253 && iter->name != NULL | |
| 254 && strcmp (key->name, iter->name) == 0) | |
| 255 return 1; | |
| 256 | |
| 257 return 0; | |
| 258 } | |
| 259 | |
| 260 /* Record a newly loaded DLL at BASE_ADDR. */ | |
| 261 | |
| 262 void | |
| 263 loaded_dll (const char *name, CORE_ADDR base_addr) | |
| 264 { | |
| 265 struct dll_info *new_dll = xmalloc (sizeof (*new_dll)); | |
| 266 memset (new_dll, 0, sizeof (*new_dll)); | |
| 267 | |
| 268 new_dll->entry.id = minus_one_ptid; | |
| 269 | |
| 270 new_dll->name = xstrdup (name); | |
| 271 new_dll->base_addr = base_addr; | |
| 272 | |
| 273 add_inferior_to_list (&all_dlls, &new_dll->entry); | |
| 274 dlls_changed = 1; | |
| 275 } | |
| 276 | |
| 277 /* Record that the DLL with NAME and BASE_ADDR has been unloaded. */ | |
| 278 | |
| 279 void | |
| 280 unloaded_dll (const char *name, CORE_ADDR base_addr) | |
| 281 { | |
| 282 struct dll_info *dll; | |
| 283 struct dll_info key_dll; | |
| 284 | |
| 285 /* Be careful not to put the key DLL in any list. */ | |
| 286 key_dll.name = (char *) name; | |
| 287 key_dll.base_addr = base_addr; | |
| 288 | |
| 289 dll = (void *) find_inferior (&all_dlls, match_dll, &key_dll); | |
| 290 | |
| 291 if (dll == NULL) | |
| 292 /* For some inferiors we might get unloaded_dll events without having | |
| 293 a corresponding loaded_dll. In that case, the dll cannot be found | |
| 294 in ALL_DLL, and there is nothing further for us to do. | |
| 295 | |
| 296 This has been observed when running 32bit executables on Windows64 | |
| 297 (i.e. through WOW64, the interface between the 32bits and 64bits | |
| 298 worlds). In that case, the inferior always does some strange | |
| 299 unloading of unnamed dll. */ | |
| 300 return; | |
| 301 else | |
| 302 { | |
| 303 /* DLL has been found so remove the entry and free associated | |
| 304 resources. */ | |
| 305 remove_inferior (&all_dlls, &dll->entry); | |
| 306 free_one_dll (&dll->entry); | |
| 307 dlls_changed = 1; | |
| 308 } | |
| 309 } | |
| 310 | |
| 311 #define clear_list(LIST) \ | 229 #define clear_list(LIST) \ |
| 312 do { (LIST)->head = (LIST)->tail = NULL; } while (0) | 230 do { (LIST)->head = (LIST)->tail = NULL; } while (0) |
| 313 | 231 |
| 314 void | 232 void |
| 315 clear_inferiors (void) | 233 clear_inferiors (void) |
| 316 { | 234 { |
| 317 for_each_inferior (&all_threads, free_one_thread); | 235 for_each_inferior (&all_threads, free_one_thread); |
| 318 for_each_inferior (&all_dlls, free_one_dll); | 236 clear_list (&all_threads); |
| 319 | 237 |
| 320 clear_list (&all_threads); | 238 clear_dlls (); |
| 321 clear_list (&all_dlls); | |
| 322 | 239 |
| 323 current_inferior = NULL; | 240 current_inferior = NULL; |
| 324 } | 241 } |
| 325 | 242 |
| 326 /* Two utility functions for a truly degenerate inferior_list: a simple | |
| 327 PID listing. */ | |
| 328 | |
| 329 void | |
| 330 add_pid_to_list (struct inferior_list *list, unsigned long pid) | |
| 331 { | |
| 332 struct inferior_list_entry *new_entry; | |
| 333 | |
| 334 new_entry = xmalloc (sizeof (struct inferior_list_entry)); | |
| 335 new_entry->id = pid_to_ptid (pid); | |
| 336 add_inferior_to_list (list, new_entry); | |
| 337 } | |
| 338 | |
| 339 int | |
| 340 pull_pid_from_list (struct inferior_list *list, unsigned long pid) | |
| 341 { | |
| 342 struct inferior_list_entry *new_entry; | |
| 343 | |
| 344 new_entry = find_inferior_id (list, pid_to_ptid (pid)); | |
| 345 if (new_entry == NULL) | |
| 346 return 0; | |
| 347 else | |
| 348 { | |
| 349 remove_inferior (list, new_entry); | |
| 350 free (new_entry); | |
| 351 return 1; | |
| 352 } | |
| 353 } | |
| 354 | |
| 355 struct process_info * | 243 struct process_info * |
| 356 add_process (int pid, int attached) | 244 add_process (int pid, int attached) |
| 357 { | 245 { |
| 358 struct process_info *process; | 246 struct process_info *process; |
| 359 | 247 |
| 360 process = xcalloc (1, sizeof (*process)); | 248 process = xcalloc (1, sizeof (*process)); |
| 361 | 249 |
| 362 process->head.id = pid_to_ptid (pid); | 250 process->head.id = pid_to_ptid (pid); |
| 363 process->attached = attached; | 251 process->attached = attached; |
| 364 | 252 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 } | 323 } |
| 436 | 324 |
| 437 struct process_info * | 325 struct process_info * |
| 438 current_process (void) | 326 current_process (void) |
| 439 { | 327 { |
| 440 if (current_inferior == NULL) | 328 if (current_inferior == NULL) |
| 441 fatal ("Current inferior requested, but current_inferior is NULL\n"); | 329 fatal ("Current inferior requested, but current_inferior is NULL\n"); |
| 442 | 330 |
| 443 return get_thread_process (current_inferior); | 331 return get_thread_process (current_inferior); |
| 444 } | 332 } |
| OLD | NEW |