]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/coregrind/m_gdbserver/inferiors.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / coregrind / m_gdbserver / inferiors.c
1 /* Inferior process information for the remote server for GDB.
2    Copyright (C) 2002, 2005, 2011
3    Free Software Foundation, Inc.
4
5    Contributed by MontaVista Software.
6
7    This file is part of GDB.
8    It has been modified to integrate it in valgrind
9
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.
14
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.
19
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.  */
24
25 #include "server.h"
26
27 struct thread_info
28 {
29    struct inferior_list_entry entry;
30    void *target_data;
31    void *regcache_data;
32    unsigned int gdb_id;
33 };
34
35 struct inferior_list all_threads;
36
37 struct thread_info *current_inferior;
38
39 #define get_thread(inf) ((struct thread_info *)(inf))
40
41 void add_inferior_to_list (struct inferior_list *list,
42                       struct inferior_list_entry *new_inferior)
43 {
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;
50 }
51
52 void for_each_inferior (struct inferior_list *list,
53                    void (*action) (struct inferior_list_entry *))
54 {
55    struct inferior_list_entry *cur = list->head, *next;
56
57    while (cur != NULL) {
58       next = cur->next;
59       (*action) (cur);
60       cur = next;
61    }
62 }
63
64 void change_inferior_id (struct inferior_list *list,
65                     unsigned long new_id)
66 {
67    if (list->head != list->tail)
68       error ("tried to change thread ID after multiple threads are created\n");
69
70    list->head->id = new_id;
71 }
72
73 void remove_inferior (struct inferior_list *list,
74                  struct inferior_list_entry *entry)
75 {
76    struct inferior_list_entry **cur;
77
78    if (list->head == entry) {
79       list->head = entry->next;
80       if (list->tail == entry)
81          list->tail = list->head;
82       return;
83    }
84
85    cur = &list->head;
86    while (*cur && (*cur)->next != entry)
87       cur = &(*cur)->next;
88
89    if (*cur == NULL)
90       return;
91
92    (*cur)->next = entry->next;
93
94    if (list->tail == entry)
95       list->tail = *cur;
96 }
97
98 void add_thread (unsigned long thread_id, void *target_data, unsigned int gdb_id)
99 {
100    struct thread_info *new_thread
101       = (struct thread_info *) malloc (sizeof (*new_thread));
102
103    VG_(memset) (new_thread, 0, sizeof (*new_thread));
104
105    new_thread->entry.id = thread_id;
106
107    add_inferior_to_list (&all_threads, & new_thread->entry);
108   
109    if (current_inferior == NULL)
110       current_inferior = new_thread;
111
112    new_thread->target_data = target_data;
113    set_inferior_regcache_data (new_thread, new_register_cache ());
114    new_thread->gdb_id = gdb_id;
115 }
116
117 unsigned int thread_id_to_gdb_id (unsigned long thread_id)
118 {
119    struct inferior_list_entry *inf = all_threads.head;
120
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;
126    }
127
128    return 0;
129 }
130
131 unsigned int thread_to_gdb_id (struct thread_info *thread)
132 {
133    return thread->gdb_id;
134 }
135
136 struct thread_info * gdb_id_to_thread (unsigned int gdb_id)
137 {
138    struct inferior_list_entry *inf = all_threads.head;
139
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;
145    }
146
147    return NULL;
148 }
149
150 unsigned long gdb_id_to_thread_id (unsigned int gdb_id)
151 {
152    struct thread_info *thread = gdb_id_to_thread (gdb_id);
153
154    return thread ? thread->entry.id : 0;
155 }
156
157 static
158 void free_one_thread (struct inferior_list_entry *inf)
159 {
160    struct thread_info *thread = get_thread (inf);
161    free_register_cache (inferior_regcache_data (thread));
162    free (thread);
163 }
164
165 void remove_thread (struct thread_info *thread)
166 {
167    remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
168    free_one_thread (&thread->entry);
169 }
170
171 void clear_inferiors (void)
172 {
173    for_each_inferior (&all_threads, free_one_thread);
174
175    all_threads.head = all_threads.tail = NULL;
176 }
177
178 struct inferior_list_entry * find_inferior (struct inferior_list *list,
179                                             int (*func) 
180                                               (struct inferior_list_entry *,
181                                                void *),
182                                             void *arg)
183 {
184    struct inferior_list_entry *inf = list->head;
185
186    while (inf != NULL) {
187       if ((*func) (inf, arg))
188          return inf;
189       inf = inf->next;
190    }
191    
192    return NULL;
193 }
194
195 struct inferior_list_entry * find_inferior_id (struct inferior_list *list,
196                                                unsigned long id)
197 {
198    struct inferior_list_entry *inf = list->head;
199
200    while (inf != NULL) {
201       if (inf->id == id)
202          return inf;
203       inf = inf->next;
204    }
205    
206    return NULL;
207 }
208
209 void * inferior_target_data (struct thread_info *inferior)
210 {
211    return inferior->target_data;
212 }
213
214 void set_inferior_target_data (struct thread_info *inferior, void *data)
215 {
216    inferior->target_data = data;
217 }
218
219 void * inferior_regcache_data (struct thread_info *inferior)
220 {
221    return inferior->regcache_data;
222 }
223
224 void set_inferior_regcache_data (struct thread_info *inferior, void *data)
225 {
226    inferior->regcache_data = data;
227 }