xref: /onnv-gate/usr/src/cmd/mdb/common/modules/genunix/tsol.c (revision 1676:37f4a3e2bd99)
1*1676Sjpk /*
2*1676Sjpk  * CDDL HEADER START
3*1676Sjpk  *
4*1676Sjpk  * The contents of this file are subject to the terms of the
5*1676Sjpk  * Common Development and Distribution License (the "License").
6*1676Sjpk  * You may not use this file except in compliance with the License.
7*1676Sjpk  *
8*1676Sjpk  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*1676Sjpk  * or http://www.opensolaris.org/os/licensing.
10*1676Sjpk  * See the License for the specific language governing permissions
11*1676Sjpk  * and limitations under the License.
12*1676Sjpk  *
13*1676Sjpk  * When distributing Covered Code, include this CDDL HEADER in each
14*1676Sjpk  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*1676Sjpk  * If applicable, add the following below this CDDL HEADER, with the
16*1676Sjpk  * fields enclosed by brackets "[]" replaced with your own identifying
17*1676Sjpk  * information: Portions Copyright [yyyy] [name of copyright owner]
18*1676Sjpk  *
19*1676Sjpk  * CDDL HEADER END
20*1676Sjpk  */
21*1676Sjpk /*
22*1676Sjpk  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*1676Sjpk  * Use is subject to license terms.
24*1676Sjpk  */
25*1676Sjpk 
26*1676Sjpk #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*1676Sjpk 
28*1676Sjpk #include <sys/types.h>
29*1676Sjpk #include <sys/tsol/tndb.h>
30*1676Sjpk #include <sys/modhash_impl.h>
31*1676Sjpk 
32*1676Sjpk #include <mdb/mdb_modapi.h>
33*1676Sjpk #include <mdb/mdb_ks.h>
34*1676Sjpk 
35*1676Sjpk #include "tsol.h"
36*1676Sjpk #include "modhash.h"
37*1676Sjpk 
38*1676Sjpk /* ****************** tnrh ****************** */
39*1676Sjpk 
40*1676Sjpk typedef struct tnrh_walk_s {
41*1676Sjpk 	tnrhc_hash_t **hptr;
42*1676Sjpk 	int idx;
43*1676Sjpk 	tnrhc_hash_t *tnrhc_table[TSOL_MASK_TABLE_SIZE];
44*1676Sjpk 	tnrhc_hash_t *tnrhc_table_v6[TSOL_MASK_TABLE_SIZE_V6];
45*1676Sjpk } tnrh_walk_t;
46*1676Sjpk 
47*1676Sjpk /*
48*1676Sjpk  * Free the mdb storage pointed to by the given per-prefix table.
49*1676Sjpk  */
50*1676Sjpk static void
free_table(tnrhc_hash_t ** table,int ntable)51*1676Sjpk free_table(tnrhc_hash_t **table, int ntable)
52*1676Sjpk {
53*1676Sjpk 	while (--ntable >= 0) {
54*1676Sjpk 		if (*table != NULL)
55*1676Sjpk 			mdb_free(*table, TNRHC_SIZE * sizeof (**table));
56*1676Sjpk 		table++;
57*1676Sjpk 	}
58*1676Sjpk }
59*1676Sjpk 
60*1676Sjpk /*
61*1676Sjpk  * Read in a list of per-prefix-length hash tables.  Allocate storage for the
62*1676Sjpk  * hashes that are present.  On successful return, the table will contain
63*1676Sjpk  * pointers to mdb-resident storage, not kernel addresses.  On failure, the
64*1676Sjpk  * contents will not point to any mdb storage.
65*1676Sjpk  */
66*1676Sjpk static int
read_table(const char * symname,tnrhc_hash_t ** table,int ntable)67*1676Sjpk read_table(const char *symname, tnrhc_hash_t **table, int ntable)
68*1676Sjpk {
69*1676Sjpk 	GElf_Sym tnrhc_hash;
70*1676Sjpk 	tnrhc_hash_t **hp;
71*1676Sjpk 	uintptr_t addr;
72*1676Sjpk 
73*1676Sjpk 	if (mdb_lookup_by_name(symname, &tnrhc_hash) == -1) {
74*1676Sjpk 		mdb_warn("failed to read %s", symname);
75*1676Sjpk 		return (-1);
76*1676Sjpk 	}
77*1676Sjpk 	if (mdb_vread(table, ntable * sizeof (*table),
78*1676Sjpk 	    tnrhc_hash.st_value) == -1) {
79*1676Sjpk 		mdb_warn("can't read %s at %p", symname, tnrhc_hash.st_value);
80*1676Sjpk 		return (-1);
81*1676Sjpk 	}
82*1676Sjpk 	for (hp = table; hp < table + ntable; hp++) {
83*1676Sjpk 		if ((addr = (uintptr_t)*hp) != 0) {
84*1676Sjpk 			*hp = mdb_alloc(TNRHC_SIZE * sizeof (**hp), UM_SLEEP);
85*1676Sjpk 			if (mdb_vread(*hp, TNRHC_SIZE * sizeof (**hp),
86*1676Sjpk 			    addr) == -1) {
87*1676Sjpk 				mdb_warn("can't read %s[%d] at %p", symname,
88*1676Sjpk 				    hp - table, addr);
89*1676Sjpk 				free_table(table, (hp - table) + 1);
90*1676Sjpk 				return (-1);
91*1676Sjpk 			}
92*1676Sjpk 		}
93*1676Sjpk 	}
94*1676Sjpk 	return (0);
95*1676Sjpk }
96*1676Sjpk 
97*1676Sjpk int
tnrh_walk_init(mdb_walk_state_t * wsp)98*1676Sjpk tnrh_walk_init(mdb_walk_state_t *wsp)
99*1676Sjpk {
100*1676Sjpk 	tnrh_walk_t *twp;
101*1676Sjpk 
102*1676Sjpk 	twp = mdb_alloc(sizeof (*twp), UM_SLEEP);
103*1676Sjpk 
104*1676Sjpk 	if (read_table("tnrhc_table", twp->tnrhc_table,
105*1676Sjpk 	    TSOL_MASK_TABLE_SIZE) == -1) {
106*1676Sjpk 		mdb_free(twp, sizeof (*twp));
107*1676Sjpk 		return (WALK_ERR);
108*1676Sjpk 	}
109*1676Sjpk 	if (read_table("tnrhc_table_v6", twp->tnrhc_table_v6,
110*1676Sjpk 	    TSOL_MASK_TABLE_SIZE_V6) == -1) {
111*1676Sjpk 		free_table(twp->tnrhc_table, TSOL_MASK_TABLE_SIZE);
112*1676Sjpk 		mdb_free(twp, sizeof (*twp));
113*1676Sjpk 		return (WALK_ERR);
114*1676Sjpk 	}
115*1676Sjpk 
116*1676Sjpk 	twp->hptr = twp->tnrhc_table;
117*1676Sjpk 	twp->idx = 0;
118*1676Sjpk 	wsp->walk_addr = 0;
119*1676Sjpk 	wsp->walk_data = twp;
120*1676Sjpk 
121*1676Sjpk 	return (WALK_NEXT);
122*1676Sjpk }
123*1676Sjpk 
124*1676Sjpk int
tnrh_walk_step(mdb_walk_state_t * wsp)125*1676Sjpk tnrh_walk_step(mdb_walk_state_t *wsp)
126*1676Sjpk {
127*1676Sjpk 	tnrh_walk_t *twp = wsp->walk_data;
128*1676Sjpk 	tsol_tnrhc_t tnrhc;
129*1676Sjpk 	int status;
130*1676Sjpk 
131*1676Sjpk 	while (wsp->walk_addr == NULL) {
132*1676Sjpk 		if (*twp->hptr == NULL || twp->idx >= TNRHC_SIZE) {
133*1676Sjpk 			twp->hptr++;
134*1676Sjpk 			if (twp->hptr == twp->tnrhc_table +
135*1676Sjpk 			    TSOL_MASK_TABLE_SIZE)
136*1676Sjpk 				twp->hptr = twp->tnrhc_table_v6;
137*1676Sjpk 			else if (twp->hptr == twp->tnrhc_table_v6 +
138*1676Sjpk 			    TSOL_MASK_TABLE_SIZE_V6)
139*1676Sjpk 				return (WALK_DONE);
140*1676Sjpk 			twp->idx = 0;
141*1676Sjpk 		} else {
142*1676Sjpk 			wsp->walk_addr = (uintptr_t)(*twp->hptr)[twp->idx++].
143*1676Sjpk 			    tnrh_list;
144*1676Sjpk 		}
145*1676Sjpk 	}
146*1676Sjpk 
147*1676Sjpk 	if (mdb_vread(&tnrhc, sizeof (tnrhc), wsp->walk_addr) == -1) {
148*1676Sjpk 		mdb_warn("can't read tsol_tnrhc_t at %p", wsp->walk_addr);
149*1676Sjpk 		return (WALK_ERR);
150*1676Sjpk 	}
151*1676Sjpk 
152*1676Sjpk 	status = wsp->walk_callback(wsp->walk_addr, &tnrhc,
153*1676Sjpk 	    wsp->walk_cbdata);
154*1676Sjpk 
155*1676Sjpk 	wsp->walk_addr = (uintptr_t)tnrhc.rhc_next;
156*1676Sjpk 	return (status);
157*1676Sjpk }
158*1676Sjpk 
159*1676Sjpk void
tnrh_walk_fini(mdb_walk_state_t * wsp)160*1676Sjpk tnrh_walk_fini(mdb_walk_state_t *wsp)
161*1676Sjpk {
162*1676Sjpk 	tnrh_walk_t *twp = wsp->walk_data;
163*1676Sjpk 
164*1676Sjpk 	free_table(twp->tnrhc_table, TSOL_MASK_TABLE_SIZE);
165*1676Sjpk 	free_table(twp->tnrhc_table_v6, TSOL_MASK_TABLE_SIZE_V6);
166*1676Sjpk 	mdb_free(twp, sizeof (*twp));
167*1676Sjpk }
168*1676Sjpk 
169*1676Sjpk /* ****************** tnrhtp ****************** */
170*1676Sjpk 
171*1676Sjpk typedef struct tnrhtp_walk_data_s {
172*1676Sjpk 	int (*old_callback)(uintptr_t, const void *, void *);
173*1676Sjpk 	void *old_cbdata;
174*1676Sjpk } tnrhtp_walk_data_t;
175*1676Sjpk 
176*1676Sjpk /* ARGSUSED */
177*1676Sjpk static int
tnrhtp_walk_callback(uintptr_t addr,const void * data,void * private)178*1676Sjpk tnrhtp_walk_callback(uintptr_t addr, const void *data, void *private)
179*1676Sjpk {
180*1676Sjpk 	const struct mod_hash_entry *mhe = data;
181*1676Sjpk 	tnrhtp_walk_data_t *twd = private;
182*1676Sjpk 	tsol_tpc_t tpc;
183*1676Sjpk 
184*1676Sjpk 	if (mdb_vread(&tpc, sizeof (tpc), (uintptr_t)mhe->mhe_val) == -1) {
185*1676Sjpk 		mdb_warn("failed to read tsol_tpc_t at %p", mhe->mhe_val);
186*1676Sjpk 		return (WALK_ERR);
187*1676Sjpk 	} else {
188*1676Sjpk 		return (twd->old_callback((uintptr_t)mhe->mhe_val, &tpc,
189*1676Sjpk 		    twd->old_cbdata));
190*1676Sjpk 	}
191*1676Sjpk }
192*1676Sjpk 
193*1676Sjpk int
tnrhtp_walk_init(mdb_walk_state_t * wsp)194*1676Sjpk tnrhtp_walk_init(mdb_walk_state_t *wsp)
195*1676Sjpk {
196*1676Sjpk 	mod_hash_t *tpc_name_hash;
197*1676Sjpk 
198*1676Sjpk 	if (mdb_readvar(&tpc_name_hash, "tpc_name_hash") == -1) {
199*1676Sjpk 		mdb_warn("failed to read tpc_name_hash");
200*1676Sjpk 		return (WALK_ERR);
201*1676Sjpk 	}
202*1676Sjpk 
203*1676Sjpk 	wsp->walk_addr = (uintptr_t)tpc_name_hash;
204*1676Sjpk 
205*1676Sjpk 	return (modent_walk_init(wsp));
206*1676Sjpk }
207*1676Sjpk 
208*1676Sjpk int
tnrhtp_walk_step(mdb_walk_state_t * wsp)209*1676Sjpk tnrhtp_walk_step(mdb_walk_state_t *wsp)
210*1676Sjpk {
211*1676Sjpk 	tnrhtp_walk_data_t twd;
212*1676Sjpk 	int retv;
213*1676Sjpk 
214*1676Sjpk 	twd.old_callback = wsp->walk_callback;
215*1676Sjpk 	twd.old_cbdata = wsp->walk_cbdata;
216*1676Sjpk 	wsp->walk_callback = tnrhtp_walk_callback;
217*1676Sjpk 	wsp->walk_cbdata = &twd;
218*1676Sjpk 
219*1676Sjpk 	retv = modent_walk_step(wsp);
220*1676Sjpk 
221*1676Sjpk 	wsp->walk_callback = twd.old_callback;
222*1676Sjpk 	wsp->walk_cbdata = twd.old_cbdata;
223*1676Sjpk 
224*1676Sjpk 	return (retv);
225*1676Sjpk }
226*1676Sjpk 
227*1676Sjpk void
tnrhtp_walk_fini(mdb_walk_state_t * wsp)228*1676Sjpk tnrhtp_walk_fini(mdb_walk_state_t *wsp)
229*1676Sjpk {
230*1676Sjpk 	modent_walk_fini(wsp);
231*1676Sjpk }
232