1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include	"_debug.h"
29 #include	"msg.h"
30 #include	"libld.h"
31 
32 void
33 Dbg_statistics_ld(Ofl_desc *ofl)
34 {
35 	Lm_list	*lml = ofl->ofl_lml;
36 
37 	if (DBG_NOTCLASS(DBG_C_STATS))
38 		return;
39 
40 	Dbg_util_nl(lml, DBG_NL_STD);
41 	dbg_print(lml, MSG_INTL(MSG_STATS_GENERAL));
42 
43 	if (ofl->ofl_objscnt || ofl->ofl_soscnt || ofl->ofl_arscnt) {
44 		dbg_print(lml, MSG_INTL(MSG_STATS_FILES),
45 		    EC_XWORD(ofl->ofl_objscnt), EC_XWORD(ofl->ofl_soscnt),
46 		    EC_XWORD(ofl->ofl_arscnt));
47 	}
48 
49 	if (ofl->ofl_locscnt || ofl->ofl_globcnt) {
50 		dbg_print(lml, MSG_INTL(MSG_STATS_SYMBOLS_OUT),
51 		    EC_XWORD(ofl->ofl_globcnt), EC_XWORD(ofl->ofl_locscnt));
52 	}
53 	if (ofl->ofl_entercnt || ofl->ofl_scopecnt || ofl->ofl_elimcnt) {
54 		dbg_print(lml, MSG_INTL(MSG_STATS_SYMBOLS_IN),
55 		    EC_XWORD(ofl->ofl_entercnt), EC_XWORD(ofl->ofl_scopecnt),
56 		    EC_XWORD(ofl->ofl_elimcnt));
57 	}
58 
59 	if (ofl->ofl_outrelscnt) {
60 		dbg_print(lml, MSG_INTL(MSG_STATS_RELOCS_OUT),
61 		    EC_XWORD(ofl->ofl_outrelscnt));
62 	}
63 	if (ofl->ofl_entrelscnt || ofl->ofl_actrelscnt) {
64 		dbg_print(lml, MSG_INTL(MSG_STATS_RELOCS_IN),
65 		    EC_XWORD(ofl->ofl_entrelscnt),
66 		    EC_XWORD(ofl->ofl_actrelscnt));
67 	}
68 }
69 
70 void
71 Dbg_statistics_ar(Ofl_desc *ofl)
72 {
73 	Listnode	*lnp;
74 	Ar_desc		*adp;
75 	Elf_Arsym	*arsym;
76 	Ar_aux		*aux;
77 	Lm_list		*lml = ofl->ofl_lml;
78 
79 	if (DBG_NOTCLASS(DBG_C_STATS | DBG_C_UNUSED))
80 		return;
81 
82 	Dbg_util_nl(lml, DBG_NL_STD);
83 	for (LIST_TRAVERSE(&ofl->ofl_ars, lnp, adp)) {
84 		size_t	poffset = 0;
85 		uint_t	count = 0, used = 0;
86 
87 		if ((adp->ad_flags & FLG_ARD_EXTRACT) == 0) {
88 			Dbg_unused_file(lml, adp->ad_name, 0, 0);
89 			continue;
90 		}
91 
92 		if (DBG_NOTCLASS(DBG_C_STATS))
93 			continue;
94 
95 		arsym = adp->ad_start;
96 		aux = adp->ad_aux;
97 		while (arsym->as_off) {
98 			/*
99 			 * Assume that symbols from the same member file are
100 			 * adjacent within the archive symbol table.
101 			 */
102 			if (poffset != arsym->as_off) {
103 				count++;
104 				poffset = arsym->as_off;
105 				if (aux->au_mem == FLG_ARMEM_PROC)
106 					used++;
107 			}
108 			aux++, arsym++;
109 		}
110 		if ((count == 0) || (used == 0))
111 			continue;
112 #ifndef	UDIV_NOT_SUPPORTED
113 		dbg_print(lml, MSG_INTL(MSG_STATS_AR), adp->ad_name, count,
114 		    used, ((used * 100) / count));
115 #endif
116 	}
117 	Dbg_util_nl(lml, DBG_NL_STD);
118 }
119