OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [gdb/] [gdbserver/] [inferiors.c] - Blame information for rev 841

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Inferior process information for the remote server for GDB.
2
   Copyright (C) 2002, 2005, 2007, 2008, 2009, 2010
3
   Free Software Foundation, Inc.
4
 
5
   Contributed by MontaVista Software.
6
 
7
   This file is part of GDB.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
 
22
#include <stdlib.h>
23
 
24
#include "server.h"
25
 
26
struct inferior_list all_processes;
27
struct inferior_list all_threads;
28
struct inferior_list all_dlls;
29
int dlls_changed;
30
 
31
struct thread_info *current_inferior;
32
 
33
 
34
/* Oft used ptids */
35
ptid_t null_ptid;
36
ptid_t minus_one_ptid;
37
 
38
/* Create a ptid given the necessary PID, LWP, and TID components.  */
39
 
40
ptid_t
41
ptid_build (int pid, long lwp, long tid)
42
{
43
  ptid_t ptid;
44
 
45
  ptid.pid = pid;
46
  ptid.lwp = lwp;
47
  ptid.tid = tid;
48
  return ptid;
49
}
50
 
51
/* Create a ptid from just a pid.  */
52
 
53
ptid_t
54
pid_to_ptid (int pid)
55
{
56
  return ptid_build (pid, 0, 0);
57
}
58
 
59
/* Fetch the pid (process id) component from a ptid.  */
60
 
61
int
62
ptid_get_pid (ptid_t ptid)
63
{
64
  return ptid.pid;
65
}
66
 
67
/* Fetch the lwp (lightweight process) component from a ptid.  */
68
 
69
long
70
ptid_get_lwp (ptid_t ptid)
71
{
72
  return ptid.lwp;
73
}
74
 
75
/* Fetch the tid (thread id) component from a ptid.  */
76
 
77
long
78
ptid_get_tid (ptid_t ptid)
79
{
80
  return ptid.tid;
81
}
82
 
83
/* ptid_equal() is used to test equality of two ptids.  */
84
 
85
int
86
ptid_equal (ptid_t ptid1, ptid_t ptid2)
87
{
88
  return (ptid1.pid == ptid2.pid
89
          && ptid1.lwp == ptid2.lwp
90
          && ptid1.tid == ptid2.tid);
91
}
92
 
93
/* Return true if this ptid represents a process.  */
94
 
95
int
96
ptid_is_pid (ptid_t ptid)
97
{
98
  if (ptid_equal (minus_one_ptid, ptid))
99
    return 0;
100
  if (ptid_equal (null_ptid, ptid))
101
    return 0;
102
 
103
  return (ptid_get_pid (ptid) != 0
104
          && ptid_get_lwp (ptid) == 0
105
          && ptid_get_tid (ptid) == 0);
106
}
107
 
108
#define get_thread(inf) ((struct thread_info *)(inf))
109
#define get_dll(inf) ((struct dll_info *)(inf))
110
 
111
void
112
add_inferior_to_list (struct inferior_list *list,
113
                      struct inferior_list_entry *new_inferior)
114
{
115
  new_inferior->next = NULL;
116
  if (list->tail != NULL)
117
    list->tail->next = new_inferior;
118
  else
119
    list->head = new_inferior;
120
  list->tail = new_inferior;
121
}
122
 
123
/* Invoke ACTION for each inferior in LIST.  */
124
 
125
void
126
for_each_inferior (struct inferior_list *list,
127
                   void (*action) (struct inferior_list_entry *))
128
{
129
  struct inferior_list_entry *cur = list->head, *next;
130
 
131
  while (cur != NULL)
132
    {
133
      next = cur->next;
134
      (*action) (cur);
135
      cur = next;
136
    }
137
}
138
 
139
void
140
remove_inferior (struct inferior_list *list,
141
                 struct inferior_list_entry *entry)
142
{
143
  struct inferior_list_entry **cur;
144
 
145
  if (list->head == entry)
146
    {
147
      list->head = entry->next;
148
      if (list->tail == entry)
149
        list->tail = list->head;
150
      return;
151
    }
152
 
153
  cur = &list->head;
154
  while (*cur && (*cur)->next != entry)
155
    cur = &(*cur)->next;
156
 
157
  if (*cur == NULL)
158
    return;
159
 
160
  (*cur)->next = entry->next;
161
 
162
  if (list->tail == entry)
163
    list->tail = *cur;
164
}
165
 
166
void
167
add_thread (ptid_t thread_id, void *target_data)
168
{
169
  struct thread_info *new_thread = xmalloc (sizeof (*new_thread));
170
 
171
  memset (new_thread, 0, sizeof (*new_thread));
172
 
173
  new_thread->entry.id = thread_id;
174
  new_thread->last_resume_kind = resume_continue;
175
  new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
176
 
177
  add_inferior_to_list (&all_threads, & new_thread->entry);
178
 
179
  if (current_inferior == NULL)
180
    current_inferior = new_thread;
181
 
182
  new_thread->target_data = target_data;
183
  set_inferior_regcache_data (new_thread, new_register_cache ());
184
}
185
 
