xref: /illumos-gate/usr/src/cmd/mdb/common/mdb/mdb_main.c (revision e4a991eb9ba3d449515f2fe5f9f2a9e1c33ca0fd)
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 2019 Joyent, Inc.
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,
494 	    (mdb_signal_f *)(uintptr_t)terminate, NULL);
495 	(void) mdb_signal_sethandler(SIGTERM,
496 	    (mdb_signal_f *)(uintptr_t)terminate, NULL);
497 
498 	for (mdb.m_rdvers = RD_VERSION; mdb.m_rdvers > 0; mdb.m_rdvers--) {
499 		if (rd_init(mdb.m_rdvers) == RD_OK)
500 			break;
501 	}
502 
503 	for (mdb.m_ctfvers = CTF_VERSION; mdb.m_ctfvers > 0; mdb.m_ctfvers--) {
504 		if (ctf_version(mdb.m_ctfvers) != -1)
505 			break;
506 	}
507 
508 	if ((p = getenv("HISTSIZE")) != NULL && strisnum(p)) {
509 		mdb.m_histlen = strtoi(p);
510 		if (mdb.m_histlen < 1)
511 			mdb.m_histlen = 1;
512 	}
513 
514 	while (optind < argc) {
515 		while ((c = getopt(argc, argv,
516 		    "e:fkmo:p:s:uwyACD:FI:KL:MOP:R:SUV:W")) != (int)EOF) {
517 			switch (c) {
518 			case 'e':
519 				if (eflag != NULL) {
520 					warn("-e already specified\n");
521 					terminate(2);
522 				}
523 				eflag = optarg;
524 				break;
525 			case 'f':
526 				fflag++;
527 				tgt_ctor = mdb_rawfile_tgt_create;
528 				break;
529 			case 'k':
530 				tgt_ctor = mdb_kvm_tgt_create;
531 				break;
532 			case 'm':
533 				mdb.m_tgtflags |= MDB_TGT_F_NOLOAD;
534 				mdb.m_tgtflags &= ~MDB_TGT_F_PRELOAD;
535 				break;
536 			case 'o':
537 				if (!mdb_set_options(optarg, TRUE))
538 					terminate(2);
539 				break;
540 			case 'p':
541 				tgt_ctor = mdb_proc_tgt_create;
542 				pidarg = optarg;
543 				break;
544 			case 's':
545 				if (!strisnum(optarg)) {
546 					warn("expected integer following -s\n");
547 					terminate(2);
548 				}
549 				mdb.m_symdist = (size_t)(uint_t)strtoi(optarg);
550 				break;
551 			case 'u':
552 				tgt_ctor = mdb_proc_tgt_create;
553 				break;
554 			case 'w':
555 				mdb.m_tgtflags |= MDB_TGT_F_RDWR;
556 				break;
557 			case 'y':
558 				mdb.m_flags |= MDB_FL_USECUP;
559 				break;
560 			case 'A':
561 				(void) mdb_set_options("nomods", TRUE);
562 				break;
563 			case 'C':
564 				(void) mdb_set_options("noctf", TRUE);
565 				break;
566 			case 'D':
567 				mdb_dmode(mdb_dstr2mode(optarg));
568 				break;
569 			case 'F':
570 				mdb.m_tgtflags |= MDB_TGT_F_FORCE;
571 				break;
572 			case 'I':
573 				Iflag = optarg;
574 				break;
575 			case 'L':
576 				Lflag = optarg;
577 				break;
578 			case 'K':
579 				Kflag++;
580 				break;
581 			case 'M':
582 				mdb.m_tgtflags |= MDB_TGT_F_PRELOAD;
583 				mdb.m_tgtflags &= ~MDB_TGT_F_NOLOAD;
584 				break;
585 			case 'O':
586 				Oflag++;
587 				break;
588 			case 'P':
589 				if (!mdb_set_prompt(optarg))
590 					terminate(2);
591 				break;
592 			case 'R':
593 				(void) strncpy(mdb.m_root, optarg, MAXPATHLEN);
594 				mdb.m_root[MAXPATHLEN - 1] = '\0';
595 				Rflag++;
596 				break;
597 			case 'S':
598 				Sflag++;
599 				break;
600 			case 'U':
601 				Uflag++;
602 				break;
603 			case 'V':
604 				Vflag = optarg;
605 				break;
606 			case 'W':
607 				mdb.m_tgtflags |= MDB_TGT_F_ALLOWIO;
608 				break;
609 			case '?':
610 				if (optopt == '?')
611 					usage(0);
612 				/* FALLTHROUGH */
613 			default:
614 				usage(2);
615 			}
616 		}
617 
618 		if (optind < argc) {
619 			const char *arg = argv[optind++];
620 
621 			if (arg[0] == '+' && strlen(arg) == 2) {
622 				if (arg[1] != 'o') {
623 					warn("illegal option -- %s\n", arg);
624 					terminate(2);
625 				}
626 				if (optind >= argc) {
627 					warn("option requires an argument -- "
628 					    "%s\n", arg);
629 					terminate(2);
630 				}
631 				if (!mdb_set_options(argv[optind++], FALSE))
632 					terminate(2);
633 			} else
634 				tgt_argv[tgt_argc++] = arg;
635 		}
636 	}
637 
638 	if (rd_ctl(RD_CTL_SET_HELPPATH, (void *)mdb.m_root) != RD_OK) {
639 		warn("cannot set librtld_db helper path to %s\n", mdb.m_root);
640 		terminate(2);
641 	}
642 
643 	if (mdb.m_debug & MDB_DBG_HELP)
644 		terminate(0); /* Quit here if we've printed out the tokens */
645 
646 
647 	if (Iflag != NULL && strchr(Iflag, ';') != NULL) {
648 		warn("macro path cannot contain semicolons\n");
649 		terminate(2);
650 	}
651 
652 	if (Lflag != NULL && strchr(Lflag, ';') != NULL) {
653 		warn("module path cannot contain semicolons\n");
654 		terminate(2);
655 	}
656 
657 	if (Kflag || Uflag) {
658 		char *nm;
659 
660 		if (tgt_ctor != NULL || Iflag != NULL) {
661 			warn("neither -f, -k, -p, -u, nor -I "
662 			    "may be used with -K\n");
663 			usage(2);
664 		}
665 
666 		if (Lflag != NULL)
667 			mdb_set_lpath(Lflag);
668 
669 		if ((nm = ttyname(STDIN_FILENO)) == NULL ||
670 		    strcmp(nm, "/dev/console") != 0) {
671 			/*
672 			 * Due to the consequences of typing mdb -K instead of
673 			 * mdb -k on a tty other than /dev/console, we require
674 			 * -F when starting kmdb from a tty other than
675 			 * /dev/console.
676 			 */
677 			if (!(mdb.m_tgtflags & MDB_TGT_F_FORCE)) {
678 				die("-F must also be supplied to start kmdb "
679 				    "from non-console tty\n");
680 			}
681 
682 			if (mdb.m_termtype == NULL || (mdb.m_flags &
683 			    MDB_FL_TERMGUESS)) {
684 				if (mdb.m_termtype != NULL)
685 					strfree(mdb.m_termtype);
686 
687 				if ((mdb.m_termtype = mdb_scf_console_term()) !=
688 				    NULL)
689 					mdb.m_flags |= MDB_FL_TERMGUESS;
690 			}
691 		} else {
692 			/*
693 			 * When on console, $TERM (if set) takes precedence over
694 			 * the SMF setting.
695 			 */
696 			if (mdb.m_termtype == NULL && (mdb.m_termtype =
697 			    mdb_scf_console_term()) != NULL)
698 				mdb.m_flags |= MDB_FL_TERMGUESS;
699 		}
700 
701 		control_kmdb(Kflag);
702 		terminate(0);
703 		/*NOTREACHED*/
704 	}
705 
706 	if (eflag != NULL) {
707 		IOP_CLOSE(in_io);
708 		in_io = mdb_strio_create(eflag);
709 		mdb.m_lastret = 0;
710 	}
711 
712 	/*
713 	 * If standard input appears to have tty attributes, attempt to
714 	 * initialize a terminal i/o backend on top of stdin and stdout.
715 	 */
716 	ttylike = (IOP_CTL(in_io, TCGETS, &tios) == 0);
717 	if (ttylike) {
718 		if ((mdb.m_term = mdb_termio_create(mdb.m_termtype,
719 		    in_io, out_io)) == NULL) {
720 			if (!(mdb.m_flags & MDB_FL_EXEC)) {
721 				warn("term init failed: command-line editing "
722 				    "and prompt will not be available\n");
723 			}
724 		} else {
725 			in_io = mdb.m_term;
726 		}
727 	}
728 
729 	mdb.m_in = mdb_iob_create(in_io, MDB_IOB_RDONLY);
730 	if (mdb.m_term != NULL) {
731 		mdb_iob_setpager(mdb.m_out, mdb.m_term);
732 		if (mdb.m_flags & MDB_FL_PAGER)
733 			mdb_iob_setflags(mdb.m_out, MDB_IOB_PGENABLE);
734 		else
735 			mdb_iob_clrflags(mdb.m_out, MDB_IOB_PGENABLE);
736 	} else if (ttylike)
737 		mdb_iob_setflags(mdb.m_in, MDB_IOB_TTYLIKE);
738 	else
739 		mdb_iob_setbuf(mdb.m_in, mdb_alloc(1, UM_SLEEP), 1);
740 
741 	mdb_pservice_init();
742 	mdb_lex_reset();
743 
744 	if ((mdb.m_shell = getenv("SHELL")) == NULL)
745 		mdb.m_shell = "/bin/sh";
746 
747 	/*
748 	 * If the debugger state is to be inherited from a previous instance,
749 	 * restore it now prior to path evaluation so that %R is updated.
750 	 */
751 	if ((p = getenv(MDB_CONFIG_ENV_VAR)) != NULL) {
752 		mdb_set_config(p);
753 		(void) unsetenv(MDB_CONFIG_ENV_VAR);
754 	}
755 
756 	/*
757 	 * Path evaluation part 1: Create the initial module path to allow
758 	 * the target constructor to load a support module.  Then expand
759 	 * any command-line arguments that modify the paths.
760 	 */
761 	if (Iflag != NULL)
762 		mdb_set_ipath(Iflag);
763 	else
764 		mdb_set_ipath(MDB_DEF_IPATH);
765 
766 	if (Lflag != NULL)
767 		mdb_set_lpath(Lflag);
768 	else
769 		mdb_set_lpath(MDB_DEF_LPATH);
770 
771 	if (mdb_get_prompt() == NULL && !(mdb.m_flags & MDB_FL_ADB))
772 		(void) mdb_set_prompt(MDB_DEF_PROMPT);
773 
774 	if (tgt_ctor == mdb_kvm_tgt_create) {
775 		if (pidarg != NULL) {
776 			warn("-p and -k options are mutually exclusive\n");
777 			terminate(2);
778 		}
779 
780 		if (tgt_argc == 0)
781 			tgt_argv[tgt_argc++] = "/dev/ksyms";
782 		if (tgt_argc == 1 && strisnum(tgt_argv[0]) == 0) {
783 			if (mdb.m_tgtflags & MDB_TGT_F_ALLOWIO)
784 				tgt_argv[tgt_argc++] = "/dev/allkmem";
785 			else
786 				tgt_argv[tgt_argc++] = "/dev/kmem";
787 		}
788 	}
789 
790 	if (pidarg != NULL) {
791 		if (tgt_argc != 0) {
792 			warn("-p may not be used with other arguments\n");
793 			terminate(2);
794 		}
795 		if (proc_arg_psinfo(pidarg, PR_ARG_PIDS, NULL, &status) == -1) {
796 			die("cannot attach to %s: %s\n",
797 			    pidarg, Pgrab_error(status));
798 		}
799 		if (strchr(pidarg, '/') != NULL)
800 			(void) mdb_iob_snprintf(object, MAXPATHLEN,
801 			    "%s/object/a.out", pidarg);
802 		else
803 			(void) mdb_iob_snprintf(object, MAXPATHLEN,
804 			    "/proc/%s/object/a.out", pidarg);
805 		tgt_argv[tgt_argc++] = object;
806 		tgt_argv[tgt_argc++] = pidarg;
807 	}
808 
809 	/*
810 	 * Find the first argument that is not a special "-" token.  If one is
811 	 * found, we will examine this file and make some inferences below.
812 	 */
813 	for (c = 0; c < tgt_argc && strcmp(tgt_argv[c], "-") == 0; c++)
814 		continue;
815 
816 	if (c < tgt_argc) {
817 		Elf32_Ehdr ehdr;
818 		mdb_io_t *io;
819 
820 		/*
821 		 * If special "-" tokens preceded an argument, shift the entire
822 		 * argument list to the left to remove the leading "-" args.
823 		 */
824 		if (c > 0) {
825 			bcopy(&tgt_argv[c], tgt_argv,
826 			    sizeof (const char *) * (tgt_argc - c));
827 			tgt_argc -= c;
828 		}
829 
830 		if (fflag)
831 			goto tcreate; /* skip re-exec and just create target */
832 
833 		/*
834 		 * If we just have an object file name, and that file doesn't
835 		 * exist, and it's a string of digits, infer it to be a
836 		 * sequence number referring to a pair of crash dump files.
837 		 */
838 		if (tgt_argc == 1 && access(tgt_argv[0], F_OK) == -1 &&
839 		    strisnum(tgt_argv[0])) {
840 
841 			size_t len = strlen(tgt_argv[0]) + 8;
842 			const char *object = tgt_argv[0];
843 
844 			tgt_argv[0] = alloca(len);
845 			tgt_argv[1] = alloca(len);
846 
847 			(void) strcpy((char *)tgt_argv[0], "unix.");
848 			(void) strcat((char *)tgt_argv[0], object);
849 			(void) strcpy((char *)tgt_argv[1], "vmcore.");
850 			(void) strcat((char *)tgt_argv[1], object);
851 
852 			if (access(tgt_argv[0], F_OK) == -1 &&
853 			    access(tgt_argv[1], F_OK) != -1) {
854 				/*
855 				 * If we have a vmcore but not a unix file,
856 				 * set the symbol table to be the vmcore to
857 				 * force libkvm to extract it out of the dump.
858 				 */
859 				tgt_argv[0] = tgt_argv[1];
860 			} else if (access(tgt_argv[0], F_OK) == -1 &&
861 			    access(tgt_argv[1], F_OK) == -1) {
862 				(void) strcpy((char *)tgt_argv[1], "vmdump.");
863 				(void) strcat((char *)tgt_argv[1], object);
864 				if (access(tgt_argv[1], F_OK) == 0) {
865 					mdb_iob_printf(mdb.m_err,
866 					    "cannot open compressed dump; "
867 					    "decompress using savecore -f %s\n",
868 					    tgt_argv[1]);
869 					terminate(0);
870 				}
871 			}
872 
873 			tgt_argc = 2;
874 		}
875 
876 		/*
877 		 * We need to open the object file in order to determine its
878 		 * ELF class and potentially re-exec ourself.
879 		 */
880 		if ((io = mdb_fdio_create_path(NULL, tgt_argv[0],
881 		    O_RDONLY, 0)) == NULL)
882 			die("failed to open %s", tgt_argv[0]);
883 
884 		if (tgt_argc == 1) {
885 			if (mdb_kvm_is_compressed_dump(io)) {
886 				/*
887 				 * We have a single vmdump.N compressed dump
888 				 * file; give a helpful message.
889 				 */
890 				mdb_iob_printf(mdb.m_err,
891 				    "cannot open compressed dump; "
892 				    "decompress using savecore -f %s\n",
893 				    tgt_argv[0]);
894 				terminate(0);
895 			} else if (mdb_kvm_is_dump(io)) {
896 				/*
897 				 * We have an uncompressed dump as our only
898 				 * argument; specify the dump as the symbol
899 				 * table to force libkvm to dig it out of the
900 				 * dump.
901 				 */
902 				tgt_argv[tgt_argc++] = tgt_argv[0];
903 			}
904 		}
905 
906 		/*
907 		 * If the target is unknown or is not the rawfile target, do
908 		 * a gelf_check to determine if the file is an ELF file.  If
909 		 * it is not and the target is unknown, use the rawfile tgt.
910 		 * Otherwise an ELF-based target is needed, so we must abort.
911 		 */
912 		if (mdb_gelf_check(io, &ehdr, ET_NONE) == -1) {
913 			if (tgt_ctor != NULL) {
914 				(void) mdb_gelf_check(io, &ehdr, ET_EXEC);
915 				mdb_io_destroy(io);
916 				terminate(1);
917 			} else
918 				tgt_ctor = mdb_rawfile_tgt_create;
919 		}
920 
921 		mdb_io_destroy(io);
922 
923 		if (identify_xvm_file(tgt_argv[0], &longmode) == 1) {
924 #ifdef _LP64
925 			if (!longmode)
926 				goto reexec;
927 #else
928 			if (longmode)
929 				goto reexec;
930 #endif
931 			tgt_ctor = mdb_kvm_tgt_create;
932 			goto tcreate;
933 		}
934 
935 		/*
936 		 * The object file turned out to be a user core file (ET_CORE),
937 		 * and no other arguments were specified, swap 0 and 1.  The
938 		 * proc target will infer the executable for us.
939 		 */
940 		if (ehdr.e_type == ET_CORE) {
941 			tgt_argv[tgt_argc++] = tgt_argv[0];
942 			tgt_argv[0] = NULL;
943 			tgt_ctor = mdb_proc_tgt_create;
944 		}
945 
946 		/*
947 		 * If tgt_argv[1] is filled in, open it up and determine if it
948 		 * is a vmcore file.  If it is, gelf_check will fail and we
949 		 * set tgt_ctor to 'kvm'; otherwise we use the default.
950 		 */
951 		if (tgt_argc > 1 && strcmp(tgt_argv[1], "-") != 0 &&
952 		    tgt_argv[0] != NULL && pidarg == NULL) {
953 			Elf32_Ehdr chdr;
954 
955 			if (access(tgt_argv[1], F_OK) == -1)
956 				die("failed to access %s", tgt_argv[1]);
957 
958 			/* *.N case: drop vmdump.N from the list */
959 			if (tgt_argc == 3) {
960 				if ((io = mdb_fdio_create_path(NULL,
961 				    tgt_argv[2], O_RDONLY, 0)) == NULL)
962 					die("failed to open %s", tgt_argv[2]);
963 				if (mdb_kvm_is_compressed_dump(io))
964 					tgt_argv[--tgt_argc] = NULL;
965 				mdb_io_destroy(io);
966 			}
967 
968 			if ((io = mdb_fdio_create_path(NULL, tgt_argv[1],
969 			    O_RDONLY, 0)) == NULL)
970 				die("failed to open %s", tgt_argv[1]);
971 
972 			if (mdb_gelf_check(io, &chdr, ET_NONE) == -1)
973 				tgt_ctor = mdb_kvm_tgt_create;
974 
975 			mdb_io_destroy(io);
976 		}
977 
978 		/*
979 		 * At this point, we've read the ELF header for either an
980 		 * object file or core into ehdr.  If the class does not match
981 		 * ours, attempt to exec the mdb of the appropriate class.
982 		 */
983 #ifdef _LP64
984 		if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
985 			goto reexec;
986 #else
987 		if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
988 			goto reexec;
989 #endif
990 	}
991 
992 tcreate:
993 	if (tgt_ctor == NULL)
994 		tgt_ctor = mdb_proc_tgt_create;
995 
996 	tgt = mdb_tgt_create(tgt_ctor, mdb.m_tgtflags, tgt_argc, tgt_argv);
997 
998 	if (tgt == NULL) {
999 		if (errno == EINVAL)
1000 			usage(2); /* target can return EINVAL to get usage */
1001 		if (errno == EMDB_TGT)
1002 			terminate(1); /* target already printed error msg */
1003 		die("failed to initialize target");
1004 	}
1005 
1006 	mdb_tgt_activate(tgt);
1007 
1008 	mdb_create_loadable_disasms();
1009 
1010 	if (Vflag != NULL && mdb_dis_select(Vflag) == -1)
1011 		warn("invalid disassembler mode -- %s\n", Vflag);
1012 
1013 
1014 	if (Rflag && mdb.m_term != NULL)
1015 		warn("Using proto area %s\n", mdb.m_root);
1016 
1017 	/*
1018 	 * If the target was successfully constructed and -O was specified,
1019 	 * we now attempt to enter piggy-mode for debugging jurassic problems.
1020 	 */
1021 	if (Oflag) {
1022 		pcinfo_t pci;
1023 
1024 		(void) strcpy(pci.pc_clname, "RT");
1025 
1026 		if (priocntl(P_LWPID, P_MYID, PC_GETCID, (caddr_t)&pci) != -1) {
1027 			pcparms_t pcp;
1028 			rtparms_t *rtp = (rtparms_t *)pcp.pc_clparms;
1029 
1030 			rtp->rt_pri = 35;
1031 			rtp->rt_tqsecs = 0;
1032 			rtp->rt_tqnsecs = RT_TQDEF;
1033 
1034 			pcp.pc_cid = pci.pc_cid;
1035 
1036 			if (priocntl(P_LWPID, P_MYID, PC_SETPARMS,
1037 			    (caddr_t)&pcp) == -1) {
1038 				warn("failed to set RT parameters");
1039 				Oflag = 0;
1040 			}
1041 		} else {
1042 			warn("failed to get RT class id");
1043 			Oflag = 0;
1044 		}
1045 
1046 		if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
1047 			warn("failed to lock address space");
1048 			Oflag = 0;
1049 		}
1050 
1051 		if (Oflag)
1052 			mdb_printf("%s: oink, oink!\n", mdb.m_pname);
1053 	}
1054 
1055 	/*
1056 	 * Path evaluation part 2: Re-evaluate the path now that the target
1057 	 * is ready (and thus we have access to the real platform string).
1058 	 * Do this before reading ~/.mdbrc to allow path modifications prior
1059 	 * to performing module auto-loading.
1060 	 */
1061 	mdb_set_ipath(mdb.m_ipathstr);
1062 	mdb_set_lpath(mdb.m_lpathstr);
1063 
1064 	if (!Sflag && (p = getenv("HOME")) != NULL) {
1065 		char rcpath[MAXPATHLEN];
1066 		mdb_io_t *rc_io;
1067 		int fd;
1068 
1069 		(void) mdb_iob_snprintf(rcpath, MAXPATHLEN, "%s/.mdbrc", p);
1070 		fd = open64(rcpath, O_RDONLY);
1071 
1072 		if (fd >= 0 && (rc_io = mdb_fdio_create_named(fd, rcpath))) {
1073 			mdb_iob_t *iob = mdb_iob_create(rc_io, MDB_IOB_RDONLY);
1074 			mdb_iob_t *old = mdb.m_in;
1075 
1076 			mdb.m_in = iob;
1077 			(void) mdb_run();
1078 			mdb.m_in = old;
1079 		}
1080 	}
1081 
1082 	if (!(mdb.m_flags & MDB_FL_NOMODS))
1083 		mdb_module_load_all(0);
1084 
1085 	(void) mdb_signal_sethandler(SIGINT, int_handler, NULL);
1086 	while ((status = mdb_run()) == MDB_ERR_ABORT ||
1087 	    status == MDB_ERR_OUTPUT) {
1088 		/*
1089 		 * If a write failed on stdout, give up.  A more informative
1090 		 * error message will already have been printed by mdb_run().
1091 		 */
1092 		if (status == MDB_ERR_OUTPUT &&
1093 		    mdb_iob_getflags(mdb.m_out) & MDB_IOB_ERR) {
1094 			mdb_warn("write to stdout failed, exiting\n");
1095 			break;
1096 		}
1097 		continue;
1098 	}
1099 
1100 	terminate((status == MDB_ERR_QUIT || status == 0) ?
1101 	    (eflag != NULL && mdb.m_lastret != 0 ? 1 : 0) : 1);
1102 	/*NOTREACHED*/
1103 
1104 reexec:
1105 	if ((p = strrchr(execname, '/')) == NULL)
1106 		die("cannot determine absolute pathname\n");
1107 #ifdef _LP64
1108 #ifdef __sparc
1109 	(void) strcpy(p, "/../sparcv7/");
1110 #else
1111 	(void) strcpy(p, "/../i86/");
1112 #endif
1113 #else
1114 #ifdef __sparc
1115 	(void) strcpy(p, "/../sparcv9/");
1116 #else
1117 	(void) strcpy(p, "/../amd64/");
1118 #endif
1119 #endif
1120 	(void) strcat(p, mdb.m_pname);
1121 
1122 	if (mdb.m_term != NULL)
1123 		(void) IOP_CTL(in_io, TCSETSW, &tios);
1124 
1125 	(void) putenv("_MDB_EXEC=1");
1126 	(void) execv(execname, argv);
1127 
1128 	/*
1129 	 * If execv fails, suppress ENOEXEC.  Experience shows the most common
1130 	 * reason is that the machine is booted under a 32-bit kernel, in which
1131 	 * case it is clearer to only print the message below.
1132 	 */
1133 	if (errno != ENOEXEC)
1134 		warn("failed to exec %s", execname);
1135 #ifdef _LP64
1136 	die("64-bit %s cannot debug 32-bit program %s\n",
1137 	    mdb.m_pname, tgt_argv[0] ?
1138 	    tgt_argv[0] : tgt_argv[1]);
1139 #else
1140 	die("32-bit %s cannot debug 64-bit program %s\n",
1141 	    mdb.m_pname, tgt_argv[0] ?
1142 	    tgt_argv[0] : tgt_argv[1]);
1143 #endif
1144 
1145 	goto tcreate;
1146 }
1147