xref: /illumos-gate/usr/src/cmd/mdb/common/kmdb/kmdb_module_load.c (revision 123d0ae215b50332e75fc140856ee4322fc2940f)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  * Copyright 2025 Edgecast Cloud LLC.
26  */
27 
28 #include <sys/param.h>
29 #include <sys/modctl.h>
30 #include <sys/kobj.h>
31 #include <sys/kobj_impl.h>
32 #include <unistd.h>
33 #include <strings.h>
34 #include <dlfcn.h>
35 #include <link.h>
36 
37 #include <kmdb/kmdb_module.h>
38 #include <kmdb/kmdb_wr_impl.h>
39 #include <kmdb/kmdb_kdi.h>
40 #include <mdb/mdb_modapi.h>
41 #include <mdb/mdb_debug.h>
42 #include <mdb/mdb_string.h>
43 #include <mdb/mdb_ctf.h>
44 #include <mdb/mdb_err.h>
45 #include <mdb/mdb_io.h>
46 #include <mdb/mdb_frame.h>
47 #include <mdb/mdb.h>
48 
49 static void kmdb_module_request_unload(kmdb_modctl_t *, const char *, int);
50 
51 static void
kmc_free(kmdb_modctl_t * kmc)52 kmc_free(kmdb_modctl_t *kmc)
53 {
54 	if (kmc->kmc_modname != NULL)
55 		strfree(kmc->kmc_modname);
56 	mdb_free(kmc, sizeof (kmdb_modctl_t));
57 }
58 
59 /*
60  * Sends a request to the driver to load the module.
61  */
62 int
mdb_module_load(const char * fname,int mode)63 mdb_module_load(const char *fname, int mode)
64 {
65 	const char *modname = strbasename(fname);
66 	kmdb_wr_load_t *dlr;
67 	kmdb_modctl_t *kmc = NULL;
68 	const char *wformat = NULL;
69 	mdb_var_t *v;
70 
71 	if (!mdb_module_validate_name(modname, &wformat))
72 		goto module_load_err;
73 
74 	if ((v = mdb_nv_lookup(&mdb.m_dmodctl, modname)) != NULL) {
75 		kmc = MDB_NV_COOKIE(v);
76 
77 		if (kmc->kmc_state == KMDB_MC_STATE_LOADING)
78 			wformat = "module %s is already being loaded\n";
79 		else
80 			wformat = "module %s is being unloaded\n";
81 		goto module_load_err;
82 	}
83 
84 	kmc = mdb_zalloc(sizeof (kmdb_modctl_t), UM_SLEEP);
85 	kmc->kmc_loadmode = mode;
86 	kmc->kmc_modname = strdup(modname);
87 	kmc->kmc_state = KMDB_MC_STATE_LOADING;
88 
89 	if (mdb_nv_insert(&mdb.m_dmodctl, modname, NULL, (uintptr_t)kmc, 0) ==
90 	    NULL) {
91 		wformat = "module %s can't be registered for load\n";
92 		kmc_free(kmc);
93 		goto module_load_err;
94 	}
95 
96 	dlr = mdb_zalloc(sizeof (kmdb_wr_load_t), UM_SLEEP);
97 	dlr->dlr_node.wn_task = WNTASK_DMOD_LOAD;
98 	dlr->dlr_fname = strdup(fname);
99 
100 	kmdb_wr_driver_notify(dlr);
101 
102 	if (!(mode & MDB_MOD_DEFER) &&
103 	    mdb_tgt_continue(mdb.m_target, NULL) == 0)
104 		return (0);
105 
106 	if (!(mode & MDB_MOD_SILENT))
107 		mdb_printf("%s load pending (:c to complete)\n", modname);
108 
109 	return (0);
110 
111 module_load_err:
112 	if (!(mode & MDB_MOD_SILENT))
113 		warn(wformat, modname);
114 
115 	return (-1);
116 }
117 
118 /*
119  * Module load post processing. Either clean up from error or
120  * update modctl state.
121  */
122 boolean_t
kmdb_module_loaded(kmdb_wr_load_t * dlr)123 kmdb_module_loaded(kmdb_wr_load_t *dlr)
124 {
125 	struct modctl *modp = dlr->dlr_modctl;
126 	const char *modname = strbasename(dlr->dlr_fname);
127 	struct module *mp;
128 	kmdb_modctl_t *kmc = NULL;
129 	mdb_var_t *v;
130 
131 	v = mdb_nv_lookup(&mdb.m_dmodctl, modname);
132 
133 	if (dlr->dlr_errno != 0) {
134 		/*
135 		 * We're somewhat limited in the diagnostics that we can
136 		 * provide in the event of a failed load.  In most load-failure
137 		 * cases, the driver can only send up a generic errno.  We use
138 		 * EMDB_ENOMOD to signal generic errors, and supply our own
139 		 * message.  This twists the meaning of EMDB_NOMOD somewhat, but
140 		 * it's better than defining a new one.
141 		 */
142 		if (dlr->dlr_errno == EMDB_NOMOD) {
143 			mdb_warn("%s does not appear to be a kmdb dmod\n",
144 			    modname);
145 		} else {
146 			(void) set_errno(dlr->dlr_errno);
147 			mdb_warn("dmod %s failed to load", modname);
148 		}
149 
150 		if (v != NULL)
151 			mdb_nv_remove(&mdb.m_dmodctl, v);
152 		return (B_FALSE);
153 	}
154 
155 	if ((mp = modp->mod_mp) == NULL || mp->symhdr == NULL ||
156 	    mp->strhdr == NULL || mp->symtbl == NULL || mp->strings == NULL) {
157 		mdb_warn("dmod %s did not load properly\n");
158 		return (B_FALSE);
159 	}
160 
161 	if (v == NULL) {
162 		kmc = mdb_zalloc(sizeof (kmdb_modctl_t), UM_SLEEP);
163 		kmc->kmc_loadmode = MDB_MOD_LOCAL;
164 		kmc->kmc_modname = strdup(modname);
165 		kmc->kmc_state = KMDB_MC_STATE_LOADING;
166 
167 		(void) mdb_nv_insert(&mdb.m_dmodctl, modname, NULL,
168 		    (uintptr_t)kmc, 0);
169 	} else {
170 		kmc = MDB_NV_COOKIE(v);
171 		ASSERT(kmc->kmc_symtab == NULL);
172 	}
173 
174 	kmc->kmc_modctl = modp;
175 	kmc->kmc_exported = (mp->flags & KOBJ_EXPORTED) != 0;
176 	mdb_gelf_ehdr_to_gehdr(&mp->hdr, &kmc->kmc_ehdr);
177 
178 	kmc->kmc_symtab = mdb_gelf_symtab_create_raw(&kmc->kmc_ehdr, mp->symhdr,
179 	    mp->symtbl, mp->strhdr, mp->strings,
180 	    MDB_TGT_SYMTAB);
181 
182 	if (mp->flags & KOBJ_PRIM)
183 		kmc->kmc_flags |= KMDB_MC_FL_NOUNLOAD;
184 
185 	if (mdb_module_create(modname, modp->mod_filename,
186 	    kmc->kmc_loadmode, &kmc->kmc_mod) < 0) {
187 		if (kmc->kmc_symtab != NULL)
188 			mdb_gelf_symtab_destroy(kmc->kmc_symtab);
189 
190 		kmdb_module_request_unload(kmc, kmc->kmc_modname,
191 		    MDB_MOD_DEFER);
192 		return (B_FALSE);
193 	}
194 
195 	kmc->kmc_state = KMDB_MC_STATE_LOADED;
196 
197 	return (B_TRUE);
198 }
199 
200 void
kmdb_module_load_ack(kmdb_wr_load_t * dlr)201 kmdb_module_load_ack(kmdb_wr_load_t *dlr)
202 {
203 	strfree(dlr->dlr_fname);
204 	mdb_free(dlr, sizeof (kmdb_wr_load_t));
205 }
206 
207 void
mdb_module_load_all(int mode)208 mdb_module_load_all(int mode)
209 {
210 	kmdb_wr_t *wn;
211 
212 	ASSERT(mode & MDB_MOD_DEFER);
213 
214 	wn = mdb_zalloc(sizeof (kmdb_wr_t), UM_SLEEP);
215 	wn->wn_task = WNTASK_DMOD_LOAD_ALL;
216 
217 	kmdb_wr_driver_notify(wn);
218 }
219 
220 void
kmdb_module_load_all_ack(kmdb_wr_t * wn)221 kmdb_module_load_all_ack(kmdb_wr_t *wn)
222 {
223 	mdb_free(wn, sizeof (kmdb_wr_t));
224 }
225 
226 static void
kmdb_module_request_unload(kmdb_modctl_t * kmc,const char * modname,int mode)227 kmdb_module_request_unload(kmdb_modctl_t *kmc, const char *modname, int mode)
228 {
229 	kmdb_wr_unload_t *dur = mdb_zalloc(sizeof (kmdb_wr_unload_t), UM_SLEEP);
230 	dur->dur_node.wn_task = WNTASK_DMOD_UNLOAD;
231 	dur->dur_modname = strdup(modname);
232 	dur->dur_modctl = kmc->kmc_modctl;
233 
234 	kmdb_wr_driver_notify(dur);
235 
236 	kmc->kmc_state = KMDB_MC_STATE_UNLOADING;
237 
238 	if (!(mode & MDB_MOD_DEFER) &&
239 	    mdb_tgt_continue(mdb.m_target, NULL) == 0)
240 		return;
241 
242 	if (!(mode & MDB_MOD_SILENT))
243 		mdb_printf("%s unload pending (:c to complete)\n", modname);
244 }
245 
246 /*ARGSUSED*/
247 int
mdb_module_unload(const char * name,int mode)248 mdb_module_unload(const char *name, int mode)
249 {
250 	kmdb_modctl_t *kmc = NULL;
251 	const char *basename;
252 	mdb_var_t *v;
253 
254 	/*
255 	 * We may have been called with the name from the module itself
256 	 * if the caller is iterating through the module list, so we need
257 	 * to make a copy of the name.  If we don't, we can't use it after
258 	 * the call to unload_common(), which frees the module.
259 	 */
260 	name = strdup(name);
261 	basename = strbasename(name);
262 
263 	/*
264 	 * Make sure the module is in the proper state for unloading.  Modules
265 	 * may only be unloaded if they have properly completed loading.
266 	 */
267 	if ((v = mdb_nv_lookup(&mdb.m_dmodctl, basename)) != NULL) {
268 		kmc = MDB_NV_COOKIE(v);
269 		switch (kmc->kmc_state) {
270 		case KMDB_MC_STATE_LOADING:
271 			warn("%s is in the process of loading\n", basename);
272 			return (set_errno(EMDB_NOMOD));
273 		case KMDB_MC_STATE_UNLOADING:
274 			warn("%s is already being unloaded\n", basename);
275 			return (set_errno(EMDB_NOMOD));
276 		default:
277 			ASSERT(kmc->kmc_state == KMDB_MC_STATE_LOADED);
278 		}
279 
280 		if (kmc->kmc_flags & KMDB_MC_FL_NOUNLOAD)
281 			return (set_errno(EMDB_KMODNOUNLOAD));
282 	}
283 
284 	if (mdb_module_unload_common(name) < 0) {
285 		if (!(mode & MDB_MOD_SILENT)) {
286 			mdb_dprintf(MDB_DBG_MODULE, "unload of %s failed\n",
287 			    name);
288 		}
289 		return (-1); /* errno is set for us */
290 	}
291 
292 	/*
293 	 * Any modules legitimately not listed in dmodctl (builtins, for
294 	 * example) will be handled by mdb_module_unload_common.  If any of
295 	 * them get here, we've got a problem.
296 	 */
297 	if (v == NULL) {
298 		warn("unload of unregistered module %s\n", basename);
299 		return (set_errno(EMDB_NOMOD));
300 	}
301 
302 	ASSERT(kmc->kmc_dlrefcnt == 0);
303 
304 	mdb_gelf_symtab_destroy(kmc->kmc_symtab);
305 
306 	kmdb_module_request_unload(kmc, basename, mode);
307 	return (0);
308 }
309 
310 boolean_t
kmdb_module_unloaded(kmdb_wr_unload_t * dur)311 kmdb_module_unloaded(kmdb_wr_unload_t *dur)
312 {
313 	mdb_var_t *v;
314 
315 	if ((v = mdb_nv_lookup(&mdb.m_dmodctl, dur->dur_modname)) == NULL) {
316 		mdb_warn("unload for unrequested module %s\n",
317 		    dur->dur_modname);
318 		return (B_FALSE);
319 	}
320 
321 	if (dur->dur_errno != 0) {
322 		mdb_warn("dmod %s failed to unload", dur->dur_modname);
323 		return (B_FALSE);
324 	}
325 
326 	kmc_free(MDB_NV_COOKIE(v));
327 	mdb_nv_remove(&mdb.m_dmodctl, v);
328 
329 	return (B_TRUE);
330 }
331 
332 void
kmdb_module_unload_ack(kmdb_wr_unload_t * dur)333 kmdb_module_unload_ack(kmdb_wr_unload_t *dur)
334 {
335 	if (dur->dur_modname != NULL)
336 		strfree(dur->dur_modname);
337 	mdb_free(dur, sizeof (kmdb_wr_unload_t));
338 }
339 
340 /*
341  * Called by the kmdb_kvm target upon debugger reentry, this routine checks
342  * to see if the loaded dmods have changed.  Of particular interest is the
343  * exportation of dmod symbol tables, which will happen during the boot
344  * process for dmods that were loaded prior to kernel startup.  If this
345  * has occurred, we'll need to reconstruct our view of the symbol tables for
346  * the affected dmods, since the old symbol tables lived in bootmem
347  * and have been moved during the kobj_export_module().
348  *
349  * Also, any ctf_file_t we might have opened is now invalid, since it
350  * has internal pointers to the old data as well.
351  */
352 void
kmdb_module_sync(void)353 kmdb_module_sync(void)
354 {
355 	mdb_var_t *v;
356 
357 	mdb_nv_rewind(&mdb.m_dmodctl);
358 	while ((v = mdb_nv_advance(&mdb.m_dmodctl)) != NULL) {
359 		kmdb_modctl_t *kmc = MDB_NV_COOKIE(v);
360 		struct module *mp;
361 
362 		if (kmc->kmc_state != KMDB_MC_STATE_LOADED)
363 			continue;
364 
365 		mp = kmc->kmc_modctl->mod_mp;
366 
367 		if ((mp->flags & (KOBJ_PRIM | KOBJ_EXPORTED)) &&
368 		    !kmc->kmc_exported) {
369 			/*
370 			 * The exporting process moves the symtab from boot
371 			 * scratch memory to vmem.
372 			 */
373 			if (kmc->kmc_symtab != NULL)
374 				mdb_gelf_symtab_destroy(kmc->kmc_symtab);
375 
376 			kmc->kmc_symtab = mdb_gelf_symtab_create_raw(
377 			    &kmc->kmc_ehdr, mp->symhdr, mp->symtbl, mp->strhdr,
378 			    mp->strings, MDB_TGT_SYMTAB);
379 
380 			if (kmc->kmc_mod->mod_ctfp != NULL) {
381 				ctf_close(kmc->kmc_mod->mod_ctfp);
382 				kmc->kmc_mod->mod_ctfp =
383 				    mdb_ctf_open(kmc->kmc_modname, NULL);
384 			}
385 			kmc->kmc_exported = TRUE;
386 		}
387 	}
388 }
389