17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*1ae08745Sheppo * Common Development and Distribution License (the "License"). 6*1ae08745Sheppo * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 225ae68c69Sjohnlev * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <sys/types.h> 297c478bd9Sstevel@tonic-gate #include <sys/mman.h> 307c478bd9Sstevel@tonic-gate #include <sys/resource.h> 317c478bd9Sstevel@tonic-gate #include <sys/termios.h> 327c478bd9Sstevel@tonic-gate #include <sys/param.h> 337c478bd9Sstevel@tonic-gate #include <sys/salib.h> 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <alloca.h> 367c478bd9Sstevel@tonic-gate #include <unistd.h> 377c478bd9Sstevel@tonic-gate #include <string.h> 387c478bd9Sstevel@tonic-gate #include <stdlib.h> 397c478bd9Sstevel@tonic-gate #include <fcntl.h> 407c478bd9Sstevel@tonic-gate #include <libctf.h> 417c478bd9Sstevel@tonic-gate #include <errno.h> 427c478bd9Sstevel@tonic-gate #include <ctype.h> 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_promif.h> 457c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_dpi.h> 467c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_umemglue.h> 477c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_io.h> 487c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_dpi.h> 497c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_wr.h> 507c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_start.h> 517c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_kdi.h> 527c478bd9Sstevel@tonic-gate #include <kmdb/kmdb_kvm.h> 537c478bd9Sstevel@tonic-gate #include <mdb/mdb_lex.h> 547c478bd9Sstevel@tonic-gate #include <mdb/mdb_debug.h> 557c478bd9Sstevel@tonic-gate #include <mdb/mdb_signal.h> 567c478bd9Sstevel@tonic-gate #include <mdb/mdb_string.h> 577c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h> 587c478bd9Sstevel@tonic-gate #include <mdb/mdb_target.h> 597c478bd9Sstevel@tonic-gate #include <mdb/mdb_gelf.h> 607c478bd9Sstevel@tonic-gate #include <mdb/mdb_conf.h> 617c478bd9Sstevel@tonic-gate #include <mdb/mdb_err.h> 627c478bd9Sstevel@tonic-gate #include <mdb/mdb_io_impl.h> 637c478bd9Sstevel@tonic-gate #include <mdb/mdb_frame.h> 647c478bd9Sstevel@tonic-gate #include <mdb/mdb_set.h> 657c478bd9Sstevel@tonic-gate #include <mdb/mdb.h> 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate #ifdef __sparc 687c478bd9Sstevel@tonic-gate #define KMDB_STACK_SIZE (384 * 1024) 697c478bd9Sstevel@tonic-gate #else 707c478bd9Sstevel@tonic-gate #define KMDB_STACK_SIZE (192 * 1024) 717c478bd9Sstevel@tonic-gate #endif 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate caddr_t kmdb_main_stack; 747c478bd9Sstevel@tonic-gate size_t kmdb_main_stack_size; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate #define KMDB_DEF_IPATH "internal" 777c478bd9Sstevel@tonic-gate #if defined(_LP64) 787c478bd9Sstevel@tonic-gate #define KMDB_DEF_LPATH \ 797c478bd9Sstevel@tonic-gate "%r/platform/%p/kernel/kmdb/%i:" \ 807c478bd9Sstevel@tonic-gate "%r/platform/%m/kernel/kmdb/%i:" \ 817c478bd9Sstevel@tonic-gate "%r/kernel/kmdb/%i" 827c478bd9Sstevel@tonic-gate #else 837c478bd9Sstevel@tonic-gate #define KMDB_DEF_LPATH \ 847c478bd9Sstevel@tonic-gate "%r/platform/%m/kernel/kmdb:" \ 857c478bd9Sstevel@tonic-gate "%r/kernel/kmdb" 867c478bd9Sstevel@tonic-gate #endif 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate #define MDB_DEF_PROMPT "[%<_cpuid>]> " 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate #define KMDB_DEF_TERM_TYPE "vt100" 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate /* 937c478bd9Sstevel@tonic-gate * Similar to the panic_* variables in the kernel, we keep some relevant 947c478bd9Sstevel@tonic-gate * information stored in a set of global _mdb_abort_* variables; in the 957c478bd9Sstevel@tonic-gate * event that the debugger dumps core, these will aid core dump analysis. 967c478bd9Sstevel@tonic-gate */ 977c478bd9Sstevel@tonic-gate const char *volatile _mdb_abort_str; /* reason for failure */ 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate /* 1007c478bd9Sstevel@tonic-gate * The kernel supplies a space-delimited list of directories 1017c478bd9Sstevel@tonic-gate * (/platform/sun4u/kernel /kernel /usr/kernel ...) which we must transform into 1027c478bd9Sstevel@tonic-gate * a debugger-friendly, colon-delimited module search path. We add the kmdb 1037c478bd9Sstevel@tonic-gate * module directory to each component and change the delimiter. 1047c478bd9Sstevel@tonic-gate */ 1057c478bd9Sstevel@tonic-gate static char * 1067c478bd9Sstevel@tonic-gate kmdb_modpath2lpath(const char *modpath) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate #ifdef _LP64 1097c478bd9Sstevel@tonic-gate static const char suffix[] = "/kmdb/%i:"; 1107c478bd9Sstevel@tonic-gate #else 1117c478bd9Sstevel@tonic-gate static const char suffix[] = "/kmdb:"; 1127c478bd9Sstevel@tonic-gate #endif 1137c478bd9Sstevel@tonic-gate const char *c; 1147c478bd9Sstevel@tonic-gate char *lpath, *lpend, *nlpath; 1157c478bd9Sstevel@tonic-gate size_t lpsz, lpres; 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate if (strchr(modpath, ':') != NULL) { 1187c478bd9Sstevel@tonic-gate warn("invalid kernel module path\n"); 1197c478bd9Sstevel@tonic-gate return (NULL); 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate lpres = lpsz = strlen(modpath) + MAXPATHLEN; 1237c478bd9Sstevel@tonic-gate lpend = lpath = mdb_zalloc(lpsz, UM_SLEEP); 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate while (isspace(*modpath)) 1267c478bd9Sstevel@tonic-gate modpath++; 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate for (; *modpath != '\0'; modpath = c) { 1297c478bd9Sstevel@tonic-gate size_t sz; 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate for (c = modpath; !isspace(*c) && *c != '\0'; c++) 1327c478bd9Sstevel@tonic-gate continue; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate sz = (c - modpath) + sizeof (suffix) - 1; 1357c478bd9Sstevel@tonic-gate if (sz >= lpres) 1367c478bd9Sstevel@tonic-gate continue; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate (void) strncpy(lpend, modpath, c - modpath); 1397c478bd9Sstevel@tonic-gate (void) strcpy(lpend + (c - modpath), suffix); 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate lpend += sz; 1427c478bd9Sstevel@tonic-gate lpres -= sz; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate while (isspace(*c)) 1457c478bd9Sstevel@tonic-gate c++; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate if (lpend != lpath) 1497c478bd9Sstevel@tonic-gate lpend[-1] = '\0'; /* eat trailing colon */ 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate nlpath = strdup(lpath); 1527c478bd9Sstevel@tonic-gate mdb_free(lpath, lpsz); 1537c478bd9Sstevel@tonic-gate return (nlpath); 1547c478bd9Sstevel@tonic-gate } 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate /* 1577c478bd9Sstevel@tonic-gate * called while the kernel is running 1587c478bd9Sstevel@tonic-gate */ 1597c478bd9Sstevel@tonic-gate int 1607c478bd9Sstevel@tonic-gate kmdb_init(const char *execname, kmdb_auxv_t *kav) 1617c478bd9Sstevel@tonic-gate { 1627c478bd9Sstevel@tonic-gate mdb_io_t *in_io, *out_io, *err_io, *null_io; 1637c478bd9Sstevel@tonic-gate mdb_tgt_ctor_f *tgt_ctor = kmdb_kvm_create; 1647c478bd9Sstevel@tonic-gate mdb_tgt_t *tgt; 1657c478bd9Sstevel@tonic-gate int i; 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* 1687c478bd9Sstevel@tonic-gate * The beginnings of debugger initialization are a bit of a dance, due 1697c478bd9Sstevel@tonic-gate * to interlocking dependencies between kmdb_prom_init, 1707c478bd9Sstevel@tonic-gate * mdb_umem_startup, and mdb_create. In particular, allocator 1717c478bd9Sstevel@tonic-gate * initialization can't begin until prom_init() is called, 1727c478bd9Sstevel@tonic-gate * kmdb_prom_init can't finish until the allocator is ready and 1737c478bd9Sstevel@tonic-gate * mdb_create has been called. We therefore split kmdb_prom_init into 1747c478bd9Sstevel@tonic-gate * two pieces, and call thembefore and after umem initialization and 1757c478bd9Sstevel@tonic-gate * mdb_create. 1767c478bd9Sstevel@tonic-gate */ 1777c478bd9Sstevel@tonic-gate kmdb_prom_init_begin("kmdb", kav); 1787c478bd9Sstevel@tonic-gate mdb_umem_startup(kav->kav_dseg, kav->kav_dseg_size, 1797c478bd9Sstevel@tonic-gate kav->kav_pagesize); 1807c478bd9Sstevel@tonic-gate mdb_create(execname, "kmdb"); 1817c478bd9Sstevel@tonic-gate kmdb_prom_init_finish(kav); 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate mdb.m_dseg = kav->kav_dseg; 1847c478bd9Sstevel@tonic-gate mdb.m_dsegsz = kav->kav_dseg_size; 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate out_io = kmdb_promio_create("stdout"); 1877c478bd9Sstevel@tonic-gate mdb.m_out = mdb_iob_create(out_io, MDB_IOB_WRONLY); 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate err_io = kmdb_promio_create("stderr"); 1907c478bd9Sstevel@tonic-gate mdb.m_err = mdb_iob_create(err_io, MDB_IOB_WRONLY); 1917c478bd9Sstevel@tonic-gate mdb_iob_clrflags(mdb.m_err, MDB_IOB_AUTOWRAP); 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate null_io = mdb_nullio_create(); 1947c478bd9Sstevel@tonic-gate mdb.m_null = mdb_iob_create(null_io, MDB_IOB_WRONLY); 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate in_io = kmdb_promio_create("stdin"); 1977c478bd9Sstevel@tonic-gate mdb.m_term = NULL; 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate if (kav->kav_config != NULL) 2007c478bd9Sstevel@tonic-gate mdb_set_config(kav->kav_config); 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate if (kav->kav_argv != NULL) { 2037c478bd9Sstevel@tonic-gate for (i = 0; kav->kav_argv[i] != NULL; i++) { 2047c478bd9Sstevel@tonic-gate if (!mdb_set_options(kav->kav_argv[i], TRUE)) 2057c478bd9Sstevel@tonic-gate return (-1); 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate if (kav->kav_flags & KMDB_AUXV_FL_NOUNLOAD) 2107c478bd9Sstevel@tonic-gate mdb.m_flags |= MDB_FL_NOUNLOAD; 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate mdb.m_in = mdb_iob_create(in_io, MDB_IOB_RDONLY); 2137c478bd9Sstevel@tonic-gate mdb_iob_setflags(mdb.m_in, MDB_IOB_TTYLIKE); 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate mdb_lex_reset(); 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate kmdb_kdi_init(kav->kav_kdi, kav); 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate if (kmdb_dpi_init(kav) < 0) { 2207c478bd9Sstevel@tonic-gate warn("Couldn't initialize kernel/PROM interface\n"); 2217c478bd9Sstevel@tonic-gate return (-1); 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate /* 2257c478bd9Sstevel@tonic-gate * Path evaluation part 1: Create the initial module path to allow 2267c478bd9Sstevel@tonic-gate * the target constructor to load a support module. We base kmdb's 2277c478bd9Sstevel@tonic-gate * module path off the kernel's module path unless the user has 2287c478bd9Sstevel@tonic-gate * explicitly supplied one. 2297c478bd9Sstevel@tonic-gate */ 2307c478bd9Sstevel@tonic-gate mdb_set_ipath(KMDB_DEF_IPATH); 2317c478bd9Sstevel@tonic-gate if (strlen(mdb.m_lpathstr) > 0) { 2327c478bd9Sstevel@tonic-gate mdb_set_lpath(mdb.m_lpathstr); 2337c478bd9Sstevel@tonic-gate } else { 2347c478bd9Sstevel@tonic-gate char *lpath; 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate if (kav->kav_modpath != NULL && *kav->kav_modpath != '\0' && 2377c478bd9Sstevel@tonic-gate (lpath = kmdb_modpath2lpath(kav->kav_modpath)) != NULL) { 2387c478bd9Sstevel@tonic-gate mdb_set_lpath(lpath); 2397c478bd9Sstevel@tonic-gate strfree(lpath); 2407c478bd9Sstevel@tonic-gate } else { 2417c478bd9Sstevel@tonic-gate mdb_set_lpath(KMDB_DEF_LPATH); 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate if (mdb_get_prompt() == NULL) 2467c478bd9Sstevel@tonic-gate (void) mdb_set_prompt(MDB_DEF_PROMPT); 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate tgt = mdb_tgt_create(tgt_ctor, mdb.m_tgtflags, 0, NULL); 2497c478bd9Sstevel@tonic-gate 2507c478bd9Sstevel@tonic-gate if (tgt == NULL) { 2517c478bd9Sstevel@tonic-gate warn("failed to initialize target"); 2527c478bd9Sstevel@tonic-gate return (-1); 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate mdb_tgt_activate(tgt); 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate mdb_create_loadable_disasms(); 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* 2607c478bd9Sstevel@tonic-gate * Path evaluation part 2: Re-evaluate the path now that the target 2617c478bd9Sstevel@tonic-gate * is ready (and thus we have access to the real platform string). 2627c478bd9Sstevel@tonic-gate */ 2637c478bd9Sstevel@tonic-gate mdb_set_ipath(mdb.m_ipathstr); 2647c478bd9Sstevel@tonic-gate mdb_set_lpath(mdb.m_lpathstr); 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate if (!(mdb.m_flags & MDB_FL_NOMODS)) 2677c478bd9Sstevel@tonic-gate mdb_module_load_all(MDB_MOD_DEFER); 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* Allocate the main debugger stack */ 2707c478bd9Sstevel@tonic-gate kmdb_main_stack = mdb_alloc(KMDB_STACK_SIZE, UM_SLEEP); 2717c478bd9Sstevel@tonic-gate kmdb_main_stack_size = KMDB_STACK_SIZE; 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate kmdb_kdi_end_init(); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate return (0); 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 278*1ae08745Sheppo #ifdef sun4v 279*1ae08745Sheppo 280*1ae08745Sheppo void 281*1ae08745Sheppo kmdb_init_promif(char *pgmname, kmdb_auxv_t *kav) 282*1ae08745Sheppo { 283*1ae08745Sheppo kmdb_prom_init_promif(pgmname, kav); 284*1ae08745Sheppo } 285*1ae08745Sheppo 286*1ae08745Sheppo #else 287*1ae08745Sheppo 288*1ae08745Sheppo /*ARGSUSED*/ 289*1ae08745Sheppo void 290*1ae08745Sheppo kmdb_init_promif(char *pgmname, kmdb_auxv_t *kav) 291*1ae08745Sheppo { 292*1ae08745Sheppo /* 293*1ae08745Sheppo * Fake function for non sun4v. See comments in kmdb_ctl.h 294*1ae08745Sheppo */ 295*1ae08745Sheppo ASSERT(0); 296*1ae08745Sheppo } 297*1ae08745Sheppo 298*1ae08745Sheppo #endif 299*1ae08745Sheppo 3007c478bd9Sstevel@tonic-gate /* 3017c478bd9Sstevel@tonic-gate * First-time kmdb startup. Run when kmdb has control of the machine for the 3027c478bd9Sstevel@tonic-gate * first time. 3037c478bd9Sstevel@tonic-gate */ 3047c478bd9Sstevel@tonic-gate static void 3057c478bd9Sstevel@tonic-gate kmdb_startup(void) 3067c478bd9Sstevel@tonic-gate { 3077c478bd9Sstevel@tonic-gate mdb_io_t *inio, *outio; 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate if (mdb.m_termtype == NULL) { 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * The terminal type wasn't specified, so we guess. If we're 3127c478bd9Sstevel@tonic-gate * on console, we'll get a terminal type from the PROM. If not, 3137c478bd9Sstevel@tonic-gate * we'll use the default. 3147c478bd9Sstevel@tonic-gate */ 3155ae68c69Sjohnlev const char *ttype; 3165ae68c69Sjohnlev 3175ae68c69Sjohnlev if ((ttype = kmdb_prom_term_type()) == NULL) { 3185ae68c69Sjohnlev ttype = KMDB_DEF_TERM_TYPE; 3195ae68c69Sjohnlev warn("unable to determine terminal type: " 3205ae68c69Sjohnlev "assuming `%s'\n", ttype); 3217c478bd9Sstevel@tonic-gate } 3225ae68c69Sjohnlev 3237c478bd9Sstevel@tonic-gate mdb.m_flags |= MDB_FL_TERMGUESS; 3245ae68c69Sjohnlev mdb.m_termtype = strdup(ttype); 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate } else if (mdb.m_flags & MDB_FL_TERMGUESS) { 3277c478bd9Sstevel@tonic-gate /* 3287c478bd9Sstevel@tonic-gate * The terminal type wasn't specified by the user, but a guess 3297c478bd9Sstevel@tonic-gate * was made using either $TERM or a property from the SMF. A 3307c478bd9Sstevel@tonic-gate * terminal type from the PROM code overrides the guess, so 3317c478bd9Sstevel@tonic-gate * we'll use that if we can. 3327c478bd9Sstevel@tonic-gate */ 3337c478bd9Sstevel@tonic-gate char *promttype; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate if ((promttype = kmdb_prom_term_type()) != NULL) { 3367c478bd9Sstevel@tonic-gate strfree(mdb.m_termtype); 3377c478bd9Sstevel@tonic-gate mdb.m_termtype = strdup(promttype); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate inio = kmdb_promio_create("stdin"); 3427c478bd9Sstevel@tonic-gate outio = kmdb_promio_create("stdout"); 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate if ((mdb.m_term = mdb_termio_create(mdb.m_termtype, inio, outio)) == 3457c478bd9Sstevel@tonic-gate NULL && strcmp(mdb.m_termtype, KMDB_DEF_TERM_TYPE) != 0) { 3467c478bd9Sstevel@tonic-gate warn("failed to set terminal type to `%s', using `" 3477c478bd9Sstevel@tonic-gate KMDB_DEF_TERM_TYPE "'\n", mdb.m_termtype); 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate strfree(mdb.m_termtype); 3507c478bd9Sstevel@tonic-gate mdb.m_termtype = strdup(KMDB_DEF_TERM_TYPE); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate if ((mdb.m_term = mdb_termio_create(mdb.m_termtype, inio, 3537c478bd9Sstevel@tonic-gate outio)) == NULL) { 3547c478bd9Sstevel@tonic-gate fail("failed to set terminal type to `" 3557c478bd9Sstevel@tonic-gate KMDB_DEF_TERM_TYPE "'\n"); 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate mdb_iob_destroy(mdb.m_in); 3607c478bd9Sstevel@tonic-gate mdb.m_in = mdb_iob_create(mdb.m_term, MDB_IOB_RDONLY); 3617c478bd9Sstevel@tonic-gate mdb_iob_setpager(mdb.m_out, mdb.m_term); 3627c478bd9Sstevel@tonic-gate mdb_iob_setflags(mdb.m_out, MDB_IOB_PGENABLE); 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate kmdb_kvm_startup(); 3657c478bd9Sstevel@tonic-gate 3667c478bd9Sstevel@tonic-gate /* 3677c478bd9Sstevel@tonic-gate * kmdb_init() and kctl_activate() may have been talking to each other, 3687c478bd9Sstevel@tonic-gate * and may have left some messages for us. The driver -> debugger 3697c478bd9Sstevel@tonic-gate * queue is normally processed during the resume path, so we have to 3707c478bd9Sstevel@tonic-gate * do it manually here if we want it to be run for first startup. 3717c478bd9Sstevel@tonic-gate */ 3727c478bd9Sstevel@tonic-gate kmdb_dpi_process_work_queue(); 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate kmdb_kvm_poststartup(); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate void 3787c478bd9Sstevel@tonic-gate kmdb_main(void) 3797c478bd9Sstevel@tonic-gate { 3807c478bd9Sstevel@tonic-gate int status; 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate kmdb_dpi_set_state(DPI_STATE_STOPPED, 0); 3837c478bd9Sstevel@tonic-gate mdb_printf("\nWelcome to kmdb\n"); 3847c478bd9Sstevel@tonic-gate kmdb_startup(); 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate /* 3877c478bd9Sstevel@tonic-gate * Debugger termination is a bit tricky. For compatibility with kadb, 3887c478bd9Sstevel@tonic-gate * neither an EOF on stdin nor a normal ::quit will cause the debugger 3897c478bd9Sstevel@tonic-gate * to unload. In both cases, they get a trip to OBP, after which the 3907c478bd9Sstevel@tonic-gate * debugger returns. 3917c478bd9Sstevel@tonic-gate * 3927c478bd9Sstevel@tonic-gate * The only supported way to cause the debugger to unload is to specify 3937c478bd9Sstevel@tonic-gate * the unload flag to ::quit, or to have the driver request it. The 3947c478bd9Sstevel@tonic-gate * driver request is the primary exit mechanism - the ::quit flag is 3957c478bd9Sstevel@tonic-gate * provided for convenience. 3967c478bd9Sstevel@tonic-gate * 3977c478bd9Sstevel@tonic-gate * Both forms of "exit" (unqualified ::quit that won't cause an unload, 3987c478bd9Sstevel@tonic-gate * and a driver request that will) are signalled by an MDB_ERR_QUIT. In 3997c478bd9Sstevel@tonic-gate * the latter case, however, the KDI will have the unload request. 4007c478bd9Sstevel@tonic-gate */ 4017c478bd9Sstevel@tonic-gate for (;;) { 4027c478bd9Sstevel@tonic-gate status = mdb_run(); 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate if (status == MDB_ERR_QUIT && kmdb_kdi_get_unload_request()) { 4057c478bd9Sstevel@tonic-gate break; 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate } else if (status == MDB_ERR_QUIT || status == 0) { 4087c478bd9Sstevel@tonic-gate kmdb_dpi_enter_mon(); 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate } else if (status == MDB_ERR_OUTPUT) { 4117c478bd9Sstevel@tonic-gate /* 4127c478bd9Sstevel@tonic-gate * If a write failed on stdout, give up. A more 4137c478bd9Sstevel@tonic-gate * informative error message will already have been 4147c478bd9Sstevel@tonic-gate * printed by mdb_run(). 4157c478bd9Sstevel@tonic-gate */ 4167c478bd9Sstevel@tonic-gate if (mdb_iob_getflags(mdb.m_out) & MDB_IOB_ERR) 4177c478bd9Sstevel@tonic-gate fail("write to stdout failed, exiting\n"); 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate } else if (status != MDB_ERR_ABORT) { 4207c478bd9Sstevel@tonic-gate fail("debugger exited abnormally (status = %s)\n", 4217c478bd9Sstevel@tonic-gate mdb_err2str(status)); 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate } 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate mdb_destroy(); 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate kmdb_dpi_resume_unload(); 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 4307c478bd9Sstevel@tonic-gate } 431