Add target_ops argument to to_extra_thread_info
[external/binutils.git] / gdb / ravenscar-thread.c
1 /* Ada Ravenscar thread support.
2
3    Copyright (C) 2004-2014 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 <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 /* This module's target-specific operations.  */
38 static struct target_ops ravenscar_ops;
39
40 /* Some base target uses a special value for the null PID (exempli gratia
41    remote).  */
42 static ptid_t base_magic_null_ptid;
43
44 /* Ptid of the inferior as seen by the process stratum.  */
45 static ptid_t base_ptid;
46
47 static const char running_thread_name[] = "__gnat_running_thread_table";
48
49 static const char known_tasks_name[] = "system__tasking__debug__known_tasks";
50 static const char first_task_name[] = "system__tasking__debug__first_task";
51
52 static const char ravenscar_runtime_initializer[] =
53   "system__bb__threads__initialize";
54
55 static void ravenscar_find_new_threads (struct target_ops *ops);
56 static ptid_t ravenscar_running_thread (void);
57 static char *ravenscar_extra_thread_info (struct target_ops *self,
58                                           struct thread_info *tp);
59 static int ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid);
60 static void ravenscar_fetch_registers (struct target_ops *ops,
61                                        struct regcache *regcache, int regnum);
62 static void ravenscar_store_registers (struct target_ops *ops,
63                                        struct regcache *regcache, int regnum);
64 static void ravenscar_prepare_to_store (struct target_ops *self,
65                                         struct regcache *regcache);
66 static void ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
67                               enum gdb_signal siggnal);
68 static void ravenscar_mourn_inferior (struct target_ops *ops);
69 static void ravenscar_update_inferior_ptid (void);
70 static int has_ravenscar_runtime (void);
71 static int ravenscar_runtime_initialized (void);
72 static void ravenscar_inferior_created (struct target_ops *target,
73                                         int from_tty);
74
75 /* Fetch the ravenscar running thread from target memory and
76    update inferior_ptid accordingly.  */
77
78 static void
79 ravenscar_update_inferior_ptid (void)
80 {
81   base_ptid = inferior_ptid;
82
83   /* If the runtime has not been initialized yet, the inferior_ptid is
84      the only ptid that there is.  */
85   if (!ravenscar_runtime_initialized ())
86     return;
87
88   /* Make sure we set base_ptid before calling ravenscar_running_thread
89      as the latter relies on it.  */
90   inferior_ptid = ravenscar_running_thread ();
91   gdb_assert (!ptid_equal (inferior_ptid, null_ptid));
92
93   /* The running thread may not have been added to
94      system.tasking.debug's list yet; so ravenscar_find_new_threads
95      may not always add it to the thread list.  Add it here.  */
96   if (!find_thread_ptid (inferior_ptid))
97     add_thread (inferior_ptid);
98 }
99
100 /* The Ravenscar Runtime exports a symbol which contains the ID of
101    the thread that is currently running.  Try to locate that symbol
102    and return its associated minimal symbol.
103    Return NULL if not found.  */
104
105 static struct minimal_symbol *
106 get_running_thread_msymbol (void)
107 {
108   struct minimal_symbol *msym;
109
110   msym = lookup_minimal_symbol (running_thread_name, NULL, NULL);
111   if (!msym)
112     /* Older versions of the GNAT runtime were using a different
113        (less ideal) name for the symbol where the active thread ID
114        is stored.  If we couldn't find the symbol using the latest
115        name, then try the old one.  */
116     msym = lookup_minimal_symbol ("running_thread", NULL, NULL);
117
118   return msym;
119 }
120
121 /* Return True if the Ada Ravenscar run-time can be found in the
122    application.  */
123
124 static int
125 has_ravenscar_runtime (void)
126 {
127   struct minimal_symbol *msym_ravenscar_runtime_initializer =
128     lookup_minimal_symbol (ravenscar_runtime_initializer, NULL, NULL);
129   struct minimal_symbol *msym_known_tasks =
130     lookup_minimal_symbol (known_tasks_name, NULL, NULL);
131   struct minimal_symbol *msym_first_task =
132     lookup_minimal_symbol (first_task_name, NULL, NULL);
133   struct minimal_symbol *msym_running_thread = get_running_thread_msymbol ();
134
135   return (msym_ravenscar_runtime_initializer
136           && (msym_known_tasks || msym_first_task)
137           && msym_running_thread);
138 }
139
140 /* Return True if the Ada Ravenscar run-time can be found in the
141    application, and if it has been initialized on target.  */
142
143 static int
144 ravenscar_runtime_initialized (void)
145 {
146   return (!(ptid_equal (ravenscar_running_thread (), null_ptid)));
147 }
148
149 /* Return the ID of the thread that is currently running.
150    Return 0 if the ID could not be determined.  */
151
152 static CORE_ADDR
153 get_running_thread_id (void)
154 {
155   const struct minimal_symbol *object_msym = get_running_thread_msymbol ();
156   int object_size;
157   int buf_size;
158   gdb_byte *buf;
159   CORE_ADDR object_addr;
160   struct type *builtin_type_void_data_ptr =
161     builtin_type (target_gdbarch ())->builtin_data_ptr;
162
163   if (!object_msym)
164     return 0;
165
166   object_addr = SYMBOL_VALUE_ADDRESS (object_msym);
167   object_size = TYPE_LENGTH (builtin_type_void_data_ptr);
168   buf_size = object_size;
169   buf = alloca (buf_size);
170   read_memory (object_addr, buf, buf_size);
171   return extract_typed_address (buf, builtin_type_void_data_ptr);
172 }
173
174 static void
175 ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
176                   enum gdb_signal siggnal)
177 {
178   struct target_ops *beneath = find_target_beneath (ops);
179
180   inferior_ptid = base_ptid;
181   beneath->to_resume (beneath, base_ptid, step, siggnal);
182 }
183
184 static ptid_t
185 ravenscar_wait (struct target_ops *ops, ptid_t ptid,
186                 struct target_waitstatus *status,
187                 int options)
188 {
189   struct target_ops *beneath = find_target_beneath (ops);
190
191   inferior_ptid = base_ptid;
192   beneath->to_wait (beneath, base_ptid, status, 0);
193   /* Find any new threads that might have been created, and update
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     }
206   return inferior_ptid;
207 }
208
209 /* Add the thread associated to the given TASK to the thread list
210    (if the thread has already been added, this is a no-op).  */
211
212 static void
213 ravenscar_add_thread (struct ada_task_info *task)
214 {
215   if (find_thread_ptid (task->ptid) == NULL)
216     add_thread (task->ptid);
217 }
218
219 static void
220 ravenscar_find_new_threads (struct target_ops *ops)
221 {
222   ada_build_task_list ();
223
224   /* Do not clear the thread list before adding the Ada task, to keep
225      the thread that the process stratum has included into it
226      (base_ptid) and the running thread, that may not have been included
227      to system.tasking.debug's list yet.  */
228
229   iterate_over_live_ada_tasks (ravenscar_add_thread);
230 }
231
232 static ptid_t
233 ravenscar_running_thread (void)
234 {
235   CORE_ADDR tid = get_running_thread_id ();
236
237   if (tid == 0)
238     return null_ptid;
239   else
240     return ptid_build (ptid_get_pid (base_ptid), 0, tid);
241 }
242
243 static char *
244 ravenscar_extra_thread_info (struct target_ops *self, struct thread_info *tp)
245 {
246   return "Ravenscar task";
247 }
248
249 static int
250 ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid)
251 {
252   /* Ravenscar tasks are non-terminating.  */
253   return 1;
254 }
255
256 static char *
257 ravenscar_pid_to_str (struct target_ops *ops, ptid_t ptid)
258 {
259   static char buf[30];
260
261   snprintf (buf, sizeof (buf), "Thread %#x", (int) ptid_get_tid (ptid));
262   return buf;
263 }
264
265 static void
266 ravenscar_fetch_registers (struct target_ops *ops,
267                            struct regcache *regcache, int regnum)
268 {
269   struct target_ops *beneath = find_target_beneath (ops);
270
271   if (!ravenscar_runtime_initialized ()
272       || ptid_equal (inferior_ptid, base_magic_null_ptid)
273       || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
274     beneath->to_fetch_registers (beneath, regcache, regnum);
275   else
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     }
283 }
284
285 static void
286 ravenscar_store_registers (struct target_ops *ops,
287                            struct regcache *regcache, int regnum)
288 {
289   struct target_ops *beneath = find_target_beneath (ops);
290
291   if (!ravenscar_runtime_initialized ()
292       || ptid_equal (inferior_ptid, base_magic_null_ptid)
293       || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
294     beneath->to_store_registers (beneath, regcache, regnum);
295   else
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     }
303 }
304
305 static void
306 ravenscar_prepare_to_store (struct target_ops *self,
307                             struct regcache *regcache)
308 {
309   struct target_ops *beneath = find_target_beneath (&ravenscar_ops);
310
311   if (!ravenscar_runtime_initialized ()
312       || ptid_equal (inferior_ptid, base_magic_null_ptid)
313       || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
314     beneath->to_prepare_to_store (beneath, regcache);
315   else
316     {
317       struct gdbarch *gdbarch = get_regcache_arch (regcache);
318       struct ravenscar_arch_ops *arch_ops
319         = gdbarch_ravenscar_ops (gdbarch);
320
321       arch_ops->to_prepare_to_store (regcache);
322     }
323 }
324
325 static void
326 ravenscar_mourn_inferior (struct target_ops *ops)
327 {
328   struct target_ops *beneath = find_target_beneath (&ravenscar_ops);
329
330   base_ptid = null_ptid;
331   beneath->to_mourn_inferior (beneath);
332   unpush_target (&ravenscar_ops);
333 }
334
335 /* Observer on inferior_created: push ravenscar thread stratum if needed.  */
336
337 static void
338 ravenscar_inferior_created (struct target_ops *target, int from_tty)
339 {
340   struct ravenscar_arch_ops *ops;
341
342   if (!ravenscar_task_support
343       || gdbarch_ravenscar_ops (current_inferior ()->gdbarch) == NULL
344       || !has_ravenscar_runtime ())
345     return;
346
347   base_magic_null_ptid = inferior_ptid;
348   ravenscar_update_inferior_ptid ();
349   push_target (&ravenscar_ops);
350 }
351
352 static ptid_t
353 ravenscar_get_ada_task_ptid (long lwp, long thread)
354 {
355   return ptid_build (ptid_get_pid (base_ptid), 0, thread);
356 }
357
358 static void
359 init_ravenscar_thread_ops (void)
360 {
361   ravenscar_ops.to_shortname = "ravenscar";
362   ravenscar_ops.to_longname = "Ravenscar tasks.";
363   ravenscar_ops.to_doc = "Ravenscar tasks support.";
364   ravenscar_ops.to_resume = ravenscar_resume;
365   ravenscar_ops.to_wait = ravenscar_wait;
366   ravenscar_ops.to_fetch_registers = ravenscar_fetch_registers;
367   ravenscar_ops.to_store_registers = ravenscar_store_registers;
368   ravenscar_ops.to_prepare_to_store = ravenscar_prepare_to_store;
369   ravenscar_ops.to_thread_alive = ravenscar_thread_alive;
370   ravenscar_ops.to_find_new_threads = ravenscar_find_new_threads;
371   ravenscar_ops.to_pid_to_str = ravenscar_pid_to_str;
372   ravenscar_ops.to_extra_thread_info = ravenscar_extra_thread_info;
373   ravenscar_ops.to_get_ada_task_ptid = ravenscar_get_ada_task_ptid;
374   ravenscar_ops.to_mourn_inferior = ravenscar_mourn_inferior;
375   ravenscar_ops.to_has_all_memory = default_child_has_all_memory;
376   ravenscar_ops.to_has_memory = default_child_has_memory;
377   ravenscar_ops.to_has_stack = default_child_has_stack;
378   ravenscar_ops.to_has_registers = default_child_has_registers;
379   ravenscar_ops.to_has_execution = default_child_has_execution;
380   ravenscar_ops.to_stratum = thread_stratum;
381   ravenscar_ops.to_magic = OPS_MAGIC;
382 }
383
384 /* Command-list for the "set/show ravenscar" prefix command.  */
385 static struct cmd_list_element *set_ravenscar_list;
386 static struct cmd_list_element *show_ravenscar_list;
387
388 /* Implement the "set ravenscar" prefix command.  */
389
390 static void
391 set_ravenscar_command (char *arg, int from_tty)
392 {
393   printf_unfiltered (_(\
394 "\"set ravenscar\" must be followed by the name of a setting.\n"));
395   help_list (set_ravenscar_list, "set ravenscar ", -1, gdb_stdout);
396 }
397
398 /* Implement the "show ravenscar" prefix command.  */
399
400 static void
401 show_ravenscar_command (char *args, int from_tty)
402 {
403   cmd_show_list (show_ravenscar_list, from_tty, "");
404 }
405
406 /* Implement the "show ravenscar task-switching" command.  */
407
408 static void
409 show_ravenscar_task_switching_command (struct ui_file *file, int from_tty,
410                                        struct cmd_list_element *c,
411                                        const char *value)
412 {
413   if (ravenscar_task_support)
414     fprintf_filtered (file, _("\
415 Support for Ravenscar task/thread switching is enabled\n"));
416   else
417     fprintf_filtered (file, _("\
418 Support for Ravenscar task/thread switching is disabled\n"));
419 }
420
421 /* Provide a prototype to silence -Wmissing-prototypes.  */
422 extern void _initialize_ravenscar (void);
423
424 /* Module startup initialization function, automagically called by
425    init.c.  */
426
427 void
428 _initialize_ravenscar (void)
429 {
430   init_ravenscar_thread_ops ();
431   base_ptid = null_ptid;
432
433   /* Notice when the inferior is created in order to push the
434      ravenscar ops if needed.  */
435   observer_attach_inferior_created (ravenscar_inferior_created);
436
437   complete_target_initialization (&ravenscar_ops);
438
439   add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command,
440                   _("Prefix command for changing Ravenscar-specific settings"),
441                   &set_ravenscar_list, "set ravenscar ", 0, &setlist);
442
443   add_prefix_cmd ("ravenscar", no_class, show_ravenscar_command,
444                   _("Prefix command for showing Ravenscar-specific settings"),
445                   &show_ravenscar_list, "show ravenscar ", 0, &showlist);
446
447   add_setshow_boolean_cmd ("task-switching", class_obscure,
448                            &ravenscar_task_support, _("\
449 Enable or disable support for GNAT Ravenscar tasks"), _("\
450 Show whether support for GNAT Ravenscar tasks is enabled"),
451                            _("\
452 Enable or disable support for task/thread switching with the GNAT\n\
453 Ravenscar run-time library for bareboard configuration."),
454                            NULL, show_ravenscar_task_switching_command,
455                            &set_ravenscar_list, &show_ravenscar_list);
456 }