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