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