9210 remove KMDB branch debugging support 9211 ::crregs could do with cr2/cr3 support 9209 ::ttrace should be able to filter by thread Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Reviewed by: Yuri Pankov <yuripv@yuripv.net>
1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * Copyright 2018 Joyent, Inc. 26 */ 27 28 /* 29 * MDB Target Layer 30 * 31 * The *target* is the program being inspected by the debugger. The MDB target 32 * layer provides a set of functions that insulate common debugger code, 33 * including the MDB Module API, from the implementation details of how the 34 * debugger accesses information from a given target. Each target exports a 35 * standard set of properties, including one or more address spaces, one or 36 * more symbol tables, a set of load objects, and a set of threads that can be 37 * examined using the interfaces in <mdb/mdb_target.h>. This technique has 38 * been employed successfully in other debuggers, including [1], primarily 39 * to improve portability, although the term "target" often refers to the 40 * encapsulation of architectural or operating system-specific details. The 41 * target abstraction is useful for MDB because it allows us to easily extend 42 * the debugger to examine a variety of different program forms. Primarily, 43 * the target functions validate input arguments and then call an appropriate 44 * function in the target ops vector, defined in <mdb/mdb_target_impl.h>. 45 * However, this interface layer provides a very high level of flexibility for 46 * separating the debugger interface from instrumentation details. Experience 47 * has shown this kind of design can facilitate separating out debugger 48 * instrumentation into an external agent [2] and enable the development of 49 * advanced instrumentation frameworks [3]. We want MDB to be an ideal 50 * extensible framework for the development of such applications. 51 * 52 * Aside from a set of wrapper functions, the target layer also provides event 53 * management for targets that represent live executing programs. Our model of 54 * events is also extensible, and is based upon work in [3] and [4]. We define 55 * a *software event* as a state transition in the target program (for example, 56 * the transition of the program counter to a location of interest) that is 57 * observed by the debugger or its agent. A *software event specifier* is a 58 * description of a class of software events that is used by the debugger to 59 * instrument the target so that the corresponding software events can be 60 * observed. In MDB, software event specifiers are represented by the 61 * mdb_sespec_t structure, defined in <mdb/mdb_target_impl.h>. As the user, 62 * the internal debugger code, and MDB modules may all wish to observe software 63 * events and receive appropriate notification and callbacks, we do not expose 64 * software event specifiers directly as part of the user interface. Instead, 65 * clients of the target layer request that events be observed by creating 66 * new *virtual event specifiers*. Each virtual specifier is named by a unique 67 * non-zero integer (the VID), and is represented by a mdb_vespec_t structure. 68 * One or more virtual specifiers are then associated with each underlying 69 * software event specifier. This design enforces the constraint that the 70 * target must only insert one set of instrumentation, regardless of how many 71 * times the target layer was asked to trace a given event. For example, if 72 * multiple clients request a breakpoint at a particular address, the virtual 73 * specifiers will map to the same sespec, ensuring that only one breakpoint 74 * trap instruction is actually planted at the given target address. When no 75 * virtual specifiers refer to an sespec, it is no longer needed and can be 76 * removed, along with the corresponding instrumentation. 77 * 78 * The following state transition diagram illustrates the life cycle of a 79 * software event specifier and example transitions: 80 * 81 * cont/ 82 * +--------+ delete +--------+ stop +-------+ 83 * (|( DEAD )|) <------- ( ACTIVE ) <------> ( ARMED ) 84 * +--------+ +--------+ +-------+ 85 * ^ load/unload ^ ^ failure/ | 86 * delete | object / \ reset | failure 87 * | v v | 88 * | +--------+ +-------+ | 89 * +---- ( IDLE ) ( ERR ) <----+ 90 * | +--------+ +-------+ 91 * | | 92 * +------------------------------+ 93 * 94 * The MDB execution control model is based upon the synchronous debugging 95 * model exported by Solaris proc(4). A target program is set running or the 96 * debugger is attached to a running target. On ISTOP (stop on event of 97 * interest), one target thread is selected as the representative. The 98 * algorithm for selecting the representative is target-specific, but we assume 99 * that if an observed software event has occurred, the target will select the 100 * thread that triggered the state transition of interest. The other threads 101 * are stopped in sympathy with the representative as soon as possible. Prior 102 * to continuing the target, we plant our instrumentation, transitioning event 103 * specifiers from the ACTIVE to the ARMED state, and then back again when the 104 * target stops. We then query each active event specifier to learn which ones 105 * are matched, and then invoke the callbacks associated with their vespecs. 106 * If an OS error occurs while attempting to arm or disarm a specifier, the 107 * specifier is transitioned to the ERROR state; we will attempt to arm it 108 * again at the next continue. If no target process is under our control or 109 * if an event is not currently applicable (e.g. a deferred breakpoint on an 110 * object that is not yet loaded), it remains in the IDLE state. The target 111 * implementation should intercept object load events and then transition the 112 * specifier to the ACTIVE state when the corresponding object is loaded. 113 * 114 * To simplify the debugger implementation and allow targets to easily provide 115 * new types of observable events, most of the event specifier management is 116 * done by the target layer. Each software event specifier provides an ops 117 * vector of subroutines that the target layer can call to perform the 118 * various state transitions described above. The target maintains two lists 119 * of mdb_sespec_t's: the t_idle list (IDLE state) and the t_active list 120 * (ACTIVE, ARMED, and ERROR states). Each mdb_sespec_t maintains a list of 121 * associated mdb_vespec_t's. If an sespec is IDLE or ERROR, its se_errno 122 * field will have an errno value specifying the reason for its inactivity. 123 * The vespec stores the client's callback function and private data, and the 124 * arguments used to construct the sespec. All objects are reference counted 125 * so we can destroy an object when it is no longer needed. The mdb_sespec_t 126 * invariants for the respective states are as follows: 127 * 128 * IDLE: on t_idle list, se_data == NULL, se_errno != 0, se_ctor not called 129 * ACTIVE: on t_active list, se_data valid, se_errno == 0, se_ctor called 130 * ARMED: on t_active list, se_data valid, se_errno == 0, se_ctor called 131 * ERROR: on t_active list, se_data valid, se_errno != 0, se_ctor called 132 * 133 * Additional commentary on specific state transitions and issues involving 134 * event management can be found below near the target layer functions. 135 * 136 * References 137 * 138 * [1] John Gilmore, "Working in GDB", Technical Report, Cygnus Support, 139 * 1.84 edition, 1994. 140 * 141 * [2] David R. Hanson and Mukund Raghavachari, "A Machine-Independent 142 * Debugger", Software--Practice and Experience, 26(11), 1277-1299(1996). 143 * 144 * [3] Michael W. Shapiro, "RDB: A System for Incremental Replay Debugging", 145 * Technical Report CS-97-12, Department of Computer Science, 146 * Brown University. 147 * 148 * [4] Daniel B. Price, "New Techniques for Replay Debugging", Technical 149 * Report CS-98-05, Department of Computer Science, Brown University. 150 */ 151 152 #include <mdb/mdb_target_impl.h> 153 #include <mdb/mdb_debug.h> 154 #include <mdb/mdb_modapi.h> 155 #include <mdb/mdb_err.h> 156 #include <mdb/mdb_callb.h> 157 #include <mdb/mdb_gelf.h> 158 #include <mdb/mdb_io_impl.h> 159 #include <mdb/mdb_string.h> 160 #include <mdb/mdb_signal.h> 161 #include <mdb/mdb_frame.h> 162 #include <mdb/mdb.h> 163 164 #include <sys/stat.h> 165 #include <sys/param.h> 166 #include <sys/signal.h> 167 #include <strings.h> 168 #include <stdlib.h> 169 #include <errno.h> 170 171 /* 172 * Define convenience macros for referencing the set of vespec flag bits that 173 * are preserved by the target implementation, and the set of bits that 174 * determine automatic ve_hits == ve_limit behavior. 175 */ 176 #define T_IMPL_BITS \ 177 (MDB_TGT_SPEC_INTERNAL | MDB_TGT_SPEC_SILENT | MDB_TGT_SPEC_MATCHED | \ 178 MDB_TGT_SPEC_DELETED) 179 180 #define T_AUTO_BITS \ 181 (MDB_TGT_SPEC_AUTOSTOP | MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS) 182 183 /* 184 * Define convenience macro for referencing target flag pending continue bits. 185 */ 186 #define T_CONT_BITS \ 187 (MDB_TGT_F_STEP | MDB_TGT_F_STEP_OUT | MDB_TGT_F_NEXT | MDB_TGT_F_CONT) 188 189 mdb_tgt_t * 190 mdb_tgt_create(mdb_tgt_ctor_f *ctor, int flags, int argc, const char *argv[]) 191 { 192 mdb_module_t *mp; 193 mdb_tgt_t *t; 194 195 if (flags & ~MDB_TGT_F_ALL) { 196 (void) set_errno(EINVAL); 197 return (NULL); 198 } 199 200 t = mdb_zalloc(sizeof (mdb_tgt_t), UM_SLEEP); 201 mdb_list_append(&mdb.m_tgtlist, t); 202 203 t->t_module = &mdb.m_rmod; 204 t->t_matched = T_SE_END; 205 t->t_flags = flags; 206 t->t_vepos = 1; 207 t->t_veneg = 1; 208 209 for (mp = mdb.m_mhead; mp != NULL; mp = mp->mod_next) { 210 if (ctor == mp->mod_tgt_ctor) { 211 t->t_module = mp; 212 break; 213 } 214 } 215 216 if (ctor(t, argc, argv) != 0) { 217 mdb_list_delete(&mdb.m_tgtlist, t); 218 mdb_free(t, sizeof (mdb_tgt_t)); 219 return (NULL); 220 } 221 222 mdb_dprintf(MDB_DBG_TGT, "t_create %s (%p)\n", 223 t->t_module->mod_name, (void *)t); 224 225 (void) t->t_ops->t_status(t, &t->t_status); 226 return (t); 227 } 228 229 int 230 mdb_tgt_getflags(mdb_tgt_t *t) 231 { 232 return (t->t_flags); 233 } 234 235 int 236 mdb_tgt_setflags(mdb_tgt_t *t, int flags) 237 { 238 if (flags & ~MDB_TGT_F_ALL) 239 return (set_errno(EINVAL)); 240 241 return (t->t_ops->t_setflags(t, flags)); 242 } 243 244 int 245 mdb_tgt_setcontext(mdb_tgt_t *t, void *context) 246 { 247 return (t->t_ops->t_setcontext(t, context)); 248 } 249 250 /*ARGSUSED*/ 251 static int 252 tgt_delete_vespec(mdb_tgt_t *t, void *private, int vid, void *data) 253 { 254 (void) mdb_tgt_vespec_delete(t, vid); 255 return (0); 256 } 257 258 void 259 mdb_tgt_destroy(mdb_tgt_t *t) 260 { 261 mdb_xdata_t *xdp, *nxdp; 262 263 if (mdb.m_target == t) { 264 mdb_dprintf(MDB_DBG_TGT, "t_deactivate %s (%p)\n", 265 t->t_module->mod_name, (void *)t); 266 t->t_ops->t_deactivate(t); 267 mdb.m_target = NULL; 268 } 269 270 mdb_dprintf(MDB_DBG_TGT, "t_destroy %s (%p)\n", 271 t->t_module->mod_name, (void *)t); 272 273 for (xdp = mdb_list_next(&t->t_xdlist); xdp != NULL; xdp = nxdp) { 274 nxdp = mdb_list_next(xdp); 275 mdb_list_delete(&t->t_xdlist, xdp); 276 mdb_free(xdp, sizeof (mdb_xdata_t)); 277 } 278 279 mdb_tgt_sespec_idle_all(t, EBUSY, TRUE); 280 (void) mdb_tgt_vespec_iter(t, tgt_delete_vespec, NULL); 281 t->t_ops->t_destroy(t); 282 283 mdb_list_delete(&mdb.m_tgtlist, t); 284 mdb_free(t, sizeof (mdb_tgt_t)); 285 286 if (mdb.m_target == NULL) 287 mdb_tgt_activate(mdb_list_prev(&mdb.m_tgtlist)); 288 } 289 290 void 291 mdb_tgt_activate(mdb_tgt_t *t) 292 { 293 mdb_tgt_t *otgt = mdb.m_target; 294 295 if (mdb.m_target != NULL) { 296 mdb_dprintf(MDB_DBG_TGT, "t_deactivate %s (%p)\n", 297 mdb.m_target->t_module->mod_name, (void *)mdb.m_target); 298 mdb.m_target->t_ops->t_deactivate(mdb.m_target); 299 } 300 301 if ((mdb.m_target = t) != NULL) { 302 const char *v = strstr(mdb.m_root, "%V"); 303 304 mdb_dprintf(MDB_DBG_TGT, "t_activate %s (%p)\n", 305 t->t_module->mod_name, (void *)t); 306 307 /* 308 * If the root was explicitly set with -R and contains %V, 309 * expand it like a path. If the resulting directory is 310 * not present, then replace %V with "latest" and re-evaluate. 311 */ 312 if (v != NULL) { 313 char old_root[MAXPATHLEN]; 314 const char **p; 315 #ifndef _KMDB 316 struct stat s; 317 #endif 318 size_t len; 319 320 p = mdb_path_alloc(mdb.m_root, &len); 321 (void) strcpy(old_root, mdb.m_root); 322 (void) strncpy(mdb.m_root, p[0], MAXPATHLEN); 323 mdb.m_root[MAXPATHLEN - 1] = '\0'; 324 mdb_path_free(p, len); 325 326 #ifndef _KMDB 327 if (stat(mdb.m_root, &s) == -1 && errno == ENOENT) { 328 mdb.m_flags |= MDB_FL_LATEST; 329 p = mdb_path_alloc(old_root, &len); 330 (void) strncpy(mdb.m_root, p[0], MAXPATHLEN); 331 mdb.m_root[MAXPATHLEN - 1] = '\0'; 332 mdb_path_free(p, len); 333 } 334 #endif 335 } 336 337 /* 338 * Re-evaluate the macro and dmod paths now that we have the 339 * new target set and m_root figured out. 340 */ 341 if (otgt == NULL) { 342 mdb_set_ipath(mdb.m_ipathstr); 343 mdb_set_lpath(mdb.m_lpathstr); 344 } 345 346 t->t_ops->t_activate(t); 347 } 348 } 349 350 void 351 mdb_tgt_periodic(mdb_tgt_t *t) 352 { 353 t->t_ops->t_periodic(t); 354 } 355 356 const char * 357 mdb_tgt_name(mdb_tgt_t *t) 358 { 359 return (t->t_ops->t_name(t)); 360 } 361 362 const char * 363 mdb_tgt_isa(mdb_tgt_t *t) 364 { 365 return (t->t_ops->t_isa(t)); 366 } 367 368 const char * 369 mdb_tgt_platform(mdb_tgt_t *t) 370 { 371 return (t->t_ops->t_platform(t)); 372 } 373 374 int 375 mdb_tgt_uname(mdb_tgt_t *t, struct utsname *utsp) 376 { 377 return (t->t_ops->t_uname(t, utsp)); 378 } 379 380 int 381 mdb_tgt_dmodel(mdb_tgt_t *t) 382 { 383 return (t->t_ops->t_dmodel(t)); 384 } 385 386 int 387 mdb_tgt_auxv(mdb_tgt_t *t, const auxv_t **auxvp) 388 { 389 return (t->t_ops->t_auxv(t, auxvp)); 390 } 391 392 ssize_t 393 mdb_tgt_aread(mdb_tgt_t *t, mdb_tgt_as_t as, 394 void *buf, size_t n, mdb_tgt_addr_t addr) 395 { 396 if (t->t_flags & MDB_TGT_F_ASIO) 397 return (t->t_ops->t_aread(t, as, buf, n, addr)); 398 399 switch ((uintptr_t)as) { 400 case (uintptr_t)MDB_TGT_AS_VIRT: 401 return (t->t_ops->t_vread(t, buf, n, addr)); 402 case (uintptr_t)MDB_TGT_AS_PHYS: 403 return (t->t_ops->t_pread(t, buf, n, addr)); 404 case (uintptr_t)MDB_TGT_AS_FILE: 405 return (t->t_ops->t_fread(t, buf, n, addr)); 406 case (uintptr_t)MDB_TGT_AS_IO: 407 return (t->t_ops->t_ioread(t, buf, n, addr)); 408 } 409 return (t->t_ops->t_aread(t, as, buf, n, addr)); 410 } 411 412 ssize_t 413 mdb_tgt_awrite(mdb_tgt_t *t, mdb_tgt_as_t as, 414 const void *buf, size_t n, mdb_tgt_addr_t addr) 415 { 416 if (!(t->t_flags & MDB_TGT_F_RDWR)) 417 return (set_errno(EMDB_TGTRDONLY)); 418 419 if (t->t_flags & MDB_TGT_F_ASIO) 420 return (t->t_ops->t_awrite(t, as, buf, n, addr)); 421 422 switch ((uintptr_t)as) { 423 case (uintptr_t)MDB_TGT_AS_VIRT: 424 return (t->t_ops->t_vwrite(t, buf, n, addr)); 425 case (uintptr_t)MDB_TGT_AS_PHYS: 426 return (t->t_ops->t_pwrite(t, buf, n, addr)); 427 case (uintptr_t)MDB_TGT_AS_FILE: 428 return (t->t_ops->t_fwrite(t, buf, n, addr)); 429 case (uintptr_t)MDB_TGT_AS_IO: 430 return (t->t_ops->t_iowrite(t, buf, n, addr)); 431 } 432 return (t->t_ops->t_awrite(t, as, buf, n, addr)); 433 } 434 435 ssize_t 436 mdb_tgt_vread(mdb_tgt_t *t, void *buf, size_t n, uintptr_t addr) 437 { 438 return (t->t_ops->t_vread(t, buf, n, addr)); 439 } 440 441 ssize_t 442 mdb_tgt_vwrite(mdb_tgt_t *t, const void *buf, size_t n, uintptr_t addr) 443 { 444 if (t->t_flags & MDB_TGT_F_RDWR) 445 return (t->t_ops->t_vwrite(t, buf, n, addr)); 446 447 return (set_errno(EMDB_TGTRDONLY)); 448 } 449 450 ssize_t 451 mdb_tgt_pread(mdb_tgt_t *t, void *buf, size_t n, physaddr_t addr) 452 { 453 return (t->t_ops->t_pread(t, buf, n, addr)); 454 } 455 456 ssize_t 457 mdb_tgt_pwrite(mdb_tgt_t *t, const void *buf, size_t n, physaddr_t addr) 458 { 459 if (t->t_flags & MDB_TGT_F_RDWR) 460 return (t->t_ops->t_pwrite(t, buf, n, addr)); 461 462 return (set_errno(EMDB_TGTRDONLY)); 463 } 464 465 ssize_t 466 mdb_tgt_fread(mdb_tgt_t *t, void *buf, size_t n, uintptr_t addr) 467 { 468 return (t->t_ops->t_fread(t, buf, n, addr)); 469 } 470 471 ssize_t 472 mdb_tgt_fwrite(mdb_tgt_t *t, const void *buf, size_t n, uintptr_t addr) 473 { 474 if (t->t_flags & MDB_TGT_F_RDWR) 475 return (t->t_ops->t_fwrite(t, buf, n, addr)); 476 477 return (set_errno(EMDB_TGTRDONLY)); 478 } 479 480 ssize_t 481 mdb_tgt_ioread(mdb_tgt_t *t, void *buf, size_t n, uintptr_t addr) 482 { 483 return (t->t_ops->t_ioread(t, buf, n, addr)); 484 } 485 486 ssize_t 487 mdb_tgt_iowrite(mdb_tgt_t *t, const void *buf, size_t n, uintptr_t addr) 488 { 489 if (t->t_flags & MDB_TGT_F_RDWR) 490 return (t->t_ops->t_iowrite(t, buf, n, addr)); 491 492 return (set_errno(EMDB_TGTRDONLY)); 493 } 494 495 int 496 mdb_tgt_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap) 497 { 498 return (t->t_ops->t_vtop(t, as, va, pap)); 499 } 500 501 ssize_t 502 mdb_tgt_readstr(mdb_tgt_t *t, mdb_tgt_as_t as, char *buf, 503 size_t nbytes, mdb_tgt_addr_t addr) 504 { 505 ssize_t n, nread = mdb_tgt_aread(t, as, buf, nbytes, addr); 506 char *p; 507 508 if (nread >= 0) { 509 if ((p = memchr(buf, '\0', nread)) != NULL) 510 nread = (size_t)(p - buf); 511 goto done; 512 } 513 514 nread = 0; 515 p = &buf[0]; 516 517 while (nread < nbytes && (n = mdb_tgt_aread(t, as, p, 1, addr)) == 1) { 518 if (*p == '\0') 519 return (nread); 520 nread++; 521 addr++; 522 p++; 523 } 524 525 if (nread == 0 && n == -1) 526 return (-1); /* If we can't even read a byte, return -1 */ 527 528 done: 529 if (nbytes != 0) 530 buf[MIN(nread, nbytes - 1)] = '\0'; 531 532 return (nread); 533 } 534 535 ssize_t 536 mdb_tgt_writestr(mdb_tgt_t *t, mdb_tgt_as_t as, 537 const char *buf, mdb_tgt_addr_t addr) 538 { 539 ssize_t nwritten = mdb_tgt_awrite(t, as, buf, strlen(buf) + 1, addr); 540 return (nwritten > 0 ? nwritten - 1 : nwritten); 541 } 542 543 int 544 mdb_tgt_lookup_by_name(mdb_tgt_t *t, const char *obj, 545 const char *name, GElf_Sym *symp, mdb_syminfo_t *sip) 546 { 547 mdb_syminfo_t info; 548 GElf_Sym sym; 549 uint_t id; 550 551 if (name == NULL || t == NULL) 552 return (set_errno(EINVAL)); 553 554 if (obj == MDB_TGT_OBJ_EVERY && 555 mdb_gelf_symtab_lookup_by_name(mdb.m_prsym, name, &sym, &id) == 0) { 556 info.sym_table = MDB_TGT_PRVSYM; 557 info.sym_id = id; 558 goto found; 559 } 560 561 if (t->t_ops->t_lookup_by_name(t, obj, name, &sym, &info) == 0) 562 goto found; 563 564 return (-1); 565 566 found: 567 if (symp != NULL) 568 *symp = sym; 569 if (sip != NULL) 570 *sip = info; 571 return (0); 572 } 573 574 int 575 mdb_tgt_lookup_by_addr(mdb_tgt_t *t, uintptr_t addr, uint_t flags, 576 char *buf, size_t len, GElf_Sym *symp, mdb_syminfo_t *sip) 577 { 578 mdb_syminfo_t info; 579 GElf_Sym sym; 580 581 if (t == NULL) 582 return (set_errno(EINVAL)); 583 584 if (t->t_ops->t_lookup_by_addr(t, addr, flags, 585 buf, len, &sym, &info) == 0) { 586 if (symp != NULL) 587 *symp = sym; 588 if (sip != NULL) 589 *sip = info; 590 return (0); 591 } 592 593 return (-1); 594 } 595 596 /* 597 * The mdb_tgt_lookup_by_scope function is a convenience routine for code that 598 * wants to look up a scoped symbol name such as "object`symbol". It is 599 * implemented as a simple wrapper around mdb_tgt_lookup_by_name. Note that 600 * we split on the *last* occurrence of "`", so the object name itself may 601 * contain additional scopes whose evaluation is left to the target. This 602 * allows targets to implement additional scopes, such as source files, 603 * function names, link map identifiers, etc. 604 */ 605 int 606 mdb_tgt_lookup_by_scope(mdb_tgt_t *t, const char *s, GElf_Sym *symp, 607 mdb_syminfo_t *sip) 608 { 609 const char *object = MDB_TGT_OBJ_EVERY; 610 const char *name = s; 611 char buf[MDB_TGT_SYM_NAMLEN]; 612 613 if (t == NULL) 614 return (set_errno(EINVAL)); 615 616 if (strchr(name, '`') != NULL) { 617 618 (void) strncpy(buf, s, sizeof (buf)); 619 buf[sizeof (buf) - 1] = '\0'; 620 name = buf; 621 622 if ((s = strrsplit(buf, '`')) != NULL) { 623 object = buf; 624 name = s; 625 if (*object == '\0') 626 return (set_errno(EMDB_NOOBJ)); 627 if (*name == '\0') 628 return (set_errno(EMDB_NOSYM)); 629 } 630 } 631 632 return (mdb_tgt_lookup_by_name(t, object, name, symp, sip)); 633 } 634 635 int 636 mdb_tgt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which, 637 uint_t type, mdb_tgt_sym_f *cb, void *p) 638 { 639 if ((which != MDB_TGT_SYMTAB && which != MDB_TGT_DYNSYM) || 640 (type & ~(MDB_TGT_BIND_ANY | MDB_TGT_TYPE_ANY)) != 0) 641 return (set_errno(EINVAL)); 642 643 return (t->t_ops->t_symbol_iter(t, obj, which, type, cb, p)); 644 } 645 646 ssize_t 647 mdb_tgt_readsym(mdb_tgt_t *t, mdb_tgt_as_t as, void *buf, size_t nbytes, 648 const char *obj, const char *name) 649 { 650 GElf_Sym sym; 651 652 if (mdb_tgt_lookup_by_name(t, obj, name, &sym, NULL) == 0) 653 return (mdb_tgt_aread(t, as, buf, nbytes, sym.st_value)); 654 655 return (-1); 656 } 657 658 ssize_t 659 mdb_tgt_writesym(mdb_tgt_t *t, mdb_tgt_as_t as, const void *buf, 660 size_t nbytes, const char *obj, const char *name) 661 { 662 GElf_Sym sym; 663 664 if (mdb_tgt_lookup_by_name(t, obj, name, &sym, NULL) == 0) 665 return (mdb_tgt_awrite(t, as, buf, nbytes, sym.st_value)); 666 667 return (-1); 668 } 669 670 int 671 mdb_tgt_mapping_iter(mdb_tgt_t *t, mdb_tgt_map_f *cb, void *p) 672 { 673 return (t->t_ops->t_mapping_iter(t, cb, p)); 674 } 675 676 int 677 mdb_tgt_object_iter(mdb_tgt_t *t, mdb_tgt_map_f *cb, void *p) 678 { 679 return (t->t_ops->t_object_iter(t, cb, p)); 680 } 681 682 const mdb_map_t * 683 mdb_tgt_addr_to_map(mdb_tgt_t *t, uintptr_t addr) 684 { 685 return (t->t_ops->t_addr_to_map(t, addr)); 686 } 687 688 const mdb_map_t * 689 mdb_tgt_name_to_map(mdb_tgt_t *t, const char *name) 690 { 691 return (t->t_ops->t_name_to_map(t, name)); 692 } 693 694 struct ctf_file * 695 mdb_tgt_addr_to_ctf(mdb_tgt_t *t, uintptr_t addr) 696 { 697 return (t->t_ops->t_addr_to_ctf(t, addr)); 698 } 699 700 struct ctf_file * 701 mdb_tgt_name_to_ctf(mdb_tgt_t *t, const char *name) 702 { 703 return (t->t_ops->t_name_to_ctf(t, name)); 704 } 705 706 /* 707 * Return the latest target status. We just copy out our cached copy. The 708 * status only needs to change when the target is run, stepped, or continued. 709 */ 710 int 711 mdb_tgt_status(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 712 { 713 uint_t dstop = (t->t_status.st_flags & MDB_TGT_DSTOP); 714 uint_t istop = (t->t_status.st_flags & MDB_TGT_ISTOP); 715 uint_t state = t->t_status.st_state; 716 717 if (tsp == NULL) 718 return (set_errno(EINVAL)); 719 720 /* 721 * If we're called with the address of the target's internal status, 722 * then call down to update it; otherwise copy out the saved status. 723 */ 724 if (tsp == &t->t_status && t->t_ops->t_status(t, &t->t_status) != 0) 725 return (-1); /* errno is set for us */ 726 727 /* 728 * Assert that our state is valid before returning it. The state must 729 * be valid, and DSTOP and ISTOP cannot be set simultaneously. ISTOP 730 * is only valid when stopped. DSTOP is only valid when running or 731 * stopped. If any test fails, abort the debugger. 732 */ 733 if (state > MDB_TGT_LOST) 734 fail("invalid target state (%u)\n", state); 735 if (state != MDB_TGT_STOPPED && istop) 736 fail("target state is (%u) and ISTOP is set\n", state); 737 if (state != MDB_TGT_STOPPED && state != MDB_TGT_RUNNING && dstop) 738 fail("target state is (%u) and DSTOP is set\n", state); 739 if (istop && dstop) 740 fail("target has ISTOP and DSTOP set simultaneously\n"); 741 742 if (tsp != &t->t_status) 743 bcopy(&t->t_status, tsp, sizeof (mdb_tgt_status_t)); 744 745 return (0); 746 } 747 748 /* 749 * For the given sespec, scan its list of vespecs for ones that are marked 750 * temporary and delete them. We use the same method as vespec_delete below. 751 */ 752 /*ARGSUSED*/ 753 void 754 mdb_tgt_sespec_prune_one(mdb_tgt_t *t, mdb_sespec_t *sep) 755 { 756 mdb_vespec_t *vep, *nvep; 757 758 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 759 nvep = mdb_list_next(vep); 760 761 if ((vep->ve_flags & (MDB_TGT_SPEC_DELETED | 762 MDB_TGT_SPEC_TEMPORARY)) == MDB_TGT_SPEC_TEMPORARY) { 763 vep->ve_flags |= MDB_TGT_SPEC_DELETED; 764 mdb_tgt_vespec_rele(t, vep); 765 } 766 } 767 } 768 769 /* 770 * Prune each sespec on the active list of temporary vespecs. This function 771 * is called, for example, after the target finishes a continue operation. 772 */ 773 void 774 mdb_tgt_sespec_prune_all(mdb_tgt_t *t) 775 { 776 mdb_sespec_t *sep, *nsep; 777 778 for (sep = mdb_list_next(&t->t_active); sep != NULL; sep = nsep) { 779 nsep = mdb_list_next(sep); 780 mdb_tgt_sespec_prune_one(t, sep); 781 } 782 } 783 784 /* 785 * Transition the given sespec to the IDLE state. We invoke the destructor, 786 * and then move the sespec from the active list to the idle list. 787 */ 788 void 789 mdb_tgt_sespec_idle_one(mdb_tgt_t *t, mdb_sespec_t *sep, int reason) 790 { 791 ASSERT(sep->se_state != MDB_TGT_SPEC_IDLE); 792 793 if (sep->se_state == MDB_TGT_SPEC_ARMED) 794 (void) sep->se_ops->se_disarm(t, sep); 795 796 sep->se_ops->se_dtor(t, sep); 797 sep->se_data = NULL; 798 799 sep->se_state = MDB_TGT_SPEC_IDLE; 800 sep->se_errno = reason; 801 802 mdb_list_delete(&t->t_active, sep); 803 mdb_list_append(&t->t_idle, sep); 804 805 mdb_tgt_sespec_prune_one(t, sep); 806 } 807 808 /* 809 * Transition each sespec on the active list to the IDLE state. This function 810 * is called, for example, after the target terminates execution. 811 */ 812 void 813 mdb_tgt_sespec_idle_all(mdb_tgt_t *t, int reason, int clear_matched) 814 { 815 mdb_sespec_t *sep, *nsep; 816 mdb_vespec_t *vep; 817 818 while ((sep = t->t_matched) != T_SE_END && clear_matched) { 819 for (vep = mdb_list_next(&sep->se_velist); vep != NULL; ) { 820 vep->ve_flags &= ~MDB_TGT_SPEC_MATCHED; 821 vep = mdb_list_next(vep); 822 } 823 824 t->t_matched = sep->se_matched; 825 sep->se_matched = NULL; 826 mdb_tgt_sespec_rele(t, sep); 827 } 828 829 for (sep = mdb_list_next(&t->t_active); sep != NULL; sep = nsep) { 830 nsep = mdb_list_next(sep); 831 mdb_tgt_sespec_idle_one(t, sep, reason); 832 } 833 } 834 835 /* 836 * Attempt to transition the given sespec from the IDLE to ACTIVE state. We 837 * do this by invoking se_ctor -- if this fails, we save the reason in se_errno 838 * and return -1 with errno set. One strange case we need to deal with here is 839 * the possibility that a given vespec is sitting on the idle list with its 840 * corresponding sespec, but it is actually a duplicate of another sespec on the 841 * active list. This can happen if the sespec is associated with a 842 * MDB_TGT_SPEC_DISABLED vespec that was just enabled, and is now ready to be 843 * activated. A more interesting reason this situation might arise is the case 844 * where a virtual address breakpoint is set at an address just mmap'ed by 845 * dlmopen. Since no symbol table information is available for this mapping 846 * yet, a pre-existing deferred symbolic breakpoint may already exist for this 847 * address, but it is on the idle list. When the symbol table is ready and the 848 * DLACTIVITY event occurs, we now discover that the virtual address obtained by 849 * evaluating the symbolic breakpoint matches the explicit virtual address of 850 * the active virtual breakpoint. To resolve this conflict in either case, we 851 * destroy the idle sespec, and attach its list of vespecs to the existing 852 * active sespec. 853 */ 854 int 855 mdb_tgt_sespec_activate_one(mdb_tgt_t *t, mdb_sespec_t *sep) 856 { 857 mdb_vespec_t *vep = mdb_list_next(&sep->se_velist); 858 859 mdb_vespec_t *nvep; 860 mdb_sespec_t *dup; 861 862 ASSERT(sep->se_state == MDB_TGT_SPEC_IDLE); 863 ASSERT(vep != NULL); 864 865 if (vep->ve_flags & MDB_TGT_SPEC_DISABLED) 866 return (0); /* cannot be activated while disabled bit set */ 867 868 /* 869 * First search the active list for an existing, duplicate sespec to 870 * handle the special case described above. 871 */ 872 for (dup = mdb_list_next(&t->t_active); dup; dup = mdb_list_next(dup)) { 873 if (dup->se_ops == sep->se_ops && 874 dup->se_ops->se_secmp(t, dup, vep->ve_args)) { 875 ASSERT(dup != sep); 876 break; 877 } 878 } 879 880 /* 881 * If a duplicate is found, destroy the existing, idle sespec, and 882 * attach all of its vespecs to the duplicate sespec. 883 */ 884 if (dup != NULL) { 885 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 886 mdb_dprintf(MDB_DBG_TGT, "merge [ %d ] to sespec %p\n", 887 vep->ve_id, (void *)dup); 888 889 if (dup->se_matched != NULL) 890 vep->ve_flags |= MDB_TGT_SPEC_MATCHED; 891 892 nvep = mdb_list_next(vep); 893 vep->ve_hits = 0; 894 895 mdb_list_delete(&sep->se_velist, vep); 896 mdb_tgt_sespec_rele(t, sep); 897 898 mdb_list_append(&dup->se_velist, vep); 899 mdb_tgt_sespec_hold(t, dup); 900 vep->ve_se = dup; 901 } 902 903 mdb_dprintf(MDB_DBG_TGT, "merged idle sespec %p with %p\n", 904 (void *)sep, (void *)dup); 905 return (0); 906 } 907 908 /* 909 * If no duplicate is found, call the sespec's constructor. If this 910 * is successful, move the sespec to the active list. 911 */ 912 if (sep->se_ops->se_ctor(t, sep, vep->ve_args) < 0) { 913 sep->se_errno = errno; 914 sep->se_data = NULL; 915 916 return (-1); 917 } 918 919 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 920 nvep = mdb_list_next(vep); 921 vep->ve_hits = 0; 922 } 923 mdb_list_delete(&t->t_idle, sep); 924 mdb_list_append(&t->t_active, sep); 925 sep->se_state = MDB_TGT_SPEC_ACTIVE; 926 sep->se_errno = 0; 927 928 return (0); 929 } 930 931 /* 932 * Transition each sespec on the idle list to the ACTIVE state. This function 933 * is called, for example, after the target's t_run() function returns. If 934 * the se_ctor() function fails, the specifier is not yet applicable; it will 935 * remain on the idle list and can be activated later. 936 * 937 * Returns 1 if there weren't any unexpected activation failures; 0 if there 938 * were. 939 */ 940 int 941 mdb_tgt_sespec_activate_all(mdb_tgt_t *t) 942 { 943 mdb_sespec_t *sep, *nsep; 944 int rc = 1; 945 946 for (sep = mdb_list_next(&t->t_idle); sep != NULL; sep = nsep) { 947 nsep = mdb_list_next(sep); 948 949 if (mdb_tgt_sespec_activate_one(t, sep) < 0 && 950 sep->se_errno != EMDB_NOOBJ) 951 rc = 0; 952 } 953 954 return (rc); 955 } 956 957 /* 958 * Transition the given sespec to the ARMED state. Note that we attempt to 959 * re-arm sespecs previously in the ERROR state. If se_arm() fails the sespec 960 * transitions to the ERROR state but stays on the active list. 961 */ 962 void 963 mdb_tgt_sespec_arm_one(mdb_tgt_t *t, mdb_sespec_t *sep) 964 { 965 ASSERT(sep->se_state != MDB_TGT_SPEC_IDLE); 966 967 if (sep->se_state == MDB_TGT_SPEC_ARMED) 968 return; /* do not arm sespecs more than once */ 969 970 if (sep->se_ops->se_arm(t, sep) == -1) { 971 sep->se_state = MDB_TGT_SPEC_ERROR; 972 sep->se_errno = errno; 973 } else { 974 sep->se_state = MDB_TGT_SPEC_ARMED; 975 sep->se_errno = 0; 976 } 977 } 978 979 /* 980 * Transition each sespec on the active list (except matched specs) to the 981 * ARMED state. This function is called prior to continuing the target. 982 */ 983 void 984 mdb_tgt_sespec_arm_all(mdb_tgt_t *t) 985 { 986 mdb_sespec_t *sep, *nsep; 987 988 for (sep = mdb_list_next(&t->t_active); sep != NULL; sep = nsep) { 989 nsep = mdb_list_next(sep); 990 if (sep->se_matched == NULL) 991 mdb_tgt_sespec_arm_one(t, sep); 992 } 993 } 994 995 /* 996 * Transition each sespec on the active list that is in the ARMED state to 997 * the ACTIVE state. If se_disarm() fails, the sespec is transitioned to 998 * the ERROR state instead, but left on the active list. 999 */ 1000 static void 1001 tgt_disarm_sespecs(mdb_tgt_t *t) 1002 { 1003 mdb_sespec_t *sep; 1004 1005 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 1006 if (sep->se_state != MDB_TGT_SPEC_ARMED) 1007 continue; /* do not disarm if in ERROR state */ 1008 1009 if (sep->se_ops->se_disarm(t, sep) == -1) { 1010 sep->se_state = MDB_TGT_SPEC_ERROR; 1011 sep->se_errno = errno; 1012 } else { 1013 sep->se_state = MDB_TGT_SPEC_ACTIVE; 1014 sep->se_errno = 0; 1015 } 1016 } 1017 } 1018 1019 /* 1020 * Determine if the software event that triggered the most recent stop matches 1021 * any of the active event specifiers. If 'all' is TRUE, we consider all 1022 * sespecs in our search. If 'all' is FALSE, we only consider ARMED sespecs. 1023 * If we successfully match an event, we add it to the t_matched list and 1024 * place an additional hold on it. 1025 */ 1026 static mdb_sespec_t * 1027 tgt_match_sespecs(mdb_tgt_t *t, int all) 1028 { 1029 mdb_sespec_t *sep; 1030 1031 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 1032 if (all == FALSE && sep->se_state != MDB_TGT_SPEC_ARMED) 1033 continue; /* restrict search to ARMED sespecs */ 1034 1035 if (sep->se_state != MDB_TGT_SPEC_ERROR && 1036 sep->se_ops->se_match(t, sep, &t->t_status)) { 1037 mdb_dprintf(MDB_DBG_TGT, "match se %p\n", (void *)sep); 1038 mdb_tgt_sespec_hold(t, sep); 1039 sep->se_matched = t->t_matched; 1040 t->t_matched = sep; 1041 } 1042 } 1043 1044 return (t->t_matched); 1045 } 1046 1047 /* 1048 * This function provides the low-level target continue algorithm. We proceed 1049 * in three phases: (1) we arm the active sespecs, except the specs matched at 1050 * the time we last stopped, (2) we call se_cont() on any matched sespecs to 1051 * step over these event transitions, and then arm the corresponding sespecs, 1052 * and (3) we call the appropriate low-level continue routine. Once the 1053 * target stops again, we determine which sespecs were matched, and invoke the 1054 * appropriate vespec callbacks and perform other vespec maintenance. 1055 */ 1056 static int 1057 tgt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp, 1058 int (*t_cont)(mdb_tgt_t *, mdb_tgt_status_t *)) 1059 { 1060 mdb_var_t *hitv = mdb_nv_lookup(&mdb.m_nv, "hits"); 1061 uintptr_t pc = t->t_status.st_pc; 1062 int error = 0; 1063 1064 mdb_sespec_t *sep, *nsep, *matched; 1065 mdb_vespec_t *vep, *nvep; 1066 uintptr_t addr; 1067 1068 uint_t cbits = 0; /* union of pending continue bits */ 1069 uint_t ncont = 0; /* # of callbacks that requested cont */ 1070 uint_t n = 0; /* # of callbacks */ 1071 1072 /* 1073 * If the target is undead, dead, or lost, we no longer allow continue. 1074 * This effectively forces the user to use ::kill or ::run after death. 1075 */ 1076 if (t->t_status.st_state == MDB_TGT_UNDEAD) 1077 return (set_errno(EMDB_TGTZOMB)); 1078 if (t->t_status.st_state == MDB_TGT_DEAD) 1079 return (set_errno(EMDB_TGTCORE)); 1080 if (t->t_status.st_state == MDB_TGT_LOST) 1081 return (set_errno(EMDB_TGTLOST)); 1082 1083 /* 1084 * If any of single-step, step-over, or step-out is pending, it takes 1085 * precedence over an explicit or pending continue, because these are 1086 * all different specialized forms of continue. 1087 */ 1088 if (t->t_flags & MDB_TGT_F_STEP) 1089 t_cont = t->t_ops->t_step; 1090 else if (t->t_flags & MDB_TGT_F_NEXT) 1091 t_cont = t->t_ops->t_step; 1092 else if (t->t_flags & MDB_TGT_F_STEP_OUT) 1093 t_cont = t->t_ops->t_cont; 1094 1095 /* 1096 * To handle step-over, we ask the target to find the address past the 1097 * next control transfer instruction. If an address is found, we plant 1098 * a temporary breakpoint there and continue; otherwise just step. 1099 */ 1100 if ((t->t_flags & MDB_TGT_F_NEXT) && !(t->t_flags & MDB_TGT_F_STEP)) { 1101 if (t->t_ops->t_next(t, &addr) == -1 || mdb_tgt_add_vbrkpt(t, 1102 addr, MDB_TGT_SPEC_HIDDEN | MDB_TGT_SPEC_TEMPORARY, 1103 no_se_f, NULL) == 0) { 1104 mdb_dprintf(MDB_DBG_TGT, "next falling back to step: " 1105 "%s\n", mdb_strerror(errno)); 1106 } else 1107 t_cont = t->t_ops->t_cont; 1108 } 1109 1110 /* 1111 * To handle step-out, we ask the target to find the return address of 1112 * the current frame, plant a temporary breakpoint there, and continue. 1113 */ 1114 if (t->t_flags & MDB_TGT_F_STEP_OUT) { 1115 if (t->t_ops->t_step_out(t, &addr) == -1) 1116 return (-1); /* errno is set for us */ 1117 1118 if (mdb_tgt_add_vbrkpt(t, addr, MDB_TGT_SPEC_HIDDEN | 1119 MDB_TGT_SPEC_TEMPORARY, no_se_f, NULL) == 0) 1120 return (-1); /* errno is set for us */ 1121 } 1122 1123 (void) mdb_signal_block(SIGHUP); 1124 (void) mdb_signal_block(SIGTERM); 1125 mdb_intr_disable(); 1126 1127 t->t_flags &= ~T_CONT_BITS; 1128 t->t_flags |= MDB_TGT_F_BUSY; 1129 mdb_tgt_sespec_arm_all(t); 1130 1131 ASSERT(t->t_matched != NULL); 1132 matched = t->t_matched; 1133 t->t_matched = T_SE_END; 1134 1135 if (mdb.m_term != NULL) 1136 IOP_SUSPEND(mdb.m_term); 1137 1138 /* 1139 * Iterate over the matched sespec list, performing autostop processing 1140 * and clearing the matched bit for each associated vespec. We then 1141 * invoke each sespec's se_cont callback in order to continue past 1142 * the corresponding event. If the matched list has more than one 1143 * sespec, we assume that the se_cont callbacks are non-interfering. 1144 */ 1145 for (sep = matched; sep != T_SE_END; sep = sep->se_matched) { 1146 for (vep = mdb_list_next(&sep->se_velist); vep != NULL; ) { 1147 if ((vep->ve_flags & MDB_TGT_SPEC_AUTOSTOP) && 1148 (vep->ve_limit && vep->ve_hits == vep->ve_limit)) 1149 vep->ve_hits = 0; 1150 1151 vep->ve_flags &= ~MDB_TGT_SPEC_MATCHED; 1152 vep = mdb_list_next(vep); 1153 } 1154 1155 if (sep->se_ops->se_cont(t, sep, &t->t_status) == -1) { 1156 error = errno ? errno : -1; 1157 tgt_disarm_sespecs(t); 1158 break; 1159 } 1160 1161 if (!(t->t_status.st_flags & MDB_TGT_ISTOP)) { 1162 tgt_disarm_sespecs(t); 1163 if (t->t_status.st_state == MDB_TGT_UNDEAD) 1164 mdb_tgt_sespec_idle_all(t, EMDB_TGTZOMB, TRUE); 1165 else if (t->t_status.st_state == MDB_TGT_LOST) 1166 mdb_tgt_sespec_idle_all(t, EMDB_TGTLOST, TRUE); 1167 break; 1168 } 1169 } 1170 1171 /* 1172 * Clear the se_matched field for each matched sespec, and drop the 1173 * reference count since the sespec is no longer on the matched list. 1174 */ 1175 for (sep = matched; sep != T_SE_END; sep = nsep) { 1176 nsep = sep->se_matched; 1177 sep->se_matched = NULL; 1178 mdb_tgt_sespec_rele(t, sep); 1179 } 1180 1181 /* 1182 * If the matched list was non-empty, see if we hit another event while 1183 * performing se_cont() processing. If so, don't bother continuing any 1184 * further. If not, arm the sespecs on the old matched list by calling 1185 * mdb_tgt_sespec_arm_all() again and then continue by calling t_cont. 1186 */ 1187 if (matched != T_SE_END) { 1188 if (error != 0 || !(t->t_status.st_flags & MDB_TGT_ISTOP)) 1189 goto out; /* abort now if se_cont() failed */ 1190 1191 if ((t->t_matched = tgt_match_sespecs(t, FALSE)) != T_SE_END) { 1192 tgt_disarm_sespecs(t); 1193 goto out; 1194 } 1195 1196 mdb_tgt_sespec_arm_all(t); 1197 } 1198 1199 if (t_cont != t->t_ops->t_step || pc == t->t_status.st_pc) { 1200 if (t_cont(t, &t->t_status) != 0) 1201 error = errno ? errno : -1; 1202 } 1203 1204 tgt_disarm_sespecs(t); 1205 1206 if (t->t_flags & MDB_TGT_F_UNLOAD) 1207 longjmp(mdb.m_frame->f_pcb, MDB_ERR_QUIT); 1208 1209 if (t->t_status.st_state == MDB_TGT_UNDEAD) 1210 mdb_tgt_sespec_idle_all(t, EMDB_TGTZOMB, TRUE); 1211 else if (t->t_status.st_state == MDB_TGT_LOST) 1212 mdb_tgt_sespec_idle_all(t, EMDB_TGTLOST, TRUE); 1213 else if (t->t_status.st_flags & MDB_TGT_ISTOP) 1214 t->t_matched = tgt_match_sespecs(t, TRUE); 1215 out: 1216 if (mdb.m_term != NULL) 1217 IOP_RESUME(mdb.m_term); 1218 1219 (void) mdb_signal_unblock(SIGTERM); 1220 (void) mdb_signal_unblock(SIGHUP); 1221 mdb_intr_enable(); 1222 1223 for (sep = t->t_matched; sep != T_SE_END; sep = sep->se_matched) { 1224 /* 1225 * When we invoke a ve_callback, it may in turn request that the 1226 * target continue immediately after callback processing is 1227 * complete. We only allow this to occur if *all* callbacks 1228 * agree to continue. To implement this behavior, we keep a 1229 * count (ncont) of such requests, and only apply the cumulative 1230 * continue bits (cbits) to the target if ncont is equal to the 1231 * total number of callbacks that are invoked (n). 1232 */ 1233 for (vep = mdb_list_next(&sep->se_velist); 1234 vep != NULL; vep = nvep, n++) { 1235 /* 1236 * Place an extra hold on the current vespec and pick 1237 * up the next pointer before invoking the callback: we 1238 * must be prepared for the vespec to be deleted or 1239 * moved to a different list by the callback. 1240 */ 1241 mdb_tgt_vespec_hold(t, vep); 1242 nvep = mdb_list_next(vep); 1243 1244 vep->ve_flags |= MDB_TGT_SPEC_MATCHED; 1245 vep->ve_hits++; 1246 1247 mdb_nv_set_value(mdb.m_dot, t->t_status.st_pc); 1248 mdb_nv_set_value(hitv, vep->ve_hits); 1249 1250 ASSERT((t->t_flags & T_CONT_BITS) == 0); 1251 vep->ve_callback(t, vep->ve_id, vep->ve_data); 1252 1253 ncont += (t->t_flags & T_CONT_BITS) != 0; 1254 cbits |= (t->t_flags & T_CONT_BITS); 1255 t->t_flags &= ~T_CONT_BITS; 1256 1257 if (vep->ve_limit && vep->ve_hits == vep->ve_limit) { 1258 if (vep->ve_flags & MDB_TGT_SPEC_AUTODEL) 1259 (void) mdb_tgt_vespec_delete(t, 1260 vep->ve_id); 1261 else if (vep->ve_flags & MDB_TGT_SPEC_AUTODIS) 1262 (void) mdb_tgt_vespec_disable(t, 1263 vep->ve_id); 1264 } 1265 1266 if (vep->ve_limit && vep->ve_hits < vep->ve_limit) { 1267 if (vep->ve_flags & MDB_TGT_SPEC_AUTOSTOP) 1268 (void) mdb_tgt_continue(t, NULL); 1269 } 1270 1271 mdb_tgt_vespec_rele(t, vep); 1272 } 1273 } 1274 1275 if (t->t_matched != T_SE_END && ncont == n) 1276 t->t_flags |= cbits; /* apply continues (see above) */ 1277 1278 mdb_tgt_sespec_prune_all(t); 1279 1280 t->t_status.st_flags &= ~MDB_TGT_BUSY; 1281 t->t_flags &= ~MDB_TGT_F_BUSY; 1282 1283 if (tsp != NULL) 1284 bcopy(&t->t_status, tsp, sizeof (mdb_tgt_status_t)); 1285 1286 if (error != 0) 1287 return (set_errno(error)); 1288 1289 return (0); 1290 } 1291 1292 /* 1293 * This function is the common glue that connects the high-level target layer 1294 * continue functions (e.g. step and cont below) with the low-level 1295 * tgt_continue() function above. Since vespec callbacks may perform any 1296 * actions, including attempting to continue the target itself, we must be 1297 * prepared to be called while the target is still marked F_BUSY. In this 1298 * case, we just set a pending bit and return. When we return from the call 1299 * to tgt_continue() that made us busy into the tgt_request_continue() call 1300 * that is still on the stack, we will loop around and call tgt_continue() 1301 * again. This allows vespecs to continue the target without recursion. 1302 */ 1303 static int 1304 tgt_request_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp, uint_t tflag, 1305 int (*t_cont)(mdb_tgt_t *, mdb_tgt_status_t *)) 1306 { 1307 mdb_tgt_spec_desc_t desc; 1308 mdb_sespec_t *sep; 1309 char buf[BUFSIZ]; 1310 int status; 1311 1312 if (t->t_flags & MDB_TGT_F_BUSY) { 1313 t->t_flags |= tflag; 1314 return (0); 1315 } 1316 1317 do { 1318 status = tgt_continue(t, tsp, t_cont); 1319 } while (status == 0 && (t->t_flags & T_CONT_BITS)); 1320 1321 if (status == 0) { 1322 for (sep = t->t_matched; sep != T_SE_END; 1323 sep = sep->se_matched) { 1324 mdb_vespec_t *vep; 1325 1326 for (vep = mdb_list_next(&sep->se_velist); vep; 1327 vep = mdb_list_next(vep)) { 1328 if (vep->ve_flags & MDB_TGT_SPEC_SILENT) 1329 continue; 1330 warn("%s\n", sep->se_ops->se_info(t, sep, 1331 vep, &desc, buf, sizeof (buf))); 1332 } 1333 } 1334 1335 mdb_callb_fire(MDB_CALLB_STCHG); 1336 } 1337 1338 t->t_flags &= ~T_CONT_BITS; 1339 return (status); 1340 } 1341 1342 /* 1343 * Restart target execution: we rely upon the underlying target implementation 1344 * to do most of the work for us. In particular, we assume it will properly 1345 * preserve the state of our event lists if the run fails for some reason, 1346 * and that it will reset all events to the IDLE state if the run succeeds. 1347 * If it is successful, we attempt to activate all of the idle sespecs. The 1348 * t_run() operation is defined to leave the target stopped at the earliest 1349 * possible point in execution, and then return control to the debugger, 1350 * awaiting a step or continue operation to set it running again. 1351 */ 1352 int 1353 mdb_tgt_run(mdb_tgt_t *t, int argc, const mdb_arg_t *argv) 1354 { 1355 int i; 1356 1357 for (i = 0; i < argc; i++) { 1358 if (argv->a_type != MDB_TYPE_STRING) 1359 return (set_errno(EINVAL)); 1360 } 1361 1362 if (t->t_ops->t_run(t, argc, argv) == -1) 1363 return (-1); /* errno is set for us */ 1364 1365 t->t_flags &= ~T_CONT_BITS; 1366 (void) mdb_tgt_sespec_activate_all(t); 1367 1368 if (mdb.m_term != NULL) 1369 IOP_CTL(mdb.m_term, MDB_IOC_CTTY, NULL); 1370 1371 return (0); 1372 } 1373 1374 int 1375 mdb_tgt_step(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 1376 { 1377 return (tgt_request_continue(t, tsp, MDB_TGT_F_STEP, t->t_ops->t_step)); 1378 } 1379 1380 int 1381 mdb_tgt_step_out(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 1382 { 1383 t->t_flags |= MDB_TGT_F_STEP_OUT; /* set flag even if tgt not busy */ 1384 return (tgt_request_continue(t, tsp, 0, t->t_ops->t_cont)); 1385 } 1386 1387 int 1388 mdb_tgt_next(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 1389 { 1390 t->t_flags |= MDB_TGT_F_NEXT; /* set flag even if tgt not busy */ 1391 return (tgt_request_continue(t, tsp, 0, t->t_ops->t_step)); 1392 } 1393 1394 int 1395 mdb_tgt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 1396 { 1397 return (tgt_request_continue(t, tsp, MDB_TGT_F_CONT, t->t_ops->t_cont)); 1398 } 1399 1400 int 1401 mdb_tgt_signal(mdb_tgt_t *t, int sig) 1402 { 1403 return (t->t_ops->t_signal(t, sig)); 1404 } 1405 1406 void * 1407 mdb_tgt_vespec_data(mdb_tgt_t *t, int vid) 1408 { 1409 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, vid); 1410 1411 if (vep == NULL) { 1412 (void) set_errno(EMDB_NOSESPEC); 1413 return (NULL); 1414 } 1415 1416 return (vep->ve_data); 1417 } 1418 1419 /* 1420 * Return a structured description and comment string for the given vespec. 1421 * We fill in the common information from the vespec, and then call down to 1422 * the underlying sespec to provide the comment string and modify any 1423 * event type-specific information. 1424 */ 1425 char * 1426 mdb_tgt_vespec_info(mdb_tgt_t *t, int vid, mdb_tgt_spec_desc_t *sp, 1427 char *buf, size_t nbytes) 1428 { 1429 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, vid); 1430 1431 mdb_tgt_spec_desc_t desc; 1432 mdb_sespec_t *sep; 1433 1434 if (vep == NULL) { 1435 if (sp != NULL) 1436 bzero(sp, sizeof (mdb_tgt_spec_desc_t)); 1437 (void) set_errno(EMDB_NOSESPEC); 1438 return (NULL); 1439 } 1440 1441 if (sp == NULL) 1442 sp = &desc; 1443 1444 sep = vep->ve_se; 1445 1446 sp->spec_id = vep->ve_id; 1447 sp->spec_flags = vep->ve_flags; 1448 sp->spec_hits = vep->ve_hits; 1449 sp->spec_limit = vep->ve_limit; 1450 sp->spec_state = sep->se_state; 1451 sp->spec_errno = sep->se_errno; 1452 sp->spec_base = NULL; 1453 sp->spec_size = 0; 1454 sp->spec_data = vep->ve_data; 1455 1456 return (sep->se_ops->se_info(t, sep, vep, sp, buf, nbytes)); 1457 } 1458 1459 /* 1460 * Qsort callback for sorting vespecs by VID, used below. 1461 */ 1462 static int 1463 tgt_vespec_compare(const mdb_vespec_t **lp, const mdb_vespec_t **rp) 1464 { 1465 return ((*lp)->ve_id - (*rp)->ve_id); 1466 } 1467 1468 /* 1469 * Iterate over all vespecs and call the specified callback function with the 1470 * corresponding VID and caller data pointer. We want the callback function 1471 * to see a consistent, sorted snapshot of the vespecs, and allow the callback 1472 * to take actions such as deleting the vespec itself, so we cannot simply 1473 * iterate over the lists. Instead, we pre-allocate an array of vespec 1474 * pointers, fill it in and place an additional hold on each vespec, and then 1475 * sort it. After the callback has been executed on each vespec in the 1476 * sorted array, we remove our hold and free the temporary array. 1477 */ 1478 int 1479 mdb_tgt_vespec_iter(mdb_tgt_t *t, mdb_tgt_vespec_f *func, void *p) 1480 { 1481 mdb_vespec_t **veps, **vepp, **vend; 1482 mdb_vespec_t *vep, *nvep; 1483 mdb_sespec_t *sep; 1484 1485 uint_t vecnt = t->t_vecnt; 1486 1487 veps = mdb_alloc(sizeof (mdb_vespec_t *) * vecnt, UM_SLEEP); 1488 vend = veps + vecnt; 1489 vepp = veps; 1490 1491 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 1492 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 1493 mdb_tgt_vespec_hold(t, vep); 1494 nvep = mdb_list_next(vep); 1495 *vepp++ = vep; 1496 } 1497 } 1498 1499 for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) { 1500 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 1501 mdb_tgt_vespec_hold(t, vep); 1502 nvep = mdb_list_next(vep); 1503 *vepp++ = vep; 1504 } 1505 } 1506 1507 if (vepp != vend) { 1508 fail("target has %u vespecs on list but vecnt shows %u\n", 1509 (uint_t)(vepp - veps), vecnt); 1510 } 1511 1512 qsort(veps, vecnt, sizeof (mdb_vespec_t *), 1513 (int (*)(const void *, const void *))tgt_vespec_compare); 1514 1515 for (vepp = veps; vepp < vend; vepp++) { 1516 if (func(t, p, (*vepp)->ve_id, (*vepp)->ve_data) != 0) 1517 break; 1518 } 1519 1520 for (vepp = veps; vepp < vend; vepp++) 1521 mdb_tgt_vespec_rele(t, *vepp); 1522 1523 mdb_free(veps, sizeof (mdb_vespec_t *) * vecnt); 1524 return (0); 1525 } 1526 1527 /* 1528 * Reset the vespec flags, match limit, and callback data to the specified 1529 * values. We silently correct invalid parameters, except for the VID. 1530 * The caller is required to query the existing properties and pass back 1531 * the existing values for any properties that should not be modified. 1532 * If the callback data is modified, the caller is responsible for cleaning 1533 * up any state associated with the previous value. 1534 */ 1535 int 1536 mdb_tgt_vespec_modify(mdb_tgt_t *t, int id, uint_t flags, 1537 uint_t limit, void *data) 1538 { 1539 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id); 1540 1541 if (vep == NULL) 1542 return (set_errno(EMDB_NOSESPEC)); 1543 1544 /* 1545 * If the value of the MDB_TGT_SPEC_DISABLED bit is changing, call the 1546 * appropriate vespec function to do the enable/disable work. 1547 */ 1548 if ((flags & MDB_TGT_SPEC_DISABLED) != 1549 (vep->ve_flags & MDB_TGT_SPEC_DISABLED)) { 1550 if (flags & MDB_TGT_SPEC_DISABLED) 1551 (void) mdb_tgt_vespec_disable(t, id); 1552 else 1553 (void) mdb_tgt_vespec_enable(t, id); 1554 } 1555 1556 /* 1557 * Make that only one MDB_TGT_SPEC_AUTO* bit is set in the new flags 1558 * value: extra bits are cleared according to order of precedence. 1559 */ 1560 if (flags & MDB_TGT_SPEC_AUTOSTOP) 1561 flags &= ~(MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS); 1562 else if (flags & MDB_TGT_SPEC_AUTODEL) 1563 flags &= ~MDB_TGT_SPEC_AUTODIS; 1564 1565 /* 1566 * The TEMPORARY property always takes precedence over STICKY. 1567 */ 1568 if (flags & MDB_TGT_SPEC_TEMPORARY) 1569 flags &= ~MDB_TGT_SPEC_STICKY; 1570 1571 /* 1572 * If any MDB_TGT_SPEC_AUTO* bits are changing, reset the hit count 1573 * back to zero and clear all of the old auto bits. 1574 */ 1575 if ((flags & T_AUTO_BITS) != (vep->ve_flags & T_AUTO_BITS)) { 1576 vep->ve_flags &= ~T_AUTO_BITS; 1577 vep->ve_hits = 0; 1578 } 1579 1580 vep->ve_flags = (vep->ve_flags & T_IMPL_BITS) | (flags & ~T_IMPL_BITS); 1581 vep->ve_data = data; 1582 1583 /* 1584 * If any MDB_TGT_SPEC_AUTO* flags are set, make sure the limit is at 1585 * least one. If none are set, reset it back to zero. 1586 */ 1587 if (vep->ve_flags & T_AUTO_BITS) 1588 vep->ve_limit = MAX(limit, 1); 1589 else 1590 vep->ve_limit = 0; 1591 1592 /* 1593 * As a convenience, we allow the caller to specify SPEC_DELETED in 1594 * the flags field as indication that the event should be deleted. 1595 */ 1596 if (flags & MDB_TGT_SPEC_DELETED) 1597 (void) mdb_tgt_vespec_delete(t, id); 1598 1599 return (0); 1600 } 1601 1602 /* 1603 * Remove the user disabled bit from the specified vespec, and attempt to 1604 * activate the underlying sespec and move it to the active list if possible. 1605 */ 1606 int 1607 mdb_tgt_vespec_enable(mdb_tgt_t *t, int id) 1608 { 1609 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id); 1610 1611 if (vep == NULL) 1612 return (set_errno(EMDB_NOSESPEC)); 1613 1614 if (vep->ve_flags & MDB_TGT_SPEC_DISABLED) { 1615 ASSERT(mdb_list_next(vep) == NULL); 1616 vep->ve_flags &= ~MDB_TGT_SPEC_DISABLED; 1617 if (mdb_tgt_sespec_activate_one(t, vep->ve_se) < 0) 1618 return (-1); /* errno is set for us */ 1619 } 1620 1621 return (0); 1622 } 1623 1624 /* 1625 * Set the user disabled bit on the specified vespec, and move it to the idle 1626 * list. If the vespec is not alone with its sespec or if it is a currently 1627 * matched event, we must always create a new idle sespec and move the vespec 1628 * there. If the vespec was alone and active, we can simply idle the sespec. 1629 */ 1630 int 1631 mdb_tgt_vespec_disable(mdb_tgt_t *t, int id) 1632 { 1633 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id); 1634 mdb_sespec_t *sep; 1635 1636 if (vep == NULL) 1637 return (set_errno(EMDB_NOSESPEC)); 1638 1639 if (vep->ve_flags & MDB_TGT_SPEC_DISABLED) 1640 return (0); /* already disabled */ 1641 1642 if (mdb_list_prev(vep) != NULL || mdb_list_next(vep) != NULL || 1643 vep->ve_se->se_matched != NULL) { 1644 1645 sep = mdb_tgt_sespec_insert(t, vep->ve_se->se_ops, &t->t_idle); 1646 1647 mdb_list_delete(&vep->ve_se->se_velist, vep); 1648 mdb_tgt_sespec_rele(t, vep->ve_se); 1649 1650 mdb_list_append(&sep->se_velist, vep); 1651 mdb_tgt_sespec_hold(t, sep); 1652 1653 vep->ve_flags &= ~MDB_TGT_SPEC_MATCHED; 1654 vep->ve_se = sep; 1655 1656 } else if (vep->ve_se->se_state != MDB_TGT_SPEC_IDLE) 1657 mdb_tgt_sespec_idle_one(t, vep->ve_se, EMDB_SPECDIS); 1658 1659 vep->ve_flags |= MDB_TGT_SPEC_DISABLED; 1660 return (0); 1661 } 1662 1663 /* 1664 * Delete the given vespec. We use the MDB_TGT_SPEC_DELETED flag to ensure that 1665 * multiple calls to mdb_tgt_vespec_delete to not attempt to decrement the 1666 * reference count on the vespec more than once. This is because the vespec 1667 * may remain referenced if it is currently held by another routine (e.g. 1668 * vespec_iter), and so the user could attempt to delete it more than once 1669 * since it reference count will be >= 2 prior to the first delete call. 1670 */ 1671 int 1672 mdb_tgt_vespec_delete(mdb_tgt_t *t, int id) 1673 { 1674 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id); 1675 1676 if (vep == NULL) 1677 return (set_errno(EMDB_NOSESPEC)); 1678 1679 if (vep->ve_flags & MDB_TGT_SPEC_DELETED) 1680 return (set_errno(EBUSY)); 1681 1682 vep->ve_flags |= MDB_TGT_SPEC_DELETED; 1683 mdb_tgt_vespec_rele(t, vep); 1684 return (0); 1685 } 1686 1687 int 1688 mdb_tgt_add_vbrkpt(mdb_tgt_t *t, uintptr_t addr, 1689 int spec_flags, mdb_tgt_se_f *func, void *p) 1690 { 1691 return (t->t_ops->t_add_vbrkpt(t, addr, spec_flags, func, p)); 1692 } 1693 1694 int 1695 mdb_tgt_add_sbrkpt(mdb_tgt_t *t, const char *symbol, 1696 int spec_flags, mdb_tgt_se_f *func, void *p) 1697 { 1698 return (t->t_ops->t_add_sbrkpt(t, symbol, spec_flags, func, p)); 1699 } 1700 1701 int 1702 mdb_tgt_add_pwapt(mdb_tgt_t *t, physaddr_t pa, size_t n, uint_t flags, 1703 int spec_flags, mdb_tgt_se_f *func, void *p) 1704 { 1705 if ((flags & ~MDB_TGT_WA_RWX) || flags == 0) { 1706 (void) set_errno(EINVAL); 1707 return (0); 1708 } 1709 1710 if (pa + n < pa) { 1711 (void) set_errno(EMDB_WPRANGE); 1712 return (0); 1713 } 1714 1715 return (t->t_ops->t_add_pwapt(t, pa, n, flags, spec_flags, func, p)); 1716 } 1717 1718 int 1719 mdb_tgt_add_vwapt(mdb_tgt_t *t, uintptr_t va, size_t n, uint_t flags, 1720 int spec_flags, mdb_tgt_se_f *func, void *p) 1721 { 1722 if ((flags & ~MDB_TGT_WA_RWX) || flags == 0) { 1723 (void) set_errno(EINVAL); 1724 return (0); 1725 } 1726 1727 if (va + n < va) { 1728 (void) set_errno(EMDB_WPRANGE); 1729 return (0); 1730 } 1731 1732 return (t->t_ops->t_add_vwapt(t, va, n, flags, spec_flags, func, p)); 1733 } 1734 1735 int 1736 mdb_tgt_add_iowapt(mdb_tgt_t *t, uintptr_t addr, size_t n, uint_t flags, 1737 int spec_flags, mdb_tgt_se_f *func, void *p) 1738 { 1739 if ((flags & ~MDB_TGT_WA_RWX) || flags == 0) { 1740 (void) set_errno(EINVAL); 1741 return (0); 1742 } 1743 1744 if (addr + n < addr) { 1745 (void) set_errno(EMDB_WPRANGE); 1746 return (0); 1747 } 1748 1749 return (t->t_ops->t_add_iowapt(t, addr, n, flags, spec_flags, func, p)); 1750 } 1751 1752 int 1753 mdb_tgt_add_sysenter(mdb_tgt_t *t, int sysnum, 1754 int spec_flags, mdb_tgt_se_f *func, void *p) 1755 { 1756 return (t->t_ops->t_add_sysenter(t, sysnum, spec_flags, func, p)); 1757 } 1758 1759 int 1760 mdb_tgt_add_sysexit(mdb_tgt_t *t, int sysnum, 1761 int spec_flags, mdb_tgt_se_f *func, void *p) 1762 { 1763 return (t->t_ops->t_add_sysexit(t, sysnum, spec_flags, func, p)); 1764 } 1765 1766 int 1767 mdb_tgt_add_signal(mdb_tgt_t *t, int sig, 1768 int spec_flags, mdb_tgt_se_f *func, void *p) 1769 { 1770 return (t->t_ops->t_add_signal(t, sig, spec_flags, func, p)); 1771 } 1772 1773 int 1774 mdb_tgt_add_fault(mdb_tgt_t *t, int flt, 1775 int spec_flags, mdb_tgt_se_f *func, void *p) 1776 { 1777 return (t->t_ops->t_add_fault(t, flt, spec_flags, func, p)); 1778 } 1779 1780 int 1781 mdb_tgt_getareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, 1782 const char *rname, mdb_tgt_reg_t *rp) 1783 { 1784 return (t->t_ops->t_getareg(t, tid, rname, rp)); 1785 } 1786 1787 int 1788 mdb_tgt_putareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, 1789 const char *rname, mdb_tgt_reg_t r) 1790 { 1791 return (t->t_ops->t_putareg(t, tid, rname, r)); 1792 } 1793 1794 int 1795 mdb_tgt_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gregs, 1796 mdb_tgt_stack_f *cb, void *p) 1797 { 1798 return (t->t_ops->t_stack_iter(t, gregs, cb, p)); 1799 } 1800 1801 int 1802 mdb_tgt_xdata_iter(mdb_tgt_t *t, mdb_tgt_xdata_f *func, void *private) 1803 { 1804 mdb_xdata_t *xdp; 1805 1806 for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) { 1807 if (func(private, xdp->xd_name, xdp->xd_desc, 1808 xdp->xd_copy(t, NULL, 0)) != 0) 1809 break; 1810 } 1811 1812 return (0); 1813 } 1814 1815 ssize_t 1816 mdb_tgt_getxdata(mdb_tgt_t *t, const char *name, void *buf, size_t nbytes) 1817 { 1818 mdb_xdata_t *xdp; 1819 1820 for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) { 1821 if (strcmp(xdp->xd_name, name) == 0) 1822 return (xdp->xd_copy(t, buf, nbytes)); 1823 } 1824 1825 return (set_errno(ENODATA)); 1826 } 1827 1828 long 1829 mdb_tgt_notsup() 1830 { 1831 return (set_errno(EMDB_TGTNOTSUP)); 1832 } 1833 1834 void * 1835 mdb_tgt_null() 1836 { 1837 (void) set_errno(EMDB_TGTNOTSUP); 1838 return (NULL); 1839 } 1840 1841 long 1842 mdb_tgt_nop() 1843 { 1844 return (0L); 1845 } 1846 1847 int 1848 mdb_tgt_xdata_insert(mdb_tgt_t *t, const char *name, const char *desc, 1849 ssize_t (*copy)(mdb_tgt_t *, void *, size_t)) 1850 { 1851 mdb_xdata_t *xdp; 1852 1853 for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) { 1854 if (strcmp(xdp->xd_name, name) == 0) 1855 return (set_errno(EMDB_XDEXISTS)); 1856 } 1857 1858 xdp = mdb_alloc(sizeof (mdb_xdata_t), UM_SLEEP); 1859 mdb_list_append(&t->t_xdlist, xdp); 1860 1861 xdp->xd_name = name; 1862 xdp->xd_desc = desc; 1863 xdp->xd_copy = copy; 1864 1865 return (0); 1866 } 1867 1868 int 1869 mdb_tgt_xdata_delete(mdb_tgt_t *t, const char *name) 1870 { 1871 mdb_xdata_t *xdp; 1872 1873 for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) { 1874 if (strcmp(xdp->xd_name, name) == 0) { 1875 mdb_list_delete(&t->t_xdlist, xdp); 1876 mdb_free(xdp, sizeof (mdb_xdata_t)); 1877 return (0); 1878 } 1879 } 1880 1881 return (set_errno(EMDB_NOXD)); 1882 } 1883 1884 int 1885 mdb_tgt_sym_match(const GElf_Sym *sym, uint_t mask) 1886 { 1887 #if STT_NUM != (STT_TLS + 1) 1888 #error "STT_NUM has grown. update mdb_tgt_sym_match()" 1889 #endif 1890 1891 uchar_t s_bind = GELF_ST_BIND(sym->st_info); 1892 uchar_t s_type = GELF_ST_TYPE(sym->st_info); 1893 1894 /* 1895 * In case you haven't already guessed, this relies on the bitmask 1896 * used by <mdb/mdb_target.h> and <libproc.h> for encoding symbol 1897 * type and binding matching the order of STB and STT constants 1898 * in <sys/elf.h>. Changes to ELF must maintain binary 1899 * compatibility, so I think this is reasonably fair game. 1900 */ 1901 if (s_bind < STB_NUM && s_type < STT_NUM) { 1902 uint_t type = (1 << (s_type + 8)) | (1 << s_bind); 1903 return ((type & ~mask) == 0); 1904 } 1905 1906 return (0); /* Unknown binding or type; fail to match */ 1907 } 1908 1909 void 1910 mdb_tgt_elf_export(mdb_gelf_file_t *gf) 1911 { 1912 GElf_Xword d = 0, t = 0; 1913 GElf_Addr b = 0, e = 0; 1914 uint32_t m = 0; 1915 mdb_var_t *v; 1916 1917 /* 1918 * Reset legacy adb variables based on the specified ELF object file 1919 * provided by the target. We define these variables: 1920 * 1921 * b - the address of the data segment (first writeable Phdr) 1922 * d - the size of the data segment 1923 * e - the address of the entry point 1924 * m - the magic number identifying the file 1925 * t - the address of the text segment (first executable Phdr) 1926 */ 1927 if (gf != NULL) { 1928 const GElf_Phdr *text = NULL, *data = NULL; 1929 size_t i; 1930 1931 e = gf->gf_ehdr.e_entry; 1932 bcopy(&gf->gf_ehdr.e_ident[EI_MAG0], &m, sizeof (m)); 1933 1934 for (i = 0; i < gf->gf_npload; i++) { 1935 if (text == NULL && (gf->gf_phdrs[i].p_flags & PF_X)) 1936 text = &gf->gf_phdrs[i]; 1937 if (data == NULL && (gf->gf_phdrs[i].p_flags & PF_W)) 1938 data = &gf->gf_phdrs[i]; 1939 } 1940 1941 if (text != NULL) 1942 t = text->p_memsz; 1943 if (data != NULL) { 1944 b = data->p_vaddr; 1945 d = data->p_memsz; 1946 } 1947 } 1948 1949 if ((v = mdb_nv_lookup(&mdb.m_nv, "b")) != NULL) 1950 mdb_nv_set_value(v, b); 1951 if ((v = mdb_nv_lookup(&mdb.m_nv, "d")) != NULL) 1952 mdb_nv_set_value(v, d); 1953 if ((v = mdb_nv_lookup(&mdb.m_nv, "e")) != NULL) 1954 mdb_nv_set_value(v, e); 1955 if ((v = mdb_nv_lookup(&mdb.m_nv, "m")) != NULL) 1956 mdb_nv_set_value(v, m); 1957 if ((v = mdb_nv_lookup(&mdb.m_nv, "t")) != NULL) 1958 mdb_nv_set_value(v, t); 1959 } 1960 1961 /*ARGSUSED*/ 1962 void 1963 mdb_tgt_sespec_hold(mdb_tgt_t *t, mdb_sespec_t *sep) 1964 { 1965 sep->se_refs++; 1966 ASSERT(sep->se_refs != 0); 1967 } 1968 1969 void 1970 mdb_tgt_sespec_rele(mdb_tgt_t *t, mdb_sespec_t *sep) 1971 { 1972 ASSERT(sep->se_refs != 0); 1973 1974 if (--sep->se_refs == 0) { 1975 mdb_dprintf(MDB_DBG_TGT, "destroying sespec %p\n", (void *)sep); 1976 ASSERT(mdb_list_next(&sep->se_velist) == NULL); 1977 1978 if (sep->se_state != MDB_TGT_SPEC_IDLE) { 1979 sep->se_ops->se_dtor(t, sep); 1980 mdb_list_delete(&t->t_active, sep); 1981 } else 1982 mdb_list_delete(&t->t_idle, sep); 1983 1984 mdb_free(sep, sizeof (mdb_sespec_t)); 1985 } 1986 } 1987 1988 mdb_sespec_t * 1989 mdb_tgt_sespec_insert(mdb_tgt_t *t, const mdb_se_ops_t *ops, mdb_list_t *list) 1990 { 1991 mdb_sespec_t *sep = mdb_zalloc(sizeof (mdb_sespec_t), UM_SLEEP); 1992 1993 if (list == &t->t_active) 1994 sep->se_state = MDB_TGT_SPEC_ACTIVE; 1995 else 1996 sep->se_state = MDB_TGT_SPEC_IDLE; 1997 1998 mdb_list_append(list, sep); 1999 sep->se_ops = ops; 2000 return (sep); 2001 } 2002 2003 mdb_sespec_t * 2004 mdb_tgt_sespec_lookup_active(mdb_tgt_t *t, const mdb_se_ops_t *ops, void *args) 2005 { 2006 mdb_sespec_t *sep; 2007 2008 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 2009 if (sep->se_ops == ops && sep->se_ops->se_secmp(t, sep, args)) 2010 break; 2011 } 2012 2013 return (sep); 2014 } 2015 2016 mdb_sespec_t * 2017 mdb_tgt_sespec_lookup_idle(mdb_tgt_t *t, const mdb_se_ops_t *ops, void *args) 2018 { 2019 mdb_sespec_t *sep; 2020 2021 for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) { 2022 if (sep->se_ops == ops && sep->se_ops->se_vecmp(t, 2023 mdb_list_next(&sep->se_velist), args)) 2024 break; 2025 } 2026 2027 return (sep); 2028 } 2029 2030 /*ARGSUSED*/ 2031 void 2032 mdb_tgt_vespec_hold(mdb_tgt_t *t, mdb_vespec_t *vep) 2033 { 2034 vep->ve_refs++; 2035 ASSERT(vep->ve_refs != 0); 2036 } 2037 2038 void 2039 mdb_tgt_vespec_rele(mdb_tgt_t *t, mdb_vespec_t *vep) 2040 { 2041 ASSERT(vep->ve_refs != 0); 2042 2043 if (--vep->ve_refs == 0) { 2044 /* 2045 * Remove this vespec from the sespec's velist and decrement 2046 * the reference count on the sespec. 2047 */ 2048 mdb_list_delete(&vep->ve_se->se_velist, vep); 2049 mdb_tgt_sespec_rele(t, vep->ve_se); 2050 2051 /* 2052 * If we are deleting the most recently assigned VID, reset 2053 * t_vepos or t_veneg as appropriate to re-use that number. 2054 * This could be enhanced to re-use any free number by 2055 * maintaining a bitmap or hash of the allocated IDs. 2056 */ 2057 if (vep->ve_id > 0 && t->t_vepos == vep->ve_id + 1) 2058 t->t_vepos = vep->ve_id; 2059 else if (vep->ve_id < 0 && t->t_veneg == -vep->ve_id + 1) 2060 t->t_veneg = -vep->ve_id; 2061 2062 /* 2063 * Call the destructor to clean up ve_args, and then free 2064 * the actual vespec structure. 2065 */ 2066 vep->ve_dtor(vep); 2067 mdb_free(vep, sizeof (mdb_vespec_t)); 2068 2069 ASSERT(t->t_vecnt != 0); 2070 t->t_vecnt--; 2071 } 2072 } 2073 2074 int 2075 mdb_tgt_vespec_insert(mdb_tgt_t *t, const mdb_se_ops_t *ops, int flags, 2076 mdb_tgt_se_f *func, void *data, void *args, void (*dtor)(mdb_vespec_t *)) 2077 { 2078 mdb_vespec_t *vep = mdb_zalloc(sizeof (mdb_vespec_t), UM_SLEEP); 2079 2080 int id, mult, *seqp; 2081 mdb_sespec_t *sep; 2082 2083 /* 2084 * Make that only one MDB_TGT_SPEC_AUTO* bit is set in the new flags 2085 * value: extra bits are cleared according to order of precedence. 2086 */ 2087 if (flags & MDB_TGT_SPEC_AUTOSTOP) 2088 flags &= ~(MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS); 2089 else if (flags & MDB_TGT_SPEC_AUTODEL) 2090 flags &= ~MDB_TGT_SPEC_AUTODIS; 2091 2092 /* 2093 * The TEMPORARY property always takes precedence over STICKY. 2094 */ 2095 if (flags & MDB_TGT_SPEC_TEMPORARY) 2096 flags &= ~MDB_TGT_SPEC_STICKY; 2097 2098 /* 2099 * Find a matching sespec or create a new one on the appropriate list. 2100 * We always create a new sespec if the vespec is created disabled. 2101 */ 2102 if (flags & MDB_TGT_SPEC_DISABLED) 2103 sep = mdb_tgt_sespec_insert(t, ops, &t->t_idle); 2104 else if ((sep = mdb_tgt_sespec_lookup_active(t, ops, args)) == NULL && 2105 (sep = mdb_tgt_sespec_lookup_idle(t, ops, args)) == NULL) 2106 sep = mdb_tgt_sespec_insert(t, ops, &t->t_active); 2107 2108 /* 2109 * Generate a new ID for the vespec. Increasing positive integers are 2110 * assigned to visible vespecs; decreasing negative integers are 2111 * assigned to hidden vespecs. The target saves our most recent choice. 2112 */ 2113 if (flags & MDB_TGT_SPEC_INTERNAL) { 2114 seqp = &t->t_veneg; 2115 mult = -1; 2116 } else { 2117 seqp = &t->t_vepos; 2118 mult = 1; 2119 } 2120 2121 id = *seqp; 2122 2123 while (mdb_tgt_vespec_lookup(t, id * mult) != NULL) 2124 id = MAX(id + 1, 1); 2125 2126 *seqp = MAX(id + 1, 1); 2127 2128 vep->ve_id = id * mult; 2129 vep->ve_flags = flags & ~(MDB_TGT_SPEC_MATCHED | MDB_TGT_SPEC_DELETED); 2130 vep->ve_se = sep; 2131 vep->ve_callback = func; 2132 vep->ve_data = data; 2133 vep->ve_args = args; 2134 vep->ve_dtor = dtor; 2135 2136 mdb_list_append(&sep->se_velist, vep); 2137 mdb_tgt_sespec_hold(t, sep); 2138 2139 mdb_tgt_vespec_hold(t, vep); 2140 t->t_vecnt++; 2141 2142 /* 2143 * If this vespec is the first reference to the sespec and it's active, 2144 * then it is newly created and we should attempt to initialize it. 2145 * If se_ctor fails, then move the sespec back to the idle list. 2146 */ 2147 if (sep->se_refs == 1 && sep->se_state == MDB_TGT_SPEC_ACTIVE && 2148 sep->se_ops->se_ctor(t, sep, vep->ve_args) == -1) { 2149 2150 mdb_list_delete(&t->t_active, sep); 2151 mdb_list_append(&t->t_idle, sep); 2152 2153 sep->se_state = MDB_TGT_SPEC_IDLE; 2154 sep->se_errno = errno; 2155 sep->se_data = NULL; 2156 } 2157 2158 /* 2159 * If the sespec is active and the target is currently running (because 2160 * we grabbed it using PGRAB_NOSTOP), then go ahead and attempt to arm 2161 * the sespec so it will take effect immediately. 2162 */ 2163 if (sep->se_state == MDB_TGT_SPEC_ACTIVE && 2164 t->t_status.st_state == MDB_TGT_RUNNING) 2165 mdb_tgt_sespec_arm_one(t, sep); 2166 2167 mdb_dprintf(MDB_DBG_TGT, "inserted [ %d ] sep=%p refs=%u state=%d\n", 2168 vep->ve_id, (void *)sep, sep->se_refs, sep->se_state); 2169 2170 return (vep->ve_id); 2171 } 2172 2173 /* 2174 * Search the target's active, idle, and disabled lists for the vespec matching 2175 * the specified VID, and return a pointer to it, or NULL if no match is found. 2176 */ 2177 mdb_vespec_t * 2178 mdb_tgt_vespec_lookup(mdb_tgt_t *t, int vid) 2179 { 2180 mdb_sespec_t *sep; 2181 mdb_vespec_t *vep; 2182 2183 if (vid == 0) 2184 return (NULL); /* 0 is never a valid VID */ 2185 2186 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 2187 for (vep = mdb_list_next(&sep->se_velist); vep; 2188 vep = mdb_list_next(vep)) { 2189 if (vep->ve_id == vid) 2190 return (vep); 2191 } 2192 } 2193 2194 for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) { 2195 for (vep = mdb_list_next(&sep->se_velist); vep; 2196 vep = mdb_list_next(vep)) { 2197 if (vep->ve_id == vid) 2198 return (vep); 2199 } 2200 } 2201 2202 return (NULL); 2203 } 2204 2205 /*ARGSUSED*/ 2206 void 2207 no_ve_dtor(mdb_vespec_t *vep) 2208 { 2209 /* default destructor does nothing */ 2210 } 2211 2212 /*ARGSUSED*/ 2213 void 2214 no_se_f(mdb_tgt_t *t, int vid, void *data) 2215 { 2216 /* default callback does nothing */ 2217 } 2218 2219 /*ARGSUSED*/ 2220 void 2221 no_se_dtor(mdb_tgt_t *t, mdb_sespec_t *sep) 2222 { 2223 /* default destructor does nothing */ 2224 } 2225 2226 /*ARGSUSED*/ 2227 int 2228 no_se_secmp(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 2229 { 2230 return (sep->se_data == args); 2231 } 2232 2233 /*ARGSUSED*/ 2234 int 2235 no_se_vecmp(mdb_tgt_t *t, mdb_vespec_t *vep, void *args) 2236 { 2237 return (vep->ve_args == args); 2238 } 2239 2240 /*ARGSUSED*/ 2241 int 2242 no_se_arm(mdb_tgt_t *t, mdb_sespec_t *sep) 2243 { 2244 return (0); /* return success */ 2245 } 2246 2247 /*ARGSUSED*/ 2248 int 2249 no_se_disarm(mdb_tgt_t *t, mdb_sespec_t *sep) 2250 { 2251 return (0); /* return success */ 2252 } 2253 2254 /*ARGSUSED*/ 2255 int 2256 no_se_cont(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 2257 { 2258 if (tsp != &t->t_status) 2259 bcopy(&t->t_status, tsp, sizeof (mdb_tgt_status_t)); 2260 2261 return (0); /* return success */ 2262 } 2263 2264 int 2265 mdb_tgt_register_dcmds(mdb_tgt_t *t, const mdb_dcmd_t *dcp, int flags) 2266 { 2267 int fail = 0; 2268 2269 for (; dcp->dc_name != NULL; dcp++) { 2270 if (mdb_module_add_dcmd(t->t_module, dcp, flags) == -1) { 2271 warn("failed to add dcmd %s", dcp->dc_name); 2272 fail++; 2273 } 2274 } 2275 2276 return (fail > 0 ? -1 : 0); 2277 } 2278 2279 int 2280 mdb_tgt_register_walkers(mdb_tgt_t *t, const mdb_walker_t *wp, int flags) 2281 { 2282 int fail = 0; 2283 2284 for (; wp->walk_name != NULL; wp++) { 2285 if (mdb_module_add_walker(t->t_module, wp, flags) == -1) { 2286 warn("failed to add walk %s", wp->walk_name); 2287 fail++; 2288 } 2289 } 2290 2291 return (fail > 0 ? -1 : 0); 2292 } 2293 2294 void 2295 mdb_tgt_register_regvars(mdb_tgt_t *t, const mdb_tgt_regdesc_t *rdp, 2296 const mdb_nv_disc_t *disc, int flags) 2297 { 2298 for (; rdp->rd_name != NULL; rdp++) { 2299 if (!(rdp->rd_flags & MDB_TGT_R_EXPORT)) 2300 continue; /* Don't export register as a variable */ 2301 2302 if (rdp->rd_flags & MDB_TGT_R_RDONLY) 2303 flags |= MDB_NV_RDONLY; 2304 2305 (void) mdb_nv_insert(&mdb.m_nv, rdp->rd_name, disc, 2306 (uintptr_t)t, MDB_NV_PERSIST | flags); 2307 } 2308 } --- EOF ---