Home | History | Annotate | Download | only in common
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #include	"msg.h"
     28 #include	"_debug.h"
     29 #include	"libld.h"
     30 
     31 /*
     32  * If any run-time linker debugging is being carried out always indicate the
     33  * fact and specify the point at which we transfer control to the main program.
     34  */
     35 void
     36 Dbg_util_call_main(Rt_map *lmp)
     37 {
     38 	Lm_list	*lml = LIST(lmp);
     39 
     40 	Dbg_util_nl(lml, DBG_NL_FRC);
     41 	dbg_print(lml, MSG_INTL(MSG_UTL_TRANS), NAME(lmp));
     42 	Dbg_util_nl(lml, DBG_NL_FRC);
     43 }
     44 
     45 void
     46 Dbg_util_call_init(Rt_map *lmp, int flag)
     47 {
     48 	Lm_list		*lml = LIST(lmp);
     49 	const char	*str;
     50 
     51 	if (DBG_NOTCLASS(DBG_C_INIT))
     52 		return;
     53 
     54 	if (flag == DBG_INIT_SORT)
     55 		str = MSG_INTL(MSG_UTL_SORT);
     56 	else if (flag == DBG_INIT_PEND)
     57 		str = MSG_INTL(MSG_UTL_PEND);
     58 	else if (flag == DBG_INIT_DYN)
     59 		str = MSG_INTL(MSG_UTL_DYN);
     60 	else
     61 		str = MSG_INTL(MSG_UTL_DONE);
     62 
     63 	Dbg_util_nl(lml, DBG_NL_STD);
     64 	dbg_print(lml, MSG_INTL(MSG_UTL_INIT), str, NAME(lmp));
     65 	Dbg_util_nl(lml, DBG_NL_STD);
     66 }
     67 
     68 void
     69 Dbg_util_no_init(Rt_map *lmp)
     70 {
     71 	Lm_list	*lml = LIST(lmp);
     72 
     73 	if (DBG_NOTCLASS(DBG_C_INIT))
     74 		return;
     75 
     76 	Dbg_util_nl(lml, DBG_NL_STD);
     77 	dbg_print(lml, MSG_INTL(MSG_UTL_NOINIT), NAME(lmp));
     78 	Dbg_util_nl(lml, DBG_NL_STD);
     79 }
     80 
     81 void
     82 Dbg_util_intoolate(Rt_map *lmp)
     83 {
     84 	Lm_list	*lml = LIST(lmp);
     85 
     86 	Dbg_util_nl(lml, DBG_NL_STD);
     87 	dbg_print(lml, MSG_INTL(MSG_UTL_INTOOLATE), NAME(lmp));
     88 	Dbg_util_nl(lml, DBG_NL_STD);
     89 }
     90 
     91 void
     92 Dbg_util_dbnotify(Lm_list *lml, rd_event_e event, r_state_e state)
     93 {
     94 	const char	*estr;
     95 	const char	*sstr;
     96 
     97 	if (DBG_NOTCLASS(DBG_C_FILES))
     98 		return;
     99 	if (DBG_NOTDETAIL())
    100 		return;
    101 
    102 	switch (event) {
    103 	case RD_PREINIT:
    104 		estr = MSG_ORIG(MSG_UTL_EVNT_PREINIT);
    105 		sstr = MSG_INTL(MSG_STR_NULL);
    106 		break;
    107 	case RD_POSTINIT:
    108 		estr = MSG_ORIG(MSG_UTL_EVNT_POSTINIT);
    109 		sstr = MSG_INTL(MSG_STR_NULL);
    110 		break;
    111 	case RD_DLACTIVITY:
    112 		estr = MSG_ORIG(MSG_UTL_EVNT_DLACT);
    113 		switch (state) {
    114 		case RT_CONSISTENT:
    115 			sstr = MSG_ORIG(MSG_UTL_STA_CONSIST);
    116 			break;
    117 		case RT_ADD:
    118 			sstr = MSG_ORIG(MSG_UTL_STA_ADD);
    119 			break;
    120 		case RT_DELETE:
    121 			sstr = MSG_ORIG(MSG_UTL_STA_DELETE);
    122 			break;
    123 		default:
    124 			sstr = MSG_INTL(MSG_STR_NULL);
    125 			break;
    126 		}
    127 		break;
    128 	default:
    129 		sstr = MSG_INTL(MSG_STR_NULL);
    130 		estr = MSG_INTL(MSG_STR_UNKNOWN);
    131 		break;
    132 	}
    133 
    134 	Dbg_util_nl(lml, DBG_NL_STD);
    135 	dbg_print(lml, MSG_INTL(MSG_UTL_DBNOTIFY), estr, sstr);
    136 	Dbg_util_nl(lml, DBG_NL_STD);
    137 }
    138 
    139 void
    140 Dbg_util_call_array(Rt_map *lmp, void *addr, int ndx, Word shtype)
    141 {
    142 	Lm_list		*lml = LIST(lmp);
    143 	const char	*str;
    144 
    145 	if (DBG_NOTCLASS(DBG_C_INIT))
    146 		return;
    147 
    148 	if (shtype == SHT_INIT_ARRAY)
    149 		str = MSG_ORIG(MSG_SCN_INITARRAY);
    150 	else if (shtype == SHT_FINI_ARRAY)
    151 		str = MSG_ORIG(MSG_SCN_FINIARRAY);
    152 	else
    153 		str = MSG_ORIG(MSG_SCN_PREINITARRAY);
    154 
    155 	dbg_print(lml, MSG_INTL(MSG_UTL_ARRAY), str, ndx, EC_NATPTR(addr),
    156 	    NAME(lmp));
    157 }
    158 
    159 void
    160 Dbg_util_call_fini(Rt_map *lmp)
    161 {
    162 	Lm_list	*lml = LIST(lmp);
    163 
    164 	if (DBG_NOTCLASS(DBG_C_INIT))
    165 		return;
    166 
    167 	Dbg_util_nl(lml, DBG_NL_STD);
    168 	dbg_print(lml, MSG_INTL(MSG_UTL_FINI), NAME(lmp));
    169 	Dbg_util_nl(lml, DBG_NL_STD);
    170 }
    171 
    172 void
    173 Dbg_util_str(Lm_list *lml, const char *str)
    174 {
    175 	Dbg_util_nl(lml, DBG_NL_STD);
    176 	Dbg_util_nl(lml, DBG_NL_FRC);
    177 	dbg_print(lml, MSG_ORIG(MSG_FMT_STR), str);
    178 	Dbg_util_nl(lml, DBG_NL_FRC);
    179 	Dbg_util_nl(lml, DBG_NL_STD);
    180 }
    181 
    182 void
    183 Dbg_util_scc_title(Lm_list *lml, int sec)
    184 {
    185 	const char	*_sec;
    186 
    187 	if (DBG_NOTCLASS(DBG_C_INIT))
    188 		return;
    189 	if (DBG_NOTDETAIL())
    190 		return;
    191 
    192 	if (sec)
    193 		_sec = MSG_INTL(MSG_UTL_SCC_SUBI);
    194 	else
    195 		_sec = MSG_INTL(MSG_UTL_SCC_SUBF);
    196 
    197 	Dbg_util_nl(lml, DBG_NL_STD);
    198 	dbg_print(lml, MSG_INTL(MSG_UTL_SCC_TITLE), _sec);
    199 }
    200 
    201 void
    202 Dbg_util_scc_entry(Rt_map *lmp, uint_t idx)
    203 {
    204 	if (DBG_NOTCLASS(DBG_C_INIT))
    205 		return;
    206 	if (DBG_NOTDETAIL())
    207 		return;
    208 
    209 	dbg_print(LIST(lmp), MSG_ORIG(MSG_UTL_SCC_ENTRY), idx, NAME(lmp));
    210 }
    211 
    212 static	int ectoggle = 0;
    213 
    214 void
    215 Dbg_util_edge_in(Lm_list *lml, Rt_map *clmp, uint_t flags, Rt_map *dlmp,
    216     int ndx, int flag)
    217 {
    218 	Conv_bnd_type_buf_t	bnd_type_buf;
    219 	const char		*str;
    220 
    221 	if (DBG_NOTCLASS(DBG_C_INIT))
    222 		return;
    223 	if (DBG_NOTDETAIL())
    224 		return;
    225 
    226 	if (flag & RT_SORT_REV)
    227 		str = MSG_ORIG(MSG_SCN_INIT);
    228 	else
    229 		str = MSG_ORIG(MSG_SCN_FINI);
    230 
    231 	if ((clmp == 0) || (ectoggle == 0))
    232 		Dbg_util_nl(lml, DBG_NL_STD);
    233 	if (clmp == 0) {
    234 		if (flag & RT_SORT_INTPOSE)
    235 			dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_I), str);
    236 		else
    237 			dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_S), str);
    238 
    239 		dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_START), ndx, NAME(dlmp));
    240 	} else
    241 		dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_IN), ndx, NAME(dlmp),
    242 		    NAME(clmp), conv_bnd_type(flags, &bnd_type_buf));
    243 
    244 	ectoggle = 1;
    245 }
    246 
    247 void
    248 Dbg_util_edge_out(Rt_map *clmp, Rt_map *dlmp)
    249 {
    250 	if (DBG_NOTCLASS(DBG_C_INIT))
    251 		return;
    252 	if (DBG_NOTDETAIL())
    253 		return;
    254 
    255 	dbg_print(LIST(clmp), MSG_INTL(MSG_UTL_EDGE_OUT), SORTVAL(clmp),
    256 	    NAME(clmp), NAME(dlmp));
    257 }
    258 
    259 void
    260 Dbg_util_collect(Rt_map *lmp, int ndx, int flag)
    261 {
    262 	Lm_list		*lml = LIST(lmp);
    263 	const char	*str;
    264 
    265 	if (DBG_NOTCLASS(DBG_C_INIT))
    266 		return;
    267 	if (DBG_NOTDETAIL())
    268 		return;
    269 
    270 	if (flag & RT_SORT_REV)
    271 		str = MSG_ORIG(MSG_SCN_INIT);
    272 	else
    273 		str = MSG_ORIG(MSG_SCN_FINI);
    274 
    275 	if (ectoggle == 1) {
    276 		Dbg_util_nl(lml, DBG_NL_STD);
    277 		ectoggle = 0;
    278 	}
    279 	dbg_print(lml, MSG_INTL(MSG_UTL_COLLECT), ndx, NAME(lmp), str);
    280 }
    281 
    282 static const Msg	tags[] = {
    283 	MSG_CI_NULL,		/* MSG_ORIG(MSG_CI_NULL) */
    284 	MSG_CI_VERSION,		/* MSG_ORIG(MSG_CI_VERSION) */
    285 	MSG_CI_ATEXIT,		/* MSG_ORIG(MSG_CI_ATEXIT) */
    286 	MSG_CI_LCMESSAGES,	/* MSG_ORIG(MSG_CI_LCMESSAGES) */
    287 	MSG_CI_BIND_GUARD,	/* MSG_ORIG(MSG_CI_BIND_GUARD) */
    288 	MSG_CI_BIND_CLEAR,	/* MSG_ORIG(MSG_CI_BIND_CLEAR) */
    289 	MSG_CI_THR_SELF,	/* MSG_ORIG(MSG_CI_THR_SELF) */
    290 	MSG_CI_TLS_MODADD,	/* MSG_ORIG(MSG_CI_TLS_MODADD) */
    291 	MSG_CI_TLS_MODREM,	/* MSG_ORIG(MSG_CI_TLS_MODREM) */
    292 	MSG_CI_TLS_STATMOD,	/* MSG_ORIG(MSG_CI_TLS_STATMOD) */
    293 	MSG_CI_THRINIT,		/* MSG_ORIG(MSG_CI_THRINIT) */
    294 	MSG_CI_CRITICAL		/* MSG_ORIG(MSG_CI_CRITICAL) */
    295 };
    296 
    297 void
    298 Dbg_util_lcinterface(Rt_map *lmp, int tag, char *val)
    299 {
    300 	const char	*str;
    301 	Conv_inv_buf_t	inv_buf;
    302 
    303 	if (DBG_NOTDETAIL())
    304 		return;
    305 
    306 	if (tag < CI_MAX)
    307 		str = MSG_ORIG(tags[tag]);
    308 	else
    309 		str = conv_invalid_val(&inv_buf, tag, 0);
    310 
    311 	dbg_print(LIST(lmp), MSG_INTL(MSG_UTL_LCINTERFACE), NAME(lmp), str,
    312 	    EC_NATPTR(val));
    313 }
    314 
    315 void
    316 Dbg_unused_lcinterface(Rt_map *nlmp, Rt_map *olmp, int tag)
    317 {
    318 	const char	*str;
    319 	Conv_inv_buf_t	inv_buf;
    320 
    321 	if (DBG_NOTCLASS(DBG_C_UNUSED))
    322 		return;
    323 
    324 	if (tag < CI_MAX)
    325 		str = MSG_ORIG(tags[tag]);
    326 	else
    327 		str = conv_invalid_val(&inv_buf, tag, 0);
    328 
    329 	dbg_print(LIST(nlmp), MSG_INTL(MSG_USD_LCINTERFACE), NAME(nlmp), str,
    330 	    NAME(olmp));
    331 }
    332 
    333 /*
    334  * Generic new line generator.  To prevent multiple newlines from being
    335  * generated, a flag is maintained in the global debug descriptor.  This flag
    336  * is cleared by the callers dbg_print() function to indicate that a newline
    337  * (actually, any line) has been printed.  Multiple newlines can be generated
    338  * using the DBG_NL_FRC flag.
    339  */
    340 void
    341 Dbg_util_nl(Lm_list *lml, int flag)
    342 {
    343 	if ((flag == DBG_NL_STD) && (dbg_desc->d_extra & DBG_E_STDNL))
    344 		return;
    345 
    346 	dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY));
    347 
    348 	if (flag == DBG_NL_STD)
    349 		dbg_desc->d_extra |= DBG_E_STDNL;
    350 }
    351 
    352 /*
    353  * Define name demanglers.
    354  */
    355 const char *
    356 Dbg_demangle_name(const char *name)
    357 {
    358 	if (DBG_NOTCLASS(DBG_C_DEMANGLE))
    359 		return (name);
    360 
    361 	return (conv_demangle_name(name));
    362 }
    363 
    364 const char *
    365 Elf_demangle_name(const char *name)
    366 {
    367 	if (DBG_ISDEMANGLE())
    368 		return (conv_demangle_name(name));
    369 	return (name);
    370 }
    371