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