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