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 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* 27 * Copyright 2015 Joyent, Inc. 28 * Copyright (c) 2014 by Delphix. All rights reserved. 29 */ 30 31 /* 32 * User Process Target 33 * 34 * The user process target is invoked when the -u or -p command-line options 35 * are used, or when an ELF executable file or ELF core file is specified on 36 * the command-line. This target is also selected by default when no target 37 * options are present. In this case, it defaults the executable name to 38 * "a.out". If no process or core file is currently attached, the target 39 * functions as a kind of virtual /dev/zero (in accordance with adb(1) 40 * semantics); reads from the virtual address space return zeroes and writes 41 * fail silently. The proc target itself is designed as a wrapper around the 42 * services provided by libproc.so: t->t_pshandle is set to the struct 43 * ps_prochandle pointer returned as a handle by libproc. The target also 44 * opens the executable file itself using the MDB GElf services, for 45 * interpreting the .symtab and .dynsym if no libproc handle has been 46 * initialized, and for handling i/o to and from the object file. Currently, 47 * the only ISA-dependent portions of the proc target are the $r and ::fpregs 48 * dcmds, the callbacks for t_next() and t_step_out(), and the list of named 49 * registers; these are linked in from the proc_isadep.c file for each ISA and 50 * called from the common code in this file. 51 * 52 * The user process target implements complete user process control using the 53 * facilities provided by libproc.so. The MDB execution control model and 54 * an overview of software event management is described in mdb_target.c. The 55 * proc target implements breakpoints by replacing the instruction of interest 56 * with a trap instruction, and then restoring the original instruction to step 57 * over the breakpoint. The idea of replacing program text with instructions 58 * that transfer control to the debugger dates back as far as 1951 [1]. When 59 * the target stops, we replace each breakpoint with the original instruction 60 * as part of the disarm operation. This means that no special processing is 61 * required for t_vread() because the instrumented instructions will never be 62 * seen by the debugger once the target stops. Some debuggers have improved 63 * start/stop performance by leaving breakpoint traps in place and then 64 * handling a read from a breakpoint address as a special case. Although this 65 * improves efficiency for a source-level debugger, it runs somewhat contrary 66 * to the philosophy of the low-level debugger. Since we remove the 67 * instructions, users can apply other external debugging tools to the process 68 * once it has stopped (e.g. the proc(1) tools) and not be misled by MDB 69 * instrumentation. The tracing of faults, signals, system calls, and 70 * watchpoints and general process inspection is implemented directly using 71 * the mechanisms provided by /proc, as described originally in [2] and [3]. 72 * 73 * References 74 * 75 * [1] S. Gill, "The Diagnosis Of Mistakes In Programmes on the EDSAC", 76 * Proceedings of the Royal Society Series A Mathematical and Physical 77 * Sciences, Cambridge University Press, 206(1087), May 1951, pp. 538-554. 78 * 79 * [2] T.J. Killian, "Processes as Files", Proceedings of the USENIX Association 80 * Summer Conference, Salt Lake City, June 1984, pp. 203-207. 81 * 82 * [3] Roger Faulkner and Ron Gomes, "The Process File System and Process 83 * Model in UNIX System V", Proceedings of the USENIX Association 84 * Winter Conference, Dallas, January 1991, pp. 243-252. 85 */ 86 87 #include <mdb/mdb_proc.h> 88 #include <mdb/mdb_disasm.h> 89 #include <mdb/mdb_signal.h> 90 #include <mdb/mdb_string.h> 91 #include <mdb/mdb_module.h> 92 #include <mdb/mdb_debug.h> 93 #include <mdb/mdb_conf.h> 94 #include <mdb/mdb_err.h> 95 #include <mdb/mdb_types.h> 96 #include <mdb/mdb.h> 97 98 #include <sys/utsname.h> 99 #include <sys/wait.h> 100 #include <sys/stat.h> 101 #include <termio.h> 102 #include <signal.h> 103 #include <stdio_ext.h> 104 #include <stdlib.h> 105 #include <string.h> 106 107 #define PC_FAKE -1UL /* illegal pc value unequal 0 */ 108 109 static const char PT_EXEC_PATH[] = "a.out"; /* Default executable */ 110 static const char PT_CORE_PATH[] = "core"; /* Default core file */ 111 112 static const pt_ptl_ops_t proc_lwp_ops; 113 static const pt_ptl_ops_t proc_tdb_ops; 114 static const mdb_se_ops_t proc_brkpt_ops; 115 static const mdb_se_ops_t proc_wapt_ops; 116 117 static int pt_setrun(mdb_tgt_t *, mdb_tgt_status_t *, int); 118 static void pt_activate_common(mdb_tgt_t *); 119 static mdb_tgt_vespec_f pt_ignore_sig; 120 static mdb_tgt_se_f pt_fork; 121 static mdb_tgt_se_f pt_exec; 122 123 static int pt_lookup_by_name_thr(mdb_tgt_t *, const char *, 124 const char *, GElf_Sym *, mdb_syminfo_t *, mdb_tgt_tid_t); 125 static int tlsbase(mdb_tgt_t *, mdb_tgt_tid_t, Lmid_t, const char *, 126 psaddr_t *); 127 128 /* 129 * When debugging postmortem, we don't resolve names as we may very well not 130 * be on a system on which those names resolve. 131 */ 132 #define PT_LIBPROC_RESOLVE(P) \ 133 (!(mdb.m_flags & MDB_FL_LMRAW) && Pstate(P) != PS_DEAD) 134 135 /* 136 * The Perror_printf() function interposes on the default, empty libproc 137 * definition. It will be called to report additional information on complex 138 * errors, such as a corrupt core file. We just pass the args to vwarn. 139 */ 140 /*ARGSUSED*/ 141 void 142 Perror_printf(struct ps_prochandle *P, const char *format, ...) 143 { 144 va_list alist; 145 146 va_start(alist, format); 147 vwarn(format, alist); 148 va_end(alist); 149 } 150 151 /* 152 * Open the specified i/o backend as the a.out executable file, and attempt to 153 * load its standard and dynamic symbol tables. Note that if mdb_gelf_create 154 * succeeds, io is assigned to p_fio and is automatically held by gelf_create. 155 */ 156 static mdb_gelf_file_t * 157 pt_open_aout(mdb_tgt_t *t, mdb_io_t *io) 158 { 159 pt_data_t *pt = t->t_data; 160 GElf_Sym s1, s2; 161 162 if ((pt->p_file = mdb_gelf_create(io, ET_NONE, GF_FILE)) == NULL) 163 return (NULL); 164 165 pt->p_symtab = mdb_gelf_symtab_create_file(pt->p_file, 166 SHT_SYMTAB, MDB_TGT_SYMTAB); 167 pt->p_dynsym = mdb_gelf_symtab_create_file(pt->p_file, 168 SHT_DYNSYM, MDB_TGT_DYNSYM); 169 170 /* 171 * If we've got an _start symbol with a zero size, prime the private 172 * symbol table with a copy of _start with its size set to the distance 173 * between _mcount and _start. We do this because DevPro has shipped 174 * the Intel crt1.o without proper .size directives for years, which 175 * precludes proper identification of _start in stack traces. 176 */ 177 if (mdb_gelf_symtab_lookup_by_name(pt->p_dynsym, "_start", &s1, 178 NULL) == 0 && s1.st_size == 0 && 179 GELF_ST_TYPE(s1.st_info) == STT_FUNC) { 180 if (mdb_gelf_symtab_lookup_by_name(pt->p_dynsym, "_mcount", 181 &s2, NULL) == 0 && GELF_ST_TYPE(s2.st_info) == STT_FUNC) { 182 s1.st_size = s2.st_value - s1.st_value; 183 mdb_gelf_symtab_insert(mdb.m_prsym, "_start", &s1); 184 } 185 } 186 187 pt->p_fio = io; 188 return (pt->p_file); 189 } 190 191 /* 192 * Destroy the symbol tables and GElf file object associated with p_fio. Note 193 * that we do not need to explicitly free p_fio: its reference count is 194 * automatically decremented by mdb_gelf_destroy, which will free it if needed. 195 */ 196 static void 197 pt_close_aout(mdb_tgt_t *t) 198 { 199 pt_data_t *pt = t->t_data; 200 201 if (pt->p_symtab != NULL) { 202 mdb_gelf_symtab_destroy(pt->p_symtab); 203 pt->p_symtab = NULL; 204 } 205 206 if (pt->p_dynsym != NULL) { 207 mdb_gelf_symtab_destroy(pt->p_dynsym); 208 pt->p_dynsym = NULL; 209 } 210 211 if (pt->p_file != NULL) { 212 mdb_gelf_destroy(pt->p_file); 213 pt->p_file = NULL; 214 } 215 216 mdb_gelf_symtab_delete(mdb.m_prsym, "_start", NULL); 217 pt->p_fio = NULL; 218 } 219 220 typedef struct tdb_mapping { 221 const char *tm_thr_lib; 222 const char *tm_db_dir; 223 const char *tm_db_name; 224 } tdb_mapping_t; 225 226 static const tdb_mapping_t tdb_map[] = { 227 { "/lwp/amd64/libthread.so", "/usr/lib/lwp/", "libthread_db.so" }, 228 { "/lwp/sparcv9/libthread.so", "/usr/lib/lwp/", "libthread_db.so" }, 229 { "/lwp/libthread.so", "/usr/lib/lwp/", "libthread_db.so" }, 230 { "/libthread.so", "/lib/", "libthread_db.so" }, 231 { "/libc_hwcap", "/lib/", "libc_db.so" }, 232 { "/libc.so", "/lib/", "libc_db.so" } 233 }; 234 235 /* 236 * Pobject_iter callback that we use to search for the presence of libthread in 237 * order to load the corresponding libthread_db support. We derive the 238 * libthread_db path dynamically based on the libthread path. If libthread is 239 * found, this function returns 1 (and thus Pobject_iter aborts and returns 1) 240 * regardless of whether it was successful in loading the libthread_db support. 241 * If we iterate over all objects and no libthread is found, 0 is returned. 242 * Since libthread_db support was then merged into libc_db, we load either 243 * libc_db or libthread_db, depending on which library we see first. 244 */ 245 /*ARGSUSED*/ 246 static int 247 thr_check(mdb_tgt_t *t, const prmap_t *pmp, const char *name) 248 { 249 pt_data_t *pt = t->t_data; 250 const mdb_tdb_ops_t *ops; 251 char *p; 252 253 char path[MAXPATHLEN]; 254 255 int libn; 256 257 if (name == NULL) 258 return (0); /* no rtld_db object name; keep going */ 259 260 for (libn = 0; libn < sizeof (tdb_map) / sizeof (tdb_map[0]); libn++) { 261 if ((p = strstr(name, tdb_map[libn].tm_thr_lib)) != NULL) 262 break; 263 } 264 265 if (p == NULL) 266 return (0); /* no match; keep going */ 267 268 path[0] = '\0'; 269 (void) strlcat(path, mdb.m_root, sizeof (path)); 270 (void) strlcat(path, tdb_map[libn].tm_db_dir, sizeof (path)); 271 #if !defined(_ILP32) 272 (void) strlcat(path, "64/", sizeof (path)); 273 #endif /* !_ILP32 */ 274 (void) strlcat(path, tdb_map[libn].tm_db_name, sizeof (path)); 275 276 /* Append the trailing library version number. */ 277 (void) strlcat(path, strrchr(name, '.'), sizeof (path)); 278 279 if ((ops = mdb_tdb_load(path)) == NULL) { 280 if (libn != 0 || errno != ENOENT) 281 warn("failed to load %s", path); 282 goto err; 283 } 284 285 if (ops == pt->p_tdb_ops) 286 return (1); /* no changes needed */ 287 288 PTL_DTOR(t); 289 pt->p_tdb_ops = ops; 290 pt->p_ptl_ops = &proc_tdb_ops; 291 pt->p_ptl_hdl = NULL; 292 293 if (PTL_CTOR(t) == -1) { 294 warn("failed to initialize %s", path); 295 goto err; 296 } 297 298 mdb_dprintf(MDB_DBG_TGT, "loaded %s for debugging %s\n", path, name); 299 (void) mdb_tgt_status(t, &t->t_status); 300 return (1); 301 err: 302 PTL_DTOR(t); 303 pt->p_tdb_ops = NULL; 304 pt->p_ptl_ops = &proc_lwp_ops; 305 pt->p_ptl_hdl = NULL; 306 307 if (libn != 0 || errno != ENOENT) { 308 warn("warning: debugger will only be able to " 309 "examine raw LWPs\n"); 310 } 311 312 (void) mdb_tgt_status(t, &t->t_status); 313 return (1); 314 } 315 316 /* 317 * Whenever the link map is consistent following an add or delete event, we ask 318 * libproc to update its mappings, check to see if we need to load libthread_db, 319 * and then update breakpoints which have been mapped or unmapped. 320 */ 321 /*ARGSUSED*/ 322 static void 323 pt_rtld_event(mdb_tgt_t *t, int vid, void *private) 324 { 325 struct ps_prochandle *P = t->t_pshandle; 326 pt_data_t *pt = t->t_data; 327 rd_event_msg_t rdm; 328 int docontinue = 1; 329 330 if (rd_event_getmsg(pt->p_rtld, &rdm) == RD_OK) { 331 332 mdb_dprintf(MDB_DBG_TGT, "rtld event type 0x%x state 0x%x\n", 333 rdm.type, rdm.u.state); 334 335 if (rdm.type == RD_DLACTIVITY && rdm.u.state == RD_CONSISTENT) { 336 mdb_sespec_t *sep, *nsep = mdb_list_next(&t->t_active); 337 pt_brkpt_t *ptb; 338 339 Pupdate_maps(P); 340 341 if (Pobject_iter(P, (proc_map_f *)thr_check, t) == 0 && 342 pt->p_ptl_ops != &proc_lwp_ops) { 343 mdb_dprintf(MDB_DBG_TGT, "unloading thread_db " 344 "support after dlclose\n"); 345 PTL_DTOR(t); 346 pt->p_tdb_ops = NULL; 347 pt->p_ptl_ops = &proc_lwp_ops; 348 pt->p_ptl_hdl = NULL; 349 (void) mdb_tgt_status(t, &t->t_status); 350 } 351 352 for (sep = nsep; sep != NULL; sep = nsep) { 353 nsep = mdb_list_next(sep); 354 ptb = sep->se_data; 355 356 if (sep->se_ops == &proc_brkpt_ops && 357 Paddr_to_map(P, ptb->ptb_addr) == NULL) 358 mdb_tgt_sespec_idle_one(t, sep, 359 EMDB_NOMAP); 360 } 361 362 if (!mdb_tgt_sespec_activate_all(t) && 363 (mdb.m_flags & MDB_FL_BPTNOSYMSTOP) && 364 pt->p_rtld_finished) { 365 /* 366 * We weren't able to activate the breakpoints. 367 * If so requested, we'll return without 368 * calling continue, thus throwing the user into 369 * the debugger. 370 */ 371 docontinue = 0; 372 } 373 374 if (pt->p_rdstate == PT_RD_ADD) 375 pt->p_rdstate = PT_RD_CONSIST; 376 } 377 378 if (rdm.type == RD_PREINIT) 379 (void) mdb_tgt_sespec_activate_all(t); 380 381 if (rdm.type == RD_POSTINIT) { 382 pt->p_rtld_finished = TRUE; 383 if (!mdb_tgt_sespec_activate_all(t) && 384 (mdb.m_flags & MDB_FL_BPTNOSYMSTOP)) { 385 /* 386 * Now that rtld has been initialized, we 387 * should be able to initialize all deferred 388 * breakpoints. If we can't, don't let the 389 * target continue. 390 */ 391 docontinue = 0; 392 } 393 } 394 395 if (rdm.type == RD_DLACTIVITY && rdm.u.state == RD_ADD && 396 pt->p_rtld_finished) 397 pt->p_rdstate = MAX(pt->p_rdstate, PT_RD_ADD); 398 } 399 400 if (docontinue) 401 (void) mdb_tgt_continue(t, NULL); 402 } 403 404 static void 405 pt_post_attach(mdb_tgt_t *t) 406 { 407 struct ps_prochandle *P = t->t_pshandle; 408 const lwpstatus_t *psp = &Pstatus(P)->pr_lwp; 409 pt_data_t *pt = t->t_data; 410 int hflag = MDB_TGT_SPEC_HIDDEN; 411 412 mdb_dprintf(MDB_DBG_TGT, "attach pr_flags=0x%x pr_why=%d pr_what=%d\n", 413 psp->pr_flags, psp->pr_why, psp->pr_what); 414 415 /* 416 * When we grab a process, the initial setting of p_rtld_finished 417 * should be false if the process was just created by exec; otherwise 418 * we permit unscoped references to resolve because we do not know how 419 * far the process has proceeded through linker initialization. 420 */ 421 if ((psp->pr_flags & PR_ISTOP) && psp->pr_why == PR_SYSEXIT && 422 psp->pr_errno == 0 && psp->pr_what == SYS_execve) { 423 if (mdb.m_target == NULL) { 424 warn("target performed exec of %s\n", 425 IOP_NAME(pt->p_fio)); 426 } 427 pt->p_rtld_finished = FALSE; 428 } else 429 pt->p_rtld_finished = TRUE; 430 431 /* 432 * When we grab a process, if it is stopped by job control and part of 433 * the same session (i.e. same controlling tty), set MDB_FL_JOBCTL so 434 * we will know to bring it to the foreground when we continue it. 435 */ 436 if (mdb.m_term != NULL && (psp->pr_flags & PR_STOPPED) && 437 psp->pr_why == PR_JOBCONTROL && getsid(0) == Pstatus(P)->pr_sid) 438 mdb.m_flags |= MDB_FL_JOBCTL; 439 440 /* 441 * When we grab control of a live process, set F_RDWR so that the 442 * target layer permits writes to the target's address space. 443 */ 444 t->t_flags |= MDB_TGT_F_RDWR; 445 446 (void) Pfault(P, FLTBPT, TRUE); /* always trace breakpoints */ 447 (void) Pfault(P, FLTWATCH, TRUE); /* always trace watchpoints */ 448 (void) Pfault(P, FLTTRACE, TRUE); /* always trace single-step */ 449 450 (void) Punsetflags(P, PR_ASYNC); /* require synchronous mode */ 451 (void) Psetflags(P, PR_BPTADJ); /* always adjust eip on x86 */ 452 (void) Psetflags(P, PR_FORK); /* inherit tracing on fork */ 453 454 /* 455 * Install event specifiers to track fork and exec activities: 456 */ 457 (void) mdb_tgt_add_sysexit(t, SYS_vfork, hflag, pt_fork, NULL); 458 (void) mdb_tgt_add_sysexit(t, SYS_forksys, hflag, pt_fork, NULL); 459 (void) mdb_tgt_add_sysexit(t, SYS_execve, hflag, pt_exec, NULL); 460 461 /* 462 * Attempt to instantiate the librtld_db agent and set breakpoints 463 * to track rtld activity. We will legitimately fail to instantiate 464 * the rtld_db agent if the target is statically linked. 465 */ 466 if (pt->p_rtld == NULL && (pt->p_rtld = Prd_agent(P)) != NULL) { 467 rd_notify_t rdn; 468 rd_err_e err; 469 470 if ((err = rd_event_enable(pt->p_rtld, TRUE)) != RD_OK) { 471 warn("failed to enable rtld_db event tracing: %s\n", 472 rd_errstr(err)); 473 goto out; 474 } 475 476 if ((err = rd_event_addr(pt->p_rtld, RD_PREINIT, 477 &rdn)) == RD_OK && rdn.type == RD_NOTIFY_BPT) { 478 (void) mdb_tgt_add_vbrkpt(t, rdn.u.bptaddr, 479 hflag, pt_rtld_event, NULL); 480 } else { 481 warn("failed to install rtld_db preinit tracing: %s\n", 482 rd_errstr(err)); 483 } 484 485 if ((err = rd_event_addr(pt->p_rtld, RD_POSTINIT, 486 &rdn)) == RD_OK && rdn.type == RD_NOTIFY_BPT) { 487 (void) mdb_tgt_add_vbrkpt(t, rdn.u.bptaddr, 488 hflag, pt_rtld_event, NULL); 489 } else { 490 warn("failed to install rtld_db postinit tracing: %s\n", 491 rd_errstr(err)); 492 } 493 494 if ((err = rd_event_addr(pt->p_rtld, RD_DLACTIVITY, 495 &rdn)) == RD_OK && rdn.type == RD_NOTIFY_BPT) { 496 (void) mdb_tgt_add_vbrkpt(t, rdn.u.bptaddr, 497 hflag, pt_rtld_event, NULL); 498 } else { 499 warn("failed to install rtld_db activity tracing: %s\n", 500 rd_errstr(err)); 501 } 502 } 503 out: 504 Pupdate_maps(P); 505 Psync(P); 506 507 /* 508 * If librtld_db failed to initialize due to an error or because we are 509 * debugging a statically linked executable, allow unscoped references. 510 */ 511 if (pt->p_rtld == NULL) 512 pt->p_rtld_finished = TRUE; 513 514 (void) mdb_tgt_sespec_activate_all(t); 515 } 516 517 /*ARGSUSED*/ 518 static int 519 pt_vespec_delete(mdb_tgt_t *t, void *private, int id, void *data) 520 { 521 if (id < 0) { 522 ASSERT(data == NULL); /* we don't use any ve_data */ 523 (void) mdb_tgt_vespec_delete(t, id); 524 } 525 return (0); 526 } 527 528 static void 529 pt_pre_detach(mdb_tgt_t *t, int clear_matched) 530 { 531 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 532 pt_data_t *pt = t->t_data; 533 long cmd = 0; 534 535 /* 536 * If we are about to release the process and it is stopped on a traced 537 * SIGINT, breakpoint fault, single-step fault, or watchpoint, make 538 * sure to clear this event prior to releasing the process so that it 539 * does not subsequently reissue the fault and die from SIGTRAP. 540 */ 541 if (psp->pr_flags & PR_ISTOP) { 542 if (psp->pr_why == PR_FAULTED && (psp->pr_what == FLTBPT || 543 psp->pr_what == FLTTRACE || psp->pr_what == FLTWATCH)) 544 cmd = PCCFAULT; 545 else if (psp->pr_why == PR_SIGNALLED && psp->pr_what == SIGINT) 546 cmd = PCCSIG; 547 548 if (cmd != 0) 549 (void) write(Pctlfd(t->t_pshandle), &cmd, sizeof (cmd)); 550 } 551 552 if (Pstate(t->t_pshandle) == PS_UNDEAD) 553 (void) waitpid(Pstatus(t->t_pshandle)->pr_pid, NULL, WNOHANG); 554 555 (void) mdb_tgt_vespec_iter(t, pt_vespec_delete, NULL); 556 mdb_tgt_sespec_idle_all(t, EMDB_NOPROC, clear_matched); 557 558 if (pt->p_fio != pt->p_aout_fio) { 559 pt_close_aout(t); 560 (void) pt_open_aout(t, pt->p_aout_fio); 561 } 562 563 PTL_DTOR(t); 564 pt->p_tdb_ops = NULL; 565 pt->p_ptl_ops = &proc_lwp_ops; 566 pt->p_ptl_hdl = NULL; 567 568 pt->p_rtld = NULL; 569 pt->p_signal = 0; 570 pt->p_rtld_finished = FALSE; 571 pt->p_rdstate = PT_RD_NONE; 572 } 573 574 static void 575 pt_release_parents(mdb_tgt_t *t) 576 { 577 struct ps_prochandle *P = t->t_pshandle; 578 pt_data_t *pt = t->t_data; 579 580 mdb_sespec_t *sep; 581 pt_vforkp_t *vfp; 582 583 while ((vfp = mdb_list_next(&pt->p_vforkp)) != NULL) { 584 mdb_dprintf(MDB_DBG_TGT, "releasing vfork parent %d\n", 585 (int)Pstatus(vfp->p_pshandle)->pr_pid); 586 587 /* 588 * To release vfork parents, we must also wipe out any armed 589 * events in the parent by switching t_pshandle and calling 590 * se_disarm(). Do not change states or lose the matched list. 591 */ 592 t->t_pshandle = vfp->p_pshandle; 593 594 for (sep = mdb_list_next(&t->t_active); sep != NULL; 595 sep = mdb_list_next(sep)) { 596 if (sep->se_state == MDB_TGT_SPEC_ARMED) 597 (void) sep->se_ops->se_disarm(t, sep); 598 } 599 600 t->t_pshandle = P; 601 602 Prelease(vfp->p_pshandle, PRELEASE_CLEAR); 603 mdb_list_delete(&pt->p_vforkp, vfp); 604 mdb_free(vfp, sizeof (pt_vforkp_t)); 605 } 606 } 607 608 /*ARGSUSED*/ 609 static void 610 pt_fork(mdb_tgt_t *t, int vid, void *private) 611 { 612 struct ps_prochandle *P = t->t_pshandle; 613 const lwpstatus_t *psp = &Pstatus(P)->pr_lwp; 614 pt_data_t *pt = t->t_data; 615 mdb_sespec_t *sep; 616 617 int follow_parent = mdb.m_forkmode != MDB_FM_CHILD; 618 int is_vfork = (psp->pr_what == SYS_vfork || 619 (psp->pr_what == SYS_forksys && psp->pr_sysarg[0] == 2)); 620 621 struct ps_prochandle *C; 622 const lwpstatus_t *csp; 623 char sysname[32]; 624 int gcode; 625 char c; 626 627 mdb_dprintf(MDB_DBG_TGT, "parent %s: errno=%d rv1=%ld rv2=%ld\n", 628 proc_sysname(psp->pr_what, sysname, sizeof (sysname)), 629 psp->pr_errno, psp->pr_rval1, psp->pr_rval2); 630 631 if (psp->pr_errno != 0) { 632 (void) mdb_tgt_continue(t, NULL); 633 return; /* fork failed */ 634 } 635 636 /* 637 * If forkmode is ASK and stdout is a terminal, then ask the user to 638 * explicitly set the fork behavior for this particular fork. 639 */ 640 if (mdb.m_forkmode == MDB_FM_ASK && mdb.m_term != NULL) { 641 mdb_iob_printf(mdb.m_err, "%s: %s detected: follow (p)arent " 642 "or (c)hild? ", mdb.m_pname, sysname); 643 mdb_iob_flush(mdb.m_err); 644 645 while (IOP_READ(mdb.m_term, &c, sizeof (c)) == sizeof (c)) { 646 if (c == 'P' || c == 'p') { 647 mdb_iob_printf(mdb.m_err, "%c\n", c); 648 follow_parent = TRUE; 649 break; 650 } else if (c == 'C' || c == 'c') { 651 mdb_iob_printf(mdb.m_err, "%c\n", c); 652 follow_parent = FALSE; 653 break; 654 } 655 } 656 } 657 658 /* 659 * The parent is now stopped on exit from its fork call. We must now 660 * grab the child on its return from fork in order to manipulate it. 661 */ 662 if ((C = Pgrab(psp->pr_rval1, PGRAB_RETAIN, &gcode)) == NULL) { 663 warn("failed to grab forked child process %ld: %s\n", 664 psp->pr_rval1, Pgrab_error(gcode)); 665 return; /* just stop if we failed to grab the child */ 666 } 667 668 /* 669 * We may have grabbed the child and stopped it prematurely before it 670 * stopped on exit from fork. If so, wait up to 1 sec for it to settle. 671 */ 672 if (Pstatus(C)->pr_lwp.pr_why != PR_SYSEXIT) 673 (void) Pwait(C, MILLISEC); 674 675 csp = &Pstatus(C)->pr_lwp; 676 677 if (csp->pr_why != PR_SYSEXIT || 678 (csp->pr_what != SYS_vfork && csp->pr_what != SYS_forksys)) { 679 warn("forked child process %ld did not stop on exit from " 680 "fork as expected\n", psp->pr_rval1); 681 } 682 683 warn("target forked child process %ld (debugger following %s)\n", 684 psp->pr_rval1, follow_parent ? "parent" : "child"); 685 686 (void) Punsetflags(C, PR_ASYNC); /* require synchronous mode */ 687 (void) Psetflags(C, PR_BPTADJ); /* always adjust eip on x86 */ 688 (void) Prd_agent(C); /* initialize librtld_db */ 689 690 /* 691 * At the time pt_fork() is called, the target event engine has already 692 * disarmed the specifiers on the active list, clearing out events in 693 * the parent process. However, this means that events that change 694 * the address space (e.g. breakpoints) have not been effectively 695 * disarmed in the child since its address space reflects the state of 696 * the process at the time of fork when events were armed. We must 697 * therefore handle this as a special case and re-invoke the disarm 698 * callback of each active specifier to clean out the child process. 699 */ 700 if (!is_vfork) { 701 for (t->t_pshandle = C, sep = mdb_list_next(&t->t_active); 702 sep != NULL; sep = mdb_list_next(sep)) { 703 if (sep->se_state == MDB_TGT_SPEC_ACTIVE) 704 (void) sep->se_ops->se_disarm(t, sep); 705 } 706 707 t->t_pshandle = P; /* restore pshandle to parent */ 708 } 709 710 /* 711 * If we're following the parent process, we need to temporarily change 712 * t_pshandle to refer to the child handle C so that we can clear out 713 * all the events in the child prior to releasing it below. If we are 714 * tracing a vfork, we also need to explicitly wait for the child to 715 * exec, exit, or die before we can reset and continue the parent. We 716 * avoid having to deal with the vfork child forking again by clearing 717 * PR_FORK and setting PR_RLC; if it does fork it will effectively be 718 * released from our control and we will continue following the parent. 719 */ 720 if (follow_parent) { 721 if (is_vfork) { 722 mdb_tgt_status_t status; 723 724 ASSERT(psp->pr_flags & PR_VFORKP); 725 mdb_tgt_sespec_idle_all(t, EBUSY, FALSE); 726 t->t_pshandle = C; 727 728 (void) Psysexit(C, SYS_execve, TRUE); 729 730 (void) Punsetflags(C, PR_FORK | PR_KLC); 731 (void) Psetflags(C, PR_RLC); 732 733 do { 734 if (pt_setrun(t, &status, 0) == -1 || 735 status.st_state == MDB_TGT_UNDEAD || 736 status.st_state == MDB_TGT_LOST) 737 break; /* failure or process died */ 738 739 } while (csp->pr_why != PR_SYSEXIT || 740 csp->pr_errno != 0 || csp->pr_what != SYS_execve); 741 } else 742 t->t_pshandle = C; 743 } 744 745 /* 746 * If we are following the child, destroy any active libthread_db 747 * handle before we release the parent process. 748 */ 749 if (!follow_parent) { 750 PTL_DTOR(t); 751 pt->p_tdb_ops = NULL; 752 pt->p_ptl_ops = &proc_lwp_ops; 753 pt->p_ptl_hdl = NULL; 754 } 755 756 /* 757 * Idle all events to make sure the address space and tracing flags are 758 * restored, and then release the process we are not tracing. If we 759 * are following the child of a vfork, we push the parent's pshandle 760 * on to a list of vfork parents to be released when we exec or exit. 761 */ 762 if (is_vfork && !follow_parent) { 763 pt_vforkp_t *vfp = mdb_alloc(sizeof (pt_vforkp_t), UM_SLEEP); 764 765 ASSERT(psp->pr_flags & PR_VFORKP); 766 vfp->p_pshandle = P; 767 mdb_list_append(&pt->p_vforkp, vfp); 768 mdb_tgt_sespec_idle_all(t, EBUSY, FALSE); 769 770 } else { 771 mdb_tgt_sespec_idle_all(t, EBUSY, FALSE); 772 Prelease(t->t_pshandle, PRELEASE_CLEAR); 773 if (!follow_parent) 774 pt_release_parents(t); 775 } 776 777 /* 778 * Now that all the hard stuff is done, switch t_pshandle back to the 779 * process we are following and reset our events to the ACTIVE state. 780 * If we are following the child, reset the libthread_db handle as well 781 * as the rtld agent. 782 */ 783 if (follow_parent) 784 t->t_pshandle = P; 785 else { 786 t->t_pshandle = C; 787 pt->p_rtld = Prd_agent(C); 788 (void) Pobject_iter(t->t_pshandle, (proc_map_f *)thr_check, t); 789 } 790 791 (void) mdb_tgt_sespec_activate_all(t); 792 (void) mdb_tgt_continue(t, NULL); 793 } 794 795 /*ARGSUSED*/ 796 static void 797 pt_exec(mdb_tgt_t *t, int vid, void *private) 798 { 799 struct ps_prochandle *P = t->t_pshandle; 800 const pstatus_t *psp = Pstatus(P); 801 pt_data_t *pt = t->t_data; 802 int follow_exec = mdb.m_execmode == MDB_EM_FOLLOW; 803 pid_t pid = psp->pr_pid; 804 805 char execname[MAXPATHLEN]; 806 mdb_sespec_t *sep, *nsep; 807 mdb_io_t *io; 808 char c; 809 810 mdb_dprintf(MDB_DBG_TGT, "exit from %s: errno=%d\n", proc_sysname( 811 psp->pr_lwp.pr_what, execname, sizeof (execname)), 812 psp->pr_lwp.pr_errno); 813 814 if (psp->pr_lwp.pr_errno != 0) { 815 (void) mdb_tgt_continue(t, NULL); 816 return; /* exec failed */ 817 } 818 819 /* 820 * If execmode is ASK and stdout is a terminal, then ask the user to 821 * explicitly set the exec behavior for this particular exec. If 822 * Pstate() still shows PS_LOST, we are being called from pt_setrun() 823 * directly and therefore we must resume the terminal since it is still 824 * in the suspended state as far as tgt_continue() is concerned. 825 */ 826 if (mdb.m_execmode == MDB_EM_ASK && mdb.m_term != NULL) { 827 if (Pstate(P) == PS_LOST) 828 IOP_RESUME(mdb.m_term); 829 830 mdb_iob_printf(mdb.m_err, "%s: %s detected: (f)ollow new " 831 "program or (s)top? ", mdb.m_pname, execname); 832 mdb_iob_flush(mdb.m_err); 833 834 while (IOP_READ(mdb.m_term, &c, sizeof (c)) == sizeof (c)) { 835 if (c == 'F' || c == 'f') { 836 mdb_iob_printf(mdb.m_err, "%c\n", c); 837 follow_exec = TRUE; 838 break; 839 } else if (c == 'S' || c == 's') { 840 mdb_iob_printf(mdb.m_err, "%c\n", c); 841 follow_exec = FALSE; 842 break; 843 } 844 } 845 846 if (Pstate(P) == PS_LOST) 847 IOP_SUSPEND(mdb.m_term); 848 } 849 850 pt_release_parents(t); /* release any waiting vfork parents */ 851 pt_pre_detach(t, FALSE); /* remove our breakpoints and idle events */ 852 Preset_maps(P); /* libproc must delete mappings and symtabs */ 853 pt_close_aout(t); /* free pt symbol tables and GElf file data */ 854 855 /* 856 * If we lost control of the process across the exec and are not able 857 * to reopen it, we have no choice but to clear the matched event list 858 * and wait for the user to quit or otherwise release the process. 859 */ 860 if (Pstate(P) == PS_LOST && Preopen(P) == -1) { 861 int error = errno; 862 863 warn("lost control of PID %d due to exec of %s executable\n", 864 (int)pid, error == EOVERFLOW ? "64-bit" : "set-id"); 865 866 for (sep = t->t_matched; sep != T_SE_END; sep = nsep) { 867 nsep = sep->se_matched; 868 sep->se_matched = NULL; 869 mdb_tgt_sespec_rele(t, sep); 870 } 871 872 if (error != EOVERFLOW) 873 return; /* just stop if we exec'd a set-id executable */ 874 } 875 876 if (Pstate(P) != PS_LOST) { 877 if (Pexecname(P, execname, sizeof (execname)) == NULL) { 878 (void) mdb_iob_snprintf(execname, sizeof (execname), 879 "/proc/%d/object/a.out", (int)pid); 880 } 881 882 if (follow_exec == FALSE || psp->pr_dmodel == PR_MODEL_NATIVE) 883 warn("target performed exec of %s\n", execname); 884 885 io = mdb_fdio_create_path(NULL, execname, pt->p_oflags, 0); 886 if (io == NULL) { 887 warn("failed to open %s", execname); 888 warn("a.out symbol tables will not be available\n"); 889 } else if (pt_open_aout(t, io) == NULL) { 890 (void) mdb_dis_select(pt_disasm(NULL)); 891 mdb_io_destroy(io); 892 } else 893 (void) mdb_dis_select(pt_disasm(&pt->p_file->gf_ehdr)); 894 } 895 896 /* 897 * We reset our libthread_db state here, but deliberately do NOT call 898 * PTL_DTOR because we do not want to call libthread_db's td_ta_delete. 899 * This interface is hopelessly broken in that it writes to the process 900 * address space (which we do not want it to do after an exec) and it 901 * doesn't bother deallocating any of its storage anyway. 902 */ 903 pt->p_tdb_ops = NULL; 904 pt->p_ptl_ops = &proc_lwp_ops; 905 pt->p_ptl_hdl = NULL; 906 907 if (follow_exec && psp->pr_dmodel != PR_MODEL_NATIVE) { 908 const char *argv[3]; 909 char *state, *env; 910 char pidarg[16]; 911 size_t envlen; 912 913 if (realpath(getexecname(), execname) == NULL) { 914 warn("cannot follow PID %d -- failed to resolve " 915 "debugger pathname for re-exec", (int)pid); 916 return; 917 } 918 919 warn("restarting debugger to follow PID %d ...\n", (int)pid); 920 mdb_dprintf(MDB_DBG_TGT, "re-exec'ing %s\n", execname); 921 922 (void) mdb_snprintf(pidarg, sizeof (pidarg), "-p%d", (int)pid); 923 924 state = mdb_get_config(); 925 envlen = strlen(MDB_CONFIG_ENV_VAR) + 1 + strlen(state) + 1; 926 env = mdb_alloc(envlen, UM_SLEEP); 927 (void) snprintf(env, envlen, 928 "%s=%s", MDB_CONFIG_ENV_VAR, state); 929 930 (void) putenv(env); 931 932 argv[0] = mdb.m_pname; 933 argv[1] = pidarg; 934 argv[2] = NULL; 935 936 if (mdb.m_term != NULL) 937 IOP_SUSPEND(mdb.m_term); 938 939 Prelease(P, PRELEASE_CLEAR | PRELEASE_HANG); 940 (void) execv(execname, (char *const *)argv); 941 warn("failed to re-exec debugger"); 942 943 if (mdb.m_term != NULL) 944 IOP_RESUME(mdb.m_term); 945 946 t->t_pshandle = pt->p_idlehandle; 947 return; 948 } 949 950 pt_post_attach(t); /* install tracing flags and activate events */ 951 pt_activate_common(t); /* initialize librtld_db and libthread_db */ 952 953 if (psp->pr_dmodel != PR_MODEL_NATIVE && mdb.m_term != NULL) { 954 warn("loadable dcmds will not operate on non-native %d-bit " 955 "data model\n", psp->pr_dmodel == PR_MODEL_ILP32 ? 32 : 64); 956 warn("use ::release -a and then run mdb -p %d to restart " 957 "debugger\n", (int)pid); 958 } 959 960 if (follow_exec) 961 (void) mdb_tgt_continue(t, NULL); 962 } 963 964 static int 965 pt_setflags(mdb_tgt_t *t, int flags) 966 { 967 pt_data_t *pt = t->t_data; 968 969 if ((flags ^ t->t_flags) & MDB_TGT_F_RDWR) { 970 int mode = (flags & MDB_TGT_F_RDWR) ? O_RDWR : O_RDONLY; 971 mdb_io_t *io; 972 973 if (pt->p_fio == NULL) 974 return (set_errno(EMDB_NOEXEC)); 975 976 io = mdb_fdio_create_path(NULL, IOP_NAME(pt->p_fio), mode, 0); 977 978 if (io == NULL) 979 return (-1); /* errno is set for us */ 980 981 t->t_flags = (t->t_flags & ~MDB_TGT_F_RDWR) | 982 (flags & MDB_TGT_F_RDWR); 983 984 pt->p_fio = mdb_io_hold(io); 985 mdb_io_rele(pt->p_file->gf_io); 986 pt->p_file->gf_io = pt->p_fio; 987 } 988 989 if (flags & MDB_TGT_F_FORCE) { 990 t->t_flags |= MDB_TGT_F_FORCE; 991 pt->p_gflags |= PGRAB_FORCE; 992 } 993 994 return (0); 995 } 996 997 /*ARGSUSED*/ 998 static int 999 pt_frame(void *arglim, uintptr_t pc, uint_t argc, const long *argv, 1000 const mdb_tgt_gregset_t *gregs) 1001 { 1002 argc = MIN(argc, (uint_t)(uintptr_t)arglim); 1003 mdb_printf("%a(", pc); 1004 1005 if (argc != 0) { 1006 mdb_printf("%lr", *argv++); 1007 for (argc--; argc != 0; argc--) 1008 mdb_printf(", %lr", *argv++); 1009 } 1010 1011 mdb_printf(")\n"); 1012 return (0); 1013 } 1014 1015 static int 1016 pt_framev(void *arglim, uintptr_t pc, uint_t argc, const long *argv, 1017 const mdb_tgt_gregset_t *gregs) 1018 { 1019 argc = MIN(argc, (uint_t)(uintptr_t)arglim); 1020 #if defined(__i386) || defined(__amd64) 1021 mdb_printf("%0?lr %a(", gregs->gregs[R_FP], pc); 1022 #else 1023 mdb_printf("%0?lr %a(", gregs->gregs[R_SP], pc); 1024 #endif 1025 if (argc != 0) { 1026 mdb_printf("%lr", *argv++); 1027 for (argc--; argc != 0; argc--) 1028 mdb_printf(", %lr", *argv++); 1029 } 1030 1031 mdb_printf(")\n"); 1032 return (0); 1033 } 1034 1035 static int 1036 pt_framer(void *arglim, uintptr_t pc, uint_t argc, const long *argv, 1037 const mdb_tgt_gregset_t *gregs) 1038 { 1039 if (pt_frameregs(arglim, pc, argc, argv, gregs, pc == PC_FAKE) == -1) { 1040 /* 1041 * Use verbose format if register format is not supported. 1042 */ 1043 return (pt_framev(arglim, pc, argc, argv, gregs)); 1044 } 1045 1046 return (0); 1047 } 1048 1049 /*ARGSUSED*/ 1050 static int 1051 pt_stack_common(uintptr_t addr, uint_t flags, int argc, 1052 const mdb_arg_t *argv, mdb_tgt_stack_f *func, prgreg_t saved_pc) 1053 { 1054 void *arg = (void *)(uintptr_t)mdb.m_nargs; 1055 mdb_tgt_t *t = mdb.m_target; 1056 mdb_tgt_gregset_t gregs; 1057 1058 if (argc != 0) { 1059 if (argv->a_type == MDB_TYPE_CHAR || argc > 1) 1060 return (DCMD_USAGE); 1061 1062 if (argv->a_type == MDB_TYPE_STRING) 1063 arg = (void *)(uintptr_t)mdb_strtoull(argv->a_un.a_str); 1064 else 1065 arg = (void *)(uintptr_t)argv->a_un.a_val; 1066 } 1067 1068 if (t->t_pshandle == NULL || Pstate(t->t_pshandle) == PS_IDLE) { 1069 mdb_warn("no process active\n"); 1070 return (DCMD_ERR); 1071 } 1072 1073 /* 1074 * In the universe of sparcv7, sparcv9, ia32, and amd64 this code can be 1075 * common: <sys/procfs_isa.h> conveniently #defines R_FP to be the 1076 * appropriate register we need to set in order to perform a stack 1077 * traceback from a given frame address. 1078 */ 1079 if (flags & DCMD_ADDRSPEC) { 1080 bzero(&gregs, sizeof (gregs)); 1081 gregs.gregs[R_FP] = addr; 1082 #ifdef __sparc 1083 gregs.gregs[R_I7] = saved_pc; 1084 #endif /* __sparc */ 1085 } else if (PTL_GETREGS(t, PTL_TID(t), gregs.gregs) != 0) { 1086 mdb_warn("failed to get current register set"); 1087 return (DCMD_ERR); 1088 } 1089 1090 (void) mdb_tgt_stack_iter(t, &gregs, func, arg); 1091 return (DCMD_OK); 1092 } 1093 1094 static int 1095 pt_stack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1096 { 1097 return (pt_stack_common(addr, flags, argc, argv, pt_frame, 0)); 1098 } 1099 1100 static int 1101 pt_stackv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1102 { 1103 return (pt_stack_common(addr, flags, argc, argv, pt_framev, 0)); 1104 } 1105 1106 static int 1107 pt_stackr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1108 { 1109 /* 1110 * Force printing of first register window, by setting the 1111 * saved pc (%i7) to PC_FAKE. 1112 */ 1113 return (pt_stack_common(addr, flags, argc, argv, pt_framer, PC_FAKE)); 1114 } 1115 1116 /*ARGSUSED*/ 1117 static int 1118 pt_ignored(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1119 { 1120 struct ps_prochandle *P = mdb.m_target->t_pshandle; 1121 char buf[PRSIGBUFSZ]; 1122 1123 if ((flags & DCMD_ADDRSPEC) || argc != 0) 1124 return (DCMD_USAGE); 1125 1126 if (P == NULL) { 1127 mdb_warn("no process is currently active\n"); 1128 return (DCMD_ERR); 1129 } 1130 1131 mdb_printf("%s\n", proc_sigset2str(&Pstatus(P)->pr_sigtrace, " ", 1132 FALSE, buf, sizeof (buf))); 1133 1134 return (DCMD_OK); 1135 } 1136 1137 /*ARGSUSED*/ 1138 static int 1139 pt_lwpid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1140 { 1141 struct ps_prochandle *P = mdb.m_target->t_pshandle; 1142 1143 if ((flags & DCMD_ADDRSPEC) || argc != 0) 1144 return (DCMD_USAGE); 1145 1146 if (P == NULL) { 1147 mdb_warn("no process is currently active\n"); 1148 return (DCMD_ERR); 1149 } 1150 1151 mdb_printf("%d\n", Pstatus(P)->pr_lwp.pr_lwpid); 1152 return (DCMD_OK); 1153 } 1154 1155 static int 1156 pt_print_lwpid(int *n, const lwpstatus_t *psp) 1157 { 1158 struct ps_prochandle *P = mdb.m_target->t_pshandle; 1159 int nlwp = Pstatus(P)->pr_nlwp; 1160 1161 if (*n == nlwp - 2) 1162 mdb_printf("%d and ", (int)psp->pr_lwpid); 1163 else if (*n == nlwp - 1) 1164 mdb_printf("%d are", (int)psp->pr_lwpid); 1165 else 1166 mdb_printf("%d, ", (int)psp->pr_lwpid); 1167 1168 (*n)++; 1169 return (0); 1170 } 1171 1172 /*ARGSUSED*/ 1173 static int 1174 pt_lwpids(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1175 { 1176 struct ps_prochandle *P = mdb.m_target->t_pshandle; 1177 int n = 0; 1178 1179 if (P == NULL) { 1180 mdb_warn("no process is currently active\n"); 1181 return (DCMD_ERR); 1182 } 1183 1184 switch (Pstatus(P)->pr_nlwp) { 1185 case 0: 1186 mdb_printf("no lwps are"); 1187 break; 1188 case 1: 1189 mdb_printf("lwpid %d is the only lwp", 1190 Pstatus(P)->pr_lwp.pr_lwpid); 1191 break; 1192 default: 1193 mdb_printf("lwpids "); 1194 (void) Plwp_iter(P, (proc_lwp_f *)pt_print_lwpid, &n); 1195 } 1196 1197 switch (Pstate(P)) { 1198 case PS_DEAD: 1199 mdb_printf(" in core of process %d.\n", Pstatus(P)->pr_pid); 1200 break; 1201 case PS_IDLE: 1202 mdb_printf(" in idle target.\n"); 1203 break; 1204 default: 1205 mdb_printf(" in process %d.\n", (int)Pstatus(P)->pr_pid); 1206 break; 1207 } 1208 1209 return (DCMD_OK); 1210 } 1211 1212 /*ARGSUSED*/ 1213 static int 1214 pt_ignore(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1215 { 1216 pt_data_t *pt = mdb.m_target->t_data; 1217 1218 if (!(flags & DCMD_ADDRSPEC) || argc != 0) 1219 return (DCMD_USAGE); 1220 1221 if (addr < 1 || addr > pt->p_maxsig) { 1222 mdb_warn("invalid signal number -- 0t%lu\n", addr); 1223 return (DCMD_ERR); 1224 } 1225 1226 (void) mdb_tgt_vespec_iter(mdb.m_target, pt_ignore_sig, (void *)addr); 1227 return (DCMD_OK); 1228 } 1229 1230 /*ARGSUSED*/ 1231 static int 1232 pt_attach(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1233 { 1234 mdb_tgt_t *t = mdb.m_target; 1235 pt_data_t *pt = t->t_data; 1236 int state, perr; 1237 1238 if (!(flags & DCMD_ADDRSPEC) && argc == 0) 1239 return (DCMD_USAGE); 1240 1241 if (((flags & DCMD_ADDRSPEC) && argc != 0) || argc > 1 || 1242 (argc != 0 && argv->a_type != MDB_TYPE_STRING)) 1243 return (DCMD_USAGE); 1244 1245 if (t->t_pshandle != NULL && Pstate(t->t_pshandle) != PS_IDLE) { 1246 mdb_warn("debugger is already attached to a %s\n", 1247 (Pstate(t->t_pshandle) == PS_DEAD) ? "core" : "process"); 1248 return (DCMD_ERR); 1249 } 1250 1251 if (pt->p_fio == NULL) { 1252 mdb_warn("attach requires executable to be specified on " 1253 "command-line (or use -p)\n"); 1254 return (DCMD_ERR); 1255 } 1256 1257 if (flags & DCMD_ADDRSPEC) 1258 t->t_pshandle = Pgrab((pid_t)addr, pt->p_gflags, &perr); 1259 else 1260 t->t_pshandle = proc_arg_grab(argv->a_un.a_str, 1261 PR_ARG_ANY, pt->p_gflags, &perr); 1262 1263 if (t->t_pshandle == NULL) { 1264 t->t_pshandle = pt->p_idlehandle; 1265 mdb_warn("cannot attach: %s\n", Pgrab_error(perr)); 1266 return (DCMD_ERR); 1267 } 1268 1269 state = Pstate(t->t_pshandle); 1270 if (state != PS_DEAD && state != PS_IDLE) { 1271 (void) Punsetflags(t->t_pshandle, PR_KLC); 1272 (void) Psetflags(t->t_pshandle, PR_RLC); 1273 pt_post_attach(t); 1274 pt_activate_common(t); 1275 } 1276 1277 (void) mdb_tgt_status(t, &t->t_status); 1278 mdb_module_load_all(0); 1279 return (DCMD_OK); 1280 } 1281 1282 static int 1283 pt_regstatus(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1284 { 1285 mdb_tgt_t *t = mdb.m_target; 1286 1287 if (t->t_pshandle != NULL) { 1288 const pstatus_t *psp = Pstatus(t->t_pshandle); 1289 int cursig = psp->pr_lwp.pr_cursig; 1290 char signame[SIG2STR_MAX]; 1291 int state = Pstate(t->t_pshandle); 1292 1293 if (state != PS_DEAD && state != PS_IDLE) 1294 mdb_printf("process id = %d\n", psp->pr_pid); 1295 else 1296 mdb_printf("no process\n"); 1297 1298 if (cursig != 0 && sig2str(cursig, signame) == 0) 1299 mdb_printf("SIG%s: %s\n", signame, strsignal(cursig)); 1300 } 1301 1302 return (pt_regs(addr, flags, argc, argv)); 1303 } 1304 1305 static int 1306 pt_findstack(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv) 1307 { 1308 mdb_tgt_t *t = mdb.m_target; 1309 mdb_tgt_gregset_t gregs; 1310 int showargs = 0; 1311 int count; 1312 uintptr_t pc, sp; 1313 1314 if (!(flags & DCMD_ADDRSPEC)) 1315 return (DCMD_USAGE); 1316 1317 count = mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &showargs, 1318 NULL); 1319 argc -= count; 1320 argv += count; 1321 1322 if (argc > 1 || (argc == 1 && argv->a_type != MDB_TYPE_STRING)) 1323 return (DCMD_USAGE); 1324 1325 if (PTL_GETREGS(t, tid, gregs.gregs) != 0) { 1326 mdb_warn("failed to get register set for thread %p", tid); 1327 return (DCMD_ERR); 1328 } 1329 1330 pc = gregs.gregs[R_PC]; 1331 #if defined(__i386) || defined(__amd64) 1332 sp = gregs.gregs[R_FP]; 1333 #else 1334 sp = gregs.gregs[R_SP]; 1335 #endif 1336 mdb_printf("stack pointer for thread %p: %p\n", tid, sp); 1337 if (pc != 0) 1338 mdb_printf("[ %0?lr %a() ]\n", sp, pc); 1339 1340 (void) mdb_inc_indent(2); 1341 mdb_set_dot(sp); 1342 1343 if (argc == 1) 1344 (void) mdb_eval(argv->a_un.a_str); 1345 else if (showargs) 1346 (void) mdb_eval("<.$C"); 1347 else 1348 (void) mdb_eval("<.$C0"); 1349 1350 (void) mdb_dec_indent(2); 1351 return (DCMD_OK); 1352 } 1353 1354 /*ARGSUSED*/ 1355 static int 1356 pt_gcore(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1357 { 1358 mdb_tgt_t *t = mdb.m_target; 1359 char *prefix = "core"; 1360 char *content_str = NULL; 1361 core_content_t content = CC_CONTENT_DEFAULT; 1362 size_t size; 1363 char *fname; 1364 pid_t pid; 1365 1366 if (flags & DCMD_ADDRSPEC) 1367 return (DCMD_USAGE); 1368 1369 if (mdb_getopts(argc, argv, 1370 'o', MDB_OPT_STR, &prefix, 1371 'c', MDB_OPT_STR, &content_str, NULL) != argc) 1372 return (DCMD_USAGE); 1373 1374 if (content_str != NULL && 1375 (proc_str2content(content_str, &content) != 0 || 1376 content == CC_CONTENT_INVALID)) { 1377 mdb_warn("invalid content string '%s'\n", content_str); 1378 return (DCMD_ERR); 1379 } 1380 1381 if (t->t_pshandle == NULL) { 1382 mdb_warn("no process active\n"); 1383 return (DCMD_ERR); 1384 } 1385 1386 pid = Pstatus(t->t_pshandle)->pr_pid; 1387 size = 1 + mdb_snprintf(NULL, 0, "%s.%d", prefix, (int)pid); 1388 fname = mdb_alloc(size, UM_SLEEP | UM_GC); 1389 (void) mdb_snprintf(fname, size, "%s.%d", prefix, (int)pid); 1390 1391 if (Pgcore(t->t_pshandle, fname, content) != 0) { 1392 /* 1393 * Short writes during dumping are specifically described by 1394 * EBADE, just as ZFS uses this otherwise-unused code for 1395 * checksum errors. Translate to and mdb errno. 1396 */ 1397 if (errno == EBADE) 1398 (void) set_errno(EMDB_SHORTWRITE); 1399 mdb_warn("couldn't dump core"); 1400 return (DCMD_ERR); 1401 } 1402 1403 mdb_warn("%s dumped\n", fname); 1404 1405 return (DCMD_OK); 1406 } 1407 1408 /*ARGSUSED*/ 1409 static int 1410 pt_kill(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1411 { 1412 mdb_tgt_t *t = mdb.m_target; 1413 pt_data_t *pt = t->t_data; 1414 int state; 1415 1416 if ((flags & DCMD_ADDRSPEC) || argc != 0) 1417 return (DCMD_USAGE); 1418 1419 if (t->t_pshandle != NULL && 1420 (state = Pstate(t->t_pshandle)) != PS_DEAD && state != PS_IDLE) { 1421 mdb_warn("victim process PID %d forcibly terminated\n", 1422 (int)Pstatus(t->t_pshandle)->pr_pid); 1423 pt_pre_detach(t, TRUE); 1424 pt_release_parents(t); 1425 Prelease(t->t_pshandle, PRELEASE_KILL); 1426 t->t_pshandle = pt->p_idlehandle; 1427 (void) mdb_tgt_status(t, &t->t_status); 1428 mdb.m_flags &= ~(MDB_FL_VCREATE | MDB_FL_JOBCTL); 1429 } else 1430 mdb_warn("no victim process is currently under control\n"); 1431 1432 return (DCMD_OK); 1433 } 1434 1435 /*ARGSUSED*/ 1436 static int 1437 pt_detach(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1438 { 1439 mdb_tgt_t *t = mdb.m_target; 1440 pt_data_t *pt = t->t_data; 1441 int rflags = pt->p_rflags; 1442 1443 if (argc != 0 && argv->a_type == MDB_TYPE_STRING && 1444 strcmp(argv->a_un.a_str, "-a") == 0) { 1445 rflags = PRELEASE_HANG | PRELEASE_CLEAR; 1446 argv++; 1447 argc--; 1448 } 1449 1450 if ((flags & DCMD_ADDRSPEC) || argc != 0) 1451 return (DCMD_USAGE); 1452 1453 if (t->t_pshandle == NULL || Pstate(t->t_pshandle) == PS_IDLE) { 1454 mdb_warn("debugger is not currently attached to a process " 1455 "or core file\n"); 1456 return (DCMD_ERR); 1457 } 1458 1459 pt_pre_detach(t, TRUE); 1460 pt_release_parents(t); 1461 Prelease(t->t_pshandle, rflags); 1462 t->t_pshandle = pt->p_idlehandle; 1463 (void) mdb_tgt_status(t, &t->t_status); 1464 mdb.m_flags &= ~(MDB_FL_VCREATE | MDB_FL_JOBCTL); 1465 1466 return (DCMD_OK); 1467 } 1468 1469 static uintmax_t 1470 reg_disc_get(const mdb_var_t *v) 1471 { 1472 mdb_tgt_t *t = MDB_NV_COOKIE(v); 1473 mdb_tgt_tid_t tid = PTL_TID(t); 1474 mdb_tgt_reg_t r = 0; 1475 1476 if (tid != (mdb_tgt_tid_t)-1L) 1477 (void) mdb_tgt_getareg(t, tid, mdb_nv_get_name(v), &r); 1478 1479 return (r); 1480 } 1481 1482 static void 1483 reg_disc_set(mdb_var_t *v, uintmax_t r) 1484 { 1485 mdb_tgt_t *t = MDB_NV_COOKIE(v); 1486 mdb_tgt_tid_t tid = PTL_TID(t); 1487 1488 if (tid != (mdb_tgt_tid_t)-1L && mdb_tgt_putareg(t, tid, 1489 mdb_nv_get_name(v), r) == -1) 1490 mdb_warn("failed to modify %%%s register", mdb_nv_get_name(v)); 1491 } 1492 1493 static void 1494 pt_print_reason(const lwpstatus_t *psp) 1495 { 1496 char name[SIG2STR_MAX + 4]; /* enough for SIG+name+\0, syscall or flt */ 1497 const char *desc; 1498 1499 switch (psp->pr_why) { 1500 case PR_REQUESTED: 1501 mdb_printf("stopped by debugger"); 1502 break; 1503 case PR_SIGNALLED: 1504 mdb_printf("stopped on %s (%s)", proc_signame(psp->pr_what, 1505 name, sizeof (name)), strsignal(psp->pr_what)); 1506 break; 1507 case PR_SYSENTRY: 1508 mdb_printf("stopped on entry to %s system call", 1509 proc_sysname(psp->pr_what, name, sizeof (name))); 1510 break; 1511 case PR_SYSEXIT: 1512 mdb_printf("stopped on exit from %s system call", 1513 proc_sysname(psp->pr_what, name, sizeof (name))); 1514 break; 1515 case PR_JOBCONTROL: 1516 mdb_printf("stopped by job control"); 1517 break; 1518 case PR_FAULTED: 1519 if (psp->pr_what == FLTBPT) { 1520 mdb_printf("stopped on a breakpoint"); 1521 } else if (psp->pr_what == FLTWATCH) { 1522 switch (psp->pr_info.si_code) { 1523 case TRAP_RWATCH: 1524 desc = "read"; 1525 break; 1526 case TRAP_WWATCH: 1527 desc = "write"; 1528 break; 1529 case TRAP_XWATCH: 1530 desc = "execute"; 1531 break; 1532 default: 1533 desc = "unknown"; 1534 } 1535 mdb_printf("stopped %s a watchpoint (%s access to %p)", 1536 psp->pr_info.si_trapafter ? "after" : "on", 1537 desc, psp->pr_info.si_addr); 1538 } else if (psp->pr_what == FLTTRACE) { 1539 mdb_printf("stopped after a single-step"); 1540 } else { 1541 mdb_printf("stopped on a %s fault", 1542 proc_fltname(psp->pr_what, name, sizeof (name))); 1543 } 1544 break; 1545 case PR_SUSPENDED: 1546 case PR_CHECKPOINT: 1547 mdb_printf("suspended by the kernel"); 1548 break; 1549 default: 1550 mdb_printf("stopped for unknown reason (%d/%d)", 1551 psp->pr_why, psp->pr_what); 1552 } 1553 } 1554 1555 /*ARGSUSED*/ 1556 static int 1557 pt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1558 { 1559 mdb_tgt_t *t = mdb.m_target; 1560 struct ps_prochandle *P = t->t_pshandle; 1561 pt_data_t *pt = t->t_data; 1562 1563 if (P != NULL) { 1564 const psinfo_t *pip = Ppsinfo(P); 1565 const pstatus_t *psp = Pstatus(P); 1566 int cursig = 0, bits = 0, coredump = 0; 1567 int state; 1568 GElf_Sym sym; 1569 uintptr_t panicstr; 1570 char *panicbuf = mdb_alloc(1024, UM_SLEEP); 1571 const siginfo_t *sip = &(psp->pr_lwp.pr_info); 1572 1573 char execname[MAXPATHLEN], buf[BUFSIZ]; 1574 char signame[SIG2STR_MAX + 4]; /* enough for SIG+name+\0 */ 1575 1576 mdb_tgt_spec_desc_t desc; 1577 mdb_sespec_t *sep; 1578 1579 struct utsname uts; 1580 prcred_t cred; 1581 psinfo_t pi; 1582 1583 (void) strcpy(uts.nodename, "unknown machine"); 1584 (void) Puname(P, &uts); 1585 1586 if (pip != NULL) { 1587 bcopy(pip, &pi, sizeof (psinfo_t)); 1588 proc_unctrl_psinfo(&pi); 1589 } else 1590 bzero(&pi, sizeof (psinfo_t)); 1591 1592 bits = pi.pr_dmodel == PR_MODEL_ILP32 ? 32 : 64; 1593 1594 state = Pstate(P); 1595 if (psp != NULL && state != PS_UNDEAD && state != PS_IDLE) 1596 cursig = psp->pr_lwp.pr_cursig; 1597 1598 if (state == PS_DEAD && pip != NULL) { 1599 mdb_printf("debugging core file of %s (%d-bit) " 1600 "from %s\n", pi.pr_fname, bits, uts.nodename); 1601 1602 } else if (state == PS_DEAD) { 1603 mdb_printf("debugging core file\n"); 1604 1605 } else if (state == PS_IDLE) { 1606 const GElf_Ehdr *ehp = &pt->p_file->gf_ehdr; 1607 1608 mdb_printf("debugging %s file (%d-bit)\n", 1609 ehp->e_type == ET_EXEC ? "executable" : "object", 1610 ehp->e_ident[EI_CLASS] == ELFCLASS32 ? 32 : 64); 1611 1612 } else if (state == PS_UNDEAD && pi.pr_pid == 0) { 1613 mdb_printf("debugging defunct process\n"); 1614 1615 } else { 1616 mdb_printf("debugging PID %d (%d-bit)\n", 1617 pi.pr_pid, bits); 1618 } 1619 1620 if (Pexecname(P, execname, sizeof (execname)) != NULL) 1621 mdb_printf("file: %s\n", execname); 1622 1623 if (pip != NULL && state == PS_DEAD) 1624 mdb_printf("initial argv: %s\n", pi.pr_psargs); 1625 1626 if (state != PS_UNDEAD && state != PS_IDLE) { 1627 mdb_printf("threading model: "); 1628 if (pt->p_ptl_ops == &proc_lwp_ops) 1629 mdb_printf("raw lwps\n"); 1630 else 1631 mdb_printf("native threads\n"); 1632 } 1633 1634 mdb_printf("status: "); 1635 switch (state) { 1636 case PS_RUN: 1637 ASSERT(!(psp->pr_flags & PR_STOPPED)); 1638 mdb_printf("process is running"); 1639 if (psp->pr_flags & PR_DSTOP) 1640 mdb_printf(", debugger stop directive pending"); 1641 mdb_printf("\n"); 1642 break; 1643 1644 case PS_STOP: 1645 ASSERT(psp->pr_flags & PR_STOPPED); 1646 pt_print_reason(&psp->pr_lwp); 1647 1648 if (psp->pr_flags & PR_DSTOP) 1649 mdb_printf(", debugger stop directive pending"); 1650 if (psp->pr_flags & PR_ASLEEP) 1651 mdb_printf(", sleeping in %s system call", 1652 proc_sysname(psp->pr_lwp.pr_syscall, 1653 signame, sizeof (signame))); 1654 1655 mdb_printf("\n"); 1656 1657 for (sep = t->t_matched; sep != T_SE_END; 1658 sep = sep->se_matched) { 1659 mdb_printf("event: %s\n", sep->se_ops->se_info( 1660 t, sep, mdb_list_next(&sep->se_velist), 1661 &desc, buf, sizeof (buf))); 1662 } 1663 break; 1664 1665 case PS_LOST: 1666 mdb_printf("debugger lost control of process\n"); 1667 break; 1668 1669 case PS_UNDEAD: 1670 coredump = WIFSIGNALED(pi.pr_wstat) && 1671 WCOREDUMP(pi.pr_wstat); 1672 /*FALLTHRU*/ 1673 1674 case PS_DEAD: 1675 if (cursig == 0 && WIFSIGNALED(pi.pr_wstat)) 1676 cursig = WTERMSIG(pi.pr_wstat); 1677 /* 1678 * We can only use pr_wstat == 0 as a test for gcore if 1679 * an NT_PRCRED note is present; these features were 1680 * added at the same time in Solaris 8. 1681 */ 1682 if (pi.pr_wstat == 0 && Pstate(P) == PS_DEAD && 1683 Pcred(P, &cred, 1) == 0) { 1684 mdb_printf("process core file generated " 1685 "with gcore(1)\n"); 1686 } else if (cursig != 0) { 1687 mdb_printf("process terminated by %s (%s)", 1688 proc_signame(cursig, signame, 1689 sizeof (signame)), strsignal(cursig)); 1690 1691 if (sip->si_signo != 0 && SI_FROMUSER(sip) && 1692 sip->si_pid != 0) { 1693 mdb_printf(", pid=%d uid=%u", 1694 (int)sip->si_pid, sip->si_uid); 1695 if (sip->si_code != 0) { 1696 mdb_printf(" code=%d", 1697 sip->si_code); 1698 } 1699 } else { 1700 switch (sip->si_signo) { 1701 case SIGILL: 1702 case SIGTRAP: 1703 case SIGFPE: 1704 case SIGSEGV: 1705 case SIGBUS: 1706 case SIGEMT: 1707 mdb_printf(", addr=%p", 1708 sip->si_addr); 1709 default: 1710 break; 1711 } 1712 } 1713 1714 if (coredump) 1715 mdb_printf(" - core file dumped"); 1716 mdb_printf("\n"); 1717 } else { 1718 mdb_printf("process terminated with exit " 1719 "status %d\n", WEXITSTATUS(pi.pr_wstat)); 1720 } 1721 1722 if (Plookup_by_name(t->t_pshandle, "libc.so", 1723 "panicstr", &sym) == 0 && 1724 Pread(t->t_pshandle, &panicstr, sizeof (panicstr), 1725 sym.st_value) == sizeof (panicstr) && 1726 Pread_string(t->t_pshandle, panicbuf, 1727 sizeof (panicbuf), panicstr) > 0) { 1728 mdb_printf("panic message: %s", 1729 panicbuf); 1730 } 1731 1732 1733 break; 1734 1735 case PS_IDLE: 1736 mdb_printf("idle\n"); 1737 break; 1738 1739 default: 1740 mdb_printf("unknown libproc Pstate: %d\n", Pstate(P)); 1741 } 1742 mdb_free(panicbuf, 1024); 1743 1744 } else if (pt->p_file != NULL) { 1745 const GElf_Ehdr *ehp = &pt->p_file->gf_ehdr; 1746 1747 mdb_printf("debugging %s file (%d-bit)\n", 1748 ehp->e_type == ET_EXEC ? "executable" : "object", 1749 ehp->e_ident[EI_CLASS] == ELFCLASS32 ? 32 : 64); 1750 mdb_printf("executable file: %s\n", IOP_NAME(pt->p_fio)); 1751 mdb_printf("status: idle\n"); 1752 } 1753 1754 return (DCMD_OK); 1755 } 1756 1757 static int 1758 pt_tls(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv) 1759 { 1760 const char *name; 1761 const char *object; 1762 GElf_Sym sym; 1763 mdb_syminfo_t si; 1764 mdb_tgt_t *t = mdb.m_target; 1765 1766 if (!(flags & DCMD_ADDRSPEC) || argc > 1) 1767 return (DCMD_USAGE); 1768 1769 if (argc == 0) { 1770 psaddr_t b; 1771 1772 if (tlsbase(t, tid, PR_LMID_EVERY, MDB_TGT_OBJ_EXEC, &b) != 0) { 1773 mdb_warn("failed to lookup tlsbase for %r", tid); 1774 return (DCMD_ERR); 1775 } 1776 1777 mdb_printf("%lr\n", b); 1778 mdb_set_dot(b); 1779 1780 return (DCMD_OK); 1781 } 1782 1783 name = argv[0].a_un.a_str; 1784 object = MDB_TGT_OBJ_EVERY; 1785 1786 if (pt_lookup_by_name_thr(t, object, name, &sym, &si, tid) != 0) { 1787 mdb_warn("failed to lookup %s", name); 1788 return (DCMD_ABORT); /* avoid repeated failure */ 1789 } 1790 1791 if (GELF_ST_TYPE(sym.st_info) != STT_TLS && DCMD_HDRSPEC(flags)) 1792 mdb_warn("%s does not refer to thread local storage\n", name); 1793 1794 mdb_printf("%llr\n", sym.st_value); 1795 mdb_set_dot(sym.st_value); 1796 1797 return (DCMD_OK); 1798 } 1799 1800 /*ARGSUSED*/ 1801 static int 1802 pt_tmodel(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1803 { 1804 mdb_tgt_t *t = mdb.m_target; 1805 pt_data_t *pt = t->t_data; 1806 const pt_ptl_ops_t *ptl_ops; 1807 1808 if (argc != 1 || argv->a_type != MDB_TYPE_STRING) 1809 return (DCMD_USAGE); 1810 1811 if (strcmp(argv->a_un.a_str, "thread") == 0) 1812 ptl_ops = &proc_tdb_ops; 1813 else if (strcmp(argv->a_un.a_str, "lwp") == 0) 1814 ptl_ops = &proc_lwp_ops; 1815 else 1816 return (DCMD_USAGE); 1817 1818 if (t->t_pshandle != NULL && pt->p_ptl_ops != ptl_ops) { 1819 PTL_DTOR(t); 1820 pt->p_tdb_ops = NULL; 1821 pt->p_ptl_ops = &proc_lwp_ops; 1822 pt->p_ptl_hdl = NULL; 1823 1824 if (ptl_ops == &proc_tdb_ops) { 1825 (void) Pobject_iter(t->t_pshandle, (proc_map_f *) 1826 thr_check, t); 1827 } 1828 } 1829 1830 (void) mdb_tgt_status(t, &t->t_status); 1831 return (DCMD_OK); 1832 } 1833 1834 static const char * 1835 env_match(const char *cmp, const char *nameval) 1836 { 1837 const char *loc; 1838 size_t cmplen = strlen(cmp); 1839 1840 loc = strchr(nameval, '='); 1841 if (loc != NULL && (loc - nameval) == cmplen && 1842 strncmp(nameval, cmp, cmplen) == 0) { 1843 return (loc + 1); 1844 } 1845 1846 return (NULL); 1847 } 1848 1849 /*ARGSUSED*/ 1850 static int 1851 print_env(void *data, struct ps_prochandle *P, uintptr_t addr, 1852 const char *nameval) 1853 { 1854 const char *value; 1855 1856 if (nameval == NULL) { 1857 mdb_printf("<0x%p>\n", addr); 1858 } else { 1859 if (data == NULL) 1860 mdb_printf("%s\n", nameval); 1861 else if ((value = env_match(data, nameval)) != NULL) 1862 mdb_printf("%s\n", value); 1863 } 1864 1865 return (0); 1866 } 1867 1868 /*ARGSUSED*/ 1869 static int 1870 pt_getenv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1871 { 1872 mdb_tgt_t *t = mdb.m_target; 1873 pt_data_t *pt = t->t_data; 1874 int i; 1875 uint_t opt_t = 0; 1876 mdb_var_t *v; 1877 1878 i = mdb_getopts(argc, argv, 1879 't', MDB_OPT_SETBITS, TRUE, &opt_t, NULL); 1880 1881 argc -= i; 1882 argv += i; 1883 1884 if ((flags & DCMD_ADDRSPEC) || argc > 1) 1885 return (DCMD_USAGE); 1886 1887 if (argc == 1 && argv->a_type != MDB_TYPE_STRING) 1888 return (DCMD_USAGE); 1889 1890 if (opt_t && t->t_pshandle == NULL) { 1891 mdb_warn("no process active\n"); 1892 return (DCMD_ERR); 1893 } 1894 1895 if (opt_t && (Pstate(t->t_pshandle) == PS_IDLE || 1896 Pstate(t->t_pshandle) == PS_UNDEAD)) { 1897 mdb_warn("-t option requires target to be running\n"); 1898 return (DCMD_ERR); 1899 } 1900 1901 if (opt_t != 0) { 1902 if (Penv_iter(t->t_pshandle, print_env, 1903 argc == 0 ? NULL : (void *)argv->a_un.a_str) != 0) 1904 return (DCMD_ERR); 1905 } else if (argc == 1) { 1906 if ((v = mdb_nv_lookup(&pt->p_env, argv->a_un.a_str)) == NULL) 1907 return (DCMD_ERR); 1908 1909 ASSERT(strchr(mdb_nv_get_cookie(v), '=') != NULL); 1910 mdb_printf("%s\n", strchr(mdb_nv_get_cookie(v), '=') + 1); 1911 } else { 1912 1913 mdb_nv_rewind(&pt->p_env); 1914 while ((v = mdb_nv_advance(&pt->p_env)) != NULL) 1915 mdb_printf("%s\n", mdb_nv_get_cookie(v)); 1916 } 1917 1918 return (DCMD_OK); 1919 } 1920 1921 /* 1922 * Function to set a variable in the internal environment, which is used when 1923 * creating new processes. Note that it is possible that 'nameval' can refer to 1924 * read-only memory, if mdb calls putenv() on an existing value before calling 1925 * this function. While we should avoid this situation, this function is 1926 * designed to be robust in the face of such changes. 1927 */ 1928 static void 1929 pt_env_set(pt_data_t *pt, const char *nameval) 1930 { 1931 mdb_var_t *v; 1932 char *equals, *val; 1933 const char *name; 1934 size_t len; 1935 1936 if ((equals = strchr(nameval, '=')) != NULL) { 1937 val = strdup(nameval); 1938 equals = val + (equals - nameval); 1939 } else { 1940 /* 1941 * nameval doesn't contain an equals character. Convert this to 1942 * be 'nameval='. 1943 */ 1944 len = strlen(nameval); 1945 val = mdb_alloc(len + 2, UM_SLEEP); 1946 (void) mdb_snprintf(val, len + 2, "%s=", nameval); 1947 equals = val + len; 1948 } 1949 1950 /* temporary truncate the string for lookup/insert */ 1951 *equals = '\0'; 1952 v = mdb_nv_lookup(&pt->p_env, val); 1953 1954 if (v != NULL) { 1955 char *old = mdb_nv_get_cookie(v); 1956 mdb_free(old, strlen(old) + 1); 1957 name = mdb_nv_get_name(v); 1958 } else { 1959 /* 1960 * The environment is created using MDB_NV_EXTNAME, so we must 1961 * provide external storage for the variable names. 1962 */ 1963 name = strdup(val); 1964 } 1965 1966 *equals = '='; 1967 1968 (void) mdb_nv_insert(&pt->p_env, name, NULL, (uintptr_t)val, 1969 MDB_NV_EXTNAME); 1970 1971 if (equals) 1972 *equals = '='; 1973 } 1974 1975 /* 1976 * Clears the internal environment. 1977 */ 1978 static void 1979 pt_env_clear(pt_data_t *pt) 1980 { 1981 mdb_var_t *v; 1982 char *val, *name; 1983 1984 mdb_nv_rewind(&pt->p_env); 1985 while ((v = mdb_nv_advance(&pt->p_env)) != NULL) { 1986 1987 name = (char *)mdb_nv_get_name(v); 1988 val = mdb_nv_get_cookie(v); 1989 1990 mdb_nv_remove(&pt->p_env, v); 1991 1992 mdb_free(name, strlen(name) + 1); 1993 mdb_free(val, strlen(val) + 1); 1994 } 1995 } 1996 1997 /*ARGSUSED*/ 1998 static int 1999 pt_setenv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 2000 { 2001 mdb_tgt_t *t = mdb.m_target; 2002 pt_data_t *pt = t->t_data; 2003 char *nameval; 2004 size_t len; 2005 int alloc; 2006 2007 if ((flags & DCMD_ADDRSPEC) || argc == 0 || argc > 2) 2008 return (DCMD_USAGE); 2009 2010 if ((argc > 0 && argv[0].a_type != MDB_TYPE_STRING) || 2011 (argc > 1 && argv[1].a_type != MDB_TYPE_STRING)) 2012 return (DCMD_USAGE); 2013 2014 if (t->t_pshandle == NULL) { 2015 mdb_warn("no process active\n"); 2016 return (DCMD_ERR); 2017 } 2018 2019 /* 2020 * If the process is in some sort of running state, warn the user that 2021 * changes won't immediately take effect. 2022 */ 2023 if (Pstate(t->t_pshandle) == PS_RUN || 2024 Pstate(t->t_pshandle) == PS_STOP) { 2025 mdb_warn("warning: changes will not take effect until process" 2026 " is restarted\n"); 2027 } 2028 2029 /* 2030 * We allow two forms of operation. The first is the usual "name=value" 2031 * parameter. We also allow the user to specify two arguments, where 2032 * the first is the name of the variable, and the second is the value. 2033 */ 2034 alloc = 0; 2035 if (argc == 1) { 2036 nameval = (char *)argv->a_un.a_str; 2037 } else { 2038 len = strlen(argv[0].a_un.a_str) + 2039 strlen(argv[1].a_un.a_str) + 2; 2040 nameval = mdb_alloc(len, UM_SLEEP); 2041 (void) mdb_snprintf(nameval, len, "%s=%s", argv[0].a_un.a_str, 2042 argv[1].a_un.a_str); 2043 alloc = 1; 2044 } 2045 2046 pt_env_set(pt, nameval); 2047 2048 if (alloc) 2049 mdb_free(nameval, strlen(nameval) + 1); 2050 2051 return (DCMD_OK); 2052 } 2053 2054 /*ARGSUSED*/ 2055 static int 2056 pt_unsetenv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 2057 { 2058 mdb_tgt_t *t = mdb.m_target; 2059 pt_data_t *pt = t->t_data; 2060 mdb_var_t *v; 2061 char *value, *name; 2062 2063 if ((flags & DCMD_ADDRSPEC) || argc > 1) 2064 return (DCMD_USAGE); 2065 2066 if (argc == 1 && argv->a_type != MDB_TYPE_STRING) 2067 return (DCMD_USAGE); 2068 2069 if (t->t_pshandle == NULL) { 2070 mdb_warn("no process active\n"); 2071 return (DCMD_ERR); 2072 } 2073 2074 /* 2075 * If the process is in some sort of running state, warn the user that 2076 * changes won't immediately take effect. 2077 */ 2078 if (Pstate(t->t_pshandle) == PS_RUN || 2079 Pstate(t->t_pshandle) == PS_STOP) { 2080 mdb_warn("warning: changes will not take effect until process" 2081 " is restarted\n"); 2082 } 2083 2084 if (argc == 0) { 2085 pt_env_clear(pt); 2086 } else { 2087 if ((v = mdb_nv_lookup(&pt->p_env, argv->a_un.a_str)) != NULL) { 2088 name = (char *)mdb_nv_get_name(v); 2089 value = mdb_nv_get_cookie(v); 2090 2091 mdb_nv_remove(&pt->p_env, v); 2092 2093 mdb_free(name, strlen(name) + 1); 2094 mdb_free(value, strlen(value) + 1); 2095 } 2096 } 2097 2098 return (DCMD_OK); 2099 } 2100 2101 void 2102 getenv_help(void) 2103 { 2104 mdb_printf("-t show current process environment" 2105 " instead of initial environment.\n"); 2106 } 2107 2108 static const mdb_dcmd_t pt_dcmds[] = { 2109 { "$c", "?[cnt]", "print stack backtrace", pt_stack }, 2110 { "$C", "?[cnt]", "print stack backtrace", pt_stackv }, 2111 { "$i", NULL, "print signals that are ignored", pt_ignored }, 2112 { "$l", NULL, "print the representative thread's lwp id", pt_lwpid }, 2113 { "$L", NULL, "print list of the active lwp ids", pt_lwpids }, 2114 { "$r", "?[-u]", "print general-purpose registers", pt_regs }, 2115 { "$x", "?", "print floating point registers", pt_fpregs }, 2116 { "$X", "?", "print floating point registers", pt_fpregs }, 2117 { "$y", "?", "print floating point registers", pt_fpregs }, 2118 { "$Y", "?", "print floating point registers", pt_fpregs }, 2119 { "$?", "?", "print status and registers", pt_regstatus }, 2120 { ":A", "?[core|pid]", "attach to process or core file", pt_attach }, 2121 { ":i", ":", "ignore signal (delete all matching events)", pt_ignore }, 2122 { ":k", NULL, "forcibly kill and release target", pt_kill }, 2123 { ":R", "[-a]", "release the previously attached process", pt_detach }, 2124 { "attach", "?[core|pid]", 2125 "attach to process or core file", pt_attach }, 2126 { "findstack", ":[-v]", "find user thread stack", pt_findstack }, 2127 { "gcore", "[-o prefix] [-c content]", 2128 "produce a core file for the attached process", pt_gcore }, 2129 { "getenv", "[-t] [name]", "display an environment variable", 2130 pt_getenv, getenv_help }, 2131 { "kill", NULL, "forcibly kill and release target", pt_kill }, 2132 { "release", "[-a]", 2133 "release the previously attached process", pt_detach }, 2134 { "regs", "?[-u]", "print general-purpose registers", pt_regs }, 2135 { "fpregs", "?[-dqs]", "print floating point registers", pt_fpregs }, 2136 { "setenv", "name=value", "set an environment variable", pt_setenv }, 2137 { "stack", "?[cnt]", "print stack backtrace", pt_stack }, 2138 { "stackregs", "?", "print stack backtrace and registers", pt_stackr }, 2139 { "status", NULL, "print summary of current target", pt_status_dcmd }, 2140 { "tls", ":symbol", 2141 "lookup TLS data in the context of a given thread", pt_tls }, 2142 { "tmodel", "{thread|lwp}", NULL, pt_tmodel }, 2143 { "unsetenv", "[name]", "clear an environment variable", pt_unsetenv }, 2144 { NULL } 2145 }; 2146 2147 static void 2148 pt_thr_walk_fini(mdb_walk_state_t *wsp) 2149 { 2150 mdb_addrvec_destroy(wsp->walk_data); 2151 mdb_free(wsp->walk_data, sizeof (mdb_addrvec_t)); 2152 } 2153 2154 static int 2155 pt_thr_walk_init(mdb_walk_state_t *wsp) 2156 { 2157 wsp->walk_data = mdb_zalloc(sizeof (mdb_addrvec_t), UM_SLEEP); 2158 mdb_addrvec_create(wsp->walk_data); 2159 2160 if (PTL_ITER(mdb.m_target, wsp->walk_data) == -1) { 2161 mdb_warn("failed to iterate over threads"); 2162 pt_thr_walk_fini(wsp); 2163 return (WALK_ERR); 2164 } 2165 2166 return (WALK_NEXT); 2167 } 2168 2169 static int 2170 pt_thr_walk_step(mdb_walk_state_t *wsp) 2171 { 2172 if (mdb_addrvec_length(wsp->walk_data) != 0) { 2173 return (wsp->walk_callback(mdb_addrvec_shift(wsp->walk_data), 2174 NULL, wsp->walk_cbdata)); 2175 } 2176 return (WALK_DONE); 2177 } 2178 2179 static const mdb_walker_t pt_walkers[] = { 2180 { "thread", "walk list of valid thread identifiers", 2181 pt_thr_walk_init, pt_thr_walk_step, pt_thr_walk_fini }, 2182 { NULL } 2183 }; 2184 2185 static int 2186 pt_agent_check(boolean_t *agent, const lwpstatus_t *psp) 2187 { 2188 if (psp->pr_flags & PR_AGENT) 2189 *agent = B_TRUE; 2190 2191 return (0); 2192 } 2193 2194 static void 2195 pt_activate_common(mdb_tgt_t *t) 2196 { 2197 pt_data_t *pt = t->t_data; 2198 boolean_t hasagent = B_FALSE; 2199 GElf_Sym sym; 2200 2201 /* 2202 * If we have a libproc handle and AT_BASE is set, the process or core 2203 * is dynamically linked. We call Prd_agent() to force libproc to 2204 * try to initialize librtld_db, and issue a warning if that fails. 2205 */ 2206 if (t->t_pshandle != NULL && Pgetauxval(t->t_pshandle, 2207 AT_BASE) != -1L && Prd_agent(t->t_pshandle) == NULL) { 2208 mdb_warn("warning: librtld_db failed to initialize; shared " 2209 "library information will not be available\n"); 2210 } 2211 2212 if (t->t_pshandle != NULL) { 2213 (void) Plwp_iter(t->t_pshandle, 2214 (proc_lwp_f *)pt_agent_check, &hasagent); 2215 } 2216 2217 if (hasagent) { 2218 mdb_warn("agent lwp detected; forcing " 2219 "lwp thread model (use ::tmodel to change)\n"); 2220 } else if (t->t_pshandle != NULL && Pstate(t->t_pshandle) != PS_IDLE) { 2221 /* 2222 * If we have a libproc handle and we do not have an agent LWP, 2223 * look for the correct thread debugging library. (If we have 2224 * an agent LWP, we leave the model as the raw LWP model to 2225 * allow the agent LWP to be visible to the debugger.) 2226 */ 2227 (void) Pobject_iter(t->t_pshandle, (proc_map_f *)thr_check, t); 2228 } 2229 2230 /* 2231 * If there's a global object named '_mdb_abort_info', assuming we're 2232 * debugging mdb itself and load the developer support module. 2233 */ 2234 if (mdb_gelf_symtab_lookup_by_name(pt->p_symtab, "_mdb_abort_info", 2235 &sym, NULL) == 0 && GELF_ST_TYPE(sym.st_info) == STT_OBJECT) { 2236 if (mdb_module_load("mdb_ds", MDB_MOD_SILENT) < 0) 2237 mdb_warn("warning: failed to load developer support\n"); 2238 } 2239 2240 mdb_tgt_elf_export(pt->p_file); 2241 } 2242 2243 static void 2244 pt_activate(mdb_tgt_t *t) 2245 { 2246 static const mdb_nv_disc_t reg_disc = { reg_disc_set, reg_disc_get }; 2247 2248 pt_data_t *pt = t->t_data; 2249 struct utsname u1, u2; 2250 mdb_var_t *v; 2251 core_content_t content; 2252 2253 if (t->t_pshandle) { 2254 mdb_prop_postmortem = (Pstate(t->t_pshandle) == PS_DEAD); 2255 mdb_prop_kernel = FALSE; 2256 } else 2257 mdb_prop_kernel = mdb_prop_postmortem = FALSE; 2258 2259 mdb_prop_datamodel = MDB_TGT_MODEL_NATIVE; 2260 2261 /* 2262 * If we're examining a core file that doesn't contain program text, 2263 * and uname(2) doesn't match the NT_UTSNAME note recorded in the 2264 * core file, issue a warning. 2265 */ 2266 if (mdb_prop_postmortem == TRUE && 2267 ((content = Pcontent(t->t_pshandle)) == CC_CONTENT_INVALID || 2268 !(content & CC_CONTENT_TEXT)) && 2269 uname(&u1) >= 0 && Puname(t->t_pshandle, &u2) == 0 && 2270 (strcmp(u1.release, u2.release) != 0 || 2271 strcmp(u1.version, u2.version) != 0)) { 2272 mdb_warn("warning: core file is from %s %s %s; shared text " 2273 "mappings may not match installed libraries\n", 2274 u2.sysname, u2.release, u2.version); 2275 } 2276 2277 /* 2278 * Perform the common initialization tasks -- these are shared with 2279 * the pt_exec() and pt_run() subroutines. 2280 */ 2281 pt_activate_common(t); 2282 2283 (void) mdb_tgt_register_dcmds(t, &pt_dcmds[0], MDB_MOD_FORCE); 2284 (void) mdb_tgt_register_walkers(t, &pt_walkers[0], MDB_MOD_FORCE); 2285 2286 /* 2287 * Iterate through our register description list and export 2288 * each register as a named variable. 2289 */ 2290 mdb_nv_rewind(&pt->p_regs); 2291 while ((v = mdb_nv_advance(&pt->p_regs)) != NULL) { 2292 ushort_t rd_flags = MDB_TGT_R_FLAGS(mdb_nv_get_value(v)); 2293 2294 if (!(rd_flags & MDB_TGT_R_EXPORT)) 2295 continue; /* Don't export register as a variable */ 2296 2297 (void) mdb_nv_insert(&mdb.m_nv, mdb_nv_get_name(v), ®_disc, 2298 (uintptr_t)t, MDB_NV_PERSIST); 2299 } 2300 } 2301 2302 static void 2303 pt_deactivate(mdb_tgt_t *t) 2304 { 2305 pt_data_t *pt = t->t_data; 2306 const mdb_dcmd_t *dcp; 2307 const mdb_walker_t *wp; 2308 mdb_var_t *v, *w; 2309 2310 mdb_nv_rewind(&pt->p_regs); 2311 while ((v = mdb_nv_advance(&pt->p_regs)) != NULL) { 2312 ushort_t rd_flags = MDB_TGT_R_FLAGS(mdb_nv_get_value(v)); 2313 2314 if (!(rd_flags & MDB_TGT_R_EXPORT)) 2315 continue; /* Didn't export register as a variable */ 2316 2317 if (w = mdb_nv_lookup(&mdb.m_nv, mdb_nv_get_name(v))) { 2318 w->v_flags &= ~MDB_NV_PERSIST; 2319 mdb_nv_remove(&mdb.m_nv, w); 2320 } 2321 } 2322 2323 for (wp = &pt_walkers[0]; wp->walk_name != NULL; wp++) { 2324 if (mdb_module_remove_walker(t->t_module, wp->walk_name) == -1) 2325 warn("failed to remove walk %s", wp->walk_name); 2326 } 2327 2328 for (dcp = &pt_dcmds[0]; dcp->dc_name != NULL; dcp++) { 2329 if (mdb_module_remove_dcmd(t->t_module, dcp->dc_name) == -1) 2330 warn("failed to remove dcmd %s", dcp->dc_name); 2331 } 2332 2333 mdb_prop_postmortem = FALSE; 2334 mdb_prop_kernel = FALSE; 2335 mdb_prop_datamodel = MDB_TGT_MODEL_UNKNOWN; 2336 } 2337 2338 static void 2339 pt_periodic(mdb_tgt_t *t) 2340 { 2341 pt_data_t *pt = t->t_data; 2342 2343 if (pt->p_rdstate == PT_RD_CONSIST) { 2344 if (t->t_pshandle != NULL && Pstate(t->t_pshandle) < PS_LOST && 2345 !(mdb.m_flags & MDB_FL_NOMODS)) { 2346 mdb_printf("%s: You've got symbols!\n", mdb.m_pname); 2347 mdb_module_load_all(0); 2348 } 2349 pt->p_rdstate = PT_RD_NONE; 2350 } 2351 } 2352 2353 static void 2354 pt_destroy(mdb_tgt_t *t) 2355 { 2356 pt_data_t *pt = t->t_data; 2357 2358 if (pt->p_idlehandle != NULL && pt->p_idlehandle != t->t_pshandle) 2359 Prelease(pt->p_idlehandle, 0); 2360 2361 if (t->t_pshandle != NULL) { 2362 PTL_DTOR(t); 2363 pt_release_parents(t); 2364 pt_pre_detach(t, TRUE); 2365 Prelease(t->t_pshandle, pt->p_rflags); 2366 } 2367 2368 mdb.m_flags &= ~(MDB_FL_VCREATE | MDB_FL_JOBCTL); 2369 pt_close_aout(t); 2370 2371 if (pt->p_aout_fio != NULL) 2372 mdb_io_rele(pt->p_aout_fio); 2373 2374 pt_env_clear(pt); 2375 mdb_nv_destroy(&pt->p_env); 2376 2377 mdb_nv_destroy(&pt->p_regs); 2378 mdb_free(pt, sizeof (pt_data_t)); 2379 } 2380 2381 /*ARGSUSED*/ 2382 static const char * 2383 pt_name(mdb_tgt_t *t) 2384 { 2385 return ("proc"); 2386 } 2387 2388 static const char * 2389 pt_platform(mdb_tgt_t *t) 2390 { 2391 pt_data_t *pt = t->t_data; 2392 2393 if (t->t_pshandle != NULL && 2394 Pplatform(t->t_pshandle, pt->p_platform, MAXNAMELEN) != NULL) 2395 return (pt->p_platform); 2396 2397 return (mdb_conf_platform()); 2398 } 2399 2400 static int 2401 pt_uname(mdb_tgt_t *t, struct utsname *utsp) 2402 { 2403 if (t->t_pshandle != NULL) 2404 return (Puname(t->t_pshandle, utsp)); 2405 2406 return (uname(utsp) >= 0 ? 0 : -1); 2407 } 2408 2409 static int 2410 pt_dmodel(mdb_tgt_t *t) 2411 { 2412 if (t->t_pshandle == NULL) 2413 return (MDB_TGT_MODEL_NATIVE); 2414 2415 switch (Pstatus(t->t_pshandle)->pr_dmodel) { 2416 case PR_MODEL_ILP32: 2417 return (MDB_TGT_MODEL_ILP32); 2418 case PR_MODEL_LP64: 2419 return (MDB_TGT_MODEL_LP64); 2420 } 2421 2422 return (MDB_TGT_MODEL_UNKNOWN); 2423 } 2424 2425 static ssize_t 2426 pt_vread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr) 2427 { 2428 ssize_t n; 2429 2430 /* 2431 * If no handle is open yet, reads from virtual addresses are 2432 * allowed to succeed but return zero-filled memory. 2433 */ 2434 if (t->t_pshandle == NULL) { 2435 bzero(buf, nbytes); 2436 return (nbytes); 2437 } 2438 2439 if ((n = Pread(t->t_pshandle, buf, nbytes, addr)) <= 0) 2440 return (set_errno(EMDB_NOMAP)); 2441 2442 return (n); 2443 } 2444 2445 static ssize_t 2446 pt_vwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr) 2447 { 2448 ssize_t n; 2449 2450 /* 2451 * If no handle is open yet, writes to virtual addresses are 2452 * allowed to succeed but do not actually modify anything. 2453 */ 2454 if (t->t_pshandle == NULL) 2455 return (nbytes); 2456 2457 n = Pwrite(t->t_pshandle, buf, nbytes, addr); 2458 2459 if (n == -1 && errno == EIO) 2460 return (set_errno(EMDB_NOMAP)); 2461 2462 return (n); 2463 } 2464 2465 static ssize_t 2466 pt_fread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr) 2467 { 2468 pt_data_t *pt = t->t_data; 2469 2470 if (pt->p_file != NULL) { 2471 return (mdb_gelf_rw(pt->p_file, buf, nbytes, addr, 2472 IOPF_READ(pt->p_fio), GIO_READ)); 2473 } 2474 2475 bzero(buf, nbytes); 2476 return (nbytes); 2477 } 2478 2479 static ssize_t 2480 pt_fwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr) 2481 { 2482 pt_data_t *pt = t->t_data; 2483 2484 if (pt->p_file != NULL) { 2485 return (mdb_gelf_rw(pt->p_file, (void *)buf, nbytes, addr, 2486 IOPF_WRITE(pt->p_fio), GIO_WRITE)); 2487 } 2488 2489 return (nbytes); 2490 } 2491 2492 static const char * 2493 pt_resolve_lmid(const char *object, Lmid_t *lmidp) 2494 { 2495 Lmid_t lmid = PR_LMID_EVERY; 2496 const char *p; 2497 2498 if (object == MDB_TGT_OBJ_EVERY || object == MDB_TGT_OBJ_EXEC) 2499 lmid = LM_ID_BASE; /* restrict scope to a.out's link map */ 2500 else if (object != MDB_TGT_OBJ_RTLD && strncmp(object, "LM", 2) == 0 && 2501 (p = strchr(object, '`')) != NULL) { 2502 object += 2; /* skip past initial "LM" prefix */ 2503 lmid = strntoul(object, (size_t)(p - object), mdb.m_radix); 2504 object = p + 1; /* skip past link map specifier */ 2505 } 2506 2507 *lmidp = lmid; 2508 return (object); 2509 } 2510 2511 static int 2512 tlsbase(mdb_tgt_t *t, mdb_tgt_tid_t tid, Lmid_t lmid, const char *object, 2513 psaddr_t *basep) 2514 { 2515 pt_data_t *pt = t->t_data; 2516 const rd_loadobj_t *loadobjp; 2517 td_thrhandle_t th; 2518 td_err_e err; 2519 2520 if (object == MDB_TGT_OBJ_EVERY) 2521 return (set_errno(EINVAL)); 2522 2523 if (t->t_pshandle == NULL || Pstate(t->t_pshandle) == PS_IDLE) 2524 return (set_errno(EMDB_NOPROC)); 2525 2526 if (pt->p_tdb_ops == NULL) 2527 return (set_errno(EMDB_TDB)); 2528 2529 err = pt->p_tdb_ops->td_ta_map_id2thr(pt->p_ptl_hdl, tid, &th); 2530 if (err != TD_OK) 2531 return (set_errno(tdb_to_errno(err))); 2532 2533 /* 2534 * If this fails, rtld_db has failed to initialize properly. 2535 */ 2536 if ((loadobjp = Plmid_to_loadobj(t->t_pshandle, lmid, object)) == NULL) 2537 return (set_errno(EMDB_NORTLD)); 2538 2539 /* 2540 * This will fail if the TLS block has not been allocated for the 2541 * object that contains the TLS symbol in question. 2542 */ 2543 err = pt->p_tdb_ops->td_thr_tlsbase(&th, loadobjp->rl_tlsmodid, basep); 2544 if (err != TD_OK) 2545 return (set_errno(tdb_to_errno(err))); 2546 2547 return (0); 2548 } 2549 2550 typedef struct { 2551 mdb_tgt_t *pl_tgt; 2552 const char *pl_name; 2553 Lmid_t pl_lmid; 2554 GElf_Sym *pl_symp; 2555 mdb_syminfo_t *pl_sip; 2556 mdb_tgt_tid_t pl_tid; 2557 mdb_bool_t pl_found; 2558 } pt_lookup_t; 2559 2560 /*ARGSUSED*/ 2561 static int 2562 pt_lookup_cb(void *data, const prmap_t *pmp, const char *object) 2563 { 2564 pt_lookup_t *plp = data; 2565 struct ps_prochandle *P = plp->pl_tgt->t_pshandle; 2566 prsyminfo_t si; 2567 GElf_Sym sym; 2568 2569 if (Pxlookup_by_name(P, plp->pl_lmid, object, plp->pl_name, &sym, 2570 &si) != 0) 2571 return (0); 2572 2573 /* 2574 * If we encounter a match with SHN_UNDEF, keep looking for a 2575 * better match. Return the first match with SHN_UNDEF set if no 2576 * better match is found. 2577 */ 2578 if (sym.st_shndx == SHN_UNDEF) { 2579 if (!plp->pl_found) { 2580 plp->pl_found = TRUE; 2581 *plp->pl_symp = sym; 2582 plp->pl_sip->sym_table = si.prs_table; 2583 plp->pl_sip->sym_id = si.prs_id; 2584 } 2585 2586 return (0); 2587 } 2588 2589 /* 2590 * Note that if the symbol's st_shndx is SHN_UNDEF we don't have the 2591 * TLS offset anyway, so adding in the tlsbase would be worthless. 2592 */ 2593 if (GELF_ST_TYPE(sym.st_info) == STT_TLS && 2594 plp->pl_tid != (mdb_tgt_tid_t)-1) { 2595 psaddr_t base; 2596 2597 if (tlsbase(plp->pl_tgt, plp->pl_tid, plp->pl_lmid, object, 2598 &base) != 0) 2599 return (-1); /* errno is set for us */ 2600 2601 sym.st_value += base; 2602 } 2603 2604 plp->pl_found = TRUE; 2605 *plp->pl_symp = sym; 2606 plp->pl_sip->sym_table = si.prs_table; 2607 plp->pl_sip->sym_id = si.prs_id; 2608 2609 return (1); 2610 } 2611 2612 /* 2613 * Lookup the symbol with a thread context so that we can adjust TLS symbols 2614 * to get the values as they would appear in the context of the given thread. 2615 */ 2616 static int 2617 pt_lookup_by_name_thr(mdb_tgt_t *t, const char *object, 2618 const char *name, GElf_Sym *symp, mdb_syminfo_t *sip, mdb_tgt_tid_t tid) 2619 { 2620 struct ps_prochandle *P = t->t_pshandle; 2621 pt_data_t *pt = t->t_data; 2622 Lmid_t lmid; 2623 uint_t i; 2624 const rd_loadobj_t *aout_lop; 2625 2626 object = pt_resolve_lmid(object, &lmid); 2627 2628 if (P != NULL) { 2629 pt_lookup_t pl; 2630 2631 pl.pl_tgt = t; 2632 pl.pl_name = name; 2633 pl.pl_lmid = lmid; 2634 pl.pl_symp = symp; 2635 pl.pl_sip = sip; 2636 pl.pl_tid = tid; 2637 pl.pl_found = FALSE; 2638 2639 if (object == MDB_TGT_OBJ_EVERY) { 2640 if (Pobject_iter_resolved(P, pt_lookup_cb, &pl) == -1) 2641 return (-1); /* errno is set for us */ 2642 if ((!pl.pl_found) && 2643 (Pobject_iter(P, pt_lookup_cb, &pl) == -1)) 2644 return (-1); /* errno is set for us */ 2645 } else { 2646 const prmap_t *pmp; 2647 2648 /* 2649 * This can fail either due to an invalid lmid or 2650 * an invalid object. To determine which is 2651 * faulty, we test the lmid against known valid 2652 * lmids and then see if using a wild-card lmid 2653 * improves ths situation. 2654 */ 2655 if ((pmp = Plmid_to_map(P, lmid, object)) == NULL) { 2656 if (lmid != PR_LMID_EVERY && 2657 lmid != LM_ID_BASE && 2658 lmid != LM_ID_LDSO && 2659 Plmid_to_map(P, PR_LMID_EVERY, object) 2660 != NULL) 2661 return (set_errno(EMDB_NOLMID)); 2662 else 2663 return (set_errno(EMDB_NOOBJ)); 2664 } 2665 2666 if (pt_lookup_cb(&pl, pmp, object) == -1) 2667 return (-1); /* errno is set for us */ 2668 } 2669 2670 if (pl.pl_found) 2671 return (0); 2672 } 2673 2674 /* 2675 * If libproc doesn't have the symbols for rtld, we're cooked -- 2676 * mdb doesn't have those symbols either. 2677 */ 2678 if (object == MDB_TGT_OBJ_RTLD) 2679 return (set_errno(EMDB_NOSYM)); 2680 2681 if (object != MDB_TGT_OBJ_EXEC && object != MDB_TGT_OBJ_EVERY) { 2682 int status = mdb_gelf_symtab_lookup_by_file(pt->p_symtab, 2683 object, name, symp, &sip->sym_id); 2684 2685 if (status != 0) { 2686 if (P != NULL && 2687 Plmid_to_map(P, PR_LMID_EVERY, object) != NULL) 2688 return (set_errno(EMDB_NOSYM)); 2689 else 2690 return (-1); /* errno set from lookup_by_file */ 2691 } 2692 2693 goto found; 2694 } 2695 2696 if (mdb_gelf_symtab_lookup_by_name(pt->p_symtab, name, symp, &i) == 0) { 2697 sip->sym_table = MDB_TGT_SYMTAB; 2698 sip->sym_id = i; 2699 goto local_found; 2700 } 2701 2702 if (mdb_gelf_symtab_lookup_by_name(pt->p_dynsym, name, symp, &i) == 0) { 2703 sip->sym_table = MDB_TGT_DYNSYM; 2704 sip->sym_id = i; 2705 goto local_found; 2706 } 2707 2708 return (set_errno(EMDB_NOSYM)); 2709 2710 local_found: 2711 if (pt->p_file != NULL && 2712 pt->p_file->gf_ehdr.e_type == ET_DYN && 2713 P != NULL && 2714 (aout_lop = Pname_to_loadobj(P, PR_OBJ_EXEC)) != NULL) 2715 symp->st_value += aout_lop->rl_base; 2716 2717 found: 2718 /* 2719 * If the symbol has type TLS, libproc should have found the symbol 2720 * if it exists and has been allocated. 2721 */ 2722 if (GELF_ST_TYPE(symp->st_info) == STT_TLS) 2723 return (set_errno(EMDB_TLS)); 2724 2725 return (0); 2726 } 2727 2728 static int 2729 pt_lookup_by_name(mdb_tgt_t *t, const char *object, 2730 const char *name, GElf_Sym *symp, mdb_syminfo_t *sip) 2731 { 2732 return (pt_lookup_by_name_thr(t, object, name, symp, sip, PTL_TID(t))); 2733 } 2734 2735 static int 2736 pt_lookup_by_addr(mdb_tgt_t *t, uintptr_t addr, uint_t flags, 2737 char *buf, size_t nbytes, GElf_Sym *symp, mdb_syminfo_t *sip) 2738 { 2739 struct ps_prochandle *P = t->t_pshandle; 2740 pt_data_t *pt = t->t_data; 2741 rd_plt_info_t rpi = { 0 }; 2742 2743 const char *pltsym; 2744 int rv, match, i; 2745 2746 mdb_gelf_symtab_t *gsts[3]; /* mdb.m_prsym, .symtab, .dynsym */ 2747 int gstc = 0; /* number of valid gsts[] entries */ 2748 2749 mdb_gelf_symtab_t *gst = NULL; /* set if 'sym' is from a gst */ 2750 const prmap_t *pmp = NULL; /* set if 'sym' is from libproc */ 2751 GElf_Sym sym; /* best symbol found so far if !exact */ 2752 prsyminfo_t si; 2753 2754 /* 2755 * Fill in our array of symbol table pointers with the private symbol 2756 * table, static symbol table, and dynamic symbol table if applicable. 2757 * These are done in order of precedence so that if we match and 2758 * MDB_TGT_SYM_EXACT is set, we need not look any further. 2759 */ 2760 if (mdb.m_prsym != NULL) 2761 gsts[gstc++] = mdb.m_prsym; 2762 if (P == NULL && pt->p_symtab != NULL) 2763 gsts[gstc++] = pt->p_symtab; 2764 if (P == NULL && pt->p_dynsym != NULL) 2765 gsts[gstc++] = pt->p_dynsym; 2766 2767 /* 2768 * Loop through our array attempting to match the address. If we match 2769 * and we're in exact mode, we're done. Otherwise save the symbol in 2770 * the local sym variable if it is closer than our previous match. 2771 * We explicitly watch for zero-valued symbols since DevPro insists 2772 * on storing __fsr_init_value's value as the symbol value instead 2773 * of storing it in a constant integer. 2774 */ 2775 for (i = 0; i < gstc; i++) { 2776 if (mdb_gelf_symtab_lookup_by_addr(gsts[i], addr, flags, buf, 2777 nbytes, symp, &sip->sym_id) != 0 || symp->st_value == 0) 2778 continue; 2779 2780 if (flags & MDB_TGT_SYM_EXACT) { 2781 gst = gsts[i]; 2782 goto found; 2783 } 2784 2785 if (gst == NULL || mdb_gelf_sym_closer(symp, &sym, addr)) { 2786 gst = gsts[i]; 2787 sym = *symp; 2788 } 2789 } 2790 2791 /* 2792 * If we have no libproc handle active, we're done: fail if gst is 2793 * NULL; otherwise copy out our best symbol and skip to the end. 2794 * We also skip to found if gst is the private symbol table: we 2795 * want this to always take precedence over PLT re-vectoring. 2796 */ 2797 if (P == NULL || (gst != NULL && gst == mdb.m_prsym)) { 2798 if (gst == NULL) 2799 return (set_errno(EMDB_NOSYMADDR)); 2800 *symp = sym; 2801 goto found; 2802 } 2803 2804 /* 2805 * Check to see if the address is in a PLT: if it is, use librtld_db to 2806 * attempt to resolve the PLT entry. If the entry is bound, reset addr 2807 * to the bound address, add a special prefix to the caller's buf, 2808 * forget our previous guess, and then continue using the new addr. 2809 * If the entry is not bound, copy the corresponding symbol name into 2810 * buf and return a fake symbol for the given address. 2811 */ 2812 if ((pltsym = Ppltdest(P, addr)) != NULL) { 2813 const rd_loadobj_t *rlp; 2814 rd_agent_t *rap; 2815 2816 if ((rap = Prd_agent(P)) != NULL && 2817 (rlp = Paddr_to_loadobj(P, addr)) != NULL && 2818 rd_plt_resolution(rap, addr, Pstatus(P)->pr_lwp.pr_lwpid, 2819 rlp->rl_plt_base, &rpi) == RD_OK && 2820 (rpi.pi_flags & RD_FLG_PI_PLTBOUND)) { 2821 size_t n; 2822 n = mdb_iob_snprintf(buf, nbytes, "PLT="); 2823 addr = rpi.pi_baddr; 2824 if (n > nbytes) { 2825 buf += nbytes; 2826 nbytes = 0; 2827 } else { 2828 buf += n; 2829 nbytes -= n; 2830 } 2831 gst = NULL; 2832 } else { 2833 (void) mdb_iob_snprintf(buf, nbytes, "PLT:%s", pltsym); 2834 bzero(symp, sizeof (GElf_Sym)); 2835 symp->st_value = addr; 2836 symp->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC); 2837 return (0); 2838 } 2839 } 2840 2841 /* 2842 * Ask libproc to convert the address to the closest symbol for us. 2843 * Once we get the closest symbol, we perform the EXACT match or 2844 * smart-mode or absolute distance check ourself: 2845 */ 2846 if (PT_LIBPROC_RESOLVE(P)) { 2847 rv = Pxlookup_by_addr_resolved(P, addr, buf, nbytes, 2848 symp, &si); 2849 } else { 2850 rv = Pxlookup_by_addr(P, addr, buf, nbytes, 2851 symp, &si); 2852 } 2853 if ((rv == 0) && (symp->st_value != 0) && 2854 (gst == NULL || mdb_gelf_sym_closer(symp, &sym, addr))) { 2855 2856 if (flags & MDB_TGT_SYM_EXACT) 2857 match = (addr == symp->st_value); 2858 else if (mdb.m_symdist == 0) 2859 match = (addr >= symp->st_value && 2860 addr < symp->st_value + symp->st_size); 2861 else 2862 match = (addr >= symp->st_value && 2863 addr < symp->st_value + mdb.m_symdist); 2864 2865 if (match) { 2866 pmp = Paddr_to_map(P, addr); 2867 gst = NULL; 2868 sip->sym_table = si.prs_table; 2869 sip->sym_id = si.prs_id; 2870 goto found; 2871 } 2872 } 2873 2874 /* 2875 * If we get here, Plookup_by_addr has failed us. If we have no 2876 * previous best symbol (gst == NULL), we've failed completely. 2877 * Otherwise we copy out that symbol and continue on to 'found'. 2878 */ 2879 if (gst == NULL) 2880 return (set_errno(EMDB_NOSYMADDR)); 2881 *symp = sym; 2882 found: 2883 /* 2884 * Once we've found something, copy the final name into the caller's 2885 * buffer and prefix it with the mapping name if appropriate. 2886 */ 2887 if (pmp != NULL && pmp != Pname_to_map(P, PR_OBJ_EXEC)) { 2888 const char *prefix = pmp->pr_mapname; 2889 Lmid_t lmid; 2890 2891 if (PT_LIBPROC_RESOLVE(P)) { 2892 if (Pobjname_resolved(P, addr, pt->p_objname, 2893 MDB_TGT_MAPSZ)) 2894 prefix = pt->p_objname; 2895 } else { 2896 if (Pobjname(P, addr, pt->p_objname, MDB_TGT_MAPSZ)) 2897 prefix = pt->p_objname; 2898 } 2899 2900 if (buf != NULL && nbytes > 1) { 2901 (void) strncpy(pt->p_symname, buf, MDB_TGT_SYM_NAMLEN); 2902 pt->p_symname[MDB_TGT_SYM_NAMLEN - 1] = '\0'; 2903 } else { 2904 pt->p_symname[0] = '\0'; 2905 } 2906 2907 if (prefix == pt->p_objname && Plmid(P, addr, &lmid) == 0 && ( 2908 (lmid != LM_ID_BASE && lmid != LM_ID_LDSO) || 2909 (mdb.m_flags & MDB_FL_SHOWLMID))) { 2910 (void) mdb_iob_snprintf(buf, nbytes, "LM%lr`%s`%s", 2911 lmid, strbasename(prefix), pt->p_symname); 2912 } else { 2913 (void) mdb_iob_snprintf(buf, nbytes, "%s`%s", 2914 strbasename(prefix), pt->p_symname); 2915 } 2916 2917 } else if (gst != NULL && buf != NULL && nbytes > 0) { 2918 (void) strncpy(buf, mdb_gelf_sym_name(gst, symp), nbytes); 2919 buf[nbytes - 1] = '\0'; 2920 } 2921 2922 return (0); 2923 } 2924 2925 2926 static int 2927 pt_symbol_iter_cb(void *arg, const GElf_Sym *sym, const char *name, 2928 const prsyminfo_t *sip) 2929 { 2930 pt_symarg_t *psp = arg; 2931 2932 psp->psym_info.sym_id = sip->prs_id; 2933 2934 return (psp->psym_func(psp->psym_private, sym, name, &psp->psym_info, 2935 psp->psym_obj)); 2936 } 2937 2938 static int 2939 pt_objsym_iter(void *arg, const prmap_t *pmp, const char *object) 2940 { 2941 Lmid_t lmid = PR_LMID_EVERY; 2942 pt_symarg_t *psp = arg; 2943 2944 psp->psym_obj = object; 2945 2946 (void) Plmid(psp->psym_targ->t_pshandle, pmp->pr_vaddr, &lmid); 2947 (void) Pxsymbol_iter(psp->psym_targ->t_pshandle, lmid, object, 2948 psp->psym_which, psp->psym_type, pt_symbol_iter_cb, arg); 2949 2950 return (0); 2951 } 2952 2953 static int 2954 pt_symbol_filt(void *arg, const GElf_Sym *sym, const char *name, uint_t id) 2955 { 2956 pt_symarg_t *psp = arg; 2957 2958 if (mdb_tgt_sym_match(sym, psp->psym_type)) { 2959 psp->psym_info.sym_id = id; 2960 return (psp->psym_func(psp->psym_private, sym, name, 2961 &psp->psym_info, psp->psym_obj)); 2962 } 2963 2964 return (0); 2965 } 2966 2967 static int 2968 pt_symbol_iter(mdb_tgt_t *t, const char *object, uint_t which, 2969 uint_t type, mdb_tgt_sym_f *func, void *private) 2970 { 2971 pt_data_t *pt = t->t_data; 2972 mdb_gelf_symtab_t *gst; 2973 pt_symarg_t ps; 2974 Lmid_t lmid; 2975 2976 object = pt_resolve_lmid(object, &lmid); 2977 2978 ps.psym_targ = t; 2979 ps.psym_which = which; 2980 ps.psym_type = type; 2981 ps.psym_func = func; 2982 ps.psym_private = private; 2983 ps.psym_obj = object; 2984 2985 if (t->t_pshandle != NULL) { 2986 if (object != MDB_TGT_OBJ_EVERY) { 2987 if (Plmid_to_map(t->t_pshandle, lmid, object) == NULL) 2988 return (set_errno(EMDB_NOOBJ)); 2989 (void) Pxsymbol_iter(t->t_pshandle, lmid, object, 2990 which, type, pt_symbol_iter_cb, &ps); 2991 return (0); 2992 } else if (Prd_agent(t->t_pshandle) != NULL) { 2993 if (PT_LIBPROC_RESOLVE(t->t_pshandle)) { 2994 (void) Pobject_iter_resolved(t->t_pshandle, 2995 pt_objsym_iter, &ps); 2996 } else { 2997 (void) Pobject_iter(t->t_pshandle, 2998 pt_objsym_iter, &ps); 2999 } 3000 return (0); 3001 } 3002 } 3003 3004 if (lmid != LM_ID_BASE && lmid != PR_LMID_EVERY) 3005 return (set_errno(EMDB_NOLMID)); 3006 3007 if (object != MDB_TGT_OBJ_EXEC && object != MDB_TGT_OBJ_EVERY && 3008 pt->p_fio != NULL && 3009 strcmp(object, IOP_NAME(pt->p_fio)) != 0) 3010 return (set_errno(EMDB_NOOBJ)); 3011 3012 if (which == MDB_TGT_SYMTAB) 3013 gst = pt->p_symtab; 3014 else 3015 gst = pt->p_dynsym; 3016 3017 if (gst != NULL) { 3018 ps.psym_info.sym_table = gst->gst_tabid; 3019 mdb_gelf_symtab_iter(gst, pt_symbol_filt, &ps); 3020 } 3021 3022 return (0); 3023 } 3024 3025 static const mdb_map_t * 3026 pt_prmap_to_mdbmap(mdb_tgt_t *t, const prmap_t *prp, mdb_map_t *mp) 3027 { 3028 struct ps_prochandle *P = t->t_pshandle; 3029 char *rv, name[MAXPATHLEN]; 3030 Lmid_t lmid; 3031 3032 if (PT_LIBPROC_RESOLVE(P)) { 3033 rv = Pobjname_resolved(P, prp->pr_vaddr, name, sizeof (name)); 3034 } else { 3035 rv = Pobjname(P, prp->pr_vaddr, name, sizeof (name)); 3036 } 3037 3038 if (rv != NULL) { 3039 if (Plmid(P, prp->pr_vaddr, &lmid) == 0 && ( 3040 (lmid != LM_ID_BASE && lmid != LM_ID_LDSO) || 3041 (mdb.m_flags & MDB_FL_SHOWLMID))) { 3042 (void) mdb_iob_snprintf(mp->map_name, MDB_TGT_MAPSZ, 3043 "LM%lr`%s", lmid, name); 3044 } else { 3045 (void) strncpy(mp->map_name, name, MDB_TGT_MAPSZ - 1); 3046 mp->map_name[MDB_TGT_MAPSZ - 1] = '\0'; 3047 } 3048 } else { 3049 (void) strncpy(mp->map_name, prp->pr_mapname, 3050 MDB_TGT_MAPSZ - 1); 3051 mp->map_name[MDB_TGT_MAPSZ - 1] = '\0'; 3052 } 3053 3054 mp->map_base = prp->pr_vaddr; 3055 mp->map_size = prp->pr_size; 3056 mp->map_flags = 0; 3057 3058 if (prp->pr_mflags & MA_READ) 3059 mp->map_flags |= MDB_TGT_MAP_R; 3060 if (prp->pr_mflags & MA_WRITE) 3061 mp->map_flags |= MDB_TGT_MAP_W; 3062 if (prp->pr_mflags & MA_EXEC) 3063 mp->map_flags |= MDB_TGT_MAP_X; 3064 3065 if (prp->pr_mflags & MA_SHM) 3066 mp->map_flags |= MDB_TGT_MAP_SHMEM; 3067 if (prp->pr_mflags & MA_BREAK) 3068 mp->map_flags |= MDB_TGT_MAP_HEAP; 3069 if (prp->pr_mflags & MA_STACK) 3070 mp->map_flags |= MDB_TGT_MAP_STACK; 3071 if (prp->pr_mflags & MA_ANON) 3072 mp->map_flags |= MDB_TGT_MAP_ANON; 3073 3074 return (mp); 3075 } 3076 3077 /*ARGSUSED*/ 3078 static int 3079 pt_map_apply(void *arg, const prmap_t *prp, const char *name) 3080 { 3081 pt_maparg_t *pmp = arg; 3082 mdb_map_t map; 3083 3084 return (pmp->pmap_func(pmp->pmap_private, 3085 pt_prmap_to_mdbmap(pmp->pmap_targ, prp, &map), map.map_name)); 3086 } 3087 3088 static int 3089 pt_mapping_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private) 3090 { 3091 if (t->t_pshandle != NULL) { 3092 pt_maparg_t pm; 3093 3094 pm.pmap_targ = t; 3095 pm.pmap_func = func; 3096 pm.pmap_private = private; 3097 3098 if (PT_LIBPROC_RESOLVE(t->t_pshandle)) { 3099 (void) Pmapping_iter_resolved(t->t_pshandle, 3100 pt_map_apply, &pm); 3101 } else { 3102 (void) Pmapping_iter(t->t_pshandle, 3103 pt_map_apply, &pm); 3104 } 3105 return (0); 3106 } 3107 3108 return (set_errno(EMDB_NOPROC)); 3109 } 3110 3111 static int 3112 pt_object_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private) 3113 { 3114 pt_data_t *pt = t->t_data; 3115 3116 /* 3117 * If we have a libproc handle, we can just call Pobject_iter to 3118 * iterate over its list of load object information. 3119 */ 3120 if (t->t_pshandle != NULL) { 3121 pt_maparg_t pm; 3122 3123 pm.pmap_targ = t; 3124 pm.pmap_func = func; 3125 pm.pmap_private = private; 3126 3127 if (PT_LIBPROC_RESOLVE(t->t_pshandle)) { 3128 (void) Pobject_iter_resolved(t->t_pshandle, 3129 pt_map_apply, &pm); 3130 } else { 3131 (void) Pobject_iter(t->t_pshandle, 3132 pt_map_apply, &pm); 3133 } 3134 return (0); 3135 } 3136 3137 /* 3138 * If we're examining an executable or other ELF file but we have no 3139 * libproc handle, fake up some information based on DT_NEEDED entries. 3140 */ 3141 if (pt->p_dynsym != NULL && pt->p_file->gf_dyns != NULL && 3142 pt->p_fio != NULL) { 3143 mdb_gelf_sect_t *gsp = pt->p_dynsym->gst_ssect; 3144 GElf_Dyn *dynp = pt->p_file->gf_dyns; 3145 mdb_map_t *mp = &pt->p_map; 3146 const char *s = IOP_NAME(pt->p_fio); 3147 size_t i; 3148 3149 (void) strncpy(mp->map_name, s, MDB_TGT_MAPSZ); 3150 mp->map_name[MDB_TGT_MAPSZ - 1] = '\0'; 3151 mp->map_flags = MDB_TGT_MAP_R | MDB_TGT_MAP_X; 3152 mp->map_base = NULL; 3153 mp->map_size = 0; 3154 3155 if (func(private, mp, s) != 0) 3156 return (0); 3157 3158 for (i = 0; i < pt->p_file->gf_ndyns; i++, dynp++) { 3159 if (dynp->d_tag == DT_NEEDED) { 3160 s = (char *)gsp->gs_data + dynp->d_un.d_val; 3161 (void) strncpy(mp->map_name, s, MDB_TGT_MAPSZ); 3162 mp->map_name[MDB_TGT_MAPSZ - 1] = '\0'; 3163 if (func(private, mp, s) != 0) 3164 return (0); 3165 } 3166 } 3167 3168 return (0); 3169 } 3170 3171 return (set_errno(EMDB_NOPROC)); 3172 } 3173 3174 static const mdb_map_t * 3175 pt_addr_to_map(mdb_tgt_t *t, uintptr_t addr) 3176 { 3177 pt_data_t *pt = t->t_data; 3178 const prmap_t *pmp; 3179 3180 if (t->t_pshandle == NULL) { 3181 (void) set_errno(EMDB_NOPROC); 3182 return (NULL); 3183 } 3184 3185 if ((pmp = Paddr_to_map(t->t_pshandle, addr)) == NULL) { 3186 (void) set_errno(EMDB_NOMAP); 3187 return (NULL); 3188 } 3189 3190 return (pt_prmap_to_mdbmap(t, pmp, &pt->p_map)); 3191 } 3192 3193 static const mdb_map_t * 3194 pt_name_to_map(mdb_tgt_t *t, const char *object) 3195 { 3196 pt_data_t *pt = t->t_data; 3197 const prmap_t *pmp; 3198 Lmid_t lmid; 3199 3200 if (t->t_pshandle == NULL) { 3201 (void) set_errno(EMDB_NOPROC); 3202 return (NULL); 3203 } 3204 3205 object = pt_resolve_lmid(object, &lmid); 3206 3207 if ((pmp = Plmid_to_map(t->t_pshandle, lmid, object)) == NULL) { 3208 (void) set_errno(EMDB_NOOBJ); 3209 return (NULL); 3210 } 3211 3212 return (pt_prmap_to_mdbmap(t, pmp, &pt->p_map)); 3213 } 3214 3215 static ctf_file_t * 3216 pt_addr_to_ctf(mdb_tgt_t *t, uintptr_t addr) 3217 { 3218 ctf_file_t *ret; 3219 3220 if (t->t_pshandle == NULL) { 3221 (void) set_errno(EMDB_NOPROC); 3222 return (NULL); 3223 } 3224 3225 if ((ret = Paddr_to_ctf(t->t_pshandle, addr)) == NULL) { 3226 (void) set_errno(EMDB_NOOBJ); 3227 return (NULL); 3228 } 3229 3230 return (ret); 3231 } 3232 3233 static ctf_file_t * 3234 pt_name_to_ctf(mdb_tgt_t *t, const char *name) 3235 { 3236 ctf_file_t *ret; 3237 3238 if (t->t_pshandle == NULL) { 3239 (void) set_errno(EMDB_NOPROC); 3240 return (NULL); 3241 } 3242 3243 if ((ret = Pname_to_ctf(t->t_pshandle, name)) == NULL) { 3244 (void) set_errno(EMDB_NOOBJ); 3245 return (NULL); 3246 } 3247 3248 return (ret); 3249 } 3250 3251 static int 3252 pt_status(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 3253 { 3254 const pstatus_t *psp; 3255 prgregset_t gregs; 3256 int state; 3257 3258 bzero(tsp, sizeof (mdb_tgt_status_t)); 3259 3260 if (t->t_pshandle == NULL) { 3261 tsp->st_state = MDB_TGT_IDLE; 3262 return (0); 3263 } 3264 3265 switch (state = Pstate(t->t_pshandle)) { 3266 case PS_RUN: 3267 tsp->st_state = MDB_TGT_RUNNING; 3268 break; 3269 3270 case PS_STOP: 3271 tsp->st_state = MDB_TGT_STOPPED; 3272 psp = Pstatus(t->t_pshandle); 3273 3274 tsp->st_tid = PTL_TID(t); 3275 if (PTL_GETREGS(t, tsp->st_tid, gregs) == 0) 3276 tsp->st_pc = gregs[R_PC]; 3277 3278 if (psp->pr_flags & PR_ISTOP) 3279 tsp->st_flags |= MDB_TGT_ISTOP; 3280 if (psp->pr_flags & PR_DSTOP) 3281 tsp->st_flags |= MDB_TGT_DSTOP; 3282 3283 break; 3284 3285 case PS_LOST: 3286 tsp->st_state = MDB_TGT_LOST; 3287 break; 3288 case PS_UNDEAD: 3289 tsp->st_state = MDB_TGT_UNDEAD; 3290 break; 3291 case PS_DEAD: 3292 tsp->st_state = MDB_TGT_DEAD; 3293 break; 3294 case PS_IDLE: 3295 tsp->st_state = MDB_TGT_IDLE; 3296 break; 3297 default: 3298 fail("unknown libproc state (%d)\n", state); 3299 } 3300 3301 if (t->t_flags & MDB_TGT_F_BUSY) 3302 tsp->st_flags |= MDB_TGT_BUSY; 3303 3304 return (0); 3305 } 3306 3307 static void 3308 pt_dupfd(const char *file, int oflags, mode_t mode, int dfd) 3309 { 3310 int fd; 3311 3312 if ((fd = open(file, oflags, mode)) >= 0) { 3313 (void) fcntl(fd, F_DUP2FD, dfd); 3314 (void) close(fd); 3315 } else 3316 warn("failed to open %s as descriptor %d", file, dfd); 3317 } 3318 3319 /* 3320 * The Pcreate_callback() function interposes on the default, empty libproc 3321 * definition. It will be called following a fork of a new child process by 3322 * Pcreate() below, but before the exec of the new process image. We use this 3323 * callback to optionally redirect stdin and stdout and reset the dispositions 3324 * of SIGPIPE and SIGQUIT from SIG_IGN back to SIG_DFL. 3325 */ 3326 /*ARGSUSED*/ 3327 void 3328 Pcreate_callback(struct ps_prochandle *P) 3329 { 3330 pt_data_t *pt = mdb.m_target->t_data; 3331 3332 if (pt->p_stdin != NULL) 3333 pt_dupfd(pt->p_stdin, O_RDWR, 0, STDIN_FILENO); 3334 if (pt->p_stdout != NULL) 3335 pt_dupfd(pt->p_stdout, O_CREAT | O_WRONLY, 0666, STDOUT_FILENO); 3336 3337 (void) mdb_signal_sethandler(SIGPIPE, SIG_DFL, NULL); 3338 (void) mdb_signal_sethandler(SIGQUIT, SIG_DFL, NULL); 3339 } 3340 3341 static int 3342 pt_run(mdb_tgt_t *t, int argc, const mdb_arg_t *argv) 3343 { 3344 pt_data_t *pt = t->t_data; 3345 struct ps_prochandle *P; 3346 char execname[MAXPATHLEN]; 3347 const char **pargv; 3348 int pargc = 0; 3349 int i, perr; 3350 char **penv; 3351 mdb_var_t *v; 3352 3353 if (pt->p_aout_fio == NULL) { 3354 warn("run requires executable to be specified on " 3355 "command-line\n"); 3356 return (set_errno(EMDB_TGT)); 3357 } 3358 3359 pargv = mdb_alloc(sizeof (char *) * (argc + 2), UM_SLEEP); 3360 pargv[pargc++] = strbasename(IOP_NAME(pt->p_aout_fio)); 3361 3362 for (i = 0; i < argc; i++) { 3363 if (argv[i].a_type != MDB_TYPE_STRING) { 3364 mdb_free(pargv, sizeof (char *) * (argc + 2)); 3365 return (set_errno(EINVAL)); 3366 } 3367 if (argv[i].a_un.a_str[0] == '<') 3368 pt->p_stdin = argv[i].a_un.a_str + 1; 3369 else if (argv[i].a_un.a_str[0] == '>') 3370 pt->p_stdout = argv[i].a_un.a_str + 1; 3371 else 3372 pargv[pargc++] = argv[i].a_un.a_str; 3373 } 3374 pargv[pargc] = NULL; 3375 3376 /* 3377 * Since Pcreate() uses execvp() and "." may not be present in $PATH, 3378 * we must manually prepend "./" when the executable is a simple name. 3379 */ 3380 if (strchr(IOP_NAME(pt->p_aout_fio), '/') == NULL) { 3381 (void) snprintf(execname, sizeof (execname), "./%s", 3382 IOP_NAME(pt->p_aout_fio)); 3383 } else { 3384 (void) snprintf(execname, sizeof (execname), "%s", 3385 IOP_NAME(pt->p_aout_fio)); 3386 } 3387 3388 penv = mdb_alloc((mdb_nv_size(&pt->p_env)+ 1) * sizeof (char *), 3389 UM_SLEEP); 3390 for (mdb_nv_rewind(&pt->p_env), i = 0; 3391 (v = mdb_nv_advance(&pt->p_env)) != NULL; i++) 3392 penv[i] = mdb_nv_get_cookie(v); 3393 penv[i] = NULL; 3394 3395 P = Pxcreate(execname, (char **)pargv, penv, &perr, NULL, 0); 3396 mdb_free(pargv, sizeof (char *) * (argc + 2)); 3397 pt->p_stdin = pt->p_stdout = NULL; 3398 3399 mdb_free(penv, i * sizeof (char *)); 3400 3401 if (P == NULL) { 3402 warn("failed to create process: %s\n", Pcreate_error(perr)); 3403 return (set_errno(EMDB_TGT)); 3404 } 3405 3406 if (t->t_pshandle != NULL) { 3407 pt_pre_detach(t, TRUE); 3408 if (t->t_pshandle != pt->p_idlehandle) 3409 Prelease(t->t_pshandle, pt->p_rflags); 3410 } 3411 3412 (void) Punsetflags(P, PR_RLC); /* make sure run-on-last-close is off */ 3413 (void) Psetflags(P, PR_KLC); /* kill on last close by debugger */ 3414 pt->p_rflags = PRELEASE_KILL; /* kill on debugger Prelease */ 3415 t->t_pshandle = P; 3416 3417 pt_post_attach(t); 3418 pt_activate_common(t); 3419 (void) mdb_tgt_status(t, &t->t_status); 3420 mdb.m_flags |= MDB_FL_VCREATE; 3421 3422 return (0); 3423 } 3424 3425 /* 3426 * Forward a signal to the victim process in order to force it to stop or die. 3427 * Refer to the comments above pt_setrun(), below, for more info. 3428 */ 3429 /*ARGSUSED*/ 3430 static void 3431 pt_sigfwd(int sig, siginfo_t *sip, ucontext_t *ucp, mdb_tgt_t *t) 3432 { 3433 struct ps_prochandle *P = t->t_pshandle; 3434 const lwpstatus_t *psp = &Pstatus(P)->pr_lwp; 3435 pid_t pid = Pstatus(P)->pr_pid; 3436 long ctl[2]; 3437 3438 if (getpgid(pid) != mdb.m_pgid) { 3439 mdb_dprintf(MDB_DBG_TGT, "fwd SIG#%d to %d\n", sig, (int)pid); 3440 (void) kill(pid, sig); 3441 } 3442 3443 if (Pwait(P, 1) == 0 && (psp->pr_flags & PR_STOPPED) && 3444 psp->pr_why == PR_JOBCONTROL && Pdstop(P) == 0) { 3445 /* 3446 * If we're job control stopped and our DSTOP is pending, the 3447 * victim will never see our signal, so undo the kill() and 3448 * then send SIGCONT the victim to kick it out of the job 3449 * control stop and force our DSTOP to take effect. 3450 */ 3451 if ((psp->pr_flags & PR_DSTOP) && 3452 prismember(&Pstatus(P)->pr_sigpend, sig)) { 3453 ctl[0] = PCUNKILL; 3454 ctl[1] = sig; 3455 (void) write(Pctlfd(P), ctl, sizeof (ctl)); 3456 } 3457 3458 mdb_dprintf(MDB_DBG_TGT, "fwd SIGCONT to %d\n", (int)pid); 3459 (void) kill(pid, SIGCONT); 3460 } 3461 } 3462 3463 /* 3464 * Common code for step and continue: if no victim process has been created, 3465 * call pt_run() to create one. Then set the victim running, clearing any 3466 * pending fault. One special case is that if the victim was previously 3467 * stopped on reception of SIGINT, we know that SIGINT was traced and the user 3468 * requested the victim to stop, so clear this signal before continuing. 3469 * For all other traced signals, the signal will be delivered on continue. 3470 * 3471 * Once the victim process is running, we wait for it to stop on an event of 3472 * interest. Although libproc provides the basic primitive to wait for the 3473 * victim, we must be careful in our handling of signals. We want to allow the 3474 * user to issue a SIGINT or SIGQUIT using the designated terminal control 3475 * character (typically ^C and ^\), and have these signals stop the target and 3476 * return control to the debugger if the signals are traced. There are three 3477 * cases to be considered in our implementation: 3478 * 3479 * (1) If the debugger and victim are in the same process group, both receive 3480 * the signal from the terminal driver. The debugger returns from Pwait() with 3481 * errno = EINTR, so we want to loop back and continue waiting until the victim 3482 * stops on receipt of its SIGINT or SIGQUIT. 3483 * 3484 * (2) If the debugger and victim are in different process groups, and the 3485 * victim is a member of the foreground process group, it will receive the 3486 * signal from the terminal driver and the debugger will not. As such, we 3487 * will remain blocked in Pwait() until the victim stops on its signal. 3488 * 3489 * (3) If the debugger and victim are in different process groups, and the 3490 * debugger is a member of the foreground process group, it will receive the 3491 * signal from the terminal driver, and the victim will not. The debugger 3492 * returns from Pwait() with errno = EINTR, so we need to forward the signal 3493 * to the victim process directly and then Pwait() again for it to stop. 3494 * 3495 * We can observe that all three cases are handled by simply calling Pwait() 3496 * repeatedly if it fails with EINTR, and forwarding SIGINT and SIGQUIT to 3497 * the victim if it is in a different process group, using pt_sigfwd() above. 3498 * 3499 * An additional complication is that the process may not be able to field 3500 * the signal if it is currently stopped by job control. In this case, we 3501 * also DSTOP the process, and then send it a SIGCONT to wake it up from 3502 * job control and force it to re-enter stop() under the control of /proc. 3503 * 3504 * Finally, we would like to allow the user to suspend the process using the 3505 * terminal suspend character (typically ^Z) if both are in the same session. 3506 * We again employ pt_sigfwd() to forward SIGTSTP to the victim, wait for it to 3507 * stop from job control, and then capture it using /proc. Once the process 3508 * has stopped, normal SIGTSTP processing is restored and the user can issue 3509 * another ^Z in order to suspend the debugger and return to the parent shell. 3510 */ 3511 static int 3512 pt_setrun(mdb_tgt_t *t, mdb_tgt_status_t *tsp, int flags) 3513 { 3514 struct ps_prochandle *P = t->t_pshandle; 3515 pt_data_t *pt = t->t_data; 3516 pid_t old_pgid = -1; 3517 3518 mdb_signal_f *intf, *quitf, *tstpf; 3519 const lwpstatus_t *psp; 3520 void *intd, *quitd, *tstpd; 3521 3522 int sig = pt->p_signal; 3523 int error = 0; 3524 int pgid = -1; 3525 3526 pt->p_signal = 0; /* clear pending signal */ 3527 3528 if (P == NULL && pt_run(t, 0, NULL) == -1) 3529 return (-1); /* errno is set for us */ 3530 3531 P = t->t_pshandle; 3532 psp = &Pstatus(P)->pr_lwp; 3533 3534 if (sig == 0 && psp->pr_why == PR_SIGNALLED && psp->pr_what == SIGINT) 3535 flags |= PRCSIG; /* clear pending SIGINT */ 3536 else 3537 flags |= PRCFAULT; /* clear any pending fault (e.g. BPT) */ 3538 3539 intf = mdb_signal_gethandler(SIGINT, &intd); 3540 quitf = mdb_signal_gethandler(SIGQUIT, &quitd); 3541 tstpf = mdb_signal_gethandler(SIGTSTP, &tstpd); 3542 3543 (void) mdb_signal_sethandler(SIGINT, (mdb_signal_f *)pt_sigfwd, t); 3544 (void) mdb_signal_sethandler(SIGQUIT, (mdb_signal_f *)pt_sigfwd, t); 3545 (void) mdb_signal_sethandler(SIGTSTP, (mdb_signal_f *)pt_sigfwd, t); 3546 3547 if (sig != 0 && Pstate(P) == PS_RUN && 3548 kill(Pstatus(P)->pr_pid, sig) == -1) { 3549 error = errno; 3550 goto out; 3551 } 3552 3553 /* 3554 * If we attached to a job stopped background process in the same 3555 * session, make its pgid the foreground process group before running 3556 * it. Ignore SIGTTOU while doing this to avoid being suspended. 3557 */ 3558 if (mdb.m_flags & MDB_FL_JOBCTL) { 3559 (void) mdb_signal_sethandler(SIGTTOU, SIG_IGN, NULL); 3560 (void) IOP_CTL(mdb.m_term, TIOCGPGRP, &old_pgid); 3561 (void) IOP_CTL(mdb.m_term, TIOCSPGRP, 3562 (void *)&Pstatus(P)->pr_pgid); 3563 (void) mdb_signal_sethandler(SIGTTOU, SIG_DFL, NULL); 3564 } 3565 3566 if (Pstate(P) != PS_RUN && Psetrun(P, sig, flags) == -1) { 3567 error = errno; 3568 goto out; 3569 } 3570 3571 /* 3572 * If the process is stopped on job control, resume its process group 3573 * by sending it a SIGCONT if we are in the same session. Otherwise 3574 * we have no choice but to wait for someone else to foreground it. 3575 */ 3576 if (psp->pr_why == PR_JOBCONTROL) { 3577 if (mdb.m_flags & MDB_FL_JOBCTL) 3578 (void) kill(-Pstatus(P)->pr_pgid, SIGCONT); 3579 else if (mdb.m_term != NULL) 3580 warn("process is still suspended by job control ...\n"); 3581 } 3582 3583 /* 3584 * Wait for the process to stop. As described above, we loop around if 3585 * we are interrupted (EINTR). If we lose control, attempt to re-open 3586 * the process, or call pt_exec() if that fails to handle a re-exec. 3587 * If the process dies (ENOENT) or Pwait() fails, break out of the loop. 3588 */ 3589 while (Pwait(P, 0) == -1) { 3590 if (errno != EINTR) { 3591 if (Pstate(P) == PS_LOST) { 3592 if (Preopen(P) == 0) 3593 continue; /* Pwait() again */ 3594 else 3595 pt_exec(t, 0, NULL); 3596 } else if (errno != ENOENT) 3597 warn("failed to wait for event"); 3598 break; 3599 } 3600 } 3601 3602 /* 3603 * If we changed the foreground process group, restore the old pgid 3604 * while ignoring SIGTTOU so we are not accidentally suspended. 3605 */ 3606 if (old_pgid != -1) { 3607 (void) mdb_signal_sethandler(SIGTTOU, SIG_IGN, NULL); 3608 (void) IOP_CTL(mdb.m_term, TIOCSPGRP, &pgid); 3609 (void) mdb_signal_sethandler(SIGTTOU, SIG_DFL, NULL); 3610 } 3611 3612 /* 3613 * If we're now stopped on exit from a successful exec, release any 3614 * vfork parents and clean out their address space before returning 3615 * to tgt_continue() and perturbing the list of armed event specs. 3616 * If we're stopped for any other reason, just update the mappings. 3617 */ 3618 switch (Pstate(P)) { 3619 case PS_STOP: 3620 if (psp->pr_why == PR_SYSEXIT && psp->pr_errno == 0 && 3621 psp->pr_what == SYS_execve) 3622 pt_release_parents(t); 3623 else 3624 Pupdate_maps(P); 3625 break; 3626 3627 case PS_UNDEAD: 3628 case PS_LOST: 3629 pt_release_parents(t); 3630 break; 3631 } 3632 3633 out: 3634 (void) mdb_signal_sethandler(SIGINT, intf, intd); 3635 (void) mdb_signal_sethandler(SIGQUIT, quitf, quitd); 3636 (void) mdb_signal_sethandler(SIGTSTP, tstpf, tstpd); 3637 (void) pt_status(t, tsp); 3638 3639 return (error ? set_errno(error) : 0); 3640 } 3641 3642 static int 3643 pt_step(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 3644 { 3645 return (pt_setrun(t, tsp, PRSTEP)); 3646 } 3647 3648 static int 3649 pt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp) 3650 { 3651 return (pt_setrun(t, tsp, 0)); 3652 } 3653 3654 static int 3655 pt_signal(mdb_tgt_t *t, int sig) 3656 { 3657 pt_data_t *pt = t->t_data; 3658 3659 if (sig > 0 && sig <= pt->p_maxsig) { 3660 pt->p_signal = sig; /* pending until next pt_setrun */ 3661 return (0); 3662 } 3663 3664 return (set_errno(EMDB_BADSIGNUM)); 3665 } 3666 3667 static int 3668 pt_sysenter_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 3669 { 3670 struct ps_prochandle *P = t->t_pshandle; 3671 3672 if (P != NULL && Pstate(P) < PS_LOST) { 3673 sep->se_data = args; /* data is raw system call number */ 3674 return (Psysentry(P, (intptr_t)args, TRUE) < 0 ? -1 : 0); 3675 } 3676 3677 return (set_errno(EMDB_NOPROC)); 3678 } 3679 3680 static void 3681 pt_sysenter_dtor(mdb_tgt_t *t, mdb_sespec_t *sep) 3682 { 3683 (void) Psysentry(t->t_pshandle, (intptr_t)sep->se_data, FALSE); 3684 } 3685 3686 /*ARGSUSED*/ 3687 static char * 3688 pt_sysenter_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep, 3689 mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes) 3690 { 3691 char name[32]; 3692 int sysnum; 3693 3694 if (vep != NULL) 3695 sysnum = (intptr_t)vep->ve_args; 3696 else 3697 sysnum = (intptr_t)sep->se_data; 3698 3699 (void) proc_sysname(sysnum, name, sizeof (name)); 3700 (void) mdb_iob_snprintf(buf, nbytes, "stop on entry to %s", name); 3701 3702 return (buf); 3703 } 3704 3705 /*ARGSUSED*/ 3706 static int 3707 pt_sysenter_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 3708 { 3709 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 3710 int sysnum = (intptr_t)sep->se_data; 3711 3712 return (psp->pr_why == PR_SYSENTRY && psp->pr_what == sysnum); 3713 } 3714 3715 static const mdb_se_ops_t proc_sysenter_ops = { 3716 pt_sysenter_ctor, /* se_ctor */ 3717 pt_sysenter_dtor, /* se_dtor */ 3718 pt_sysenter_info, /* se_info */ 3719 no_se_secmp, /* se_secmp */ 3720 no_se_vecmp, /* se_vecmp */ 3721 no_se_arm, /* se_arm */ 3722 no_se_disarm, /* se_disarm */ 3723 no_se_cont, /* se_cont */ 3724 pt_sysenter_match /* se_match */ 3725 }; 3726 3727 static int 3728 pt_sysexit_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 3729 { 3730 struct ps_prochandle *P = t->t_pshandle; 3731 3732 if (P != NULL && Pstate(P) < PS_LOST) { 3733 sep->se_data = args; /* data is raw system call number */ 3734 return (Psysexit(P, (intptr_t)args, TRUE) < 0 ? -1 : 0); 3735 } 3736 3737 return (set_errno(EMDB_NOPROC)); 3738 } 3739 3740 static void 3741 pt_sysexit_dtor(mdb_tgt_t *t, mdb_sespec_t *sep) 3742 { 3743 (void) Psysexit(t->t_pshandle, (intptr_t)sep->se_data, FALSE); 3744 } 3745 3746 /*ARGSUSED*/ 3747 static char * 3748 pt_sysexit_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep, 3749 mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes) 3750 { 3751 char name[32]; 3752 int sysnum; 3753 3754 if (vep != NULL) 3755 sysnum = (intptr_t)vep->ve_args; 3756 else 3757 sysnum = (intptr_t)sep->se_data; 3758 3759 (void) proc_sysname(sysnum, name, sizeof (name)); 3760 (void) mdb_iob_snprintf(buf, nbytes, "stop on exit from %s", name); 3761 3762 return (buf); 3763 } 3764 3765 /*ARGSUSED*/ 3766 static int 3767 pt_sysexit_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 3768 { 3769 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 3770 int sysnum = (intptr_t)sep->se_data; 3771 3772 return (psp->pr_why == PR_SYSEXIT && psp->pr_what == sysnum); 3773 } 3774 3775 static const mdb_se_ops_t proc_sysexit_ops = { 3776 pt_sysexit_ctor, /* se_ctor */ 3777 pt_sysexit_dtor, /* se_dtor */ 3778 pt_sysexit_info, /* se_info */ 3779 no_se_secmp, /* se_secmp */ 3780 no_se_vecmp, /* se_vecmp */ 3781 no_se_arm, /* se_arm */ 3782 no_se_disarm, /* se_disarm */ 3783 no_se_cont, /* se_cont */ 3784 pt_sysexit_match /* se_match */ 3785 }; 3786 3787 static int 3788 pt_signal_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 3789 { 3790 struct ps_prochandle *P = t->t_pshandle; 3791 3792 if (P != NULL && Pstate(P) < PS_LOST) { 3793 sep->se_data = args; /* data is raw signal number */ 3794 return (Psignal(P, (intptr_t)args, TRUE) < 0 ? -1 : 0); 3795 } 3796 3797 return (set_errno(EMDB_NOPROC)); 3798 } 3799 3800 static void 3801 pt_signal_dtor(mdb_tgt_t *t, mdb_sespec_t *sep) 3802 { 3803 (void) Psignal(t->t_pshandle, (intptr_t)sep->se_data, FALSE); 3804 } 3805 3806 /*ARGSUSED*/ 3807 static char * 3808 pt_signal_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep, 3809 mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes) 3810 { 3811 char name[SIG2STR_MAX]; 3812 int signum; 3813 3814 if (vep != NULL) 3815 signum = (intptr_t)vep->ve_args; 3816 else 3817 signum = (intptr_t)sep->se_data; 3818 3819 (void) proc_signame(signum, name, sizeof (name)); 3820 (void) mdb_iob_snprintf(buf, nbytes, "stop on %s", name); 3821 3822 return (buf); 3823 } 3824 3825 /*ARGSUSED*/ 3826 static int 3827 pt_signal_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 3828 { 3829 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 3830 int signum = (intptr_t)sep->se_data; 3831 3832 return (psp->pr_why == PR_SIGNALLED && psp->pr_what == signum); 3833 } 3834 3835 static const mdb_se_ops_t proc_signal_ops = { 3836 pt_signal_ctor, /* se_ctor */ 3837 pt_signal_dtor, /* se_dtor */ 3838 pt_signal_info, /* se_info */ 3839 no_se_secmp, /* se_secmp */ 3840 no_se_vecmp, /* se_vecmp */ 3841 no_se_arm, /* se_arm */ 3842 no_se_disarm, /* se_disarm */ 3843 no_se_cont, /* se_cont */ 3844 pt_signal_match /* se_match */ 3845 }; 3846 3847 static int 3848 pt_fault_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 3849 { 3850 struct ps_prochandle *P = t->t_pshandle; 3851 3852 if (P != NULL && Pstate(P) < PS_LOST) { 3853 sep->se_data = args; /* data is raw fault number */ 3854 return (Pfault(P, (intptr_t)args, TRUE) < 0 ? -1 : 0); 3855 } 3856 3857 return (set_errno(EMDB_NOPROC)); 3858 } 3859 3860 static void 3861 pt_fault_dtor(mdb_tgt_t *t, mdb_sespec_t *sep) 3862 { 3863 int fault = (intptr_t)sep->se_data; 3864 3865 if (fault != FLTBPT && fault != FLTTRACE && fault != FLTWATCH) 3866 (void) Pfault(t->t_pshandle, fault, FALSE); 3867 } 3868 3869 /*ARGSUSED*/ 3870 static char * 3871 pt_fault_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep, 3872 mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes) 3873 { 3874 char name[32]; 3875 int fltnum; 3876 3877 if (vep != NULL) 3878 fltnum = (intptr_t)vep->ve_args; 3879 else 3880 fltnum = (intptr_t)sep->se_data; 3881 3882 (void) proc_fltname(fltnum, name, sizeof (name)); 3883 (void) mdb_iob_snprintf(buf, nbytes, "stop on %s", name); 3884 3885 return (buf); 3886 } 3887 3888 /*ARGSUSED*/ 3889 static int 3890 pt_fault_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 3891 { 3892 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 3893 int fltnum = (intptr_t)sep->se_data; 3894 3895 return (psp->pr_why == PR_FAULTED && psp->pr_what == fltnum); 3896 } 3897 3898 static const mdb_se_ops_t proc_fault_ops = { 3899 pt_fault_ctor, /* se_ctor */ 3900 pt_fault_dtor, /* se_dtor */ 3901 pt_fault_info, /* se_info */ 3902 no_se_secmp, /* se_secmp */ 3903 no_se_vecmp, /* se_vecmp */ 3904 no_se_arm, /* se_arm */ 3905 no_se_disarm, /* se_disarm */ 3906 no_se_cont, /* se_cont */ 3907 pt_fault_match /* se_match */ 3908 }; 3909 3910 /* 3911 * Callback for pt_ignore() dcmd above: for each VID, determine if it 3912 * corresponds to a vespec that traces the specified signal, and delete it. 3913 */ 3914 /*ARGSUSED*/ 3915 static int 3916 pt_ignore_sig(mdb_tgt_t *t, void *sig, int vid, void *data) 3917 { 3918 mdb_vespec_t *vep = mdb_tgt_vespec_lookup(t, vid); 3919 3920 if (vep->ve_se->se_ops == &proc_signal_ops && vep->ve_args == sig) 3921 (void) mdb_tgt_vespec_delete(t, vid); 3922 3923 return (0); 3924 } 3925 3926 static int 3927 pt_brkpt_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 3928 { 3929 pt_data_t *pt = t->t_data; 3930 pt_bparg_t *pta = args; 3931 pt_brkpt_t *ptb; 3932 GElf_Sym s; 3933 3934 if (t->t_pshandle == NULL || Pstate(t->t_pshandle) >= PS_LOST) 3935 return (set_errno(EMDB_NOPROC)); 3936 3937 if (pta->pta_symbol != NULL) { 3938 if (!pt->p_rtld_finished && 3939 strchr(pta->pta_symbol, '`') == NULL) 3940 return (set_errno(EMDB_NOSYM)); 3941 if (mdb_tgt_lookup_by_scope(t, pta->pta_symbol, &s, 3942 NULL) == -1) { 3943 if (errno != EMDB_NOOBJ && !(errno == EMDB_NOSYM && 3944 (!(mdb.m_flags & MDB_FL_BPTNOSYMSTOP) || 3945 !pt->p_rtld_finished))) { 3946 warn("breakpoint %s activation failed", 3947 pta->pta_symbol); 3948 } 3949 return (-1); /* errno is set for us */ 3950 } 3951 3952 pta->pta_addr = (uintptr_t)s.st_value; 3953 } 3954 3955 #ifdef __sparc 3956 if (pta->pta_addr & 3) 3957 return (set_errno(EMDB_BPALIGN)); 3958 #endif 3959 3960 if (Paddr_to_map(t->t_pshandle, pta->pta_addr) == NULL) 3961 return (set_errno(EMDB_NOMAP)); 3962 3963 ptb = mdb_alloc(sizeof (pt_brkpt_t), UM_SLEEP); 3964 ptb->ptb_addr = pta->pta_addr; 3965 ptb->ptb_instr = NULL; 3966 sep->se_data = ptb; 3967 3968 return (0); 3969 } 3970 3971 /*ARGSUSED*/ 3972 static void 3973 pt_brkpt_dtor(mdb_tgt_t *t, mdb_sespec_t *sep) 3974 { 3975 mdb_free(sep->se_data, sizeof (pt_brkpt_t)); 3976 } 3977 3978 /*ARGSUSED*/ 3979 static char * 3980 pt_brkpt_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep, 3981 mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes) 3982 { 3983 uintptr_t addr = NULL; 3984 3985 if (vep != NULL) { 3986 pt_bparg_t *pta = vep->ve_args; 3987 3988 if (pta->pta_symbol != NULL) { 3989 (void) mdb_iob_snprintf(buf, nbytes, "stop at %s", 3990 pta->pta_symbol); 3991 } else { 3992 (void) mdb_iob_snprintf(buf, nbytes, "stop at %a", 3993 pta->pta_addr); 3994 addr = pta->pta_addr; 3995 } 3996 3997 } else { 3998 addr = ((pt_brkpt_t *)sep->se_data)->ptb_addr; 3999 (void) mdb_iob_snprintf(buf, nbytes, "stop at %a", addr); 4000 } 4001 4002 sp->spec_base = addr; 4003 sp->spec_size = sizeof (instr_t); 4004 4005 return (buf); 4006 } 4007 4008 static int 4009 pt_brkpt_secmp(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 4010 { 4011 pt_brkpt_t *ptb = sep->se_data; 4012 pt_bparg_t *pta = args; 4013 GElf_Sym sym; 4014 4015 if (pta->pta_symbol != NULL) { 4016 return (mdb_tgt_lookup_by_scope(t, pta->pta_symbol, 4017 &sym, NULL) == 0 && sym.st_value == ptb->ptb_addr); 4018 } 4019 4020 return (pta->pta_addr == ptb->ptb_addr); 4021 } 4022 4023 /*ARGSUSED*/ 4024 static int 4025 pt_brkpt_vecmp(mdb_tgt_t *t, mdb_vespec_t *vep, void *args) 4026 { 4027 pt_bparg_t *pta1 = vep->ve_args; 4028 pt_bparg_t *pta2 = args; 4029 4030 if (pta1->pta_symbol != NULL && pta2->pta_symbol != NULL) 4031 return (strcmp(pta1->pta_symbol, pta2->pta_symbol) == 0); 4032 4033 if (pta1->pta_symbol == NULL && pta2->pta_symbol == NULL) 4034 return (pta1->pta_addr == pta2->pta_addr); 4035 4036 return (0); /* fail if one is symbolic, other is an explicit address */ 4037 } 4038 4039 static int 4040 pt_brkpt_arm(mdb_tgt_t *t, mdb_sespec_t *sep) 4041 { 4042 pt_brkpt_t *ptb = sep->se_data; 4043 return (Psetbkpt(t->t_pshandle, ptb->ptb_addr, &ptb->ptb_instr)); 4044 } 4045 4046 /* 4047 * In order to disarm a breakpoint, we replace the trap instruction at ptb_addr 4048 * with the saved instruction. However, if we have stopped after a successful 4049 * exec(2), we do not want to restore ptb_instr because the address space has 4050 * now been replaced with the text of a different executable, and so restoring 4051 * the saved instruction would be incorrect. The exec itself has effectively 4052 * removed all breakpoint trap instructions for us, so we can just return. 4053 */ 4054 static int 4055 pt_brkpt_disarm(mdb_tgt_t *t, mdb_sespec_t *sep) 4056 { 4057 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 4058 pt_brkpt_t *ptb = sep->se_data; 4059 4060 if (psp->pr_why == PR_SYSEXIT && psp->pr_errno == 0 && 4061 psp->pr_what == SYS_execve) 4062 return (0); /* do not restore saved instruction */ 4063 4064 return (Pdelbkpt(t->t_pshandle, ptb->ptb_addr, ptb->ptb_instr)); 4065 } 4066 4067 /* 4068 * Determine whether the specified sespec is an armed watchpoint that overlaps 4069 * with the given breakpoint and has the given flags set. We use this to find 4070 * conflicts with breakpoints, below. 4071 */ 4072 static int 4073 pt_wp_overlap(mdb_sespec_t *sep, pt_brkpt_t *ptb, int flags) 4074 { 4075 const prwatch_t *wp = sep->se_data; 4076 4077 return (sep->se_state == MDB_TGT_SPEC_ARMED && 4078 sep->se_ops == &proc_wapt_ops && (wp->pr_wflags & flags) && 4079 ptb->ptb_addr - wp->pr_vaddr < wp->pr_size); 4080 } 4081 4082 /* 4083 * We step over breakpoints using Pxecbkpt() in libproc. If a conflicting 4084 * watchpoint is present, we must temporarily remove it before stepping over 4085 * the breakpoint so we do not immediately re-trigger the watchpoint. We know 4086 * the watchpoint has already triggered on our trap instruction as part of 4087 * fetching it. Before we return, we must re-install any disabled watchpoints. 4088 */ 4089 static int 4090 pt_brkpt_cont(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 4091 { 4092 pt_brkpt_t *ptb = sep->se_data; 4093 int status = -1; 4094 int error; 4095 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 4096 4097 /* 4098 * If the PC no longer matches our original address, then the user has 4099 * changed it while we have been stopped. In this case, it no longer 4100 * makes any sense to continue over this breakpoint. We return as if we 4101 * continued normally. 4102 */ 4103 if ((uintptr_t)psp->pr_info.si_addr != psp->pr_reg[R_PC]) 4104 return (pt_status(t, tsp)); 4105 4106 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 4107 if (pt_wp_overlap(sep, ptb, WA_EXEC)) 4108 (void) Pdelwapt(t->t_pshandle, sep->se_data); 4109 } 4110 4111 if (Pxecbkpt(t->t_pshandle, ptb->ptb_instr) == 0 && 4112 Pdelbkpt(t->t_pshandle, ptb->ptb_addr, ptb->ptb_instr) == 0) 4113 status = pt_status(t, tsp); 4114 4115 error = errno; /* save errno from Pxecbkpt, Pdelbkpt, or pt_status */ 4116 4117 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 4118 if (pt_wp_overlap(sep, ptb, WA_EXEC) && 4119 Psetwapt(t->t_pshandle, sep->se_data) == -1) { 4120 sep->se_state = MDB_TGT_SPEC_ERROR; 4121 sep->se_errno = errno; 4122 } 4123 } 4124 4125 (void) set_errno(error); 4126 return (status); 4127 } 4128 4129 /*ARGSUSED*/ 4130 static int 4131 pt_brkpt_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 4132 { 4133 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 4134 pt_brkpt_t *ptb = sep->se_data; 4135 4136 return (psp->pr_why == PR_FAULTED && psp->pr_what == FLTBPT && 4137 psp->pr_reg[R_PC] == ptb->ptb_addr); 4138 } 4139 4140 static const mdb_se_ops_t proc_brkpt_ops = { 4141 pt_brkpt_ctor, /* se_ctor */ 4142 pt_brkpt_dtor, /* se_dtor */ 4143 pt_brkpt_info, /* se_info */ 4144 pt_brkpt_secmp, /* se_secmp */ 4145 pt_brkpt_vecmp, /* se_vecmp */ 4146 pt_brkpt_arm, /* se_arm */ 4147 pt_brkpt_disarm, /* se_disarm */ 4148 pt_brkpt_cont, /* se_cont */ 4149 pt_brkpt_match /* se_match */ 4150 }; 4151 4152 static int 4153 pt_wapt_ctor(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 4154 { 4155 if (t->t_pshandle == NULL || Pstate(t->t_pshandle) >= PS_LOST) 4156 return (set_errno(EMDB_NOPROC)); 4157 4158 sep->se_data = mdb_alloc(sizeof (prwatch_t), UM_SLEEP); 4159 bcopy(args, sep->se_data, sizeof (prwatch_t)); 4160 return (0); 4161 } 4162 4163 /*ARGSUSED*/ 4164 static void 4165 pt_wapt_dtor(mdb_tgt_t *t, mdb_sespec_t *sep) 4166 { 4167 mdb_free(sep->se_data, sizeof (prwatch_t)); 4168 } 4169 4170 /*ARGSUSED*/ 4171 static char * 4172 pt_wapt_info(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_vespec_t *vep, 4173 mdb_tgt_spec_desc_t *sp, char *buf, size_t nbytes) 4174 { 4175 prwatch_t *wp = vep != NULL ? vep->ve_args : sep->se_data; 4176 char desc[24]; 4177 4178 ASSERT(wp->pr_wflags != 0); 4179 desc[0] = '\0'; 4180 4181 switch (wp->pr_wflags) { 4182 case WA_READ: 4183 (void) strcat(desc, "/read"); 4184 break; 4185 case WA_WRITE: 4186 (void) strcat(desc, "/write"); 4187 break; 4188 case WA_EXEC: 4189 (void) strcat(desc, "/exec"); 4190 break; 4191 default: 4192 if (wp->pr_wflags & WA_READ) 4193 (void) strcat(desc, "/r"); 4194 if (wp->pr_wflags & WA_WRITE) 4195 (void) strcat(desc, "/w"); 4196 if (wp->pr_wflags & WA_EXEC) 4197 (void) strcat(desc, "/x"); 4198 } 4199 4200 (void) mdb_iob_snprintf(buf, nbytes, "stop on %s of [%la, %la)", 4201 desc + 1, wp->pr_vaddr, wp->pr_vaddr + wp->pr_size); 4202 4203 sp->spec_base = wp->pr_vaddr; 4204 sp->spec_size = wp->pr_size; 4205 4206 return (buf); 4207 } 4208 4209 /*ARGSUSED*/ 4210 static int 4211 pt_wapt_secmp(mdb_tgt_t *t, mdb_sespec_t *sep, void *args) 4212 { 4213 prwatch_t *wp1 = sep->se_data; 4214 prwatch_t *wp2 = args; 4215 4216 return (wp1->pr_vaddr == wp2->pr_vaddr && 4217 wp1->pr_size == wp2->pr_size && wp1->pr_wflags == wp2->pr_wflags); 4218 } 4219 4220 /*ARGSUSED*/ 4221 static int 4222 pt_wapt_vecmp(mdb_tgt_t *t, mdb_vespec_t *vep, void *args) 4223 { 4224 prwatch_t *wp1 = vep->ve_args; 4225 prwatch_t *wp2 = args; 4226 4227 return (wp1->pr_vaddr == wp2->pr_vaddr && 4228 wp1->pr_size == wp2->pr_size && wp1->pr_wflags == wp2->pr_wflags); 4229 } 4230 4231 static int 4232 pt_wapt_arm(mdb_tgt_t *t, mdb_sespec_t *sep) 4233 { 4234 return (Psetwapt(t->t_pshandle, sep->se_data)); 4235 } 4236 4237 static int 4238 pt_wapt_disarm(mdb_tgt_t *t, mdb_sespec_t *sep) 4239 { 4240 return (Pdelwapt(t->t_pshandle, sep->se_data)); 4241 } 4242 4243 /* 4244 * Determine whether the specified sespec is an armed breakpoint at the 4245 * given %pc. We use this to find conflicts with watchpoints below. 4246 */ 4247 static int 4248 pt_bp_overlap(mdb_sespec_t *sep, uintptr_t pc) 4249 { 4250 pt_brkpt_t *ptb = sep->se_data; 4251 4252 return (sep->se_state == MDB_TGT_SPEC_ARMED && 4253 sep->se_ops == &proc_brkpt_ops && ptb->ptb_addr == pc); 4254 } 4255 4256 /* 4257 * We step over watchpoints using Pxecwapt() in libproc. If a conflicting 4258 * breakpoint is present, we must temporarily disarm it before stepping 4259 * over the watchpoint so we do not immediately re-trigger the breakpoint. 4260 * This is similar to the case handled in pt_brkpt_cont(), above. 4261 */ 4262 static int 4263 pt_wapt_cont(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 4264 { 4265 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 4266 mdb_sespec_t *bep = NULL; 4267 int status = -1; 4268 int error; 4269 4270 /* 4271 * If the PC no longer matches our original address, then the user has 4272 * changed it while we have been stopped. In this case, it no longer 4273 * makes any sense to continue over this instruction. We return as if 4274 * we continued normally. 4275 */ 4276 if ((uintptr_t)psp->pr_info.si_pc != psp->pr_reg[R_PC]) 4277 return (pt_status(t, tsp)); 4278 4279 if (psp->pr_info.si_code != TRAP_XWATCH) { 4280 for (bep = mdb_list_next(&t->t_active); bep != NULL; 4281 bep = mdb_list_next(bep)) { 4282 if (pt_bp_overlap(bep, psp->pr_reg[R_PC])) { 4283 (void) bep->se_ops->se_disarm(t, bep); 4284 bep->se_state = MDB_TGT_SPEC_ACTIVE; 4285 break; 4286 } 4287 } 4288 } 4289 4290 if (Pxecwapt(t->t_pshandle, sep->se_data) == 0) 4291 status = pt_status(t, tsp); 4292 4293 error = errno; /* save errno from Pxecwapt or pt_status */ 4294 4295 if (bep != NULL) 4296 mdb_tgt_sespec_arm_one(t, bep); 4297 4298 (void) set_errno(error); 4299 return (status); 4300 } 4301 4302 /*ARGSUSED*/ 4303 static int 4304 pt_wapt_match(mdb_tgt_t *t, mdb_sespec_t *sep, mdb_tgt_status_t *tsp) 4305 { 4306 const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; 4307 prwatch_t *wp = sep->se_data; 4308 4309 return (psp->pr_why == PR_FAULTED && psp->pr_what == FLTWATCH && 4310 (uintptr_t)psp->pr_info.si_addr - wp->pr_vaddr < wp->pr_size); 4311 } 4312 4313 static const mdb_se_ops_t proc_wapt_ops = { 4314 pt_wapt_ctor, /* se_ctor */ 4315 pt_wapt_dtor, /* se_dtor */ 4316 pt_wapt_info, /* se_info */ 4317 pt_wapt_secmp, /* se_secmp */ 4318 pt_wapt_vecmp, /* se_vecmp */ 4319 pt_wapt_arm, /* se_arm */ 4320 pt_wapt_disarm, /* se_disarm */ 4321 pt_wapt_cont, /* se_cont */ 4322 pt_wapt_match /* se_match */ 4323 }; 4324 4325 static void 4326 pt_bparg_dtor(mdb_vespec_t *vep) 4327 { 4328 pt_bparg_t *pta = vep->ve_args; 4329 4330 if (pta->pta_symbol != NULL) 4331 strfree(pta->pta_symbol); 4332 4333 mdb_free(pta, sizeof (pt_bparg_t)); 4334 } 4335 4336 static int 4337 pt_add_vbrkpt(mdb_tgt_t *t, uintptr_t addr, 4338 int spec_flags, mdb_tgt_se_f *func, void *data) 4339 { 4340 pt_bparg_t *pta = mdb_alloc(sizeof (pt_bparg_t), UM_SLEEP); 4341 4342 pta->pta_symbol = NULL; 4343 pta->pta_addr = addr; 4344 4345 return (mdb_tgt_vespec_insert(t, &proc_brkpt_ops, spec_flags, 4346 func, data, pta, pt_bparg_dtor)); 4347 } 4348 4349 static int 4350 pt_add_sbrkpt(mdb_tgt_t *t, const char *sym, 4351 int spec_flags, mdb_tgt_se_f *func, void *data) 4352 { 4353 pt_bparg_t *pta; 4354 4355 if (sym[0] == '`') { 4356 (void) set_errno(EMDB_NOOBJ); 4357 return (0); 4358 } 4359 4360 if (sym[strlen(sym) - 1] == '`') { 4361 (void) set_errno(EMDB_NOSYM); 4362 return (0); 4363 } 4364 4365 pta = mdb_alloc(sizeof (pt_bparg_t), UM_SLEEP); 4366 pta->pta_symbol = strdup(sym); 4367 pta->pta_addr = NULL; 4368 4369 return (mdb_tgt_vespec_insert(t, &proc_brkpt_ops, spec_flags, 4370 func, data, pta, pt_bparg_dtor)); 4371 } 4372 4373 static int 4374 pt_wparg_overlap(const prwatch_t *wp1, const prwatch_t *wp2) 4375 { 4376 if (wp2->pr_vaddr + wp2->pr_size <= wp1->pr_vaddr) 4377 return (0); /* no range overlap */ 4378 4379 if (wp1->pr_vaddr + wp1->pr_size <= wp2->pr_vaddr) 4380 return (0); /* no range overlap */ 4381 4382 return (wp1->pr_vaddr != wp2->pr_vaddr || 4383 wp1->pr_size != wp2->pr_size || wp1->pr_wflags != wp2->pr_wflags); 4384 } 4385 4386 static void 4387 pt_wparg_dtor(mdb_vespec_t *vep) 4388 { 4389 mdb_free(vep->ve_args, sizeof (prwatch_t)); 4390 } 4391 4392 static int 4393 pt_add_vwapt(mdb_tgt_t *t, uintptr_t addr, size_t len, uint_t wflags, 4394 int spec_flags, mdb_tgt_se_f *func, void *data) 4395 { 4396 prwatch_t *wp = mdb_alloc(sizeof (prwatch_t), UM_SLEEP); 4397 mdb_sespec_t *sep; 4398 4399 wp->pr_vaddr = addr; 4400 wp->pr_size = len; 4401 wp->pr_wflags = 0; 4402 4403 if (wflags & MDB_TGT_WA_R) 4404 wp->pr_wflags |= WA_READ; 4405 if (wflags & MDB_TGT_WA_W) 4406 wp->pr_wflags |= WA_WRITE; 4407 if (wflags & MDB_TGT_WA_X) 4408 wp->pr_wflags |= WA_EXEC; 4409 4410 for (sep = mdb_list_next(&t->t_active); sep; sep = mdb_list_next(sep)) { 4411 if (sep->se_ops == &proc_wapt_ops && 4412 mdb_list_next(&sep->se_velist) != NULL && 4413 pt_wparg_overlap(wp, sep->se_data)) 4414 goto dup; 4415 } 4416 4417 for (sep = mdb_list_next(&t->t_idle); sep; sep = mdb_list_next(sep)) { 4418 if (sep->se_ops == &proc_wapt_ops && pt_wparg_overlap(wp, 4419 ((mdb_vespec_t *)mdb_list_next(&sep->se_velist))->ve_args)) 4420 goto dup; 4421 } 4422 4423 return (mdb_tgt_vespec_insert(t, &proc_wapt_ops, spec_flags, 4424 func, data, wp, pt_wparg_dtor)); 4425 4426 dup: 4427 mdb_free(wp, sizeof (prwatch_t)); 4428 (void) set_errno(EMDB_WPDUP); 4429 return (0); 4430 } 4431 4432 static int 4433 pt_add_sysenter(mdb_tgt_t *t, int sysnum, 4434 int spec_flags, mdb_tgt_se_f *func, void *data) 4435 { 4436 if (sysnum <= 0 || sysnum > PRMAXSYS) { 4437 (void) set_errno(EMDB_BADSYSNUM); 4438 return (0); 4439 } 4440 4441 return (mdb_tgt_vespec_insert(t, &proc_sysenter_ops, spec_flags, 4442 func, data, (void *)(uintptr_t)sysnum, no_ve_dtor)); 4443 } 4444 4445 static int 4446 pt_add_sysexit(mdb_tgt_t *t, int sysnum, 4447 int spec_flags, mdb_tgt_se_f *func, void *data) 4448 { 4449 if (sysnum <= 0 || sysnum > PRMAXSYS) { 4450 (void) set_errno(EMDB_BADSYSNUM); 4451 return (0); 4452 } 4453 4454 return (mdb_tgt_vespec_insert(t, &proc_sysexit_ops, spec_flags, 4455 func, data, (void *)(uintptr_t)sysnum, no_ve_dtor)); 4456 } 4457 4458 static int 4459 pt_add_signal(mdb_tgt_t *t, int signum, 4460 int spec_flags, mdb_tgt_se_f *func, void *data) 4461 { 4462 pt_data_t *pt = t->t_data; 4463 4464 if (signum <= 0 || signum > pt->p_maxsig) { 4465 (void) set_errno(EMDB_BADSIGNUM); 4466 return (0); 4467 } 4468 4469 return (mdb_tgt_vespec_insert(t, &proc_signal_ops, spec_flags, 4470 func, data, (void *)(uintptr_t)signum, no_ve_dtor)); 4471 } 4472 4473 static int 4474 pt_add_fault(mdb_tgt_t *t, int fltnum, 4475 int spec_flags, mdb_tgt_se_f *func, void *data) 4476 { 4477 if (fltnum <= 0 || fltnum > PRMAXFAULT) { 4478 (void) set_errno(EMDB_BADFLTNUM); 4479 return (0); 4480 } 4481 4482 return (mdb_tgt_vespec_insert(t, &proc_fault_ops, spec_flags, 4483 func, data, (void *)(uintptr_t)fltnum, no_ve_dtor)); 4484 } 4485 4486 static int 4487 pt_getareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, 4488 const char *rname, mdb_tgt_reg_t *rp) 4489 { 4490 pt_data_t *pt = t->t_data; 4491 prgregset_t grs; 4492 mdb_var_t *v; 4493 4494 if (t->t_pshandle == NULL) 4495 return (set_errno(EMDB_NOPROC)); 4496 4497 if ((v = mdb_nv_lookup(&pt->p_regs, rname)) != NULL) { 4498 uintmax_t rd_nval = mdb_nv_get_value(v); 4499 ushort_t rd_num = MDB_TGT_R_NUM(rd_nval); 4500 ushort_t rd_flags = MDB_TGT_R_FLAGS(rd_nval); 4501 4502 if (!MDB_TGT_R_IS_FP(rd_flags)) { 4503 mdb_tgt_reg_t r = 0; 4504 4505 #if defined(__sparc) && defined(_ILP32) 4506 /* 4507 * If we are debugging on 32-bit SPARC, the globals and 4508 * outs can have 32 upper bits hiding in the xregs. 4509 */ 4510 /* gcc doesn't like >= R_G0 because R_G0 == 0 */ 4511 int is_g = (rd_num == R_G0 || 4512 rd_num >= R_G1 && rd_num <= R_G7); 4513 int is_o = (rd_num >= R_O0 && rd_num <= R_O7); 4514 prxregset_t xrs; 4515 4516 if (is_g && PTL_GETXREGS(t, tid, &xrs) == 0 && 4517 xrs.pr_type == XR_TYPE_V8P) { 4518 r |= (uint64_t)xrs.pr_un.pr_v8p.pr_xg[ 4519 rd_num - R_G0 + XR_G0] << 32; 4520 } 4521 4522 if (is_o && PTL_GETXREGS(t, tid, &xrs) == 0 && 4523 xrs.pr_type == XR_TYPE_V8P) { 4524 r |= (uint64_t)xrs.pr_un.pr_v8p.pr_xo[ 4525 rd_num - R_O0 + XR_O0] << 32; 4526 } 4527 #endif /* __sparc && _ILP32 */ 4528 4529 /* 4530 * Avoid sign-extension by casting: recall that procfs 4531 * defines prgreg_t as a long or int and our native 4532 * register handling uses uint64_t's. 4533 */ 4534 if (PTL_GETREGS(t, tid, grs) == 0) { 4535 *rp = r | (ulong_t)grs[rd_num]; 4536 if (rd_flags & MDB_TGT_R_32) 4537 *rp &= 0xffffffffULL; 4538 else if (rd_flags & MDB_TGT_R_16) 4539 *rp &= 0xffffULL; 4540 else if (rd_flags & MDB_TGT_R_8H) 4541 *rp = (*rp & 0xff00ULL) >> 8; 4542 else if (rd_flags & MDB_TGT_R_8L) 4543 *rp &= 0xffULL; 4544 return (0); 4545 } 4546 return (-1); 4547 } else 4548 return (pt_getfpreg(t, tid, rd_num, rd_flags, rp)); 4549 } 4550 4551 return (set_errno(EMDB_BADREG)); 4552 } 4553 4554 static int 4555 pt_putareg(mdb_tgt_t *t, mdb_tgt_tid_t tid, const char *rname, mdb_tgt_reg_t r) 4556 { 4557 pt_data_t *pt = t->t_data; 4558 prgregset_t grs; 4559 mdb_var_t *v; 4560 4561 if (t->t_pshandle == NULL) 4562 return (set_errno(EMDB_NOPROC)); 4563 4564 if ((v = mdb_nv_lookup(&pt->p_regs, rname)) != NULL) { 4565 uintmax_t rd_nval = mdb_nv_get_value(v); 4566 ushort_t rd_num = MDB_TGT_R_NUM(rd_nval); 4567 ushort_t rd_flags = MDB_TGT_R_FLAGS(rd_nval); 4568 4569 if (!MDB_TGT_R_IS_FP(rd_flags)) { 4570 4571 if (rd_flags & MDB_TGT_R_32) 4572 r &= 0xffffffffULL; 4573 else if (rd_flags & MDB_TGT_R_16) 4574 r &= 0xffffULL; 4575 else if (rd_flags & MDB_TGT_R_8H) 4576 r = (r & 0xffULL) << 8; 4577 else if (rd_flags & MDB_TGT_R_8L) 4578 r &= 0xffULL; 4579 4580 #if defined(__sparc) && defined(_ILP32) 4581 /* 4582 * If we are debugging on 32-bit SPARC, the globals and 4583 * outs can have 32 upper bits stored in the xregs. 4584 */ 4585 int is_g = (rd_num == R_G0 || 4586 rd_num >= R_G1 && rd_num <= R_G7); 4587 int is_o = (rd_num >= R_O0 && rd_num <= R_O7); 4588 prxregset_t xrs; 4589 4590 if ((is_g || is_o) && PTL_GETXREGS(t, tid, &xrs) == 0 && 4591 xrs.pr_type == XR_TYPE_V8P) { 4592 if (is_g) { 4593 xrs.pr_un.pr_v8p.pr_xg[rd_num - 4594 R_G0 + XR_G0] = (uint32_t)(r >> 32); 4595 } else if (is_o) { 4596 xrs.pr_un.pr_v8p.pr_xo[rd_num - 4597 R_O0 + XR_O0] = (uint32_t)(r >> 32); 4598 } 4599 4600 if (PTL_SETXREGS(t, tid, &xrs) == -1) 4601 return (-1); 4602 } 4603 #endif /* __sparc && _ILP32 */ 4604 4605 if (PTL_GETREGS(t, tid, grs) == 0) { 4606 grs[rd_num] = (prgreg_t)r; 4607 return (PTL_SETREGS(t, tid, grs)); 4608 } 4609 return (-1); 4610 } else 4611 return (pt_putfpreg(t, tid, rd_num, rd_flags, r)); 4612 } 4613 4614 return (set_errno(EMDB_BADREG)); 4615 } 4616 4617 static int 4618 pt_stack_call(pt_stkarg_t *psp, const prgregset_t grs, uint_t argc, long *argv) 4619 { 4620 psp->pstk_gotpc |= (grs[R_PC] != 0); 4621 4622 if (!psp->pstk_gotpc) 4623 return (0); /* skip initial zeroed frames */ 4624 4625 return (psp->pstk_func(psp->pstk_private, grs[R_PC], 4626 argc, argv, (const struct mdb_tgt_gregset *)grs)); 4627 } 4628 4629 static int 4630 pt_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, 4631 mdb_tgt_stack_f *func, void *arg) 4632 { 4633 if (t->t_pshandle != NULL) { 4634 pt_stkarg_t pstk; 4635 4636 pstk.pstk_func = func; 4637 pstk.pstk_private = arg; 4638 pstk.pstk_gotpc = FALSE; 4639 4640 (void) Pstack_iter(t->t_pshandle, gsp->gregs, 4641 (proc_stack_f *)pt_stack_call, &pstk); 4642 4643 return (0); 4644 } 4645 4646 return (set_errno(EMDB_NOPROC)); 4647 } 4648 4649 static int 4650 pt_auxv(mdb_tgt_t *t, const auxv_t **auxvp) 4651 { 4652 if (t->t_pshandle != NULL) { 4653 *auxvp = Pgetauxvec(t->t_pshandle); 4654 return (0); 4655 } 4656 4657 return (set_errno(EMDB_NOPROC)); 4658 } 4659 4660 4661 static const mdb_tgt_ops_t proc_ops = { 4662 pt_setflags, /* t_setflags */ 4663 (int (*)()) mdb_tgt_notsup, /* t_setcontext */ 4664 pt_activate, /* t_activate */ 4665 pt_deactivate, /* t_deactivate */ 4666 pt_periodic, /* t_periodic */ 4667 pt_destroy, /* t_destroy */ 4668 pt_name, /* t_name */ 4669 (const char *(*)()) mdb_conf_isa, /* t_isa */ 4670 pt_platform, /* t_platform */ 4671 pt_uname, /* t_uname */ 4672 pt_dmodel, /* t_dmodel */ 4673 (ssize_t (*)()) mdb_tgt_notsup, /* t_aread */ 4674 (ssize_t (*)()) mdb_tgt_notsup, /* t_awrite */ 4675 pt_vread, /* t_vread */ 4676 pt_vwrite, /* t_vwrite */ 4677 (ssize_t (*)()) mdb_tgt_notsup, /* t_pread */ 4678 (ssize_t (*)()) mdb_tgt_notsup, /* t_pwrite */ 4679 pt_fread, /* t_fread */ 4680 pt_fwrite, /* t_fwrite */ 4681 (ssize_t (*)()) mdb_tgt_notsup, /* t_ioread */ 4682 (ssize_t (*)()) mdb_tgt_notsup, /* t_iowrite */ 4683 (int (*)()) mdb_tgt_notsup, /* t_vtop */ 4684 pt_lookup_by_name, /* t_lookup_by_name */ 4685 pt_lookup_by_addr, /* t_lookup_by_addr */ 4686 pt_symbol_iter, /* t_symbol_iter */ 4687 pt_mapping_iter, /* t_mapping_iter */ 4688 pt_object_iter, /* t_object_iter */ 4689 pt_addr_to_map, /* t_addr_to_map */ 4690 pt_name_to_map, /* t_name_to_map */ 4691 pt_addr_to_ctf, /* t_addr_to_ctf */ 4692 pt_name_to_ctf, /* t_name_to_ctf */ 4693 pt_status, /* t_status */ 4694 pt_run, /* t_run */ 4695 pt_step, /* t_step */ 4696 pt_step_out, /* t_step_out */ 4697 (int (*)()) mdb_tgt_notsup, /* t_step_branch */ 4698 pt_next, /* t_next */ 4699 pt_continue, /* t_cont */ 4700 pt_signal, /* t_signal */ 4701 pt_add_vbrkpt, /* t_add_vbrkpt */ 4702 pt_add_sbrkpt, /* t_add_sbrkpt */ 4703 (int (*)()) mdb_tgt_null, /* t_add_pwapt */ 4704 pt_add_vwapt, /* t_add_vwapt */ 4705 (int (*)()) mdb_tgt_null, /* t_add_iowapt */ 4706 pt_add_sysenter, /* t_add_sysenter */ 4707 pt_add_sysexit, /* t_add_sysexit */ 4708 pt_add_signal, /* t_add_signal */ 4709 pt_add_fault, /* t_add_fault */ 4710 pt_getareg, /* t_getareg */ 4711 pt_putareg, /* t_putareg */ 4712 pt_stack_iter, /* t_stack_iter */ 4713 pt_auxv /* t_auxv */ 4714 }; 4715 4716 /* 4717 * Utility function for converting libproc errno values to mdb error values 4718 * for the ptl calls below. Currently, we only need to convert ENOENT to 4719 * EMDB_NOTHREAD to produce a more useful error message for the user. 4720 */ 4721 static int 4722 ptl_err(int error) 4723 { 4724 if (error != 0 && errno == ENOENT) 4725 return (set_errno(EMDB_NOTHREAD)); 4726 4727 return (error); 4728 } 4729 4730 /*ARGSUSED*/ 4731 static mdb_tgt_tid_t 4732 pt_lwp_tid(mdb_tgt_t *t, void *tap) 4733 { 4734 if (t->t_pshandle != NULL) 4735 return (Pstatus(t->t_pshandle)->pr_lwp.pr_lwpid); 4736 4737 return (set_errno(EMDB_NOPROC)); 4738 } 4739 4740 static int 4741 pt_lwp_add(mdb_addrvec_t *ap, const lwpstatus_t *psp) 4742 { 4743 mdb_addrvec_unshift(ap, psp->pr_lwpid); 4744 return (0); 4745 } 4746 4747 /*ARGSUSED*/ 4748 static int 4749 pt_lwp_iter(mdb_tgt_t *t, void *tap, mdb_addrvec_t *ap) 4750 { 4751 if (t->t_pshandle != NULL) 4752 return (Plwp_iter(t->t_pshandle, (proc_lwp_f *)pt_lwp_add, ap)); 4753 4754 return (set_errno(EMDB_NOPROC)); 4755 } 4756 4757 /*ARGSUSED*/ 4758 static int 4759 pt_lwp_getregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs) 4760 { 4761 if (t->t_pshandle != NULL) { 4762 return (ptl_err(Plwp_getregs(t->t_pshandle, 4763 (lwpid_t)tid, gregs))); 4764 } 4765 return (set_errno(EMDB_NOPROC)); 4766 } 4767 4768 /*ARGSUSED*/ 4769 static int 4770 pt_lwp_setregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs) 4771 { 4772 if (t->t_pshandle != NULL) { 4773 return (ptl_err(Plwp_setregs(t->t_pshandle, 4774 (lwpid_t)tid, gregs))); 4775 } 4776 return (set_errno(EMDB_NOPROC)); 4777 } 4778 4779 #ifdef __sparc 4780 4781 /*ARGSUSED*/ 4782 static int 4783 pt_lwp_getxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prxregset_t *xregs) 4784 { 4785 if (t->t_pshandle != NULL) { 4786 return (ptl_err(Plwp_getxregs(t->t_pshandle, 4787 (lwpid_t)tid, xregs))); 4788 } 4789 return (set_errno(EMDB_NOPROC)); 4790 } 4791 4792 /*ARGSUSED*/ 4793 static int 4794 pt_lwp_setxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, 4795 const prxregset_t *xregs) 4796 { 4797 if (t->t_pshandle != NULL) { 4798 return (ptl_err(Plwp_setxregs(t->t_pshandle, 4799 (lwpid_t)tid, xregs))); 4800 } 4801 return (set_errno(EMDB_NOPROC)); 4802 } 4803 4804 #endif /* __sparc */ 4805 4806 /*ARGSUSED*/ 4807 static int 4808 pt_lwp_getfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, 4809 prfpregset_t *fpregs) 4810 { 4811 if (t->t_pshandle != NULL) { 4812 return (ptl_err(Plwp_getfpregs(t->t_pshandle, 4813 (lwpid_t)tid, fpregs))); 4814 } 4815 return (set_errno(EMDB_NOPROC)); 4816 } 4817 4818 /*ARGSUSED*/ 4819 static int 4820 pt_lwp_setfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, 4821 const prfpregset_t *fpregs) 4822 { 4823 if (t->t_pshandle != NULL) { 4824 return (ptl_err(Plwp_setfpregs(t->t_pshandle, 4825 (lwpid_t)tid, fpregs))); 4826 } 4827 return (set_errno(EMDB_NOPROC)); 4828 } 4829 4830 static const pt_ptl_ops_t proc_lwp_ops = { 4831 (int (*)()) mdb_tgt_nop, 4832 (void (*)()) mdb_tgt_nop, 4833 pt_lwp_tid, 4834 pt_lwp_iter, 4835 pt_lwp_getregs, 4836 pt_lwp_setregs, 4837 #ifdef __sparc 4838 pt_lwp_getxregs, 4839 pt_lwp_setxregs, 4840 #endif 4841 pt_lwp_getfpregs, 4842 pt_lwp_setfpregs 4843 }; 4844 4845 static int 4846 pt_tdb_ctor(mdb_tgt_t *t) 4847 { 4848 pt_data_t *pt = t->t_data; 4849 td_thragent_t *tap; 4850 td_err_e err; 4851 4852 if ((err = pt->p_tdb_ops->td_ta_new(t->t_pshandle, &tap)) != TD_OK) 4853 return (set_errno(tdb_to_errno(err))); 4854 4855 pt->p_ptl_hdl = tap; 4856 return (0); 4857 } 4858 4859 static void 4860 pt_tdb_dtor(mdb_tgt_t *t, void *tap) 4861 { 4862 pt_data_t *pt = t->t_data; 4863 4864 ASSERT(tap == pt->p_ptl_hdl); 4865 (void) pt->p_tdb_ops->td_ta_delete(tap); 4866 pt->p_ptl_hdl = NULL; 4867 } 4868 4869 static mdb_tgt_tid_t 4870 pt_tdb_tid(mdb_tgt_t *t, void *tap) 4871 { 4872 pt_data_t *pt = t->t_data; 4873 4874 td_thrhandle_t th; 4875 td_thrinfo_t ti; 4876 td_err_e err; 4877 4878 if (t->t_pshandle == NULL) 4879 return (set_errno(EMDB_NOPROC)); 4880 4881 if ((err = pt->p_tdb_ops->td_ta_map_lwp2thr(tap, 4882 Pstatus(t->t_pshandle)->pr_lwp.pr_lwpid, &th)) != TD_OK) 4883 return (set_errno(tdb_to_errno(err))); 4884 4885 if ((err = pt->p_tdb_ops->td_thr_get_info(&th, &ti)) != TD_OK) 4886 return (set_errno(tdb_to_errno(err))); 4887 4888 return (ti.ti_tid); 4889 } 4890 4891 static int 4892 pt_tdb_add(const td_thrhandle_t *thp, pt_addarg_t *pap) 4893 { 4894 td_thrinfo_t ti; 4895 4896 if (pap->pa_pt->p_tdb_ops->td_thr_get_info(thp, &ti) == TD_OK && 4897 ti.ti_state != TD_THR_ZOMBIE) 4898 mdb_addrvec_unshift(pap->pa_ap, ti.ti_tid); 4899 4900 return (0); 4901 } 4902 4903 static int 4904 pt_tdb_iter(mdb_tgt_t *t, void *tap, mdb_addrvec_t *ap) 4905 { 4906 pt_data_t *pt = t->t_data; 4907 pt_addarg_t arg; 4908 int err; 4909 4910 if (t->t_pshandle == NULL) 4911 return (set_errno(EMDB_NOPROC)); 4912 4913 arg.pa_pt = pt; 4914 arg.pa_ap = ap; 4915 4916 if ((err = pt->p_tdb_ops->td_ta_thr_iter(tap, (td_thr_iter_f *) 4917 pt_tdb_add, &arg, TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, 4918 TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS)) != TD_OK) 4919 return (set_errno(tdb_to_errno(err))); 4920 4921 return (0); 4922 } 4923 4924 static int 4925 pt_tdb_getregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs) 4926 { 4927 pt_data_t *pt = t->t_data; 4928 4929 td_thrhandle_t th; 4930 td_err_e err; 4931 4932 if (t->t_pshandle == NULL) 4933 return (set_errno(EMDB_NOPROC)); 4934 4935 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK) 4936 return (set_errno(tdb_to_errno(err))); 4937 4938 err = pt->p_tdb_ops->td_thr_getgregs(&th, gregs); 4939 if (err != TD_OK && err != TD_PARTIALREG) 4940 return (set_errno(tdb_to_errno(err))); 4941 4942 return (0); 4943 } 4944 4945 static int 4946 pt_tdb_setregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prgregset_t gregs) 4947 { 4948 pt_data_t *pt = t->t_data; 4949 4950 td_thrhandle_t th; 4951 td_err_e err; 4952 4953 if (t->t_pshandle == NULL) 4954 return (set_errno(EMDB_NOPROC)); 4955 4956 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK) 4957 return (set_errno(tdb_to_errno(err))); 4958 4959 err = pt->p_tdb_ops->td_thr_setgregs(&th, gregs); 4960 if (err != TD_OK && err != TD_PARTIALREG) 4961 return (set_errno(tdb_to_errno(err))); 4962 4963 return (0); 4964 } 4965 4966 #ifdef __sparc 4967 4968 static int 4969 pt_tdb_getxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, prxregset_t *xregs) 4970 { 4971 pt_data_t *pt = t->t_data; 4972 4973 td_thrhandle_t th; 4974 td_err_e err; 4975 4976 if (t->t_pshandle == NULL) 4977 return (set_errno(EMDB_NOPROC)); 4978 4979 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK) 4980 return (set_errno(tdb_to_errno(err))); 4981 4982 err = pt->p_tdb_ops->td_thr_getxregs(&th, xregs); 4983 if (err != TD_OK && err != TD_PARTIALREG) 4984 return (set_errno(tdb_to_errno(err))); 4985 4986 return (0); 4987 } 4988 4989 static int 4990 pt_tdb_setxregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, 4991 const prxregset_t *xregs) 4992 { 4993 pt_data_t *pt = t->t_data; 4994 4995 td_thrhandle_t th; 4996 td_err_e err; 4997 4998 if (t->t_pshandle == NULL) 4999 return (set_errno(EMDB_NOPROC)); 5000 5001 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK) 5002 return (set_errno(tdb_to_errno(err))); 5003 5004 err = pt->p_tdb_ops->td_thr_setxregs(&th, xregs); 5005 if (err != TD_OK && err != TD_PARTIALREG) 5006 return (set_errno(tdb_to_errno(err))); 5007 5008 return (0); 5009 } 5010 5011 #endif /* __sparc */ 5012 5013 static int 5014 pt_tdb_getfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, 5015 prfpregset_t *fpregs) 5016 { 5017 pt_data_t *pt = t->t_data; 5018 5019 td_thrhandle_t th; 5020 td_err_e err; 5021 5022 if (t->t_pshandle == NULL) 5023 return (set_errno(EMDB_NOPROC)); 5024 5025 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK) 5026 return (set_errno(tdb_to_errno(err))); 5027 5028 err = pt->p_tdb_ops->td_thr_getfpregs(&th, fpregs); 5029 if (err != TD_OK && err != TD_PARTIALREG) 5030 return (set_errno(tdb_to_errno(err))); 5031 5032 return (0); 5033 } 5034 5035 static int 5036 pt_tdb_setfpregs(mdb_tgt_t *t, void *tap, mdb_tgt_tid_t tid, 5037 const prfpregset_t *fpregs) 5038 { 5039 pt_data_t *pt = t->t_data; 5040 5041 td_thrhandle_t th; 5042 td_err_e err; 5043 5044 if (t->t_pshandle == NULL) 5045 return (set_errno(EMDB_NOPROC)); 5046 5047 if ((err = pt->p_tdb_ops->td_ta_map_id2thr(tap, tid, &th)) != TD_OK) 5048 return (set_errno(tdb_to_errno(err))); 5049 5050 err = pt->p_tdb_ops->td_thr_setfpregs(&th, fpregs); 5051 if (err != TD_OK && err != TD_PARTIALREG) 5052 return (set_errno(tdb_to_errno(err))); 5053 5054 return (0); 5055 } 5056 5057 static const pt_ptl_ops_t proc_tdb_ops = { 5058 pt_tdb_ctor, 5059 pt_tdb_dtor, 5060 pt_tdb_tid, 5061 pt_tdb_iter, 5062 pt_tdb_getregs, 5063 pt_tdb_setregs, 5064 #ifdef __sparc 5065 pt_tdb_getxregs, 5066 pt_tdb_setxregs, 5067 #endif 5068 pt_tdb_getfpregs, 5069 pt_tdb_setfpregs 5070 }; 5071 5072 static ssize_t 5073 pt_xd_auxv(mdb_tgt_t *t, void *buf, size_t nbytes) 5074 { 5075 struct ps_prochandle *P = t->t_pshandle; 5076 const auxv_t *auxp, *auxv = NULL; 5077 int auxn = 0; 5078 5079 if (P != NULL && (auxv = Pgetauxvec(P)) != NULL && 5080 auxv->a_type != AT_NULL) { 5081 for (auxp = auxv, auxn = 1; auxp->a_type != NULL; auxp++) 5082 auxn++; 5083 } 5084 5085 if (buf == NULL && nbytes == 0) 5086 return (sizeof (auxv_t) * auxn); 5087 5088 if (auxn == 0) 5089 return (set_errno(ENODATA)); 5090 5091 nbytes = MIN(nbytes, sizeof (auxv_t) * auxn); 5092 bcopy(auxv, buf, nbytes); 5093 return (nbytes); 5094 } 5095 5096 static ssize_t 5097 pt_xd_cred(mdb_tgt_t *t, void *buf, size_t nbytes) 5098 { 5099 prcred_t cr, *crp; 5100 size_t cbytes = 0; 5101 5102 if (t->t_pshandle != NULL && Pcred(t->t_pshandle, &cr, 1) == 0) { 5103 cbytes = (cr.pr_ngroups <= 1) ? sizeof (prcred_t) : 5104 (sizeof (prcred_t) + (cr.pr_ngroups - 1) * sizeof (gid_t)); 5105 } 5106 5107 if (buf == NULL && nbytes == 0) 5108 return (cbytes); 5109 5110 if (cbytes == 0) 5111 return (set_errno(ENODATA)); 5112 5113 crp = mdb_alloc(cbytes, UM_SLEEP); 5114 5115 if (Pcred(t->t_pshandle, crp, cr.pr_ngroups) == -1) 5116 return (set_errno(ENODATA)); 5117 5118 nbytes = MIN(nbytes, cbytes); 5119 bcopy(crp, buf, nbytes); 5120 mdb_free(crp, cbytes); 5121 return (nbytes); 5122 } 5123 5124 static ssize_t 5125 pt_xd_ehdr(mdb_tgt_t *t, void *buf, size_t nbytes) 5126 { 5127 pt_data_t *pt = t->t_data; 5128 5129 if (buf == NULL && nbytes == 0) 5130 return (sizeof (GElf_Ehdr)); 5131 5132 if (pt->p_file == NULL) 5133 return (set_errno(ENODATA)); 5134 5135 nbytes = MIN(nbytes, sizeof (GElf_Ehdr)); 5136 bcopy(&pt->p_file->gf_ehdr, buf, nbytes); 5137 return (nbytes); 5138 } 5139 5140 static int 5141 pt_copy_lwp(lwpstatus_t **lspp, const lwpstatus_t *lsp) 5142 { 5143 bcopy(lsp, *lspp, sizeof (lwpstatus_t)); 5144 (*lspp)++; 5145 return (0); 5146 } 5147 5148 static ssize_t 5149 pt_xd_lwpstatus(mdb_tgt_t *t, void *buf, size_t nbytes) 5150 { 5151 lwpstatus_t *lsp, *lbuf; 5152 const pstatus_t *psp; 5153 int nlwp = 0; 5154 5155 if (t->t_pshandle != NULL && (psp = Pstatus(t->t_pshandle)) != NULL) 5156 nlwp = psp->pr_nlwp; 5157 5158 if (buf == NULL && nbytes == 0) 5159 return (sizeof (lwpstatus_t) * nlwp); 5160 5161 if (nlwp == 0) 5162 return (set_errno(ENODATA)); 5163 5164 lsp = lbuf = mdb_alloc(sizeof (lwpstatus_t) * nlwp, UM_SLEEP); 5165 nbytes = MIN(nbytes, sizeof (lwpstatus_t) * nlwp); 5166 5167 (void) Plwp_iter(t->t_pshandle, (proc_lwp_f *)pt_copy_lwp, &lsp); 5168 bcopy(lbuf, buf, nbytes); 5169 5170 mdb_free(lbuf, sizeof (lwpstatus_t) * nlwp); 5171 return (nbytes); 5172 } 5173 5174 static ssize_t 5175 pt_xd_pshandle(mdb_tgt_t *t, void *buf, size_t nbytes) 5176 { 5177 if (buf == NULL && nbytes == 0) 5178 return (sizeof (struct ps_prochandle *)); 5179 5180 if (t->t_pshandle == NULL || nbytes != sizeof (struct ps_prochandle *)) 5181 return (set_errno(ENODATA)); 5182 5183 bcopy(&t->t_pshandle, buf, nbytes); 5184 return (nbytes); 5185 } 5186 5187 static ssize_t 5188 pt_xd_psinfo(mdb_tgt_t *t, void *buf, size_t nbytes) 5189 { 5190 const psinfo_t *psp; 5191 5192 if (buf == NULL && nbytes == 0) 5193 return (sizeof (psinfo_t)); 5194 5195 if (t->t_pshandle == NULL || (psp = Ppsinfo(t->t_pshandle)) == NULL) 5196 return (set_errno(ENODATA)); 5197 5198 nbytes = MIN(nbytes, sizeof (psinfo_t)); 5199 bcopy(psp, buf, nbytes); 5200 return (nbytes); 5201 } 5202 5203 static ssize_t 5204 pt_xd_pstatus(mdb_tgt_t *t, void *buf, size_t nbytes) 5205 { 5206 const pstatus_t *psp; 5207 5208 if (buf == NULL && nbytes == 0) 5209 return (sizeof (pstatus_t)); 5210 5211 if (t->t_pshandle == NULL || (psp = Pstatus(t->t_pshandle)) == NULL) 5212 return (set_errno(ENODATA)); 5213 5214 nbytes = MIN(nbytes, sizeof (pstatus_t)); 5215 bcopy(psp, buf, nbytes); 5216 return (nbytes); 5217 } 5218 5219 static ssize_t 5220 pt_xd_utsname(mdb_tgt_t *t, void *buf, size_t nbytes) 5221 { 5222 struct utsname uts; 5223 5224 if (buf == NULL && nbytes == 0) 5225 return (sizeof (struct utsname)); 5226 5227 if (t->t_pshandle == NULL || Puname(t->t_pshandle, &uts) != 0) 5228 return (set_errno(ENODATA)); 5229 5230 nbytes = MIN(nbytes, sizeof (struct utsname)); 5231 bcopy(&uts, buf, nbytes); 5232 return (nbytes); 5233 } 5234 5235 int 5236 mdb_proc_tgt_create(mdb_tgt_t *t, int argc, const char *argv[]) 5237 { 5238 pt_data_t *pt = mdb_zalloc(sizeof (pt_data_t), UM_SLEEP); 5239 5240 const char *aout_path = argc > 0 ? argv[0] : PT_EXEC_PATH; 5241 const char *core_path = argc > 1 ? argv[1] : NULL; 5242 5243 const mdb_tgt_regdesc_t *rdp; 5244 char execname[MAXPATHLEN]; 5245 struct stat64 st; 5246 int perr; 5247 int state; 5248 struct rlimit rlim; 5249 int i; 5250 5251 if (argc > 2) { 5252 mdb_free(pt, sizeof (pt_data_t)); 5253 return (set_errno(EINVAL)); 5254 } 5255 5256 if (t->t_flags & MDB_TGT_F_RDWR) 5257 pt->p_oflags = O_RDWR; 5258 else 5259 pt->p_oflags = O_RDONLY; 5260 5261 if (t->t_flags & MDB_TGT_F_FORCE) 5262 pt->p_gflags |= PGRAB_FORCE; 5263 if (t->t_flags & MDB_TGT_F_NOSTOP) 5264 pt->p_gflags |= PGRAB_NOSTOP; 5265 5266 pt->p_ptl_ops = &proc_lwp_ops; 5267 pt->p_maxsig = sysconf(_SC_SIGRT_MAX); 5268 5269 (void) mdb_nv_create(&pt->p_regs, UM_SLEEP); 5270 (void) mdb_nv_create(&pt->p_env, UM_SLEEP); 5271 5272 t->t_ops = &proc_ops; 5273 t->t_data = pt; 5274 5275 /* 5276 * If no core file name was specified, but the file ./core is present, 5277 * infer that we want to debug it. I find this behavior confusing, 5278 * so we only do this when precise adb(1) compatibility is required. 5279 */ 5280 if (core_path == NULL && (mdb.m_flags & MDB_FL_ADB) && 5281 access(PT_CORE_PATH, F_OK) == 0) 5282 core_path = PT_CORE_PATH; 5283 5284 /* 5285 * For compatibility with adb(1), the special name "-" may be used 5286 * to suppress the loading of the executable or core file. 5287 */ 5288 if (aout_path != NULL && strcmp(aout_path, "-") == 0) 5289 aout_path = NULL; 5290 if (core_path != NULL && strcmp(core_path, "-") == 0) 5291 core_path = NULL; 5292 5293 /* 5294 * If a core file or pid was specified, attempt to grab it now using 5295 * proc_arg_grab(); otherwise we'll create a fresh process later. 5296 */ 5297 if (core_path != NULL && (t->t_pshandle = proc_arg_xgrab(core_path, 5298 aout_path == PT_EXEC_PATH ? NULL : aout_path, PR_ARG_ANY, 5299 pt->p_gflags, &perr, NULL)) == NULL) { 5300 mdb_warn("cannot debug %s: %s\n", core_path, Pgrab_error(perr)); 5301 goto err; 5302 } 5303 5304 if (aout_path != NULL && 5305 (pt->p_idlehandle = Pgrab_file(aout_path, &perr)) != NULL && 5306 t->t_pshandle == NULL) 5307 t->t_pshandle = pt->p_idlehandle; 5308 5309 if (t->t_pshandle != NULL) 5310 state = Pstate(t->t_pshandle); 5311 5312 /* 5313 * Make sure we'll have enough file descriptors to handle a target 5314 * has many many mappings. 5315 */ 5316 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) { 5317 rlim.rlim_cur = rlim.rlim_max; 5318 (void) setrlimit(RLIMIT_NOFILE, &rlim); 5319 (void) enable_extended_FILE_stdio(-1, -1); 5320 } 5321 5322 /* 5323 * If we don't have an executable path or the executable path is the 5324 * /proc/<pid>/object/a.out path, but we now have a libproc handle, 5325 * attempt to derive the executable path using Pexecname(). We need 5326 * to do this in the /proc case in order to open the executable for 5327 * writing because /proc/object/<file> permission are masked with 0555. 5328 * If Pexecname() fails us, fall back to /proc/<pid>/object/a.out. 5329 */ 5330 if (t->t_pshandle != NULL && (aout_path == NULL || (stat64(aout_path, 5331 &st) == 0 && strcmp(st.st_fstype, "proc") == 0))) { 5332 GElf_Sym s; 5333 aout_path = Pexecname(t->t_pshandle, execname, MAXPATHLEN); 5334 if (aout_path == NULL && state != PS_DEAD && state != PS_IDLE) { 5335 (void) mdb_iob_snprintf(execname, sizeof (execname), 5336 "/proc/%d/object/a.out", 5337 (int)Pstatus(t->t_pshandle)->pr_pid); 5338 aout_path = execname; 5339 } 5340 if (aout_path == NULL && 5341 Plookup_by_name(t->t_pshandle, "a.out", "_start", &s) != 0) 5342 mdb_warn("warning: failed to infer pathname to " 5343 "executable; symbol table will not be available\n"); 5344 5345 mdb_dprintf(MDB_DBG_TGT, "a.out is %s\n", aout_path); 5346 } 5347 5348 /* 5349 * Attempt to open the executable file. We only want this operation 5350 * to actually cause the constructor to abort if the executable file 5351 * name was given explicitly. If we defaulted to PT_EXEC_PATH or 5352 * derived the executable using Pexecname, then we want to continue 5353 * along with p_fio and p_file set to NULL. 5354 */ 5355 if (aout_path != NULL && (pt->p_aout_fio = mdb_fdio_create_path(NULL, 5356 aout_path, pt->p_oflags, 0)) == NULL && argc > 0) { 5357 mdb_warn("failed to open %s", aout_path); 5358 goto err; 5359 } 5360 5361 /* 5362 * Now create an ELF file from the input file, if we have one. Again, 5363 * only abort the constructor if the name was given explicitly. 5364 */ 5365 if (pt->p_aout_fio != NULL && pt_open_aout(t, 5366 mdb_io_hold(pt->p_aout_fio)) == NULL && argc > 0) 5367 goto err; 5368 5369 /* 5370 * If we've successfully opened an ELF file, select the appropriate 5371 * disassembler based on the ELF header. 5372 */ 5373 if (pt->p_file != NULL) 5374 (void) mdb_dis_select(pt_disasm(&pt->p_file->gf_ehdr)); 5375 else 5376 (void) mdb_dis_select(pt_disasm(NULL)); 5377 5378 /* 5379 * Add each register described in the target ISA register description 5380 * list to our hash table of register descriptions and then add any 5381 * appropriate ISA-specific floating-point register descriptions. 5382 */ 5383 for (rdp = pt_regdesc; rdp->rd_name != NULL; rdp++) { 5384 (void) mdb_nv_insert(&pt->p_regs, rdp->rd_name, NULL, 5385 MDB_TGT_R_NVAL(rdp->rd_num, rdp->rd_flags), MDB_NV_RDONLY); 5386 } 5387 pt_addfpregs(t); 5388 5389 /* 5390 * Certain important /proc structures may be of interest to mdb 5391 * modules and their dcmds. Export these using the xdata interface: 5392 */ 5393 (void) mdb_tgt_xdata_insert(t, "auxv", 5394 "procfs auxv_t array", pt_xd_auxv); 5395 (void) mdb_tgt_xdata_insert(t, "cred", 5396 "procfs prcred_t structure", pt_xd_cred); 5397 (void) mdb_tgt_xdata_insert(t, "ehdr", 5398 "executable file GElf_Ehdr structure", pt_xd_ehdr); 5399 (void) mdb_tgt_xdata_insert(t, "lwpstatus", 5400 "procfs lwpstatus_t array", pt_xd_lwpstatus); 5401 (void) mdb_tgt_xdata_insert(t, "pshandle", 5402 "libproc proc service API handle", pt_xd_pshandle); 5403 (void) mdb_tgt_xdata_insert(t, "psinfo", 5404 "procfs psinfo_t structure", pt_xd_psinfo); 5405 (void) mdb_tgt_xdata_insert(t, "pstatus", 5406 "procfs pstatus_t structure", pt_xd_pstatus); 5407 (void) mdb_tgt_xdata_insert(t, "utsname", 5408 "utsname structure", pt_xd_utsname); 5409 5410 /* 5411 * Force a status update now so that we fill in t_status with the 5412 * latest information based on any successful grab. 5413 */ 5414 (void) mdb_tgt_status(t, &t->t_status); 5415 5416 /* 5417 * If we're not examining a core file, trace SIGINT and all signals 5418 * that cause the process to dump core as part of our initialization. 5419 */ 5420 if ((t->t_pshandle != NULL && state != PS_DEAD && state != PS_IDLE) || 5421 (pt->p_file != NULL && pt->p_file->gf_ehdr.e_type == ET_EXEC)) { 5422 5423 int tflag = MDB_TGT_SPEC_STICKY; /* default sigs are sticky */ 5424 5425 (void) mdb_tgt_add_signal(t, SIGINT, tflag, no_se_f, NULL); 5426 (void) mdb_tgt_add_signal(t, SIGQUIT, tflag, no_se_f, NULL); 5427 (void) mdb_tgt_add_signal(t, SIGILL, tflag, no_se_f, NULL); 5428 (void) mdb_tgt_add_signal(t, SIGTRAP, tflag, no_se_f, NULL); 5429 (void) mdb_tgt_add_signal(t, SIGABRT, tflag, no_se_f, NULL); 5430 (void) mdb_tgt_add_signal(t, SIGEMT, tflag, no_se_f, NULL); 5431 (void) mdb_tgt_add_signal(t, SIGFPE, tflag, no_se_f, NULL); 5432 (void) mdb_tgt_add_signal(t, SIGBUS, tflag, no_se_f, NULL); 5433 (void) mdb_tgt_add_signal(t, SIGSEGV, tflag, no_se_f, NULL); 5434 (void) mdb_tgt_add_signal(t, SIGSYS, tflag, no_se_f, NULL); 5435 (void) mdb_tgt_add_signal(t, SIGXCPU, tflag, no_se_f, NULL); 5436 (void) mdb_tgt_add_signal(t, SIGXFSZ, tflag, no_se_f, NULL); 5437 } 5438 5439 /* 5440 * If we've grabbed a live process, establish our initial breakpoints 5441 * and librtld_db agent so we can track rtld activity. If FL_VCREATE 5442 * is set, this process was created by a previous instantiation of 5443 * the debugger, so reset pr_flags to kill it; otherwise we attached 5444 * to an already running process. Pgrab() has already set the PR_RLC 5445 * flag appropriately based on whether the process was stopped when we 5446 * attached. 5447 */ 5448 if (t->t_pshandle != NULL && state != PS_DEAD && state != PS_IDLE) { 5449 if (mdb.m_flags & MDB_FL_VCREATE) { 5450 (void) Punsetflags(t->t_pshandle, PR_RLC); 5451 (void) Psetflags(t->t_pshandle, PR_KLC); 5452 pt->p_rflags = PRELEASE_KILL; 5453 } else { 5454 (void) Punsetflags(t->t_pshandle, PR_KLC); 5455 } 5456 pt_post_attach(t); 5457 } 5458 5459 /* 5460 * Initialize a local copy of the environment, which can be modified 5461 * before running the program. 5462 */ 5463 for (i = 0; mdb.m_env[i] != NULL; i++) 5464 pt_env_set(pt, mdb.m_env[i]); 5465 5466 /* 5467 * If adb(1) compatibility mode is on, then print the appropriate 5468 * greeting message if we have grabbed a core file. 5469 */ 5470 if ((mdb.m_flags & MDB_FL_ADB) && t->t_pshandle != NULL && 5471 state == PS_DEAD) { 5472 const pstatus_t *psp = Pstatus(t->t_pshandle); 5473 int cursig = psp->pr_lwp.pr_cursig; 5474 char signame[SIG2STR_MAX]; 5475 5476 mdb_printf("core file = %s -- program ``%s'' on platform %s\n", 5477 core_path, aout_path ? aout_path : "?", pt_platform(t)); 5478 5479 if (cursig != 0 && sig2str(cursig, signame) == 0) 5480 mdb_printf("SIG%s: %s\n", signame, strsignal(cursig)); 5481 } 5482 5483 return (0); 5484 5485 err: 5486 pt_destroy(t); 5487 return (-1); 5488 } 5489