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