xref: /illumos-gate/usr/src/cmd/sgs/liblddbg/common/statistics.c (revision bf994817a71d4ac680198e25fe79d13c247306e0)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
55aefb655Srie  * Common Development and Distribution License (the "License").
65aefb655Srie  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21c174926fSrie 
227c478bd9Sstevel@tonic-gate /*
23*bf994817SAli Bahrami  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
26*bf994817SAli Bahrami #include	<stdio.h>
277c478bd9Sstevel@tonic-gate #include	"_debug.h"
287c478bd9Sstevel@tonic-gate #include	"msg.h"
297c478bd9Sstevel@tonic-gate #include	"libld.h"
307c478bd9Sstevel@tonic-gate 
31*bf994817SAli Bahrami static const char *
32*bf994817SAli Bahrami fmt_human_units(size_t bytes, char *buf, size_t bufsize)
33*bf994817SAli Bahrami {
34*bf994817SAli Bahrami 	static int	unit_arr[] = { 'K', 'M', 'G', 'T' };
35*bf994817SAli Bahrami 
36*bf994817SAli Bahrami 	int		i, unit_ch;
37*bf994817SAli Bahrami 	size_t		unit_bytes = bytes;
38*bf994817SAli Bahrami 
39*bf994817SAli Bahrami 	/* Convert to human readable units */
40*bf994817SAli Bahrami 	for (i = 0; i < sizeof (unit_arr) / sizeof (unit_arr[0]); i++) {
41*bf994817SAli Bahrami 		if (unit_bytes < 1024)
42*bf994817SAli Bahrami 			break;
43*bf994817SAli Bahrami 		unit_ch = unit_arr[i];
44*bf994817SAli Bahrami 		unit_bytes /= 1024;
45*bf994817SAli Bahrami 	}
46*bf994817SAli Bahrami 	if (unit_bytes == bytes)
47*bf994817SAli Bahrami 		buf[0] = '\0';
48*bf994817SAli Bahrami 	else
49*bf994817SAli Bahrami 		(void) snprintf(buf, bufsize, MSG_ORIG(MSG_FMT_MEMUNIT),
50*bf994817SAli Bahrami 		    EC_XWORD(unit_bytes), unit_ch);
51*bf994817SAli Bahrami 
52*bf994817SAli Bahrami 	return (buf);
53*bf994817SAli Bahrami }
54*bf994817SAli Bahrami 
55*bf994817SAli Bahrami /*
56*bf994817SAli Bahrami  * Generate a relocation cache statistics line for the active or
57*bf994817SAli Bahrami  * output relocation cache.
58*bf994817SAli Bahrami  *
59*bf994817SAli Bahrami  * entry:
60*bf994817SAli Bahrami  *	ofl - output file descriptor
61*bf994817SAli Bahrami  *	alp - One of ofl->ofl_actrels or ofl->ofl_outrels.
62*bf994817SAli Bahrami  */
63*bf994817SAli Bahrami static void
64*bf994817SAli Bahrami rel_cache_statistics(Ofl_desc *ofl, const char *title, APlist *alp)
65*bf994817SAli Bahrami {
66*bf994817SAli Bahrami 	Lm_list		*lml = ofl->ofl_lml;
67*bf994817SAli Bahrami 	size_t		desc_cnt = 0, desc_used = 0, bytes;
68*bf994817SAli Bahrami 	Aliste		idx;
69*bf994817SAli Bahrami 	Rel_cachebuf	*rcp;
70*bf994817SAli Bahrami 	char		unit_buf[CONV_INV_BUFSIZE + 10];
71*bf994817SAli Bahrami 
72*bf994817SAli Bahrami 	/* Sum the total memory allocated across all the buffers */
73*bf994817SAli Bahrami 	for (APLIST_TRAVERSE(alp, idx, rcp)) {
74*bf994817SAli Bahrami 		desc_cnt += rcp->rc_end - rcp->rc_arr;
75*bf994817SAli Bahrami 		desc_used += rcp->rc_free - rcp->rc_arr;
76*bf994817SAli Bahrami 	}
77*bf994817SAli Bahrami 	bytes = desc_cnt * sizeof (Rel_desc);
78*bf994817SAli Bahrami 
79*bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_CACHE), title,
80*bf994817SAli Bahrami 	    EC_WORD(aplist_nitems(alp)),
81*bf994817SAli Bahrami 	    EC_XWORD(desc_used), EC_XWORD(desc_cnt),
82*bf994817SAli Bahrami 	    (desc_cnt == 0) ? 100 : EC_WORD((desc_used * 100) / desc_cnt),
83*bf994817SAli Bahrami 	    EC_XWORD(bytes),
84*bf994817SAli Bahrami 	    fmt_human_units(bytes, unit_buf, sizeof (unit_buf)));
85*bf994817SAli Bahrami }
86*bf994817SAli Bahrami 
87*bf994817SAli Bahrami 
88*bf994817SAli Bahrami /*
89*bf994817SAli Bahrami  * Generate a statistics line for the auxiliary relocation descriptor cache.
90*bf994817SAli Bahrami  *
91*bf994817SAli Bahrami  * entry:
92*bf994817SAli Bahrami  *	ofl - output file descriptor
93*bf994817SAli Bahrami  */
94*bf994817SAli Bahrami static void
95*bf994817SAli Bahrami rel_aux_cache_statistics(Ofl_desc *ofl)
96*bf994817SAli Bahrami {
97*bf994817SAli Bahrami 	Rel_aux_cachebuf	*racp;
98*bf994817SAli Bahrami 	Lm_list	*lml = ofl->ofl_lml;
99*bf994817SAli Bahrami 	size_t	desc_cnt = 0, desc_used = 0, bytes;
100*bf994817SAli Bahrami 	Aliste	idx;
101*bf994817SAli Bahrami 	char	unit_buf[CONV_INV_BUFSIZE + 10];
102*bf994817SAli Bahrami 
103*bf994817SAli Bahrami 	/* Sum the total memory allocated across all the buffers */
104*bf994817SAli Bahrami 	for (APLIST_TRAVERSE(ofl->ofl_relaux, idx, racp)) {
105*bf994817SAli Bahrami 		desc_cnt += racp->rac_end - racp->rac_arr;
106*bf994817SAli Bahrami 		desc_used += racp->rac_free - racp->rac_arr;
107*bf994817SAli Bahrami 	}
108*bf994817SAli Bahrami 	bytes = desc_cnt * sizeof (Rel_desc);
109*bf994817SAli Bahrami 
110*bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_ACACHE),
111*bf994817SAli Bahrami 	    EC_WORD(aplist_nitems(ofl->ofl_relaux)),
112*bf994817SAli Bahrami 	    EC_XWORD(desc_used), EC_XWORD(desc_cnt),
113*bf994817SAli Bahrami 	    (desc_cnt == 0) ? 100 : EC_WORD((desc_used * 100) / desc_cnt),
114*bf994817SAli Bahrami 	    EC_XWORD(bytes),
115*bf994817SAli Bahrami 	    fmt_human_units(bytes, unit_buf, sizeof (unit_buf)));
116*bf994817SAli Bahrami }
117*bf994817SAli Bahrami 
118*bf994817SAli Bahrami 
1197c478bd9Sstevel@tonic-gate void
1207c478bd9Sstevel@tonic-gate Dbg_statistics_ld(Ofl_desc *ofl)
1217c478bd9Sstevel@tonic-gate {
1225aefb655Srie 	Lm_list	*lml = ofl->ofl_lml;
1235aefb655Srie 
1245aefb655Srie 	if (DBG_NOTCLASS(DBG_C_STATS))
1257c478bd9Sstevel@tonic-gate 		return;
1267c478bd9Sstevel@tonic-gate 
1275aefb655Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1285aefb655Srie 	dbg_print(lml, MSG_INTL(MSG_STATS_GENERAL));
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	if (ofl->ofl_objscnt || ofl->ofl_soscnt || ofl->ofl_arscnt) {
1315aefb655Srie 		dbg_print(lml, MSG_INTL(MSG_STATS_FILES),
1327c478bd9Sstevel@tonic-gate 		    EC_XWORD(ofl->ofl_objscnt), EC_XWORD(ofl->ofl_soscnt),
1337c478bd9Sstevel@tonic-gate 		    EC_XWORD(ofl->ofl_arscnt));
1347c478bd9Sstevel@tonic-gate 	}
1357c478bd9Sstevel@tonic-gate 
136c174926fSrie 	if (ofl->ofl_locscnt || ofl->ofl_globcnt) {
1375aefb655Srie 		dbg_print(lml, MSG_INTL(MSG_STATS_SYMBOLS_OUT),
138c174926fSrie 		    EC_XWORD(ofl->ofl_globcnt), EC_XWORD(ofl->ofl_locscnt));
139c174926fSrie 	}
140c174926fSrie 	if (ofl->ofl_entercnt || ofl->ofl_scopecnt || ofl->ofl_elimcnt) {
1415aefb655Srie 		dbg_print(lml, MSG_INTL(MSG_STATS_SYMBOLS_IN),
142c174926fSrie 		    EC_XWORD(ofl->ofl_entercnt), EC_XWORD(ofl->ofl_scopecnt),
143c174926fSrie 		    EC_XWORD(ofl->ofl_elimcnt));
1447c478bd9Sstevel@tonic-gate 	}
1457c478bd9Sstevel@tonic-gate 
146*bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_OUT),
147*bf994817SAli Bahrami 	    EC_XWORD(ofl->ofl_outrels.rc_cnt));
148*bf994817SAli Bahrami 
149*bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_IN),
150*bf994817SAli Bahrami 	    EC_XWORD(ofl->ofl_entrelscnt), EC_XWORD(ofl->ofl_actrels.rc_cnt));
151*bf994817SAli Bahrami 
152*bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_TICACHE));
153*bf994817SAli Bahrami 	rel_cache_statistics(ofl, MSG_INTL(MSG_STATS_REL_TIOUT),
154*bf994817SAli Bahrami 	    ofl->ofl_outrels.rc_list);
155*bf994817SAli Bahrami 	rel_cache_statistics(ofl, MSG_INTL(MSG_STATS_REL_TIACT),
156*bf994817SAli Bahrami 	    ofl->ofl_actrels.rc_list);
157*bf994817SAli Bahrami 	rel_aux_cache_statistics(ofl);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate void
1617c478bd9Sstevel@tonic-gate Dbg_statistics_ar(Ofl_desc *ofl)
1627c478bd9Sstevel@tonic-gate {
16357ef7aa9SRod Evans 	Aliste		idx;
1647c478bd9Sstevel@tonic-gate 	Ar_desc		*adp;
1657c478bd9Sstevel@tonic-gate 	Elf_Arsym	*arsym;
1667c478bd9Sstevel@tonic-gate 	Ar_aux		*aux;
1675aefb655Srie 	Lm_list		*lml = ofl->ofl_lml;
1687c478bd9Sstevel@tonic-gate 
1695aefb655Srie 	if (DBG_NOTCLASS(DBG_C_STATS | DBG_C_UNUSED))
1707c478bd9Sstevel@tonic-gate 		return;
1717c478bd9Sstevel@tonic-gate 
1725aefb655Srie 	Dbg_util_nl(lml, DBG_NL_STD);
17357ef7aa9SRod Evans 	for (APLIST_TRAVERSE(ofl->ofl_ars, idx, adp)) {
1747c478bd9Sstevel@tonic-gate 		size_t	poffset = 0;
1757c478bd9Sstevel@tonic-gate 		uint_t	count = 0, used = 0;
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 		if ((adp->ad_flags & FLG_ARD_EXTRACT) == 0) {
1785aefb655Srie 			Dbg_unused_file(lml, adp->ad_name, 0, 0);
1797c478bd9Sstevel@tonic-gate 			continue;
1807c478bd9Sstevel@tonic-gate 		}
1817c478bd9Sstevel@tonic-gate 
1825aefb655Srie 		if (DBG_NOTCLASS(DBG_C_STATS))
1837c478bd9Sstevel@tonic-gate 			continue;
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate 		arsym = adp->ad_start;
1867c478bd9Sstevel@tonic-gate 		aux = adp->ad_aux;
1877c478bd9Sstevel@tonic-gate 		while (arsym->as_off) {
1887c478bd9Sstevel@tonic-gate 			/*
1897c478bd9Sstevel@tonic-gate 			 * Assume that symbols from the same member file are
1907c478bd9Sstevel@tonic-gate 			 * adjacent within the archive symbol table.
1917c478bd9Sstevel@tonic-gate 			 */
1927c478bd9Sstevel@tonic-gate 			if (poffset != arsym->as_off) {
1937c478bd9Sstevel@tonic-gate 				count++;
1947c478bd9Sstevel@tonic-gate 				poffset = arsym->as_off;
1957c478bd9Sstevel@tonic-gate 				if (aux->au_mem == FLG_ARMEM_PROC)
1967c478bd9Sstevel@tonic-gate 					used++;
1977c478bd9Sstevel@tonic-gate 			}
1987c478bd9Sstevel@tonic-gate 			aux++, arsym++;
1997c478bd9Sstevel@tonic-gate 		}
2007c478bd9Sstevel@tonic-gate 		if ((count == 0) || (used == 0))
2017c478bd9Sstevel@tonic-gate 			continue;
2027c478bd9Sstevel@tonic-gate #ifndef	UDIV_NOT_SUPPORTED
2035aefb655Srie 		dbg_print(lml, MSG_INTL(MSG_STATS_AR), adp->ad_name, count,
2045aefb655Srie 		    used, ((used * 100) / count));
2057c478bd9Sstevel@tonic-gate #endif
2067c478bd9Sstevel@tonic-gate 	}
2075aefb655Srie 	Dbg_util_nl(lml, DBG_NL_STD);
2087c478bd9Sstevel@tonic-gate }
209