xref: /illumos-gate/usr/src/cmd/mdb/common/mdb/mdb_kproc.c (revision 0c1b95be)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  *
25  * Copyright 2018 Joyent, Inc.
26  * Copyright 2024 Oxide Computer Company
27  */
28 
29 /*
30  * Kernel Process View Target
31  *
32  * The kproc target is activated when the user is debugging a kernel using the
33  * kvm target and executes a ::context dcmd to change the debugger view to one
34  * of the running processes.  The kvm target's t_setcontext operation will
35  * create and activate a kproc target in response to this call.  The kproc
36  * target itself is built upon the kvm target's libkvm cookie and the ability
37  * to read information from the kernel itself and the ability to read the
38  * address space of a particular user process with kvm_aread().  It also relies
39  * on a special set of functions provided by the kvm target's mdb_ks support
40  * module in order to bootstrap: specifically, given the initial proc pointer,
41  * mdb_ks provides functions to return the set of address space mappings, the
42  * address space pointer itself, the aux vector vector saved in the u-area,
43  * and the process data model.  The kproc target maintains a list of address
44  * space mappings (kp_map_t) and load objects (kp_file_t), and for each load
45  * object will attempt to read the corresponding dynamic symbol table.  In
46  * order to bootstrap, the target uses the AT_BASE and AT_ENTRY aux vector
47  * elements to locate the dynamic linker and executable mappings.  With these
48  * mappings in place, we initialize a librtld_db agent on the target (see
49  * mdb_pservice.c for how this is done), and then process each load object
50  * found in the link-map chain.  In order to simplify the construction of
51  * symbol tables for each load object, we would like make use of our existing
52  * library of GElf processing code.  Since the MDB GElf code uses mdb_io
53  * objects to read in an ELF file, we simply define a new type of mdb_io object
54  * where each read operation is translated into a call to kproc's t_vread
55  * function to read from the range of the address space defined by the mapping
56  * as if it were a file.
57  */
58 
59 #include <sys/types.h>
60 #include <sys/proc.h>
61 #include <sys/auxv.h>
62 
63 #include <strings.h>
64 #include <limits.h>
65 #include <rtld_db.h>
66 #include <procfs.h>
67 #include <dlfcn.h>
68 #include <kvm.h>
69 
70 #include <mdb/mdb_target_impl.h>
71 #include <mdb/mdb_debug.h>
72 #include <mdb/mdb_string.h>
73 #include <mdb/mdb_err.h>
74 #include <mdb/mdb_ks.h>
75 #include <mdb/mdb_gelf.h>
76 #include <mdb/mdb_io_impl.h>
77 #include <mdb/mdb.h>
78 
79 typedef struct kp_symarg {
80 	mdb_tgt_sym_f *sym_cb;		/* Caller's callback function */
81 	void *sym_data;			/* Callback function argument */
82 	uint_t sym_type;		/* Symbol type/binding filter */
83 	uintptr_t sym_adjust;		/* Symbol value adjustment */
84 	mdb_syminfo_t sym_info;		/* Symbol id and table id */
85 	const char *sym_obj;		/* Containing object */
86 } kp_symarg_t;
87 
88 typedef struct kp_file {
89 	mdb_gelf_file_t *kpf_file;	/* ELF file object */
90 	mdb_io_t *kpf_fio;		/* ELF file back-end */
91 	mdb_gelf_symtab_t *kpf_dynsym;	/* Dynamic symbol table */
92 	struct kp_map *kpf_map;		/* Primary (text) mapping */
93 	const char *kpf_basename;	/* Mapping basename */
94 	uintptr_t kpf_dyn_base;		/* Load address for ET_DYN files */
95 	uintptr_t kpf_text_base;	/* Base address of text mapping */
96 	uintptr_t kpf_data_base;	/* Base address of data mapping */
97 	struct kp_file *kpf_next;	/* Pointer to next file */
98 } kp_file_t;
99 
100 typedef struct kp_map {
101 	mdb_map_t kpm_map;		/* Mapping information */
102 	kp_file_t *kpm_file;		/* Pointer to load object */
103 	struct kp_map *kpm_next;	/* Pointer to next mapping */
104 } kp_map_t;
105 
106 typedef struct kp_io {
107 	mdb_tgt_t *kpi_tgt;		/* Backpointer to kproc target */
108 	kp_map_t *kpi_map;		/* Mapping for this i/o */
109 	uintptr_t kpi_ptr;		/* Virtual address pointer */
110 	uintptr_t kpi_lim;		/* Virtual address limit */
111 } kp_io_t;
112 
113 typedef struct kp_data {
114 	mdb_tgt_t *kp_parent;		/* Parent kvm target */
115 	kvm_t *kp_cookie;		/* Cookie for libkvm routines */
116 	rd_agent_t *kp_rap;		/* Cookie for librtld_db routines */
117 	proc_t *kp_proc;		/* Proc address in dump */
118 	struct as *kp_as;		/* Proc as address in dump */
119 	pid_t kp_pid;			/* Process ID */
120 	auxv_t *kp_auxv;		/* Auxv array from u-area */
121 	int kp_nauxv;			/* Length of kp_auxv */
122 	const char *kp_platform;	/* Platform string from kvm target */
123 	uint_t kp_model;		/* Process data model */
124 	kp_file_t *kp_file_head;	/* Head of load object list */
125 	kp_file_t *kp_file_tail;	/* Tail of load object list */
126 	kp_map_t *kp_map_head;		/* Head of mapping list */
127 	kp_map_t *kp_map_tail;		/* Tail of mapping list */
128 	int kp_num_files;		/* Length of load object list */
129 	int kp_num_maps;		/* Length of mapping list */
130 	kp_map_t *kp_map_exec;		/* Executable mapping */
131 	kp_map_t *kp_map_ldso;		/* Interpreter mapping */
132 	kp_file_t kp_prfile;		/* Fake file for mdb.m_prsym */
133 } kp_data_t;
134 
135 static mdb_io_t *kp_io_create(mdb_tgt_t *, kp_map_t *);
136 
137 static kp_map_t *
kp_addr_to_kpmap(kp_data_t * kp,uintptr_t addr)138 kp_addr_to_kpmap(kp_data_t *kp, uintptr_t addr)
139 {
140 	kp_map_t *kpm;
141 
142 	for (kpm = kp->kp_map_head; kpm != NULL; kpm = kpm->kpm_next) {
143 		if (addr >= kpm->kpm_map.map_base &&
144 		    addr < kpm->kpm_map.map_base + kpm->kpm_map.map_size)
145 			return (kpm);
146 	}
147 
148 	return (NULL);
149 }
150 
151 static long
kp_getauxval(kp_data_t * kp,int type)152 kp_getauxval(kp_data_t *kp, int type)
153 {
154 	auxv_t *auxp;
155 
156 	for (auxp = kp->kp_auxv; auxp->a_type != AT_NULL; auxp++) {
157 		if (auxp->a_type == type)
158 			return (auxp->a_un.a_val);
159 	}
160 
161 	return (-1L);
162 }
163 
164 static void
kp_add_mapping(const mdb_map_t * pmp,void * data)165 kp_add_mapping(const mdb_map_t *pmp, void *data)
166 {
167 	kp_map_t *kpm = mdb_zalloc(sizeof (kp_map_t), UM_SLEEP);
168 	kp_data_t *kp = data;
169 
170 	bcopy(pmp, &kpm->kpm_map, sizeof (mdb_map_t));
171 
172 	if (kp->kp_map_tail != NULL)
173 		kp->kp_map_tail->kpm_next = kpm;
174 	else
175 		kp->kp_map_head = kpm;
176 
177 	kp->kp_map_tail = kpm;
178 	kp->kp_num_maps++;
179 }
180 
181 static kp_file_t *
kp_file_create(mdb_tgt_t * t,kp_map_t * kpm,GElf_Half etype)182 kp_file_create(mdb_tgt_t *t, kp_map_t *kpm, GElf_Half etype)
183 {
184 	kp_file_t *kpf = mdb_zalloc(sizeof (kp_file_t), UM_SLEEP);
185 	kp_data_t *kp = t->t_data;
186 	size_t dyns_sz;
187 	void *dyns;
188 
189 	kpf->kpf_fio = kp_io_create(t, kpm);
190 	kpf->kpf_map = kpm;
191 	kpf->kpf_basename = strbasename(kpm->kpm_map.map_name);
192 	kpf->kpf_file = mdb_gelf_create(kpf->kpf_fio, etype, GF_PROGRAM);
193 	kpf->kpf_text_base = kpm->kpm_map.map_base;
194 
195 	if (kpm != kp->kp_map_exec)
196 		kpf->kpf_dyn_base = kpf->kpf_text_base;
197 
198 	if (kpf->kpf_file == NULL)
199 		goto err; /* Failed to create ELF file */
200 
201 	mdb_dprintf(MDB_DBG_TGT, "loading symbols for %s\n",
202 	    kpm->kpm_map.map_name);
203 
204 	if ((kp->kp_rap != NULL) && (rd_get_dyns(kp->kp_rap,
205 	    kpf->kpf_text_base, &dyns, &dyns_sz) == RD_OK))
206 		mdb_gelf_dyns_set(kpf->kpf_file, dyns, dyns_sz);
207 
208 	kpf->kpf_dynsym = mdb_gelf_symtab_create_dynamic(kpf->kpf_file,
209 	    MDB_TGT_DYNSYM);
210 
211 	if (kpf->kpf_dynsym == NULL)
212 		goto err; /* Failed to create symbol table */
213 
214 	kpm->kpm_file = kpf;
215 
216 	if (kp->kp_file_tail != NULL)
217 		kp->kp_file_tail->kpf_next = kpf;
218 	else
219 		kp->kp_file_head = kpf;
220 
221 	kp->kp_file_tail = kpf;
222 	kp->kp_num_files++;
223 
224 	return (kpf);
225 
226 err:
227 	if (kpf->kpf_file != NULL)
228 		mdb_gelf_destroy(kpf->kpf_file);
229 	else
230 		mdb_io_destroy(kpf->kpf_fio);
231 	mdb_free(kpf, sizeof (kp_file_t));
232 	return (NULL);
233 }
234 
235 static void
kp_file_destroy(kp_file_t * kpf)236 kp_file_destroy(kp_file_t *kpf)
237 {
238 	if (kpf->kpf_dynsym != NULL)
239 		mdb_gelf_symtab_destroy(kpf->kpf_dynsym);
240 
241 	mdb_gelf_destroy(kpf->kpf_file);
242 	mdb_free(kpf, sizeof (kp_file_t));
243 }
244 
245 static int
kp_setcontext(mdb_tgt_t * t,void * context)246 kp_setcontext(mdb_tgt_t *t, void *context)
247 {
248 	kp_data_t *kp = t->t_data;
249 
250 	if (kp->kp_proc != context) {
251 		mdb_tgt_destroy(t);
252 		return (mdb_tgt_setcontext(mdb.m_target, context));
253 	}
254 
255 	mdb_warn("debugger context is already set to proc %p\n", context);
256 	return (0);
257 }
258 
259 static kp_map_t *
kp_find_data(kp_data_t * kp,kp_file_t * kpf,const rd_loadobj_t * rlp)260 kp_find_data(kp_data_t *kp, kp_file_t *kpf, const rd_loadobj_t *rlp)
261 {
262 	GElf_Phdr *gpp = kpf->kpf_file->gf_phdrs;
263 	size_t i, n = kpf->kpf_file->gf_npload;
264 
265 	/*
266 	 * Find the first loadable, writeable Phdr and compute kpf_data_base
267 	 * as the virtual address at which is was loaded.
268 	 */
269 	for (i = 0; i < n; i++, gpp++) {
270 		if (gpp->p_type == PT_LOAD && (gpp->p_flags & PF_W)) {
271 			kpf->kpf_data_base = gpp->p_vaddr;
272 			if (kpf->kpf_map != kp->kp_map_exec)
273 				kpf->kpf_data_base += rlp->rl_base;
274 			break;
275 		}
276 	}
277 
278 	/*
279 	 * If we found a suitable Phdr and set kpf_data_base, return
280 	 * the mapping information for this address; otherwise fail.
281 	 */
282 	if (kpf->kpf_data_base != 0)
283 		return (kp_addr_to_kpmap(kp, kpf->kpf_data_base));
284 
285 	return (NULL);
286 }
287 
288 static int
kp_iter_mapping(const rd_loadobj_t * rlp,mdb_tgt_t * t)289 kp_iter_mapping(const rd_loadobj_t *rlp, mdb_tgt_t *t)
290 {
291 	kp_data_t *kp = t->t_data;
292 	kp_file_t *kpf;
293 	kp_map_t *kpm;
294 
295 	char name[MDB_TGT_MAPSZ];
296 
297 	if (mdb_tgt_readstr(t, MDB_TGT_AS_VIRT, name,
298 	    sizeof (name), (mdb_tgt_addr_t)rlp->rl_nameaddr) <= 0) {
299 		mdb_dprintf(MDB_DBG_TGT, "failed to read name %p",
300 		    (void *)rlp->rl_nameaddr);
301 		return (1); /* Keep going; forget this if we can't read name */
302 	}
303 
304 	mdb_dprintf(MDB_DBG_TGT, "rd_loadobj name = \"%s\" rl_base = %p\n",
305 	    name, (void *)rlp->rl_base);
306 
307 	if ((kpm = kp_addr_to_kpmap(kp, rlp->rl_base)) == NULL)
308 		return (1); /* Keep going; no mapping at this address */
309 
310 	(void) strncpy(kpm->kpm_map.map_name, name, MDB_TGT_MAPSZ);
311 	kpm->kpm_map.map_name[MDB_TGT_MAPSZ - 1] = '\0';
312 
313 	if ((kpf = kpm->kpm_file) == NULL) {
314 		if (kpm == kp->kp_map_exec)
315 			kpf = kp_file_create(t, kpm, ET_EXEC);
316 		else
317 			kpf = kp_file_create(t, kpm, ET_DYN);
318 
319 		if (kpf == NULL)
320 			return (1); /* Keep going; failed to build ELF file */
321 	} else
322 		kpf->kpf_basename = strbasename(kpm->kpm_map.map_name);
323 
324 	if ((kpm = kp_find_data(kp, kpf, rlp)) != NULL) {
325 		mdb_dprintf(MDB_DBG_TGT, "found data for %s at %p\n",
326 		    kpf->kpf_basename, (void *)kpm->kpm_map.map_base);
327 		kpm->kpm_file = kpf;
328 	}
329 
330 	return (1);
331 }
332 
333 /*ARGSUSED*/
334 static int
kp_status_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)335 kp_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
336 {
337 	kp_data_t *kp = mdb.m_target->t_data;
338 
339 	mdb_printf("debugging PID %d (%d-bit) in kernel crash dump\n",
340 	    kp->kp_pid, kp->kp_model == PR_MODEL_ILP32 ? 32 : 64);
341 
342 	if (kp->kp_map_exec != NULL) {
343 		mdb_printf("executable file: %s\n",
344 		    kp->kp_map_exec->kpm_map.map_name);
345 	}
346 
347 	return (DCMD_OK);
348 }
349 
350 static const mdb_dcmd_t kp_dcmds[] = {
351 	{ "status", NULL, "print summary of current target", kp_status_dcmd },
352 	{ NULL }
353 };
354 
355 static void
kp_activate(mdb_tgt_t * t)356 kp_activate(mdb_tgt_t *t)
357 {
358 	kp_data_t *kp = t->t_data;
359 
360 	mdb_prop_postmortem = TRUE;
361 	mdb_prop_kernel = FALSE;
362 
363 	if (kp->kp_model == PR_MODEL_ILP32)
364 		mdb_prop_datamodel = MDB_TGT_MODEL_ILP32;
365 	else
366 		mdb_prop_datamodel = MDB_TGT_MODEL_LP64;
367 
368 	/*
369 	 * Initialize our rtld_db agent and then iterate over the link map,
370 	 * instantiating kp_file objects as we go.
371 	 */
372 	if ((kp->kp_rap = rd_new((struct ps_prochandle *)t)) != NULL) {
373 		(void) rd_loadobj_iter(kp->kp_rap, (rl_iter_f *)
374 		    kp_iter_mapping, t);
375 	} else {
376 		mdb_warn("unable to initialize rtld_db agent for proc %p\n",
377 		    (void *)kp->kp_proc);
378 	}
379 
380 	(void) mdb_tgt_register_dcmds(t, &kp_dcmds[0], MDB_MOD_FORCE);
381 
382 	if (kp->kp_map_exec != NULL && kp->kp_map_exec->kpm_file != NULL)
383 		mdb_tgt_elf_export(kp->kp_map_exec->kpm_file->kpf_file);
384 	else
385 		mdb_tgt_elf_export(NULL);
386 }
387 
388 static void
kp_deactivate(mdb_tgt_t * t)389 kp_deactivate(mdb_tgt_t *t)
390 {
391 	const mdb_dcmd_t *dcp;
392 
393 	for (dcp = &kp_dcmds[0]; dcp->dc_name != NULL; dcp++) {
394 		if (mdb_module_remove_dcmd(t->t_module, dcp->dc_name) == -1)
395 			warn("failed to remove dcmd %s", dcp->dc_name);
396 	}
397 
398 	mdb_prop_postmortem = FALSE;
399 	mdb_prop_kernel = FALSE;
400 	mdb_prop_datamodel = MDB_TGT_MODEL_UNKNOWN;
401 }
402 
403 static void
kp_destroy(mdb_tgt_t * t)404 kp_destroy(mdb_tgt_t *t)
405 {
406 	kp_data_t *kp = t->t_data;
407 	kp_map_t *kpm, *nkpm;
408 	kp_file_t *kpf, *nkpf;
409 
410 	if (kp->kp_rap != NULL)
411 		rd_delete(kp->kp_rap);
412 
413 	for (kpm = kp->kp_map_head; kpm != NULL; kpm = nkpm) {
414 		nkpm = kpm->kpm_next;
415 		mdb_free(kpm, sizeof (kp_map_t));
416 	}
417 
418 	for (kpf = kp->kp_file_head; kpf != NULL; kpf = nkpf) {
419 		nkpf = kpf->kpf_next;
420 		kp_file_destroy(kpf);
421 	}
422 
423 	mdb_free(kp->kp_auxv, kp->kp_nauxv * sizeof (auxv_t));
424 	mdb_free(kp, sizeof (kp_data_t));
425 }
426 
427 /*ARGSUSED*/
428 static const char *
kp_name(mdb_tgt_t * t)429 kp_name(mdb_tgt_t *t)
430 {
431 	return ("kproc");
432 }
433 
434 static const char *
kp_isa(mdb_tgt_t * t)435 kp_isa(mdb_tgt_t *t)
436 {
437 	kp_data_t *kp = t->t_data;
438 #ifdef __sparc
439 	return (kp->kp_model == PR_MODEL_ILP32 ? "sparc" : "sparcv9");
440 #else
441 	return (kp->kp_model == PR_MODEL_ILP32 ? "i386" : "amd64");
442 #endif
443 }
444 
445 static const char *
kp_platform(mdb_tgt_t * t)446 kp_platform(mdb_tgt_t *t)
447 {
448 	return (((kp_data_t *)t->t_data)->kp_platform);
449 }
450 
451 static int
kp_uname(mdb_tgt_t * t,struct utsname * utsp)452 kp_uname(mdb_tgt_t *t, struct utsname *utsp)
453 {
454 	kp_data_t *kp = t->t_data;
455 	return (mdb_tgt_uname(kp->kp_parent, utsp));
456 }
457 
458 static int
kp_dmodel(mdb_tgt_t * t)459 kp_dmodel(mdb_tgt_t *t)
460 {
461 	kp_data_t *kp = t->t_data;
462 
463 	switch (kp->kp_model) {
464 	case PR_MODEL_ILP32:
465 		return (MDB_TGT_MODEL_ILP32);
466 	case PR_MODEL_LP64:
467 		return (MDB_TGT_MODEL_LP64);
468 	}
469 
470 	return (MDB_TGT_MODEL_UNKNOWN);
471 }
472 
473 static kp_map_t *
kp_name_to_kpmap(kp_data_t * kp,const char * name)474 kp_name_to_kpmap(kp_data_t *kp, const char *name)
475 {
476 	size_t namelen;
477 	kp_file_t *kpf;
478 	kp_map_t *kpm;
479 
480 	/*
481 	 * Handle special reserved names (except for MDB_TGT_OBJ_EVERY):
482 	 */
483 	if (name == MDB_TGT_OBJ_EXEC)
484 		return (kp->kp_map_exec);
485 
486 	if (name == MDB_TGT_OBJ_RTLD)
487 		return (kp->kp_map_ldso);
488 
489 	/*
490 	 * First pass: look for exact matches on the entire pathname
491 	 * associated with the mapping or its basename.
492 	 */
493 	for (kpm = kp->kp_map_head; kpm != NULL; kpm = kpm->kpm_next) {
494 		if ((kpf = kpm->kpm_file) != NULL) {
495 			if (strcmp(kpm->kpm_map.map_name, name) == 0 ||
496 			    strcmp(kpf->kpf_basename, name) == 0)
497 				return (kpf->kpf_map);
498 		}
499 	}
500 
501 	namelen = strlen(name);
502 
503 	/*
504 	 * Second pass: look for partial matches (initial basename match
505 	 * up to a '.' suffix); allows "libc.so" or "libc" to match "libc.so.1"
506 	 */
507 	for (kpm = kp->kp_map_head; kpm != NULL; kpm = kpm->kpm_next) {
508 		if ((kpf = kpm->kpm_file) != NULL) {
509 			if (strncmp(kpf->kpf_basename, name, namelen) == 0 &&
510 			    kpf->kpf_basename[namelen] == '.')
511 				return (kpf->kpf_map);
512 		}
513 	}
514 
515 	/*
516 	 * One last check: we allow "a.out" to always alias the executable,
517 	 * assuming this name was not in use for something else.
518 	 */
519 	if (strcmp(name, "a.out") == 0)
520 		return (kp->kp_map_exec);
521 
522 	return (NULL);
523 }
524 
525 
526 static ssize_t
kp_vread(mdb_tgt_t * t,void * buf,size_t nbytes,uintptr_t addr)527 kp_vread(mdb_tgt_t *t, void *buf, size_t nbytes, uintptr_t addr)
528 {
529 	kp_data_t *kp = t->t_data;
530 	ssize_t n = kvm_aread(kp->kp_cookie, addr, buf, nbytes, kp->kp_as);
531 
532 	if (n == -1)
533 		return (set_errno(EMDB_NOMAP));
534 
535 	return (n);
536 }
537 
538 static ssize_t
kp_vwrite(mdb_tgt_t * t,const void * buf,size_t nbytes,uintptr_t addr)539 kp_vwrite(mdb_tgt_t *t, const void *buf, size_t nbytes, uintptr_t addr)
540 {
541 	kp_data_t *kp = t->t_data;
542 	ssize_t n = kvm_awrite(kp->kp_cookie, addr, buf, nbytes, kp->kp_as);
543 
544 	if (n == -1)
545 		return (set_errno(EMDB_NOMAP));
546 
547 	return (n);
548 }
549 
550 
551 int
kp_vtop(mdb_tgt_t * t,mdb_tgt_as_t as,uintptr_t va,physaddr_t * pap)552 kp_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap)
553 {
554 	kp_data_t *kp = t->t_data;
555 	physaddr_t pa;
556 
557 	if (as != MDB_TGT_AS_VIRT && as != MDB_TGT_AS_VIRT_I &&
558 	    as != MDB_TGT_AS_VIRT_S)
559 		return (set_errno(EINVAL));
560 
561 	if ((pa = kvm_physaddr(kp->kp_cookie, kp->kp_as, va)) != -1ULL) {
562 		*pap = pa;
563 		return (0);
564 	}
565 
566 	return (set_errno(EMDB_NOMAP));
567 }
568 
569 static int
kp_lookup_by_name(mdb_tgt_t * t,const char * object,const char * name,GElf_Sym * symp,mdb_syminfo_t * sip)570 kp_lookup_by_name(mdb_tgt_t *t, const char *object,
571     const char *name, GElf_Sym *symp, mdb_syminfo_t *sip)
572 {
573 	kp_data_t *kp = t->t_data;
574 	kp_file_t *kpf;
575 	int n;
576 
577 	GElf_Sym sym;
578 	uint_t symid;
579 	int rv = -1;
580 
581 	/*
582 	 * Simplify our task: if object is EVERY, then we need to search
583 	 * kp_num_files files beginning at kp_file_head; otherwise we are
584 	 * searching 1 file whose file pointer is obtained via object_to_map.
585 	 */
586 	if (object != MDB_TGT_OBJ_EVERY) {
587 		kp_map_t *kpm = kp_name_to_kpmap(kp, object);
588 		if (kpm == NULL || kpm->kpm_file == NULL)
589 			return (set_errno(EMDB_NOOBJ));
590 		kpf = kpm->kpm_file;
591 		n = 1;
592 	} else {
593 		kpf = kp->kp_file_head;
594 		n = kp->kp_num_files;
595 	}
596 
597 	/*
598 	 * Iterate through the load object files and look for the symbol name
599 	 * in the .dynsym of each.  If we encounter a match with SHN_UNDEF,
600 	 * keep looking in hopes of finding a better match.  This means that
601 	 * a name such as "puts" will match the puts function in libc instead
602 	 * of matching the puts PLT entry in the a.out file.
603 	 */
604 	for (; n > 0; n--, kpf = kpf->kpf_next) {
605 		if (kpf->kpf_dynsym == NULL)
606 			continue; /* No symbols for this file */
607 
608 		if (mdb_gelf_symtab_lookup_by_name(kpf->kpf_dynsym,
609 		    name, symp, &sip->sym_id) != 0)
610 			continue; /* Symbol name not found */
611 
612 		symp->st_value += kpf->kpf_dyn_base;
613 
614 		if (symp->st_shndx != SHN_UNDEF) {
615 			sip->sym_table = MDB_TGT_DYNSYM;
616 			return (0);
617 		}
618 
619 		if (rv != 0) {
620 			sym = *symp;
621 			symid = sip->sym_id;
622 			rv = 0;
623 		}
624 	}
625 
626 	if (rv != 0)
627 		return (set_errno(EMDB_NOSYM));
628 
629 	sip->sym_table = MDB_TGT_DYNSYM;
630 	sip->sym_id = symid;
631 	*symp = sym;
632 
633 	return (0);
634 }
635 
636 static int
kp_lookup_by_addr(mdb_tgt_t * t,uintptr_t addr,uint_t flags,char * buf,size_t nbytes,GElf_Sym * symp,mdb_syminfo_t * sip)637 kp_lookup_by_addr(mdb_tgt_t *t, uintptr_t addr, uint_t flags,
638     char *buf, size_t nbytes, GElf_Sym *symp, mdb_syminfo_t *sip)
639 {
640 	kp_data_t *kp = t->t_data;
641 	kp_map_t *kpm = kp_addr_to_kpmap(kp, addr);
642 
643 	kp_file_t *sym_kpf = NULL;
644 	GElf_Sym sym;
645 	uint_t symid;
646 
647 	const char *name;
648 	kp_file_t *kpf;
649 	int n;
650 
651 	/*
652 	 * Check the user's private symbol table first; if a match is
653 	 * found there, we're done or we have a first guess.
654 	 */
655 	if (mdb_gelf_symtab_lookup_by_addr(mdb.m_prsym,
656 	    addr, flags, buf, nbytes, symp, &sip->sym_id) == 0) {
657 		sym_kpf = &kp->kp_prfile;
658 		if (flags & MDB_TGT_SYM_EXACT)
659 			goto found;
660 		sym = *symp;
661 		symid = sip->sym_id;
662 	}
663 
664 	/*
665 	 * If no mapping contains the address and EXACT mode is set, we're done.
666 	 * Otherwise we need to search all the symbol tables in fuzzy mode.
667 	 * If we find a mapping, then we only need to search that symtab.
668 	 */
669 	if (kpm == NULL || kpm->kpm_file == NULL) {
670 		if (flags & MDB_TGT_SYM_EXACT)
671 			return (set_errno(EMDB_NOSYMADDR));
672 		kpf = kp->kp_file_head;
673 		n = kp->kp_num_files;
674 	} else {
675 		kpf = kpm->kpm_file;
676 		n = 1;
677 	}
678 
679 	/*
680 	 * Iterate through our list of load objects, scanning each one which
681 	 * has a symbol table.  In fuzzy mode, we continue looking and
682 	 * improve our choice if we find a closer symbol.
683 	 */
684 	for (; n > 0; n--, kpf = kpf->kpf_next) {
685 		if (kpf->kpf_dynsym == NULL)
686 			continue; /* No symbols for this file */
687 
688 		if (mdb_gelf_symtab_lookup_by_addr(kpf->kpf_dynsym,
689 		    addr - kpf->kpf_dyn_base, flags, buf, nbytes,
690 		    symp, &sip->sym_id) != 0)
691 			continue; /* No symbol for this address */
692 
693 		symp->st_value += kpf->kpf_dyn_base;
694 
695 		if (flags & MDB_TGT_SYM_EXACT) {
696 			sym_kpf = kpf;
697 			goto found;
698 		}
699 
700 		if (sym_kpf == NULL || mdb_gelf_sym_closer(symp, &sym, addr)) {
701 			sym_kpf = kpf;
702 			sym = *symp;
703 			symid = sip->sym_id;
704 		}
705 	}
706 
707 	if (sym_kpf == NULL)
708 		return (set_errno(EMDB_NOSYMADDR));
709 
710 	*symp = sym;	/* Copy our best symbol into the caller's symbol */
711 	sip->sym_id = symid;
712 found:
713 	/*
714 	 * Once we've found something, copy the final name into the caller's
715 	 * buffer and prefix it with the load object name if appropriate.
716 	 */
717 	name = mdb_gelf_sym_name(sym_kpf->kpf_dynsym, symp);
718 
719 	if (sym_kpf != kp->kp_map_exec->kpm_file && sym_kpf != &kp->kp_prfile) {
720 		(void) mdb_snprintf(buf, nbytes, "%s`%s",
721 		    sym_kpf->kpf_basename, name);
722 	} else if (nbytes > 0) {
723 		(void) strncpy(buf, name, nbytes);
724 		buf[nbytes - 1] = '\0';
725 	}
726 
727 	if (sym_kpf == &kp->kp_prfile)
728 		sip->sym_table = MDB_TGT_PRVSYM;
729 	else
730 		sip->sym_table = MDB_TGT_DYNSYM;
731 
732 	return (0);
733 }
734 
735 static int
kp_symtab_func(void * data,const GElf_Sym * symp,const char * name,uint_t id)736 kp_symtab_func(void *data, const GElf_Sym *symp, const char *name, uint_t id)
737 {
738 	kp_symarg_t *argp = data;
739 	if (mdb_tgt_sym_match(symp, argp->sym_type)) {
740 		GElf_Sym sym = *symp;
741 
742 		sym.st_value += argp->sym_adjust;
743 
744 		argp->sym_info.sym_id = id;
745 
746 		return (argp->sym_cb(argp->sym_data, &sym, name,
747 		    &argp->sym_info, argp->sym_obj));
748 	}
749 
750 	return (0);
751 }
752 
753 static void
kp_symtab_iter(kp_file_t * kpf,uint_t type,const char * obj,mdb_tgt_sym_f * cb,void * data)754 kp_symtab_iter(kp_file_t *kpf, uint_t type, const char *obj,
755     mdb_tgt_sym_f *cb, void *data)
756 {
757 	if (kpf->kpf_dynsym != NULL) {
758 		kp_symarg_t arg;
759 
760 		arg.sym_cb = cb;
761 		arg.sym_data = data;
762 		arg.sym_type = type;
763 		arg.sym_adjust = kpf->kpf_dyn_base;
764 		arg.sym_info.sym_table = kpf->kpf_dynsym->gst_tabid;
765 		arg.sym_obj = obj;
766 
767 		mdb_gelf_symtab_iter(kpf->kpf_dynsym, kp_symtab_func, &arg);
768 	}
769 }
770 
771 /*ARGSUSED*/
772 static int
kp_symbol_iter(mdb_tgt_t * t,const char * object,uint_t which,uint_t type,mdb_tgt_sym_f * func,void * private)773 kp_symbol_iter(mdb_tgt_t *t, const char *object, uint_t which,
774     uint_t type, mdb_tgt_sym_f *func, void *private)
775 {
776 	kp_data_t *kp = t->t_data;
777 	kp_file_t *kpf = NULL;
778 	kp_map_t *kpm;
779 
780 	switch ((uintptr_t)object) {
781 	case (uintptr_t)MDB_TGT_OBJ_EVERY:
782 		if (kp->kp_map_exec && kp->kp_map_exec->kpm_file) {
783 			kpf = kp->kp_map_exec->kpm_file;
784 			kp_symtab_iter(kpf, type, MDB_TGT_OBJ_EXEC, func,
785 			    private);
786 		}
787 		if (kp->kp_map_ldso && kp->kp_map_ldso->kpm_file) {
788 			kpf = kp->kp_map_ldso->kpm_file;
789 			kp_symtab_iter(kpf, type, MDB_TGT_OBJ_RTLD, func,
790 			    private);
791 		}
792 		return (0);
793 
794 	case (uintptr_t)MDB_TGT_OBJ_EXEC:
795 		if (kp->kp_map_exec && kp->kp_map_exec->kpm_file)
796 			kpf = kp->kp_map_exec->kpm_file;
797 		break;
798 
799 	case (uintptr_t)MDB_TGT_OBJ_RTLD:
800 		if (kp->kp_map_ldso && kp->kp_map_ldso->kpm_file)
801 			kpf = kp->kp_map_ldso->kpm_file;
802 		break;
803 
804 	default:
805 		if ((kpm = kp_name_to_kpmap(kp, object)) != NULL) {
806 			kpf = kpm->kpm_file;
807 			break;
808 		} else
809 			return (set_errno(EMDB_NOOBJ));
810 	}
811 
812 	if (kpf != NULL)
813 		kp_symtab_iter(kpf, type, object, func, private);
814 
815 	return (0);
816 }
817 
818 static int
kp_mapping_iter(mdb_tgt_t * t,mdb_tgt_map_f * func,void * private)819 kp_mapping_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private)
820 {
821 	kp_data_t *kp = t->t_data;
822 	kp_map_t *kpm;
823 
824 	for (kpm = kp->kp_map_head; kpm != NULL; kpm = kpm->kpm_next) {
825 		if (func(private, &kpm->kpm_map, kpm->kpm_map.map_name) != 0)
826 			break;
827 	}
828 
829 	return (0);
830 }
831 
832 static int
kp_object_iter(mdb_tgt_t * t,mdb_tgt_map_f * func,void * private)833 kp_object_iter(mdb_tgt_t *t, mdb_tgt_map_f *func, void *private)
834 {
835 	kp_data_t *kp = t->t_data;
836 	kp_file_t *kpf;
837 
838 	for (kpf = kp->kp_file_head; kpf != NULL; kpf = kpf->kpf_next) {
839 		if (func(private, &kpf->kpf_map->kpm_map,
840 		    kpf->kpf_map->kpm_map.map_name) != 0)
841 			break;
842 	}
843 
844 	return (0);
845 }
846 
847 static const mdb_map_t *
kp_addr_to_map(mdb_tgt_t * t,uintptr_t addr)848 kp_addr_to_map(mdb_tgt_t *t, uintptr_t addr)
849 {
850 	kp_map_t *kpm = kp_addr_to_kpmap(t->t_data, addr);
851 
852 	if (kpm != NULL)
853 		return (&kpm->kpm_map);
854 
855 	(void) set_errno(EMDB_NOMAP);
856 	return (NULL);
857 }
858 
859 static const mdb_map_t *
kp_name_to_map(mdb_tgt_t * t,const char * name)860 kp_name_to_map(mdb_tgt_t *t, const char *name)
861 {
862 	kp_map_t *kpm = kp_name_to_kpmap(t->t_data, name);
863 
864 	if (kpm != NULL)
865 		return (&kpm->kpm_map);
866 
867 	(void) set_errno(EMDB_NOOBJ);
868 	return (NULL);
869 }
870 
871 /*ARGSUSED*/
872 static int
kp_status(mdb_tgt_t * t,mdb_tgt_status_t * tsp)873 kp_status(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
874 {
875 	bzero(tsp, sizeof (mdb_tgt_status_t));
876 	tsp->st_state = MDB_TGT_DEAD;
877 	return (0);
878 }
879 
880 static int
kp_auxv(mdb_tgt_t * t,const auxv_t ** auxvp)881 kp_auxv(mdb_tgt_t *t, const auxv_t **auxvp)
882 {
883 	kp_data_t *kp = t->t_data;
884 	*auxvp = kp->kp_auxv;
885 	return (0);
886 }
887 
888 static const mdb_tgt_ops_t kproc_ops = {
889 	.t_setflags = (int (*)())(uintptr_t)mdb_tgt_notsup,
890 	.t_setcontext = kp_setcontext,
891 	.t_activate = kp_activate,
892 	.t_deactivate = kp_deactivate,
893 	.t_periodic = (void (*)())(uintptr_t)mdb_tgt_nop,
894 	.t_destroy = kp_destroy,
895 	.t_name = kp_name,
896 	.t_isa = kp_isa,
897 	.t_platform = kp_platform,
898 	.t_uname = kp_uname,
899 	.t_dmodel = kp_dmodel,
900 	.t_aread = (ssize_t (*)())mdb_tgt_notsup,
901 	.t_awrite = (ssize_t (*)())mdb_tgt_notsup,
902 	.t_vread = kp_vread,
903 	.t_vwrite = kp_vwrite,
904 	.t_pread = (ssize_t (*)())mdb_tgt_notsup,
905 	.t_pwrite = (ssize_t (*)())mdb_tgt_notsup,
906 	.t_fread = (ssize_t (*)())mdb_tgt_notsup,
907 	.t_fwrite = (ssize_t (*)())mdb_tgt_notsup,
908 	.t_ioread = (ssize_t (*)())mdb_tgt_notsup,
909 	.t_iowrite = (ssize_t (*)())mdb_tgt_notsup,
910 	.t_vtop = kp_vtop,
911 	.t_lookup_by_name = kp_lookup_by_name,
912 	.t_lookup_by_addr = kp_lookup_by_addr,
913 	.t_symbol_iter = kp_symbol_iter,
914 	.t_mapping_iter = kp_mapping_iter,
915 	.t_object_iter = kp_object_iter,
916 	.t_addr_to_map = kp_addr_to_map,
917 	.t_name_to_map = kp_name_to_map,
918 	.t_addr_to_ctf = (struct ctf_file *(*)())mdb_tgt_null,
919 	.t_name_to_ctf = (struct ctf_file *(*)())mdb_tgt_null,
920 	.t_status = kp_status,
921 	.t_run = (int (*)())(uintptr_t)mdb_tgt_notsup,
922 	.t_step = (int (*)())(uintptr_t)mdb_tgt_notsup,
923 	.t_step_out = (int (*)())(uintptr_t)mdb_tgt_notsup,
924 	.t_next = (int (*)())(uintptr_t)mdb_tgt_notsup,
925 	.t_cont = (int (*)())(uintptr_t)mdb_tgt_notsup,
926 	.t_signal = (int (*)())(uintptr_t)mdb_tgt_notsup,
927 	.t_add_sbrkpt = (int (*)())(uintptr_t)mdb_tgt_null,
928 	.t_add_vbrkpt = (int (*)())(uintptr_t)mdb_tgt_null,
929 	.t_add_pwapt = (int (*)())(uintptr_t)mdb_tgt_null,
930 	.t_add_vwapt = (int (*)())(uintptr_t)mdb_tgt_null,
931 	.t_add_iowapt = (int (*)())(uintptr_t)mdb_tgt_null,
932 	.t_add_sysenter = (int (*)())(uintptr_t)mdb_tgt_null,
933 	.t_add_sysexit = (int (*)())(uintptr_t)mdb_tgt_null,
934 	.t_add_signal = (int (*)())(uintptr_t)mdb_tgt_null,
935 	.t_add_fault = (int (*)())(uintptr_t)mdb_tgt_null,
936 	.t_getareg = (int (*)())(uintptr_t)mdb_tgt_notsup,	/* XXX */
937 	.t_putareg = (int (*)())(uintptr_t)mdb_tgt_notsup,	/* XXX */
938 	.t_stack_iter = (int (*)())(uintptr_t)mdb_tgt_notsup,	/* XXX */
939 	.t_auxv = kp_auxv,
940 	.t_thread_name = (int (*)())(uintptr_t)mdb_tgt_notsup,
941 };
942 
943 int
mdb_kproc_tgt_create(mdb_tgt_t * t,int argc,const char * argv[])944 mdb_kproc_tgt_create(mdb_tgt_t *t, int argc, const char *argv[])
945 {
946 	kp_data_t *kp = mdb_zalloc(sizeof (kp_data_t), UM_SLEEP);
947 	void *proc = (void *)argv[0];
948 	long at_entry, at_base;
949 	GElf_Sym sym;
950 
951 	int (*f_asiter)(uintptr_t, void (*)(const mdb_map_t *, void *), void *);
952 	int (*f_auxv)(uintptr_t, auxv_t *);
953 	uintptr_t (*f_as)(uintptr_t);
954 	uint_t (*f_model)(uintptr_t);
955 	pid_t (*f_pid)(uintptr_t);
956 
957 	if (argc != 1)
958 		return (set_errno(EINVAL));
959 
960 	t->t_flags &= ~MDB_TGT_F_RDWR;
961 	t->t_data = kp;
962 	t->t_ops = &kproc_ops;
963 
964 	f_asiter = (int (*)()) dlsym(RTLD_NEXT, "mdb_kproc_asiter");
965 	f_auxv = (int (*)()) dlsym(RTLD_NEXT, "mdb_kproc_auxv");
966 	f_as = (uintptr_t (*)()) dlsym(RTLD_NEXT, "mdb_kproc_as");
967 	f_model = (model_t (*)()) dlsym(RTLD_NEXT, "mdb_kproc_model");
968 	f_pid = (pid_t (*)()) dlsym(RTLD_NEXT, "mdb_kproc_pid");
969 
970 	if (f_asiter == NULL || f_auxv == NULL ||
971 	    f_as == NULL || f_model == NULL || f_pid == NULL) {
972 		warn("required kernel support module is not loaded\n");
973 		goto err;
974 	}
975 
976 	/*
977 	 * Here the kproc target relies on the fact that at the time of its
978 	 * instantiation, mdb.m_target is pointing at a kvm target, and
979 	 * that the kvm target has stored its libkvm handle in t_pshandle.
980 	 */
981 	kp->kp_parent = mdb.m_target;
982 	kp->kp_cookie = mdb.m_target->t_pshandle;
983 	kp->kp_platform = mdb_tgt_platform(mdb.m_target);
984 	kp->kp_proc = proc;
985 	kp->kp_as = (struct as *)f_as((uintptr_t)proc);
986 	kp->kp_pid = f_pid((uintptr_t)proc);
987 
988 	if (kp->kp_as == NULL) {
989 		warn("failed to obtain address space for proc %p\n", proc);
990 		goto err;
991 	}
992 
993 	if (kp->kp_pid == -1) {
994 		warn("failed to obtain PID for proc %p\n", proc);
995 		goto err;
996 	}
997 
998 	if (mdb_tgt_lookup_by_name(kp->kp_parent, MDB_TGT_OBJ_EXEC, "kas",
999 	    &sym, NULL) == 0 && kp->kp_as ==
1000 	    (struct as *)(uintptr_t)sym.st_value) {
1001 		warn("specified process is a system process (no context)\n");
1002 		goto err;
1003 	}
1004 
1005 	if ((kp->kp_model = f_model((uintptr_t)proc)) == PR_MODEL_UNKNOWN) {
1006 		warn("failed to obtain data model for proc %p\n", proc);
1007 		goto err;
1008 	}
1009 
1010 	if (f_asiter((uintptr_t)kp->kp_as, kp_add_mapping, kp) == -1) {
1011 		warn("failed to load mappings for proc %p", proc);
1012 		goto err;
1013 	}
1014 
1015 	kp->kp_nauxv = f_auxv((uintptr_t)proc, NULL) + 1;
1016 	kp->kp_auxv = mdb_alloc(sizeof (auxv_t) * kp->kp_nauxv, UM_SLEEP);
1017 
1018 	if (f_auxv((uintptr_t)proc, kp->kp_auxv) == -1) {
1019 		warn("failed to load auxv for proc %p", proc);
1020 		goto err;
1021 	}
1022 
1023 	kp->kp_auxv[kp->kp_nauxv - 1].a_type = AT_NULL;
1024 	kp->kp_auxv[kp->kp_nauxv - 1].a_un.a_val = 0;
1025 
1026 	if ((at_entry = kp_getauxval(kp, AT_ENTRY)) == -1L) {
1027 		warn("auxv for proc %p is missing AT_ENTRY\n", proc);
1028 		goto err;
1029 	}
1030 
1031 	if ((at_base = kp_getauxval(kp, AT_BASE)) == -1L) {
1032 		warn("auxv for proc %p is missing AT_BASE\n", proc);
1033 		goto err;
1034 	}
1035 
1036 	/*
1037 	 * If we're applying kproc to a live kernel, we need to force libkvm
1038 	 * to set the current process to the process in question so we can
1039 	 * read from its address space.  If kvm_getproc returns NULL, the
1040 	 * process may have gone away since our previous calls to mdb_ks.
1041 	 */
1042 	if (mdb_prop_postmortem == FALSE &&
1043 	    kvm_getproc(kp->kp_cookie, kp->kp_pid) == NULL)
1044 		warn("failed to attach to PID %d\n", (int)kp->kp_pid);
1045 
1046 	kp->kp_map_exec = kp_addr_to_kpmap(kp, at_entry);
1047 	kp->kp_map_ldso = kp_addr_to_kpmap(kp, at_base);
1048 
1049 	(void) kp_file_create(t, kp->kp_map_exec, ET_EXEC);
1050 	(void) kp_file_create(t, kp->kp_map_ldso, ET_DYN);
1051 
1052 	kp->kp_prfile.kpf_dynsym = mdb.m_prsym;
1053 
1054 	return (0);
1055 
1056 err:
1057 	kp_destroy(t);
1058 	return (-1);
1059 }
1060 
1061 static ssize_t
kp_io_read(mdb_io_t * io,void * buf,size_t nbytes)1062 kp_io_read(mdb_io_t *io, void *buf, size_t nbytes)
1063 {
1064 	kp_io_t *kpi = io->io_data;
1065 	kp_data_t *kp = kpi->kpi_tgt->t_data;
1066 
1067 	kp_map_t *kpm = kp_addr_to_kpmap(kp, kpi->kpi_ptr);
1068 	size_t left;
1069 
1070 	if (kpm != NULL) {
1071 		const mdb_map_t *mp = &kpm->kpm_map;
1072 		left = mp->map_base + mp->map_size - kpi->kpi_ptr;
1073 	} else
1074 		left = 0;
1075 
1076 	if (left != 0) {
1077 		ssize_t rbytes = kp_vread(kpi->kpi_tgt,
1078 		    buf, MIN(nbytes, left), kpi->kpi_ptr);
1079 
1080 		if (rbytes >= 0)
1081 			kpi->kpi_ptr += rbytes;
1082 
1083 		return (rbytes);
1084 	}
1085 
1086 	return (0); /* At end of segment or in hole; return EOF */
1087 }
1088 
1089 static off64_t
kp_io_seek(mdb_io_t * io,off64_t offset,int whence)1090 kp_io_seek(mdb_io_t *io, off64_t offset, int whence)
1091 {
1092 	kp_io_t *kpi = io->io_data;
1093 	const mdb_map_t *mp = &kpi->kpi_map->kpm_map;
1094 	uintptr_t nptr;
1095 
1096 	if (io->io_next != NULL)
1097 		return (IOP_SEEK(io->io_next, offset, whence));
1098 
1099 	switch (whence) {
1100 	case SEEK_SET:
1101 		nptr = mp->map_base + offset;
1102 		break;
1103 	case SEEK_CUR:
1104 		nptr = kpi->kpi_ptr + offset;
1105 		break;
1106 	case SEEK_END:
1107 		nptr = kpi->kpi_lim + offset;
1108 		break;
1109 	default:
1110 		return (set_errno(EINVAL));
1111 	}
1112 
1113 	if (nptr < mp->map_base || nptr >= kpi->kpi_lim)
1114 		return (set_errno(EINVAL));
1115 
1116 	kpi->kpi_ptr = nptr;
1117 	return ((off64_t)(nptr - mp->map_base));
1118 }
1119 
1120 static void
kp_io_close(mdb_io_t * io)1121 kp_io_close(mdb_io_t *io)
1122 {
1123 	mdb_free(io->io_data, sizeof (kp_io_t));
1124 }
1125 
1126 static const char *
kp_io_name(mdb_io_t * io)1127 kp_io_name(mdb_io_t *io)
1128 {
1129 	kp_io_t *kpi = io->io_data;
1130 
1131 	if (io->io_next != NULL)
1132 		return (IOP_NAME(io->io_next));
1133 
1134 	return (kpi->kpi_map->kpm_map.map_name);
1135 }
1136 
1137 static const mdb_io_ops_t kp_io_ops = {
1138 	.io_read = kp_io_read,
1139 	.io_write = no_io_write,
1140 	.io_seek = kp_io_seek,
1141 	.io_ctl = no_io_ctl,
1142 	.io_close = kp_io_close,
1143 	.io_name = kp_io_name,
1144 	.io_link = no_io_link,
1145 	.io_unlink = no_io_unlink,
1146 	.io_setattr = no_io_setattr,
1147 	.io_suspend = no_io_suspend,
1148 	.io_resume = no_io_resume,
1149 };
1150 
1151 static mdb_io_t *
kp_io_create(mdb_tgt_t * t,kp_map_t * kpm)1152 kp_io_create(mdb_tgt_t *t, kp_map_t *kpm)
1153 {
1154 	kp_data_t *kp = t->t_data;
1155 	mdb_map_t *mp = &kp->kp_map_tail->kpm_map;
1156 
1157 	mdb_io_t *io = mdb_alloc(sizeof (mdb_io_t), UM_SLEEP);
1158 	kp_io_t *kpi = mdb_alloc(sizeof (kp_io_t), UM_SLEEP);
1159 
1160 	kpi->kpi_tgt = t;
1161 	kpi->kpi_map = kpm;
1162 	kpi->kpi_ptr = kpm->kpm_map.map_base;
1163 	kpi->kpi_lim = mp->map_base + mp->map_size;
1164 
1165 	io->io_ops = &kp_io_ops;
1166 	io->io_data = kpi;
1167 	io->io_next = NULL;
1168 	io->io_refcnt = 0;
1169 
1170 	return (io);
1171 }
1172