/* * Sends a request to the driver to load the module. If/when the load has * completed successfully, kmdb_module_loaded is called. */ int mdb_module_load(const char *fname, int mode) { const char *modname = strbasename(fname); kmdb_wr_load_t *dlr; kmdb_modctl_t *kmc = NULL; const char *wformat = NULL; mdb_var_t *v; if (!mdb_module_validate_name(modname, &wformat)) goto module_load_err; if ((v = mdb_nv_lookup(&mdb.m_dmodctl, modname)) != NULL) { kmc = MDB_NV_COOKIE(v); if (kmc->kmc_state == KMDB_MC_STATE_LOADING) wformat = "module %s is already being loaded\n"; else wformat = "module %s is being unloaded\n"; goto module_load_err; } kmc = mdb_zalloc(sizeof (kmdb_modctl_t), UM_SLEEP); kmc->kmc_loadmode = mode; kmc->kmc_modname = strdup(modname); kmc->kmc_state = KMDB_MC_STATE_LOADING; if (mdb_nv_insert(&mdb.m_dmodctl, modname, NULL, (uintptr_t)kmc, 0) == NULL) { wformat = "module %s can't be registered for load\n"; kmc_free(kmc); goto module_load_err; } dlr = mdb_zalloc(sizeof (kmdb_wr_load_t), UM_SLEEP); dlr->dlr_node.wn_task = WNTASK_DMOD_LOAD; dlr->dlr_fname = strdup(fname); kmdb_wr_driver_notify(dlr); if (!(mode & MDB_MOD_DEFER) && mdb_tgt_continue(mdb.m_target, NULL) == 0) return (0); if (!(mode & MDB_MOD_SILENT)) mdb_printf("%s load pending (:c to complete)\n", modname); return (0); module_load_err: if (!(mode & MDB_MOD_SILENT)) warn(wformat, modname); return (-1); }
void mdb_module_load_all(int mode) { kmdb_wr_t *wn; ASSERT(mode & MDB_MOD_DEFER); wn = mdb_zalloc(sizeof (kmdb_wr_t), UM_SLEEP); wn->wn_task = WNTASK_DMOD_LOAD_ALL; kmdb_wr_driver_notify(wn); }
static void kmdb_module_request_unload(kmdb_modctl_t *kmc, const char *modname, int mode) { kmdb_wr_unload_t *dur = mdb_zalloc(sizeof (kmdb_wr_unload_t), UM_SLEEP); dur->dur_node.wn_task = WNTASK_DMOD_UNLOAD; dur->dur_modname = strdup(modname); dur->dur_modctl = kmc->kmc_modctl; kmdb_wr_driver_notify(dur); kmc->kmc_state = KMDB_MC_STATE_UNLOADING; if (!(mode & MDB_MOD_DEFER) && mdb_tgt_continue(mdb.m_target, NULL) == 0) return; if (!(mode & MDB_MOD_SILENT)) mdb_printf("%s unload pending (:c to complete)\n", modname); }
static int kmdb_dbgnotify_cb(kmdb_wr_t *wn, void *arg) { work_results_t *res = arg; switch (WR_TASK(wn)) { case WNTASK_DMOD_LOAD: { /* * If this is an ack, the driver finished processing a load we * requested. We process it and free the message. If this * isn't an ack, then it's a driver-initiated load. We process * the message, and send it back as an ack so the driver can * free it. */ kmdb_wr_load_t *dlr = (kmdb_wr_load_t *)wn; mdb_dprintf(MDB_DBG_DPI, "received module load message\n"); if (kmdb_module_loaded(dlr) && res != NULL) { (void) mdb_nv_insert(&res->res_loads, strbasename(dlr->dlr_fname), NULL, 0, 0); } if (WR_ISACK(dlr)) { kmdb_module_load_ack(dlr); return (0); } /* Send it back as an ack */ mdb_dprintf(MDB_DBG_DPI, "Sending load request for %s back " "as an ack\n", dlr->dlr_fname); WR_ACK(wn); kmdb_wr_driver_notify(wn); return (0); } case WNTASK_DMOD_LOAD_ALL: /* * We initiated the load-all, so this must be an ack. The * individual module load messages will arrive separately - * there's no need to do anything further with this message. */ ASSERT(WR_ISACK(wn)); mdb_dprintf(MDB_DBG_DPI, "received module load all ack\n"); kmdb_module_load_all_ack(wn); return (0); case WNTASK_DMOD_UNLOAD: { /* * The debugger received an unload message. The driver isn't * supposed to initiate unloads, so we shouldn't see anything * but acks. We tell the dmod subsystem that the module has * been unloaded, and we free the message. */ kmdb_wr_unload_t *dur = (kmdb_wr_unload_t *)wn; ASSERT(WR_ISACK(dur)); mdb_dprintf(MDB_DBG_DPI, "received module unload ack\n"); if (kmdb_module_unloaded(dur) && res != NULL) { (void) mdb_nv_insert(&res->res_unloads, dur->dur_modname, NULL, 0, 0); } /* Done with message */ kmdb_module_unload_ack(dur); return (0); } case WNTASK_DMOD_PATH_CHANGE: { /* * The debugger received a path change message. The driver * can't initiate these, so it must be an acknowledgement. * There's no processing to be done, so just free the message. */ kmdb_wr_path_t *dpth = (kmdb_wr_path_t *)wn; ASSERT(WR_ISACK(dpth)); mdb_dprintf(MDB_DBG_DPI, "received path change ack\n"); kmdb_module_path_ack(dpth); return (0); } default: mdb_warn("Received unknown message type %d from driver\n", wn->wn_task); /* Ignore it */ return (0); } }