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 511021a81Smb158278 * Common Development and Distribution License (the "License"). 611021a81Smb158278 * 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 /* 2211021a81Smb158278 * Copyright 2007 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/cmn_err.h> 307c478bd9Sstevel@tonic-gate #include <sys/modctl.h> 317c478bd9Sstevel@tonic-gate #include <sys/kobj.h> 327c478bd9Sstevel@tonic-gate #include <sys/kobj_impl.h> 337c478bd9Sstevel@tonic-gate #include <sys/promif.h> 347c478bd9Sstevel@tonic-gate #include <sys/promimpl.h> 357c478bd9Sstevel@tonic-gate #include <sys/reboot.h> 367c478bd9Sstevel@tonic-gate #include <sys/bootconf.h> 377c478bd9Sstevel@tonic-gate #include <sys/systm.h> /* strstr */ 387c478bd9Sstevel@tonic-gate #include <sys/machsystm.h> /* obpdebug */ 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #define FDEBUGFILE "misc/forthdebug" 417c478bd9Sstevel@tonic-gate #define INSTALL_DBP "kdbg-words dbp-install previous" 427c478bd9Sstevel@tonic-gate #define SYMBOL_END "END OF SYMBOL" 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #ifdef DEBUG 457c478bd9Sstevel@tonic-gate static int forthdebug = 1; 467c478bd9Sstevel@tonic-gate #else 477c478bd9Sstevel@tonic-gate static int forthdebug = 0; 487c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate static int forthdebug_dbp = 0; 517c478bd9Sstevel@tonic-gate int forthdebug_supported = 1; 527c478bd9Sstevel@tonic-gate int modreloc_flag = KOBJ_RELOCATED; 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate /* 557c478bd9Sstevel@tonic-gate * basic_sym[] holds all essential symbols the symbol lookup 567c478bd9Sstevel@tonic-gate * service requires. Forthdebug stub names appears in forthdebug 577c478bd9Sstevel@tonic-gate * as place holders. They are replaced with the value of corresponding 587c478bd9Sstevel@tonic-gate * kernel variables. For example, "modules-val-here" in forthdebug 597c478bd9Sstevel@tonic-gate * is replaced with the address of "modules" variable. 607c478bd9Sstevel@tonic-gate * 617c478bd9Sstevel@tonic-gate * To improve performance, we mandate the records be in the same 627c478bd9Sstevel@tonic-gate * sequence they appear in forthdebug, i.e "modules-val-here" is 637c478bd9Sstevel@tonic-gate * ahead of "primaries-v-here" in misc/forthdebug. 647c478bd9Sstevel@tonic-gate * 657c478bd9Sstevel@tonic-gate * The last record must be all 0 to indicate end of the array. 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate static char *basic_sym[] = { 687c478bd9Sstevel@tonic-gate /* kernel variable */ /* forthdebug stub name - must be 16 chars */ 697c478bd9Sstevel@tonic-gate "modules", "modules-val-here", 707c478bd9Sstevel@tonic-gate "primaries", "primaries-v-here", 717c478bd9Sstevel@tonic-gate "modreloc_flag", "modreloc-flagval", 727c478bd9Sstevel@tonic-gate 0, 0 737c478bd9Sstevel@tonic-gate }; 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate static void fdbp_hook() {} /* null function for defer breakpoint operation */ 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 787c478bd9Sstevel@tonic-gate static void fdbp_snoop(unsigned int i, struct modctl *modctl_p) 797c478bd9Sstevel@tonic-gate { 807c478bd9Sstevel@tonic-gate promif_preprom(); 817c478bd9Sstevel@tonic-gate fdbp_hook(); 827c478bd9Sstevel@tonic-gate promif_postprom(); 837c478bd9Sstevel@tonic-gate } 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate static kobj_notify_list_t knl_load = { 867c478bd9Sstevel@tonic-gate fdbp_snoop, KOBJ_NOTIFY_MODLOADED, 0, 0 877c478bd9Sstevel@tonic-gate }; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate static kobj_notify_list_t knl_unload = { 907c478bd9Sstevel@tonic-gate fdbp_snoop, KOBJ_NOTIFY_MODUNLOADING, 0, 0 917c478bd9Sstevel@tonic-gate }; 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate void 947c478bd9Sstevel@tonic-gate forthdebug_init(void) 957c478bd9Sstevel@tonic-gate { 967c478bd9Sstevel@tonic-gate char *fth_buf, *buf_p; 977c478bd9Sstevel@tonic-gate ulong_t modsym; 987c478bd9Sstevel@tonic-gate int i, sz; 99*986fd29aSsetje uint64_t fsz; 1007c478bd9Sstevel@tonic-gate struct _buf *file; 1017c478bd9Sstevel@tonic-gate 1027c478bd9Sstevel@tonic-gate if (!forthdebug_supported) { 1037c478bd9Sstevel@tonic-gate (void) modload("misc", "obpsym"); 1047c478bd9Sstevel@tonic-gate return; 1057c478bd9Sstevel@tonic-gate } 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate forthdebug_dbp |= boothowto & RB_FORTHDEBUGDBP; 1087c478bd9Sstevel@tonic-gate forthdebug |= (boothowto & RB_FORTHDEBUG) | forthdebug_dbp; 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate file = kobj_open_path(FDEBUGFILE, 1, 1); 1117c478bd9Sstevel@tonic-gate if (file == (struct _buf *)-1) { 1127c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Can't open %s\n", FDEBUGFILE); 1137c478bd9Sstevel@tonic-gate return; 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate 116*986fd29aSsetje i = kobj_get_filesize(file, &fsz); 117*986fd29aSsetje if (i || !fsz) { 1187c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Can't stat %s stat=%x sz=%llx\n", 119*986fd29aSsetje FDEBUGFILE, i, (long long)fsz); 1207c478bd9Sstevel@tonic-gate goto err_stat; 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate 123*986fd29aSsetje fth_buf = (char *)kobj_zalloc(fsz + 1, KM_SLEEP); 124*986fd29aSsetje sz = kobj_read_file(file, fth_buf, fsz, 0); /* entire file */ 1257c478bd9Sstevel@tonic-gate if (sz < 0) { 1267c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "Error(%d) reading %s\n", sz, FDEBUGFILE); 1277c478bd9Sstevel@tonic-gate goto done; 1287c478bd9Sstevel@tonic-gate } 129*986fd29aSsetje ASSERT(fsz == sz); 1307c478bd9Sstevel@tonic-gate fth_buf[sz] = 0; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate /* resolve all essential symbols in basic_sym[] */ 1337c478bd9Sstevel@tonic-gate for (i = 0; basic_sym[i]; i += 2) { 1347c478bd9Sstevel@tonic-gate buf_p = strstr(fth_buf, basic_sym[i + 1]); 1357c478bd9Sstevel@tonic-gate modsym = kobj_getsymvalue(basic_sym[i], 0); 1367c478bd9Sstevel@tonic-gate if (buf_p && modsym) { 1377c478bd9Sstevel@tonic-gate (void) sprintf(buf_p, "%16p", (void *)modsym); 1387c478bd9Sstevel@tonic-gate buf_p += 16; 1397c478bd9Sstevel@tonic-gate *buf_p++ = ' '; /* erase null char by sprintf */ 1407c478bd9Sstevel@tonic-gate } else { 1417c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, 1427c478bd9Sstevel@tonic-gate "forthdebug_init: No %s symbol(%p,%p), aborted\n", 1437c478bd9Sstevel@tonic-gate basic_sym[i], (void *)buf_p, (void *)modsym); 1447c478bd9Sstevel@tonic-gate goto done; 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate if (!forthdebug) { /* symbol lookup services only */ 1487c478bd9Sstevel@tonic-gate if (!(buf_p = strstr(fth_buf, SYMBOL_END))) { 1497c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "No %s in forthdebug\n", SYMBOL_END); 1507c478bd9Sstevel@tonic-gate goto done; 1517c478bd9Sstevel@tonic-gate } 1527c478bd9Sstevel@tonic-gate *buf_p = '\0'; 1537c478bd9Sstevel@tonic-gate #ifdef DEBUG 1547c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "symbol lookup service (%ld bytes)\n", 1557c478bd9Sstevel@tonic-gate (long)(buf_p - fth_buf)); 1567c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 1577c478bd9Sstevel@tonic-gate prom_interpret(fth_buf, 0, 0, 0, 0, 0); 1587c478bd9Sstevel@tonic-gate goto done; 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "%s (%d bytes) ", FDEBUGFILE, sz); 1627c478bd9Sstevel@tonic-gate prom_interpret(fth_buf, 0, 0, 0, 0, 0); 1637c478bd9Sstevel@tonic-gate cmn_err(CE_CONT, "loaded\n"); 1647c478bd9Sstevel@tonic-gate obpdebug = 1; /* backward compatibility */ 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate if (forthdebug_dbp) { 1677c478bd9Sstevel@tonic-gate #ifdef NO_KOBJ_NOTIFY 1687c478bd9Sstevel@tonic-gate modsym = kobj_getsymvalue("kobj_notify_add", 0); 1697c478bd9Sstevel@tonic-gate (void) ((int (*)(kobj_notify_list_t *))modsym)(&knl_load); 1707c478bd9Sstevel@tonic-gate (void) ((int (*)(kobj_notify_list_t *))modsym)(&knl_unload); 1717c478bd9Sstevel@tonic-gate #else 1727c478bd9Sstevel@tonic-gate (void) kobj_notify_add(&knl_load); 1737c478bd9Sstevel@tonic-gate (void) kobj_notify_add(&knl_unload); 1747c478bd9Sstevel@tonic-gate #endif /* NO_KOBJ_NOTIFY */ 1757c478bd9Sstevel@tonic-gate prom_interpret(INSTALL_DBP, 0, 0, 0, 0, 0); 1767c478bd9Sstevel@tonic-gate debug_enter("Defer breakpoint enabled. Add breakpoints, then"); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate done: 179*986fd29aSsetje kobj_free(fth_buf, fsz + 1); 1807c478bd9Sstevel@tonic-gate err_stat: 1817c478bd9Sstevel@tonic-gate kobj_close_file(file); 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate if (boothowto & RB_HALT) 1847c478bd9Sstevel@tonic-gate debug_enter("forthdebug: halt flag (-h) is set.\n"); 1857c478bd9Sstevel@tonic-gate } 186