1 1.1 christos /* Code dealing with dummy stack frames, for GDB, the GNU debugger. 2 1.1 christos 3 1.11 christos Copyright (C) 1986-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos 21 1.1 christos #include "dummy-frame.h" 22 1.1 christos #include "regcache.h" 23 1.1 christos #include "frame.h" 24 1.1 christos #include "inferior.h" 25 1.1 christos #include "frame-unwind.h" 26 1.1 christos #include "command.h" 27 1.11 christos #include "cli/cli-cmds.h" 28 1.8 christos #include "observable.h" 29 1.1 christos #include "gdbthread.h" 30 1.5 christos #include "infcall.h" 31 1.9 christos #include "gdbarch.h" 32 1.1 christos 33 1.3 christos struct dummy_frame_id 34 1.3 christos { 35 1.3 christos /* This frame's ID. Must match the value returned by 36 1.3 christos gdbarch_dummy_id. */ 37 1.3 christos struct frame_id id; 38 1.3 christos 39 1.3 christos /* The thread this dummy_frame relates to. */ 40 1.8 christos thread_info *thread; 41 1.3 christos }; 42 1.3 christos 43 1.3 christos /* Return whether dummy_frame_id *ID1 and *ID2 are equal. */ 44 1.3 christos 45 1.3 christos static int 46 1.3 christos dummy_frame_id_eq (struct dummy_frame_id *id1, 47 1.3 christos struct dummy_frame_id *id2) 48 1.3 christos { 49 1.10 christos return id1->id == id2->id && id1->thread == id2->thread; 50 1.3 christos } 51 1.3 christos 52 1.5 christos /* List of dummy_frame destructors. */ 53 1.5 christos 54 1.5 christos struct dummy_frame_dtor_list 55 1.5 christos { 56 1.5 christos /* Next element in the list or NULL if this is the last element. */ 57 1.5 christos struct dummy_frame_dtor_list *next; 58 1.5 christos 59 1.5 christos /* If non-NULL, a destructor that is run when this dummy frame is freed. */ 60 1.5 christos dummy_frame_dtor_ftype *dtor; 61 1.5 christos 62 1.5 christos /* Arbitrary data that is passed to DTOR. */ 63 1.5 christos void *dtor_data; 64 1.5 christos }; 65 1.5 christos 66 1.1 christos /* Dummy frame. This saves the processor state just prior to setting 67 1.1 christos up the inferior function call. Older targets save the registers 68 1.1 christos on the target stack (but that really slows down function calls). */ 69 1.1 christos 70 1.1 christos struct dummy_frame 71 1.1 christos { 72 1.1 christos struct dummy_frame *next; 73 1.3 christos 74 1.3 christos /* An id represents a dummy frame. */ 75 1.3 christos struct dummy_frame_id id; 76 1.3 christos 77 1.1 christos /* The caller's state prior to the call. */ 78 1.1 christos struct infcall_suspend_state *caller_state; 79 1.3 christos 80 1.5 christos /* First element of destructors list or NULL if there are no 81 1.5 christos destructors registered for this dummy_frame. */ 82 1.5 christos struct dummy_frame_dtor_list *dtor_list; 83 1.1 christos }; 84 1.1 christos 85 1.1 christos static struct dummy_frame *dummy_frame_stack = NULL; 86 1.1 christos 87 1.1 christos /* Push the caller's state, along with the dummy frame info, onto the 88 1.1 christos dummy-frame stack. */ 89 1.1 christos 90 1.1 christos void 91 1.1 christos dummy_frame_push (struct infcall_suspend_state *caller_state, 92 1.8 christos const frame_id *dummy_id, thread_info *thread) 93 1.1 christos { 94 1.1 christos struct dummy_frame *dummy_frame; 95 1.1 christos 96 1.3 christos dummy_frame = XCNEW (struct dummy_frame); 97 1.1 christos dummy_frame->caller_state = caller_state; 98 1.3 christos dummy_frame->id.id = (*dummy_id); 99 1.8 christos dummy_frame->id.thread = thread; 100 1.1 christos dummy_frame->next = dummy_frame_stack; 101 1.1 christos dummy_frame_stack = dummy_frame; 102 1.1 christos } 103 1.1 christos 104 1.1 christos /* Remove *DUMMY_PTR from the dummy frame stack. */ 105 1.1 christos 106 1.1 christos static void 107 1.1 christos remove_dummy_frame (struct dummy_frame **dummy_ptr) 108 1.1 christos { 109 1.1 christos struct dummy_frame *dummy = *dummy_ptr; 110 1.1 christos 111 1.5 christos while (dummy->dtor_list != NULL) 112 1.5 christos { 113 1.5 christos struct dummy_frame_dtor_list *list = dummy->dtor_list; 114 1.5 christos 115 1.5 christos dummy->dtor_list = list->next; 116 1.5 christos list->dtor (list->dtor_data, 0); 117 1.5 christos xfree (list); 118 1.5 christos } 119 1.5 christos 120 1.1 christos *dummy_ptr = dummy->next; 121 1.1 christos discard_infcall_suspend_state (dummy->caller_state); 122 1.1 christos xfree (dummy); 123 1.1 christos } 124 1.1 christos 125 1.1 christos /* Delete any breakpoint B which is a momentary breakpoint for return from 126 1.1 christos inferior call matching DUMMY_VOIDP. */ 127 1.1 christos 128 1.9 christos static bool 129 1.9 christos pop_dummy_frame_bpt (struct breakpoint *b, struct dummy_frame *dummy) 130 1.1 christos { 131 1.8 christos if (b->thread == dummy->id.thread->global_num 132 1.10 christos && b->disposition == disp_del && b->frame_id == dummy->id.id) 133 1.1 christos { 134 1.1 christos while (b->related_breakpoint != b) 135 1.1 christos delete_breakpoint (b->related_breakpoint); 136 1.1 christos 137 1.1 christos delete_breakpoint (b); 138 1.1 christos 139 1.1 christos /* Stop the traversal. */ 140 1.9 christos return true; 141 1.1 christos } 142 1.1 christos 143 1.1 christos /* Continue the traversal. */ 144 1.9 christos return false; 145 1.1 christos } 146 1.1 christos 147 1.1 christos /* Pop *DUMMY_PTR, restoring program state to that before the 148 1.1 christos frame was created. */ 149 1.1 christos 150 1.1 christos static void 151 1.1 christos pop_dummy_frame (struct dummy_frame **dummy_ptr) 152 1.1 christos { 153 1.1 christos struct dummy_frame *dummy = *dummy_ptr; 154 1.1 christos 155 1.8 christos gdb_assert (dummy->id.thread == inferior_thread ()); 156 1.3 christos 157 1.5 christos while (dummy->dtor_list != NULL) 158 1.5 christos { 159 1.5 christos struct dummy_frame_dtor_list *list = dummy->dtor_list; 160 1.5 christos 161 1.5 christos dummy->dtor_list = list->next; 162 1.5 christos list->dtor (list->dtor_data, 1); 163 1.5 christos xfree (list); 164 1.5 christos } 165 1.3 christos 166 1.1 christos restore_infcall_suspend_state (dummy->caller_state); 167 1.1 christos 168 1.11 christos for (breakpoint &bp : all_breakpoints_safe ()) 169 1.11 christos if (pop_dummy_frame_bpt (&bp, dummy)) 170 1.10 christos break; 171 1.1 christos 172 1.1 christos /* restore_infcall_control_state frees inf_state, 173 1.1 christos all that remains is to pop *dummy_ptr. */ 174 1.1 christos *dummy_ptr = dummy->next; 175 1.1 christos xfree (dummy); 176 1.1 christos 177 1.1 christos /* We've made right mess of GDB's local state, just discard 178 1.1 christos everything. */ 179 1.1 christos reinit_frame_cache (); 180 1.1 christos } 181 1.1 christos 182 1.1 christos /* Look up DUMMY_ID. 183 1.1 christos Return NULL if not found. */ 184 1.1 christos 185 1.1 christos static struct dummy_frame ** 186 1.3 christos lookup_dummy_frame (struct dummy_frame_id *dummy_id) 187 1.1 christos { 188 1.1 christos struct dummy_frame **dp; 189 1.1 christos 190 1.1 christos for (dp = &dummy_frame_stack; *dp != NULL; dp = &(*dp)->next) 191 1.1 christos { 192 1.3 christos if (dummy_frame_id_eq (&(*dp)->id, dummy_id)) 193 1.1 christos return dp; 194 1.1 christos } 195 1.1 christos 196 1.1 christos return NULL; 197 1.1 christos } 198 1.1 christos 199 1.8 christos /* Find the dummy frame by DUMMY_ID and THREAD, and pop it, restoring 200 1.3 christos program state to that before the frame was created. 201 1.1 christos On return reinit_frame_cache has been called. 202 1.3 christos If the frame isn't found, flag an internal error. */ 203 1.1 christos 204 1.1 christos void 205 1.8 christos dummy_frame_pop (frame_id dummy_id, thread_info *thread) 206 1.1 christos { 207 1.1 christos struct dummy_frame **dp; 208 1.8 christos struct dummy_frame_id id = { dummy_id, thread }; 209 1.1 christos 210 1.3 christos dp = lookup_dummy_frame (&id); 211 1.1 christos gdb_assert (dp != NULL); 212 1.1 christos 213 1.1 christos pop_dummy_frame (dp); 214 1.1 christos } 215 1.1 christos 216 1.3 christos /* Find the dummy frame by DUMMY_ID and PTID and drop it. Do nothing 217 1.3 christos if it is not found. Do not restore its state into inferior, just 218 1.3 christos free its memory. */ 219 1.1 christos 220 1.1 christos void 221 1.8 christos dummy_frame_discard (struct frame_id dummy_id, thread_info *thread) 222 1.1 christos { 223 1.1 christos struct dummy_frame **dp; 224 1.8 christos struct dummy_frame_id id = { dummy_id, thread }; 225 1.1 christos 226 1.3 christos dp = lookup_dummy_frame (&id); 227 1.1 christos if (dp) 228 1.1 christos remove_dummy_frame (dp); 229 1.1 christos } 230 1.1 christos 231 1.3 christos /* See dummy-frame.h. */ 232 1.3 christos 233 1.3 christos void 234 1.8 christos register_dummy_frame_dtor (frame_id dummy_id, thread_info *thread, 235 1.3 christos dummy_frame_dtor_ftype *dtor, void *dtor_data) 236 1.3 christos { 237 1.8 christos struct dummy_frame_id id = { dummy_id, thread }; 238 1.3 christos struct dummy_frame **dp, *d; 239 1.5 christos struct dummy_frame_dtor_list *list; 240 1.3 christos 241 1.3 christos dp = lookup_dummy_frame (&id); 242 1.3 christos gdb_assert (dp != NULL); 243 1.3 christos d = *dp; 244 1.6 christos list = XNEW (struct dummy_frame_dtor_list); 245 1.5 christos list->next = d->dtor_list; 246 1.5 christos d->dtor_list = list; 247 1.5 christos list->dtor = dtor; 248 1.5 christos list->dtor_data = dtor_data; 249 1.3 christos } 250 1.3 christos 251 1.3 christos /* See dummy-frame.h. */ 252 1.3 christos 253 1.3 christos int 254 1.3 christos find_dummy_frame_dtor (dummy_frame_dtor_ftype *dtor, void *dtor_data) 255 1.3 christos { 256 1.3 christos struct dummy_frame *d; 257 1.3 christos 258 1.3 christos for (d = dummy_frame_stack; d != NULL; d = d->next) 259 1.5 christos { 260 1.5 christos struct dummy_frame_dtor_list *list; 261 1.5 christos 262 1.5 christos for (list = d->dtor_list; list != NULL; list = list->next) 263 1.5 christos if (list->dtor == dtor && list->dtor_data == dtor_data) 264 1.5 christos return 1; 265 1.5 christos } 266 1.3 christos return 0; 267 1.3 christos } 268 1.3 christos 269 1.1 christos /* There may be stale dummy frames, perhaps left over from when an uncaught 270 1.1 christos longjmp took us out of a function that was called by the debugger. Clean 271 1.1 christos them up at least once whenever we start a new inferior. */ 272 1.1 christos 273 1.1 christos static void 274 1.10 christos cleanup_dummy_frames (inferior *inf) 275 1.1 christos { 276 1.1 christos while (dummy_frame_stack != NULL) 277 1.1 christos remove_dummy_frame (&dummy_frame_stack); 278 1.1 christos } 279 1.1 christos 280 1.1 christos /* Return the dummy frame cache, it contains both the ID, and a 281 1.1 christos pointer to the regcache. */ 282 1.1 christos struct dummy_frame_cache 283 1.1 christos { 284 1.1 christos struct frame_id this_id; 285 1.8 christos readonly_detached_regcache *prev_regcache; 286 1.1 christos }; 287 1.1 christos 288 1.1 christos static int 289 1.1 christos dummy_frame_sniffer (const struct frame_unwind *self, 290 1.11 christos const frame_info_ptr &this_frame, 291 1.1 christos void **this_prologue_cache) 292 1.1 christos { 293 1.1 christos /* When unwinding a normal frame, the stack structure is determined 294 1.1 christos by analyzing the frame's function's code (be it using brute force 295 1.1 christos prologue analysis, or the dwarf2 CFI). In the case of a dummy 296 1.1 christos frame, that simply isn't possible. The PC is either the program 297 1.1 christos entry point, or some random address on the stack. Trying to use 298 1.1 christos that PC to apply standard frame ID unwind techniques is just 299 1.1 christos asking for trouble. */ 300 1.1 christos 301 1.1 christos /* Don't bother unless there is at least one dummy frame. */ 302 1.1 christos if (dummy_frame_stack != NULL) 303 1.1 christos { 304 1.3 christos struct dummy_frame *dummyframe; 305 1.1 christos /* Use an architecture specific method to extract this frame's 306 1.1 christos dummy ID, assuming it is a dummy frame. */ 307 1.3 christos struct frame_id this_id 308 1.3 christos = gdbarch_dummy_id (get_frame_arch (this_frame), this_frame); 309 1.8 christos struct dummy_frame_id dummy_id = { this_id, inferior_thread () }; 310 1.1 christos 311 1.1 christos /* Use that ID to find the corresponding cache entry. */ 312 1.1 christos for (dummyframe = dummy_frame_stack; 313 1.1 christos dummyframe != NULL; 314 1.1 christos dummyframe = dummyframe->next) 315 1.1 christos { 316 1.3 christos if (dummy_frame_id_eq (&dummyframe->id, &dummy_id)) 317 1.1 christos { 318 1.1 christos struct dummy_frame_cache *cache; 319 1.1 christos 320 1.1 christos cache = FRAME_OBSTACK_ZALLOC (struct dummy_frame_cache); 321 1.1 christos cache->prev_regcache = get_infcall_suspend_state_regcache 322 1.1 christos (dummyframe->caller_state); 323 1.1 christos cache->this_id = this_id; 324 1.1 christos (*this_prologue_cache) = cache; 325 1.1 christos return 1; 326 1.1 christos } 327 1.1 christos } 328 1.1 christos } 329 1.1 christos return 0; 330 1.1 christos } 331 1.1 christos 332 1.1 christos /* Given a call-dummy dummy-frame, return the registers. Here the 333 1.1 christos register value is taken from the local copy of the register buffer. */ 334 1.1 christos 335 1.1 christos static struct value * 336 1.11 christos dummy_frame_prev_register (const frame_info_ptr &this_frame, 337 1.1 christos void **this_prologue_cache, 338 1.1 christos int regnum) 339 1.1 christos { 340 1.6 christos struct dummy_frame_cache *cache 341 1.6 christos = (struct dummy_frame_cache *) *this_prologue_cache; 342 1.1 christos struct gdbarch *gdbarch = get_frame_arch (this_frame); 343 1.1 christos struct value *reg_val; 344 1.1 christos 345 1.1 christos /* The dummy-frame sniffer always fills in the cache. */ 346 1.1 christos gdb_assert (cache != NULL); 347 1.1 christos 348 1.1 christos /* Describe the register's location. Generic dummy frames always 349 1.1 christos have the register value in an ``expression''. */ 350 1.11 christos reg_val = value::zero (register_type (gdbarch, regnum), not_lval); 351 1.1 christos 352 1.1 christos /* Use the regcache_cooked_read() method so that it, on the fly, 353 1.1 christos constructs either a raw or pseudo register from the raw 354 1.1 christos register cache. */ 355 1.10 christos cache->prev_regcache->cooked_read 356 1.11 christos (regnum, reg_val->contents_writeable ().data ()); 357 1.1 christos return reg_val; 358 1.1 christos } 359 1.1 christos 360 1.1 christos /* Assuming that THIS_FRAME is a dummy, return its ID. That ID is 361 1.1 christos determined by examining the NEXT frame's unwound registers using 362 1.1 christos the method dummy_id(). As a side effect, THIS dummy frame's 363 1.1 christos dummy cache is located and saved in THIS_PROLOGUE_CACHE. */ 364 1.1 christos 365 1.1 christos static void 366 1.11 christos dummy_frame_this_id (const frame_info_ptr &this_frame, 367 1.1 christos void **this_prologue_cache, 368 1.1 christos struct frame_id *this_id) 369 1.1 christos { 370 1.1 christos /* The dummy-frame sniffer always fills in the cache. */ 371 1.6 christos struct dummy_frame_cache *cache 372 1.6 christos = (struct dummy_frame_cache *) *this_prologue_cache; 373 1.1 christos 374 1.1 christos gdb_assert (cache != NULL); 375 1.1 christos (*this_id) = cache->this_id; 376 1.1 christos } 377 1.1 christos 378 1.1 christos const struct frame_unwind dummy_frame_unwind = 379 1.1 christos { 380 1.10 christos "dummy", 381 1.1 christos DUMMY_FRAME, 382 1.1 christos default_frame_unwind_stop_reason, 383 1.1 christos dummy_frame_this_id, 384 1.1 christos dummy_frame_prev_register, 385 1.1 christos NULL, 386 1.1 christos dummy_frame_sniffer, 387 1.1 christos }; 388 1.1 christos 389 1.8 christos /* See dummy-frame.h. */ 390 1.8 christos 391 1.8 christos struct frame_id 392 1.11 christos default_dummy_id (struct gdbarch *gdbarch, const frame_info_ptr &this_frame) 393 1.8 christos { 394 1.8 christos CORE_ADDR sp, pc; 395 1.8 christos 396 1.8 christos sp = get_frame_sp (this_frame); 397 1.8 christos pc = get_frame_pc (this_frame); 398 1.8 christos return frame_id_build (sp, pc); 399 1.8 christos } 400 1.8 christos 401 1.1 christos static void 402 1.1 christos fprint_dummy_frames (struct ui_file *file) 403 1.1 christos { 404 1.1 christos struct dummy_frame *s; 405 1.1 christos 406 1.1 christos for (s = dummy_frame_stack; s != NULL; s = s->next) 407 1.10 christos gdb_printf (file, "%s: id=%s, ptid=%s\n", 408 1.10 christos host_address_to_string (s), 409 1.10 christos s->id.id.to_string ().c_str (), 410 1.10 christos s->id.thread->ptid.to_string ().c_str ()); 411 1.1 christos } 412 1.1 christos 413 1.1 christos static void 414 1.8 christos maintenance_print_dummy_frames (const char *args, int from_tty) 415 1.1 christos { 416 1.1 christos if (args == NULL) 417 1.1 christos fprint_dummy_frames (gdb_stdout); 418 1.1 christos else 419 1.1 christos { 420 1.7 christos stdio_file file; 421 1.1 christos 422 1.7 christos if (!file.open (args, "w")) 423 1.1 christos perror_with_name (_("maintenance print dummy-frames")); 424 1.7 christos fprint_dummy_frames (&file); 425 1.1 christos } 426 1.1 christos } 427 1.1 christos 428 1.9 christos void _initialize_dummy_frame (); 429 1.1 christos void 430 1.9 christos _initialize_dummy_frame () 431 1.1 christos { 432 1.1 christos add_cmd ("dummy-frames", class_maintenance, maintenance_print_dummy_frames, 433 1.1 christos _("Print the contents of the internal dummy-frame stack."), 434 1.1 christos &maintenanceprintlist); 435 1.1 christos 436 1.10 christos gdb::observers::inferior_created.attach (cleanup_dummy_frames, "dummy-frame"); 437 1.1 christos } 438