1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include <sys/types.h>
30*0Sstevel@tonic-gate #include <sys/sysmacros.h>
31*0Sstevel@tonic-gate #include <sys/dditypes.h>
32*0Sstevel@tonic-gate #include <sys/ddi_impldefs.h>
33*0Sstevel@tonic-gate #include <sys/ddipropdefs.h>
34*0Sstevel@tonic-gate #include <sys/modctl.h>
35*0Sstevel@tonic-gate #include <sys/file.h>
36*0Sstevel@tonic-gate #include <sys/sunldi_impl.h>
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
39*0Sstevel@tonic-gate #include <mdb/mdb_ks.h>
40*0Sstevel@tonic-gate
41*0Sstevel@tonic-gate #include "ldi.h"
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gate /*
44*0Sstevel@tonic-gate * ldi handle walker structure
45*0Sstevel@tonic-gate */
46*0Sstevel@tonic-gate typedef struct lh_walk {
47*0Sstevel@tonic-gate struct ldi_handle **hash; /* current bucket pointer */
48*0Sstevel@tonic-gate struct ldi_handle *lhp; /* ldi handle pointer */
49*0Sstevel@tonic-gate size_t index; /* hash table index */
50*0Sstevel@tonic-gate struct ldi_handle buf; /* buffer used for handle reads */
51*0Sstevel@tonic-gate } lh_walk_t;
52*0Sstevel@tonic-gate
53*0Sstevel@tonic-gate /*
54*0Sstevel@tonic-gate * ldi identifier walker structure
55*0Sstevel@tonic-gate */
56*0Sstevel@tonic-gate typedef struct li_walk {
57*0Sstevel@tonic-gate struct ldi_ident **hash; /* current bucket pointer */
58*0Sstevel@tonic-gate struct ldi_ident *lip; /* ldi handle pointer */
59*0Sstevel@tonic-gate size_t index; /* hash table index */
60*0Sstevel@tonic-gate struct ldi_ident buf; /* buffer used for ident reads */
61*0Sstevel@tonic-gate } li_walk_t;
62*0Sstevel@tonic-gate
63*0Sstevel@tonic-gate /*
64*0Sstevel@tonic-gate * Options for ldi_handles dcmd
65*0Sstevel@tonic-gate */
66*0Sstevel@tonic-gate #define LH_IDENTINFO 0x1
67*0Sstevel@tonic-gate
68*0Sstevel@tonic-gate /*
69*0Sstevel@tonic-gate * LDI walkers
70*0Sstevel@tonic-gate */
71*0Sstevel@tonic-gate int
ldi_handle_walk_init(mdb_walk_state_t * wsp)72*0Sstevel@tonic-gate ldi_handle_walk_init(mdb_walk_state_t *wsp)
73*0Sstevel@tonic-gate {
74*0Sstevel@tonic-gate lh_walk_t *lhwp;
75*0Sstevel@tonic-gate GElf_Sym sym;
76*0Sstevel@tonic-gate
77*0Sstevel@tonic-gate /* get the address of the hash table */
78*0Sstevel@tonic-gate if (mdb_lookup_by_name("ldi_handle_hash", &sym) == -1) {
79*0Sstevel@tonic-gate mdb_warn("couldn't find ldi_handle_hash");
80*0Sstevel@tonic-gate return (WALK_ERR);
81*0Sstevel@tonic-gate }
82*0Sstevel@tonic-gate
83*0Sstevel@tonic-gate lhwp = mdb_alloc(sizeof (lh_walk_t), UM_SLEEP|UM_GC);
84*0Sstevel@tonic-gate lhwp->hash = (struct ldi_handle **)(uintptr_t)sym.st_value;
85*0Sstevel@tonic-gate lhwp->index = 0;
86*0Sstevel@tonic-gate
87*0Sstevel@tonic-gate /* get the address of the first element in the first hash bucket */
88*0Sstevel@tonic-gate if ((mdb_vread(&lhwp->lhp, sizeof (struct ldi_handle *),
89*0Sstevel@tonic-gate (uintptr_t)lhwp->hash)) == -1) {
90*0Sstevel@tonic-gate mdb_warn("couldn't read ldi handle hash at %p", lhwp->hash);
91*0Sstevel@tonic-gate return (WALK_ERR);
92*0Sstevel@tonic-gate }
93*0Sstevel@tonic-gate
94*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)lhwp->lhp;
95*0Sstevel@tonic-gate wsp->walk_data = lhwp;
96*0Sstevel@tonic-gate
97*0Sstevel@tonic-gate return (WALK_NEXT);
98*0Sstevel@tonic-gate }
99*0Sstevel@tonic-gate
100*0Sstevel@tonic-gate int
ldi_handle_walk_step(mdb_walk_state_t * wsp)101*0Sstevel@tonic-gate ldi_handle_walk_step(mdb_walk_state_t *wsp)
102*0Sstevel@tonic-gate {
103*0Sstevel@tonic-gate lh_walk_t *lhwp = (lh_walk_t *)wsp->walk_data;
104*0Sstevel@tonic-gate int status;
105*0Sstevel@tonic-gate
106*0Sstevel@tonic-gate /* check if we need to go to the next hash bucket */
107*0Sstevel@tonic-gate while (wsp->walk_addr == NULL) {
108*0Sstevel@tonic-gate
109*0Sstevel@tonic-gate /* advance to the next bucket */
110*0Sstevel@tonic-gate if (++(lhwp->index) >= LH_HASH_SZ)
111*0Sstevel@tonic-gate return (WALK_DONE);
112*0Sstevel@tonic-gate
113*0Sstevel@tonic-gate /* get handle address from the hash bucket */
114*0Sstevel@tonic-gate if ((mdb_vread(&lhwp->lhp, sizeof (struct ldi_handle *),
115*0Sstevel@tonic-gate (uintptr_t)(lhwp->hash + lhwp->index))) == -1) {
116*0Sstevel@tonic-gate mdb_warn("couldn't read ldi handle hash at %p",
117*0Sstevel@tonic-gate (uintptr_t)lhwp->hash + lhwp->index);
118*0Sstevel@tonic-gate return (WALK_ERR);
119*0Sstevel@tonic-gate }
120*0Sstevel@tonic-gate
121*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)lhwp->lhp;
122*0Sstevel@tonic-gate }
123*0Sstevel@tonic-gate
124*0Sstevel@tonic-gate /* invoke the walker callback for this hash element */
125*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, NULL, wsp->walk_cbdata);
126*0Sstevel@tonic-gate if (status != WALK_NEXT)
127*0Sstevel@tonic-gate return (status);
128*0Sstevel@tonic-gate
129*0Sstevel@tonic-gate /* get a pointer to the next hash element */
130*0Sstevel@tonic-gate if (mdb_vread(&lhwp->buf, sizeof (struct ldi_handle),
131*0Sstevel@tonic-gate wsp->walk_addr) == -1) {
132*0Sstevel@tonic-gate mdb_warn("couldn't read ldi handle at %p", wsp->walk_addr);
133*0Sstevel@tonic-gate return (WALK_ERR);
134*0Sstevel@tonic-gate }
135*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)lhwp->buf.lh_next;
136*0Sstevel@tonic-gate return (WALK_NEXT);
137*0Sstevel@tonic-gate }
138*0Sstevel@tonic-gate
139*0Sstevel@tonic-gate int
ldi_ident_walk_init(mdb_walk_state_t * wsp)140*0Sstevel@tonic-gate ldi_ident_walk_init(mdb_walk_state_t *wsp)
141*0Sstevel@tonic-gate {
142*0Sstevel@tonic-gate li_walk_t *liwp;
143*0Sstevel@tonic-gate GElf_Sym sym;
144*0Sstevel@tonic-gate
145*0Sstevel@tonic-gate /* get the address of the hash table */
146*0Sstevel@tonic-gate if (mdb_lookup_by_name("ldi_ident_hash", &sym) == -1) {
147*0Sstevel@tonic-gate mdb_warn("couldn't find ldi_ident_hash");
148*0Sstevel@tonic-gate return (WALK_ERR);
149*0Sstevel@tonic-gate }
150*0Sstevel@tonic-gate
151*0Sstevel@tonic-gate liwp = mdb_alloc(sizeof (li_walk_t), UM_SLEEP|UM_GC);
152*0Sstevel@tonic-gate liwp->hash = (struct ldi_ident **)(uintptr_t)sym.st_value;
153*0Sstevel@tonic-gate liwp->index = 0;
154*0Sstevel@tonic-gate
155*0Sstevel@tonic-gate /* get the address of the first element in the first hash bucket */
156*0Sstevel@tonic-gate if ((mdb_vread(&liwp->lip, sizeof (struct ldi_ident *),
157*0Sstevel@tonic-gate (uintptr_t)liwp->hash)) == -1) {
158*0Sstevel@tonic-gate mdb_warn("couldn't read ldi ident hash at %p", liwp->hash);
159*0Sstevel@tonic-gate return (WALK_ERR);
160*0Sstevel@tonic-gate }
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)liwp->lip;
163*0Sstevel@tonic-gate wsp->walk_data = liwp;
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gate return (WALK_NEXT);
166*0Sstevel@tonic-gate }
167*0Sstevel@tonic-gate
168*0Sstevel@tonic-gate int
ldi_ident_walk_step(mdb_walk_state_t * wsp)169*0Sstevel@tonic-gate ldi_ident_walk_step(mdb_walk_state_t *wsp)
170*0Sstevel@tonic-gate {
171*0Sstevel@tonic-gate li_walk_t *liwp = (li_walk_t *)wsp->walk_data;
172*0Sstevel@tonic-gate int status;
173*0Sstevel@tonic-gate
174*0Sstevel@tonic-gate /* check if we need to go to the next hash bucket */
175*0Sstevel@tonic-gate while (wsp->walk_addr == NULL) {
176*0Sstevel@tonic-gate
177*0Sstevel@tonic-gate /* advance to the next bucket */
178*0Sstevel@tonic-gate if (++(liwp->index) >= LI_HASH_SZ)
179*0Sstevel@tonic-gate return (WALK_DONE);
180*0Sstevel@tonic-gate
181*0Sstevel@tonic-gate /* get handle address from the hash bucket */
182*0Sstevel@tonic-gate if ((mdb_vread(&liwp->lip, sizeof (struct ldi_ident *),
183*0Sstevel@tonic-gate (uintptr_t)(liwp->hash + liwp->index))) == -1) {
184*0Sstevel@tonic-gate mdb_warn("couldn't read ldi ident hash at %p",
185*0Sstevel@tonic-gate (uintptr_t)liwp->hash + liwp->index);
186*0Sstevel@tonic-gate return (WALK_ERR);
187*0Sstevel@tonic-gate }
188*0Sstevel@tonic-gate
189*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)liwp->lip;
190*0Sstevel@tonic-gate }
191*0Sstevel@tonic-gate
192*0Sstevel@tonic-gate /* invoke the walker callback for this hash element */
193*0Sstevel@tonic-gate status = wsp->walk_callback(wsp->walk_addr, NULL, wsp->walk_cbdata);
194*0Sstevel@tonic-gate if (status != WALK_NEXT)
195*0Sstevel@tonic-gate return (status);
196*0Sstevel@tonic-gate
197*0Sstevel@tonic-gate /* get a pointer to the next hash element */
198*0Sstevel@tonic-gate if (mdb_vread(&liwp->buf, sizeof (struct ldi_ident),
199*0Sstevel@tonic-gate wsp->walk_addr) == -1) {
200*0Sstevel@tonic-gate mdb_warn("couldn't read ldi ident at %p", wsp->walk_addr);
201*0Sstevel@tonic-gate return (WALK_ERR);
202*0Sstevel@tonic-gate }
203*0Sstevel@tonic-gate wsp->walk_addr = (uintptr_t)liwp->buf.li_next;
204*0Sstevel@tonic-gate return (WALK_NEXT);
205*0Sstevel@tonic-gate }
206*0Sstevel@tonic-gate
207*0Sstevel@tonic-gate /*
208*0Sstevel@tonic-gate * LDI dcmds
209*0Sstevel@tonic-gate */
210*0Sstevel@tonic-gate static void
ldi_ident_header(int start,int refs)211*0Sstevel@tonic-gate ldi_ident_header(int start, int refs)
212*0Sstevel@tonic-gate {
213*0Sstevel@tonic-gate if (start) {
214*0Sstevel@tonic-gate mdb_printf("%-?s ", "IDENT");
215*0Sstevel@tonic-gate } else {
216*0Sstevel@tonic-gate mdb_printf("%?s ", "IDENT");
217*0Sstevel@tonic-gate }
218*0Sstevel@tonic-gate
219*0Sstevel@tonic-gate if (refs)
220*0Sstevel@tonic-gate mdb_printf("%4s ", "REFS");
221*0Sstevel@tonic-gate
222*0Sstevel@tonic-gate mdb_printf("%?s %5s %5s %s\n", "DIP", "MINOR", "MODID", "MODULE NAME");
223*0Sstevel@tonic-gate }
224*0Sstevel@tonic-gate
225*0Sstevel@tonic-gate static int
ldi_ident_print(uintptr_t addr,int refs)226*0Sstevel@tonic-gate ldi_ident_print(uintptr_t addr, int refs)
227*0Sstevel@tonic-gate {
228*0Sstevel@tonic-gate struct ldi_ident li;
229*0Sstevel@tonic-gate
230*0Sstevel@tonic-gate /* read the ldi ident */
231*0Sstevel@tonic-gate if (mdb_vread(&li, sizeof (struct ldi_ident), addr) == -1) {
232*0Sstevel@tonic-gate mdb_warn("couldn't read ldi ident at %p", addr);
233*0Sstevel@tonic-gate return (1);
234*0Sstevel@tonic-gate }
235*0Sstevel@tonic-gate
236*0Sstevel@tonic-gate /* display the ident address */
237*0Sstevel@tonic-gate mdb_printf("%0?p ", addr);
238*0Sstevel@tonic-gate
239*0Sstevel@tonic-gate /* display the ref count */
240*0Sstevel@tonic-gate if (refs)
241*0Sstevel@tonic-gate mdb_printf("%4u ", li.li_ref);
242*0Sstevel@tonic-gate
243*0Sstevel@tonic-gate /* display the dip (if any) */
244*0Sstevel@tonic-gate if (li.li_dip != NULL) {
245*0Sstevel@tonic-gate mdb_printf("%0?p ", li.li_dip);
246*0Sstevel@tonic-gate } else {
247*0Sstevel@tonic-gate mdb_printf("%?s ", "-");
248*0Sstevel@tonic-gate }
249*0Sstevel@tonic-gate
250*0Sstevel@tonic-gate /* display the minor node (if any) */
251*0Sstevel@tonic-gate if (li.li_dev != DDI_DEV_T_NONE) {
252*0Sstevel@tonic-gate mdb_printf("%5u ", getminor(li.li_dev));
253*0Sstevel@tonic-gate } else {
254*0Sstevel@tonic-gate mdb_printf("%5s ", "-");
255*0Sstevel@tonic-gate }
256*0Sstevel@tonic-gate
257*0Sstevel@tonic-gate /* display the module info */
258*0Sstevel@tonic-gate mdb_printf("%5d %s\n", li.li_modid, li.li_modname);
259*0Sstevel@tonic-gate
260*0Sstevel@tonic-gate return (0);
261*0Sstevel@tonic-gate }
262*0Sstevel@tonic-gate
263*0Sstevel@tonic-gate int
ldi_ident(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)264*0Sstevel@tonic-gate ldi_ident(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
265*0Sstevel@tonic-gate {
266*0Sstevel@tonic-gate int start = 1;
267*0Sstevel@tonic-gate int refs = 1;
268*0Sstevel@tonic-gate
269*0Sstevel@tonic-gate /* Determine if there is an ldi identifier address */
270*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
271*0Sstevel@tonic-gate if (mdb_walk_dcmd("ldi_ident", "ldi_ident",
272*0Sstevel@tonic-gate argc, argv) == -1) {
273*0Sstevel@tonic-gate mdb_warn("can't walk ldi idents");
274*0Sstevel@tonic-gate return (DCMD_ERR);
275*0Sstevel@tonic-gate }
276*0Sstevel@tonic-gate return (DCMD_OK);
277*0Sstevel@tonic-gate }
278*0Sstevel@tonic-gate
279*0Sstevel@tonic-gate /* display the header line */
280*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags))
281*0Sstevel@tonic-gate ldi_ident_header(start, refs);
282*0Sstevel@tonic-gate
283*0Sstevel@tonic-gate /* display the ldi ident */
284*0Sstevel@tonic-gate if (ldi_ident_print(addr, refs))
285*0Sstevel@tonic-gate return (DCMD_ERR);
286*0Sstevel@tonic-gate
287*0Sstevel@tonic-gate return (DCMD_OK);
288*0Sstevel@tonic-gate }
289*0Sstevel@tonic-gate
290*0Sstevel@tonic-gate static void
ldi_handle_header(int refs,int ident)291*0Sstevel@tonic-gate ldi_handle_header(int refs, int ident) {
292*0Sstevel@tonic-gate mdb_printf("%-?s ", "HANDLE");
293*0Sstevel@tonic-gate
294*0Sstevel@tonic-gate if (refs)
295*0Sstevel@tonic-gate mdb_printf("%4s ", "REFS");
296*0Sstevel@tonic-gate
297*0Sstevel@tonic-gate mdb_printf("%?s %10s %5s %?s ", "VNODE", "DRV", "MINOR", "EVENTS");
298*0Sstevel@tonic-gate
299*0Sstevel@tonic-gate if (!ident) {
300*0Sstevel@tonic-gate mdb_printf("%?s\n", "IDENT");
301*0Sstevel@tonic-gate } else {
302*0Sstevel@tonic-gate ldi_ident_header(0, 0);
303*0Sstevel@tonic-gate }
304*0Sstevel@tonic-gate }
305*0Sstevel@tonic-gate
306*0Sstevel@tonic-gate static int
ldi_handle_print(uintptr_t addr,int ident,int refs)307*0Sstevel@tonic-gate ldi_handle_print(uintptr_t addr, int ident, int refs)
308*0Sstevel@tonic-gate {
309*0Sstevel@tonic-gate vnode_t vnode;
310*0Sstevel@tonic-gate struct ldi_handle lh;
311*0Sstevel@tonic-gate const char *name;
312*0Sstevel@tonic-gate
313*0Sstevel@tonic-gate /* read in the ldi handle */
314*0Sstevel@tonic-gate if (mdb_vread(&lh, sizeof (struct ldi_handle), addr) == -1) {
315*0Sstevel@tonic-gate mdb_warn("couldn't read ldi handle at %p", addr);
316*0Sstevel@tonic-gate return (DCMD_ERR);
317*0Sstevel@tonic-gate }
318*0Sstevel@tonic-gate
319*0Sstevel@tonic-gate /* display the handle address */
320*0Sstevel@tonic-gate mdb_printf("%0?p ", addr);
321*0Sstevel@tonic-gate
322*0Sstevel@tonic-gate /* display the ref count */
323*0Sstevel@tonic-gate if (refs)
324*0Sstevel@tonic-gate mdb_printf("%4u ", lh.lh_ref);
325*0Sstevel@tonic-gate
326*0Sstevel@tonic-gate /* display the vnode */
327*0Sstevel@tonic-gate mdb_printf("%0?p ", lh.lh_vp);
328*0Sstevel@tonic-gate
329*0Sstevel@tonic-gate /* read in the vnode associated with the handle */
330*0Sstevel@tonic-gate addr = (uintptr_t)lh.lh_vp;
331*0Sstevel@tonic-gate if (mdb_vread(&vnode, sizeof (vnode_t), addr) == -1) {
332*0Sstevel@tonic-gate mdb_warn("couldn't read vnode at %p", addr);
333*0Sstevel@tonic-gate return (1);
334*0Sstevel@tonic-gate }
335*0Sstevel@tonic-gate
336*0Sstevel@tonic-gate /* display the driver name */
337*0Sstevel@tonic-gate if ((name = mdb_major_to_name(getmajor(vnode.v_rdev))) == NULL) {
338*0Sstevel@tonic-gate mdb_warn("failed to convert major number to name\n");
339*0Sstevel@tonic-gate return (1);
340*0Sstevel@tonic-gate }
341*0Sstevel@tonic-gate mdb_printf("%10s ", name);
342*0Sstevel@tonic-gate
343*0Sstevel@tonic-gate /* display the minor number */
344*0Sstevel@tonic-gate mdb_printf("%5d ", getminor(vnode.v_rdev));
345*0Sstevel@tonic-gate
346*0Sstevel@tonic-gate /* display the event pointer (if any) */
347*0Sstevel@tonic-gate if (lh.lh_events != NULL) {
348*0Sstevel@tonic-gate mdb_printf("%0?p ", lh.lh_events);
349*0Sstevel@tonic-gate } else {
350*0Sstevel@tonic-gate mdb_printf("%?s ", "-");
351*0Sstevel@tonic-gate }
352*0Sstevel@tonic-gate
353*0Sstevel@tonic-gate if (!ident) {
354*0Sstevel@tonic-gate /* display the ident address */
355*0Sstevel@tonic-gate mdb_printf("%0?p\n", lh.lh_ident);
356*0Sstevel@tonic-gate return (0);
357*0Sstevel@tonic-gate }
358*0Sstevel@tonic-gate
359*0Sstevel@tonic-gate /* display the entire ident */
360*0Sstevel@tonic-gate return (ldi_ident_print((uintptr_t)lh.lh_ident, refs));
361*0Sstevel@tonic-gate }
362*0Sstevel@tonic-gate
363*0Sstevel@tonic-gate int
ldi_handle(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)364*0Sstevel@tonic-gate ldi_handle(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
365*0Sstevel@tonic-gate {
366*0Sstevel@tonic-gate int ident = 0;
367*0Sstevel@tonic-gate int refs = 1;
368*0Sstevel@tonic-gate
369*0Sstevel@tonic-gate if (mdb_getopts(argc, argv,
370*0Sstevel@tonic-gate 'i', MDB_OPT_SETBITS, TRUE, &ident) != argc)
371*0Sstevel@tonic-gate return (DCMD_USAGE);
372*0Sstevel@tonic-gate
373*0Sstevel@tonic-gate if (ident)
374*0Sstevel@tonic-gate refs = 0;
375*0Sstevel@tonic-gate
376*0Sstevel@tonic-gate /* Determine if there is an ldi handle address */
377*0Sstevel@tonic-gate if (!(flags & DCMD_ADDRSPEC)) {
378*0Sstevel@tonic-gate if (mdb_walk_dcmd("ldi_handle", "ldi_handle",
379*0Sstevel@tonic-gate argc, argv) == -1) {
380*0Sstevel@tonic-gate mdb_warn("can't walk ldi handles");
381*0Sstevel@tonic-gate return (DCMD_ERR);
382*0Sstevel@tonic-gate } return (DCMD_OK);
383*0Sstevel@tonic-gate }
384*0Sstevel@tonic-gate
385*0Sstevel@tonic-gate /* display the header line */
386*0Sstevel@tonic-gate if (DCMD_HDRSPEC(flags))
387*0Sstevel@tonic-gate ldi_handle_header(refs, ident);
388*0Sstevel@tonic-gate
389*0Sstevel@tonic-gate /* display the ldi handle */
390*0Sstevel@tonic-gate if (ldi_handle_print(addr, ident, refs))
391*0Sstevel@tonic-gate return (DCMD_ERR);
392*0Sstevel@tonic-gate
393*0Sstevel@tonic-gate return (DCMD_OK);
394*0Sstevel@tonic-gate }
395*0Sstevel@tonic-gate
396*0Sstevel@tonic-gate void
ldi_ident_help(void)397*0Sstevel@tonic-gate ldi_ident_help(void)
398*0Sstevel@tonic-gate {
399*0Sstevel@tonic-gate mdb_printf("Displays an ldi identifier.\n"
400*0Sstevel@tonic-gate "Without the address of an \"ldi_ident_t\", "
401*0Sstevel@tonic-gate "print all identifiers.\n"
402*0Sstevel@tonic-gate "With an address, print the specified identifier.\n");
403*0Sstevel@tonic-gate }
404*0Sstevel@tonic-gate
405*0Sstevel@tonic-gate void
ldi_handle_help(void)406*0Sstevel@tonic-gate ldi_handle_help(void)
407*0Sstevel@tonic-gate {
408*0Sstevel@tonic-gate mdb_printf("Displays an ldi handle.\n"
409*0Sstevel@tonic-gate "Without the address of an \"ldi_handle_t\", "
410*0Sstevel@tonic-gate "print all handles.\n"
411*0Sstevel@tonic-gate "With an address, print the specified handle.\n\n"
412*0Sstevel@tonic-gate "Switches:\n"
413*0Sstevel@tonic-gate " -i print the module identifier information\n");
414*0Sstevel@tonic-gate }
415