* gdbarch.sh (target_gdbarch): Remove macro.
[external/binutils.git] / gdb / ravenscar-thread.c
1 /* Ada Ravenscar thread support.
2
3    Copyright 2004, 2009-2012 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
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/>.  */
19
20 #include "defs.h"
21 #include "gdbcore.h"
22 #include "gdbthread.h"
23 #include "ada-lang.h"
24 #include "target.h"
25 #include "inferior.h"
26 #include "command.h"
27 #include "ravenscar-thread.h"
28 #include "observer.h"
29 #include "gdb_string.h"
30 #include "gdbcmd.h"
31 #include "top.h"
32 #include "regcache.h"
33
34 /* If non-null, ravenscar task support is enabled.  */
35 static int ravenscar_task_support = 1;
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.  */
42 static struct target_ops ravenscar_ops;
43
44 /* Some base target uses a special value for the null PID (exempli gratia
45    remote).  */
46 static ptid_t base_magic_null_ptid;
47
48 /* Ptid of the inferior as seen by the process stratum.  */
49 static ptid_t base_ptid;
50
51 static const char running_thread_name[] = "__gnat_running_thread_table";
52
53 static const char known_tasks_name[] = "system__tasking__debug__known_tasks";
54 static const char first_task_name[] = "system__tasking__debug__first_task";
55
56 static const char ravenscar_runtime_initializer[] =
57   "system__bb__threads__initialize";
58
59 static struct observer *update_target_observer = NULL;
60
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);
65 static ptid_t ravenscar_running_thread (void);
66 static char *ravenscar_extra_thread_info (struct thread_info *tp);
67 static int ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid);
68 static void ravenscar_fetch_registers (struct target_ops *ops,
69                                        struct regcache *regcache, int regnum);
70 static void ravenscar_store_registers (struct target_ops *ops,
71                                        struct regcache *regcache, int regnum);
72 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,
75                               enum gdb_signal siggnal);
76 static void ravenscar_mourn_inferior (struct target_ops *ops);
77 static void ravenscar_update_inferior_ptid (void);
78 static int has_ravenscar_runtime (void);
79 static int ravenscar_runtime_initialized (void);
80 static void ravenscar_inferior_created (struct target_ops *target,
81                                         int from_tty);
82
83 /* Fetch the ravenscar running thread from target memory and
84    update inferior_ptid accordingly.  */
85
86 static void
87 ravenscar_update_inferior_ptid (void)
88 {
89   base_ptid = inferior_ptid;
90
91   /* If the runtime has not been initialized yet, the inferior_ptid is
92      the only ptid that there is.  */
93   if (!ravenscar_runtime_initialized ())
94     return;
95
96   /* Make sure we set base_ptid before calling ravenscar_running_thread
97      as the latter relies on it.  */
98   inferior_ptid = ravenscar_running_thread ();
99   gdb_assert (!ptid_equal (inferior_ptid, null_ptid));
100
101   /* The running thread may not have been added to
102      system.tasking.debug's list yet; so ravenscar_find_new_threads
103      may not always add it to the thread list.  Add it here.  */
104   if (!find_thread_ptid (inferior_ptid))
105     add_thread (inferior_ptid);
106 }
107
108 /* The Ravenscar Runtime exports a symbol which contains the ID of
109    the thread that is currently running.  Try to locate that symbol
110    and return its associated minimal symbol.
111    Return NULL if not found.  */
112
113 static struct minimal_symbol *
114 get_running_thread_msymbol (void)
115 {
116   struct minimal_symbol *msym;
117
118   msym = lookup_minimal_symbol (running_thread_name, NULL, NULL);
119   if (!msym)
120     /* Older versions of the GNAT runtime were using a different
121        (less ideal) name for the symbol where the active thread ID
122        is stored.  If we couldn't find the symbol using the latest
123        name, then try the old one.  */
124     msym = lookup_minimal_symbol ("running_thread", NULL, NULL);
125
126   return msym;
127 }
128
129 /* Return True if the Ada Ravenscar run-time can be found in the
130    application.  */
131
132 static int
133 has_ravenscar_runtime (void)
134 {
135   struct minimal_symbol *msym_ravenscar_runtime_initializer =
136     lookup_minimal_symbol (ravenscar_runtime_initializer, NULL, NULL);
137   struct minimal_symbol *msym_known_tasks =
138     lookup_minimal_symbol (known_tasks_name, NULL, NULL);
139   struct minimal_symbol *msym_first_task =
140     lookup_minimal_symbol (first_task_name, NULL, NULL);
141   struct minimal_symbol *msym_running_thread = get_running_thread_msymbol ();
142
143   return (msym_ravenscar_runtime_initializer
144           && (msym_known_tasks || msym_first_task)
145           && msym_running_thread);
146 }
147
148 /* Return True if the Ada Ravenscar run-time can be found in the
149    application, and if it has been initialized on target.  */
150
151 static int
152 ravenscar_runtime_initialized (void)
153 {
154   return (!(ptid_equal (ravenscar_running_thread (), null_ptid)));
155 }
156
157 /* Return the ID of the thread that is currently running.
158    Return 0 if the ID could not be determined.  */
159
160 static CORE_ADDR
161 get_running_thread_id (void)
162 {
163   const struct minimal_symbol *object_msym = get_running_thread_msymbol ();
164   int object_size;
165   int buf_size;
166   char *buf;
167   CORE_ADDR object_addr;
168   struct type *builtin_type_void_data_ptr =
169     builtin_type (target_gdbarch ())->builtin_data_ptr;
170
171   if (!object_msym)
172     return 0;
173
174   object_addr = SYMBOL_VALUE_ADDRESS (object_msym);
175   object_size = TYPE_LENGTH (builtin_type_void_data_ptr);
176   buf_size = object_size;
177   buf = alloca (buf_size);
178   read_memory (object_addr, buf, buf_size);
179   return extract_typed_address (buf, builtin_type_void_data_ptr);
180 }
181
182 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,
190                   enum gdb_signal siggnal)
191 {
192   struct target_ops *beneath = find_target_beneath (ops);
193
194   inferior_ptid = base_ptid;
195   beneath->to_resume (beneath, base_ptid, step, siggnal);
196 }
197
198 static ptid_t
199 ravenscar_wait (struct target_ops *ops, ptid_t ptid,
200                 struct target_waitstatus *status,
201                 int options)
202 {
203   struct target_ops *beneath = find_target_beneath (ops);
204
205   inferior_ptid = base_ptid;
206   beneath->to_wait (beneath, base_ptid, status, 0);
207   /* Find any new threads that might have been created, and update
208      inferior_ptid to the active thread.
209
210      Only do it if the program is still alive, though.  Otherwise,
211      this causes problems when debugging through the remote protocol,
212      because we might try switching threads (and thus sending packets)
213      after the remote has disconnected.  */
214   if (status->kind != TARGET_WAITKIND_EXITED
215       && status->kind != TARGET_WAITKIND_SIGNALLED)
216     {
217       ravenscar_find_new_threads (ops);
218       ravenscar_update_inferior_ptid ();
219     }
220   return inferior_ptid;
221 }
222
223 /* Add the thread associated to the given TASK to the thread list
224    (if the thread has already been added, this is a no-op).  */
225
226 static void
227 ravenscar_add_thread (struct ada_task_info *task)
228 {
229   if (find_thread_ptid (task->ptid) == NULL)
230     add_thread (task->ptid);
231 }
232
233 static void
234 ravenscar_find_new_threads (struct target_ops *ops)
235 {
236   ada_build_task_list ();
237
238   /* Do not clear the thread list before adding the Ada task, to keep
239      the thread that the process stratum has included into it
240      (base_ptid) and the running thread, that may not have been included
241      to system.tasking.debug's list yet.  */
242
243   iterate_over_live_ada_tasks (ravenscar_add_thread);
244 }
245
246 static ptid_t
247 ravenscar_running_thread (void)
248 {
249   CORE_ADDR tid = get_running_thread_id ();
250
251   if (tid == 0)
252     return null_ptid;
253   else
254     return ptid_build (ptid_get_pid (base_ptid), 0, tid);
255 }
256
257 static char *
258 ravenscar_extra_thread_info (struct thread_info *tp)
259 {
260   return "Ravenscar task";
261 }
262
263 static int
264 ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid)
265 {
266   /* Ravenscar tasks are non-terminating.  */
267   return 1;
268 }
269
270 static char *
271 ravenscar_pid_to_str (struct target_ops *ops, ptid_t ptid)
272 {
273   static char buf[30];
274
275   snprintf (buf, sizeof (buf), "Thread %#x", (int) ptid_get_tid (ptid));
276   return buf;
277 }
278
279 static void
280 ravenscar_fetch_registers (struct target_ops *ops,
281                            struct regcache *regcache, int regnum)
282 {
283   struct target_ops *beneath = find_target_beneath (ops);
284
285   if (!ravenscar_runtime_initialized ()
286       || ptid_equal (inferior_ptid, base_magic_null_ptid)
287       || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
288     beneath->to_fetch_registers (beneath, regcache, regnum);
289   else
290     current_arch_ops->to_fetch_registers (regcache, regnum);
291 }
292
293 static void
294 ravenscar_store_registers (struct target_ops *ops,
295                            struct regcache *regcache, int regnum)
296 {
297   struct target_ops *beneath = find_target_beneath (ops);
298
299   if (!ravenscar_runtime_initialized ()
300       || ptid_equal (inferior_ptid, base_magic_null_ptid)
301       || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
302     beneath->to_store_registers (beneath, regcache, regnum);
303   else
304     current_arch_ops->to_store_registers (regcache, regnum);
305 }
306
307 static void
308 ravenscar_prepare_to_store (struct regcache *regcache)
309 {
310   struct target_ops *beneath = find_target_beneath (&ravenscar_ops);
311
312   if (!ravenscar_runtime_initialized ()
313       || ptid_equal (inferior_ptid, base_magic_null_ptid)
314       || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
315     beneath->to_prepare_to_store (regcache);
316   else
317     current_arch_ops->to_prepare_to_store (regcache);
318 }
319
320 static void
321 ravenscar_mourn_inferior (struct target_ops *ops)
322 {
323   struct target_ops *beneath = find_target_beneath (&ravenscar_ops);
324
325   base_ptid = null_ptid;
326   beneath->to_mourn_inferior (beneath);
327   unpush_target (&ravenscar_ops);
328 }
329
330 /* Observer on inferior_created: push ravenscar thread stratum if needed.  */
331
332 static void
333 ravenscar_inferior_created (struct target_ops *target, int from_tty)
334 {
335   if (ravenscar_task_support
336       && has_ravenscar_runtime ())
337     ravenscar_initialize (NULL, 0);
338 }
339
340 void
341 ravenscar_register_arch_ops (struct ravenscar_arch_ops *ops)
342 {
343   /* FIXME: To be clean, we would need to handle a list of
344      architectures, just like in remote-wtx-hw.c.  However, for now the
345      only Ravenscar run-time for bare board that is implemented in
346      GNAT is for only one architecture: erc32-elf.  So no need to care about
347      that for now...  */
348   current_arch_ops = ops;
349 }
350
351 /* Initialize Ravenscar support.  */
352
353 static void
354 ravenscar_initialize (char *name, int from_tty)
355 {
356   if (ravenscar_is_open)
357     return;
358
359   base_magic_null_ptid = inferior_ptid;
360   ravenscar_update_inferior_ptid ();
361   push_target (&ravenscar_ops);
362   ravenscar_is_open = 1;
363 }
364
365 static ptid_t
366 ravenscar_get_ada_task_ptid (long lwp, long thread)
367 {
368   return ptid_build (ptid_get_pid (base_ptid), 0, thread);
369 }
370
371 static void
372 init_ravenscar_thread_ops (void)
373 {
374   ravenscar_ops.to_shortname = "ravenscar";
375   ravenscar_ops.to_longname = "Ravenscar tasks.";
376   ravenscar_ops.to_doc = "Ravenscar tasks support.";
377   ravenscar_ops.to_close = ravenscar_close;
378   ravenscar_ops.to_resume = ravenscar_resume;
379   ravenscar_ops.to_wait = ravenscar_wait;
380   ravenscar_ops.to_fetch_registers = ravenscar_fetch_registers;
381   ravenscar_ops.to_store_registers = ravenscar_store_registers;
382   ravenscar_ops.to_prepare_to_store = ravenscar_prepare_to_store;
383   ravenscar_ops.to_thread_alive = ravenscar_thread_alive;
384   ravenscar_ops.to_find_new_threads = ravenscar_find_new_threads;
385   ravenscar_ops.to_pid_to_str = ravenscar_pid_to_str;
386   ravenscar_ops.to_extra_thread_info = ravenscar_extra_thread_info;
387   ravenscar_ops.to_get_ada_task_ptid = ravenscar_get_ada_task_ptid;
388   ravenscar_ops.to_mourn_inferior = ravenscar_mourn_inferior;
389   ravenscar_ops.to_has_all_memory = default_child_has_all_memory;
390   ravenscar_ops.to_has_memory = default_child_has_memory;
391   ravenscar_ops.to_has_stack = default_child_has_stack;
392   ravenscar_ops.to_has_registers = default_child_has_registers;
393   ravenscar_ops.to_has_execution = default_child_has_execution;
394   ravenscar_ops.to_stratum = thread_stratum;
395   ravenscar_ops.to_magic = OPS_MAGIC;
396 }
397
398 /* Command-list for the "set/show ravenscar" prefix command.  */
399 static struct cmd_list_element *set_ravenscar_list;
400 static struct cmd_list_element *show_ravenscar_list;
401
402 /* Implement the "set ravenscar" prefix command.  */
403
404 static void
405 set_ravenscar_command (char *arg, int from_tty)
406 {
407   printf_unfiltered (_(\
408 "\"set ravenscar\" must be followed by the name of a setting.\n"));
409   help_list (set_ravenscar_list, "set ravenscar ", -1, gdb_stdout);
410 }
411
412 /* Implement the "show ravenscar" prefix command.  */
413
414 static void
415 show_ravenscar_command (char *args, int from_tty)
416 {
417   cmd_show_list (show_ravenscar_list, from_tty, "");
418 }
419
420 /* Implement the "show ravenscar task-switching" command.  */
421
422 static void
423 show_ravenscar_task_switching_command (struct ui_file *file, int from_tty,
424                                        struct cmd_list_element *c,
425                                        const char *value)
426 {
427   if (ravenscar_task_support)
428     fprintf_filtered (file, _("\
429 Support for Ravenscar task/thread switching is enabled\n"));
430   else
431     fprintf_filtered (file, _("\
432 Support for Ravenscar task/thread switching is disabled\n"));
433 }
434
435 /* Provide a prototype to silence -Wmissing-prototypes.  */
436 extern void _initialize_ravenscar (void);
437
438 /* Module startup initialization function, automagically called by
439    init.c.  */
440
441 void
442 _initialize_ravenscar (void)
443 {
444   init_ravenscar_thread_ops ();
445   base_ptid = null_ptid;
446
447   /* Notice when the inferior is created in order to push the
448      ravenscar ops if needed.  */
449   observer_attach_inferior_created (ravenscar_inferior_created);
450
451   add_target (&ravenscar_ops);
452
453   add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command,
454                   _("Prefix command for changing Ravenscar-specific settings"),
455                   &set_ravenscar_list, "set ravenscar ", 0, &setlist);
456
457   add_prefix_cmd ("ravenscar", no_class, show_ravenscar_command,
458                   _("Prefix command for showing Ravenscar-specific settings"),
459                   &show_ravenscar_list, "show ravenscar ", 0, &showlist);
460
461   add_setshow_boolean_cmd ("task-switching", class_obscure,
462                            &ravenscar_task_support, _("\
463 Enable or disable support for GNAT Ravenscar tasks"), _("\
464 Show whether support for GNAT Ravenscar tasks is enabled"),
465                            _("\
466 Enable or disable support for task/thread switching with the GNAT\n\
467 Ravenscar run-time library for bareboard configuration."),
468                            NULL, show_ravenscar_task_switching_command,
469                            &set_ravenscar_list, &show_ravenscar_list);
470 }