1 1.1 christos /* Guile interface to program spaces. 2 1.1 christos 3 1.9 christos Copyright (C) 2010-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 #include "charset.h" 21 1.1 christos #include "progspace.h" 22 1.1 christos #include "objfiles.h" 23 1.1 christos #include "language.h" 24 1.1 christos #include "arch-utils.h" 25 1.1 christos #include "guile-internal.h" 26 1.1 christos 27 1.1 christos /* NOTE: Python exports the name "Progspace", so we export "progspace". 28 1.1 christos Internally we shorten that to "pspace". */ 29 1.1 christos 30 1.8 christos /* The <gdb:progspace> smob. */ 31 1.1 christos 32 1.8 christos struct pspace_smob 33 1.1 christos { 34 1.1 christos /* This always appears first. */ 35 1.1 christos gdb_smob base; 36 1.1 christos 37 1.1 christos /* The corresponding pspace. */ 38 1.1 christos struct program_space *pspace; 39 1.1 christos 40 1.1 christos /* The pretty-printer list of functions. */ 41 1.1 christos SCM pretty_printers; 42 1.1 christos 43 1.1 christos /* The <gdb:progspace> object we are contained in, needed to 44 1.1 christos protect/unprotect the object since a reference to it comes from 45 1.1 christos non-gc-managed space (the progspace). */ 46 1.1 christos SCM containing_scm; 47 1.1 christos }; 48 1.1 christos 49 1.1 christos static const char pspace_smob_name[] = "gdb:progspace"; 50 1.1 christos 51 1.1 christos /* The tag Guile knows the pspace smob by. */ 52 1.1 christos static scm_t_bits pspace_smob_tag; 53 1.1 christos 54 1.8 christos /* Progspace registry cleanup handler for when a progspace is deleted. */ 55 1.8 christos struct psscm_deleter 56 1.8 christos { 57 1.8 christos void operator() (pspace_smob *p_smob) 58 1.8 christos { 59 1.8 christos p_smob->pspace = NULL; 60 1.8 christos scm_gc_unprotect_object (p_smob->containing_scm); 61 1.8 christos } 62 1.8 christos }; 63 1.8 christos 64 1.8 christos static const registry<program_space>::key<pspace_smob, psscm_deleter> 65 1.8 christos psscm_pspace_data_key; 66 1.1 christos 67 1.1 christos /* Return the list of pretty-printers registered with P_SMOB. */ 68 1.1 christos 69 1.1 christos SCM 70 1.1 christos psscm_pspace_smob_pretty_printers (const pspace_smob *p_smob) 71 1.1 christos { 72 1.1 christos return p_smob->pretty_printers; 73 1.1 christos } 74 1.1 christos 75 1.1 christos /* Administrivia for progspace smobs. */ 77 1.1 christos 78 1.1 christos /* The smob "print" function for <gdb:progspace>. */ 79 1.1 christos 80 1.1 christos static int 81 1.1 christos psscm_print_pspace_smob (SCM self, SCM port, scm_print_state *pstate) 82 1.1 christos { 83 1.1 christos pspace_smob *p_smob = (pspace_smob *) SCM_SMOB_DATA (self); 84 1.1 christos 85 1.1 christos gdbscm_printf (port, "#<%s ", pspace_smob_name); 86 1.1 christos if (p_smob->pspace != NULL) 87 1.1 christos { 88 1.1 christos struct objfile *objfile = p_smob->pspace->symfile_object_file; 89 1.1 christos 90 1.1 christos gdbscm_printf (port, "%s", 91 1.1 christos objfile != NULL 92 1.1 christos ? objfile_name (objfile) 93 1.1 christos : "{no symfile}"); 94 1.1 christos } 95 1.1 christos else 96 1.1 christos scm_puts ("{invalid}", port); 97 1.1 christos scm_puts (">", port); 98 1.1 christos 99 1.1 christos scm_remember_upto_here_1 (self); 100 1.1 christos 101 1.1 christos /* Non-zero means success. */ 102 1.1 christos return 1; 103 1.1 christos } 104 1.1 christos 105 1.1 christos /* Low level routine to create a <gdb:progspace> object. 106 1.1 christos It's empty in the sense that a progspace still needs to be associated 107 1.1 christos with it. */ 108 1.1 christos 109 1.1 christos static SCM 110 1.1 christos psscm_make_pspace_smob (void) 111 1.1 christos { 112 1.1 christos pspace_smob *p_smob = (pspace_smob *) 113 1.1 christos scm_gc_malloc (sizeof (pspace_smob), pspace_smob_name); 114 1.1 christos SCM p_scm; 115 1.1 christos 116 1.1 christos p_smob->pspace = NULL; 117 1.1 christos p_smob->pretty_printers = SCM_EOL; 118 1.1 christos p_scm = scm_new_smob (pspace_smob_tag, (scm_t_bits) p_smob); 119 1.1 christos p_smob->containing_scm = p_scm; 120 1.1 christos gdbscm_init_gsmob (&p_smob->base); 121 1.1 christos 122 1.1 christos return p_scm; 123 1.1 christos } 124 1.1 christos 125 1.1 christos /* Return non-zero if SCM is a <gdb:progspace> object. */ 126 1.1 christos 127 1.1 christos static int 128 1.1 christos psscm_is_pspace (SCM scm) 129 1.1 christos { 130 1.1 christos return SCM_SMOB_PREDICATE (pspace_smob_tag, scm); 131 1.1 christos } 132 1.1 christos 133 1.1 christos /* (progspace? object) -> boolean */ 134 1.1 christos 135 1.1 christos static SCM 136 1.1 christos gdbscm_progspace_p (SCM scm) 137 1.1 christos { 138 1.1 christos return scm_from_bool (psscm_is_pspace (scm)); 139 1.1 christos } 140 1.1 christos 141 1.1 christos /* Return a pointer to the progspace_smob that encapsulates PSPACE, 142 1.1 christos creating one if necessary. 143 1.1 christos The result is cached so that we have only one copy per objfile. */ 144 1.1 christos 145 1.1 christos pspace_smob * 146 1.1 christos psscm_pspace_smob_from_pspace (struct program_space *pspace) 147 1.1 christos { 148 1.1 christos pspace_smob *p_smob; 149 1.8 christos 150 1.1 christos p_smob = psscm_pspace_data_key.get (pspace); 151 1.1 christos if (p_smob == NULL) 152 1.1 christos { 153 1.1 christos SCM p_scm = psscm_make_pspace_smob (); 154 1.1 christos 155 1.1 christos p_smob = (pspace_smob *) SCM_SMOB_DATA (p_scm); 156 1.1 christos p_smob->pspace = pspace; 157 1.8 christos 158 1.1 christos psscm_pspace_data_key.set (pspace, p_smob); 159 1.1 christos scm_gc_protect_object (p_smob->containing_scm); 160 1.1 christos } 161 1.1 christos 162 1.1 christos return p_smob; 163 1.1 christos } 164 1.1 christos 165 1.1 christos /* Return the <gdb:progspace> object that encapsulates PSPACE. */ 166 1.1 christos 167 1.1 christos SCM 168 1.1 christos psscm_scm_from_pspace (struct program_space *pspace) 169 1.1 christos { 170 1.1 christos pspace_smob *p_smob = psscm_pspace_smob_from_pspace (pspace); 171 1.1 christos 172 1.1 christos return p_smob->containing_scm; 173 1.1 christos } 174 1.1 christos 175 1.1 christos /* Returns the <gdb:progspace> object in SELF. 176 1.1 christos Throws an exception if SELF is not a <gdb:progspace> object. */ 177 1.1 christos 178 1.1 christos static SCM 179 1.1 christos psscm_get_pspace_arg_unsafe (SCM self, int arg_pos, const char *func_name) 180 1.1 christos { 181 1.1 christos SCM_ASSERT_TYPE (psscm_is_pspace (self), self, arg_pos, func_name, 182 1.1 christos pspace_smob_name); 183 1.1 christos 184 1.1 christos return self; 185 1.1 christos } 186 1.1 christos 187 1.1 christos /* Returns a pointer to the pspace smob of SELF. 188 1.1 christos Throws an exception if SELF is not a <gdb:progspace> object. */ 189 1.1 christos 190 1.1 christos static pspace_smob * 191 1.1 christos psscm_get_pspace_smob_arg_unsafe (SCM self, int arg_pos, 192 1.1 christos const char *func_name) 193 1.1 christos { 194 1.1 christos SCM p_scm = psscm_get_pspace_arg_unsafe (self, arg_pos, func_name); 195 1.1 christos pspace_smob *p_smob = (pspace_smob *) SCM_SMOB_DATA (p_scm); 196 1.1 christos 197 1.1 christos return p_smob; 198 1.1 christos } 199 1.1 christos 200 1.1 christos /* Return non-zero if pspace P_SMOB is valid. */ 201 1.1 christos 202 1.1 christos static int 203 1.1 christos psscm_is_valid (pspace_smob *p_smob) 204 1.1 christos { 205 1.1 christos return p_smob->pspace != NULL; 206 1.1 christos } 207 1.1 christos 208 1.1 christos /* Return the pspace smob in SELF, verifying it's valid. 209 1.1 christos Throws an exception if SELF is not a <gdb:progspace> object or is 210 1.1 christos invalid. */ 211 1.1 christos 212 1.1 christos static pspace_smob * 213 1.1 christos psscm_get_valid_pspace_smob_arg_unsafe (SCM self, int arg_pos, 214 1.1 christos const char *func_name) 215 1.1 christos { 216 1.1 christos pspace_smob *p_smob 217 1.1 christos = psscm_get_pspace_smob_arg_unsafe (self, arg_pos, func_name); 218 1.1 christos 219 1.1 christos if (!psscm_is_valid (p_smob)) 220 1.1 christos { 221 1.1 christos gdbscm_invalid_object_error (func_name, arg_pos, self, 222 1.1 christos _("<gdb:progspace>")); 223 1.1 christos } 224 1.1 christos 225 1.1 christos return p_smob; 226 1.1 christos } 227 1.1 christos 228 1.1 christos /* Program space methods. */ 230 1.1 christos 231 1.1 christos /* (progspace-valid? <gdb:progspace>) -> boolean 232 1.1 christos Returns #t if this program space still exists in GDB. */ 233 1.1 christos 234 1.1 christos static SCM 235 1.1 christos gdbscm_progspace_valid_p (SCM self) 236 1.1 christos { 237 1.1 christos pspace_smob *p_smob 238 1.1 christos = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 239 1.1 christos 240 1.1 christos return scm_from_bool (p_smob->pspace != NULL); 241 1.1 christos } 242 1.1 christos 243 1.1 christos /* (progspace-filename <gdb:progspace>) -> string 244 1.1 christos Returns the name of the main symfile associated with the progspace, 245 1.1 christos or #f if there isn't one. 246 1.1 christos Throw's an exception if the underlying pspace is invalid. */ 247 1.1 christos 248 1.1 christos static SCM 249 1.1 christos gdbscm_progspace_filename (SCM self) 250 1.1 christos { 251 1.1 christos pspace_smob *p_smob 252 1.1 christos = psscm_get_valid_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 253 1.1 christos struct objfile *objfile = p_smob->pspace->symfile_object_file; 254 1.1 christos 255 1.1 christos if (objfile != NULL) 256 1.1 christos return gdbscm_scm_from_c_string (objfile_name (objfile)); 257 1.1 christos return SCM_BOOL_F; 258 1.1 christos } 259 1.1 christos 260 1.1 christos /* (progspace-objfiles <gdb:progspace>) -> list 261 1.1 christos Return the list of objfiles in the progspace. 262 1.1 christos Objfiles that are separate debug objfiles are *not* included in the result, 263 1.1 christos only the "original/real" one appears in the result. 264 1.1 christos The order of appearance of objfiles in the result is arbitrary. 265 1.1 christos Throw's an exception if the underlying pspace is invalid. 266 1.1 christos 267 1.1 christos Some apps can have 1000s of shared libraries. Seriously. 268 1.1 christos A future extension here could be to provide, e.g., a regexp to select 269 1.1 christos just the ones the caller is interested in (rather than building the list 270 1.1 christos and then selecting the desired ones). Another alternative is passing a 271 1.1 christos predicate, then the filter criteria can be more general. */ 272 1.1 christos 273 1.1 christos static SCM 274 1.1 christos gdbscm_progspace_objfiles (SCM self) 275 1.1 christos { 276 1.1 christos pspace_smob *p_smob 277 1.1 christos = psscm_get_valid_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 278 1.1 christos SCM result; 279 1.1 christos 280 1.6 christos result = SCM_EOL; 281 1.6 christos 282 1.6 christos for (objfile *objfile : p_smob->pspace->objfiles ()) 283 1.6 christos { 284 1.6 christos if (objfile->separate_debug_objfile_backlink == NULL) 285 1.1 christos { 286 1.6 christos SCM item = ofscm_scm_from_objfile (objfile); 287 1.6 christos 288 1.6 christos result = scm_cons (item, result); 289 1.1 christos } 290 1.1 christos } 291 1.1 christos 292 1.1 christos /* We don't really have to return the list in the same order as recorded 293 1.1 christos internally, but for consistency we do. We still advertise that one 294 1.1 christos cannot assume anything about the order. */ 295 1.1 christos return scm_reverse_x (result, SCM_EOL); 296 1.1 christos } 297 1.1 christos 298 1.1 christos /* (progspace-pretty-printers <gdb:progspace>) -> list 299 1.1 christos Returns the list of pretty-printers for this program space. */ 300 1.1 christos 301 1.1 christos static SCM 302 1.1 christos gdbscm_progspace_pretty_printers (SCM self) 303 1.1 christos { 304 1.1 christos pspace_smob *p_smob 305 1.1 christos = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 306 1.1 christos 307 1.1 christos return p_smob->pretty_printers; 308 1.1 christos } 309 1.1 christos 310 1.1 christos /* (set-progspace-pretty-printers! <gdb:progspace> list) -> unspecified 311 1.1 christos Set the pretty-printers for this program space. */ 312 1.1 christos 313 1.1 christos static SCM 314 1.1 christos gdbscm_set_progspace_pretty_printers_x (SCM self, SCM printers) 315 1.1 christos { 316 1.1 christos pspace_smob *p_smob 317 1.1 christos = psscm_get_pspace_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); 318 1.1 christos 319 1.1 christos SCM_ASSERT_TYPE (gdbscm_is_true (scm_list_p (printers)), printers, 320 1.1 christos SCM_ARG2, FUNC_NAME, _("list")); 321 1.1 christos 322 1.1 christos p_smob->pretty_printers = printers; 323 1.1 christos 324 1.1 christos return SCM_UNSPECIFIED; 325 1.1 christos } 326 1.1 christos 327 1.1 christos /* (current-progspace) -> <gdb:progspace> 328 1.1 christos Return the current program space. There always is one. */ 329 1.1 christos 330 1.1 christos static SCM 331 1.1 christos gdbscm_current_progspace (void) 332 1.1 christos { 333 1.1 christos SCM result; 334 1.1 christos 335 1.1 christos result = psscm_scm_from_pspace (current_program_space); 336 1.1 christos 337 1.1 christos return result; 338 1.1 christos } 339 1.1 christos 340 1.1 christos /* (progspaces) -> list 341 1.1 christos Return a list of all progspaces. */ 342 1.1 christos 343 1.1 christos static SCM 344 1.1 christos gdbscm_progspaces (void) 345 1.1 christos { 346 1.1 christos SCM result; 347 1.1 christos 348 1.7 christos result = SCM_EOL; 349 1.7 christos 350 1.7 christos for (struct program_space *ps : program_spaces) 351 1.1 christos { 352 1.7 christos SCM item = psscm_scm_from_pspace (ps); 353 1.7 christos 354 1.1 christos result = scm_cons (item, result); 355 1.1 christos } 356 1.1 christos 357 1.1 christos return scm_reverse_x (result, SCM_EOL); 358 1.1 christos } 359 1.1 christos 360 1.1 christos /* Initialize the Scheme program space support. */ 362 1.4 christos 363 1.1 christos static const scheme_function pspace_functions[] = 364 1.1 christos { 365 1.1 christos { "progspace?", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_p), 366 1.4 christos "\ 367 1.1 christos Return #t if the object is a <gdb:objfile> object." }, 368 1.1 christos 369 1.1 christos { "progspace-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_valid_p), 370 1.4 christos "\ 371 1.1 christos Return #t if the progspace is valid (hasn't been deleted from gdb)." }, 372 1.1 christos 373 1.1 christos { "progspace-filename", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_filename), 374 1.4 christos "\ 375 1.1 christos Return the name of the main symbol file of the progspace." }, 376 1.1 christos 377 1.1 christos { "progspace-objfiles", 1, 0, 0, as_a_scm_t_subr (gdbscm_progspace_objfiles), 378 1.1 christos "\ 379 1.1 christos Return the list of objfiles associated with the progspace.\n\ 380 1.4 christos Objfiles that are separate debug objfiles are not included in the result.\n\ 381 1.4 christos The order of appearance of objfiles in the result is arbitrary." }, 382 1.1 christos 383 1.1 christos { "progspace-pretty-printers", 1, 0, 0, 384 1.1 christos as_a_scm_t_subr (gdbscm_progspace_pretty_printers), 385 1.1 christos "\ 386 1.4 christos Return a list of pretty-printers of the progspace." }, 387 1.1 christos 388 1.1 christos { "set-progspace-pretty-printers!", 2, 0, 0, 389 1.1 christos as_a_scm_t_subr (gdbscm_set_progspace_pretty_printers_x), 390 1.4 christos "\ 391 1.1 christos Set the list of pretty-printers of the progspace." }, 392 1.1 christos 393 1.1 christos { "current-progspace", 0, 0, 0, as_a_scm_t_subr (gdbscm_current_progspace), 394 1.4 christos "\ 395 1.1 christos Return the current program space if there is one or #f if there isn't one." }, 396 1.1 christos 397 1.1 christos { "progspaces", 0, 0, 0, as_a_scm_t_subr (gdbscm_progspaces), 398 1.1 christos "\ 399 1.1 christos Return a list of all program spaces." }, 400 1.1 christos 401 1.1 christos END_FUNCTIONS 402 1.1 christos }; 403 1.1 christos 404 1.1 christos void 405 1.1 christos gdbscm_initialize_pspaces (void) 406 1.1 christos { 407 1.1 christos pspace_smob_tag 408 1.1 christos = gdbscm_make_smob_type (pspace_smob_name, sizeof (pspace_smob)); 409 1.1 christos scm_set_smob_print (pspace_smob_tag, psscm_print_pspace_smob); 410 411 gdbscm_define_functions (pspace_functions, 1); 412 } 413