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