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