1 1.1 christos /* Scheme interface to blocks. 2 1.1 christos 3 1.9 christos Copyright (C) 2008-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 /* See README file in this directory for implementation notes, coding 21 1.1 christos conventions, et.al. */ 22 1.1 christos 23 1.1 christos #include "block.h" 24 1.1 christos #include "dictionary.h" 25 1.1 christos #include "objfiles.h" 26 1.1 christos #include "source.h" 27 1.1 christos #include "symtab.h" 28 1.1 christos #include "guile-internal.h" 29 1.1 christos 30 1.1 christos /* A smob describing a gdb block. */ 31 1.1 christos 32 1.8 christos struct block_smob 33 1.1 christos { 34 1.1 christos /* This always appears first. 35 1.1 christos We want blocks to be eq?-able. And we need to be able to invalidate 36 1.1 christos blocks when the associated objfile is deleted. */ 37 1.1 christos eqable_gdb_smob base; 38 1.1 christos 39 1.1 christos /* The GDB block structure that represents a frame's code block. */ 40 1.1 christos const struct block *block; 41 1.1 christos 42 1.1 christos /* The backing object file. There is no direct relationship in GDB 43 1.1 christos between a block and an object file. When a block is created also 44 1.1 christos store a pointer to the object file for later use. */ 45 1.1 christos struct objfile *objfile; 46 1.8 christos }; 47 1.1 christos 48 1.1 christos /* To iterate over block symbols from Scheme we need to store 49 1.1 christos struct block_iterator somewhere. This is stored in the "progress" field 50 1.1 christos of <gdb:iterator>. We store the block object in iterator_smob.object, 51 1.1 christos so we don't store it here. 52 1.1 christos 53 1.1 christos Remember: While iterating over block symbols, you must continually check 54 1.1 christos whether the block is still valid. */ 55 1.1 christos 56 1.8 christos struct block_syms_progress_smob 57 1.1 christos { 58 1.1 christos /* This always appears first. */ 59 1.1 christos gdb_smob base; 60 1.1 christos 61 1.1 christos /* The iterator for that block. */ 62 1.1 christos struct block_iterator iter; 63 1.1 christos 64 1.1 christos /* Has the iterator been initialized flag. */ 65 1.1 christos int initialized_p; 66 1.8 christos }; 67 1.1 christos 68 1.1 christos static const char block_smob_name[] = "gdb:block"; 69 1.1 christos static const char block_syms_progress_smob_name[] = "gdb:block-symbols-iterator"; 70 1.1 christos 71 1.1 christos /* The tag Guile knows the block smobs by. */ 72 1.1 christos static scm_t_bits block_smob_tag; 73 1.1 christos static scm_t_bits block_syms_progress_smob_tag; 74 1.1 christos 75 1.1 christos /* The "next!" block syms iterator method. */ 76 1.1 christos static SCM bkscm_next_symbol_x_proc; 77 1.1 christos 78 1.8 christos /* This is called when an objfile is about to be freed. 79 1.8 christos Invalidate the block as further actions on the block would result 80 1.8 christos in bad data. All access to b_smob->block should be gated by 81 1.8 christos checks to ensure the block is (still) valid. */ 82 1.8 christos struct bkscm_deleter 83 1.8 christos { 84 1.8 christos /* Helper function for bkscm_del_objfile_blocks to mark the block 85 1.8 christos as invalid. */ 86 1.8 christos 87 1.8 christos static int 88 1.8 christos bkscm_mark_block_invalid (void **slot, void *info) 89 1.8 christos { 90 1.8 christos block_smob *b_smob = (block_smob *) *slot; 91 1.8 christos 92 1.8 christos b_smob->block = NULL; 93 1.8 christos b_smob->objfile = NULL; 94 1.8 christos return 1; 95 1.8 christos } 96 1.8 christos 97 1.8 christos void operator() (htab_t htab) 98 1.8 christos { 99 1.8 christos gdb_assert (htab != nullptr); 100 1.8 christos htab_traverse_noresize (htab, bkscm_mark_block_invalid, NULL); 101 1.8 christos htab_delete (htab); 102 1.8 christos } 103 1.8 christos }; 104 1.8 christos 105 1.8 christos static const registry<objfile>::key<htab, bkscm_deleter> 106 1.8 christos bkscm_objfile_data_key; 107 1.1 christos 108 1.1 christos /* Administrivia for block smobs. */ 110 1.1 christos 111 1.1 christos /* Helper function to hash a block_smob. */ 112 1.1 christos 113 1.1 christos static hashval_t 114 1.1 christos bkscm_hash_block_smob (const void *p) 115 1.4 christos { 116 1.1 christos const block_smob *b_smob = (const block_smob *) p; 117 1.1 christos 118 1.1 christos return htab_hash_pointer (b_smob->block); 119 1.1 christos } 120 1.1 christos 121 1.1 christos /* Helper function to compute equality of block_smobs. */ 122 1.1 christos 123 1.1 christos static int 124 1.1 christos bkscm_eq_block_smob (const void *ap, const void *bp) 125 1.4 christos { 126 1.4 christos const block_smob *a = (const block_smob *) ap; 127 1.1 christos const block_smob *b = (const block_smob *) bp; 128 1.1 christos 129 1.1 christos return (a->block == b->block 130 1.1 christos && a->block != NULL); 131 1.1 christos } 132 1.1 christos 133 1.1 christos /* Return the struct block pointer -> SCM mapping table. 134 1.1 christos It is created if necessary. */ 135 1.1 christos 136 1.1 christos static htab_t 137 1.1 christos bkscm_objfile_block_map (struct objfile *objfile) 138 1.8 christos { 139 1.1 christos htab_t htab = bkscm_objfile_data_key.get (objfile); 140 1.1 christos 141 1.1 christos if (htab == NULL) 142 1.1 christos { 143 1.1 christos htab = gdbscm_create_eqable_gsmob_ptr_map (bkscm_hash_block_smob, 144 1.8 christos bkscm_eq_block_smob); 145 1.1 christos bkscm_objfile_data_key.set (objfile, htab); 146 1.1 christos } 147 1.1 christos 148 1.1 christos return htab; 149 1.1 christos } 150 1.1 christos 151 1.1 christos /* The smob "free" function for <gdb:block>. */ 152 1.1 christos 153 1.1 christos static size_t 154 1.1 christos bkscm_free_block_smob (SCM self) 155 1.1 christos { 156 1.1 christos block_smob *b_smob = (block_smob *) SCM_SMOB_DATA (self); 157 1.1 christos 158 1.1 christos if (b_smob->block != NULL) 159 1.1 christos { 160 1.1 christos htab_t htab = bkscm_objfile_block_map (b_smob->objfile); 161 1.1 christos 162 1.1 christos gdbscm_clear_eqable_gsmob_ptr_slot (htab, &b_smob->base); 163 1.1 christos } 164 1.1 christos 165 1.1 christos /* Not necessary, done to catch bugs. */ 166 1.1 christos b_smob->block = NULL; 167 1.1 christos b_smob->objfile = NULL; 168 1.1 christos 169 1.1 christos return 0; 170 1.1 christos } 171 1.1 christos 172 1.1 christos /* The smob "print" function for <gdb:block>. */ 173 1.1 christos 174 1.1 christos static int 175 1.1 christos bkscm_print_block_smob (SCM self, SCM port, scm_print_state *pstate) 176 1.1 christos { 177 1.1 christos block_smob *b_smob = (block_smob *) SCM_SMOB_DATA (self); 178 1.1 christos const struct block *b = b_smob->block; 179 1.1 christos 180 1.1 christos gdbscm_printf (port, "#<%s", block_smob_name); 181 1.8 christos 182 1.1 christos if (b->superblock () == NULL) 183 1.8 christos gdbscm_printf (port, " global"); 184 1.1 christos else if (b->superblock ()->superblock () == NULL) 185 1.1 christos gdbscm_printf (port, " static"); 186 1.8 christos 187 1.8 christos if (b->function () != NULL) 188 1.1 christos gdbscm_printf (port, " %s", b->function ()->print_name ()); 189 1.1 christos 190 1.8 christos gdbscm_printf (port, " %s-%s", 191 1.1 christos hex_string (b->start ()), hex_string (b->end ())); 192 1.1 christos 193 1.1 christos scm_puts (">", port); 194 1.1 christos 195 1.1 christos scm_remember_upto_here_1 (self); 196 1.1 christos 197 1.1 christos /* Non-zero means success. */ 198 1.1 christos return 1; 199 1.1 christos } 200 1.1 christos 201 1.1 christos /* Low level routine to create a <gdb:block> object. */ 202 1.1 christos 203 1.1 christos static SCM 204 1.1 christos bkscm_make_block_smob (void) 205 1.1 christos { 206 1.1 christos block_smob *b_smob = (block_smob *) 207 1.1 christos scm_gc_malloc (sizeof (block_smob), block_smob_name); 208 1.1 christos SCM b_scm; 209 1.1 christos 210 1.1 christos b_smob->block = NULL; 211 1.1 christos b_smob->objfile = NULL; 212 1.1 christos b_scm = scm_new_smob (block_smob_tag, (scm_t_bits) b_smob); 213 1.1 christos gdbscm_init_eqable_gsmob (&b_smob->base, b_scm); 214 1.1 christos 215 1.1 christos return b_scm; 216 1.1 christos } 217 1.1 christos 218 1.1 christos /* Returns non-zero if SCM is a <gdb:block> object. */ 219 1.1 christos 220 1.1 christos static int 221 1.1 christos bkscm_is_block (SCM scm) 222 1.1 christos { 223 1.1 christos return SCM_SMOB_PREDICATE (block_smob_tag, scm); 224 1.1 christos } 225 1.1 christos 226 1.1 christos /* (block? scm) -> boolean */ 227 1.1 christos 228 1.1 christos static SCM 229 1.1 christos gdbscm_block_p (SCM scm) 230 1.1 christos { 231 1.1 christos return scm_from_bool (bkscm_is_block (scm)); 232 1.1 christos } 233 1.1 christos 234 1.1 christos /* Return the existing object that encapsulates BLOCK, or create a new 235 1.1 christos <gdb:block> object. */ 236 1.1 christos 237 1.1 christos SCM 238 1.1 christos bkscm_scm_from_block (const struct block *block, struct objfile *objfile) 239 1.1 christos { 240 1.1 christos htab_t htab; 241 1.1 christos eqable_gdb_smob **slot; 242 1.1 christos block_smob *b_smob, b_smob_for_lookup; 243 1.1 christos SCM b_scm; 244 1.1 christos 245 1.1 christos /* If we've already created a gsmob for this block, return it. 246 1.1 christos This makes blocks eq?-able. */ 247 1.1 christos htab = bkscm_objfile_block_map (objfile); 248 1.1 christos b_smob_for_lookup.block = block; 249 1.1 christos slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &b_smob_for_lookup.base); 250 1.1 christos if (*slot != NULL) 251 1.1 christos return (*slot)->containing_scm; 252 1.1 christos 253 1.1 christos b_scm = bkscm_make_block_smob (); 254 1.1 christos b_smob = (block_smob *) SCM_SMOB_DATA (b_scm); 255 1.1 christos b_smob->block = block; 256 1.1 christos b_smob->objfile = objfile; 257 1.1 christos gdbscm_fill_eqable_gsmob_ptr_slot (slot, &b_smob->base); 258 1.1 christos 259 1.1 christos return b_scm; 260 1.1 christos } 261 1.1 christos 262 1.1 christos /* Returns the <gdb:block> object in SELF. 263 1.1 christos Throws an exception if SELF is not a <gdb:block> object. */ 264 1.1 christos 265 1.1 christos static SCM 266 1.1 christos bkscm_get_block_arg_unsafe (SCM self, int arg_pos, const char *func_name) 267 1.1 christos { 268 1.1 christos SCM_ASSERT_TYPE (bkscm_is_block (self), self, arg_pos, func_name, 269 1.1 christos block_smob_name); 270 1.1 christos 271 1.1 christos return self; 272 1.1 christos } 273 1.1 christos 274 1.1 christos /* Returns a pointer to the block smob of SELF. 275 1.1 christos Throws an exception if SELF is not a <gdb:block> object. */ 276 1.1 christos 277 1.1 christos static block_smob * 278 1.1 christos bkscm_get_block_smob_arg_unsafe (SCM self, int arg_pos, const char *func_name) 279 1.1 christos { 280 1.1 christos SCM b_scm = bkscm_get_block_arg_unsafe (self, arg_pos, func_name); 281 1.1 christos block_smob *b_smob = (block_smob *) SCM_SMOB_DATA (b_scm); 282 1.1 christos 283 1.1 christos return b_smob; 284 1.1 christos } 285 1.1 christos 286 1.1 christos /* Returns non-zero if block B_SMOB is valid. */ 287 1.1 christos 288 1.1 christos static int 289 1.1 christos bkscm_is_valid (block_smob *b_smob) 290 1.1 christos { 291 1.1 christos return b_smob->block != NULL; 292 1.1 christos } 293 1.1 christos 294 1.1 christos /* Returns the block smob in SELF, verifying it's valid. 295 1.1 christos Throws an exception if SELF is not a <gdb:block> object or is invalid. */ 296 1.1 christos 297 1.1 christos static block_smob * 298 1.1 christos bkscm_get_valid_block_smob_arg_unsafe (SCM self, int arg_pos, 299 1.1 christos const char *func_name) 300 1.1 christos { 301 1.1 christos block_smob *b_smob 302 1.1 christos = bkscm_get_block_smob_arg_unsafe (self, arg_pos, func_name); 303 1.1 christos 304 1.1 christos if (!bkscm_is_valid (b_smob)) 305 1.1 christos { 306 1.1 christos gdbscm_invalid_object_error (func_name, arg_pos, self, 307 1.1 christos _("<gdb:block>")); 308 1.1 christos } 309 1.1 christos 310 1.1 christos return b_smob; 311 1.1 christos } 312 1.1 christos 313 1.1 christos /* Returns the block smob contained in SCM or NULL if SCM is not a 314 1.1 christos <gdb:block> object. 315 1.1 christos If there is an error a <gdb:exception> object is stored in *EXCP. */ 316 1.1 christos 317 1.1 christos static block_smob * 318 1.1 christos bkscm_get_valid_block (SCM scm, int arg_pos, const char *func_name, SCM *excp) 319 1.1 christos { 320 1.1 christos block_smob *b_smob; 321 1.1 christos 322 1.1 christos if (!bkscm_is_block (scm)) 323 1.1 christos { 324 1.1 christos *excp = gdbscm_make_type_error (func_name, arg_pos, scm, 325 1.1 christos block_smob_name); 326 1.1 christos return NULL; 327 1.1 christos } 328 1.1 christos 329 1.1 christos b_smob = (block_smob *) SCM_SMOB_DATA (scm); 330 1.1 christos if (!bkscm_is_valid (b_smob)) 331 1.1 christos { 332 1.1 christos *excp = gdbscm_make_invalid_object_error (func_name, arg_pos, scm, 333 1.1 christos _("<gdb:block>")); 334 1.1 christos return NULL; 335 1.1 christos } 336 1.1 christos 337 1.1 christos return b_smob; 338 1.1 christos } 339 1.1 christos 340 1.1 christos /* Returns the struct block that is wrapped by BLOCK_SCM. 341 1.1 christos If BLOCK_SCM is not a block, or is an invalid block, then NULL is returned 342 1.1 christos and a <gdb:exception> object is stored in *EXCP. */ 343 1.1 christos 344 1.1 christos const struct block * 345 1.1 christos bkscm_scm_to_block (SCM block_scm, int arg_pos, const char *func_name, 346 1.1 christos SCM *excp) 347 1.1 christos { 348 1.1 christos block_smob *b_smob; 349 1.1 christos 350 1.1 christos b_smob = bkscm_get_valid_block (block_scm, arg_pos, func_name, excp); 351 1.1 christos 352 1.1 christos if (b_smob != NULL) 353 1.1 christos return b_smob->block; 354 1.1 christos return NULL; 355 1.1 christos } 356 1.1 christos 357 1.1 christos 358 1.1 christos /* Block methods. */ 360 1.1 christos 361 1.1 christos /* (block-valid? <gdb:block>) -> boolean 362 1.1 christos Returns #t if SELF still exists in GDB. */ 363 1.1 christos 364 1.1 christos static SCM 365 1.1 christos gdbscm_block_valid_p (SCM self) 366 1.1 christos { 367 1.1 christos block_smob *b_smob 368 1.1 christos = bkscm_get_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 369 1.1 christos 370 1.1 christos return scm_from_bool (bkscm_is_valid (b_smob)); 371 1.1 christos } 372 1.1 christos 373 1.1 christos /* (block-start <gdb:block>) -> address */ 374 1.1 christos 375 1.1 christos static SCM 376 1.1 christos gdbscm_block_start (SCM self) 377 1.1 christos { 378 1.1 christos block_smob *b_smob 379 1.1 christos = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 380 1.8 christos const struct block *block = b_smob->block; 381 1.1 christos 382 1.1 christos return gdbscm_scm_from_ulongest (block->start ()); 383 1.1 christos } 384 1.1 christos 385 1.1 christos /* (block-end <gdb:block>) -> address */ 386 1.1 christos 387 1.1 christos static SCM 388 1.1 christos gdbscm_block_end (SCM self) 389 1.1 christos { 390 1.1 christos block_smob *b_smob 391 1.1 christos = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 392 1.8 christos const struct block *block = b_smob->block; 393 1.1 christos 394 1.1 christos return gdbscm_scm_from_ulongest (block->end ()); 395 1.1 christos } 396 1.1 christos 397 1.1 christos /* (block-function <gdb:block>) -> <gdb:symbol> */ 398 1.1 christos 399 1.1 christos static SCM 400 1.1 christos gdbscm_block_function (SCM self) 401 1.1 christos { 402 1.1 christos block_smob *b_smob 403 1.1 christos = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 404 1.1 christos const struct block *block = b_smob->block; 405 1.8 christos struct symbol *sym; 406 1.1 christos 407 1.1 christos sym = block->function (); 408 1.1 christos 409 1.1 christos if (sym != NULL) 410 1.1 christos return syscm_scm_from_symbol (sym); 411 1.1 christos return SCM_BOOL_F; 412 1.1 christos } 413 1.1 christos 414 1.1 christos /* (block-superblock <gdb:block>) -> <gdb:block> */ 415 1.1 christos 416 1.1 christos static SCM 417 1.1 christos gdbscm_block_superblock (SCM self) 418 1.1 christos { 419 1.1 christos block_smob *b_smob 420 1.1 christos = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 421 1.1 christos const struct block *block = b_smob->block; 422 1.8 christos const struct block *super_block; 423 1.1 christos 424 1.1 christos super_block = block->superblock (); 425 1.1 christos 426 1.1 christos if (super_block) 427 1.1 christos return bkscm_scm_from_block (super_block, b_smob->objfile); 428 1.1 christos return SCM_BOOL_F; 429 1.1 christos } 430 1.1 christos 431 1.1 christos /* (block-global-block <gdb:block>) -> <gdb:block> 432 1.1 christos Returns the global block associated to this block. */ 433 1.1 christos 434 1.1 christos static SCM 435 1.1 christos gdbscm_block_global_block (SCM self) 436 1.1 christos { 437 1.1 christos block_smob *b_smob 438 1.1 christos = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 439 1.1 christos const struct block *block = b_smob->block; 440 1.9 christos const struct block *global_block; 441 1.1 christos 442 1.1 christos global_block = block->global_block (); 443 1.1 christos 444 1.1 christos return bkscm_scm_from_block (global_block, b_smob->objfile); 445 1.1 christos } 446 1.1 christos 447 1.1 christos /* (block-static-block <gdb:block>) -> <gdb:block> 448 1.1 christos Returns the static block associated to this block. 449 1.1 christos Returns #f if we cannot get the static block (this is the global block). */ 450 1.1 christos 451 1.1 christos static SCM 452 1.1 christos gdbscm_block_static_block (SCM self) 453 1.1 christos { 454 1.1 christos block_smob *b_smob 455 1.1 christos = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 456 1.1 christos const struct block *block = b_smob->block; 457 1.8 christos const struct block *static_block; 458 1.1 christos 459 1.1 christos if (block->superblock () == NULL) 460 1.9 christos return SCM_BOOL_F; 461 1.1 christos 462 1.1 christos static_block = block->static_block (); 463 1.1 christos 464 1.1 christos return bkscm_scm_from_block (static_block, b_smob->objfile); 465 1.1 christos } 466 1.1 christos 467 1.1 christos /* (block-global? <gdb:block>) -> boolean 468 1.1 christos Returns #t if this block object is a global block. */ 469 1.1 christos 470 1.1 christos static SCM 471 1.1 christos gdbscm_block_global_p (SCM self) 472 1.1 christos { 473 1.1 christos block_smob *b_smob 474 1.1 christos = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 475 1.8 christos const struct block *block = b_smob->block; 476 1.1 christos 477 1.1 christos return scm_from_bool (block->superblock () == NULL); 478 1.1 christos } 479 1.1 christos 480 1.1 christos /* (block-static? <gdb:block>) -> boolean 481 1.1 christos Returns #t if this block object is a static block. */ 482 1.1 christos 483 1.1 christos static SCM 484 1.1 christos gdbscm_block_static_p (SCM self) 485 1.1 christos { 486 1.1 christos block_smob *b_smob 487 1.1 christos = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 488 1.8 christos const struct block *block = b_smob->block; 489 1.8 christos 490 1.1 christos if (block->superblock () != NULL 491 1.1 christos && block->superblock ()->superblock () == NULL) 492 1.1 christos return SCM_BOOL_T; 493 1.1 christos return SCM_BOOL_F; 494 1.1 christos } 495 1.1 christos 496 1.1 christos /* (block-symbols <gdb:block>) -> list of <gdb:symbol objects 497 1.1 christos Returns a list of symbols of the block. */ 498 1.1 christos 499 1.1 christos static SCM 500 1.1 christos gdbscm_block_symbols (SCM self) 501 1.1 christos { 502 1.1 christos block_smob *b_smob 503 1.1 christos = bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 504 1.1 christos const struct block *block = b_smob->block; 505 1.1 christos SCM result; 506 1.1 christos 507 1.9 christos result = SCM_EOL; 508 1.1 christos 509 1.1 christos for (struct symbol *sym : block_iterator_range (block)) 510 1.1 christos { 511 1.1 christos SCM s_scm = syscm_scm_from_symbol (sym); 512 1.1 christos 513 1.1 christos result = scm_cons (s_scm, result); 514 1.1 christos } 515 1.1 christos 516 1.1 christos return scm_reverse_x (result, SCM_EOL); 517 1.1 christos } 518 1.1 christos 519 1.1 christos /* The <gdb:block-symbols-iterator> object, 521 1.1 christos for iterating over all symbols in a block. */ 522 1.1 christos 523 1.1 christos /* The smob "print" function for <gdb:block-symbols-iterator>. */ 524 1.1 christos 525 1.1 christos static int 526 1.1 christos bkscm_print_block_syms_progress_smob (SCM self, SCM port, 527 1.1 christos scm_print_state *pstate) 528 1.1 christos { 529 1.1 christos block_syms_progress_smob *i_smob 530 1.1 christos = (block_syms_progress_smob *) SCM_SMOB_DATA (self); 531 1.1 christos 532 1.1 christos gdbscm_printf (port, "#<%s", block_syms_progress_smob_name); 533 1.1 christos 534 1.1 christos if (i_smob->initialized_p) 535 1.1 christos { 536 1.1 christos switch (i_smob->iter.which) 537 1.1 christos { 538 1.1 christos case GLOBAL_BLOCK: 539 1.1 christos case STATIC_BLOCK: 540 1.1 christos { 541 1.1 christos struct compunit_symtab *cust; 542 1.1 christos 543 1.1 christos gdbscm_printf (port, " %s", 544 1.1 christos i_smob->iter.which == GLOBAL_BLOCK 545 1.1 christos ? "global" : "static"); 546 1.1 christos if (i_smob->iter.idx != -1) 547 1.1 christos gdbscm_printf (port, " @%d", i_smob->iter.idx); 548 1.1 christos cust = (i_smob->iter.idx == -1 549 1.1 christos ? i_smob->iter.d.compunit_symtab 550 1.8 christos : i_smob->iter.d.compunit_symtab->includes[i_smob->iter.idx]); 551 1.1 christos gdbscm_printf (port, " %s", 552 1.1 christos symtab_to_filename_for_display 553 1.1 christos (cust->primary_filetab ())); 554 1.1 christos break; 555 1.1 christos } 556 1.1 christos case FIRST_LOCAL_BLOCK: 557 1.1 christos gdbscm_printf (port, " single block"); 558 1.1 christos break; 559 1.1 christos } 560 1.1 christos } 561 1.1 christos else 562 1.1 christos gdbscm_printf (port, " !initialized"); 563 1.1 christos 564 1.1 christos scm_puts (">", port); 565 1.1 christos 566 1.1 christos scm_remember_upto_here_1 (self); 567 1.1 christos 568 1.1 christos /* Non-zero means success. */ 569 1.1 christos return 1; 570 1.1 christos } 571 1.1 christos 572 1.1 christos /* Low level routine to create a <gdb:block-symbols-progress> object. */ 573 1.1 christos 574 1.1 christos static SCM 575 1.1 christos bkscm_make_block_syms_progress_smob (void) 576 1.1 christos { 577 1.1 christos block_syms_progress_smob *i_smob = (block_syms_progress_smob *) 578 1.1 christos scm_gc_malloc (sizeof (block_syms_progress_smob), 579 1.1 christos block_syms_progress_smob_name); 580 1.1 christos SCM smob; 581 1.1 christos 582 1.1 christos memset (&i_smob->iter, 0, sizeof (i_smob->iter)); 583 1.1 christos i_smob->initialized_p = 0; 584 1.1 christos smob = scm_new_smob (block_syms_progress_smob_tag, (scm_t_bits) i_smob); 585 1.1 christos gdbscm_init_gsmob (&i_smob->base); 586 1.1 christos 587 1.1 christos return smob; 588 1.1 christos } 589 1.1 christos 590 1.1 christos /* Returns non-zero if SCM is a <gdb:block-symbols-progress> object. */ 591 1.1 christos 592 1.1 christos static int 593 1.1 christos bkscm_is_block_syms_progress (SCM scm) 594 1.1 christos { 595 1.1 christos return SCM_SMOB_PREDICATE (block_syms_progress_smob_tag, scm); 596 1.1 christos } 597 1.1 christos 598 1.1 christos /* (block-symbols-progress? scm) -> boolean */ 599 1.1 christos 600 1.1 christos static SCM 601 1.1 christos bkscm_block_syms_progress_p (SCM scm) 602 1.1 christos { 603 1.1 christos return scm_from_bool (bkscm_is_block_syms_progress (scm)); 604 1.1 christos } 605 1.1 christos 606 1.1 christos /* (make-block-symbols-iterator <gdb:block>) -> <gdb:iterator> 607 1.1 christos Return a <gdb:iterator> object for iterating over the symbols of SELF. */ 608 1.1 christos 609 1.6 christos static SCM 610 1.6 christos gdbscm_make_block_syms_iter (SCM self) 611 1.1 christos { 612 1.1 christos /* Call for side effects. */ 613 1.1 christos bkscm_get_valid_block_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 614 1.1 christos SCM progress, iter; 615 1.1 christos 616 1.1 christos progress = bkscm_make_block_syms_progress_smob (); 617 1.1 christos 618 1.1 christos iter = gdbscm_make_iterator (self, progress, bkscm_next_symbol_x_proc); 619 1.1 christos 620 1.1 christos return iter; 621 1.1 christos } 622 1.1 christos 623 1.1 christos /* Returns the next symbol in the iteration through the block's dictionary, 624 1.1 christos or (end-of-iteration). 625 1.1 christos This is the iterator_smob.next_x method. */ 626 1.1 christos 627 1.1 christos static SCM 628 1.1 christos gdbscm_block_next_symbol_x (SCM self) 629 1.1 christos { 630 1.1 christos SCM progress, iter_scm, block_scm; 631 1.1 christos iterator_smob *iter_smob; 632 1.1 christos block_smob *b_smob; 633 1.1 christos const struct block *block; 634 1.1 christos block_syms_progress_smob *p_smob; 635 1.1 christos struct symbol *sym; 636 1.1 christos 637 1.1 christos iter_scm = itscm_get_iterator_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 638 1.1 christos iter_smob = (iterator_smob *) SCM_SMOB_DATA (iter_scm); 639 1.1 christos 640 1.1 christos block_scm = itscm_iterator_smob_object (iter_smob); 641 1.1 christos b_smob = bkscm_get_valid_block_smob_arg_unsafe (block_scm, 642 1.1 christos SCM_ARG1, FUNC_NAME); 643 1.1 christos block = b_smob->block; 644 1.1 christos 645 1.1 christos progress = itscm_iterator_smob_progress (iter_smob); 646 1.1 christos 647 1.1 christos SCM_ASSERT_TYPE (bkscm_is_block_syms_progress (progress), 648 1.1 christos progress, SCM_ARG1, FUNC_NAME, 649 1.1 christos block_syms_progress_smob_name); 650 1.1 christos p_smob = (block_syms_progress_smob *) SCM_SMOB_DATA (progress); 651 1.1 christos 652 1.1 christos if (!p_smob->initialized_p) 653 1.1 christos { 654 1.1 christos sym = block_iterator_first (block, &p_smob->iter); 655 1.1 christos p_smob->initialized_p = 1; 656 1.1 christos } 657 1.1 christos else 658 1.1 christos sym = block_iterator_next (&p_smob->iter); 659 1.1 christos 660 1.1 christos if (sym == NULL) 661 1.1 christos return gdbscm_end_of_iteration (); 662 1.1 christos 663 1.1 christos return syscm_scm_from_symbol (sym); 664 1.1 christos } 665 1.1 christos 666 1.1 christos /* (lookup-block address) -> <gdb:block> 668 1.1 christos Returns the innermost lexical block containing the specified pc value, 669 1.1 christos or #f if there is none. */ 670 1.1 christos 671 1.1 christos static SCM 672 1.1 christos gdbscm_lookup_block (SCM pc_scm) 673 1.1 christos { 674 1.1 christos CORE_ADDR pc; 675 1.1 christos const struct block *block = NULL; 676 1.7 christos struct compunit_symtab *cust = NULL; 677 1.7 christos 678 1.1 christos gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "U", pc_scm, &pc); 679 1.1 christos 680 1.1 christos gdbscm_gdb_exception exc {}; 681 1.8 christos try 682 1.1 christos { 683 1.1 christos cust = find_pc_compunit_symtab (pc); 684 1.7 christos 685 1.3 christos if (cust != NULL && cust->objfile () != NULL) 686 1.7 christos block = block_for_pc (pc); 687 1.3 christos } 688 1.1 christos catch (const gdb_exception &except) 689 1.7 christos { 690 1.8 christos exc = unpack (except); 691 1.1 christos } 692 1.1 christos 693 1.1 christos GDBSCM_HANDLE_GDB_EXCEPTION (exc); 694 1.1 christos if (cust == NULL || cust->objfile () == NULL) 695 1.1 christos { 696 1.1 christos gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, pc_scm, 697 1.8 christos _("cannot locate object file for block")); 698 1.1 christos } 699 1.1 christos 700 1.1 christos if (block != NULL) 701 1.1 christos return bkscm_scm_from_block (block, cust->objfile ()); 702 1.1 christos return SCM_BOOL_F; 703 1.1 christos } 704 1.1 christos 705 1.4 christos /* Initialize the Scheme block support. */ 707 1.1 christos 708 1.1 christos static const scheme_function block_functions[] = 709 1.4 christos { 710 1.1 christos { "block?", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_p), 711 1.1 christos "\ 712 1.1 christos Return #t if the object is a <gdb:block> object." }, 713 1.1 christos 714 1.4 christos { "block-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_valid_p), 715 1.1 christos "\ 716 1.1 christos Return #t if the block is valid.\n\ 717 1.1 christos A block becomes invalid when its objfile is freed." }, 718 1.4 christos 719 1.1 christos { "block-start", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_start), 720 1.1 christos "\ 721 1.1 christos Return the start address of the block." }, 722 1.4 christos 723 1.1 christos { "block-end", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_end), 724 1.1 christos "\ 725 1.1 christos Return the end address of the block." }, 726 1.1 christos 727 1.4 christos { "block-function", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_function), 728 1.1 christos "\ 729 1.1 christos Return the gdb:symbol object of the function containing the block\n\ 730 1.1 christos or #f if the block does not live in any function." }, 731 1.4 christos 732 1.1 christos { "block-superblock", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_superblock), 733 1.1 christos "\ 734 1.1 christos Return the superblock (parent block) of the block." }, 735 1.4 christos 736 1.1 christos { "block-global-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_global_block), 737 1.1 christos "\ 738 1.1 christos Return the global block of the block." }, 739 1.4 christos 740 1.1 christos { "block-static-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_static_block), 741 1.1 christos "\ 742 1.1 christos Return the static block of the block." }, 743 1.4 christos 744 1.1 christos { "block-global?", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_global_p), 745 1.1 christos "\ 746 1.1 christos Return #t if block is a global block." }, 747 1.4 christos 748 1.1 christos { "block-static?", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_static_p), 749 1.1 christos "\ 750 1.1 christos Return #t if block is a static block." }, 751 1.4 christos 752 1.4 christos { "block-symbols", 1, 0, 0, as_a_scm_t_subr (gdbscm_block_symbols), 753 1.1 christos "\ 754 1.1 christos Return a list of all symbols (as <gdb:symbol> objects) in the block." }, 755 1.1 christos 756 1.4 christos { "make-block-symbols-iterator", 1, 0, 0, 757 1.4 christos as_a_scm_t_subr (gdbscm_make_block_syms_iter), 758 1.1 christos "\ 759 1.1 christos Return a <gdb:iterator> object for iterating over all symbols in the block." }, 760 1.1 christos 761 1.4 christos { "block-symbols-progress?", 1, 0, 0, 762 1.1 christos as_a_scm_t_subr (bkscm_block_syms_progress_p), 763 1.1 christos "\ 764 1.1 christos Return #t if the object is a <gdb:block-symbols-progress> object." }, 765 1.1 christos 766 1.1 christos { "lookup-block", 1, 0, 0, as_a_scm_t_subr (gdbscm_lookup_block), 767 1.1 christos "\ 768 1.1 christos Return the innermost GDB block containing the address or #f if none found.\n\ 769 1.1 christos \n\ 770 1.1 christos Arguments:\n\ 771 1.1 christos address: the address to lookup" }, 772 1.1 christos 773 1.1 christos END_FUNCTIONS 774 1.1 christos }; 775 1.1 christos 776 1.1 christos void 777 1.1 christos gdbscm_initialize_blocks (void) 778 1.1 christos { 779 1.1 christos block_smob_tag 780 1.1 christos = gdbscm_make_smob_type (block_smob_name, sizeof (block_smob)); 781 1.1 christos scm_set_smob_free (block_smob_tag, bkscm_free_block_smob); 782 1.1 christos scm_set_smob_print (block_smob_tag, bkscm_print_block_smob); 783 1.1 christos 784 1.1 christos block_syms_progress_smob_tag 785 1.1 christos = gdbscm_make_smob_type (block_syms_progress_smob_name, 786 1.1 christos sizeof (block_syms_progress_smob)); 787 1.1 christos scm_set_smob_print (block_syms_progress_smob_tag, 788 1.1 christos bkscm_print_block_syms_progress_smob); 789 1.1 christos 790 1.4 christos gdbscm_define_functions (block_functions, 1); 791 1.1 christos 792 1.1 christos /* This function is "private". */ 793 1.1 christos bkscm_next_symbol_x_proc 794 1.1 christos = scm_c_define_gsubr ("%block-next-symbol!", 1, 0, 0, 795 1.1 christos as_a_scm_t_subr (gdbscm_block_next_symbol_x)); 796 scm_set_procedure_property_x (bkscm_next_symbol_x_proc, 797 gdbscm_documentation_symbol, 798 gdbscm_scm_from_c_string ("\ 799 Internal function to assist the block symbols iterator.")); 800 } 801