mips: Add some missing syscalls for mips32
[valgrind.git] / coregrind / m_gdbserver / inferiors.c
blobfbf7d2359cde4c1414a8f2d778fd9f3e1e6d48c2
1 /* Inferior process information for the remote server for GDB.
2 Copyright (C) 2002, 2005, 2011
3 Free Software Foundation, Inc.
5 Contributed by MontaVista Software.
7 This file is part of GDB.
8 It has been modified to integrate it in valgrind
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 Boston, MA 02110-1301, USA. */
25 #include "server.h"
27 struct thread_info
29 struct inferior_list_entry entry;
30 void *target_data;
31 void *regcache_data;
32 unsigned int gdb_id;
35 struct inferior_list all_threads;
37 struct thread_info *current_inferior;
39 #define get_thread(inf) ((struct thread_info *)(inf))
41 void add_inferior_to_list (struct inferior_list *list,
42 struct inferior_list_entry *new_inferior)
44 new_inferior->next = NULL;
45 if (list->tail != NULL)
46 list->tail->next = new_inferior;
47 else
48 list->head = new_inferior;
49 list->tail = new_inferior;
52 void for_each_inferior (struct inferior_list *list,
53 void (*action) (struct inferior_list_entry *))
55 struct inferior_list_entry *cur = list->head, *next;
57 while (cur != NULL) {
58 next = cur->next;
59 (*action) (cur);
60 cur = next;
64 void change_inferior_id (struct inferior_list *list,
65 unsigned long new_id)
67 if (list->head != list->tail)
68 error ("tried to change thread ID after multiple threads are created\n");
70 list->head->id = new_id;
73 void remove_inferior (struct inferior_list *list,
74 struct inferior_list_entry *entry)
76 struct inferior_list_entry **cur;
78 if (list->head == entry) {
79 list->head = entry->next;
80 if (list->tail == entry)
81 list->tail = list->head;
82 return;
85 cur = &list->head;
86 while (*cur && (*cur)->next != entry)
87 cur = &(*cur)->next;
89 if (*cur == NULL)
90 return;
92 (*cur)->next = entry->next;
94 if (list->tail == entry)
95 list->tail = *cur;
98 void add_thread (unsigned long thread_id, void *target_data, unsigned int gdb_id)
100 struct thread_info *new_thread
101 = (struct thread_info *) malloc (sizeof (*new_thread));
103 memset (new_thread, 0, sizeof (*new_thread));
105 new_thread->entry.id = thread_id;
107 add_inferior_to_list (&all_threads, & new_thread->entry);
109 if (current_inferior == NULL)
110 current_inferior = new_thread;
112 new_thread->target_data = target_data;
113 set_inferior_regcache_data (new_thread, new_register_cache ());
114 new_thread->gdb_id = gdb_id;
117 unsigned int thread_id_to_gdb_id (unsigned long thread_id)
119 struct inferior_list_entry *inf = all_threads.head;
121 while (inf != NULL) {
122 struct thread_info *thread = get_thread (inf);
123 if (inf->id == thread_id)
124 return thread->gdb_id;
125 inf = inf->next;
128 return 0;
131 unsigned int thread_to_gdb_id (struct thread_info *thread)
133 return thread->gdb_id;
136 struct thread_info * gdb_id_to_thread (unsigned int gdb_id)
138 struct inferior_list_entry *inf = all_threads.head;
140 while (inf != NULL) {
141 struct thread_info *thread = get_thread (inf);
142 if (thread->gdb_id == gdb_id)
143 return thread;
144 inf = inf->next;
147 return NULL;
150 unsigned long gdb_id_to_thread_id (unsigned int gdb_id)
152 struct thread_info *thread = gdb_id_to_thread (gdb_id);
154 return thread ? thread->entry.id : 0;
157 static
158 void free_one_thread (struct inferior_list_entry *inf)
160 struct thread_info *thread = get_thread (inf);
161 free_register_cache (inferior_regcache_data (thread));
162 free (thread);
165 void remove_thread (struct thread_info *thread)
167 remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
168 free_one_thread (&thread->entry);
171 void clear_inferiors (void)
173 for_each_inferior (&all_threads, free_one_thread);
175 all_threads.head = all_threads.tail = NULL;
178 struct inferior_list_entry * find_inferior (struct inferior_list *list,
179 int (*func)
180 (struct inferior_list_entry *,
181 void *),
182 void *arg)
184 struct inferior_list_entry *inf = list->head;
186 while (inf != NULL) {
187 if ((*func) (inf, arg))
188 return inf;
189 inf = inf->next;
192 return NULL;
195 struct inferior_list_entry * find_inferior_id (struct inferior_list *list,
196 unsigned long id)
198 struct inferior_list_entry *inf = list->head;
200 while (inf != NULL) {
201 if (inf->id == id)
202 return inf;
203 inf = inf->next;
206 return NULL;
209 void * inferior_target_data (struct thread_info *inferior)
211 return inferior->target_data;
214 void set_inferior_target_data (struct thread_info *inferior, void *data)
216 inferior->target_data = data;
219 void * inferior_regcache_data (struct thread_info *inferior)
221 return inferior->regcache_data;
224 void set_inferior_regcache_data (struct thread_info *inferior, void *data)
226 inferior->regcache_data = data;