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