8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / link_audit / common / dumpbind.c
blobe1ae6ff75d225ee6fe3253b6eac819762dae44bf
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <sys/lwp.h>
30 #include <fcntl.h>
31 #include <stdio.h>
32 #include <sys/mman.h>
33 #include <synch.h>
34 #include <errno.h>
36 #include "bindings.h"
38 void
39 usage()
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.
52 static int
53 query_lock(lwp_mutex_t *lock) {
54 if (_lwp_mutex_trylock(lock) == 0) {
55 (void) _lwp_mutex_unlock(lock);
56 return (0);
57 } else
58 return (1);
61 static void
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");
69 else
70 (void) printf("free\n");
72 (void) printf("bh_lock: ");
73 if (query_lock(&bhp->bh_lock) == 1)
74 (void) printf("lock held\n");
75 else
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) {
81 bkt_locks_held++;
82 (void) printf("\tbkt[%d]: lock held\n", i);
85 if (bkt_locks_held == 0)
86 (void) printf("\tnone.\n");
87 else
88 (void) printf("\t[%d bucket(s) locked]\n", bkt_locks_held);
91 static void
92 clear_buffer_locks(bindhead * bhp)
94 int i;
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);
112 static void
113 set_buffer_locks(bindhead * bhp)
115 int i;
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)
127 int fd;
128 char *fname, *format_string;
129 bindhead *bhp, *tmp_bhp;
130 int i, c;
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)
135 switch (c) {
136 case 'b':
137 bflag++;
138 break;
139 case 'p':
140 pflag++;
141 break;
142 case 'q':
143 qflag++;
144 break;
145 case 'c':
146 cflag++;
147 break;
148 case 's':
149 sflag++;
150 break;
151 case '?':
152 usage();
153 return (1);
156 if (optind == argc) {
157 usage();
158 return (1);
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);
164 perror("open");
165 return (1);
167 /* LINTED */
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");
171 perror("mmap");
172 return (1);
175 if (qflag) {
176 query_buffer_locks(bhp);
177 return (0);
180 if (cflag) {
181 clear_buffer_locks(bhp);
182 return (0);
184 if (sflag) {
185 set_buffer_locks(bhp);
186 return (0);
189 /* LINTED */
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");
193 perror("mmap");
194 return (1);
196 (void) close(fd);
198 (void) munmap((void *)bhp, sizeof (bindhead));
199 bhp = tmp_bhp;
201 if (pflag)
202 format_string = "%s|%s|%8d\n";
203 else {
204 if (!bflag) {
205 (void) printf(" "
206 "Bindings Summary Report\n\n"
207 "Library Symbol"
208 " Call Count\n"
209 "----------------------------------------------"
210 "--------------------------\n");
212 format_string = "%-35s %-25s %5d\n";
215 symcount = 0;
216 callcount = 0;
217 for (i = 0; i < bhp->bh_bktcnt; i++) {
218 int ent_cnt = 0;
219 binding_entry * bep;
220 unsigned int bep_off = bhp->bh_bkts[i].bb_head;
222 while (bep_off) {
223 /* LINTED */
224 bep = (binding_entry *)((char *)bhp + bep_off);
225 if (!bflag) {
226 /* LINTED */
227 (void) printf(format_string,
228 (char *)bhp + bep->be_lib_name,
229 (char *)bhp + bep->be_sym_name,
230 bep->be_count);
231 symcount++;
232 callcount += bep->be_count;
234 bep_off = bep->be_next;
235 ent_cnt++;
237 if (bflag)
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);
247 return (0);