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.
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.
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]
23 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
27 #include <sys/types.h>
41 (void) printf("usage: dumpbind [-pqsc] <bindings.data>\n");
42 (void) printf("\t-p\tdisplay output in parsable format\n");
43 (void) printf("\t-q\tquery all mutex_locks in data buffer\n");
44 (void) printf("\t-c\tclear all mutex_locks in data buffer\n");
45 (void) printf("\t-s\tset all mutex_locks in data buffer\n");
46 (void) printf("\t-b\tprint bucket usage statistics\n");
50 * Returns 1 if lock held - 0 otherwise.
53 query_lock(lwp_mutex_t
*lock
) {
54 if (_lwp_mutex_trylock(lock
) == 0) {
55 (void) _lwp_mutex_unlock(lock
);
62 query_buffer_locks(bindhead
* bhp
)
64 int i
, bkt_locks_held
= 0;
66 (void) printf("bh_strlock: ");
67 if (query_lock(&bhp
->bh_strlock
) == 1)
68 (void) printf("lock held\n");
70 (void) printf("free\n");
72 (void) printf("bh_lock: ");
73 if (query_lock(&bhp
->bh_lock
) == 1)
74 (void) printf("lock held\n");
76 (void) printf("free\n");
78 (void) printf("Buckets: %d - locks held:\n", bhp
->bh_bktcnt
);
79 for (i
= 0; i
< bhp
->bh_bktcnt
; i
++) {
80 if (query_lock(&bhp
->bh_bkts
[i
].bb_lock
) == 1) {
82 (void) printf("\tbkt[%d]: lock held\n", i
);
85 if (bkt_locks_held
== 0)
86 (void) printf("\tnone.\n");
88 (void) printf("\t[%d bucket(s) locked]\n", bkt_locks_held
);
92 clear_buffer_locks(bindhead
* bhp
)
96 if (query_lock(&bhp
->bh_strlock
) == 1) {
97 (void) _lwp_mutex_unlock(&bhp
->bh_strlock
);
98 (void) printf("bh_strlock: cleared\n");
100 if (query_lock(&bhp
->bh_lock
) == 1) {
101 (void) _lwp_mutex_unlock(&bhp
->bh_lock
);
102 (void) printf("bh_lock: cleared\n");
104 for (i
= 0; i
< bhp
->bh_bktcnt
; i
++) {
105 if (query_lock(&bhp
->bh_bkts
[i
].bb_lock
) == 1) {
106 (void) _lwp_mutex_unlock(&bhp
->bh_bkts
[i
].bb_lock
);
107 (void) printf("bkt[%d]: lock cleared\n", i
);
113 set_buffer_locks(bindhead
* bhp
)
117 for (i
= 0; i
< bhp
->bh_bktcnt
; i
++)
118 (void) _lwp_mutex_lock(&bhp
->bh_bkts
[i
].bb_lock
);
120 (void) _lwp_mutex_lock(&bhp
->bh_strlock
);
121 (void) _lwp_mutex_lock(&bhp
->bh_lock
);
125 main(int argc
, char **argv
)
128 char *fname
, *format_string
;
129 bindhead
*bhp
, *tmp_bhp
;
131 int bflag
= 0, pflag
= 0, qflag
= 0, cflag
= 0, sflag
= 0;
132 ulong_t symcount
, callcount
;
134 while ((c
= getopt(argc
, argv
, "bspcq")) != EOF
)
156 if (optind
== argc
) {
160 fname
= argv
[optind
];
161 if ((fd
= open(fname
, O_RDWR
)) == -1) {
162 (void) fprintf(stderr
,
163 "dumpbindings: unable to open file: %s\n", fname
);
168 if ((bhp
= (bindhead
*)mmap(0, sizeof (bindhead
),
169 (PROT_READ
| PROT_WRITE
), MAP_SHARED
, fd
, 0)) == MAP_FAILED
) {
170 (void) fprintf(stderr
, "dumpbind: mmap failed\n");
176 query_buffer_locks(bhp
);
181 clear_buffer_locks(bhp
);
185 set_buffer_locks(bhp
);
190 if ((tmp_bhp
= (bindhead
*)mmap(0, bhp
->bh_size
,
191 (PROT_READ
| PROT_WRITE
), MAP_SHARED
, fd
, 0)) == MAP_FAILED
) {
192 (void) fprintf(stderr
, "dumpbind: remap: mmap failed\n");
198 (void) munmap((void *)bhp
, sizeof (bindhead
));
202 format_string
= "%s|%s|%8d\n";
206 "Bindings Summary Report\n\n"
209 "----------------------------------------------"
210 "--------------------------\n");
212 format_string
= "%-35s %-25s %5d\n";
217 for (i
= 0; i
< bhp
->bh_bktcnt
; i
++) {
220 unsigned int bep_off
= bhp
->bh_bkts
[i
].bb_head
;
224 bep
= (binding_entry
*)((char *)bhp
+ bep_off
);
227 (void) printf(format_string
,
228 (char *)bhp
+ bep
->be_lib_name
,
229 (char *)bhp
+ bep
->be_sym_name
,
232 callcount
+= bep
->be_count
;
234 bep_off
= bep
->be_next
;
238 (void) printf("bkt[%d] - %d entries\n", i
, ent_cnt
);
241 if (!bflag
&& !pflag
) {
242 (void) printf("----------------------------------------------"
243 "--------------------------\n"
244 "Symbol Count: %lu Call Count: %lu\n\n",
245 symcount
, callcount
);