1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 2712 nn35248 * Common Development and Distribution License (the "License"). 6 2712 nn35248 * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 10843 Dave * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel #include <sys/types.h> 27 0 stevel #include <sys/mman.h> 28 0 stevel #include <sys/priocntl.h> 29 0 stevel #include <sys/rtpriocntl.h> 30 0 stevel #include <sys/resource.h> 31 0 stevel #include <sys/termios.h> 32 0 stevel #include <sys/param.h> 33 0 stevel #include <sys/regset.h> 34 0 stevel #include <sys/frame.h> 35 0 stevel #include <sys/stack.h> 36 0 stevel #include <sys/reg.h> 37 0 stevel 38 0 stevel #include <libproc.h> 39 0 stevel #include <libscf.h> 40 0 stevel #include <alloca.h> 41 0 stevel #include <unistd.h> 42 0 stevel #include <string.h> 43 0 stevel #include <stdlib.h> 44 0 stevel #include <fcntl.h> 45 0 stevel #include <dlfcn.h> 46 0 stevel #include <libctf.h> 47 0 stevel #include <errno.h> 48 5084 johnlev #include <kvm.h> 49 0 stevel 50 0 stevel #include <mdb/mdb_lex.h> 51 0 stevel #include <mdb/mdb_debug.h> 52 0 stevel #include <mdb/mdb_signal.h> 53 0 stevel #include <mdb/mdb_string.h> 54 0 stevel #include <mdb/mdb_modapi.h> 55 0 stevel #include <mdb/mdb_target.h> 56 0 stevel #include <mdb/mdb_gelf.h> 57 0 stevel #include <mdb/mdb_conf.h> 58 0 stevel #include <mdb/mdb_err.h> 59 0 stevel #include <mdb/mdb_io_impl.h> 60 0 stevel #include <mdb/mdb_frame.h> 61 0 stevel #include <mdb/mdb_set.h> 62 0 stevel #include <kmdb/kmdb_kctl.h> 63 0 stevel #include <mdb/mdb.h> 64 0 stevel 65 0 stevel #ifndef STACK_BIAS 66 0 stevel #define STACK_BIAS 0 67 0 stevel #endif 68 0 stevel 69 0 stevel #if defined(__sparc) 70 0 stevel #define STACK_REGISTER SP 71 0 stevel #else 72 0 stevel #define STACK_REGISTER REG_FP 73 0 stevel #endif 74 0 stevel 75 0 stevel #ifdef _LP64 76 0 stevel #define MDB_DEF_IPATH \ 77 0 stevel "%r/usr/platform/%p/lib/adb/%i:" \ 78 0 stevel "%r/usr/platform/%m/lib/adb/%i:" \ 79 0 stevel "%r/usr/lib/adb/%i" 80 0 stevel #define MDB_DEF_LPATH \ 81 0 stevel "%r/usr/platform/%p/lib/mdb/%t/%i:" \ 82 0 stevel "%r/usr/platform/%m/lib/mdb/%t/%i:" \ 83 0 stevel "%r/usr/lib/mdb/%t/%i" 84 0 stevel #else 85 0 stevel #define MDB_DEF_IPATH \ 86 0 stevel "%r/usr/platform/%p/lib/adb:" \ 87 0 stevel "%r/usr/platform/%m/lib/adb:" \ 88 0 stevel "%r/usr/lib/adb" 89 0 stevel #define MDB_DEF_LPATH \ 90 0 stevel "%r/usr/platform/%p/lib/mdb/%t:" \ 91 0 stevel "%r/usr/platform/%m/lib/mdb/%t:" \ 92 0 stevel "%r/usr/lib/mdb/%t" 93 0 stevel #endif 94 0 stevel 95 0 stevel #define MDB_DEF_PROMPT "> " 96 0 stevel 97 0 stevel /* 98 0 stevel * Similar to the panic_* variables in the kernel, we keep some relevant 99 0 stevel * information stored in a set of global _mdb_abort_* variables; in the 100 0 stevel * event that the debugger dumps core, these will aid core dump analysis. 101 0 stevel */ 102 0 stevel const char *volatile _mdb_abort_str; /* reason for failure */ 103 0 stevel siginfo_t _mdb_abort_info; /* signal info for fatal signal */ 104 0 stevel ucontext_t _mdb_abort_ctx; /* context fatal signal interrupted */ 105 0 stevel int _mdb_abort_rcount; /* number of times resume requested */ 106 0 stevel int _mdb_self_fd = -1; /* fd for self as for valid_frame */ 107 0 stevel 108 0 stevel static void 109 0 stevel terminate(int status) 110 0 stevel { 111 7383 Vitezslav (void) mdb_signal_blockall(); 112 0 stevel mdb_destroy(); 113 0 stevel exit(status); 114 0 stevel } 115 0 stevel 116 0 stevel static void 117 0 stevel print_frame(uintptr_t pc, int fnum) 118 0 stevel { 119 0 stevel Dl_info dli; 120 0 stevel 121 0 stevel if (dladdr((void *)pc, &dli)) { 122 0 stevel mdb_iob_printf(mdb.m_err, " [%d] %s`%s+0x%lx()\n", fnum, 123 0 stevel strbasename(dli.dli_fname), dli.dli_sname, 124 0 stevel pc - (uintptr_t)dli.dli_saddr); 125 0 stevel } else 126 0 stevel mdb_iob_printf(mdb.m_err, " [%d] %p()\n", fnum, pc); 127 0 stevel } 128 0 stevel 129 0 stevel static int 130 0 stevel valid_frame(struct frame *fr) 131 0 stevel { 132 0 stevel static struct frame fake; 133 0 stevel uintptr_t addr = (uintptr_t)fr; 134 0 stevel 135 0 stevel if (pread(_mdb_self_fd, &fake, sizeof (fake), addr) != sizeof (fake)) { 136 0 stevel mdb_iob_printf(mdb.m_err, " invalid frame (%p)\n", fr); 137 0 stevel return (0); 138 0 stevel } 139 0 stevel 140 0 stevel if (addr & (STACK_ALIGN - 1)) { 141 0 stevel mdb_iob_printf(mdb.m_err, " mis-aligned frame (%p)\n", fr); 142 0 stevel return (0); 143 0 stevel } 144 0 stevel 145 0 stevel return (1); 146 0 stevel } 147 0 stevel 148 0 stevel /*ARGSUSED*/ 149 0 stevel static void 150 0 stevel flt_handler(int sig, siginfo_t *sip, ucontext_t *ucp, void *data) 151 0 stevel { 152 0 stevel static const struct rlimit rl = { 153 0 stevel (rlim_t)RLIM_INFINITY, (rlim_t)RLIM_INFINITY 154 0 stevel }; 155 0 stevel 156 0 stevel const mdb_idcmd_t *idcp = NULL; 157 0 stevel 158 0 stevel if (mdb.m_frame != NULL && mdb.m_frame->f_cp != NULL) 159 0 stevel idcp = mdb.m_frame->f_cp->c_dcmd; 160 0 stevel 161 0 stevel if (sip != NULL) 162 0 stevel bcopy(sip, &_mdb_abort_info, sizeof (_mdb_abort_info)); 163 0 stevel if (ucp != NULL) 164 0 stevel bcopy(ucp, &_mdb_abort_ctx, sizeof (_mdb_abort_ctx)); 165 0 stevel 166 0 stevel _mdb_abort_info.si_signo = sig; 167 0 stevel (void) mdb_signal_sethandler(sig, SIG_DFL, NULL); 168 0 stevel 169 0 stevel /* 170 0 stevel * If there is no current dcmd, or the current dcmd comes from a 171 0 stevel * builtin module, we don't allow resume and always core dump. 172 0 stevel */ 173 0 stevel if (idcp == NULL || idcp->idc_modp == NULL || 174 0 stevel idcp->idc_modp == &mdb.m_rmod || idcp->idc_modp->mod_hdl == NULL) 175 0 stevel goto dump; 176 0 stevel 177 0 stevel if (mdb.m_term != NULL) { 178 0 stevel struct frame *fr = (struct frame *) 179 0 stevel (ucp->uc_mcontext.gregs[STACK_REGISTER] + STACK_BIAS); 180 0 stevel 181 0 stevel char signame[SIG2STR_MAX]; 182 0 stevel int i = 1; 183 0 stevel char c; 184 0 stevel 185 0 stevel if (sig2str(sig, signame) == -1) { 186 0 stevel mdb_iob_printf(mdb.m_err, 187 0 stevel "\n*** %s: received signal %d at:\n", 188 0 stevel mdb.m_pname, sig); 189 0 stevel } else { 190 0 stevel mdb_iob_printf(mdb.m_err, 191 0 stevel "\n*** %s: received signal %s at:\n", 192 0 stevel mdb.m_pname, signame); 193 0 stevel } 194 0 stevel 195 0 stevel if (ucp->uc_mcontext.gregs[REG_PC] != 0) 196 0 stevel print_frame(ucp->uc_mcontext.gregs[REG_PC], i++); 197 0 stevel 198 0 stevel while (fr != NULL && valid_frame(fr) && fr->fr_savpc != 0) { 199 0 stevel print_frame(fr->fr_savpc, i++); 200 0 stevel fr = (struct frame *) 201 0 stevel ((uintptr_t)fr->fr_savfp + STACK_BIAS); 202 0 stevel } 203 0 stevel 204 0 stevel query: 205 0 stevel mdb_iob_printf(mdb.m_err, "\n%s: (c)ore dump, (q)uit, " 206 0 stevel "(r)ecover, or (s)top for debugger [cqrs]? ", mdb.m_pname); 207 0 stevel 208 0 stevel mdb_iob_flush(mdb.m_err); 209 0 stevel 210 0 stevel for (;;) { 211 0 stevel if (IOP_READ(mdb.m_term, &c, sizeof (c)) != sizeof (c)) 212 0 stevel goto dump; 213 0 stevel 214 0 stevel switch (c) { 215 0 stevel case 'c': 216 0 stevel case 'C': 217 0 stevel (void) setrlimit(RLIMIT_CORE, &rl); 218 0 stevel mdb_iob_printf(mdb.m_err, "\n%s: attempting " 219 0 stevel "to dump core ...\n", mdb.m_pname); 220 0 stevel goto dump; 221 0 stevel 222 0 stevel case 'q': 223 0 stevel case 'Q': 224 0 stevel mdb_iob_discard(mdb.m_out); 225 0 stevel mdb_iob_nl(mdb.m_err); 226 0 stevel (void) mdb_signal_unblockall(); 227 0 stevel terminate(1); 228 0 stevel /*NOTREACHED*/ 229 0 stevel 230 0 stevel case 'r': 231 0 stevel case 'R': 232 0 stevel mdb_iob_printf(mdb.m_err, "\n%s: unloading " 233 0 stevel "module '%s' ...\n", mdb.m_pname, 234 0 stevel idcp->idc_modp->mod_name); 235 0 stevel 236 0 stevel (void) mdb_module_unload( 237 0 stevel idcp->idc_modp->mod_name, 0); 238 0 stevel 239 0 stevel (void) mdb_signal_sethandler(sig, 240 0 stevel flt_handler, NULL); 241 0 stevel 242 0 stevel _mdb_abort_rcount++; 243 0 stevel mdb.m_intr = 0; 244 0 stevel mdb.m_pend = 0; 245 0 stevel 246 0 stevel (void) mdb_signal_unblockall(); 247 0 stevel longjmp(mdb.m_frame->f_pcb, MDB_ERR_ABORT); 248 0 stevel /*NOTREACHED*/ 249 0 stevel 250 0 stevel case 's': 251 0 stevel case 'S': 252 0 stevel mdb_iob_printf(mdb.m_err, "\n%s: " 253 0 stevel "attempting to stop pid %d ...\n", 254 0 stevel mdb.m_pname, (int)getpid()); 255 0 stevel 256 0 stevel /* 257 0 stevel * Stop ourself; if this fails or we are 258 0 stevel * subsequently continued, ask again. 259 0 stevel */ 260 0 stevel (void) mdb_signal_raise(SIGSTOP); 261 0 stevel (void) mdb_signal_unblockall(); 262 0 stevel goto query; 263 0 stevel } 264 0 stevel } 265 0 stevel } 266 0 stevel 267 0 stevel dump: 268 0 stevel if (SI_FROMUSER(sip)) { 269 0 stevel (void) mdb_signal_block(sig); 270 0 stevel (void) mdb_signal_raise(sig); 271 0 stevel } 272 0 stevel 273 0 stevel (void) sigfillset(&ucp->uc_sigmask); 274 0 stevel (void) sigdelset(&ucp->uc_sigmask, sig); 275 0 stevel 276 0 stevel if (_mdb_abort_str == NULL) 277 0 stevel _mdb_abort_str = "fatal signal received"; 278 0 stevel 279 0 stevel ucp->uc_flags |= UC_SIGMASK; 280 0 stevel (void) setcontext(ucp); 281 0 stevel } 282 0 stevel 283 0 stevel /*ARGSUSED*/ 284 0 stevel static void 285 0 stevel int_handler(int sig, siginfo_t *sip, ucontext_t *ucp, void *data) 286 0 stevel { 287 0 stevel if (mdb.m_intr == 0) 288 0 stevel longjmp(mdb.m_frame->f_pcb, MDB_ERR_SIGINT); 289 0 stevel else 290 0 stevel mdb.m_pend++; 291 0 stevel } 292 0 stevel 293 0 stevel static void 294 0 stevel control_kmdb(int start) 295 0 stevel { 296 0 stevel int fd; 297 0 stevel 298 0 stevel if ((fd = open("/dev/kmdb", O_RDONLY)) < 0) 299 0 stevel die("failed to open /dev/kmdb"); 300 0 stevel 301 0 stevel if (start) { 302 0 stevel char *state = mdb_get_config(); 303 0 stevel 304 0 stevel if (ioctl(fd, KMDB_IOC_START, state) < 0) 305 0 stevel die("failed to start kmdb"); 306 0 stevel 307 0 stevel strfree(state); 308 0 stevel } else { 309 0 stevel if (ioctl(fd, KMDB_IOC_STOP) < 0) 310 0 stevel die("failed to stop kmdb"); 311 0 stevel } 312 0 stevel 313 11053 Surya (void) close(fd); 314 0 stevel } 315 0 stevel 316 0 stevel static void 317 0 stevel usage(int status) 318 0 stevel { 319 0 stevel mdb_iob_printf(mdb.m_err, "Usage: %s [-fkmuwyAFKMSUW] [+/-o option] " 320 0 stevel "[-p pid] [-s dist] [-I path] [-L path]\n\t[-P prompt] " 321 0 stevel "[-R root] [-V dis-version] [object [core] | core | suffix]\n\n", 322 0 stevel mdb.m_pname); 323 0 stevel 324 0 stevel mdb_iob_puts(mdb.m_err, 325 0 stevel "\t-f force raw file debugging mode\n" 326 0 stevel "\t-k force kernel debugging mode\n" 327 0 stevel "\t-m disable demand-loading of module symbols\n" 328 0 stevel "\t-o set specified debugger option (+o to unset)\n" 329 0 stevel "\t-p attach to specified process-id\n" 330 0 stevel "\t-s set symbol matching distance\n" 331 0 stevel "\t-u force user program debugging mode\n" 332 0 stevel "\t-w enable write mode\n" 333 0 stevel "\t-y send terminal initialization sequences for tty mode\n" 334 0 stevel "\t-A disable automatic loading of mdb modules\n" 335 0 stevel "\t-F enable forcible takeover mode\n" 336 0 stevel "\t-K stop operating system and enter live kernel debugger\n" 337 0 stevel "\t-M preload all module symbols\n" 338 0 stevel "\t-I set initial path for macro files\n" 339 0 stevel "\t-L set initial path for module libs\n" 340 0 stevel "\t-P set command-line prompt\n" 341 0 stevel "\t-R set root directory for pathname expansion\n" 342 0 stevel "\t-S suppress processing of ~/.mdbrc file\n" 343 0 stevel "\t-U unload live kernel debugger\n" 344 0 stevel "\t-W enable I/O-mapped memory access (kernel only)\n" 345 0 stevel "\t-V set disassembler version\n"); 346 0 stevel 347 0 stevel terminate(status); 348 0 stevel } 349 0 stevel 350 0 stevel static char * 351 0 stevel mdb_scf_console_term(void) 352 0 stevel { 353 0 stevel scf_simple_prop_t *prop; 354 0 stevel char *term = NULL; 355 0 stevel 356 0 stevel if ((prop = scf_simple_prop_get(NULL, 357 0 stevel "svc:/system/console-login:default", "ttymon", 358 0 stevel "terminal_type")) == NULL) 359 0 stevel return (NULL); 360 0 stevel 361 0 stevel if (scf_simple_prop_type(prop) == SCF_TYPE_ASTRING && 362 0 stevel (term = scf_simple_prop_next_astring(prop)) != NULL) 363 0 stevel term = strdup(term); 364 0 stevel 365 0 stevel scf_simple_prop_free(prop); 366 0 stevel return (term); 367 0 stevel } 368 0 stevel 369 6144 rab /* 370 6144 rab * Unpleasant hack: we might be debugging a hypervisor domain dump. 371 6144 rab * Earlier versions use a non-ELF file. Later versions are ELF, but are 372 6144 rab * /always/ ELF64, so our standard ehdr check isn't good enough. Since 373 6144 rab * we don't want to know too much about the file format, we'll ask 374 6144 rab * mdb_kb. 375 6144 rab */ 376 6144 rab #ifdef __x86 377 6144 rab static int 378 6144 rab identify_xvm_file(const char *file, int *longmode) 379 6144 rab { 380 6144 rab int (*identify)(const char *, int *); 381 6144 rab 382 6144 rab if (mdb_module_load("mdb_kb", MDB_MOD_GLOBAL | MDB_MOD_SILENT) != 0) 383 6144 rab return (0); 384 6144 rab 385 6144 rab identify = (int (*)())dlsym(RTLD_NEXT, "xkb_identify"); 386 6144 rab 387 6144 rab if (identify == NULL) 388 6144 rab return (0); 389 6144 rab 390 6144 rab return (identify(file, longmode)); 391 6144 rab } 392 6144 rab #else 393 6144 rab /*ARGSUSED*/ 394 6144 rab static int 395 6144 rab identify_xvm_file(const char *file, int *longmode) 396 6144 rab { 397 6144 rab return (0); 398 6144 rab } 399 6144 rab #endif /* __x86 */ 400 6144 rab 401 0 stevel int 402 0 stevel main(int argc, char *argv[], char *envp[]) 403 0 stevel { 404 10843 Dave extern int mdb_kvm_is_compressed_dump(mdb_io_t *); 405 0 stevel mdb_tgt_ctor_f *tgt_ctor = NULL; 406 0 stevel const char **tgt_argv = alloca(argc * sizeof (char *)); 407 0 stevel int tgt_argc = 0; 408 0 stevel mdb_tgt_t *tgt; 409 0 stevel 410 0 stevel char object[MAXPATHLEN], execname[MAXPATHLEN]; 411 0 stevel mdb_io_t *in_io, *out_io, *err_io, *null_io; 412 0 stevel struct termios tios; 413 0 stevel int status, c; 414 0 stevel char *p; 415 0 stevel 416 0 stevel const char *Iflag = NULL, *Lflag = NULL, *Vflag = NULL, *pidarg = NULL; 417 5084 johnlev int fflag = 0, Kflag = 0, Rflag = 0, Sflag = 0, Oflag = 0, Uflag = 0; 418 0 stevel 419 0 stevel int ttylike; 420 6144 rab int longmode = 0; 421 0 stevel 422 0 stevel stack_t sigstack; 423 0 stevel 424 0 stevel if (realpath(getexecname(), execname) == NULL) { 425 0 stevel (void) strncpy(execname, argv[0], MAXPATHLEN); 426 0 stevel execname[MAXPATHLEN - 1] = '\0'; 427 0 stevel } 428 0 stevel 429 0 stevel mdb_create(execname, argv[0]); 430 0 stevel bzero(tgt_argv, argc * sizeof (char *)); 431 0 stevel argv[0] = (char *)mdb.m_pname; 432 0 stevel _mdb_self_fd = open("/proc/self/as", O_RDONLY); 433 0 stevel 434 0 stevel mdb.m_env = envp; 435 0 stevel 436 0 stevel out_io = mdb_fdio_create(STDOUT_FILENO); 437 0 stevel mdb.m_out = mdb_iob_create(out_io, MDB_IOB_WRONLY); 438 0 stevel 439 0 stevel err_io = mdb_fdio_create(STDERR_FILENO); 440 0 stevel mdb.m_err = mdb_iob_create(err_io, MDB_IOB_WRONLY); 441 0 stevel mdb_iob_clrflags(mdb.m_err, MDB_IOB_AUTOWRAP); 442 0 stevel 443 0 stevel null_io = mdb_nullio_create(); 444 0 stevel mdb.m_null = mdb_iob_create(null_io, MDB_IOB_WRONLY); 445 0 stevel 446 0 stevel in_io = mdb_fdio_create(STDIN_FILENO); 447 0 stevel if ((mdb.m_termtype = getenv("TERM")) != NULL) { 448 0 stevel mdb.m_termtype = strdup(mdb.m_termtype); 449 0 stevel mdb.m_flags |= MDB_FL_TERMGUESS; 450 0 stevel } 451 0 stevel mdb.m_term = NULL; 452 0 stevel 453 0 stevel mdb_dmode(mdb_dstr2mode(getenv("MDB_DEBUG"))); 454 0 stevel mdb.m_pgid = getpgrp(); 455 0 stevel 456 0 stevel if (getenv("_MDB_EXEC") != NULL) 457 0 stevel mdb.m_flags |= MDB_FL_EXEC; 458 0 stevel 459 0 stevel /* 460 0 stevel * Setup an alternate signal stack. When tearing down pipelines in 461 0 stevel * terminate(), we may have to destroy the stack of the context in 462 0 stevel * which we are currently executing the signal handler. 463 0 stevel */ 464 0 stevel sigstack.ss_sp = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE, 465 0 stevel MAP_PRIVATE | MAP_ANON, -1, 0); 466 0 stevel if (sigstack.ss_sp == MAP_FAILED) 467 0 stevel die("could not allocate signal stack"); 468 0 stevel sigstack.ss_size = SIGSTKSZ; 469 0 stevel sigstack.ss_flags = 0; 470 0 stevel if (sigaltstack(&sigstack, NULL) != 0) 471 0 stevel die("could not set signal stack"); 472 0 stevel 473 0 stevel (void) mdb_signal_sethandler(SIGPIPE, SIG_IGN, NULL); 474 0 stevel (void) mdb_signal_sethandler(SIGQUIT, SIG_IGN, NULL); 475 0 stevel 476 0 stevel (void) mdb_signal_sethandler(SIGILL, flt_handler, NULL); 477 0 stevel (void) mdb_signal_sethandler(SIGTRAP, flt_handler, NULL); 478 0 stevel (void) mdb_signal_sethandler(SIGIOT, flt_handler, NULL); 479 0 stevel (void) mdb_signal_sethandler(SIGEMT, flt_handler, NULL); 480 0 stevel (void) mdb_signal_sethandler(SIGFPE, flt_handler, NULL); 481 0 stevel (void) mdb_signal_sethandler(SIGBUS, flt_handler, NULL); 482 0 stevel (void) mdb_signal_sethandler(SIGSEGV, flt_handler, NULL); 483 0 stevel 484 0 stevel (void) mdb_signal_sethandler(SIGHUP, (mdb_signal_f *)terminate, NULL); 485 0 stevel (void) mdb_signal_sethandler(SIGTERM, (mdb_signal_f *)terminate, NULL); 486 0 stevel 487 0 stevel for (mdb.m_rdvers = RD_VERSION; mdb.m_rdvers > 0; mdb.m_rdvers--) { 488 0 stevel if (rd_init(mdb.m_rdvers) == RD_OK) 489 0 stevel break; 490 0 stevel } 491 0 stevel 492 0 stevel for (mdb.m_ctfvers = CTF_VERSION; mdb.m_ctfvers > 0; mdb.m_ctfvers--) { 493 0 stevel if (ctf_version(mdb.m_ctfvers) != -1) 494 0 stevel break; 495 0 stevel } 496 0 stevel 497 0 stevel if ((p = getenv("HISTSIZE")) != NULL && strisnum(p)) { 498 0 stevel mdb.m_histlen = strtoi(p); 499 0 stevel if (mdb.m_histlen < 1) 500 0 stevel mdb.m_histlen = 1; 501 0 stevel } 502 0 stevel 503 0 stevel while (optind < argc) { 504 0 stevel while ((c = getopt(argc, argv, 505 0 stevel "fkmo:p:s:uwyACD:FI:KL:MOP:R:SUV:W")) != (int)EOF) { 506 0 stevel switch (c) { 507 0 stevel case 'f': 508 5084 johnlev fflag++; 509 0 stevel tgt_ctor = mdb_rawfile_tgt_create; 510 0 stevel break; 511 0 stevel case 'k': 512 0 stevel tgt_ctor = mdb_kvm_tgt_create; 513 0 stevel break; 514 0 stevel case 'm': 515 0 stevel mdb.m_tgtflags |= MDB_TGT_F_NOLOAD; 516 0 stevel mdb.m_tgtflags &= ~MDB_TGT_F_PRELOAD; 517 0 stevel break; 518 0 stevel case 'o': 519 0 stevel if (!mdb_set_options(optarg, TRUE)) 520 0 stevel terminate(2); 521 0 stevel break; 522 0 stevel case 'p': 523 0 stevel tgt_ctor = mdb_proc_tgt_create; 524 0 stevel pidarg = optarg; 525 0 stevel break; 526 0 stevel case 's': 527 0 stevel if (!strisnum(optarg)) { 528 0 stevel warn("expected integer following -s\n"); 529 0 stevel terminate(2); 530 0 stevel } 531 0 stevel mdb.m_symdist = (size_t)(uint_t)strtoi(optarg); 532 0 stevel break; 533 0 stevel case 'u': 534 0 stevel tgt_ctor = mdb_proc_tgt_create; 535 0 stevel break; 536 0 stevel case 'w': 537 0 stevel mdb.m_tgtflags |= MDB_TGT_F_RDWR; 538 0 stevel break; 539 0 stevel case 'y': 540 0 stevel mdb.m_flags |= MDB_FL_USECUP; 541 0 stevel break; 542 0 stevel case 'A': 543 0 stevel (void) mdb_set_options("nomods", TRUE); 544 0 stevel break; 545 0 stevel case 'C': 546 0 stevel (void) mdb_set_options("noctf", TRUE); 547 0 stevel break; 548 0 stevel case 'D': 549 0 stevel mdb_dmode(mdb_dstr2mode(optarg)); 550 0 stevel break; 551 0 stevel case 'F': 552 0 stevel mdb.m_tgtflags |= MDB_TGT_F_FORCE; 553 0 stevel break; 554 0 stevel case 'I': 555 0 stevel Iflag = optarg; 556 0 stevel break; 557 0 stevel case 'L': 558 0 stevel Lflag = optarg; 559 0 stevel break; 560 0 stevel case 'K': 561 0 stevel Kflag++; 562 0 stevel break; 563 0 stevel case 'M': 564 0 stevel mdb.m_tgtflags |= MDB_TGT_F_PRELOAD; 565 0 stevel mdb.m_tgtflags &= ~MDB_TGT_F_NOLOAD; 566 0 stevel break; 567 0 stevel case 'O': 568 0 stevel Oflag++; 569 0 stevel break; 570 0 stevel case 'P': 571 0 stevel if (!mdb_set_prompt(optarg)) 572 0 stevel terminate(2); 573 0 stevel break; 574 0 stevel case 'R': 575 0 stevel (void) strncpy(mdb.m_root, optarg, MAXPATHLEN); 576 0 stevel mdb.m_root[MAXPATHLEN - 1] = '\0'; 577 0 stevel Rflag++; 578 0 stevel break; 579 0 stevel case 'S': 580 0 stevel Sflag++; 581 0 stevel break; 582 0 stevel case 'U': 583 0 stevel Uflag++; 584 0 stevel break; 585 0 stevel case 'V': 586 0 stevel Vflag = optarg; 587 0 stevel break; 588 0 stevel case 'W': 589 0 stevel mdb.m_tgtflags |= MDB_TGT_F_ALLOWIO; 590 0 stevel break; 591 0 stevel case '?': 592 0 stevel if (optopt == '?') 593 0 stevel usage(0); 594 0 stevel /* FALLTHROUGH */ 595 0 stevel default: 596 0 stevel usage(2); 597 0 stevel } 598 0 stevel } 599 0 stevel 600 0 stevel if (optind < argc) { 601 0 stevel const char *arg = argv[optind++]; 602 0 stevel 603 0 stevel if (arg[0] == '+' && strlen(arg) == 2) { 604 0 stevel if (arg[1] != 'o') { 605 0 stevel warn("illegal option -- %s\n", arg); 606 0 stevel terminate(2); 607 0 stevel } 608 0 stevel if (optind >= argc) { 609 0 stevel warn("option requires an argument -- " 610 0 stevel "%s\n", arg); 611 0 stevel terminate(2); 612 0 stevel } 613 0 stevel if (!mdb_set_options(argv[optind++], FALSE)) 614 0 stevel terminate(2); 615 0 stevel } else 616 0 stevel tgt_argv[tgt_argc++] = arg; 617 0 stevel } 618 0 stevel } 619 0 stevel 620 2712 nn35248 if (rd_ctl(RD_CTL_SET_HELPPATH, (void *)mdb.m_root) != RD_OK) { 621 2712 nn35248 warn("cannot set librtld_db helper path to %s\n", mdb.m_root); 622 2712 nn35248 terminate(2); 623 2712 nn35248 } 624 2712 nn35248 625 0 stevel if (mdb.m_debug & MDB_DBG_HELP) 626 0 stevel terminate(0); /* Quit here if we've printed out the tokens */ 627 2712 nn35248 628 0 stevel 629 0 stevel if (Iflag != NULL && strchr(Iflag, ';') != NULL) { 630 0 stevel warn("macro path cannot contain semicolons\n"); 631 0 stevel terminate(2); 632 0 stevel } 633 0 stevel 634 0 stevel if (Lflag != NULL && strchr(Lflag, ';') != NULL) { 635 0 stevel warn("module path cannot contain semicolons\n"); 636 0 stevel terminate(2); 637 0 stevel } 638 0 stevel 639 0 stevel if (Kflag || Uflag) { 640 0 stevel char *nm; 641 0 stevel 642 0 stevel if (tgt_ctor != NULL || Iflag != NULL) { 643 0 stevel warn("neither -f, -k, -p, -u, nor -I " 644 0 stevel "may be used with -K\n"); 645 0 stevel usage(2); 646 0 stevel } 647 0 stevel 648 0 stevel if (Lflag != NULL) 649 0 stevel mdb_set_lpath(Lflag); 650 0 stevel 651 0 stevel if ((nm = ttyname(STDIN_FILENO)) == NULL || 652 0 stevel strcmp(nm, "/dev/console") != 0) { 653 0 stevel /* 654 0 stevel * Due to the consequences of typing mdb -K instead of 655 0 stevel * mdb -k on a tty other than /dev/console, we require 656 0 stevel * -F when starting kmdb from a tty other than 657 0 stevel * /dev/console. 658 0 stevel */ 659 0 stevel if (!(mdb.m_tgtflags & MDB_TGT_F_FORCE)) { 660 0 stevel die("-F must also be supplied to start kmdb " 661 0 stevel "from non-console tty\n"); 662 0 stevel } 663 0 stevel 664 0 stevel if (mdb.m_termtype == NULL || (mdb.m_flags & 665 0 stevel MDB_FL_TERMGUESS)) { 666 0 stevel if (mdb.m_termtype != NULL) 667 0 stevel strfree(mdb.m_termtype); 668 0 stevel 669 0 stevel if ((mdb.m_termtype = mdb_scf_console_term()) != 670 0 stevel NULL) 671 0 stevel mdb.m_flags |= MDB_FL_TERMGUESS; 672 0 stevel } 673 0 stevel } else { 674 0 stevel /* 675 0 stevel * When on console, $TERM (if set) takes precedence over 676 0 stevel * the SMF setting. 677 0 stevel */ 678 0 stevel if (mdb.m_termtype == NULL && (mdb.m_termtype = 679 0 stevel mdb_scf_console_term()) != NULL) 680 0 stevel mdb.m_flags |= MDB_FL_TERMGUESS; 681 0 stevel } 682 0 stevel 683 0 stevel control_kmdb(Kflag); 684 0 stevel terminate(0); 685 0 stevel /*NOTREACHED*/ 686 0 stevel } 687 0 stevel 688 0 stevel /* 689 0 stevel * If standard input appears to have tty attributes, attempt to 690 0 stevel * initialize a terminal i/o backend on top of stdin and stdout. 691 0 stevel */ 692 0 stevel ttylike = (IOP_CTL(in_io, TCGETS, &tios) == 0); 693 0 stevel if (ttylike) { 694 0 stevel if ((mdb.m_term = mdb_termio_create(mdb.m_termtype, 695 0 stevel in_io, out_io)) == NULL) { 696 0 stevel if (!(mdb.m_flags & MDB_FL_EXEC)) { 697 0 stevel warn("term init failed: command-line editing " 698 0 stevel "and prompt will not be available\n"); 699 0 stevel } 700 0 stevel } else { 701 0 stevel in_io = mdb.m_term; 702 0 stevel } 703 0 stevel } 704 0 stevel 705 0 stevel mdb.m_in = mdb_iob_create(in_io, MDB_IOB_RDONLY); 706 0 stevel if (mdb.m_term != NULL) { 707 0 stevel mdb_iob_setpager(mdb.m_out, mdb.m_term); 708 0 stevel if (mdb.m_flags & MDB_FL_PAGER) 709 0 stevel mdb_iob_setflags(mdb.m_out, MDB_IOB_PGENABLE); 710 0 stevel else 711 0 stevel mdb_iob_clrflags(mdb.m_out, MDB_IOB_PGENABLE); 712 0 stevel } else if (ttylike) 713 0 stevel mdb_iob_setflags(mdb.m_in, MDB_IOB_TTYLIKE); 714 0 stevel else 715 0 stevel mdb_iob_setbuf(mdb.m_in, mdb_alloc(1, UM_SLEEP), 1); 716 0 stevel 717 0 stevel mdb_pservice_init(); 718 0 stevel mdb_lex_reset(); 719 0 stevel 720 0 stevel if ((mdb.m_shell = getenv("SHELL")) == NULL) 721 0 stevel mdb.m_shell = "/bin/sh"; 722 0 stevel 723 6144 rab /* 724 6144 rab * If the debugger state is to be inherited from a previous instance, 725 6144 rab * restore it now prior to path evaluation so that %R is updated. 726 6144 rab */ 727 6144 rab if ((p = getenv(MDB_CONFIG_ENV_VAR)) != NULL) { 728 6144 rab mdb_set_config(p); 729 6144 rab (void) unsetenv(MDB_CONFIG_ENV_VAR); 730 6144 rab } 731 6144 rab 732 6144 rab /* 733 6144 rab * Path evaluation part 1: Create the initial module path to allow 734 6144 rab * the target constructor to load a support module. Then expand 735 6144 rab * any command-line arguments that modify the paths. 736 6144 rab */ 737 6144 rab if (Iflag != NULL) 738 6144 rab mdb_set_ipath(Iflag); 739 6144 rab else 740 6144 rab mdb_set_ipath(MDB_DEF_IPATH); 741 6144 rab 742 6144 rab if (Lflag != NULL) 743 6144 rab mdb_set_lpath(Lflag); 744 6144 rab else 745 6144 rab mdb_set_lpath(MDB_DEF_LPATH); 746 6144 rab 747 6144 rab if (mdb_get_prompt() == NULL && !(mdb.m_flags & MDB_FL_ADB)) 748 6144 rab (void) mdb_set_prompt(MDB_DEF_PROMPT); 749 6144 rab 750 0 stevel if (tgt_ctor == mdb_kvm_tgt_create) { 751 0 stevel if (pidarg != NULL) { 752 0 stevel warn("-p and -k options are mutually exclusive\n"); 753 0 stevel terminate(2); 754 0 stevel } 755 0 stevel 756 0 stevel if (tgt_argc == 0) 757 0 stevel tgt_argv[tgt_argc++] = "/dev/ksyms"; 758 0 stevel if (tgt_argc == 1 && strisnum(tgt_argv[0]) == 0) { 759 0 stevel if (mdb.m_tgtflags & MDB_TGT_F_ALLOWIO) 760 0 stevel tgt_argv[tgt_argc++] = "/dev/allkmem"; 761 0 stevel else 762 0 stevel tgt_argv[tgt_argc++] = "/dev/kmem"; 763 0 stevel } 764 0 stevel } 765 0 stevel 766 0 stevel if (pidarg != NULL) { 767 0 stevel if (tgt_argc != 0) { 768 0 stevel warn("-p may not be used with other arguments\n"); 769 0 stevel terminate(2); 770 0 stevel } 771 0 stevel if (proc_arg_psinfo(pidarg, PR_ARG_PIDS, NULL, &status) == -1) { 772 0 stevel die("cannot attach to %s: %s\n", 773 0 stevel pidarg, Pgrab_error(status)); 774 0 stevel } 775 0 stevel if (strchr(pidarg, '/') != NULL) 776 0 stevel (void) mdb_iob_snprintf(object, MAXPATHLEN, 777 0 stevel "%s/object/a.out", pidarg); 778 0 stevel else 779 0 stevel (void) mdb_iob_snprintf(object, MAXPATHLEN, 780 0 stevel "/proc/%s/object/a.out", pidarg); 781 0 stevel tgt_argv[tgt_argc++] = object; 782 0 stevel tgt_argv[tgt_argc++] = pidarg; 783 0 stevel } 784 0 stevel 785 0 stevel /* 786 0 stevel * Find the first argument that is not a special "-" token. If one is 787 0 stevel * found, we will examine this file and make some inferences below. 788 0 stevel */ 789 0 stevel for (c = 0; c < tgt_argc && strcmp(tgt_argv[c], "-") == 0; c++) 790 0 stevel continue; 791 0 stevel 792 0 stevel if (c < tgt_argc) { 793 0 stevel Elf32_Ehdr ehdr; 794 0 stevel mdb_io_t *io; 795 0 stevel 796 0 stevel /* 797 0 stevel * If special "-" tokens preceded an argument, shift the entire 798 0 stevel * argument list to the left to remove the leading "-" args. 799 0 stevel */ 800 0 stevel if (c > 0) { 801 0 stevel bcopy(&tgt_argv[c], tgt_argv, 802 0 stevel sizeof (const char *) * (tgt_argc - c)); 803 0 stevel tgt_argc -= c; 804 0 stevel } 805 0 stevel 806 0 stevel /* 807 0 stevel * If we just have an object file name, and that file doesn't 808 0 stevel * exist, and it's a string of digits, infer it to be a 809 0 stevel * sequence number referring to a pair of crash dump files. 810 0 stevel */ 811 0 stevel if (tgt_argc == 1 && access(tgt_argv[0], F_OK) == -1 && 812 0 stevel strisnum(tgt_argv[0])) { 813 0 stevel 814 0 stevel size_t len = strlen(tgt_argv[0]) + 8; 815 0 stevel const char *object = tgt_argv[0]; 816 0 stevel 817 0 stevel tgt_argv[0] = mdb_alloc(len, UM_SLEEP); 818 0 stevel tgt_argv[1] = mdb_alloc(len, UM_SLEEP); 819 0 stevel 820 0 stevel (void) strcpy((char *)tgt_argv[0], "unix."); 821 0 stevel (void) strcat((char *)tgt_argv[0], object); 822 0 stevel (void) strcpy((char *)tgt_argv[1], "vmcore."); 823 0 stevel (void) strcat((char *)tgt_argv[1], object); 824 0 stevel 825 10843 Dave if (access(tgt_argv[0], F_OK) == -1 && 826 10843 Dave access(tgt_argv[1], F_OK) == -1) { 827 10843 Dave (void) strcpy((char *)tgt_argv[1], "vmdump."); 828 10843 Dave (void) strcat((char *)tgt_argv[1], object); 829 10843 Dave if (access(tgt_argv[1], F_OK) == 0) { 830 10843 Dave mdb_iob_printf(mdb.m_err, 831 10843 Dave "cannot open compressed dump; " 832 10843 Dave "decompress using savecore -f %s\n", 833 10843 Dave tgt_argv[1]); 834 10843 Dave terminate(0); 835 10843 Dave } 836 10843 Dave } 837 10843 Dave 838 0 stevel tgt_argc = 2; 839 0 stevel } 840 0 stevel 841 0 stevel /* 842 0 stevel * We need to open the object file in order to determine its 843 0 stevel * ELF class and potentially re-exec ourself. 844 0 stevel */ 845 0 stevel if ((io = mdb_fdio_create_path(NULL, tgt_argv[0], 846 0 stevel O_RDONLY, 0)) == NULL) 847 0 stevel die("failed to open %s", tgt_argv[0]); 848 10843 Dave 849 10843 Dave /* 850 10843 Dave * Check for a single vmdump.N compressed dump file, 851 10843 Dave * and give a helpful message. 852 10843 Dave */ 853 10843 Dave if (tgt_argc == 1) { 854 10843 Dave if (mdb_kvm_is_compressed_dump(io)) { 855 10843 Dave mdb_iob_printf(mdb.m_err, 856 10843 Dave "cannot open compressed dump; " 857 10843 Dave "decompress using savecore -f %s\n", 858 10843 Dave tgt_argv[0]); 859 10843 Dave terminate(0); 860 10843 Dave } 861 10843 Dave } 862 0 stevel 863 0 stevel /* 864 0 stevel * If the target is unknown or is not the rawfile target, do 865 0 stevel * a gelf_check to determine if the file is an ELF file. If 866 0 stevel * it is not and the target is unknown, use the rawfile tgt. 867 0 stevel * Otherwise an ELF-based target is needed, so we must abort. 868 0 stevel */ 869 0 stevel if (tgt_ctor != mdb_rawfile_tgt_create && 870 0 stevel mdb_gelf_check(io, &ehdr, ET_NONE) == -1) { 871 0 stevel if (tgt_ctor != NULL) { 872 0 stevel (void) mdb_gelf_check(io, &ehdr, ET_EXEC); 873 0 stevel mdb_io_destroy(io); 874 0 stevel terminate(1); 875 0 stevel } else 876 0 stevel tgt_ctor = mdb_rawfile_tgt_create; 877 0 stevel } 878 0 stevel 879 0 stevel mdb_io_destroy(io); 880 0 stevel 881 6144 rab if (identify_xvm_file(tgt_argv[0], &longmode) == 1 && 882 6144 rab !fflag) { 883 6144 rab #ifdef _LP64 884 6144 rab if (!longmode) 885 6144 rab goto reexec; 886 6144 rab #else 887 6144 rab if (longmode) 888 6144 rab goto reexec; 889 6144 rab #endif 890 6144 rab tgt_ctor = mdb_kvm_tgt_create; 891 6144 rab goto tcreate; 892 6144 rab } 893 6144 rab 894 0 stevel if (tgt_ctor == mdb_rawfile_tgt_create) 895 0 stevel goto tcreate; /* skip re-exec and just create target */ 896 0 stevel 897 0 stevel /* 898 0 stevel * The object file turned out to be a user core file (ET_CORE), 899 0 stevel * and no other arguments were specified, swap 0 and 1. The 900 0 stevel * proc target will infer the executable for us. 901 0 stevel */ 902 0 stevel if (ehdr.e_type == ET_CORE) { 903 0 stevel tgt_argv[tgt_argc++] = tgt_argv[0]; 904 0 stevel tgt_argv[0] = NULL; 905 0 stevel tgt_ctor = mdb_proc_tgt_create; 906 0 stevel } 907 0 stevel 908 0 stevel /* 909 0 stevel * If tgt_argv[1] is filled in, open it up and determine if it 910 0 stevel * is a vmcore file. If it is, gelf_check will fail and we 911 0 stevel * set tgt_ctor to 'kvm'; otherwise we use the default. 912 0 stevel */ 913 0 stevel if (tgt_argc > 1 && strcmp(tgt_argv[1], "-") != 0 && 914 0 stevel tgt_argv[0] != NULL && pidarg == NULL) { 915 0 stevel Elf32_Ehdr chdr; 916 0 stevel 917 0 stevel if (access(tgt_argv[1], F_OK) == -1) 918 0 stevel die("failed to access %s", tgt_argv[1]); 919 10843 Dave 920 10843 Dave /* *.N case: drop vmdump.N from the list */ 921 10843 Dave if (tgt_argc == 3) { 922 10843 Dave if ((io = mdb_fdio_create_path(NULL, 923 10843 Dave tgt_argv[2], O_RDONLY, 0)) == NULL) 924 10843 Dave die("failed to open %s", tgt_argv[2]); 925 10843 Dave if (mdb_kvm_is_compressed_dump(io)) 926 10843 Dave tgt_argv[--tgt_argc] = NULL; 927 10843 Dave mdb_io_destroy(io); 928 10843 Dave } 929 0 stevel 930 0 stevel if ((io = mdb_fdio_create_path(NULL, tgt_argv[1], 931 0 stevel O_RDONLY, 0)) == NULL) 932 0 stevel die("failed to open %s", tgt_argv[1]); 933 0 stevel 934 0 stevel if (mdb_gelf_check(io, &chdr, ET_NONE) == -1) 935 0 stevel tgt_ctor = mdb_kvm_tgt_create; 936 0 stevel 937 0 stevel mdb_io_destroy(io); 938 0 stevel } 939 0 stevel 940 0 stevel /* 941 0 stevel * At this point, we've read the ELF header for either an 942 0 stevel * object file or core into ehdr. If the class does not match 943 0 stevel * ours, attempt to exec the mdb of the appropriate class. 944 0 stevel */ 945 0 stevel #ifdef _LP64 946 5084 johnlev if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) 947 5084 johnlev goto reexec; 948 0 stevel #else 949 5084 johnlev if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) 950 5084 johnlev goto reexec; 951 0 stevel #endif 952 0 stevel } 953 0 stevel 954 0 stevel tcreate: 955 0 stevel if (tgt_ctor == NULL) 956 0 stevel tgt_ctor = mdb_proc_tgt_create; 957 0 stevel 958 0 stevel tgt = mdb_tgt_create(tgt_ctor, mdb.m_tgtflags, tgt_argc, tgt_argv); 959 0 stevel 960 0 stevel if (tgt == NULL) { 961 0 stevel if (errno == EINVAL) 962 0 stevel usage(2); /* target can return EINVAL to get usage */ 963 0 stevel if (errno == EMDB_TGT) 964 0 stevel terminate(1); /* target already printed error msg */ 965 0 stevel die("failed to initialize target"); 966 0 stevel } 967 0 stevel 968 0 stevel mdb_tgt_activate(tgt); 969 0 stevel 970 0 stevel mdb_create_loadable_disasms(); 971 0 stevel 972 0 stevel if (Vflag != NULL && mdb_dis_select(Vflag) == -1) 973 0 stevel warn("invalid disassembler mode -- %s\n", Vflag); 974 0 stevel 975 0 stevel 976 0 stevel if (Rflag && mdb.m_term != NULL) 977 0 stevel warn("Using proto area %s\n", mdb.m_root); 978 0 stevel 979 0 stevel /* 980 0 stevel * If the target was successfully constructed and -O was specified, 981 0 stevel * we now attempt to enter piggy-mode for debugging jurassic problems. 982 0 stevel */ 983 0 stevel if (Oflag) { 984 0 stevel pcinfo_t pci; 985 0 stevel 986 0 stevel (void) strcpy(pci.pc_clname, "RT"); 987 0 stevel 988 0 stevel if (priocntl(P_LWPID, P_MYID, PC_GETCID, (caddr_t)&pci) != -1) { 989 0 stevel pcparms_t pcp; 990 0 stevel rtparms_t *rtp = (rtparms_t *)pcp.pc_clparms; 991 0 stevel 992 0 stevel rtp->rt_pri = 35; 993 0 stevel rtp->rt_tqsecs = 0; 994 0 stevel rtp->rt_tqnsecs = RT_TQDEF; 995 0 stevel 996 0 stevel pcp.pc_cid = pci.pc_cid; 997 0 stevel 998 0 stevel if (priocntl(P_LWPID, P_MYID, PC_SETPARMS, 999 0 stevel (caddr_t)&pcp) == -1) { 1000 0 stevel warn("failed to set RT parameters"); 1001 0 stevel Oflag = 0; 1002 0 stevel } 1003 0 stevel } else { 1004 0 stevel warn("failed to get RT class id"); 1005 0 stevel Oflag = 0; 1006 0 stevel } 1007 0 stevel 1008 0 stevel if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) { 1009 0 stevel warn("failed to lock address space"); 1010 0 stevel Oflag = 0; 1011 0 stevel } 1012 0 stevel 1013 0 stevel if (Oflag) 1014 0 stevel mdb_printf("%s: oink, oink!\n", mdb.m_pname); 1015 0 stevel } 1016 0 stevel 1017 0 stevel /* 1018 0 stevel * Path evaluation part 2: Re-evaluate the path now that the target 1019 0 stevel * is ready (and thus we have access to the real platform string). 1020 0 stevel * Do this before reading ~/.mdbrc to allow path modifications prior 1021 0 stevel * to performing module auto-loading. 1022 0 stevel */ 1023 0 stevel mdb_set_ipath(mdb.m_ipathstr); 1024 0 stevel mdb_set_lpath(mdb.m_lpathstr); 1025 0 stevel 1026 0 stevel if (!Sflag && (p = getenv("HOME")) != NULL) { 1027 0 stevel char rcpath[MAXPATHLEN]; 1028 0 stevel mdb_io_t *rc_io; 1029 0 stevel int fd; 1030 0 stevel 1031 0 stevel (void) mdb_iob_snprintf(rcpath, MAXPATHLEN, "%s/.mdbrc", p); 1032 0 stevel fd = open64(rcpath, O_RDONLY); 1033 0 stevel 1034 0 stevel if (fd >= 0 && (rc_io = mdb_fdio_create_named(fd, rcpath))) { 1035 0 stevel mdb_iob_t *iob = mdb_iob_create(rc_io, MDB_IOB_RDONLY); 1036 0 stevel mdb_iob_t *old = mdb.m_in; 1037 0 stevel 1038 0 stevel mdb.m_in = iob; 1039 0 stevel (void) mdb_run(); 1040 0 stevel mdb.m_in = old; 1041 0 stevel } 1042 0 stevel } 1043 0 stevel 1044 0 stevel if (!(mdb.m_flags & MDB_FL_NOMODS)) 1045 0 stevel mdb_module_load_all(0); 1046 0 stevel 1047 0 stevel (void) mdb_signal_sethandler(SIGINT, int_handler, NULL); 1048 0 stevel while ((status = mdb_run()) == MDB_ERR_ABORT || 1049 0 stevel status == MDB_ERR_OUTPUT) { 1050 0 stevel /* 1051 0 stevel * If a write failed on stdout, give up. A more informative 1052 0 stevel * error message will already have been printed by mdb_run(). 1053 0 stevel */ 1054 0 stevel if (status == MDB_ERR_OUTPUT && 1055 0 stevel mdb_iob_getflags(mdb.m_out) & MDB_IOB_ERR) { 1056 0 stevel mdb_warn("write to stdout failed, exiting\n"); 1057 0 stevel break; 1058 0 stevel } 1059 0 stevel continue; 1060 0 stevel } 1061 0 stevel 1062 0 stevel terminate((status == MDB_ERR_QUIT || status == 0) ? 0 : 1); 1063 0 stevel /*NOTREACHED*/ 1064 0 stevel return (0); 1065 5084 johnlev 1066 5084 johnlev reexec: 1067 5084 johnlev if ((p = strrchr(execname, '/')) == NULL) 1068 5084 johnlev die("cannot determine absolute pathname\n"); 1069 5084 johnlev #ifdef _LP64 1070 5084 johnlev #ifdef __sparc 1071 5084 johnlev (void) strcpy(p, "/../sparcv7/"); 1072 5084 johnlev #else 1073 5084 johnlev (void) strcpy(p, "/../i86/"); 1074 5084 johnlev #endif 1075 5084 johnlev #else 1076 5084 johnlev #ifdef __sparc 1077 5084 johnlev (void) strcpy(p, "/../sparcv9/"); 1078 5084 johnlev #else 1079 5084 johnlev (void) strcpy(p, "/../amd64/"); 1080 5084 johnlev #endif 1081 5084 johnlev #endif 1082 5084 johnlev (void) strcat(p, mdb.m_pname); 1083 5084 johnlev 1084 5084 johnlev if (mdb.m_term != NULL) 1085 5084 johnlev (void) IOP_CTL(in_io, TCSETSW, &tios); 1086 5084 johnlev 1087 5084 johnlev (void) putenv("_MDB_EXEC=1"); 1088 5084 johnlev (void) execv(execname, argv); 1089 5084 johnlev 1090 5084 johnlev /* 1091 5084 johnlev * If execv fails, suppress ENOEXEC. Experience shows the most common 1092 5084 johnlev * reason is that the machine is booted under a 32-bit kernel, in which 1093 5084 johnlev * case it is clearer to only print the message below. 1094 5084 johnlev */ 1095 5084 johnlev if (errno != ENOEXEC) 1096 5084 johnlev warn("failed to exec %s", execname); 1097 5084 johnlev #ifdef _LP64 1098 5084 johnlev die("64-bit %s cannot debug 32-bit program %s\n", 1099 5084 johnlev mdb.m_pname, tgt_argv[0] ? 1100 5084 johnlev tgt_argv[0] : tgt_argv[1]); 1101 5084 johnlev #else 1102 5084 johnlev die("32-bit %s cannot debug 64-bit program %s\n", 1103 5084 johnlev mdb.m_pname, tgt_argv[0] ? 1104 5084 johnlev tgt_argv[0] : tgt_argv[1]); 1105 5084 johnlev #endif 1106 5084 johnlev 1107 5084 johnlev goto tcreate; 1108 0 stevel } 1109