gdb/ravenscar-thread.c - gdb
Global variables defined
Functions defined
Source code
- #include "defs.h"
- #include "gdbcore.h"
- #include "gdbthread.h"
- #include "ada-lang.h"
- #include "target.h"
- #include "inferior.h"
- #include "command.h"
- #include "ravenscar-thread.h"
- #include "observer.h"
- #include "gdbcmd.h"
- #include "top.h"
- #include "regcache.h"
- #include "objfiles.h"
- static int ravenscar_task_support = 1;
- static struct target_ops ravenscar_ops;
- static ptid_t base_magic_null_ptid;
- static ptid_t base_ptid;
- static const char running_thread_name[] = "__gnat_running_thread_table";
- static const char known_tasks_name[] = "system__tasking__debug__known_tasks";
- static const char first_task_name[] = "system__tasking__debug__first_task";
- static const char ravenscar_runtime_initializer[] =
- "system__bb__threads__initialize";
- static void ravenscar_update_thread_list (struct target_ops *ops);
- static ptid_t ravenscar_running_thread (void);
- static char *ravenscar_extra_thread_info (struct target_ops *self,
- struct thread_info *tp);
- static int ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid);
- static void ravenscar_fetch_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum);
- static void ravenscar_store_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum);
- static void ravenscar_prepare_to_store (struct target_ops *self,
- struct regcache *regcache);
- static void ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
- enum gdb_signal siggnal);
- static void ravenscar_mourn_inferior (struct target_ops *ops);
- static void ravenscar_update_inferior_ptid (void);
- static int has_ravenscar_runtime (void);
- static int ravenscar_runtime_initialized (void);
- static void ravenscar_inferior_created (struct target_ops *target,
- int from_tty);
- static void
- ravenscar_update_inferior_ptid (void)
- {
- base_ptid = inferior_ptid;
-
- if (!ravenscar_runtime_initialized ())
- return;
-
- inferior_ptid = ravenscar_running_thread ();
- gdb_assert (!ptid_equal (inferior_ptid, null_ptid));
-
- if (!find_thread_ptid (inferior_ptid))
- add_thread (inferior_ptid);
- }
- static struct bound_minimal_symbol
- get_running_thread_msymbol (void)
- {
- struct bound_minimal_symbol msym;
- msym = lookup_minimal_symbol (running_thread_name, NULL, NULL);
- if (!msym.minsym)
-
- msym = lookup_minimal_symbol ("running_thread", NULL, NULL);
- return msym;
- }
- static int
- has_ravenscar_runtime (void)
- {
- struct bound_minimal_symbol msym_ravenscar_runtime_initializer =
- lookup_minimal_symbol (ravenscar_runtime_initializer, NULL, NULL);
- struct bound_minimal_symbol msym_known_tasks =
- lookup_minimal_symbol (known_tasks_name, NULL, NULL);
- struct bound_minimal_symbol msym_first_task =
- lookup_minimal_symbol (first_task_name, NULL, NULL);
- struct bound_minimal_symbol msym_running_thread
- = get_running_thread_msymbol ();
- return (msym_ravenscar_runtime_initializer.minsym
- && (msym_known_tasks.minsym || msym_first_task.minsym)
- && msym_running_thread.minsym);
- }
- static int
- ravenscar_runtime_initialized (void)
- {
- return (!(ptid_equal (ravenscar_running_thread (), null_ptid)));
- }
- static CORE_ADDR
- get_running_thread_id (void)
- {
- struct bound_minimal_symbol object_msym = get_running_thread_msymbol ();
- int object_size;
- int buf_size;
- gdb_byte *buf;
- CORE_ADDR object_addr;
- struct type *builtin_type_void_data_ptr =
- builtin_type (target_gdbarch ())->builtin_data_ptr;
- if (!object_msym.minsym)
- return 0;
- object_addr = BMSYMBOL_VALUE_ADDRESS (object_msym);
- object_size = TYPE_LENGTH (builtin_type_void_data_ptr);
- buf_size = object_size;
- buf = alloca (buf_size);
- read_memory (object_addr, buf, buf_size);
- return extract_typed_address (buf, builtin_type_void_data_ptr);
- }
- static void
- ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
- enum gdb_signal siggnal)
- {
- struct target_ops *beneath = find_target_beneath (ops);
- inferior_ptid = base_ptid;
- beneath->to_resume (beneath, base_ptid, step, siggnal);
- }
- static ptid_t
- ravenscar_wait (struct target_ops *ops, ptid_t ptid,
- struct target_waitstatus *status,
- int options)
- {
- struct target_ops *beneath = find_target_beneath (ops);
- inferior_ptid = base_ptid;
- beneath->to_wait (beneath, base_ptid, status, 0);
-
- if (status->kind != TARGET_WAITKIND_EXITED
- && status->kind != TARGET_WAITKIND_SIGNALLED)
- {
- ravenscar_update_thread_list (ops);
- ravenscar_update_inferior_ptid ();
- }
- return inferior_ptid;
- }
- static void
- ravenscar_add_thread (struct ada_task_info *task)
- {
- if (find_thread_ptid (task->ptid) == NULL)
- add_thread (task->ptid);
- }
- static void
- ravenscar_update_thread_list (struct target_ops *ops)
- {
- ada_build_task_list ();
-
- iterate_over_live_ada_tasks (ravenscar_add_thread);
- }
- static ptid_t
- ravenscar_running_thread (void)
- {
- CORE_ADDR tid = get_running_thread_id ();
- if (tid == 0)
- return null_ptid;
- else
- return ptid_build (ptid_get_pid (base_ptid), 0, tid);
- }
- static char *
- ravenscar_extra_thread_info (struct target_ops *self, struct thread_info *tp)
- {
- return "Ravenscar task";
- }
- static int
- ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid)
- {
-
- return 1;
- }
- static char *
- ravenscar_pid_to_str (struct target_ops *ops, ptid_t ptid)
- {
- static char buf[30];
- snprintf (buf, sizeof (buf), "Thread %#x", (int) ptid_get_tid (ptid));
- return buf;
- }
- static void
- ravenscar_fetch_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
- {
- struct target_ops *beneath = find_target_beneath (ops);
- if (!ravenscar_runtime_initialized ()
- || ptid_equal (inferior_ptid, base_magic_null_ptid)
- || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
- beneath->to_fetch_registers (beneath, regcache, regnum);
- else
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct ravenscar_arch_ops *arch_ops
- = gdbarch_ravenscar_ops (gdbarch);
- arch_ops->to_fetch_registers (regcache, regnum);
- }
- }
- static void
- ravenscar_store_registers (struct target_ops *ops,
- struct regcache *regcache, int regnum)
- {
- struct target_ops *beneath = find_target_beneath (ops);
- if (!ravenscar_runtime_initialized ()
- || ptid_equal (inferior_ptid, base_magic_null_ptid)
- || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
- beneath->to_store_registers (beneath, regcache, regnum);
- else
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct ravenscar_arch_ops *arch_ops
- = gdbarch_ravenscar_ops (gdbarch);
- arch_ops->to_store_registers (regcache, regnum);
- }
- }
- static void
- ravenscar_prepare_to_store (struct target_ops *self,
- struct regcache *regcache)
- {
- struct target_ops *beneath = find_target_beneath (self);
- if (!ravenscar_runtime_initialized ()
- || ptid_equal (inferior_ptid, base_magic_null_ptid)
- || ptid_equal (inferior_ptid, ravenscar_running_thread ()))
- beneath->to_prepare_to_store (beneath, regcache);
- else
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct ravenscar_arch_ops *arch_ops
- = gdbarch_ravenscar_ops (gdbarch);
- arch_ops->to_prepare_to_store (regcache);
- }
- }
- static void
- ravenscar_mourn_inferior (struct target_ops *ops)
- {
- struct target_ops *beneath = find_target_beneath (ops);
- base_ptid = null_ptid;
- beneath->to_mourn_inferior (beneath);
- unpush_target (&ravenscar_ops);
- }
- static void
- ravenscar_inferior_created (struct target_ops *target, int from_tty)
- {
- struct ravenscar_arch_ops *ops;
- if (!ravenscar_task_support
- || gdbarch_ravenscar_ops (current_inferior ()->gdbarch) == NULL
- || !has_ravenscar_runtime ())
- return;
- base_magic_null_ptid = inferior_ptid;
- ravenscar_update_inferior_ptid ();
- push_target (&ravenscar_ops);
- }
- static ptid_t
- ravenscar_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
- {
- return ptid_build (ptid_get_pid (base_ptid), 0, thread);
- }
- static void
- init_ravenscar_thread_ops (void)
- {
- ravenscar_ops.to_shortname = "ravenscar";
- ravenscar_ops.to_longname = "Ravenscar tasks.";
- ravenscar_ops.to_doc = "Ravenscar tasks support.";
- ravenscar_ops.to_resume = ravenscar_resume;
- ravenscar_ops.to_wait = ravenscar_wait;
- ravenscar_ops.to_fetch_registers = ravenscar_fetch_registers;
- ravenscar_ops.to_store_registers = ravenscar_store_registers;
- ravenscar_ops.to_prepare_to_store = ravenscar_prepare_to_store;
- ravenscar_ops.to_thread_alive = ravenscar_thread_alive;
- ravenscar_ops.to_update_thread_list = ravenscar_update_thread_list;
- ravenscar_ops.to_pid_to_str = ravenscar_pid_to_str;
- ravenscar_ops.to_extra_thread_info = ravenscar_extra_thread_info;
- ravenscar_ops.to_get_ada_task_ptid = ravenscar_get_ada_task_ptid;
- ravenscar_ops.to_mourn_inferior = ravenscar_mourn_inferior;
- ravenscar_ops.to_has_all_memory = default_child_has_all_memory;
- ravenscar_ops.to_has_memory = default_child_has_memory;
- ravenscar_ops.to_has_stack = default_child_has_stack;
- ravenscar_ops.to_has_registers = default_child_has_registers;
- ravenscar_ops.to_has_execution = default_child_has_execution;
- ravenscar_ops.to_stratum = thread_stratum;
- ravenscar_ops.to_magic = OPS_MAGIC;
- }
- static struct cmd_list_element *set_ravenscar_list;
- static struct cmd_list_element *show_ravenscar_list;
- static void
- set_ravenscar_command (char *arg, int from_tty)
- {
- printf_unfiltered (_(\
- "\"set ravenscar\" must be followed by the name of a setting.\n"));
- help_list (set_ravenscar_list, "set ravenscar ", all_commands, gdb_stdout);
- }
- static void
- show_ravenscar_command (char *args, int from_tty)
- {
- cmd_show_list (show_ravenscar_list, from_tty, "");
- }
- static void
- show_ravenscar_task_switching_command (struct ui_file *file, int from_tty,
- struct cmd_list_element *c,
- const char *value)
- {
- if (ravenscar_task_support)
- fprintf_filtered (file, _("\
- Support for Ravenscar task/thread switching is enabled\n"));
- else
- fprintf_filtered (file, _("\
- Support for Ravenscar task/thread switching is disabled\n"));
- }
- extern void _initialize_ravenscar (void);
- void
- _initialize_ravenscar (void)
- {
- init_ravenscar_thread_ops ();
- base_ptid = null_ptid;
-
- observer_attach_inferior_created (ravenscar_inferior_created);
- complete_target_initialization (&ravenscar_ops);
- add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command,
- _("Prefix command for changing Ravenscar-specific settings"),
- &set_ravenscar_list, "set ravenscar ", 0, &setlist);
- add_prefix_cmd ("ravenscar", no_class, show_ravenscar_command,
- _("Prefix command for showing Ravenscar-specific settings"),
- &show_ravenscar_list, "show ravenscar ", 0, &showlist);
- add_setshow_boolean_cmd ("task-switching", class_obscure,
- &ravenscar_task_support, _("\
- Enable or disable support for GNAT Ravenscar tasks"), _("\
- Show whether support for GNAT Ravenscar tasks is enabled"),
- _("\
- Enable or disable support for task/thread switching with the GNAT\n\
- Ravenscar run-time library for bareboard configuration."),
- NULL, show_ravenscar_task_switching_command,
- &set_ravenscar_list, &show_ravenscar_list);
- }