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