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