186
ptid_t
187
thread_id_to_gdb_id (ptid_t thread_id)
188
{
189
  struct inferior_list_entry *inf = all_threads.head;
190
 
191
  while (inf != NULL)
192
    {
193
      if (ptid_equal (inf->id, thread_id))
194
        return thread_id;
195
      inf = inf->next;
196
    }
197
 
198
  return null_ptid;
199
}
200
 
201
ptid_t
202
thread_to_gdb_id (struct thread_info *thread)
203
{
204
  return thread->entry.id;
205
}
206
 
207
struct thread_info *
208
find_thread_ptid (ptid_t ptid)
209
{
210
  struct inferior_list_entry *inf = all_threads.head;
211
 
212
  while (inf != NULL)
213
    {
214
      struct thread_info *thread = get_thread (inf);
215
      if (ptid_equal (thread->entry.id, ptid))
216
        return thread;
217
      inf = inf->next;
218
    }
219
 
220
  return NULL;
221
}
222
 
223
ptid_t
224
gdb_id_to_thread_id (ptid_t gdb_id)
225
{
226
  struct thread_info *thread = find_thread_ptid (gdb_id);
227
 
228
  return thread ? thread->entry.id : null_ptid;
229
}
230
 
231
static void
232
free_one_thread (struct inferior_list_entry *inf)
233
{
234
  struct thread_info *thread = get_thread (inf);
235
  free_register_cache (inferior_regcache_data (thread));
236
  free (thread);
237
}
238
 
239
void
240
remove_thread (struct thread_info *thread)
241
{
242
  remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
243
  free_one_thread (&thread->entry);
244
}
245
 
246
/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
247
   returns non-zero.  If no entry is found then return NULL.  */
248
 
249
struct inferior_list_entry *
250
find_inferior (struct inferior_list *list,
251
               int (*func) (struct inferior_list_entry *, void *), void *arg)
252
{
253
  struct inferior_list_entry *inf = list->head;
254
 
255
  while (inf != NULL)
256
    {
257
      struct inferior_list_entry *next;
258
 
259
      next = inf->next;
260
      if ((*func) (inf, arg))
261
        return inf;
262
      inf = next;
263
    }
264
 
265
  return NULL;
266
}
267
 
268
struct inferior_list_entry *
269
find_inferior_id (struct inferior_list *list, ptid_t id)
270
{
271
  struct inferior_list_entry *inf = list->head;
272
 
273
  while (inf != NULL)
274
    {
275
      if (ptid_equal (inf->id, id))
276
        return inf;
277
      inf = inf->next;
278
    }
279
 
280
  return NULL;
281
}
282
 
283
void *
284
inferior_target_data (struct thread_info *inferior)
285
{
286
  return inferior->target_data;
287
}
288
 
289
void
290
set_inferior_target_data (struct thread_info *inferior, void *data)
291
{
292
  inferior->target_data = data;
293
}
294
 
295
void *
296
inferior_regcache_data (struct thread_info *inferior)
297
{
298
  return inferior->regcache_data;
299
}
300
 
301
void
302
set_inferior_regcache_data (struct thread_info *inferior, void *data)
303
{
304
  inferior->regcache_data = data;
305
}
306
 
307
static void
308
free_one_dll (struct inferior_list_entry *inf)
309
{
310
  struct dll_info *dll = get_dll (inf);
311
  if (dll->name != NULL)
312
    free (dll->name);
313
  free (dll);
314
}
315
 
316
/* Find a DLL with the same name and/or base address.  A NULL name in
317
   the key is ignored; so is an all-ones base address.  */
318
 
319
static int
320
match_dll (struct inferior_list_entry *inf, void *arg)
321
{
322
  struct dll_info *iter = (void *) inf;
323
  struct dll_info *key = arg;
324
 
325
  if (key->base_addr != ~(CORE_ADDR) 0
326
      && iter->base_addr == key->base_addr)
327
    return 1;
328
  else if (key->name != NULL
329
           && iter->name != NULL
330
           && strcmp (key->name, iter->name) == 0)
331
    return 1;
332
 
333
  return 0;
334
}
335
 
336
/* Record a newly loaded DLL at BASE_ADDR.  */
337
 
338
void
339
loaded_dll (const char *name, CORE_ADDR base_addr)
340
{
341
  struct dll_info *new_dll = xmalloc (sizeof (*new_dll));
342
  memset (new_dll, 0, sizeof (*new_dll));
343
 
344
  new_dll->entry.id = minus_one_ptid;
345
 
346
  new_dll->name = xstrdup (name);
347
  new_dll->base_addr = base_addr;
348
 
349
  add_inferior_to_list (&all_dlls, &new_dll->entry);
350
  dlls_changed = 1;
351
}
352
 
353
/* Record that the DLL with NAME and BASE_ADDR has been unloaded.  */
354
 
