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 /*
23bf994817SAli Bahrami  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
26bf994817SAli 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 
31bf994817SAli Bahrami static const char *
fmt_human_units(size_t bytes,char * buf,size_t bufsize)32bf994817SAli Bahrami fmt_human_units(size_t bytes, char *buf, size_t bufsize)
33bf994817SAli Bahrami {
34bf994817SAli Bahrami 	static int	unit_arr[] = { 'K', 'M', 'G', 'T' };
35bf994817SAli Bahrami 
36bf994817SAli Bahrami 	int		i, unit_ch;
37bf994817SAli Bahrami 	size_t		unit_bytes = bytes;
38bf994817SAli Bahrami 
39bf994817SAli Bahrami 	/* Convert to human readable units */
40bf994817SAli Bahrami 	for (i = 0; i < sizeof (unit_arr) / sizeof (unit_arr[0]); i++) {
41bf994817SAli Bahrami 		if (unit_bytes < 1024)
42bf994817SAli Bahrami 			break;
43bf994817SAli Bahrami 		unit_ch = unit_arr[i];
44bf994817SAli Bahrami 		unit_bytes /= 1024;
45bf994817SAli Bahrami 	}
46bf994817SAli Bahrami 	if (unit_bytes == bytes)
47bf994817SAli Bahrami 		buf[0] = '\0';
48bf994817SAli Bahrami 	else
49bf994817SAli Bahrami 		(void) snprintf(buf, bufsize, MSG_ORIG(MSG_FMT_MEMUNIT),
50bf994817SAli Bahrami 		    EC_XWORD(unit_bytes), unit_ch);
51bf994817SAli Bahrami 
52bf994817SAli Bahrami 	return (buf);
53bf994817SAli Bahrami }
54bf994817SAli Bahrami 
55bf994817SAli Bahrami /*
56bf994817SAli Bahrami  * Generate a relocation cache statistics line for the active or
57bf994817SAli Bahrami  * output relocation cache.
58bf994817SAli Bahrami  *
59bf994817SAli Bahrami  * entry:
60bf994817SAli Bahrami  *	ofl - output file descriptor
61bf994817SAli Bahrami  *	alp - One of ofl->ofl_actrels or ofl->ofl_outrels.
62bf994817SAli Bahrami  */
63bf994817SAli Bahrami static void
rel_cache_statistics(Ofl_desc * ofl,const char * title,APlist * alp)64bf994817SAli Bahrami rel_cache_statistics(Ofl_desc *ofl, const char *title, APlist *alp)
65bf994817SAli Bahrami {
66bf994817SAli Bahrami 	Lm_list		*lml = ofl->ofl_lml;
67bf994817SAli Bahrami 	size_t		desc_cnt = 0, desc_used = 0, bytes;
68bf994817SAli Bahrami 	Aliste		idx;
69bf994817SAli Bahrami 	Rel_cachebuf	*rcp;
70bf994817SAli Bahrami 	char		unit_buf[CONV_INV_BUFSIZE + 10];
71bf994817SAli Bahrami 
72bf994817SAli Bahrami 	/* Sum the total memory allocated across all the buffers */
73bf994817SAli Bahrami 	for (APLIST_TRAVERSE(alp, idx, rcp)) {
74bf994817SAli Bahrami 		desc_cnt += rcp->rc_end - rcp->rc_arr;
75bf994817SAli Bahrami 		desc_used += rcp->rc_free - rcp->rc_arr;
76bf994817SAli Bahrami 	}
77bf994817SAli Bahrami 	bytes = desc_cnt * sizeof (Rel_desc);
78bf994817SAli Bahrami 
79bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_CACHE), title,
80bf994817SAli Bahrami 	    EC_WORD(aplist_nitems(alp)),
81bf994817SAli Bahrami 	    EC_XWORD(desc_used), EC_XWORD(desc_cnt),
82bf994817SAli Bahrami 	    (desc_cnt == 0) ? 100 : EC_WORD((desc_used * 100) / desc_cnt),
83bf994817SAli Bahrami 	    EC_XWORD(bytes),
84bf994817SAli Bahrami 	    fmt_human_units(bytes, unit_buf, sizeof (unit_buf)));
85bf994817SAli Bahrami }
86bf994817SAli Bahrami 
87bf994817SAli Bahrami 
88bf994817SAli Bahrami /*
89bf994817SAli Bahrami  * Generate a statistics line for the auxiliary relocation descriptor cache.
90bf994817SAli Bahrami  *
91bf994817SAli Bahrami  * entry:
92bf994817SAli Bahrami  *	ofl - output file descriptor
93bf994817SAli Bahrami  */
94bf994817SAli Bahrami static void
rel_aux_cache_statistics(Ofl_desc * ofl)95bf994817SAli Bahrami rel_aux_cache_statistics(Ofl_desc *ofl)
96bf994817SAli Bahrami {
97bf994817SAli Bahrami 	Rel_aux_cachebuf	*racp;
98bf994817SAli Bahrami 	Lm_list	*lml = ofl->ofl_lml;
99bf994817SAli Bahrami 	size_t	desc_cnt = 0, desc_used = 0, bytes;
100bf994817SAli Bahrami 	Aliste	idx;
101bf994817SAli Bahrami 	char	unit_buf[CONV_INV_BUFSIZE + 10];
102bf994817SAli Bahrami 
103bf994817SAli Bahrami 	/* Sum the total memory allocated across all the buffers */
104bf994817SAli Bahrami 	for (APLIST_TRAVERSE(ofl->ofl_relaux, idx, racp)) {
105bf994817SAli Bahrami 		desc_cnt += racp->rac_end - racp->rac_arr;
106bf994817SAli Bahrami 		desc_used += racp->rac_free - racp->rac_arr;
107bf994817SAli Bahrami 	}
108bf994817SAli Bahrami 	bytes = desc_cnt * sizeof (Rel_desc);
109bf994817SAli Bahrami 
110bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_ACACHE),
111bf994817SAli Bahrami 	    EC_WORD(aplist_nitems(ofl->ofl_relaux)),
112bf994817SAli Bahrami 	    EC_XWORD(desc_used), EC_XWORD(desc_cnt),
113bf994817SAli Bahrami 	    (desc_cnt == 0) ? 100 : EC_WORD((desc_used * 100) / desc_cnt),
114bf994817SAli Bahrami 	    EC_XWORD(bytes),
115bf994817SAli Bahrami 	    fmt_human_units(bytes, unit_buf, sizeof (unit_buf)));
116bf994817SAli Bahrami }
117bf994817SAli Bahrami 
118bf994817SAli Bahrami 
1197c478bd9Sstevel@tonic-gate void
Dbg_statistics_ld(Ofl_desc * ofl)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 
146bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_OUT),
147bf994817SAli Bahrami 	    EC_XWORD(ofl->ofl_outrels.rc_cnt));
148bf994817SAli Bahrami 
149bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_IN),
150bf994817SAli Bahrami 	    EC_XWORD(ofl->ofl_entrelscnt), EC_XWORD(ofl->ofl_actrels.rc_cnt));
151bf994817SAli Bahrami 
152bf994817SAli Bahrami 	dbg_print(lml, MSG_INTL(MSG_STATS_REL_TICACHE));
153bf994817SAli Bahrami 	rel_cache_statistics(ofl, MSG_INTL(MSG_STATS_REL_TIOUT),
154bf994817SAli Bahrami 	    ofl->ofl_outrels.rc_list);
155bf994817SAli Bahrami 	rel_cache_statistics(ofl, MSG_INTL(MSG_STATS_REL_TIACT),
156bf994817SAli Bahrami 	    ofl->ofl_actrels.rc_list);
157bf994817SAli Bahrami 	rel_aux_cache_statistics(ofl);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate void
Dbg_statistics_ar(Ofl_desc * ofl)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;
187*ad24f9fbSToomas Soome 		while ((arsym != NULL) && (arsym->as_off != 0)) {
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;
20210a268c1SRichard Lowe 
2035aefb655Srie 		dbg_print(lml, MSG_INTL(MSG_STATS_AR), adp->ad_name, count,
2045aefb655Srie 		    used, ((used * 100) / count));
2057c478bd9Sstevel@tonic-gate 	}
2065aefb655Srie 	Dbg_util_nl(lml, DBG_NL_STD);
2077c478bd9Sstevel@tonic-gate }
208