xref: /openbsd-src/gnu/usr.bin/binutils/gdb/gdbserver/inferiors.c (revision b725ae7711052a2233e31a66fefb8a752c388d7a)
1*b725ae77Skettenis /* Inferior process information for the remote server for GDB.
2*b725ae77Skettenis    Copyright 2002
3*b725ae77Skettenis    Free Software Foundation, Inc.
4*b725ae77Skettenis 
5*b725ae77Skettenis    Contributed by MontaVista Software.
6*b725ae77Skettenis 
7*b725ae77Skettenis    This file is part of GDB.
8*b725ae77Skettenis 
9*b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
10*b725ae77Skettenis    it under the terms of the GNU General Public License as published by
11*b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
12*b725ae77Skettenis    (at your option) any later version.
13*b725ae77Skettenis 
14*b725ae77Skettenis    This program is distributed in the hope that it will be useful,
15*b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
16*b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17*b725ae77Skettenis    GNU General Public License for more details.
18*b725ae77Skettenis 
19*b725ae77Skettenis    You should have received a copy of the GNU General Public License
20*b725ae77Skettenis    along with this program; if not, write to the Free Software
21*b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
22*b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
23*b725ae77Skettenis 
24*b725ae77Skettenis #include <stdlib.h>
25*b725ae77Skettenis 
26*b725ae77Skettenis #include "server.h"
27*b725ae77Skettenis 
28*b725ae77Skettenis struct thread_info
29*b725ae77Skettenis {
30*b725ae77Skettenis   struct inferior_list_entry entry;
31*b725ae77Skettenis   void *target_data;
32*b725ae77Skettenis   void *regcache_data;
33*b725ae77Skettenis };
34*b725ae77Skettenis 
35*b725ae77Skettenis struct inferior_list all_threads;
36*b725ae77Skettenis 
37*b725ae77Skettenis struct thread_info *current_inferior;
38*b725ae77Skettenis 
39*b725ae77Skettenis #define get_thread(inf) ((struct thread_info *)(inf))
40*b725ae77Skettenis 
41*b725ae77Skettenis void
add_inferior_to_list(struct inferior_list * list,struct inferior_list_entry * new_inferior)42*b725ae77Skettenis add_inferior_to_list (struct inferior_list *list,
43*b725ae77Skettenis 		      struct inferior_list_entry *new_inferior)
44*b725ae77Skettenis {
45*b725ae77Skettenis   new_inferior->next = NULL;
46*b725ae77Skettenis   if (list->tail != NULL)
47*b725ae77Skettenis     list->tail->next = new_inferior;
48*b725ae77Skettenis   else
49*b725ae77Skettenis     list->head = new_inferior;
50*b725ae77Skettenis   list->tail = new_inferior;
51*b725ae77Skettenis }
52*b725ae77Skettenis 
53*b725ae77Skettenis void
for_each_inferior(struct inferior_list * list,void (* action)(struct inferior_list_entry *))54*b725ae77Skettenis for_each_inferior (struct inferior_list *list,
55*b725ae77Skettenis 		   void (*action) (struct inferior_list_entry *))
56*b725ae77Skettenis {
57*b725ae77Skettenis   struct inferior_list_entry *cur = list->head, *next;
58*b725ae77Skettenis 
59*b725ae77Skettenis   while (cur != NULL)
60*b725ae77Skettenis     {
61*b725ae77Skettenis       next = cur->next;
62*b725ae77Skettenis       (*action) (cur);
63*b725ae77Skettenis       cur = next;
64*b725ae77Skettenis     }
65*b725ae77Skettenis }
66*b725ae77Skettenis 
67*b725ae77Skettenis void
change_inferior_id(struct inferior_list * list,int new_id)68*b725ae77Skettenis change_inferior_id (struct inferior_list *list,
69*b725ae77Skettenis 		    int new_id)
70*b725ae77Skettenis {
71*b725ae77Skettenis   if (list->head != list->tail)
72*b725ae77Skettenis     error ("tried to change thread ID after multiple threads are created");
73*b725ae77Skettenis 
74*b725ae77Skettenis   list->head->id = new_id;
75*b725ae77Skettenis }
76*b725ae77Skettenis 
77*b725ae77Skettenis void
remove_inferior(struct inferior_list * list,struct inferior_list_entry * entry)78*b725ae77Skettenis remove_inferior (struct inferior_list *list,
79*b725ae77Skettenis 		 struct inferior_list_entry *entry)
80*b725ae77Skettenis {
81*b725ae77Skettenis   struct inferior_list_entry **cur;
82*b725ae77Skettenis 
83*b725ae77Skettenis   if (list->head == entry)
84*b725ae77Skettenis     {
85*b725ae77Skettenis       list->head = entry->next;
86*b725ae77Skettenis       if (list->tail == entry)
87*b725ae77Skettenis 	list->tail = list->head;
88*b725ae77Skettenis       return;
89*b725ae77Skettenis     }
90*b725ae77Skettenis 
91*b725ae77Skettenis   cur = &list->head;
92*b725ae77Skettenis   while (*cur && (*cur)->next != entry)
93*b725ae77Skettenis     cur = &(*cur)->next;
94*b725ae77Skettenis 
95*b725ae77Skettenis   if (*cur == NULL)
96*b725ae77Skettenis     return;
97*b725ae77Skettenis 
98*b725ae77Skettenis   (*cur)->next = entry->next;
99*b725ae77Skettenis 
100*b725ae77Skettenis   if (list->tail == entry)
101*b725ae77Skettenis     list->tail = *cur;
102*b725ae77Skettenis }
103*b725ae77Skettenis 
104*b725ae77Skettenis void
add_thread(int thread_id,void * target_data)105*b725ae77Skettenis add_thread (int thread_id, void *target_data)
106*b725ae77Skettenis {
107*b725ae77Skettenis   struct thread_info *new_thread
108*b725ae77Skettenis     = (struct thread_info *) malloc (sizeof (*new_thread));
109*b725ae77Skettenis 
110*b725ae77Skettenis   memset (new_thread, 0, sizeof (*new_thread));
111*b725ae77Skettenis 
112*b725ae77Skettenis   new_thread->entry.id = thread_id;
113*b725ae77Skettenis 
114*b725ae77Skettenis   add_inferior_to_list (&all_threads, & new_thread->entry);
115*b725ae77Skettenis 
116*b725ae77Skettenis   if (current_inferior == NULL)
117*b725ae77Skettenis     current_inferior = new_thread;
118*b725ae77Skettenis 
119*b725ae77Skettenis   new_thread->target_data = target_data;
120*b725ae77Skettenis   set_inferior_regcache_data (new_thread, new_register_cache ());
121*b725ae77Skettenis }
122*b725ae77Skettenis 
123*b725ae77Skettenis static void
free_one_thread(struct inferior_list_entry * inf)124*b725ae77Skettenis free_one_thread (struct inferior_list_entry *inf)
125*b725ae77Skettenis {
126*b725ae77Skettenis   struct thread_info *thread = get_thread (inf);
127*b725ae77Skettenis   free_register_cache (inferior_regcache_data (thread));
128*b725ae77Skettenis   free (thread);
129*b725ae77Skettenis }
130*b725ae77Skettenis 
131*b725ae77Skettenis void
remove_thread(struct thread_info * thread)132*b725ae77Skettenis remove_thread (struct thread_info *thread)
133*b725ae77Skettenis {
134*b725ae77Skettenis   remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
135*b725ae77Skettenis   free_one_thread (&thread->entry);
136*b725ae77Skettenis }
137*b725ae77Skettenis 
138*b725ae77Skettenis void
clear_inferiors(void)139*b725ae77Skettenis clear_inferiors (void)
140*b725ae77Skettenis {
141*b725ae77Skettenis   for_each_inferior (&all_threads, free_one_thread);
142*b725ae77Skettenis 
143*b725ae77Skettenis   all_threads.head = all_threads.tail = NULL;
144*b725ae77Skettenis }
145*b725ae77Skettenis 
146*b725ae77Skettenis struct inferior_list_entry *
find_inferior(struct inferior_list * list,int (* func)(struct inferior_list_entry *,void *),void * arg)147*b725ae77Skettenis find_inferior (struct inferior_list *list,
148*b725ae77Skettenis 	       int (*func) (struct inferior_list_entry *, void *), void *arg)
149*b725ae77Skettenis {
150*b725ae77Skettenis   struct inferior_list_entry *inf = list->head;
151*b725ae77Skettenis 
152*b725ae77Skettenis   while (inf != NULL)
153*b725ae77Skettenis     {
154*b725ae77Skettenis       if ((*func) (inf, arg))
155*b725ae77Skettenis 	return inf;
156*b725ae77Skettenis       inf = inf->next;
157*b725ae77Skettenis     }
158*b725ae77Skettenis 
159*b725ae77Skettenis   return NULL;
160*b725ae77Skettenis }
161*b725ae77Skettenis 
162*b725ae77Skettenis struct inferior_list_entry *
find_inferior_id(struct inferior_list * list,int id)163*b725ae77Skettenis find_inferior_id (struct inferior_list *list, int id)
164*b725ae77Skettenis {
165*b725ae77Skettenis   struct inferior_list_entry *inf = list->head;
166*b725ae77Skettenis 
167*b725ae77Skettenis   while (inf != NULL)
168*b725ae77Skettenis     {
169*b725ae77Skettenis       if (inf->id == id)
170*b725ae77Skettenis 	return inf;
171*b725ae77Skettenis       inf = inf->next;
172*b725ae77Skettenis     }
173*b725ae77Skettenis 
174*b725ae77Skettenis   return NULL;
175*b725ae77Skettenis }
176*b725ae77Skettenis 
177*b725ae77Skettenis void *
inferior_target_data(struct thread_info * inferior)178*b725ae77Skettenis inferior_target_data (struct thread_info *inferior)
179*b725ae77Skettenis {
180*b725ae77Skettenis   return inferior->target_data;
181*b725ae77Skettenis }
182*b725ae77Skettenis 
183*b725ae77Skettenis void
set_inferior_target_data(struct thread_info * inferior,void * data)184*b725ae77Skettenis set_inferior_target_data (struct thread_info *inferior, void *data)
185*b725ae77Skettenis {
186*b725ae77Skettenis   inferior->target_data = data;
187*b725ae77Skettenis }
188*b725ae77Skettenis 
189*b725ae77Skettenis void *
inferior_regcache_data(struct thread_info * inferior)190*b725ae77Skettenis inferior_regcache_data (struct thread_info *inferior)
191*b725ae77Skettenis {
192*b725ae77Skettenis   return inferior->regcache_data;
193*b725ae77Skettenis }
194*b725ae77Skettenis 
195*b725ae77Skettenis void
set_inferior_regcache_data(struct thread_info * inferior,void * data)196*b725ae77Skettenis set_inferior_regcache_data (struct thread_info *inferior, void *data)
197*b725ae77Skettenis {
198*b725ae77Skettenis   inferior->regcache_data = data;
199*b725ae77Skettenis }
200