void kt_deactivate(mdb_tgt_t *t) { kt_data_t *kt = t->t_data; const mdb_tgt_regdesc_t *rdp; const mdb_dcmd_t *dcp; for (rdp = kt->k_rds; rdp->rd_name != NULL; rdp++) { mdb_var_t *v; if (!(rdp->rd_flags & MDB_TGT_R_EXPORT)) continue; /* Didn't export register as a variable */ if ((v = mdb_nv_lookup(&mdb.m_nv, rdp->rd_name)) != NULL) { v->v_flags &= ~MDB_NV_PERSIST; mdb_nv_remove(&mdb.m_nv, v); } } for (dcp = &kt_dcmds[0]; dcp->dc_name != NULL; dcp++) { if (mdb_module_remove_dcmd(t->t_module, dcp->dc_name) == -1) warn("failed to remove dcmd %s", dcp->dc_name); } mdb_prop_postmortem = FALSE; mdb_prop_kernel = FALSE; mdb_prop_datamodel = MDB_TGT_MODEL_UNKNOWN; }
int kmdb_module_unloaded(kmdb_wr_unload_t *dur) { mdb_var_t *v; if ((v = mdb_nv_lookup(&mdb.m_dmodctl, dur->dur_modname)) == NULL) { mdb_warn("unload for unrequested module %s\n", dur->dur_modname); return (0); } if (dur->dur_errno != 0) { mdb_warn("dmod %s failed to unload", dur->dur_modname); return (0); } kmc_free(MDB_NV_COOKIE(v)); mdb_nv_remove(&mdb.m_dmodctl, v); return (1); }
int kmdb_module_loaded(kmdb_wr_load_t *dlr) { struct modctl *modp = dlr->dlr_modctl; const char *modname = strbasename(dlr->dlr_fname); struct module *mp; kmdb_modctl_t *kmc; mdb_var_t *v; v = mdb_nv_lookup(&mdb.m_dmodctl, modname); if (dlr->dlr_errno != 0) { /* * We're somewhat limited in the diagnostics that we can * provide in the event of a failed load. In most load-failure * cases, the driver can only send up a generic errno. We use * EMDB_ENOMOD to signal generic errors, and supply our own * message. This twists the meaning of EMDB_NOMOD somewhat, but * it's better than defining a new one. */ if (dlr->dlr_errno == EMDB_NOMOD) { mdb_warn("%s does not appear to be a kmdb dmod\n", modname); } else { (void) set_errno(dlr->dlr_errno); mdb_warn("dmod %s failed to load", modname); } if (v != NULL) mdb_nv_remove(&mdb.m_dmodctl, v); return (0); } if ((mp = modp->mod_mp) == NULL || mp->symhdr == NULL || mp->strhdr == NULL || mp->symtbl == NULL || mp->strings == NULL) { mdb_warn("dmod %s did not load properly\n"); goto module_loaded_err; } if ((v = mdb_nv_lookup(&mdb.m_dmodctl, modname)) == NULL) { kmc = mdb_zalloc(sizeof (kmdb_modctl_t), UM_SLEEP); kmc->kmc_loadmode = MDB_MOD_LOCAL; kmc->kmc_modname = strdup(modname); kmc->kmc_state = KMDB_MC_STATE_LOADING; (void) mdb_nv_insert(&mdb.m_dmodctl, modname, NULL, (uintptr_t)kmc, 0); } else { kmc = MDB_NV_COOKIE(v); ASSERT(kmc->kmc_symtab == NULL); } kmc->kmc_modctl = modp; kmc->kmc_exported = (mp->flags & KOBJ_EXPORTED) != 0; mdb_gelf_ehdr_to_gehdr(&mp->hdr, &kmc->kmc_ehdr); kmc->kmc_symtab = mdb_gelf_symtab_create_raw(&kmc->kmc_ehdr, mp->symhdr, mp->symtbl, mp->strhdr, mp->strings, MDB_TGT_SYMTAB); if (mp->flags & KOBJ_PRIM) kmc->kmc_flags |= KMDB_MC_FL_NOUNLOAD; if (mdb_module_create(modname, modp->mod_filename, kmc->kmc_loadmode, &kmc->kmc_mod) < 0) goto module_loaded_err; kmc->kmc_state = KMDB_MC_STATE_LOADED; return (1); module_loaded_err: if (kmc->kmc_symtab != NULL) mdb_gelf_symtab_destroy(kmc->kmc_symtab); kmdb_module_request_unload(kmc, kmc->kmc_modname, MDB_MOD_DEFER); return (0); }