xref: /titanic_44/usr/src/cmd/mdb/common/kmdb/kmdb_main.c (revision 28167c24ba5be8b7c1d05e02d053f4a55cd21cc9)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/types.h>
30 #include <sys/mman.h>
31 #include <sys/resource.h>
32 #include <sys/termios.h>
33 #include <sys/param.h>
34 #include <sys/salib.h>
35 
36 #include <alloca.h>
37 #include <unistd.h>
38 #include <string.h>
39 #include <stdlib.h>
40 #include <fcntl.h>
41 #include <libctf.h>
42 #include <errno.h>
43 #include <ctype.h>
44 
45 #include <kmdb/kmdb_promif.h>
46 #include <kmdb/kmdb_dpi.h>
47 #include <kmdb/kmdb_umemglue.h>
48 #include <kmdb/kmdb_io.h>
49 #include <kmdb/kmdb_dpi.h>
50 #include <kmdb/kmdb_wr.h>
51 #include <kmdb/kmdb_start.h>
52 #include <kmdb/kmdb_kdi.h>
53 #include <kmdb/kmdb_kvm.h>
54 #include <mdb/mdb_lex.h>
55 #include <mdb/mdb_debug.h>
56 #include <mdb/mdb_signal.h>
57 #include <mdb/mdb_string.h>
58 #include <mdb/mdb_modapi.h>
59 #include <mdb/mdb_target.h>
60 #include <mdb/mdb_gelf.h>
61 #include <mdb/mdb_conf.h>
62 #include <mdb/mdb_err.h>
63 #include <mdb/mdb_io_impl.h>
64 #include <mdb/mdb_frame.h>
65 #include <mdb/mdb_set.h>
66 #include <mdb/mdb.h>
67 
68 #ifdef __sparc
69 #define	KMDB_STACK_SIZE	(384 * 1024)
70 #else
71 #define	KMDB_STACK_SIZE (192 * 1024)
72 #endif
73 
74 caddr_t kmdb_main_stack;
75 size_t kmdb_main_stack_size;
76 
77 #define	KMDB_DEF_IPATH	"internal"
78 #if defined(_LP64)
79 #define	KMDB_DEF_LPATH	\
80 	"%r/platform/%p/kernel/kmdb/%i:" \
81 	"%r/platform/%m/kernel/kmdb/%i:" \
82 	"%r/kernel/kmdb/%i"
83 #else
84 #define	KMDB_DEF_LPATH	\
85 	"%r/platform/%m/kernel/kmdb:" \
86 	"%r/kernel/kmdb"
87 #endif
88 
89 #define	MDB_DEF_PROMPT "[%<_cpuid>]> "
90 
91 #define	KMDB_DEF_TERM_TYPE	"vt100"
92 
93 /*
94  * Similar to the panic_* variables in the kernel, we keep some relevant
95  * information stored in a set of global _mdb_abort_* variables; in the
96  * event that the debugger dumps core, these will aid core dump analysis.
97  */
98 const char *volatile _mdb_abort_str;	/* reason for failure */
99 
100 /*
101  * The kernel supplies a space-delimited list of directories
102  * (/platform/sun4u/kernel /kernel /usr/kernel ...) which we must transform into
103  * a debugger-friendly, colon-delimited module search path.  We add the kmdb
104  * module directory to each component and change the delimiter.
105  */
106 static char *
107 kmdb_modpath2lpath(const char *modpath)
108 {
109 #ifdef	_LP64
110 	static const char suffix[] = "/kmdb/%i:";
111 #else
112 	static const char suffix[] = "/kmdb:";
113 #endif
114 	const char *c;
115 	char *lpath, *lpend, *nlpath;
116 	size_t lpsz, lpres;
117 
118 	if (strchr(modpath, ':') != NULL) {
119 		warn("invalid kernel module path\n");
120 		return (NULL);
121 	}
122 
123 	lpres = lpsz = strlen(modpath) + MAXPATHLEN;
124 	lpend = lpath = mdb_zalloc(lpsz, UM_SLEEP);
125 
126 	while (isspace(*modpath))
127 		modpath++;
128 
129 	for (; *modpath != '\0'; modpath = c) {
130 		size_t sz;
131 
132 		for (c = modpath; !isspace(*c) && *c != '\0'; c++)
133 			continue;
134 
135 		sz = (c - modpath) + sizeof (suffix) - 1;
136 		if (sz >= lpres)
137 			continue;
138 
139 		(void) strncpy(lpend, modpath, c - modpath);
140 		(void) strcpy(lpend + (c - modpath), suffix);
141 
142 		lpend += sz;
143 		lpres -= sz;
144 
145 		while (isspace(*c))
146 			c++;
147 	}
148 
149 	if (lpend != lpath)
150 		lpend[-1] = '\0';	/* eat trailing colon */
151 
152 	nlpath = strdup(lpath);
153 	mdb_free(lpath, lpsz);
154 	return (nlpath);
155 }
156 
157 /*
158  * called while the kernel is running
159  */
160 int
161 kmdb_init(const char *execname, kmdb_auxv_t *kav)
162 {
163 	mdb_io_t *in_io, *out_io, *err_io, *null_io;
164 	mdb_tgt_ctor_f *tgt_ctor = kmdb_kvm_create;
165 	mdb_tgt_t *tgt;
166 	int i;
167 
168 	/*
169 	 * The beginnings of debugger initialization are a bit of a dance, due
170 	 * to interlocking dependencies between kmdb_prom_init,
171 	 * mdb_umem_startup, and mdb_create.  In particular, allocator
172 	 * initialization can't begin until prom_init() is called,
173 	 * kmdb_prom_init can't finish until the allocator is ready and
174 	 * mdb_create has been called.  We therefore split kmdb_prom_init into
175 	 * two pieces, and call thembefore and after umem initialization and
176 	 * mdb_create.
177 	 */
178 	kmdb_prom_init_begin("kmdb", kav);
179 	mdb_umem_startup(kav->kav_dseg, kav->kav_dseg_size,
180 	    kav->kav_pagesize);
181 	mdb_create(execname, "kmdb");
182 	kmdb_prom_init_finish(kav);
183 
184 	mdb.m_dseg = kav->kav_dseg;
185 	mdb.m_dsegsz = kav->kav_dseg_size;
186 
187 	out_io = kmdb_promio_create("stdout");
188 	mdb.m_out = mdb_iob_create(out_io, MDB_IOB_WRONLY);
189 
190 	err_io = kmdb_promio_create("stderr");
191 	mdb.m_err = mdb_iob_create(err_io, MDB_IOB_WRONLY);
192 	mdb_iob_clrflags(mdb.m_err, MDB_IOB_AUTOWRAP);
193 
194 	null_io = mdb_nullio_create();
195 	mdb.m_null = mdb_iob_create(null_io, MDB_IOB_WRONLY);
196 
197 	in_io = kmdb_promio_create("stdin");
198 	mdb.m_term = NULL;
199 
200 	if (kav->kav_config != NULL)
201 		mdb_set_config(kav->kav_config);
202 
203 	if (kav->kav_argv != NULL) {
204 		for (i = 0; kav->kav_argv[i] != NULL; i++) {
205 			if (!mdb_set_options(kav->kav_argv[i], TRUE))
206 				return (-1);
207 		}
208 	}
209 
210 	if (kav->kav_flags & KMDB_AUXV_FL_NOUNLOAD)
211 		mdb.m_flags |= MDB_FL_NOUNLOAD;
212 
213 	mdb.m_in = mdb_iob_create(in_io, MDB_IOB_RDONLY);
214 	mdb_iob_setflags(mdb.m_in, MDB_IOB_TTYLIKE);
215 
216 	mdb_lex_reset();
217 
218 	kmdb_kdi_init(kav->kav_kdi, kav);
219 
220 	if (kmdb_dpi_init(kav) < 0) {
221 		warn("Couldn't initialize kernel/PROM interface\n");
222 		return (-1);
223 	}
224 
225 	/*
226 	 * Path evaluation part 1: Create the initial module path to allow
227 	 * the target constructor to load a support module.  We base kmdb's
228 	 * module path off the kernel's module path unless the user has
229 	 * explicitly supplied one.
230 	 */
231 	mdb_set_ipath(KMDB_DEF_IPATH);
232 	if (strlen(mdb.m_lpathstr) > 0) {
233 		mdb_set_lpath(mdb.m_lpathstr);
234 	} else {
235 		char *lpath;
236 
237 		if (kav->kav_modpath != NULL && *kav->kav_modpath != '\0' &&
238 		    (lpath = kmdb_modpath2lpath(kav->kav_modpath)) != NULL) {
239 			mdb_set_lpath(lpath);
240 			strfree(lpath);
241 		} else {
242 			mdb_set_lpath(KMDB_DEF_LPATH);
243 		}
244 	}
245 
246 	if (mdb_get_prompt() == NULL)
247 		(void) mdb_set_prompt(MDB_DEF_PROMPT);
248 
249 	tgt = mdb_tgt_create(tgt_ctor, mdb.m_tgtflags, 0, NULL);
250 
251 	if (tgt == NULL) {
252 		warn("failed to initialize target");
253 		return (-1);
254 	}
255 
256 	mdb_tgt_activate(tgt);
257 
258 	mdb_create_loadable_disasms();
259 
260 	/*
261 	 * Path evaluation part 2: Re-evaluate the path now that the target
262 	 * is ready (and thus we have access to the real platform string).
263 	 */
264 	mdb_set_ipath(mdb.m_ipathstr);
265 	mdb_set_lpath(mdb.m_lpathstr);
266 
267 	if (!(mdb.m_flags & MDB_FL_NOMODS))
268 		mdb_module_load_all(MDB_MOD_DEFER);
269 
270 	/* Allocate the main debugger stack */
271 	kmdb_main_stack = mdb_alloc(KMDB_STACK_SIZE, UM_SLEEP);
272 	kmdb_main_stack_size = KMDB_STACK_SIZE;
273 
274 	kmdb_kdi_end_init();
275 
276 	return (0);
277 }
278 
279 /*
280  * First-time kmdb startup.  Run when kmdb has control of the machine for the
281  * first time.
282  */
283 static void
284 kmdb_startup(void)
285 {
286 	mdb_io_t *inio, *outio;
287 
288 	if (mdb.m_termtype == NULL) {
289 		/*
290 		 * The terminal type wasn't specified, so we guess.  If we're
291 		 * on console, we'll get a terminal type from the PROM.  If not,
292 		 * we'll use the default.
293 		 */
294 		const char *ttype;
295 
296 		if ((ttype = kmdb_prom_term_type()) == NULL) {
297 			ttype = KMDB_DEF_TERM_TYPE;
298 			warn("unable to determine terminal type: "
299 			    "assuming `%s'\n", ttype);
300 		}
301 
302 		mdb.m_flags |= MDB_FL_TERMGUESS;
303 		mdb.m_termtype = strdup(ttype);
304 
305 	} else if (mdb.m_flags & MDB_FL_TERMGUESS) {
306 		/*
307 		 * The terminal type wasn't specified by the user, but a guess
308 		 * was made using either $TERM or a property from the SMF.  A
309 		 * terminal type from the PROM code overrides the guess, so
310 		 * we'll use that if we can.
311 		 */
312 		char *promttype;
313 
314 		if ((promttype = kmdb_prom_term_type()) != NULL) {
315 			strfree(mdb.m_termtype);
316 			mdb.m_termtype = strdup(promttype);
317 		}
318 	}
319 
320 	inio = kmdb_promio_create("stdin");
321 	outio = kmdb_promio_create("stdout");
322 
323 	if ((mdb.m_term = mdb_termio_create(mdb.m_termtype, inio, outio)) ==
324 	    NULL && strcmp(mdb.m_termtype, KMDB_DEF_TERM_TYPE) != 0) {
325 		warn("failed to set terminal type to `%s', using `"
326 		    KMDB_DEF_TERM_TYPE "'\n", mdb.m_termtype);
327 
328 		strfree(mdb.m_termtype);
329 		mdb.m_termtype = strdup(KMDB_DEF_TERM_TYPE);
330 
331 		if ((mdb.m_term = mdb_termio_create(mdb.m_termtype, inio,
332 		    outio)) == NULL) {
333 			fail("failed to set terminal type to `"
334 			    KMDB_DEF_TERM_TYPE "'\n");
335 		}
336 	}
337 
338 	mdb_iob_destroy(mdb.m_in);
339 	mdb.m_in = mdb_iob_create(mdb.m_term, MDB_IOB_RDONLY);
340 	mdb_iob_setpager(mdb.m_out, mdb.m_term);
341 	mdb_iob_setflags(mdb.m_out, MDB_IOB_PGENABLE);
342 
343 	kmdb_kvm_startup();
344 
345 	/*
346 	 * kmdb_init() and kctl_activate() may have been talking to each other,
347 	 * and may have left some messages for us.  The driver -> debugger
348 	 * queue is normally processed during the resume path, so we have to
349 	 * do it manually here if we want it to be run for first startup.
350 	 */
351 	kmdb_dpi_process_work_queue();
352 
353 	kmdb_kvm_poststartup();
354 }
355 
356 void
357 kmdb_main(void)
358 {
359 	int status;
360 
361 	kmdb_dpi_set_state(DPI_STATE_STOPPED, 0);
362 	mdb_printf("\nWelcome to kmdb\n");
363 	kmdb_startup();
364 
365 	/*
366 	 * Debugger termination is a bit tricky.  For compatibility with kadb,
367 	 * neither an EOF on stdin nor a normal ::quit will cause the debugger
368 	 * to unload.  In both cases, they get a trip to OBP, after which the
369 	 * debugger returns.
370 	 *
371 	 * The only supported way to cause the debugger to unload is to specify
372 	 * the unload flag to ::quit, or to have the driver request it.  The
373 	 * driver request is the primary exit mechanism - the ::quit flag is
374 	 * provided for convenience.
375 	 *
376 	 * Both forms of "exit" (unqualified ::quit that won't cause an unload,
377 	 * and a driver request that will) are signalled by an MDB_ERR_QUIT.  In
378 	 * the latter case, however, the KDI will have the unload request.
379 	 */
380 	for (;;) {
381 		status = mdb_run();
382 
383 		if (status == MDB_ERR_QUIT && kmdb_kdi_get_unload_request()) {
384 			break;
385 
386 		} else if (status == MDB_ERR_QUIT || status == 0) {
387 			kmdb_dpi_enter_mon();
388 
389 		} else if (status == MDB_ERR_OUTPUT) {
390 			/*
391 			 * If a write failed on stdout, give up.  A more
392 			 * informative error message will already have been
393 			 * printed by mdb_run().
394 			 */
395 			if (mdb_iob_getflags(mdb.m_out) & MDB_IOB_ERR)
396 				fail("write to stdout failed, exiting\n");
397 
398 		} else if (status != MDB_ERR_ABORT) {
399 			fail("debugger exited abnormally (status = %s)\n",
400 			    mdb_err2str(status));
401 		}
402 	}
403 
404 	mdb_destroy();
405 
406 	kmdb_dpi_resume_unload();
407 
408 	/*NOTREACHED*/
409 }
410