X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fravenscar-thread.c;h=f3b4ecf8706ad84ce9b20272b755b0a2fbbf6ab1;hb=b6cdac4b80c1d32726227305e16483cef9d40e2c;hp=95c4046724163b15582e61a2acb9b4f47fab5d65;hpb=7657f14df7c697792b626efbd24ac44ad5642485;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c index 95c4046724..f3b4ecf870 100644 --- a/gdb/ravenscar-thread.c +++ b/gdb/ravenscar-thread.c @@ -1,6 +1,6 @@ /* Ada Ravenscar thread support. - Copyright (C) 2004-2019 Free Software Foundation, Inc. + Copyright (C) 2004-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -57,21 +57,16 @@ is running, switching to its corresponding ptid, and then performing the operation on that ptid using the target beneath us. */ -/* If non-null, ravenscar task support is enabled. */ -static int ravenscar_task_support = 1; - -/* PTID of the last thread that received an event. - This can be useful to determine the associated task that received - the event, to make it the current task. */ -static ptid_t base_ptid; +/* If true, ravenscar task support is enabled. */ +static bool ravenscar_task_support = true; 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 const char ravenscar_runtime_initializer[] + = "system__bb__threads__initialize"; static const target_info ravenscar_target_info = { "ravenscar", @@ -81,6 +76,11 @@ static const target_info ravenscar_target_info = { struct ravenscar_thread_target final : public target_ops { + ravenscar_thread_target () + { + update_inferior_ptid (); + } + const target_info &info () const override { return ravenscar_target_info; } @@ -110,26 +110,33 @@ struct ravenscar_thread_target final : public target_ops const char *extra_thread_info (struct thread_info *) override; - const char *pid_to_str (ptid_t) override; + std::string pid_to_str (ptid_t) override; ptid_t get_ada_task_ptid (long lwp, long thread) override; void mourn_inferior () override; -}; -/* This module's target-specific operations. */ -static ravenscar_thread_target ravenscar_ops; + void close () override + { + delete this; + } -static ptid_t ravenscar_active_task (int cpu); -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); +private: -/* Return nonzero iff PTID corresponds to a ravenscar task. */ + /* PTID of the last thread that received an event. + This can be useful to determine the associated task that received + the event, to make it the current task. */ + ptid_t m_base_ptid = null_ptid; -static int + void update_inferior_ptid (); + ptid_t active_task (int cpu); + bool task_is_currently_active (ptid_t ptid); + bool runtime_initialized (); +}; + +/* Return true iff PTID corresponds to a ravenscar task. */ + +static bool is_ravenscar_task (ptid_t ptid) { /* By construction, ravenscar tasks have their LWP set to zero. @@ -169,7 +176,7 @@ ravenscar_get_thread_base_cpu (ptid_t ptid) return base_cpu; } -/* Given a ravenscar task (identified by its ptid_t PTID), return nonzero +/* Given a ravenscar task (identified by its ptid_t PTID), return true if this task is the currently active task on the cpu that task is running on. @@ -179,11 +186,11 @@ ravenscar_get_thread_base_cpu (ptid_t ptid) that task's registers are in the CPU bank. Otherwise, the task is currently suspended, and its registers have been saved in memory. */ -static int -ravenscar_task_is_currently_active (ptid_t ptid) +bool +ravenscar_thread_target::task_is_currently_active (ptid_t ptid) { ptid_t active_task_ptid - = ravenscar_active_task (ravenscar_get_thread_base_cpu (ptid)); + = active_task (ravenscar_get_thread_base_cpu (ptid)); return ptid == active_task_ptid; } @@ -209,31 +216,34 @@ get_base_thread_from_ravenscar_task (ptid_t ptid) /* Fetch the ravenscar running thread from target memory and update inferior_ptid accordingly. */ -static void -ravenscar_update_inferior_ptid (void) +void +ravenscar_thread_target::update_inferior_ptid () { + process_stratum_target *proc_target + = as_process_stratum_target (this->beneath ()); + int base_cpu; - base_ptid = inferior_ptid; + m_base_ptid = inferior_ptid; gdb_assert (!is_ravenscar_task (inferior_ptid)); - base_cpu = ravenscar_get_thread_base_cpu (base_ptid); + base_cpu = ravenscar_get_thread_base_cpu (m_base_ptid); /* If the runtime has not been initialized yet, the inferior_ptid is the only ptid that there is. */ - if (!ravenscar_runtime_initialized ()) + if (!runtime_initialized ()) return; - /* Make sure we set base_ptid before calling ravenscar_active_task + /* Make sure we set m_base_ptid before calling active_task as the latter relies on it. */ - inferior_ptid = ravenscar_active_task (base_cpu); + inferior_ptid = active_task (base_cpu); gdb_assert (inferior_ptid != null_ptid); /* The running thread may not have been added to system.tasking.debug's list yet; so ravenscar_update_thread_list may not always add it to the thread list. Add it here. */ - if (!find_thread_ptid (inferior_ptid)) - add_thread (inferior_ptid); + if (!find_thread_ptid (proc_target, inferior_ptid)) + add_thread (proc_target, inferior_ptid); } /* The Ravenscar Runtime exports a symbol which contains the ID of @@ -242,7 +252,7 @@ ravenscar_update_inferior_ptid (void) Return NULL if not found. */ static struct bound_minimal_symbol -get_running_thread_msymbol (void) +get_running_thread_msymbol () { struct bound_minimal_symbol msym; @@ -260,15 +270,15 @@ get_running_thread_msymbol (void) /* Return True if the Ada Ravenscar run-time can be found in the application. */ -static int -has_ravenscar_runtime (void) +static bool +has_ravenscar_runtime () { - 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_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 (); @@ -280,10 +290,10 @@ has_ravenscar_runtime (void) /* Return True if the Ada Ravenscar run-time can be found in the application, and if it has been initialized on target. */ -static int -ravenscar_runtime_initialized (void) +bool +ravenscar_thread_target::runtime_initialized () { - return (!(ravenscar_active_task (1) == null_ptid)); + return active_task (1) != null_ptid; } /* Return the ID of the thread that is currently running. @@ -297,8 +307,8 @@ get_running_thread_id (int cpu) int buf_size; gdb_byte *buf; CORE_ADDR object_addr; - struct type *builtin_type_void_data_ptr = - builtin_type (target_gdbarch ())->builtin_data_ptr; + struct type *builtin_type_void_data_ptr + = builtin_type (target_gdbarch ())->builtin_data_ptr; if (!object_msym.minsym) return 0; @@ -313,10 +323,15 @@ get_running_thread_id (int cpu) } void -ravenscar_thread_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal) +ravenscar_thread_target::resume (ptid_t ptid, int step, + enum gdb_signal siggnal) { - inferior_ptid = base_ptid; - beneath ()->resume (base_ptid, step, siggnal); + /* If we see a wildcard resume, we simply pass that on. Otherwise, + arrange to resume the base ptid. */ + inferior_ptid = m_base_ptid; + if (ptid != minus_one_ptid) + ptid = m_base_ptid; + beneath ()->resume (ptid, step, siggnal); } ptid_t @@ -324,10 +339,14 @@ ravenscar_thread_target::wait (ptid_t ptid, struct target_waitstatus *status, int options) { + process_stratum_target *beneath + = as_process_stratum_target (this->beneath ()); ptid_t event_ptid; - inferior_ptid = base_ptid; - event_ptid = beneath ()->wait (base_ptid, status, 0); + inferior_ptid = m_base_ptid; + if (ptid != minus_one_ptid) + ptid = m_base_ptid; + event_ptid = beneath->wait (ptid, status, 0); /* Find any new threads that might have been created, and update inferior_ptid to the active thread. @@ -340,8 +359,10 @@ ravenscar_thread_target::wait (ptid_t ptid, { inferior_ptid = event_ptid; this->update_thread_list (); - ravenscar_update_inferior_ptid (); + this->update_inferior_ptid (); } + else + inferior_ptid = m_base_ptid; return inferior_ptid; } @@ -351,32 +372,30 @@ ravenscar_thread_target::wait (ptid_t ptid, static void ravenscar_add_thread (struct ada_task_info *task) { - if (find_thread_ptid (task->ptid) == NULL) - add_thread (task->ptid); + if (find_thread_ptid (current_inferior (), task->ptid) == NULL) + add_thread (current_inferior ()->process_target (), task->ptid); } void ravenscar_thread_target::update_thread_list () { - ada_build_task_list (); - /* Do not clear the thread list before adding the Ada task, to keep the thread that the process stratum has included into it - (base_ptid) and the running thread, that may not have been included + (m_base_ptid) and the running thread, that may not have been included to system.tasking.debug's list yet. */ iterate_over_live_ada_tasks (ravenscar_add_thread); } -static ptid_t -ravenscar_active_task (int cpu) +ptid_t +ravenscar_thread_target::active_task (int cpu) { CORE_ADDR tid = get_running_thread_id (cpu); if (tid == 0) return null_ptid; else - return ptid_t (base_ptid.pid (), 0, tid); + return ptid_t (m_base_ptid.pid (), 0, tid); } const char * @@ -392,13 +411,10 @@ ravenscar_thread_target::thread_alive (ptid_t ptid) return true; } -const char * +std::string ravenscar_thread_target::pid_to_str (ptid_t ptid) { - static char buf[30]; - - snprintf (buf, sizeof (buf), "Thread %#x", (int) ptid.tid ()); - return buf; + return string_printf ("Thread %#x", (int) ptid.tid ()); } void @@ -406,9 +422,9 @@ ravenscar_thread_target::fetch_registers (struct regcache *regcache, int regnum) { ptid_t ptid = regcache->ptid (); - if (ravenscar_runtime_initialized () + if (runtime_initialized () && is_ravenscar_task (ptid) - && !ravenscar_task_is_currently_active (ptid)) + && !task_is_currently_active (ptid)) { struct gdbarch *gdbarch = regcache->arch (); struct ravenscar_arch_ops *arch_ops @@ -426,9 +442,9 @@ ravenscar_thread_target::store_registers (struct regcache *regcache, { ptid_t ptid = regcache->ptid (); - if (ravenscar_runtime_initialized () + if (runtime_initialized () && is_ravenscar_task (ptid) - && !ravenscar_task_is_currently_active (ptid)) + && !task_is_currently_active (ptid)) { struct gdbarch *gdbarch = regcache->arch (); struct ravenscar_arch_ops *arch_ops @@ -445,9 +461,9 @@ ravenscar_thread_target::prepare_to_store (struct regcache *regcache) { ptid_t ptid = regcache->ptid (); - if (ravenscar_runtime_initialized () + if (runtime_initialized () && is_ravenscar_task (ptid) - && !ravenscar_task_is_currently_active (ptid)) + && !task_is_currently_active (ptid)) { /* Nothing. */ } @@ -498,9 +514,10 @@ ravenscar_thread_target::stopped_data_address (CORE_ADDR *addr_p) void ravenscar_thread_target::mourn_inferior () { - base_ptid = null_ptid; - beneath ()->mourn_inferior (); - unpush_target (&ravenscar_ops); + m_base_ptid = null_ptid; + target_ops *beneath = this->beneath (); + unpush_target (this); + beneath->mourn_inferior (); } /* Implement the to_core_of_thread target_ops "method". */ @@ -532,38 +549,20 @@ ravenscar_inferior_created (struct target_ops *target, int from_tty) return; } - ravenscar_update_inferior_ptid (); - push_target (&ravenscar_ops); + target_ops_up target_holder (new ravenscar_thread_target ()); + push_target (std::move (target_holder)); } ptid_t ravenscar_thread_target::get_ada_task_ptid (long lwp, long thread) { - return ptid_t (base_ptid.pid (), 0, thread); + return ptid_t (m_base_ptid.pid (), 0, thread); } /* Command-list for the "set/show ravenscar" prefix command. */ static struct cmd_list_element *set_ravenscar_list; static struct cmd_list_element *show_ravenscar_list; -/* Implement the "set ravenscar" prefix command. */ - -static void -set_ravenscar_command (const 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); -} - -/* Implement the "show ravenscar" prefix command. */ - -static void -show_ravenscar_command (const char *args, int from_tty) -{ - cmd_show_list (show_ravenscar_list, from_tty, ""); -} - /* Implement the "show ravenscar task-switching" command. */ static void @@ -582,27 +581,26 @@ Support for Ravenscar task/thread switching is disabled\n")); /* Module startup initialization function, automagically called by init.c. */ +void _initialize_ravenscar (); void -_initialize_ravenscar (void) +_initialize_ravenscar () { - base_ptid = null_ptid; - /* Notice when the inferior is created in order to push the ravenscar ops if needed. */ gdb::observers::inferior_created.attach (ravenscar_inferior_created); - add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command, - _("Prefix command for changing Ravenscar-specific settings"), - &set_ravenscar_list, "set ravenscar ", 0, &setlist); + add_basic_prefix_cmd ("ravenscar", no_class, + _("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_show_prefix_cmd ("ravenscar", no_class, + _("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 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."),