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 case (uintptr_t)MDB_TGT_AS_VIRT_I: 402 case (uintptr_t)MDB_TGT_AS_VIRT_S: 403 return (t->t_ops->t_vread(t, buf, n, addr)); 404 case (uintptr_t)MDB_TGT_AS_PHYS: 405 return (t->t_ops->t_pread(t, buf, n, addr)); 406 case (uintptr_t)MDB_TGT_AS_FILE: 407 return (t->t_ops->t_fread(t, buf, n, addr)); 408 case (uintptr_t)MDB_TGT_AS_IO: 409 return (t->t_ops->t_ioread(t, buf, n, addr)); 410 } 411 return (t->t_ops->t_aread(t, as, buf, n, addr)); 412 } 413 414 ssize_t 415 mdb_tgt_awrite(mdb_tgt_t *t, mdb_tgt_as_t as, 416 const void *buf, size_t n, mdb_tgt_addr_t addr) 417 { 418 if (!(t->t_flags & MDB_TGT_F_RDWR)) 419 return (set_errno(EMDB_TGTRDONLY)); 420 421 if (t->t_flags & MDB_TGT_F_ASIO) 422 return (t->t_ops->t_awrite(t, as, buf, n, addr)); 423 424 switch ((uintptr_t)as) { 425 case (uintptr_t)MDB_TGT_AS_VIRT: 426 case (uintptr_t)MDB_TGT_AS_VIRT_I: 427 case (uintptr_t)MDB_TGT_AS_VIRT_S: 428 return (t->t_ops->t_vwrite(t, buf, n, addr)); 429 case (uintptr_t)MDB_TGT_AS_PHYS: 430 return (t->t_ops->t_pwrite(t, buf, n, addr)); 431 case (uintptr_t)MDB_TGT_AS_FILE: 432 return (t->t_ops->t_fwrite(t, buf, n, addr)); 433 case (uintptr_t)MDB_TGT_AS_IO: 434 return (t->t_ops->t_iowrite(t, buf, n, addr)); 435 } 436 return (t->t_ops->t_awrite(t, as, buf, n, addr)); 437 } 438 439 ssize_t 440 mdb_tgt_vread(mdb_tgt_t *t, void *buf, size_t n, uintptr_t addr) 441 { 442 return (t->t_ops->t_vread(t, buf, n, addr)); 443 } 444 445 ssize_t 446 mdb_tgt_vwrite(mdb_tgt_t *t, const void *buf, size_t n, uintptr_t addr) 447 { 448 if (t->t_flags & MDB_TGT_F_RDWR) 449 return (t->t_ops->t_vwrite(t, buf, n, addr)); 450 451 return (set_errno(EMDB_TGTRDONLY)); 452 } 453 454 ssize_t 455 mdb_tgt_pread(mdb_tgt_t *t, void *buf, size_t n, physaddr_t addr) 456 { 457 return (t->t_ops->t_pread(t, buf, n, addr)); 458 } 459 460 ssize_t 461 mdb_tgt_pwrite(mdb_tgt_t *t, const void *buf, size_t n, physaddr_t addr) 462 { 463 if (t->t_flags & MDB_TGT_F_RDWR) 464 return (t->t_ops->t_pwrite(t, buf, n, addr)); 465 466 return (set_errno(EMDB_TGTRDONLY)); 467 } 468 469 ssize_t 470 mdb_tgt_fread(mdb_tgt_t *t, void *buf, size_t n, uintptr_t addr) 471 { 472 return (t->t_ops->t_fread(t, buf, n, addr)); 473 } 474 475 ssize_t 476 mdb_tgt_fwrite(mdb_tgt_t *t, const void *buf, size_t n, uintptr_t addr) 477 { 478 if (t->t_flags & MDB_TGT_F_RDWR) 479 return (t->t_ops->t_fwrite(t, buf, n, addr)); 480 481 return (set_errno(EMDB_TGTRDONLY)); 482 } 483 484 ssize_t 485 mdb_tgt_ioread(mdb_tgt_t *t, void *buf, size_t n, uintptr_t addr) 486 { 487 return (t->t_ops->t_ioread(t, buf, n, addr)); 488 } 489 490 ssize_t 491 mdb_tgt_iowrite(mdb_tgt_t *t, const void *buf, size_t n, uintptr_t addr) 492 { 493 if (t->t_flags & MDB_TGT_F_RDWR) 494 return (t->t_ops->t_iowrite(t, buf, n, addr)); 495 496 return (set_errno(EMDB_TGTRDONLY)); 497 } 498 499 int 500 mdb_tgt_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap) 501 { 502 return (t->t_ops->t_vtop(t, as, va, pap)); 503 } 504 505 ssize_t 506 mdb_tgt_readstr(mdb_tgt_t *t, mdb_tgt_as_t as, char *buf, 507 size_t nbytes, mdb_tgt_addr_t addr) 508 { 509 ssize_t n = -1, nread = mdb_tgt_aread(t, as, buf, nbytes, addr); 510 char *p; 511 512 if (nread >= 0) { 513 if ((p = memchr(buf, '\0', nread)) != NULL) 514 nread = (size_t)(p - buf); 515 goto done; 516 } 517 518 nread = 0; 519 p = &buf[0]; 520 521 while (nread < nbytes && (n = mdb_tgt_aread(t, as, p, 1, addr)) == 1) { 522 if (*p == '\0') 523 return (nread); 524 nread++; 525 addr++; 526 p++; 527 } 528 529 if (nread == 0 && n == -1) 530 return (-1); /* If we can't even read a byte, return -1 */ 531 532 done: 533 if (nbytes != 0) 534 buf[MIN(nread, nbytes - 1)] = '\0'; 535 536 return (nread); 537 } 538 539 ssize_t 540 mdb_tgt_writestr(mdb_tgt_t *t, mdb_tgt_as_t as, 541 const char *buf, mdb_tgt_addr_t addr) 542 { 543 ssize_t nwritten = mdb_tgt_awrite(t, as, buf, strlen(buf) + 1, addr); 544 return (nwritten > 0 ? nwritten - 1 : nwritten); 545 } 546 547 int 548 mdb_tgt_lookup_by_name(mdb_tgt_t *t, const char *obj, 549 const char *name, GElf_Sym *symp, mdb_syminfo_t *sip) 550 { 551 mdb_syminfo_t info; 552 GElf_Sym sym; 553 uint_t id; 554 555 if (name == NULL || t == NULL) 556 return (set_errno(EINVAL)); 557 558 if (obj == MDB_TGT_OBJ_EVERY && 559 mdb_gelf_symtab_lookup_by_name(mdb.m_prsym, name, &sym, &id) == 0) { 560 info.sym_table = MDB_TGT_PRVSYM; 561 info.sym_id = id; 562 goto found; 563 } 564 565 if (t->t_ops->t_lookup_by_name(t, obj, name, &sym, &info) == 0) 566 goto found; 567 568 return (-1); 569 570 found: 571 if (symp != NULL) 572 *symp = sym; 573 if (sip != NULL) 574 *sip = info; 575 return (0); 576 } 577 578 int 579 mdb_tgt_lookup_by_addr(mdb_tgt_t *t, uintptr_t addr, uint_t flags, 580 char *buf, size_t len, GElf_Sym *symp, mdb_syminfo_t *sip) 581 { 582 mdb_syminfo_t info; 583 GElf_Sym sym; 584 585 if (t == NULL) 586 return (set_errno(EINVAL)); 587 588 if (t->t_ops->t_lookup_by_addr(t, addr, flags, 589 buf, len, &sym, &info) == 0) { 590 if (symp != NULL) 591 *symp = sym; 592 if (sip != NULL) 593 *sip = info; 594 return (0); 595 } 596 597 return (-1); 598 } 599 600 /* 601 * The mdb_tgt_lookup_by_scope function is a convenience routine for code that 602 * wants to look up a scoped symbol name such as "object`symbol". It is 603 * implemented as a simple wrapper around mdb_tgt_lookup_by_name. Note that 604 * we split on the *last* occurrence of "`", so the object name itself may 605 * contain additional scopes whose evaluation is left to the target. This 606 * allows targets to implement additional scopes, such as source files, 607 * function names, link map identifiers, etc. 608 */ 609 int 610 mdb_tgt_lookup_by_scope(mdb_tgt_t *t, const char *s, GElf_Sym *symp, 611 mdb_syminfo_t *sip) 612 { 613 const char *object = MDB_TGT_OBJ_EVERY; 614 const char *name = s; 615 char buf[MDB_TGT_SYM_NAMLEN]; 616 617 if (t == NULL) 618 return (set_errno(EINVAL)); 619 620 if (strchr(name, '`') != NULL) { 621 622 (void) strncpy(buf, s, sizeof (buf)); 623 buf[sizeof (buf) - 1] = '\0'; 624 name = buf; 625 626 if ((s = strrsplit(buf, '`')) != NULL) { 627 object = buf; 628 name = s; 629 if (*object == '\0') 630 return (set_errno(EMDB_NOOBJ)); 631 if (*name == '\0') 632 return (set_errno(EMDB_NOSYM)); 633 } 634 } 635 636 return (mdb_tgt_lookup_by_name(t, object, name, symp, sip)); 637 } 638 639 int 640 mdb_tgt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which, 641 uint_t type, mdb_tgt_sym_f *cb, void *p) 642 { 643 if ((which != MDB_TGT_SYMTAB && which != MDB_TGT_DYNSYM) || 644 (type & ~(MDB_TGT_BIND_ANY | MDB_TGT_TYPE_ANY)) != 0) 645 return (set_errno(EINVAL)); 646 647 return (t->t_ops->t_symbol_iter(t, obj, which, type, cb, p)); 648 } 649 650 ssize_t 651 mdb_tgt_readsym(mdb_tgt_t *t, mdb_tgt_as_t as, void *buf, size_t nbytes, 652 const char *obj, const char *name) 653 { 654 GElf_Sym sym; 655 656 if (mdb_tgt_lookup_by_name(t, obj, name, &sym, NULL) == 0) 657 return (mdb_tgt_aread(t, as, buf, nbytes, sym.st_value)); 658 659 return (-1); 660 } 661 662 ssize_t 663 mdb_tgt_writesym(mdb_tgt_t *t, mdb_tgt_as_t as, const void *buf, 664 size_t nbytes, const char *obj, const char *name) 665 { 666 GElf_Sym sym; 667 668 if (mdb_tgt_lookup_by_name(t, obj, name, &sym, NULL) == 0) 669 return (mdb_tgt_awrite(t, as, buf, nbytes, sym.st_value)); 670 671 return (-1); 672 } 673 674 int 675 mdb_tgt_mapping_iter(mdb_tgt_t *t, mdb_tgt_map_f *cb, void *p) 676 { 677 return (t->t_ops->t_mapping_iter(t, cb, p)); 678 } 679 680 int 681 mdb_tgt_object_iter(mdb_tgt_t *t, mdb_tgt_map_f *cb, void *p) 682 { 683 return (t->t_ops->t_object_iter(t, cb, p)); 684 } 685 686 const mdb_map_t * 687 mdb_tgt_addr_to_map(mdb_tgt_t *t, uintptr_t addr) 688 { 689 return (t->t_ops->t_addr_to_map(t, addr)); 690 } 691 692 const mdb_map_t * 693 mdb_tgt_name_to_map(mdb_tgt_t *t, const char *name) 694 { 695 return (t->t_ops->t_name_to_map(t, name)); 696 } 697 698 struct ctf_file * 699 mdb_tgt_addr_to_ctf(mdb_tgt_t *t, uintptr_t addr) 700 { 701 return (t->t_ops->t_addr_to_ctf(t, addr)); 702 } 703 704 struct ctf_file * 705 mdb_tgt_name_to_ctf(mdb_tgt_t *t, const char *name) 706 { 707 return (t->t_ops->t_name_to_ctf(t, name)); 708 } 709 710 /* 711 * Return the latest target status. We just copy out our cached copy. The 712 * status only needs to change when the target is run, stepped, or continued. 713 */ 714 int 715 mdb_tgt_status(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 716 { 717 uint_t dstop = (t->t_status.st_flags & MDB_TGT_DSTOP); 718 uint_t istop = (t->t_status.st_flags & MDB_TGT_ISTOP); 719 uint_t state = t->t_status.st_state; 720 721 if (tsp == NULL) 722 return (set_errno(EINVAL)); 723 724 /* 725 * If we're called with the address of the target's internal status, 726 * then call down to update it; otherwise copy out the saved status. 727 */ 728 if (tsp == &t->t_status && t->t_ops->t_status(t, &t->t_status) != 0) 729 return (-1); /* errno is set for us */ 730 731 /* 732 * Assert that our state is valid before returning it. The state must 733 * be valid, and DSTOP and ISTOP cannot be set simultaneously. ISTOP 734 * is only valid when stopped. DSTOP is only valid when running or 735 * stopped. If any test fails, abort the debugger. 736 */ 737 if (state > MDB_TGT_LOST) 738 fail("invalid target state (%u)\n", state); 739 if (state != MDB_TGT_STOPPED && istop) 740 fail("target state is (%u) and ISTOP is set\n", state); 741 if (state != MDB_TGT_STOPPED && state != MDB_TGT_RUNNING && dstop) 742 fail("target state is (%u) and DSTOP is set\n", state); 743 if (istop && dstop) 744 fail("target has ISTOP and DSTOP set simultaneously\n"); 745 746 if (tsp != &t->t_status) 747 bcopy(&t->t_status, tsp, sizeof (mdb_tgt_status_t)); 748 749 return (0); 750 } 751 752 /* 753 * For the given sespec, scan its list of vespecs for ones that are marked 754 * temporary and delete them. We use the same method as vespec_delete below. 755 */ 756 /*ARGSUSED*/ 757 void 758 mdb_tgt_sespec_prune_one(mdb_tgt_t *t, mdb_sespec_t *sep) 759 { 760 mdb_vespec_t *vep, *nvep; 761 762 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 763 nvep = mdb_list_next(vep); 764 765 if ((vep->ve_flags & (MDB_TGT_SPEC_DELETED | 766 MDB_TGT_SPEC_TEMPORARY)) == MDB_TGT_SPEC_TEMPORARY) { 767 vep->ve_flags |= MDB_TGT_SPEC_DELETED; 768 mdb_tgt_vespec_rele(t, vep); 769 } 770 } 771 } 772 773 /* 774 * Prune each sespec on the active list of temporary vespecs. This function 775 * is called, for example, after the target finishes a continue operation. 776 */ 777 void 778 mdb_tgt_sespec_prune_all(mdb_tgt_t *t) 779 { 780 mdb_sespec_t *sep, *nsep; 781 782 for (sep = mdb_list_next(&t->t_active); sep != NULL; sep = nsep) { 783 nsep = mdb_list_next(sep); 784 mdb_tgt_sespec_prune_one(t, sep); 785 } 786 } 787 788 /* 789 * Transition the given sespec to the IDLE state. We invoke the destructor, 790 * and then move the sespec from the active list to the idle list. 791 */ 792 void 793 mdb_tgt_sespec_idle_one(mdb_tgt_t *t, mdb_sespec_t *sep, int reason) 794 { 795 ASSERT(sep->se_state != MDB_TGT_SPEC_IDLE); 796 797 if (sep->se_state == MDB_TGT_SPEC_ARMED) 798 (void) sep->se_ops->se_disarm(t, sep); 799 800 sep->se_ops->se_dtor(t, sep); 801 sep->se_data = NULL; 802 803 sep->se_state = MDB_TGT_SPEC_IDLE; 804 sep->se_errno = reason; 805 806 mdb_list_delete(&t->t_active, sep); 807 mdb_list_append(&t->t_idle, sep); 808 809 mdb_tgt_sespec_prune_one(t, sep); 810 } 811 812 /* 813 * Transition each sespec on the active list to the IDLE state. This function 814 * is called, for example, after the target terminates execution. 815 */ 816 void 817 mdb_tgt_sespec_idle_all(mdb_tgt_t *t, int reason, int clear_matched) 818 { 819 mdb_sespec_t *sep, *nsep; 820 mdb_vespec_t *vep; 821 822 while ((sep = t->t_matched) != T_SE_END && clear_matched) { 823 for (vep = mdb_list_next(&sep->se_velist); vep != NULL; ) { 824 vep->ve_flags &= ~MDB_TGT_SPEC_MATCHED; 825 vep = mdb_list_next(vep); 826 } 827 828 t->t_matched = sep->se_matched; 829 sep->se_matched = NULL; 830 mdb_tgt_sespec_rele(t, sep); 831 } 832 833 for (sep = mdb_list_next(&t->t_active); sep != NULL; sep = nsep) { 834 nsep = mdb_list_next(sep); 835 mdb_tgt_sespec_idle_one(t, sep, reason); 836 } 837 } 838 839 /* 840 * Attempt to transition the given sespec from the IDLE to ACTIVE state. We 841 * do this by invoking se_ctor -- if this fails, we save the reason in se_errno 842 * and return -1 with errno set. One strange case we need to deal with here is 843 * the possibility that a given vespec is sitting on the idle list with its 844 * corresponding sespec, but it is actually a duplicate of another sespec on the 845 * active list. This can happen if the sespec is associated with a 846 * MDB_TGT_SPEC_DISABLED vespec that was just enabled, and is now ready to be 847 * activated. A more interesting reason this situation might arise is the case 848 * where a virtual address breakpoint is set at an address just mmap'ed by 849 * dlmopen. Since no symbol table information is available for this mapping 850 * yet, a pre-existing deferred symbolic breakpoint may already exist for this 851 * address, but it is on the idle list. When the symbol table is ready and the 852 * DLACTIVITY event occurs, we now discover that the virtual address obtained by 853 * evaluating the symbolic breakpoint matches the explicit virtual address of 854 * the active virtual breakpoint. To resolve this conflict in either case, we 855 * destroy the idle sespec, and attach its list of vespecs to the existing 856 * active sespec. 857 */ 858 int 859 mdb_tgt_sespec_activate_one(mdb_tgt_t *t, mdb_sespec_t *sep) 860 { 861 mdb_vespec_t *vep = mdb_list_next(&sep->se_velist); 862 863 mdb_vespec_t *nvep; 864 mdb_sespec_t *dup; 865 866 ASSERT(sep->se_state == MDB_TGT_SPEC_IDLE); 867 ASSERT(vep != NULL); 868 869 if (vep->ve_flags & MDB_TGT_SPEC_DISABLED) 870 return (0); /* cannot be activated while disabled bit set */ 871 872 /* 873 * First search the active list for an existing, duplicate sespec to 874 * handle the special case described above. 875 */ 876 for (dup = mdb_list_next(&t->t_active); dup; dup = mdb_list_next(dup)) { 877 if (dup->se_ops == sep->se_ops && 878 dup->se_ops->se_secmp(t, dup, vep->ve_args)) { 879 ASSERT(dup != sep); 880 break; 881 } 882 } 883 884 /* 885 * If a duplicate is found, destroy the existing, idle sespec, and 886 * attach all of its vespecs to the duplicate sespec. 887 */ 888 if (dup != NULL) { 889 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 890 mdb_dprintf(MDB_DBG_TGT, "merge [ %d ] to sespec %p\n", 891 vep->ve_id, (void *)dup); 892 893 if (dup->se_matched != NULL) 894 vep->ve_flags |= MDB_TGT_SPEC_MATCHED; 895 896 nvep = mdb_list_next(vep); 897 vep->ve_hits = 0; 898 899 mdb_list_delete(&sep->se_velist, vep); 900 mdb_tgt_sespec_rele(t, sep); 901 902 mdb_list_append(&dup->se_velist, vep); 903 mdb_tgt_sespec_hold(t, dup); 904 vep->ve_se = dup; 905 } 906 907 mdb_dprintf(MDB_DBG_TGT, "merged idle sespec %p with %p\n", 908 (void *)sep, (void *)dup); 909 return (0); 910 } 911 912 /* 913 * If no duplicate is found, call the sespec's constructor. If this 914 * is successful, move the sespec to the active list. 915 */ 916 if (sep->se_ops->se_ctor(t, sep, vep->ve_args) < 0) { 917 sep->se_errno = errno; 918 sep->se_data = NULL; 919 920 return (-1); 921 } 922 923 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 924 nvep = mdb_list_next(vep); 925 vep->ve_hits = 0; 926 } 927 mdb_list_delete(&t->t_idle, sep); 928 mdb_list_append(&t->t_active, sep); 929 sep->se_state = MDB_TGT_SPEC_ACTIVE; 930 sep->se_errno = 0; 931 932 return (0); 933 } 934 935 /* 936 * Transition each sespec on the idle list to the ACTIVE state. This function 937 * is called, for example, after the target's t_run() function returns. If 938 * the se_ctor() function fails, the specifier is not yet applicable; it will 939 * remain on the idle list and can be activated later. 940 * 941 * Returns 1 if there weren't any unexpected activation failures; 0 if there 942 * were. 943 */ 944 int 945 mdb_tgt_sespec_activate_all(mdb_tgt_t *t) 946 { 947 mdb_sespec_t *sep, *nsep; 948 int rc = 1; 949 950 for (sep = mdb_list_next(&t->t_idle); sep != NULL; sep = nsep) { 951 nsep = mdb_list_next(sep); 952 953 if (mdb_tgt_sespec_activate_one(t, sep) < 0 && 954 sep->se_errno != EMDB_NOOBJ) 955 rc = 0; 956 } 957 958 return (rc); 959 } 960 961 /* 962 * Transition the given sespec to the ARMED state. Note that we attempt to 963 * re-arm sespecs previously in the ERROR state. If se_arm() fails the sespec 964 * transitions to the ERROR state but stays on the active list. 965 */ 966 void 967 mdb_tgt_sespec_arm_one(mdb_tgt_t *t, mdb_sespec_t *sep) 968 { 969 ASSERT(sep->se_state != MDB_TGT_SPEC_IDLE); 970 971 if (sep->se_state == MDB_TGT_SPEC_ARMED) 972 return; /* do not arm sespecs more than once */ 973 974 if (sep->se_ops->se_arm(t, sep) == -1) { 975 sep->se_state = MDB_TGT_SPEC_ERROR; 976 sep->se_errno = errno; 977 } else { 978 sep->se_state = MDB_TGT_SPEC_ARMED; 979 sep->se_errno = 0; 980 } 981 } 982 983 /* 984 * Transition each sespec on the active list (except matched specs) to the 985 * ARMED state. This function is called prior to continuing the target. 986 */ 987 void 988 mdb_tgt_sespec_arm_all(mdb_tgt_t *t) 989 { 990 mdb_sespec_t *sep, *nsep; 991 992 for (sep = mdb_list_next(&t->t_active); sep != NULL; sep = nsep) { 993 nsep = mdb_list_next(sep); 994 if (sep->se_matched == NULL) 995 mdb_tgt_sespec_arm_one(t, sep); 996 } 997 } 998 999 /* 1000 * Transition each sespec on the active list that is in the ARMED state to 1001 * the ACTIVE state. If se_disarm() fails, the sespec is transitioned to 1002 * the ERROR state instead, but left on the active list. 1003 */ 1004 static void 1005 tgt_disarm_sespecs(mdb_tgt_t *t) 1006 { 1007 mdb_sespec_t *sep; 1008 1009 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 1010 if (sep->se_state != MDB_TGT_SPEC_ARMED) 1011 continue; /* do not disarm if in ERROR state */ 1012 1013 if (sep->se_ops->se_disarm(t, sep) == -1) { 1014 sep->se_state = MDB_TGT_SPEC_ERROR; 1015 sep->se_errno = errno; 1016 } else { 1017 sep->se_state = MDB_TGT_SPEC_ACTIVE; 1018 sep->se_errno = 0; 1019 } 1020 } 1021 } 1022 1023 /* 1024 * Determine if the software event that triggered the most recent stop matches 1025 * any of the active event specifiers. If 'all' is TRUE, we consider all 1026 * sespecs in our search. If 'all' is FALSE, we only consider ARMED sespecs. 1027 * If we successfully match an event, we add it to the t_matched list and 1028 * place an additional hold on it. 1029 */ 1030 static mdb_sespec_t * 1031 tgt_match_sespecs(mdb_tgt_t *t, int all) 1032 { 1033 mdb_sespec_t *sep; 1034 1035 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 1036 if (all == FALSE && sep->se_state != MDB_TGT_SPEC_ARMED) 1037 continue; /* restrict search to ARMED sespecs */ 1038 1039 if (sep->se_state != MDB_TGT_SPEC_ERROR && 1040 sep->se_ops->se_match(t, sep, &t->t_status)) { 1041 mdb_dprintf(MDB_DBG_TGT, "match se %p\n", (void *)sep); 1042 mdb_tgt_sespec_hold(t, sep); 1043 sep->se_matched = t->t_matched; 1044 t->t_matched = sep; 1045 } 1046 } 1047 1048 return (t->t_matched); 1049 } 1050 1051 /* 1052 * This function provides the low-level target continue algorithm. We proceed 1053 * in three phases: (1) we arm the active sespecs, except the specs matched at 1054 * the time we last stopped, (2) we call se_cont() on any matched sespecs to 1055 * step over these event transitions, and then arm the corresponding sespecs, 1056 * and (3) we call the appropriate low-level continue routine. Once the 1057 * target stops again, we determine which sespecs were matched, and invoke the 1058 * appropriate vespec callbacks and perform other vespec maintenance. 1059 */ 1060 static int 1061 tgt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp, 1062 int (*t_cont)(mdb_tgt_t *, mdb_tgt_status_t *)) 1063 { 1064 mdb_var_t *hitv = mdb_nv_lookup(&mdb.m_nv, "hits"); 1065 uintptr_t pc = t->t_status.st_pc; 1066 int error = 0; 1067 1068 mdb_sespec_t *sep, *nsep, *matched; 1069 mdb_vespec_t *vep, *nvep; 1070 uintptr_t addr; 1071 1072 uint_t cbits = 0; /* union of pending continue bits */ 1073 uint_t ncont = 0; /* # of callbacks that requested cont */ 1074 uint_t n = 0; /* # of callbacks */ 1075 1076 /* 1077 * If the target is undead, dead, or lost, we no longer allow continue. 1078 * This effectively forces the user to use ::kill or ::run after death. 1079 */ 1080 if (t->t_status.st_state == MDB_TGT_UNDEAD) 1081 return (set_errno(EMDB_TGTZOMB)); 1082 if (t->t_status.st_state == MDB_TGT_DEAD) 1083 return (set_errno(EMDB_TGTCORE)); 1084 if (t->t_status.st_state == MDB_TGT_LOST) 1085 return (set_errno(EMDB_TGTLOST)); 1086 1087 /* 1088 * If any of single-step, step-over, or step-out is pending, it takes 1089 * precedence over an explicit or pending continue, because these are 1090 * all different specialized forms of continue. 1091 */ 1092 if (t->t_flags & MDB_TGT_F_STEP) 1093 t_cont = t->t_ops->t_step; 1094 else if (t->t_flags & MDB_TGT_F_NEXT) 1095 t_cont = t->t_ops->t_step; 1096 else if (t->t_flags & MDB_TGT_F_STEP_OUT) 1097 t_cont = t->t_ops->t_cont; 1098 1099 /* 1100 * To handle step-over, we ask the target to find the address past the 1101 * next control transfer instruction. If an address is found, we plant 1102 * a temporary breakpoint there and continue; otherwise just step. 1103 */ 1104 if ((t->t_flags & MDB_TGT_F_NEXT) && !(t->t_flags & MDB_TGT_F_STEP)) { 1105 if (t->t_ops->t_next(t, &addr) == -1 || mdb_tgt_add_vbrkpt(t, 1106 addr, MDB_TGT_SPEC_HIDDEN | MDB_TGT_SPEC_TEMPORARY, 1107 no_se_f, NULL) == 0) { 1108 mdb_dprintf(MDB_DBG_TGT, "next falling back to step: " 1109 "%s\n", mdb_strerror(errno)); 1110 } else 1111 t_cont = t->t_ops->t_cont; 1112 } 1113 1114 /* 1115 * To handle step-out, we ask the target to find the return address of 1116 * the current frame, plant a temporary breakpoint there, and continue. 1117 */ 1118 if (t->t_flags & MDB_TGT_F_STEP_OUT) { 1119 if (t->t_ops->t_step_out(t, &addr) == -1) 1120 return (-1); /* errno is set for us */ 1121 1122 if (mdb_tgt_add_vbrkpt(t, addr, MDB_TGT_SPEC_HIDDEN | 1123 MDB_TGT_SPEC_TEMPORARY, no_se_f, NULL) == 0) 1124 return (-1); /* errno is set for us */ 1125 } 1126 1127 (void) mdb_signal_block(SIGHUP); 1128 (void) mdb_signal_block(SIGTERM); 1129 mdb_intr_disable(); 1130 1131 t->t_flags &= ~T_CONT_BITS; 1132 t->t_flags |= MDB_TGT_F_BUSY; 1133 mdb_tgt_sespec_arm_all(t); 1134 1135 ASSERT(t->t_matched != NULL); 1136 matched = t->t_matched; 1137 t->t_matched = T_SE_END; 1138 1139 if (mdb.m_term != NULL) 1140 IOP_SUSPEND(mdb.m_term); 1141 1142 /* 1143 * Iterate over the matched sespec list, performing autostop processing 1144 * and clearing the matched bit for each associated vespec. We then 1145 * invoke each sespec's se_cont callback in order to continue past 1146 * the corresponding event. If the matched list has more than one 1147 * sespec, we assume that the se_cont callbacks are non-interfering. 1148 */ 1149 for (sep = matched; sep != T_SE_END; sep = sep->se_matched) { 1150 for (vep = mdb_list_next(&sep->se_velist); vep != NULL; ) { 1151 if ((vep->ve_flags & MDB_TGT_SPEC_AUTOSTOP) && 1152 (vep->ve_limit && vep->ve_hits == vep->ve_limit)) 1153 vep->ve_hits = 0; 1154 1155 vep->ve_flags &= ~MDB_TGT_SPEC_MATCHED; 1156 vep = mdb_list_next(vep); 1157 } 1158 1159 if (sep->se_ops->se_cont(t, sep, &t->t_status) == -1) { 1160 error = errno ? errno : -1; 1161 tgt_disarm_sespecs(t); 1162 break; 1163 } 1164 1165 if (!(t->t_status.st_flags & MDB_TGT_ISTOP)) { 1166 tgt_disarm_sespecs(t); 1167 if (t->t_status.st_state == MDB_TGT_UNDEAD) 1168 mdb_tgt_sespec_idle_all(t, EMDB_TGTZOMB, TRUE); 1169 else if (t->t_status.st_state == MDB_TGT_LOST) 1170 mdb_tgt_sespec_idle_all(t, EMDB_TGTLOST, TRUE); 1171 break; 1172 } 1173 } 1174 1175 /* 1176 * Clear the se_matched field for each matched sespec, and drop the 1177 * reference count since the sespec is no longer on the matched list. 1178 */ 1179 for (sep = matched; sep != T_SE_END; sep = nsep) { 1180 nsep = sep->se_matched; 1181 sep->se_matched = NULL; 1182 mdb_tgt_sespec_rele(t, sep); 1183 } 1184 1185 /* 1186 * If the matched list was non-empty, see if we hit another event while 1187 * performing se_cont() processing. If so, don't bother continuing any 1188 * further. If not, arm the sespecs on the old matched list by calling 1189 * mdb_tgt_sespec_arm_all() again and then continue by calling t_cont. 1190 */ 1191 if (matched != T_SE_END) { 1192 if (error != 0 || !(t->t_status.st_flags & MDB_TGT_ISTOP)) 1193 goto out; /* abort now if se_cont() failed */ 1194 1195 if ((t->t_matched = tgt_match_sespecs(t, FALSE)) != T_SE_END) { 1196 tgt_disarm_sespecs(t); 1197 goto out; 1198 } 1199 1200 mdb_tgt_sespec_arm_all(t); 1201 } 1202 1203 if (t_cont != t->t_ops->t_step || pc == t->t_status.st_pc) { 1204 if (t_cont(t, &t->t_status) != 0) 1205 error = errno ? errno : -1; 1206 } 1207 1208 tgt_disarm_sespecs(t); 1209 1210 if (t->t_flags & MDB_TGT_F_UNLOAD) 1211 longjmp(mdb.m_frame->f_pcb, MDB_ERR_QUIT); 1212 1213 if (t->t_status.st_state == MDB_TGT_UNDEAD) 1214 mdb_tgt_sespec_idle_all(t, EMDB_TGTZOMB, TRUE); 1215 else if (t->t_status.st_state == MDB_TGT_LOST) 1216 mdb_tgt_sespec_idle_all(t, EMDB_TGTLOST, TRUE); 1217 else if (t->t_status.st_flags & MDB_TGT_ISTOP) 1218 t->t_matched = tgt_match_sespecs(t, TRUE); 1219 out: 1220 if (mdb.m_term != NULL) 1221 IOP_RESUME(mdb.m_term); 1222 1223 (void) mdb_signal_unblock(SIGTERM); 1224 (void) mdb_signal_unblock(SIGHUP); 1225 mdb_intr_enable(); 1226 1227 for (sep = t->t_matched; sep != T_SE_END; sep = sep->se_matched) { 1228 /* 1229 * When we invoke a ve_callback, it may in turn request that the 1230 * target continue immediately after callback processing is 1231 * complete. We only allow this to occur if *all* callbacks 1232 * agree to continue. To implement this behavior, we keep a 1233 * count (ncont) of such requests, and only apply the cumulative 1234 * continue bits (cbits) to the target if ncont is equal to the 1235 * total number of callbacks that are invoked (n). 1236 */ 1237 for (vep = mdb_list_next(&sep->se_velist); 1238 vep != NULL; vep = nvep, n++) { 1239 /* 1240 * Place an extra hold on the current vespec and pick 1241 * up the next pointer before invoking the callback: we 1242 * must be prepared for the vespec to be deleted or 1243 * moved to a different list by the callback. 1244 */ 1245 mdb_tgt_vespec_hold(t, vep); 1246 nvep = mdb_list_next(vep); 1247 1248 vep->ve_flags |= MDB_TGT_SPEC_MATCHED; 1249 vep->ve_hits++; 1250 1251 mdb_nv_set_value(mdb.m_dot, t->t_status.st_pc); 1252 mdb_nv_set_value(hitv, vep->ve_hits); 1253 1254 ASSERT((t->t_flags & T_CONT_BITS) == 0); 1255 vep->ve_callback(t, vep->ve_id, vep->ve_data); 1256 1257 ncont += (t->t_flags & T_CONT_BITS) != 0; 1258 cbits |= (t->t_flags & T_CONT_BITS); 1259 t->t_flags &= ~T_CONT_BITS; 1260 1261 if (vep->ve_limit && vep->ve_hits == vep->ve_limit) { 1262 if (vep->ve_flags & MDB_TGT_SPEC_AUTODEL) 1263 (void) mdb_tgt_vespec_delete(t, 1264 vep->ve_id); 1265 else if (vep->ve_flags & MDB_TGT_SPEC_AUTODIS) 1266 (void) mdb_tgt_vespec_disable(t, 1267 vep->ve_id); 1268 } 1269 1270 if (vep->ve_limit && vep->ve_hits < vep->ve_limit) { 1271 if (vep->ve_flags & MDB_TGT_SPEC_AUTOSTOP) 1272 (void) mdb_tgt_continue(t, NULL); 1273 } 1274 1275 mdb_tgt_vespec_rele(t, vep); 1276 } 1277 } 1278 1279 if (t->t_matched != T_SE_END && ncont == n) 1280 t->t_flags |= cbits; /* apply continues (see above) */ 1281 1282 mdb_tgt_sespec_prune_all(t); 1283 1284 t->t_status.st_flags &= ~MDB_TGT_BUSY; 1285 t->t_flags &= ~MDB_TGT_F_BUSY; 1286 1287 if (tsp != NULL) 1288 bcopy(&t->t_status, tsp, sizeof (mdb_tgt_status_t)); 1289 1290 if (error != 0) 1291 return (set_errno(error)); 1292 1293 return (0); 1294 } 1295 1296 /* 1297 * This function is the common glue that connects the high-level target layer 1298 * continue functions (e.g. step and cont below) with the low-level 1299 * tgt_continue() function above. Since vespec callbacks may perform any 1300 * actions, including attempting to continue the target itself, we must be 1301 * prepared to be called while the target is still marked F_BUSY. In this 1302 * case, we just set a pending bit and return. When we return from the call 1303 * to tgt_continue() that made us busy into the tgt_request_continue() call 1304 * that is still on the stack, we will loop around and call tgt_continue() 1305 * again. This allows vespecs to continue the target without recursion. 1306 */ 1307 static int 1308 tgt_request_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp, uint_t tflag, 1309 int (*t_cont)(mdb_tgt_t *, mdb_tgt_status_t *)) 1310 { 1311 mdb_tgt_spec_desc_t desc; 1312 mdb_sespec_t *sep; 1313 char buf[BUFSIZ]; 1314 int status; 1315 1316 if (t->t_flags & MDB_TGT_F_BUSY) { 1317 t->t_flags |= tflag; 1318 return (0); 1319 } 1320 1321 do { 1322 status = tgt_continue(t, tsp, t_cont); 1323 } while (status == 0 && (t->t_flags & T_CONT_BITS)); 1324 1325 if (status == 0) { 1326 for (sep = t->t_matched; sep != T_SE_END; 1327 sep = sep->se_matched) { 1328 mdb_vespec_t *vep; 1329 1330 for (vep = mdb_list_next(&sep->se_velist); vep; 1331 vep = mdb_list_next(vep)) { 1332 if (vep->ve_flags & MDB_TGT_SPEC_SILENT) 1333 continue; 1334 warn("%s\n", sep->se_ops->se_info(t, sep, 1335 vep, &desc, buf, sizeof (buf))); 1336 } 1337 } 1338 1339 mdb_callb_fire(MDB_CALLB_STCHG); 1340 } 1341 1342 t->t_flags &= ~T_CONT_BITS; 1343 return (status); 1344 } 1345 1346 /* 1347 * Restart target execution: we rely upon the underlying target implementation 1348 * to do most of the work for us. In particular, we assume it will properly 1349 * preserve the state of our event lists if the run fails for some reason, 1350 * and that it will reset all events to the IDLE state if the run succeeds. 1351 * If it is successful, we attempt to activate all of the idle sespecs. The 1352 * t_run() operation is defined to leave the target stopped at the earliest 1353 * possible point in execution, and then return control to the debugger, 1354 * awaiting a step or continue operation to set it running again. 1355 */ 1356 int 1357 mdb_tgt_run(mdb_tgt_t *t, int argc, const mdb_arg_t *argv) 1358 { 1359 int i; 1360 1361 for (i = 0; i < argc; i++) { 1362 if (argv->a_type != MDB_TYPE_STRING) 1363 return (set_errno(EINVAL)); 1364 } 1365 1366 if (t->t_ops->t_run(t, argc, argv) == -1) 1367 return (-1); /* errno is set for us */ 1368 1369 t->t_flags &= ~T_CONT_BITS; 1370 (void) mdb_tgt_sespec_activate_all(t); 1371 1372 if (mdb.m_term != NULL) 1373 IOP_CTL(mdb.m_term, MDB_IOC_CTTY, NULL); 1374 1375 return (0); 1376 } 1377 1378 int 1379 mdb_tgt_step(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 1380 { 1381 return (tgt_request_continue(t, tsp, MDB_TGT_F_STEP, t->t_ops->t_step)); 1382 } 1383 1384 int 1385 mdb_tgt_step_out(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 1386 { 1387 t->t_flags |= MDB_TGT_F_STEP_OUT; /* set flag even if tgt not busy */ 1388 return (tgt_request_continue(t, tsp, 0, t->t_ops->t_cont)); 1389 } 1390 1391 int 1392 mdb_tgt_next(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 1393 { 1394 t->t_flags |= MDB_TGT_F_NEXT; /* set flag even if tgt not busy */ 1395 return (tgt_request_continue(t, tsp, 0, t->t_ops->t_step)); 1396 } 1397 1398 int 1399 mdb_tgt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 1400 { 1401 return (tgt_request_continue(t, tsp, MDB_TGT_F_CONT, t->t_ops->t_cont)); 1402 } 1403 1404 int 1405 mdb_tgt_signal(mdb_tgt_t *t, int sig) 1406 { 1407 return (t->t_ops->t_signal(t, sig)); 1408 } 1409 1410 void * 1411 mdb_tgt_vespec_data(mdb_tgt_t *t, int vid) 1412 { 1413 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, vid); 1414 1415 if (vep == NULL) { 1416 (void) set_errno(EMDB_NOSESPEC); 1417 return (NULL); 1418 } 1419 1420 return (vep->ve_data); 1421 } 1422 1423 /* 1424 * Return a structured description and comment string for the given vespec. 1425 * We fill in the common information from the vespec, and then call down to 1426 * the underlying sespec to provide the comment string and modify any 1427 * event type-specific information. 1428 */ 1429 char * 1430 mdb_tgt_vespec_info(mdb_tgt_t *t, int vid, mdb_tgt_spec_desc_t *sp, 1431 char *buf, size_t nbytes) 1432 { 1433 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, vid); 1434 1435 mdb_tgt_spec_desc_t desc; 1436 mdb_sespec_t *sep; 1437 1438 if (vep == NULL) { 1439 if (sp != NULL) 1440 bzero(sp, sizeof (mdb_tgt_spec_desc_t)); 1441 (void) set_errno(EMDB_NOSESPEC); 1442 return (NULL); 1443 } 1444 1445 if (sp == NULL) 1446 sp = &desc; 1447 1448 sep = vep->ve_se; 1449 1450 sp->spec_id = vep->ve_id; 1451 sp->spec_flags = vep->ve_flags; 1452 sp->spec_hits = vep->ve_hits; 1453 sp->spec_limit = vep->ve_limit; 1454 sp->spec_state = sep->se_state; 1455 sp->spec_errno = sep->se_errno; 1456 sp->spec_base = 0; 1457 sp->spec_size = 0; 1458 sp->spec_data = vep->ve_data; 1459 1460 return (sep->se_ops->se_info(t, sep, vep, sp, buf, nbytes)); 1461 } 1462 1463 /* 1464 * Qsort callback for sorting vespecs by VID, used below. 1465 */ 1466 static int 1467 tgt_vespec_compare(const mdb_vespec_t **lp, const mdb_vespec_t **rp) 1468 { 1469 return ((*lp)->ve_id - (*rp)->ve_id); 1470 } 1471 1472 /* 1473 * Iterate over all vespecs and call the specified callback function with the 1474 * corresponding VID and caller data pointer. We want the callback function 1475 * to see a consistent, sorted snapshot of the vespecs, and allow the callback 1476 * to take actions such as deleting the vespec itself, so we cannot simply 1477 * iterate over the lists. Instead, we pre-allocate an array of vespec 1478 * pointers, fill it in and place an additional hold on each vespec, and then 1479 * sort it. After the callback has been executed on each vespec in the 1480 * sorted array, we remove our hold and free the temporary array. 1481 */ 1482 int 1483 mdb_tgt_vespec_iter(mdb_tgt_t *t, mdb_tgt_vespec_f *func, void *p) 1484 { 1485 mdb_vespec_t **veps, **vepp, **vend; 1486 mdb_vespec_t *vep, *nvep; 1487 mdb_sespec_t *sep; 1488 1489 uint_t vecnt = t->t_vecnt; 1490 1491 veps = mdb_alloc(sizeof (mdb_vespec_t *) * vecnt, UM_SLEEP); 1492 vend = veps + vecnt; 1493 vepp = veps; 1494 1495 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 1496 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 1497 mdb_tgt_vespec_hold(t, vep); 1498 nvep = mdb_list_next(vep); 1499 *vepp++ = vep; 1500 } 1501 } 1502 1503 for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) { 1504 for (vep = mdb_list_next(&sep->se_velist); vep; vep = nvep) { 1505 mdb_tgt_vespec_hold(t, vep); 1506 nvep = mdb_list_next(vep); 1507 *vepp++ = vep; 1508 } 1509 } 1510 1511 if (vepp != vend) { 1512 fail("target has %u vespecs on list but vecnt shows %u\n", 1513 (uint_t)(vepp - veps), vecnt); 1514 } 1515 1516 qsort(veps, vecnt, sizeof (mdb_vespec_t *), 1517 (int (*)(const void *, const void *))tgt_vespec_compare); 1518 1519 for (vepp = veps; vepp < vend; vepp++) { 1520 if (func(t, p, (*vepp)->ve_id, (*vepp)->ve_data) != 0) 1521 break; 1522 } 1523 1524 for (vepp = veps; vepp < vend; vepp++) 1525 mdb_tgt_vespec_rele(t, *vepp); 1526 1527 mdb_free(veps, sizeof (mdb_vespec_t *) * vecnt); 1528 return (0); 1529 } 1530 1531 /* 1532 * Reset the vespec flags, match limit, and callback data to the specified 1533 * values. We silently correct invalid parameters, except for the VID. 1534 * The caller is required to query the existing properties and pass back 1535 * the existing values for any properties that should not be modified. 1536 * If the callback data is modified, the caller is responsible for cleaning 1537 * up any state associated with the previous value. 1538 */ 1539 int 1540 mdb_tgt_vespec_modify(mdb_tgt_t *t, int id, uint_t flags, 1541 uint_t limit, void *data) 1542 { 1543 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id); 1544 1545 if (vep == NULL) 1546 return (set_errno(EMDB_NOSESPEC)); 1547 1548 /* 1549 * If the value of the MDB_TGT_SPEC_DISABLED bit is changing, call the 1550 * appropriate vespec function to do the enable/disable work. 1551 */ 1552 if ((flags & MDB_TGT_SPEC_DISABLED) != 1553 (vep->ve_flags & MDB_TGT_SPEC_DISABLED)) { 1554 if (flags & MDB_TGT_SPEC_DISABLED) 1555 (void) mdb_tgt_vespec_disable(t, id); 1556 else 1557 (void) mdb_tgt_vespec_enable(t, id); 1558 } 1559 1560 /* 1561 * Make that only one MDB_TGT_SPEC_AUTO* bit is set in the new flags 1562 * value: extra bits are cleared according to order of precedence. 1563 */ 1564 if (flags & MDB_TGT_SPEC_AUTOSTOP) 1565 flags &= ~(MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS); 1566 else if (flags & MDB_TGT_SPEC_AUTODEL) 1567 flags &= ~MDB_TGT_SPEC_AUTODIS; 1568 1569 /* 1570 * The TEMPORARY property always takes precedence over STICKY. 1571 */ 1572 if (flags & MDB_TGT_SPEC_TEMPORARY) 1573 flags &= ~MDB_TGT_SPEC_STICKY; 1574 1575 /* 1576 * If any MDB_TGT_SPEC_AUTO* bits are changing, reset the hit count 1577 * back to zero and clear all of the old auto bits. 1578 */ 1579 if ((flags & T_AUTO_BITS) != (vep->ve_flags & T_AUTO_BITS)) { 1580 vep->ve_flags &= ~T_AUTO_BITS; 1581 vep->ve_hits = 0; 1582 } 1583 1584 vep->ve_flags = (vep->ve_flags & T_IMPL_BITS) | (flags & ~T_IMPL_BITS); 1585 vep->ve_data = data; 1586 1587 /* 1588 * If any MDB_TGT_SPEC_AUTO* flags are set, make sure the limit is at 1589 * least one. If none are set, reset it back to zero. 1590 */ 1591 if (vep->ve_flags & T_AUTO_BITS) 1592 vep->ve_limit = MAX(limit, 1); 1593 else 1594 vep->ve_limit = 0; 1595 1596 /* 1597 * As a convenience, we allow the caller to specify SPEC_DELETED in 1598 * the flags field as indication that the event should be deleted. 1599 */ 1600 if (flags & MDB_TGT_SPEC_DELETED) 1601 (void) mdb_tgt_vespec_delete(t, id); 1602 1603 return (0); 1604 } 1605 1606 /* 1607 * Remove the user disabled bit from the specified vespec, and attempt to 1608 * activate the underlying sespec and move it to the active list if possible. 1609 */ 1610 int 1611 mdb_tgt_vespec_enable(mdb_tgt_t *t, int id) 1612 { 1613 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id); 1614 1615 if (vep == NULL) 1616 return (set_errno(EMDB_NOSESPEC)); 1617 1618 if (vep->ve_flags & MDB_TGT_SPEC_DISABLED) { 1619 ASSERT(mdb_list_next(vep) == NULL); 1620 vep->ve_flags &= ~MDB_TGT_SPEC_DISABLED; 1621 if (mdb_tgt_sespec_activate_one(t, vep->ve_se) < 0) 1622 return (-1); /* errno is set for us */ 1623 } 1624 1625 return (0); 1626 } 1627 1628 /* 1629 * Set the user disabled bit on the specified vespec, and move it to the idle 1630 * list. If the vespec is not alone with its sespec or if it is a currently 1631 * matched event, we must always create a new idle sespec and move the vespec 1632 * there. If the vespec was alone and active, we can simply idle the sespec. 1633 */ 1634 int 1635 mdb_tgt_vespec_disable(mdb_tgt_t *t, int id) 1636 { 1637 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id); 1638 mdb_sespec_t *sep; 1639 1640 if (vep == NULL) 1641 return (set_errno(EMDB_NOSESPEC)); 1642 1643 if (vep->ve_flags & MDB_TGT_SPEC_DISABLED) 1644 return (0); /* already disabled */ 1645 1646 if (mdb_list_prev(vep) != NULL || mdb_list_next(vep) != NULL || 1647 vep->ve_se->se_matched != NULL) { 1648 1649 sep = mdb_tgt_sespec_insert(t, vep->ve_se->se_ops, &t->t_idle); 1650 1651 mdb_list_delete(&vep->ve_se->se_velist, vep); 1652 mdb_tgt_sespec_rele(t, vep->ve_se); 1653 1654 mdb_list_append(&sep->se_velist, vep); 1655 mdb_tgt_sespec_hold(t, sep); 1656 1657 vep->ve_flags &= ~MDB_TGT_SPEC_MATCHED; 1658 vep->ve_se = sep; 1659 1660 } else if (vep->ve_se->se_state != MDB_TGT_SPEC_IDLE) 1661 mdb_tgt_sespec_idle_one(t, vep->ve_se, EMDB_SPECDIS); 1662 1663 vep->ve_flags |= MDB_TGT_SPEC_DISABLED; 1664 return (0); 1665 } 1666 1667 /* 1668 * Delete the given vespec. We use the MDB_TGT_SPEC_DELETED flag to ensure that 1669 * multiple calls to mdb_tgt_vespec_delete to not attempt to decrement the 1670 * reference count on the vespec more than once. This is because the vespec 1671 * may remain referenced if it is currently held by another routine (e.g. 1672 * vespec_iter), and so the user could attempt to delete it more than once 1673 * since it reference count will be >= 2 prior to the first delete call. 1674 */ 1675 int 1676 mdb_tgt_vespec_delete(mdb_tgt_t *t, int id) 1677 { 1678 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, id); 1679 1680 if (vep == NULL) 1681 return (set_errno(EMDB_NOSESPEC)); 1682 1683 if (vep->ve_flags & MDB_TGT_SPEC_DELETED) 1684 return (set_errno(EBUSY)); 1685 1686 vep->ve_flags |= MDB_TGT_SPEC_DELETED; 1687 mdb_tgt_vespec_rele(t, vep); 1688 return (0); 1689 } 1690 1691 int 1692 mdb_tgt_add_vbrkpt(mdb_tgt_t *t, uintptr_t addr, 1693 int spec_flags, mdb_tgt_se_f *func, void *p) 1694 { 1695 return (t->t_ops->t_add_vbrkpt(t, addr, spec_flags, func, p)); 1696 } 1697 1698 int 1699 mdb_tgt_add_sbrkpt(mdb_tgt_t *t, const char *symbol, 1700 int spec_flags, mdb_tgt_se_f *func, void *p) 1701 { 1702 return (t->t_ops->t_add_sbrkpt(t, symbol, spec_flags, func, p)); 1703 } 1704 1705 int 1706 mdb_tgt_add_pwapt(mdb_tgt_t *t, physaddr_t pa, size_t n, uint_t flags, 1707 int spec_flags, mdb_tgt_se_f *func, void *p) 1708 { 1709 if ((flags & ~MDB_TGT_WA_RWX) || flags == 0) { 1710 (void) set_errno(EINVAL); 1711 return (0); 1712 } 1713 1714 if (pa + n < pa) { 1715 (void) set_errno(EMDB_WPRANGE); 1716 return (0); 1717 } 1718 1719 return (t->t_ops->t_add_pwapt(t, pa, n, flags, spec_flags, func, p)); 1720 } 1721 1722 int 1723 mdb_tgt_add_vwapt(mdb_tgt_t *t, uintptr_t va, size_t n, uint_t flags, 1724 int spec_flags, mdb_tgt_se_f *func, void *p) 1725 { 1726 if ((flags & ~MDB_TGT_WA_RWX) || flags == 0) { 1727 (void) set_errno(EINVAL); 1728 return (0); 1729 } 1730 1731 if (va + n < va) { 1732 (void) set_errno(EMDB_WPRANGE); 1733 return (0); 1734 } 1735 1736 return (t->t_ops->t_add_vwapt(t, va, n, flags, spec_flags, func, p)); 1737 } 1738 1739 int 1740 mdb_tgt_add_iowapt(mdb_tgt_t *t, uintptr_t addr, size_t n, uint_t flags, 1741 int spec_flags, mdb_tgt_se_f *func, void *p) 1742 { 1743 if ((flags & ~MDB_TGT_WA_RWX) || flags == 0) { 1744 (void) set_errno(EINVAL); 1745 return (0); 1746 } 1747 1748 if (addr + n < addr) { 1749 (void) set_errno(EMDB_WPRANGE); 1750 return (0); 1751 } 1752 1753 return (t->t_ops->t_add_iowapt(t, addr, n, flags, spec_flags, func, p)); 1754 } 1755 1756 int 1757 mdb_tgt_add_sysenter(mdb_tgt_t *t, int sysnum, 1758 int spec_flags, mdb_tgt_se_f *func, void *p) 1759 { 1760 return (t->t_ops->t_add_sysenter(t, sysnum, spec_flags, func, p)); 1761 } 1762 1763 int 1764 mdb_tgt_add_sysexit(mdb_tgt_t *t, int sysnum, 1765 int spec_flags, mdb_tgt_se_f *func, void *p) 1766 { 1767 return (t->t_ops->t_add_sysexit(t, sysnum, spec_flags, func, p)); 1768 } 1769 1770 int 1771 mdb_tgt_add_signal(mdb_tgt_t *t, int sig, 1772 int spec_flags, mdb_tgt_se_f *func, void *p) 1773 { 1774 return (t->t_ops->t_add_signal(t, sig, spec_flags, func, p)); 1775 } 1776 1777 int 1778 mdb_tgt_add_fault(mdb_tgt_t *t, int flt, 1779 int spec_flags, mdb_tgt_se_f *func, void *p) 1780 { 1781 return (t->t_ops->t_add_fault(t, flt, spec_flags, func, p)); 1782 } 1783 1784 int 1785 mdb_tgt_getareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, 1786 const char *rname, mdb_tgt_reg_t *rp) 1787 { 1788 return (t->t_ops->t_getareg(t, tid, rname, rp)); 1789 } 1790 1791 int 1792 mdb_tgt_putareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, 1793 const char *rname, mdb_tgt_reg_t r) 1794 { 1795 return (t->t_ops->t_putareg(t, tid, rname, r)); 1796 } 1797 1798 int 1799 mdb_tgt_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gregs, 1800 mdb_tgt_stack_f *cb, void *p) 1801 { 1802 return (t->t_ops->t_stack_iter(t, gregs, cb, p)); 1803 } 1804 1805 int 1806 mdb_tgt_xdata_iter(mdb_tgt_t *t, mdb_tgt_xdata_f *func, void *private) 1807 { 1808 mdb_xdata_t *xdp; 1809 1810 for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) { 1811 if (func(private, xdp->xd_name, xdp->xd_desc, 1812 xdp->xd_copy(t, NULL, 0)) != 0) 1813 break; 1814 } 1815 1816 return (0); 1817 } 1818 1819 ssize_t 1820 mdb_tgt_getxdata(mdb_tgt_t *t, const char *name, void *buf, size_t nbytes) 1821 { 1822 mdb_xdata_t *xdp; 1823 1824 for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) { 1825 if (strcmp(xdp->xd_name, name) == 0) 1826 return (xdp->xd_copy(t, buf, nbytes)); 1827 } 1828 1829 return (set_errno(ENODATA)); 1830 } 1831 1832 long 1833 mdb_tgt_notsup() 1834 { 1835 return (set_errno(EMDB_TGTNOTSUP)); 1836 } 1837 1838 void * 1839 mdb_tgt_null() 1840 { 1841 (void) set_errno(EMDB_TGTNOTSUP); 1842 return (NULL); 1843 } 1844 1845 long 1846 mdb_tgt_nop() 1847 { 1848 return (0L); 1849 } 1850 1851 int 1852 mdb_tgt_xdata_insert(mdb_tgt_t *t, const char *name, const char *desc, 1853 ssize_t (*copy)(mdb_tgt_t *, void *, size_t)) 1854 { 1855 mdb_xdata_t *xdp; 1856 1857 for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) { 1858 if (strcmp(xdp->xd_name, name) == 0) 1859 return (set_errno(EMDB_XDEXISTS)); 1860 } 1861 1862 xdp = mdb_alloc(sizeof (mdb_xdata_t), UM_SLEEP); 1863 mdb_list_append(&t->t_xdlist, xdp); 1864 1865 xdp->xd_name = name; 1866 xdp->xd_desc = desc; 1867 xdp->xd_copy = copy; 1868 1869 return (0); 1870 } 1871 1872 int 1873 mdb_tgt_xdata_delete(mdb_tgt_t *t, const char *name) 1874 { 1875 mdb_xdata_t *xdp; 1876 1877 for (xdp = mdb_list_next(&t->t_xdlist); xdp; xdp = mdb_list_next(xdp)) { 1878 if (strcmp(xdp->xd_name, name) == 0) { 1879 mdb_list_delete(&t->t_xdlist, xdp); 1880 mdb_free(xdp, sizeof (mdb_xdata_t)); 1881 return (0); 1882 } 1883 } 1884 1885 return (set_errno(EMDB_NOXD)); 1886 } 1887 1888 int 1889 mdb_tgt_sym_match(const GElf_Sym *sym, uint_t mask) 1890 { 1891 #if STT_NUM != (STT_TLS + 1) 1892 #error "STT_NUM has grown. update mdb_tgt_sym_match()" 1893 #endif 1894 1895 uchar_t s_bind = GELF_ST_BIND(sym->st_info); 1896 uchar_t s_type = GELF_ST_TYPE(sym->st_info); 1897 1898 /* 1899 * In case you haven't already guessed, this relies on the bitmask 1900 * used by <mdb/mdb_target.h> and <libproc.h> for encoding symbol 1901 * type and binding matching the order of STB and STT constants 1902 * in <sys/elf.h>. Changes to ELF must maintain binary 1903 * compatibility, so I think this is reasonably fair game. 1904 */ 1905 if (s_bind < STB_NUM && s_type < STT_NUM) { 1906 uint_t type = (1 << (s_type + 8)) | (1 << s_bind); 1907 return ((type & ~mask) == 0); 1908 } 1909 1910 return (0); /* Unknown binding or type; fail to match */ 1911 } 1912 1913 void 1914 mdb_tgt_elf_export(mdb_gelf_file_t *gf) 1915 { 1916 GElf_Xword d = 0, t = 0; 1917 GElf_Addr b = 0, e = 0; 1918 uint32_t m = 0; 1919 mdb_var_t *v; 1920 1921 /* 1922 * Reset legacy adb variables based on the specified ELF object file 1923 * provided by the target. We define these variables: 1924 * 1925 * b - the address of the data segment (first writeable Phdr) 1926 * d - the size of the data segment 1927 * e - the address of the entry point 1928 * m - the magic number identifying the file 1929 * t - the address of the text segment (first executable Phdr) 1930 */ 1931 if (gf != NULL) { 1932 const GElf_Phdr *text = NULL, *data = NULL; 1933 size_t i; 1934 1935 e = gf->gf_ehdr.e_entry; 1936 bcopy(&gf->gf_ehdr.e_ident[EI_MAG0], &m, sizeof (m)); 1937 1938 for (i = 0; i < gf->gf_npload; i++) { 1939 if (text == NULL && (gf->gf_phdrs[i].p_flags & PF_X)) 1940 text = &gf->gf_phdrs[i]; 1941 if (data == NULL && (gf->gf_phdrs[i].p_flags & PF_W)) 1942 data = &gf->gf_phdrs[i]; 1943 } 1944 1945 if (text != NULL) 1946 t = text->p_memsz; 1947 if (data != NULL) { 1948 b = data->p_vaddr; 1949 d = data->p_memsz; 1950 } 1951 } 1952 1953 if ((v = mdb_nv_lookup(&mdb.m_nv, "b")) != NULL) 1954 mdb_nv_set_value(v, b); 1955 if ((v = mdb_nv_lookup(&mdb.m_nv, "d")) != NULL) 1956 mdb_nv_set_value(v, d); 1957 if ((v = mdb_nv_lookup(&mdb.m_nv, "e")) != NULL) 1958 mdb_nv_set_value(v, e); 1959 if ((v = mdb_nv_lookup(&mdb.m_nv, "m")) != NULL) 1960 mdb_nv_set_value(v, m); 1961 if ((v = mdb_nv_lookup(&mdb.m_nv, "t")) != NULL) 1962 mdb_nv_set_value(v, t); 1963 } 1964 1965 /*ARGSUSED*/ 1966 void 1967 mdb_tgt_sespec_hold(mdb_tgt_t *t, mdb_sespec_t *sep) 1968 { 1969 sep->se_refs++; 1970 ASSERT(sep->se_refs != 0); 1971 } 1972 1973 void 1974 mdb_tgt_sespec_rele(mdb_tgt_t *t, mdb_sespec_t *sep) 1975 { 1976 ASSERT(sep->se_refs != 0); 1977 1978 if (--sep->se_refs == 0) { 1979 mdb_dprintf(MDB_DBG_TGT, "destroying sespec %p\n", (void *)sep); 1980 ASSERT(mdb_list_next(&sep->se_velist) == NULL); 1981 1982 if (sep->se_state != MDB_TGT_SPEC_IDLE) { 1983 sep->se_ops->se_dtor(t, sep); 1984 mdb_list_delete(&t->t_active, sep); 1985 } else 1986 mdb_list_delete(&t->t_idle, sep); 1987 1988 mdb_free(sep, sizeof (mdb_sespec_t)); 1989 } 1990 } 1991 1992 mdb_sespec_t * 1993 mdb_tgt_sespec_insert(mdb_tgt_t *t, const mdb_se_ops_t *ops, mdb_list_t *list) 1994 { 1995 mdb_sespec_t *sep = mdb_zalloc(sizeof (mdb_sespec_t), UM_SLEEP); 1996 1997 if (list == &t->t_active) 1998 sep->se_state = MDB_TGT_SPEC_ACTIVE; 1999 else 2000 sep->se_state = MDB_TGT_SPEC_IDLE; 2001 2002 mdb_list_append(list, sep); 2003 sep->se_ops = ops; 2004 return (sep); 2005 } 2006 2007 mdb_sespec_t * 2008 mdb_tgt_sespec_lookup_active(mdb_tgt_t *t, const mdb_se_ops_t *ops, void *args) 2009 { 2010 mdb_sespec_t *sep; 2011 2012 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 2013 if (sep->se_ops == ops && sep->se_ops->se_secmp(t, sep, args)) 2014 break; 2015 } 2016 2017 return (sep); 2018 } 2019 2020 mdb_sespec_t * 2021 mdb_tgt_sespec_lookup_idle(mdb_tgt_t *t, const mdb_se_ops_t *ops, void *args) 2022 { 2023 mdb_sespec_t *sep; 2024 2025 for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) { 2026 if (sep->se_ops == ops && sep->se_ops->se_vecmp(t, 2027 mdb_list_next(&sep->se_velist), args)) 2028 break; 2029 } 2030 2031 return (sep); 2032 } 2033 2034 /*ARGSUSED*/ 2035 void 2036 mdb_tgt_vespec_hold(mdb_tgt_t *t, mdb_vespec_t *vep) 2037 { 2038 vep->ve_refs++; 2039 ASSERT(vep->ve_refs != 0); 2040 } 2041 2042 void 2043 mdb_tgt_vespec_rele(mdb_tgt_t *t, mdb_vespec_t *vep) 2044 { 2045 ASSERT(vep->ve_refs != 0); 2046 2047 if (--vep->ve_refs == 0) { 2048 /* 2049 * Remove this vespec from the sespec's velist and decrement 2050 * the reference count on the sespec. 2051 */ 2052 mdb_list_delete(&vep->ve_se->se_velist, vep); 2053 mdb_tgt_sespec_rele(t, vep->ve_se); 2054 2055 /* 2056 * If we are deleting the most recently assigned VID, reset 2057 * t_vepos or t_veneg as appropriate to re-use that number. 2058 * This could be enhanced to re-use any free number by 2059 * maintaining a bitmap or hash of the allocated IDs. 2060 */ 2061 if (vep->ve_id > 0 && t->t_vepos == vep->ve_id + 1) 2062 t->t_vepos = vep->ve_id; 2063 else if (vep->ve_id < 0 && t->t_veneg == -vep->ve_id + 1) 2064 t->t_veneg = -vep->ve_id; 2065 2066 /* 2067 * Call the destructor to clean up ve_args, and then free 2068 * the actual vespec structure. 2069 */ 2070 vep->ve_dtor(vep); 2071 mdb_free(vep, sizeof (mdb_vespec_t)); 2072 2073 ASSERT(t->t_vecnt != 0); 2074 t->t_vecnt--; 2075 } 2076 } 2077 2078 int 2079 mdb_tgt_vespec_insert(mdb_tgt_t *t, const mdb_se_ops_t *ops, int flags, 2080 mdb_tgt_se_f *func, void *data, void *args, void (*dtor)(mdb_vespec_t *)) 2081 { 2082 mdb_vespec_t *vep = mdb_zalloc(sizeof (mdb_vespec_t), UM_SLEEP); 2083 2084 int id, mult, *seqp; 2085 mdb_sespec_t *sep; 2086 2087 /* 2088 * Make that only one MDB_TGT_SPEC_AUTO* bit is set in the new flags 2089 * value: extra bits are cleared according to order of precedence. 2090 */ 2091 if (flags & MDB_TGT_SPEC_AUTOSTOP) 2092 flags &= ~(MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS); 2093 else if (flags & MDB_TGT_SPEC_AUTODEL) 2094 flags &= ~MDB_TGT_SPEC_AUTODIS; 2095 2096 /* 2097 * The TEMPORARY property always takes precedence over STICKY. 2098 */ 2099 if (flags & MDB_TGT_SPEC_TEMPORARY) 2100 flags &= ~MDB_TGT_SPEC_STICKY; 2101 2102 /* 2103 * Find a matching sespec or create a new one on the appropriate list. 2104 * We always create a new sespec if the vespec is created disabled. 2105 */ 2106 if (flags & MDB_TGT_SPEC_DISABLED) 2107 sep = mdb_tgt_sespec_insert(t, ops, &t->t_idle); 2108 else if ((sep = mdb_tgt_sespec_lookup_active(t, ops, args)) == NULL && 2109 (sep = mdb_tgt_sespec_lookup_idle(t, ops, args)) == NULL) 2110 sep = mdb_tgt_sespec_insert(t, ops, &t->t_active); 2111 2112 /* 2113 * Generate a new ID for the vespec. Increasing positive integers are 2114 * assigned to visible vespecs; decreasing negative integers are 2115 * assigned to hidden vespecs. The target saves our most recent choice. 2116 */ 2117 if (flags & MDB_TGT_SPEC_INTERNAL) { 2118 seqp = &t->t_veneg; 2119 mult = -1; 2120 } else { 2121 seqp = &t->t_vepos; 2122 mult = 1; 2123 } 2124 2125 id = *seqp; 2126 2127 while (mdb_tgt_vespec_lookup(t, id * mult) != NULL) 2128 id = MAX(id + 1, 1); 2129 2130 *seqp = MAX(id + 1, 1); 2131 2132 vep->ve_id = id * mult; 2133 vep->ve_flags = flags & ~(MDB_TGT_SPEC_MATCHED | MDB_TGT_SPEC_DELETED); 2134 vep->ve_se = sep; 2135 vep->ve_callback = func; 2136 vep->ve_data = data; 2137 vep->ve_args = args; 2138 vep->ve_dtor = dtor; 2139 2140 mdb_list_append(&sep->se_velist, vep); 2141 mdb_tgt_sespec_hold(t, sep); 2142 2143 mdb_tgt_vespec_hold(t, vep); 2144 t->t_vecnt++; 2145 2146 /* 2147 * If this vespec is the first reference to the sespec and it's active, 2148 * then it is newly created and we should attempt to initialize it. 2149 * If se_ctor fails, then move the sespec back to the idle list. 2150 */ 2151 if (sep->se_refs == 1 && sep->se_state == MDB_TGT_SPEC_ACTIVE && 2152 sep->se_ops->se_ctor(t, sep, vep->ve_args) == -1) { 2153 2154 mdb_list_delete(&t->t_active, sep); 2155 mdb_list_append(&t->t_idle, sep); 2156 2157 sep->se_state = MDB_TGT_SPEC_IDLE; 2158 sep->se_errno = errno; 2159 sep->se_data = NULL; 2160 } 2161 2162 /* 2163 * If the sespec is active and the target is currently running (because 2164 * we grabbed it using PGRAB_NOSTOP), then go ahead and attempt to arm 2165 * the sespec so it will take effect immediately. 2166 */ 2167 if (sep->se_state == MDB_TGT_SPEC_ACTIVE && 2168 t->t_status.st_state == MDB_TGT_RUNNING) 2169 mdb_tgt_sespec_arm_one(t, sep); 2170 2171 mdb_dprintf(MDB_DBG_TGT, "inserted [ %d ] sep=%p refs=%u state=%d\n", 2172 vep->ve_id, (void *)sep, sep->se_refs, sep->se_state); 2173 2174 return (vep->ve_id); 2175 } 2176 2177 /* 2178 * Search the target's active, idle, and disabled lists for the vespec matching 2179 * the specified VID, and return a pointer to it, or NULL if no match is found. 2180 */ 2181 mdb_vespec_t * 2182 mdb_tgt_vespec_lookup(mdb_tgt_t *t, int vid) 2183 { 2184 mdb_sespec_t *sep; 2185 mdb_vespec_t *vep; 2186 2187 if (vid == 0) 2188 return (NULL); /* 0 is never a valid VID */ 2189 2190 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 2191 for (vep = mdb_list_next(&sep->se_velist); vep; 2192 vep = mdb_list_next(vep)) { 2193 if (vep->ve_id == vid) 2194 return (vep); 2195 } 2196 } 2197 2198 for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) { 2199 for (vep = mdb_list_next(&sep->se_velist); vep; 2200 vep = mdb_list_next(vep)) { 2201 if (vep->ve_id == vid) 2202 return (vep); 2203 } 2204 } 2205 2206 return (NULL); 2207 } 2208 2209 /*ARGSUSED*/ 2210 void 2211 no_ve_dtor(mdb_vespec_t *vep) 2212 { 2213 /* default destructor does nothing */ 2214 } 2215 2216 /*ARGSUSED*/ 2217 void 2218 no_se_f(mdb_tgt_t *t, int vid, void *data) 2219 { 2220 /* default callback does nothing */ 2221 } 2222 2223 /*ARGSUSED*/ 2224 void 2225 no_se_dtor(mdb_tgt_t *t, mdb_sespec_t *sep) 2226 { 2227 /* default destructor does nothing */ 2228 } 2229 2230 /*ARGSUSED*/ 2231 int 2232 no_se_secmp(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 2233 { 2234 return (sep->se_data == args); 2235 } 2236 2237 /*ARGSUSED*/ 2238 int 2239 no_se_vecmp(mdb_tgt_t *t, mdb_vespec_t *vep, void *args) 2240 { 2241 return (vep->ve_args == args); 2242 } 2243 2244 /*ARGSUSED*/ 2245 int 2246 no_se_arm(mdb_tgt_t *t, mdb_sespec_t *sep) 2247 { 2248 return (0); /* return success */ 2249 } 2250 2251 /*ARGSUSED*/ 2252 int 2253 no_se_disarm(mdb_tgt_t *t, mdb_sespec_t *sep) 2254 { 2255 return (0); /* return success */ 2256 } 2257 2258 /*ARGSUSED*/ 2259 int 2260 no_se_cont(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 2261 { 2262 if (tsp != &t->t_status) 2263 bcopy(&t->t_status, tsp, sizeof (mdb_tgt_status_t)); 2264 2265 return (0); /* return success */ 2266 } 2267 2268 int 2269 mdb_tgt_register_dcmds(mdb_tgt_t *t, const mdb_dcmd_t *dcp, int flags) 2270 { 2271 int fail = 0; 2272 2273 for (; dcp->dc_name != NULL; dcp++) { 2274 if (mdb_module_add_dcmd(t->t_module, dcp, flags) == -1) { 2275 warn("failed to add dcmd %s", dcp->dc_name); 2276 fail++; 2277 } 2278 } 2279 2280 return (fail > 0 ? -1 : 0); 2281 } 2282 2283 int 2284 mdb_tgt_register_walkers(mdb_tgt_t *t, const mdb_walker_t *wp, int flags) 2285 { 2286 int fail = 0; 2287 2288 for (; wp->walk_name != NULL; wp++) { 2289 if (mdb_module_add_walker(t->t_module, wp, flags) == -1) { 2290 warn("failed to add walk %s", wp->walk_name); 2291 fail++; 2292 } 2293 } 2294 2295 return (fail > 0 ? -1 : 0); 2296 } 2297 2298 void 2299 mdb_tgt_register_regvars(mdb_tgt_t *t, const mdb_tgt_regdesc_t *rdp, 2300 const mdb_nv_disc_t *disc, int flags) 2301 { 2302 for (; rdp->rd_name != NULL; rdp++) { 2303 if (!(rdp->rd_flags & MDB_TGT_R_EXPORT)) 2304 continue; /* Don't export register as a variable */ 2305 2306 if (rdp->rd_flags & MDB_TGT_R_RDONLY) 2307 flags |= MDB_NV_RDONLY; 2308 2309 (void) mdb_nv_insert(&mdb.m_nv, rdp->rd_name, disc, 2310 (uintptr_t)t, MDB_NV_PERSIST | flags); 2311 } 2312 } 2313