355
void
356
unloaded_dll (const char *name, CORE_ADDR base_addr)
357
{
358
  struct dll_info *dll;
359
  struct dll_info key_dll;
360
 
361
  /* Be careful not to put the key DLL in any list.  */
362
  key_dll.name = (char *) name;
363
  key_dll.base_addr = base_addr;
364
 
365
  dll = (void *) find_inferior (&all_dlls, match_dll, &key_dll);
366
 
367
  if (dll == NULL)
368
    /* For some inferiors we might get unloaded_dll events without having
369
       a corresponding loaded_dll.  In that case, the dll cannot be found
370
       in ALL_DLL, and there is nothing further for us to do.
371
 
372
       This has been observed when running 32bit executables on Windows64
373
       (i.e. through WOW64, the interface between the 32bits and 64bits
374
       worlds).  In that case, the inferior always does some strange
375
       unloading of unnamed dll.  */
376
    return;
377
  else
378
    {
379
      /* DLL has been found so remove the entry and free associated
380
         resources.  */
381
      remove_inferior (&all_dlls, &dll->entry);
382
      free_one_dll (&dll->entry);
383
      dlls_changed = 1;
384
    }
385
}
386
 
387
#define clear_list(LIST) \
388
  do { (LIST)->head = (LIST)->tail = NULL; } while (0)
389
 
390
void
391
clear_inferiors (void)
392
{
393
  for_each_inferior (&all_threads, free_one_thread);
394
  for_each_inferior (&all_dlls, free_one_dll);
395
 
396
  clear_list (&all_threads);
397
  clear_list (&all_dlls);
398
 
399
  current_inferior = NULL;
400
}
401
 
402
/* Two utility functions for a truly degenerate inferior_list: a simple
403
   PID listing.  */
404
 
405
void
406
add_pid_to_list (struct inferior_list *list, unsigned long pid)
407
{
408
  struct inferior_list_entry *new_entry;
409
 
410
  new_entry = xmalloc (sizeof (struct inferior_list_entry));
411
  new_entry->id = pid_to_ptid (pid);
412
  add_inferior_to_list (list, new_entry);
413
}
414
 
415
int
416
pull_pid_from_list (struct inferior_list *list, unsigned long pid)
417
{
418
  struct inferior_list_entry *new_entry;
419
 
420
  new_entry = find_inferior_id (list, pid_to_ptid (pid));
421
  if (new_entry == NULL)
422
    return 0;
423
  else
424
    {
425
      remove_inferior (list, new_entry);
426
      free (new_entry);
427
      return 1;
428
    }
429
}
430
 
431
struct process_info *
432
add_process (int pid, int attached)
433
{
434
  struct process_info *process;
435
 
436
  process = xcalloc (1, sizeof (*process));
437
 
438
  process->head.id = pid_to_ptid (pid);
439
  process->attached = attached;
440
 
441
  add_inferior_to_list (&all_processes, &process->head);
442
 
443
  return process;
444
}
445
 
446
/* Remove a process from the common process list and free the memory
447
   allocated for it.
448
   The caller is responsible for freeing private data first.  */
449
 
450
void
451
remove_process (struct process_info *process)
452
{
453
  clear_symbol_cache (&process->symbol_cache);
454
  free_all_breakpoints (process);
455
  remove_inferior (&all_processes, &process->head);
456
  free (process);
457
}
458
 
459
struct process_info *
460
find_process_pid (int pid)
461
{
462
  return (struct process_info *)
463
    find_inferior_id (&all_processes, pid_to_ptid (pid));
464
}
465
 
466
/* Return non-zero if INF, a struct process_info, was started by us,
467
   i.e. not attached to.  */
468
 
469
static int
470
started_inferior_callback (struct inferior_list_entry *entry, void *args)
471
{
472
  struct process_info *process = (struct process_info *) entry;
473
 
474
  return ! process->attached;
475
}
476
 
477
/* Return non-zero if there are any inferiors that we have created
478
   (as opposed to attached-to).  */
479
 
480
int
481
have_started_inferiors_p (void)
482
{
483
  return (find_inferior (&all_processes, started_inferior_callback, NULL)
484
          != NULL);
485
}
486
 
487
/* Return non-zero if INF, a struct process_info, was attached to.  */
488
 
489
static int
490
attached_inferior_callback (struct inferior_list_entry *entry, void *args)
491
{
492
  struct process_info *process = (struct process_info *) entry;
493
 
494
  return process->attached;
495
}
496
 
497
/* Return non-zero if there are any inferiors that we have attached to.  */
498
 
499
int
500
have_attached_inferiors_p (void)
501
{
502
  return (find_inferior (&all_processes, attached_inferior_callback, NULL)
503
          != NULL);
504
}
505
 
506
struct process_info *
507
get_thread_process (struct thread_info *thread)
508
{
509
  int pid = ptid_get_pid (thread->entry.id);
510
  return find_process_pid (pid);
511
}
512
 
513
struct process_info *
514
current_process (void)
515
{
516
  if (current_inferior == NULL)
517
    fatal ("Current inferior requested, but current_inferior is NULL\n");
518
 
519
  return get_thread_process (current_inferior);
520
}
521
 
522
void
523
initialize_inferiors (void)
524
{
525
  null_ptid = ptid_build (0, 0, 0);
526
  minus_one_ptid = ptid_build (-1, 0, 0);
527
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.