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