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 2001-2002 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 #include <sys/time.h>
30 #include <ipp/ipp.h>
31 #include <ipp/ipp_impl.h>
32 #include <mdb/mdb_modapi.h>
33
34 static uintptr_t ipp_mod_byid;
35 static uintptr_t ipp_action_byid;
36
37 static int byid_walk_init(mdb_walk_state_t *);
38 static int byid_walk_step(mdb_walk_state_t *);
39 static void byid_walk_fini(mdb_walk_state_t *);
40
41 static int action(uintptr_t, uint_t, int, const mdb_arg_t *);
42 static int action_format(uintptr_t, const void *, void *);
43 static int action_dump(uintptr_t, ipp_action_t *, boolean_t);
44 static int action_summary(uintptr_t, ipp_action_t *, boolean_t);
45
46 static int cfglock(uintptr_t, uint_t, int, const mdb_arg_t *);
47
48 static int mod(uintptr_t, uint_t, int, const mdb_arg_t *);
49 static int mod_format(uintptr_t, const void *, void *);
50 static int mod_dump(uintptr_t, ipp_mod_t *, boolean_t);
51 static int mod_summary(uintptr_t, ipp_mod_t *, boolean_t);
52 static int cfglock(uintptr_t, uint_t, int, const mdb_arg_t *);
53
54 static int ippops(uintptr_t, uint_t, int, const mdb_arg_t *);
55
56 static int packet(uintptr_t, uint_t, int, const mdb_arg_t *);
57 static void dump_classes(uintptr_t, uint_t);
58 static void dump_log(uintptr_t, uint_t);
59 static void aid2aname(ipp_action_id_t, char *);
60
61 static int ref_walk_init(mdb_walk_state_t *);
62 static int ref_walk_step(mdb_walk_state_t *);
63 static void ref_walk_fini(mdb_walk_state_t *);
64
65 typedef struct afdata {
66 boolean_t af_banner;
67 uint_t af_flags;
68 } afdata_t;
69
70 #define AF_VERBOSE 1
71
72 typedef struct mfdata {
73 boolean_t mf_banner;
74 uint_t mf_flags;
75 } mfdata_t;
76
77 #define MF_VERBOSE 1
78
79 /*
80 * walker. Skips entries that are NULL.
81 */
82
83 static int
byid_walk_init(mdb_walk_state_t * wsp)84 byid_walk_init(
85 mdb_walk_state_t *wsp)
86 {
87 uintptr_t start;
88
89 if (mdb_vread(&start, sizeof (uintptr_t), wsp->walk_addr) == -1) {
90 mdb_warn("failed to read from address %p", wsp->walk_addr);
91 return (WALK_ERR);
92 }
93
94 wsp->walk_addr = start;
95
96 return (WALK_NEXT);
97 }
98
99 static int
byid_walk_step(mdb_walk_state_t * wsp)100 byid_walk_step(
101 mdb_walk_state_t *wsp)
102 {
103 int status;
104 void *ptr;
105
106 if (mdb_vread(&ptr, sizeof (void *), wsp->walk_addr) == -1) {
107 mdb_warn("failed to read from address %p", wsp->walk_addr);
108 return (WALK_ERR);
109 }
110
111 if (ptr == (void *)-1) {
112 status = WALK_DONE;
113 } else if (ptr == NULL) {
114 status = WALK_NEXT;
115 } else {
116 status = wsp->walk_callback((uintptr_t)ptr, NULL,
117 wsp->walk_cbdata);
118 }
119
120 wsp->walk_addr += sizeof (void *);
121
122 return (status);
123 }
124
125 /*ARGSUSED*/
126 static void
byid_walk_fini(mdb_walk_state_t * wsp)127 byid_walk_fini(
128 mdb_walk_state_t *wsp)
129 {
130 }
131
132
133 /*ARGSUSED*/
134 static int
action(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)135 action(
136 uintptr_t addr,
137 uint_t flags,
138 int argc,
139 const mdb_arg_t *argv)
140 {
141 int status;
142 int rc = DCMD_OK;
143 afdata_t *afp;
144
145 afp = mdb_zalloc(sizeof (afdata_t), UM_SLEEP);
146
147 if (mdb_getopts(argc, argv,
148 'v', MDB_OPT_SETBITS, AF_VERBOSE, &afp->af_flags,
149 NULL) != argc)
150 return (DCMD_USAGE);
151
152 if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP))
153 afp->af_banner = B_TRUE;
154
155 if (flags & DCMD_ADDRSPEC) {
156 status = action_format(addr, NULL, afp);
157 rc = (status == WALK_NEXT) ? DCMD_OK : DCMD_ERR;
158 goto cleanup;
159 }
160
161 if (mdb_pwalk("ipp_byid", action_format, afp,
162 ipp_action_byid) == -1) {
163 mdb_warn("failed to execute ipp_byid walk");
164 rc = DCMD_ERR;
165 }
166
167 cleanup:
168 mdb_free(afp, sizeof (afdata_t));
169
170 return (rc);
171 }
172
173 /*ARGSUSED*/
174 static int
action_format(uintptr_t addr,const void * data,void * arg)175 action_format(
176 uintptr_t addr,
177 const void *data,
178 void *arg)
179 {
180 afdata_t *afp = (afdata_t *)arg;
181 ipp_action_t *ap;
182 int rc;
183
184 ap = mdb_alloc(sizeof (ipp_action_t), UM_SLEEP);
185 if (mdb_vread(ap, sizeof (ipp_action_t), addr) == -1) {
186 mdb_warn("failed to read ipp_action_t at %p", addr);
187 rc = WALK_ERR;
188 goto done;
189 }
190
191 if (afp->af_flags & AF_VERBOSE)
192 rc = action_dump(addr, ap, afp->af_banner);
193 else
194 rc = action_summary(addr, ap, afp->af_banner);
195
196 afp->af_banner = B_FALSE;
197 done:
198 mdb_free(ap, sizeof (ipp_action_t));
199 return (rc);
200 }
201
202 /*ARGSUSED*/
203 static int
action_dump(uintptr_t addr,ipp_action_t * ap,boolean_t banner)204 action_dump(
205 uintptr_t addr,
206 ipp_action_t *ap,
207 boolean_t banner)
208 {
209 mdb_printf("%?p: %20s = %d\n", addr, "id", ap->ippa_id);
210 if (!ap->ippa_nameless) {
211 mdb_printf("%?s %20s = %s\n", "", "name", ap->ippa_name);
212 }
213 mdb_printf("%?s %20s = 0x%p\n", "", "mod", ap->ippa_mod);
214 mdb_printf("%?s %20s = 0x%p\n", "", "ref", ap->ippa_ref);
215 mdb_printf("%?s %20s = 0x%p\n", "", "refby", ap->ippa_refby);
216 mdb_printf("%?s %20s = 0x%p\n", "", "ptr", ap->ippa_ptr);
217
218 mdb_printf("%?s %20s = ", "", "state");
219 switch (ap->ippa_state) {
220 case IPP_ASTATE_PROTO:
221 mdb_printf("%s\n", "PROTO");
222 break;
223 case IPP_ASTATE_CONFIG_PENDING:
224 mdb_printf("%s\n", "CONFIG_PENDING");
225 break;
226 case IPP_ASTATE_AVAILABLE:
227 mdb_printf("%s\n", "AVAILABLE");
228 break;
229 default:
230 mdb_printf("%s\n", "<unknown>");
231 break;
232 }
233
234 mdb_printf("%?s %20s = %d\n", "", "packets", ap->ippa_packets);
235 mdb_printf("%?s %20s = %d\n", "", "hold_count", ap->ippa_hold_count);
236 mdb_printf("%?s %20s = %s\n", "", "destruct_pending",
237 (ap->ippa_destruct_pending) ? "TRUE" : "FALSE");
238 mdb_printf("%?s %20s = 0x%p\n", "", "lock",
239 addr + ((uintptr_t)ap->ippa_lock - (uintptr_t)ap));
240 mdb_printf("%?s %20s = 0x%p\n", "", "config_lock",
241 addr + ((uintptr_t)ap->ippa_config_lock - (uintptr_t)ap));
242 mdb_printf("\n");
243
244 return (WALK_NEXT);
245 }
246
247 static int
action_summary(uintptr_t addr,ipp_action_t * ap,boolean_t banner)248 action_summary(
249 uintptr_t addr,
250 ipp_action_t *ap,
251 boolean_t banner)
252 {
253 ipp_mod_t *imp;
254 uintptr_t ptr;
255
256 if (banner)
257 mdb_printf("%?s %<u>%20s %5s %20s%</u>\n",
258 "", "NAME", "ID", "MODNAME");
259
260 imp = mdb_alloc(sizeof (ipp_mod_t), UM_SLEEP);
261 ptr = (uintptr_t)ap->ippa_mod;
262 if (mdb_vread(imp, sizeof (ipp_mod_t), ptr) == -1) {
263 mdb_warn("failed to read ipp_mod_t at %p", ptr);
264 mdb_free(imp, sizeof (ipp_mod_t));
265 return (WALK_ERR);
266 }
267
268 mdb_printf("%?p:%20s %5d %20s\n", addr, ap->ippa_name, ap->ippa_id,
269 imp->ippm_name);
270
271 mdb_free(imp, sizeof (ipp_mod_t));
272 return (WALK_NEXT);
273 }
274
275 /*ARGSUSED*/
276 static int
cfglock(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)277 cfglock(
278 uintptr_t addr,
279 uint_t flags,
280 int argc,
281 const mdb_arg_t *argv)
282 {
283 cfglock_t *clp;
284
285 if ((flags & DCMD_ADDRSPEC) == 0)
286 return (DCMD_ERR);
287
288 clp = mdb_alloc(sizeof (cfglock_t), UM_SLEEP);
289 if (mdb_vread(clp, sizeof (cfglock_t), addr) == -1) {
290 mdb_warn("failed to read cfglock_t at %p", addr);
291 mdb_free(clp, sizeof (cfglock_t));
292 return (WALK_ERR);
293 }
294
295 mdb_printf("%?p: %20s = %p\n", addr, "owner", clp->cl_owner);
296 mdb_printf("%?s %20s = %s\n", "", "reader",
297 clp->cl_reader ? "TRUE" : "FALSE");
298 mdb_printf("%?s %20s = %d\n", "", "writers", clp->cl_writers);
299 mdb_printf("%?s %20s = 0x%p\n", "", "mutex",
300 addr + ((uintptr_t)clp->cl_mutex - (uintptr_t)clp));
301 mdb_printf("%?s %20s = 0x%p\n", "", "cv",
302 addr + ((uintptr_t)clp->cl_cv - (uintptr_t)clp));
303 mdb_printf("\n");
304
305 mdb_free(clp, sizeof (cfglock_t));
306
307 return (DCMD_OK);
308 }
309
310 /*ARGSUSED*/
311 static int
mod(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)312 mod(
313 uintptr_t addr,
314 uint_t flags,
315 int argc,
316 const mdb_arg_t *argv)
317 {
318 int status;
319 int rc = DCMD_OK;
320 mfdata_t *mfp;
321
322 mfp = mdb_zalloc(sizeof (mfdata_t), UM_SLEEP);
323
324 if (mdb_getopts(argc, argv,
325 'v', MDB_OPT_SETBITS, MF_VERBOSE, &mfp->mf_flags,
326 NULL) != argc)
327 return (DCMD_USAGE);
328
329 if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP))
330 mfp->mf_banner = B_TRUE;
331
332 if (flags & DCMD_ADDRSPEC) {
333 status = mod_format(addr, NULL, mfp);
334 rc = (status == WALK_NEXT) ? DCMD_OK : DCMD_ERR;
335 goto cleanup;
336 }
337
338 if (mdb_pwalk("ipp_byid", mod_format, mfp,
339 ipp_mod_byid) == -1) {
340 mdb_warn("failed to execute ipp_byid walk");
341 rc = DCMD_ERR;
342 }
343
344 cleanup:
345 mdb_free(mfp, sizeof (mfdata_t));
346
347 return (rc);
348 }
349
350 /*ARGSUSED*/
351 static int
mod_format(uintptr_t addr,const void * data,void * arg)352 mod_format(
353 uintptr_t addr,
354 const void *data,
355 void *arg)
356 {
357 mfdata_t *mfp = (mfdata_t *)arg;
358 ipp_mod_t *imp;
359 int rc;
360
361 imp = mdb_alloc(sizeof (ipp_mod_t), UM_SLEEP);
362 if (mdb_vread(imp, sizeof (ipp_mod_t), addr) == -1) {
363 mdb_warn("failed to read ipp_mod_t at %p", addr);
364 rc = WALK_ERR;
365 goto done;
366 }
367
368 if (mfp->mf_flags & MF_VERBOSE)
369 rc = mod_dump(addr, imp, mfp->mf_banner);
370 else
371 rc = mod_summary(addr, imp, mfp->mf_banner);
372
373 mfp->mf_banner = B_FALSE;
374 done:
375 mdb_free(imp, sizeof (ipp_mod_t));
376 return (rc);
377 }
378
379 /*ARGSUSED*/
380 static int
mod_dump(uintptr_t addr,ipp_mod_t * imp,boolean_t banner)381 mod_dump(
382 uintptr_t addr,
383 ipp_mod_t *imp,
384 boolean_t banner)
385 {
386 mdb_printf("%?p: %20s = %d\n", addr, "id", imp->ippm_id);
387 mdb_printf("%?s %20s = %s\n", "", "name", imp->ippm_name);
388 mdb_printf("%?s %20s = 0x%p\n", "", "ops", imp->ippm_ops);
389 mdb_printf("%?s %20s = 0x%p\n", "", "action", imp->ippm_action);
390
391 mdb_printf("%?s %20s = ", "", "state");
392 switch (imp->ippm_state) {
393 case IPP_MODSTATE_PROTO:
394 mdb_printf("%s\n", "PROTO");
395 break;
396 case IPP_MODSTATE_AVAILABLE:
397 mdb_printf("%s\n", "AVAILABLE");
398 break;
399 default:
400 mdb_printf("%s\n", "<unknown>");
401 break;
402 }
403
404 mdb_printf("%?s %20s = %d\n", "", "hold_count", imp->ippm_hold_count);
405 mdb_printf("%?s %20s = %s\n", "", "destruct_pending",
406 (imp->ippm_destruct_pending) ? "TRUE" : "FALSE");
407 mdb_printf("%?s %20s = 0x%p\n", "", "lock",
408 addr + ((uintptr_t)imp->ippm_lock - (uintptr_t)imp));
409 mdb_printf("\n");
410
411 return (WALK_NEXT);
412 }
413
414 static int
mod_summary(uintptr_t addr,ipp_mod_t * imp,boolean_t banner)415 mod_summary(
416 uintptr_t addr,
417 ipp_mod_t *imp,
418 boolean_t banner)
419 {
420 if (banner)
421 mdb_printf("%?s %<u>%20s %5s%</u>\n",
422 "", "NAME", "ID");
423
424 mdb_printf("%?p:%20s %5d\n", addr, imp->ippm_name, imp->ippm_id);
425
426 return (WALK_NEXT);
427 }
428
429 /*ARGSUSED*/
430 static int
ippops(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)431 ippops(
432 uintptr_t addr,
433 uint_t flags,
434 int argc,
435 const mdb_arg_t *argv)
436 {
437 ipp_ops_t *ippo;
438 GElf_Sym sym;
439 char buf[MDB_SYM_NAMLEN];
440
441 if ((flags & DCMD_ADDRSPEC) == 0)
442 return (DCMD_ERR);
443
444 ippo = mdb_alloc(sizeof (ipp_ops_t), UM_SLEEP);
445 if (mdb_vread(ippo, sizeof (ipp_ops_t), addr) == -1) {
446 mdb_warn("failed to read ipp_ops_t at %p", addr);
447 mdb_free(ippo, sizeof (ipp_ops_t));
448 return (DCMD_ERR);
449 }
450
451 mdb_printf("%?p: %20s = %d\n", addr, "rev", ippo->ippo_rev);
452
453 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_create,
454 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0)
455 mdb_printf("%?s %20s = %s\n", "", "action_create", buf);
456 else
457 mdb_printf("%?s %20s = 0x%p\n", "", "action_create",
458 ippo->ippo_action_create);
459
460 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_modify,
461 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0)
462 mdb_printf("%?s %20s = %s\n", "", "action_modify", buf);
463 else
464 mdb_printf("%?s %20s = 0x%p\n", "", "action_modify",
465 ippo->ippo_action_modify);
466
467 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_destroy,
468 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0)
469 mdb_printf("%?s %20s = %s\n", "", "action_destroy", buf);
470 else
471 mdb_printf("%?s %20s = 0x%p\n", "", "action_destroy",
472 ippo->ippo_action_destroy);
473
474 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_info,
475 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0)
476 mdb_printf("%?s %20s = %s\n", "", "action_info", buf);
477 else
478 mdb_printf("%?s %20s = 0x%p\n", "", "action_info",
479 ippo->ippo_action_info);
480
481 if (mdb_lookup_by_addr((uintptr_t)ippo->ippo_action_invoke,
482 MDB_SYM_EXACT, buf, MDB_SYM_NAMLEN, &sym) == 0)
483 mdb_printf("%?s %20s = %s\n", "", "action_invoke", buf);
484 else
485 mdb_printf("%?s %20s = 0x%p\n", "", "action_invoke",
486 ippo->ippo_action_invoke);
487
488 mdb_printf("\n");
489
490 mdb_free(ippo, sizeof (ipp_ops_t));
491 return (DCMD_OK);
492 }
493
494 static int
ref_walk_init(mdb_walk_state_t * wsp)495 ref_walk_init(
496 mdb_walk_state_t *wsp)
497 {
498 if (wsp->walk_addr == NULL)
499 return (WALK_DONE);
500
501 return (WALK_NEXT);
502 }
503
504 static int
ref_walk_step(mdb_walk_state_t * wsp)505 ref_walk_step(
506 mdb_walk_state_t *wsp)
507 {
508 ipp_ref_t *rp;
509 int status;
510
511 if (wsp->walk_addr == NULL)
512 return (WALK_DONE);
513
514 rp = mdb_alloc(sizeof (ipp_ref_t), UM_SLEEP);
515
516 if (mdb_vread(rp, sizeof (ipp_ref_t), wsp->walk_addr) == -1) {
517 mdb_warn("failed to read ipp_ref_t at %p", wsp->walk_addr);
518 mdb_free(rp, sizeof (ipp_ref_t));
519 return (WALK_ERR);
520 }
521
522 status = wsp->walk_callback((uintptr_t)rp->ippr_ptr, NULL,
523 wsp->walk_cbdata);
524
525 wsp->walk_addr = (uintptr_t)(rp->ippr_nextp);
526
527 mdb_free(rp, sizeof (ipp_ref_t));
528 return (status);
529 }
530
531 /*ARGSUSED*/
532 static void
ref_walk_fini(mdb_walk_state_t * wsp)533 ref_walk_fini(
534 mdb_walk_state_t *wsp)
535 {
536 }
537
538 /*ARGSUSED*/
539 static int
packet(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)540 packet(
541 uintptr_t addr,
542 uint_t flags,
543 int argc,
544 const mdb_arg_t *argv)
545 {
546 ipp_packet_t *pp;
547
548 if ((flags & DCMD_ADDRSPEC) == 0)
549 return (DCMD_ERR);
550
551 pp = mdb_alloc(sizeof (ipp_packet_t), UM_SLEEP);
552 if (mdb_vread(pp, sizeof (ipp_packet_t), addr) == -1) {
553 mdb_warn("failed to read ipp_packet_t at %p", addr);
554 mdb_free(pp, sizeof (ipp_packet_t));
555 return (DCMD_ERR);
556 }
557
558 mdb_printf("%?p: %20s = 0x%p\n", addr, "data", pp->ippp_data);
559 mdb_printf("%?s %20s = 0x%p\n", "", "private", pp->ippp_private);
560 dump_classes((uintptr_t)pp->ippp_class_array, pp->ippp_class_windex);
561 dump_log((uintptr_t)pp->ippp_log, pp->ippp_log_windex);
562
563 mdb_free(pp, sizeof (ipp_packet_t));
564 return (DCMD_OK);
565 }
566
567 static void
dump_classes(uintptr_t ptr,uint_t nelt)568 dump_classes(
569 uintptr_t ptr,
570 uint_t nelt)
571 {
572 ipp_class_t *array;
573 ipp_class_t *cp;
574 uint_t i;
575 boolean_t first_time = B_TRUE;
576 char buf[MAXNAMELEN];
577
578 array = mdb_alloc(sizeof (ipp_class_t) * nelt, UM_SLEEP);
579 if (mdb_vread(array, sizeof (ipp_class_t) * nelt, ptr) == -1) {
580 mdb_warn("failed to read ipp_class_t array at %p", ptr);
581 return;
582 }
583
584 for (i = 0; i < nelt; i++) {
585 if (first_time) {
586 mdb_printf("%20s %?s %<u>%15s %15s%</u>\n", "",
587 "classes", "NAME", "ACTION");
588 first_time = B_FALSE;
589 }
590
591 cp = &(array[i]);
592 aid2aname(cp->ippc_aid, buf);
593 mdb_printf("%20s %?p: %15s %15s%\n", "",
594 ptr + (i * sizeof (ipp_class_t)), cp->ippc_name, buf);
595 }
596
597 mdb_free(cp, sizeof (ipp_class_t) * nelt);
598 }
599
600 static void
dump_log(uintptr_t ptr,uint_t nelt)601 dump_log(
602 uintptr_t ptr,
603 uint_t nelt)
604 {
605 ipp_log_t *array;
606 ipp_log_t *lp;
607 uint_t i;
608 boolean_t first_time = B_TRUE;
609 char buf[MAXNAMELEN];
610
611 array = mdb_alloc(sizeof (ipp_log_t) * nelt, UM_SLEEP);
612 if (mdb_vread(array, sizeof (ipp_log_t) * nelt, ptr) == -1) {
613 mdb_warn("failed to read ipp_log_t array at %p", ptr);
614 return;
615 }
616
617 for (i = 0; i < nelt; i++) {
618 if (first_time) {
619 mdb_printf("%20s %?s %<u>%15s %15s%</u>\n", "",
620 "log", "CLASS NAME", "ACTION");
621 first_time = B_FALSE;
622 }
623
624 lp = &(array[i]);
625 aid2aname(lp->ippl_aid, buf);
626 mdb_printf("%20s %?p: %15s %15s\n", "",
627 ptr + (i * sizeof (ipp_class_t)), lp->ippl_name, buf);
628 }
629
630 mdb_free(lp, sizeof (ipp_log_t) * nelt);
631 }
632
633 static void
aid2aname(ipp_action_id_t aid,char * buf)634 aid2aname(
635 ipp_action_id_t aid,
636 char *buf)
637 {
638 uintptr_t addr;
639 uintptr_t ptr;
640 ipp_action_t *ap;
641
642 switch (aid) {
643 case IPP_ACTION_INVAL:
644 strcpy(buf, "invalid");
645 break;
646 case IPP_ACTION_CONT:
647 strcpy(buf, "continue");
648 break;
649 case IPP_ACTION_DEFER:
650 strcpy(buf, "defer");
651 break;
652 case IPP_ACTION_DROP:
653 strcpy(buf, "drop");
654 break;
655 default:
656 if (mdb_vread(&addr, sizeof (uintptr_t),
657 ipp_action_byid) == -1) {
658 mdb_warn("failed to read from address %p",
659 ipp_action_byid);
660 strcpy(buf, "???");
661 break;
662 }
663
664 addr += ((int32_t)aid * sizeof (void *));
665 if (mdb_vread(&ptr, sizeof (uintptr_t), addr) == -1) {
666 mdb_warn("failed to read from address %p", addr);
667 strcpy(buf, "???");
668 break;
669 }
670
671 ap = mdb_alloc(sizeof (ipp_action_t), UM_SLEEP);
672 if (mdb_vread(ap, sizeof (ipp_action_t), ptr) == -1) {
673 mdb_warn("failed to read ipp_action_t at %p", ptr);
674 mdb_free(ap, sizeof (ipp_action_t));
675 strcpy(buf, "???");
676 break;
677 }
678
679 if (ap->ippa_id != aid) {
680 mdb_warn("corrupt action at %p", ptr);
681 mdb_free(ap, sizeof (ipp_action_t));
682 strcpy(buf, "???");
683 break;
684 }
685
686 strcpy(buf, ap->ippa_name);
687 }
688 }
689
690 static const mdb_dcmd_t dcmds[] = {
691 { "ipp_action", "?[-v]",
692 "display ipp_action structure", action },
693 { "ipp_mod", "?[-v]",
694 "display ipp_mod structure", mod },
695 { "cfglock", ":",
696 "display cfglock structure", cfglock },
697 { "ippops", ":",
698 "display ipp_ops structure", ippops },
699 { "ipp_packet", ":",
700 "display ipp_packet structure", packet },
701 { NULL }
702 };
703
704 static const mdb_walker_t walkers[] = {
705 { "ipp_byid", "walk byid array", byid_walk_init, byid_walk_step,
706 byid_walk_fini },
707 { "ipp_ref", "walk reference list", ref_walk_init, ref_walk_step,
708 ref_walk_fini },
709 { NULL }
710 };
711
712 static const mdb_modinfo_t ipp_modinfo = { MDB_API_VERSION, dcmds, walkers };
713
714 const mdb_modinfo_t *
_mdb_init(void)715 _mdb_init(void)
716 {
717 GElf_Sym sym;
718
719 if (mdb_lookup_by_name("ipp_action_byid", &sym) == -1) {
720 mdb_warn("failed to lookup 'ipp_action_byid'");
721 return (NULL);
722 }
723
724 ipp_action_byid = (uintptr_t)sym.st_value;
725
726 if (mdb_lookup_by_name("ipp_mod_byid", &sym) == -1) {
727 mdb_warn("failed to lookup 'ipp_mod_byid'");
728 return (NULL);
729 }
730
731 ipp_mod_byid = (uintptr_t)sym.st_value;
732
733 return (&ipp_modinfo);
734 }
735