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