X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fravenscar-thread.c;h=ef825073a96132a5ff748cb5aae3ed62965820a5;hb=c6ef89f56b506f7279d98fad13360bce30c06022;hp=63ecad5440a39faa1bd4a68706222529ea09608f;hpb=0b30217134add051e159a192066a1e568ebd837f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c index 63ecad5440..ef825073a9 100644 --- a/gdb/ravenscar-thread.c +++ b/gdb/ravenscar-thread.c @@ -1,6 +1,6 @@ /* Ada Ravenscar thread support. - Copyright 2004, 2009-2012 Free Software Foundation, Inc. + Copyright (C) 2004-2015 Free Software Foundation, Inc. This file is part of GDB. @@ -26,18 +26,14 @@ #include "command.h" #include "ravenscar-thread.h" #include "observer.h" -#include "gdb_string.h" #include "gdbcmd.h" #include "top.h" #include "regcache.h" +#include "objfiles.h" /* If non-null, ravenscar task support is enabled. */ static int ravenscar_task_support = 1; -/* Non-null if the ravenscar thread layer has been pushed on the target - stack. */ -static int ravenscar_is_open = 0; - /* This module's target-specific operations. */ static struct target_ops ravenscar_ops; @@ -56,23 +52,19 @@ static const char first_task_name[] = "system__tasking__debug__first_task"; static const char ravenscar_runtime_initializer[] = "system__bb__threads__initialize"; -static struct observer *update_target_observer = NULL; - -/* Architecture-specific hooks. */ -static struct ravenscar_arch_ops* current_arch_ops; - -static void ravenscar_find_new_threads (struct target_ops *ops); +static void ravenscar_update_thread_list (struct target_ops *ops); static ptid_t ravenscar_running_thread (void); -static char *ravenscar_extra_thread_info (struct thread_info *tp); +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 regcache *regcache); -static void ravenscar_initialize (char *name, int from_tty); +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 target_signal siggnal); + 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); @@ -99,7 +91,7 @@ ravenscar_update_inferior_ptid (void) gdb_assert (!ptid_equal (inferior_ptid, null_ptid)); /* The running thread may not have been added to - system.tasking.debug's list yet; so ravenscar_find_new_threads + 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); @@ -110,13 +102,13 @@ ravenscar_update_inferior_ptid (void) and return its associated minimal symbol. Return NULL if not found. */ -static struct minimal_symbol * +static struct bound_minimal_symbol get_running_thread_msymbol (void) { - struct minimal_symbol *msym; + struct bound_minimal_symbol msym; msym = lookup_minimal_symbol (running_thread_name, NULL, NULL); - if (!msym) + if (!msym.minsym) /* Older versions of the GNAT runtime were using a different (less ideal) name for the symbol where the active thread ID is stored. If we couldn't find the symbol using the latest @@ -132,17 +124,18 @@ get_running_thread_msymbol (void) static int has_ravenscar_runtime (void) { - struct minimal_symbol *msym_ravenscar_runtime_initializer = + struct bound_minimal_symbol msym_ravenscar_runtime_initializer = lookup_minimal_symbol (ravenscar_runtime_initializer, NULL, NULL); - struct minimal_symbol *msym_known_tasks = + struct bound_minimal_symbol msym_known_tasks = lookup_minimal_symbol (known_tasks_name, NULL, NULL); - struct minimal_symbol *msym_first_task = + struct bound_minimal_symbol msym_first_task = lookup_minimal_symbol (first_task_name, NULL, NULL); - struct minimal_symbol *msym_running_thread = get_running_thread_msymbol (); + struct bound_minimal_symbol msym_running_thread + = get_running_thread_msymbol (); - return (msym_ravenscar_runtime_initializer - && (msym_known_tasks || msym_first_task) - && msym_running_thread); + return (msym_ravenscar_runtime_initializer.minsym + && (msym_known_tasks.minsym || msym_first_task.minsym) + && msym_running_thread.minsym); } /* Return True if the Ada Ravenscar run-time can be found in the @@ -160,18 +153,18 @@ ravenscar_runtime_initialized (void) static CORE_ADDR get_running_thread_id (void) { - const struct minimal_symbol *object_msym = get_running_thread_msymbol (); + struct bound_minimal_symbol object_msym = get_running_thread_msymbol (); int object_size; int buf_size; - char *buf; + gdb_byte *buf; CORE_ADDR object_addr; struct type *builtin_type_void_data_ptr = - builtin_type (target_gdbarch)->builtin_data_ptr; + builtin_type (target_gdbarch ())->builtin_data_ptr; - if (!object_msym) + if (!object_msym.minsym) return 0; - object_addr = SYMBOL_VALUE_ADDRESS (object_msym); + object_addr = BMSYMBOL_VALUE_ADDRESS (object_msym); object_size = TYPE_LENGTH (builtin_type_void_data_ptr); buf_size = object_size; buf = alloca (buf_size); @@ -179,15 +172,9 @@ get_running_thread_id (void) return extract_typed_address (buf, builtin_type_void_data_ptr); } -static void -ravenscar_close (int quitting) -{ - ravenscar_is_open = 0; -} - static void ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step, - enum target_signal siggnal) + enum gdb_signal siggnal) { struct target_ops *beneath = find_target_beneath (ops); @@ -204,8 +191,19 @@ ravenscar_wait (struct target_ops *ops, ptid_t ptid, inferior_ptid = base_ptid; beneath->to_wait (beneath, base_ptid, status, 0); - ravenscar_find_new_threads (ops); - ravenscar_update_inferior_ptid (); + /* Find any new threads that might have been created, and update + inferior_ptid to the active thread. + + Only do it if the program is still alive, though. Otherwise, + this causes problems when debugging through the remote protocol, + because we might try switching threads (and thus sending packets) + after the remote has disconnected. */ + if (status->kind != TARGET_WAITKIND_EXITED + && status->kind != TARGET_WAITKIND_SIGNALLED) + { + ravenscar_update_thread_list (ops); + ravenscar_update_inferior_ptid (); + } return inferior_ptid; } @@ -220,7 +218,7 @@ ravenscar_add_thread (struct ada_task_info *task) } static void -ravenscar_find_new_threads (struct target_ops *ops) +ravenscar_update_thread_list (struct target_ops *ops) { ada_build_task_list (); @@ -244,7 +242,7 @@ ravenscar_running_thread (void) } static char * -ravenscar_extra_thread_info (struct thread_info *tp) +ravenscar_extra_thread_info (struct target_ops *self, struct thread_info *tp) { return "Ravenscar task"; } @@ -276,7 +274,13 @@ ravenscar_fetch_registers (struct target_ops *ops, || ptid_equal (inferior_ptid, ravenscar_running_thread ())) beneath->to_fetch_registers (beneath, regcache, regnum); else - current_arch_ops->to_fetch_registers (regcache, regnum); + { + 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 @@ -290,26 +294,39 @@ ravenscar_store_registers (struct target_ops *ops, || ptid_equal (inferior_ptid, ravenscar_running_thread ())) beneath->to_store_registers (beneath, regcache, regnum); else - current_arch_ops->to_store_registers (regcache, regnum); + { + 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 regcache *regcache) +ravenscar_prepare_to_store (struct target_ops *self, + struct regcache *regcache) { - struct target_ops *beneath = find_target_beneath (&ravenscar_ops); + 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 (regcache); + beneath->to_prepare_to_store (beneath, regcache); else - current_arch_ops->to_prepare_to_store (regcache); + { + 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 (&ravenscar_ops); + struct target_ops *beneath = find_target_beneath (ops); base_ptid = null_ptid; beneath->to_mourn_inferior (beneath); @@ -321,38 +338,20 @@ ravenscar_mourn_inferior (struct target_ops *ops) static void ravenscar_inferior_created (struct target_ops *target, int from_tty) { - if (ravenscar_task_support - && has_ravenscar_runtime ()) - ravenscar_initialize (NULL, 0); -} - -void -ravenscar_register_arch_ops (struct ravenscar_arch_ops *ops) -{ - /* FIXME: To be clean, we would need to handle a list of - architectures, just like in remote-wtx-hw.c. However, for now the - only Ravenscar run-time for bare board that is implemented in - GNAT is for only one architecture: erc32-elf. So no need to care about - that for now... */ - current_arch_ops = ops; -} - -/* Initialize Ravenscar support. */ + struct ravenscar_arch_ops *ops; -static void -ravenscar_initialize (char *name, int from_tty) -{ - if (ravenscar_is_open) + 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); - ravenscar_is_open = 1; } static ptid_t -ravenscar_get_ada_task_ptid (long lwp, long thread) +ravenscar_get_ada_task_ptid (struct target_ops *self, long lwp, long thread) { return ptid_build (ptid_get_pid (base_ptid), 0, thread); } @@ -363,14 +362,13 @@ 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_close = ravenscar_close; 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_find_new_threads = ravenscar_find_new_threads; + 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; @@ -395,7 +393,7 @@ 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 ", -1, gdb_stdout); + help_list (set_ravenscar_list, "set ravenscar ", all_commands, gdb_stdout); } /* Implement the "show ravenscar" prefix command. */ @@ -421,6 +419,9 @@ Support for Ravenscar task/thread switching is enabled\n")); Support for Ravenscar task/thread switching is disabled\n")); } +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern void _initialize_ravenscar (void); + /* Module startup initialization function, automagically called by init.c. */ @@ -434,7 +435,7 @@ _initialize_ravenscar (void) ravenscar ops if needed. */ observer_attach_inferior_created (ravenscar_inferior_created); - add_target (&ravenscar_ops); + complete_target_initialization (&ravenscar_ops); add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command, _("Prefix command for changing Ravenscar-specific settings"),