kctl_mod.c revision 11053:f33a1c7f3155
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/* 27 * Tracking of kernel module loads and unloads 28 */ 29 30#include <kmdb/kmdb_kdi.h> 31#include <kmdb/kctl/kctl.h> 32#include <sys/kobj.h> 33#include <sys/kobj_impl.h> 34#include <sys/ctf_api.h> 35 36static kobj_notify_list_t kctl_mod_notifiers[] = { 37 { kctl_mod_changed, KOBJ_NOTIFY_MODLOADED }, 38 { kctl_mod_changed, KOBJ_NOTIFY_MODUNLOADING }, 39 { NULL, 0 } 40}; 41 42int 43kctl_mod_decompress(struct modctl *modp) 44{ 45 ctf_file_t *fp; 46 struct module *mp = modp->mod_mp; 47 int rc; 48 49 if ((kmdb_kdi_get_flags() & KMDB_KDI_FL_NOCTF) || mp->ctfdata == NULL) 50 return (0); 51 52 if ((fp = ctf_modopen(mp, &rc)) == NULL) 53 return (rc); 54 55 ctf_close(fp); 56 57 return (0); 58} 59 60void 61kctl_mod_loaded(struct modctl *modp) 62{ 63 int rc; 64 65 mutex_enter(&mod_lock); 66 if (modp->mod_mp == NULL) { 67 mutex_exit(&mod_lock); 68 return; 69 } 70 71 if ((rc = kctl_mod_decompress(modp)) != 0) { 72 cmn_err(CE_WARN, "failed to decompress CTF data for %s: %s\n", 73 modp->mod_modname, ctf_errmsg(rc)); 74 } 75 mutex_exit(&mod_lock); 76 77 if (!(kmdb_kdi_get_flags() & KMDB_KDI_FL_NOMODS)) 78 kctl_dmod_autoload(modp->mod_modname); 79} 80 81/*ARGSUSED*/ 82void 83kctl_mod_changed(uint_t why, struct modctl *what) 84{ 85 if (why == KOBJ_NOTIFY_MODLOADED) 86 kctl_mod_loaded(what); 87} 88 89/* 90 * Tell krtld to notify kmdb when modules have been loaded and unloaded 91 */ 92void 93kctl_mod_notify_reg(void) 94{ 95 kobj_notify_list_t *kn; 96 97 for (kn = kctl_mod_notifiers; kn->kn_func != NULL; kn++) 98 (void) kobj_notify_add(kn); 99} 100 101void 102kctl_mod_notify_unreg(void) 103{ 104 kobj_notify_list_t *kn; 105 106 for (kn = kctl_mod_notifiers; kn->kn_func != NULL; kn++) 107 (void) kobj_notify_remove(kn); 108} 109