Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(652)

Side by Side Diff: gdb/ravenscar-thread.c

Issue 124383005: GDB 7.6.50 (Closed) Base URL: http://git.chromium.org/native_client/nacl-gdb.git@upstream
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gdb/ravenscar-thread.h ('k') | gdb/record.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Ada Ravenscar thread support. 1 /* Ada Ravenscar thread support.
2 2
3 Copyright 2004, 2009-2012 Free Software Foundation, Inc. 3 Copyright (C) 2004-2013 Free Software Foundation, Inc.
4 4
5 This file is part of GDB. 5 This file is part of GDB.
6 6
7 This program is free software; you can redistribute it and/or modify 7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or 9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version. 10 (at your option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 19
20 #include "defs.h" 20 #include "defs.h"
21 #include "gdbcore.h" 21 #include "gdbcore.h"
22 #include "gdbthread.h" 22 #include "gdbthread.h"
23 #include "ada-lang.h" 23 #include "ada-lang.h"
24 #include "target.h" 24 #include "target.h"
25 #include "inferior.h" 25 #include "inferior.h"
26 #include "command.h" 26 #include "command.h"
27 #include "ravenscar-thread.h" 27 #include "ravenscar-thread.h"
28 #include "observer.h" 28 #include "observer.h"
29 #include "gdb_string.h" 29 #include <string.h>
30 #include "gdbcmd.h" 30 #include "gdbcmd.h"
31 #include "top.h" 31 #include "top.h"
32 #include "regcache.h" 32 #include "regcache.h"
33 33
34 /* If non-null, ravenscar task support is enabled. */ 34 /* If non-null, ravenscar task support is enabled. */
35 static int ravenscar_task_support = 1; 35 static int ravenscar_task_support = 1;
36 36
37 /* Non-null if the ravenscar thread layer has been pushed on the target
38 stack. */
39 static int ravenscar_is_open = 0;
40
41 /* This module's target-specific operations. */ 37 /* This module's target-specific operations. */
42 static struct target_ops ravenscar_ops; 38 static struct target_ops ravenscar_ops;
43 39
44 /* Some base target uses a special value for the null PID (exempli gratia 40 /* Some base target uses a special value for the null PID (exempli gratia
45 remote). */ 41 remote). */
46 static ptid_t base_magic_null_ptid; 42 static ptid_t base_magic_null_ptid;
47 43
48 /* Ptid of the inferior as seen by the process stratum. */ 44 /* Ptid of the inferior as seen by the process stratum. */
49 static ptid_t base_ptid; 45 static ptid_t base_ptid;
50 46
51 static const char running_thread_name[] = "__gnat_running_thread_table"; 47 static const char running_thread_name[] = "__gnat_running_thread_table";
52 48
53 static const char known_tasks_name[] = "system__tasking__debug__known_tasks"; 49 static const char known_tasks_name[] = "system__tasking__debug__known_tasks";
54 static const char first_task_name[] = "system__tasking__debug__first_task"; 50 static const char first_task_name[] = "system__tasking__debug__first_task";
55 51
56 static const char ravenscar_runtime_initializer[] = 52 static const char ravenscar_runtime_initializer[] =
57 "system__bb__threads__initialize"; 53 "system__bb__threads__initialize";
58 54
59 static struct observer *update_target_observer = NULL; 55 static struct observer *update_target_observer = NULL;
60 56
61 /* Architecture-specific hooks. */
62 static struct ravenscar_arch_ops* current_arch_ops;
63
64 static void ravenscar_find_new_threads (struct target_ops *ops); 57 static void ravenscar_find_new_threads (struct target_ops *ops);
65 static ptid_t ravenscar_running_thread (void); 58 static ptid_t ravenscar_running_thread (void);
66 static char *ravenscar_extra_thread_info (struct thread_info *tp); 59 static char *ravenscar_extra_thread_info (struct thread_info *tp);
67 static int ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid); 60 static int ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid);
68 static void ravenscar_fetch_registers (struct target_ops *ops, 61 static void ravenscar_fetch_registers (struct target_ops *ops,
69 struct regcache *regcache, int regnum); 62 struct regcache *regcache, int regnum);
70 static void ravenscar_store_registers (struct target_ops *ops, 63 static void ravenscar_store_registers (struct target_ops *ops,
71 struct regcache *regcache, int regnum); 64 struct regcache *regcache, int regnum);
72 static void ravenscar_prepare_to_store (struct regcache *regcache); 65 static void ravenscar_prepare_to_store (struct regcache *regcache);
73 static void ravenscar_initialize (char *name, int from_tty);
74 static void ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step, 66 static void ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
75 enum gdb_signal siggnal); 67 enum gdb_signal siggnal);
76 static void ravenscar_mourn_inferior (struct target_ops *ops); 68 static void ravenscar_mourn_inferior (struct target_ops *ops);
77 static void ravenscar_update_inferior_ptid (void); 69 static void ravenscar_update_inferior_ptid (void);
78 static int has_ravenscar_runtime (void); 70 static int has_ravenscar_runtime (void);
79 static int ravenscar_runtime_initialized (void); 71 static int ravenscar_runtime_initialized (void);
80 static void ravenscar_inferior_created (struct target_ops *target, 72 static void ravenscar_inferior_created (struct target_ops *target,
81 int from_tty); 73 int from_tty);
82 74
83 /* Fetch the ravenscar running thread from target memory and 75 /* Fetch the ravenscar running thread from target memory and
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 148
157 /* Return the ID of the thread that is currently running. 149 /* Return the ID of the thread that is currently running.
158 Return 0 if the ID could not be determined. */ 150 Return 0 if the ID could not be determined. */
159 151
160 static CORE_ADDR 152 static CORE_ADDR
161 get_running_thread_id (void) 153 get_running_thread_id (void)
162 { 154 {
163 const struct minimal_symbol *object_msym = get_running_thread_msymbol (); 155 const struct minimal_symbol *object_msym = get_running_thread_msymbol ();
164 int object_size; 156 int object_size;
165 int buf_size; 157 int buf_size;
166 char *buf; 158 gdb_byte *buf;
167 CORE_ADDR object_addr; 159 CORE_ADDR object_addr;
168 struct type *builtin_type_void_data_ptr = 160 struct type *builtin_type_void_data_ptr =
169 builtin_type (target_gdbarch)->builtin_data_ptr; 161 builtin_type (target_gdbarch ())->builtin_data_ptr;
170 162
171 if (!object_msym) 163 if (!object_msym)
172 return 0; 164 return 0;
173 165
174 object_addr = SYMBOL_VALUE_ADDRESS (object_msym); 166 object_addr = SYMBOL_VALUE_ADDRESS (object_msym);
175 object_size = TYPE_LENGTH (builtin_type_void_data_ptr); 167 object_size = TYPE_LENGTH (builtin_type_void_data_ptr);
176 buf_size = object_size; 168 buf_size = object_size;
177 buf = alloca (buf_size); 169 buf = alloca (buf_size);
178 read_memory (object_addr, buf, buf_size); 170 read_memory (object_addr, buf, buf_size);
179 return extract_typed_address (buf, builtin_type_void_data_ptr); 171 return extract_typed_address (buf, builtin_type_void_data_ptr);
180 } 172 }
181 173
182 static void 174 static void
183 ravenscar_close (int quitting)
184 {
185 ravenscar_is_open = 0;
186 }
187
188 static void
189 ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step, 175 ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
190 enum gdb_signal siggnal) 176 enum gdb_signal siggnal)
191 { 177 {
192 struct target_ops *beneath = find_target_beneath (ops); 178 struct target_ops *beneath = find_target_beneath (ops);
193 179
194 inferior_ptid = base_ptid; 180 inferior_ptid = base_ptid;
195 beneath->to_resume (beneath, base_ptid, step, siggnal); 181 beneath->to_resume (beneath, base_ptid, step, siggnal);
196 } 182 }
197 183
198 static ptid_t 184 static ptid_t
199 ravenscar_wait (struct target_ops *ops, ptid_t ptid, 185 ravenscar_wait (struct target_ops *ops, ptid_t ptid,
200 struct target_waitstatus *status, 186 struct target_waitstatus *status,
201 int options) 187 int options)
202 { 188 {
203 struct target_ops *beneath = find_target_beneath (ops); 189 struct target_ops *beneath = find_target_beneath (ops);
204 190
205 inferior_ptid = base_ptid; 191 inferior_ptid = base_ptid;
206 beneath->to_wait (beneath, base_ptid, status, 0); 192 beneath->to_wait (beneath, base_ptid, status, 0);
207 ravenscar_find_new_threads (ops); 193 /* Find any new threads that might have been created, and update
208 ravenscar_update_inferior_ptid (); 194 inferior_ptid to the active thread.
195
196 Only do it if the program is still alive, though. Otherwise,
197 this causes problems when debugging through the remote protocol,
198 because we might try switching threads (and thus sending packets)
199 after the remote has disconnected. */
200 if (status->kind != TARGET_WAITKIND_EXITED
201 && status->kind != TARGET_WAITKIND_SIGNALLED)
202 {
203 ravenscar_find_new_threads (ops);
204 ravenscar_update_inferior_ptid ();
205 }
209 return inferior_ptid; 206 return inferior_ptid;
210 } 207 }
211 208
212 /* Add the thread associated to the given TASK to the thread list 209 /* Add the thread associated to the given TASK to the thread list
213 (if the thread has already been added, this is a no-op). */ 210 (if the thread has already been added, this is a no-op). */
214 211
215 static void 212 static void
216 ravenscar_add_thread (struct ada_task_info *task) 213 ravenscar_add_thread (struct ada_task_info *task)
217 { 214 {
218 if (find_thread_ptid (task->ptid) == NULL) 215 if (find_thread_ptid (task->ptid) == NULL)
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 ravenscar_fetch_registers (struct target_ops *ops, 266 ravenscar_fetch_registers (struct target_ops *ops,
270 struct regcache *regcache, int regnum) 267 struct regcache *regcache, int regnum)
271 { 268 {
272 struct target_ops *beneath = find_target_beneath (ops); 269 struct target_ops *beneath = find_target_beneath (ops);
273 270
274 if (!ravenscar_runtime_initialized () 271 if (!ravenscar_runtime_initialized ()
275 || ptid_equal (inferior_ptid, base_magic_null_ptid) 272 || ptid_equal (inferior_ptid, base_magic_null_ptid)
276 || ptid_equal (inferior_ptid, ravenscar_running_thread ())) 273 || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
277 beneath->to_fetch_registers (beneath, regcache, regnum); 274 beneath->to_fetch_registers (beneath, regcache, regnum);
278 else 275 else
279 current_arch_ops->to_fetch_registers (regcache, regnum); 276 {
277 struct gdbarch *gdbarch = get_regcache_arch (regcache);
278 struct ravenscar_arch_ops *arch_ops
279 » = gdbarch_ravenscar_ops (gdbarch);
280
281 arch_ops->to_fetch_registers (regcache, regnum);
282 }
280 } 283 }
281 284
282 static void 285 static void
283 ravenscar_store_registers (struct target_ops *ops, 286 ravenscar_store_registers (struct target_ops *ops,
284 struct regcache *regcache, int regnum) 287 struct regcache *regcache, int regnum)
285 { 288 {
286 struct target_ops *beneath = find_target_beneath (ops); 289 struct target_ops *beneath = find_target_beneath (ops);
287 290
288 if (!ravenscar_runtime_initialized () 291 if (!ravenscar_runtime_initialized ()
289 || ptid_equal (inferior_ptid, base_magic_null_ptid) 292 || ptid_equal (inferior_ptid, base_magic_null_ptid)
290 || ptid_equal (inferior_ptid, ravenscar_running_thread ())) 293 || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
291 beneath->to_store_registers (beneath, regcache, regnum); 294 beneath->to_store_registers (beneath, regcache, regnum);
292 else 295 else
293 current_arch_ops->to_store_registers (regcache, regnum); 296 {
297 struct gdbarch *gdbarch = get_regcache_arch (regcache);
298 struct ravenscar_arch_ops *arch_ops
299 » = gdbarch_ravenscar_ops (gdbarch);
300
301 arch_ops->to_store_registers (regcache, regnum);
302 }
294 } 303 }
295 304
296 static void 305 static void
297 ravenscar_prepare_to_store (struct regcache *regcache) 306 ravenscar_prepare_to_store (struct regcache *regcache)
298 { 307 {
299 struct target_ops *beneath = find_target_beneath (&ravenscar_ops); 308 struct target_ops *beneath = find_target_beneath (&ravenscar_ops);
300 309
301 if (!ravenscar_runtime_initialized () 310 if (!ravenscar_runtime_initialized ()
302 || ptid_equal (inferior_ptid, base_magic_null_ptid) 311 || ptid_equal (inferior_ptid, base_magic_null_ptid)
303 || ptid_equal (inferior_ptid, ravenscar_running_thread ())) 312 || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
304 beneath->to_prepare_to_store (regcache); 313 beneath->to_prepare_to_store (regcache);
305 else 314 else
306 current_arch_ops->to_prepare_to_store (regcache); 315 {
316 struct gdbarch *gdbarch = get_regcache_arch (regcache);
317 struct ravenscar_arch_ops *arch_ops
318 » = gdbarch_ravenscar_ops (gdbarch);
319
320 arch_ops->to_prepare_to_store (regcache);
321 }
307 } 322 }
308 323
309 static void 324 static void
310 ravenscar_mourn_inferior (struct target_ops *ops) 325 ravenscar_mourn_inferior (struct target_ops *ops)
311 { 326 {
312 struct target_ops *beneath = find_target_beneath (&ravenscar_ops); 327 struct target_ops *beneath = find_target_beneath (&ravenscar_ops);
313 328
314 base_ptid = null_ptid; 329 base_ptid = null_ptid;
315 beneath->to_mourn_inferior (beneath); 330 beneath->to_mourn_inferior (beneath);
316 unpush_target (&ravenscar_ops); 331 unpush_target (&ravenscar_ops);
317 } 332 }
318 333
319 /* Observer on inferior_created: push ravenscar thread stratum if needed. */ 334 /* Observer on inferior_created: push ravenscar thread stratum if needed. */
320 335
321 static void 336 static void
322 ravenscar_inferior_created (struct target_ops *target, int from_tty) 337 ravenscar_inferior_created (struct target_ops *target, int from_tty)
323 { 338 {
324 if (ravenscar_task_support 339 struct ravenscar_arch_ops *ops;
325 && has_ravenscar_runtime ())
326 ravenscar_initialize (NULL, 0);
327 }
328 340
329 void 341 if (!ravenscar_task_support
330 ravenscar_register_arch_ops (struct ravenscar_arch_ops *ops) 342 || gdbarch_ravenscar_ops (current_inferior ()->gdbarch) == NULL
331 { 343 || !has_ravenscar_runtime ())
332 /* FIXME: To be clean, we would need to handle a list of
333 architectures, just like in remote-wtx-hw.c. However, for now the
334 only Ravenscar run-time for bare board that is implemented in
335 GNAT is for only one architecture: erc32-elf. So no need to care about
336 that for now... */
337 current_arch_ops = ops;
338 }
339
340 /* Initialize Ravenscar support. */
341
342 static void
343 ravenscar_initialize (char *name, int from_tty)
344 {
345 if (ravenscar_is_open)
346 return; 344 return;
347 345
348 base_magic_null_ptid = inferior_ptid; 346 base_magic_null_ptid = inferior_ptid;
349 ravenscar_update_inferior_ptid (); 347 ravenscar_update_inferior_ptid ();
350 push_target (&ravenscar_ops); 348 push_target (&ravenscar_ops);
351 ravenscar_is_open = 1;
352 } 349 }
353 350
354 static ptid_t 351 static ptid_t
355 ravenscar_get_ada_task_ptid (long lwp, long thread) 352 ravenscar_get_ada_task_ptid (long lwp, long thread)
356 { 353 {
357 return ptid_build (ptid_get_pid (base_ptid), 0, thread); 354 return ptid_build (ptid_get_pid (base_ptid), 0, thread);
358 } 355 }
359 356
360 static void 357 static void
361 init_ravenscar_thread_ops (void) 358 init_ravenscar_thread_ops (void)
362 { 359 {
363 ravenscar_ops.to_shortname = "ravenscar"; 360 ravenscar_ops.to_shortname = "ravenscar";
364 ravenscar_ops.to_longname = "Ravenscar tasks."; 361 ravenscar_ops.to_longname = "Ravenscar tasks.";
365 ravenscar_ops.to_doc = "Ravenscar tasks support."; 362 ravenscar_ops.to_doc = "Ravenscar tasks support.";
366 ravenscar_ops.to_close = ravenscar_close;
367 ravenscar_ops.to_resume = ravenscar_resume; 363 ravenscar_ops.to_resume = ravenscar_resume;
368 ravenscar_ops.to_wait = ravenscar_wait; 364 ravenscar_ops.to_wait = ravenscar_wait;
369 ravenscar_ops.to_fetch_registers = ravenscar_fetch_registers; 365 ravenscar_ops.to_fetch_registers = ravenscar_fetch_registers;
370 ravenscar_ops.to_store_registers = ravenscar_store_registers; 366 ravenscar_ops.to_store_registers = ravenscar_store_registers;
371 ravenscar_ops.to_prepare_to_store = ravenscar_prepare_to_store; 367 ravenscar_ops.to_prepare_to_store = ravenscar_prepare_to_store;
372 ravenscar_ops.to_thread_alive = ravenscar_thread_alive; 368 ravenscar_ops.to_thread_alive = ravenscar_thread_alive;
373 ravenscar_ops.to_find_new_threads = ravenscar_find_new_threads; 369 ravenscar_ops.to_find_new_threads = ravenscar_find_new_threads;
374 ravenscar_ops.to_pid_to_str = ravenscar_pid_to_str; 370 ravenscar_ops.to_pid_to_str = ravenscar_pid_to_str;
375 ravenscar_ops.to_extra_thread_info = ravenscar_extra_thread_info; 371 ravenscar_ops.to_extra_thread_info = ravenscar_extra_thread_info;
376 ravenscar_ops.to_get_ada_task_ptid = ravenscar_get_ada_task_ptid; 372 ravenscar_ops.to_get_ada_task_ptid = ravenscar_get_ada_task_ptid;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 void 426 void
431 _initialize_ravenscar (void) 427 _initialize_ravenscar (void)
432 { 428 {
433 init_ravenscar_thread_ops (); 429 init_ravenscar_thread_ops ();
434 base_ptid = null_ptid; 430 base_ptid = null_ptid;
435 431
436 /* Notice when the inferior is created in order to push the 432 /* Notice when the inferior is created in order to push the
437 ravenscar ops if needed. */ 433 ravenscar ops if needed. */
438 observer_attach_inferior_created (ravenscar_inferior_created); 434 observer_attach_inferior_created (ravenscar_inferior_created);
439 435
440 add_target (&ravenscar_ops); 436 complete_target_initialization (&ravenscar_ops);
441 437
442 add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command, 438 add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command,
443 _("Prefix command for changing Ravenscar-specific settings"), 439 _("Prefix command for changing Ravenscar-specific settings"),
444 &set_ravenscar_list, "set ravenscar ", 0, &setlist); 440 &set_ravenscar_list, "set ravenscar ", 0, &setlist);
445 441
446 add_prefix_cmd ("ravenscar", no_class, show_ravenscar_command, 442 add_prefix_cmd ("ravenscar", no_class, show_ravenscar_command,
447 _("Prefix command for showing Ravenscar-specific settings"), 443 _("Prefix command for showing Ravenscar-specific settings"),
448 &show_ravenscar_list, "show ravenscar ", 0, &showlist); 444 &show_ravenscar_list, "show ravenscar ", 0, &showlist);
449 445
450 add_setshow_boolean_cmd ("task-switching", class_obscure, 446 add_setshow_boolean_cmd ("task-switching", class_obscure,
451 &ravenscar_task_support, _("\ 447 &ravenscar_task_support, _("\
452 Enable or disable support for GNAT Ravenscar tasks"), _("\ 448 Enable or disable support for GNAT Ravenscar tasks"), _("\
453 Show whether support for GNAT Ravenscar tasks is enabled"), 449 Show whether support for GNAT Ravenscar tasks is enabled"),
454 _("\ 450 _("\
455 Enable or disable support for task/thread switching with the GNAT\n\ 451 Enable or disable support for task/thread switching with the GNAT\n\
456 Ravenscar run-time library for bareboard configuration."), 452 Ravenscar run-time library for bareboard configuration."),
457 NULL, show_ravenscar_task_switching_command, 453 NULL, show_ravenscar_task_switching_command,
458 &set_ravenscar_list, &show_ravenscar_list); 454 &set_ravenscar_list, &show_ravenscar_list);
459 } 455 }
OLDNEW
« no previous file with comments | « gdb/ravenscar-thread.h ('k') | gdb/record.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698