10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51618Srie  * Common Development and Distribution License (the "License").
61618Srie  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211618Srie 
220Sstevel@tonic-gate /*
238598SRod.Evans@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #include	"msg.h"
280Sstevel@tonic-gate #include	"_debug.h"
290Sstevel@tonic-gate #include	"libld.h"
300Sstevel@tonic-gate 
310Sstevel@tonic-gate /*
320Sstevel@tonic-gate  * If any run-time linker debugging is being carried out always indicate the
330Sstevel@tonic-gate  * fact and specify the point at which we transfer control to the main program.
340Sstevel@tonic-gate  */
350Sstevel@tonic-gate void
361618Srie Dbg_util_call_main(Rt_map *lmp)
370Sstevel@tonic-gate {
381618Srie 	Lm_list	*lml = LIST(lmp);
391618Srie 
401618Srie 	Dbg_util_nl(lml, DBG_NL_FRC);
411618Srie 	dbg_print(lml, MSG_INTL(MSG_UTL_TRANS), NAME(lmp));
421618Srie 	Dbg_util_nl(lml, DBG_NL_FRC);
430Sstevel@tonic-gate }
440Sstevel@tonic-gate 
450Sstevel@tonic-gate void
461618Srie Dbg_util_call_init(Rt_map *lmp, int flag)
470Sstevel@tonic-gate {
481618Srie 	Lm_list		*lml = LIST(lmp);
491618Srie 	const char	*str;
500Sstevel@tonic-gate 
511618Srie 	if (DBG_NOTCLASS(DBG_C_INIT))
52280Srie 		return;
53280Srie 
540Sstevel@tonic-gate 	if (flag == DBG_INIT_SORT)
550Sstevel@tonic-gate 		str = MSG_INTL(MSG_UTL_SORT);
560Sstevel@tonic-gate 	else if (flag == DBG_INIT_PEND)
570Sstevel@tonic-gate 		str = MSG_INTL(MSG_UTL_PEND);
580Sstevel@tonic-gate 	else if (flag == DBG_INIT_DYN)
590Sstevel@tonic-gate 		str = MSG_INTL(MSG_UTL_DYN);
600Sstevel@tonic-gate 	else
610Sstevel@tonic-gate 		str = MSG_INTL(MSG_UTL_DONE);
620Sstevel@tonic-gate 
631618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
641618Srie 	dbg_print(lml, MSG_INTL(MSG_UTL_INIT), str, NAME(lmp));
651618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
660Sstevel@tonic-gate }
670Sstevel@tonic-gate 
680Sstevel@tonic-gate void
691618Srie Dbg_util_no_init(Rt_map *lmp)
700Sstevel@tonic-gate {
711618Srie 	Lm_list	*lml = LIST(lmp);
721618Srie 
731618Srie 	if (DBG_NOTCLASS(DBG_C_INIT))
74280Srie 		return;
75280Srie 
761618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
771618Srie 	dbg_print(lml, MSG_INTL(MSG_UTL_NOINIT), NAME(lmp));
781618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
790Sstevel@tonic-gate }
800Sstevel@tonic-gate 
810Sstevel@tonic-gate void
821618Srie Dbg_util_intoolate(Rt_map *lmp)
830Sstevel@tonic-gate {
841618Srie 	Lm_list	*lml = LIST(lmp);
851618Srie 
861618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
871618Srie 	dbg_print(lml, MSG_INTL(MSG_UTL_INTOOLATE), NAME(lmp));
881618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
890Sstevel@tonic-gate }
900Sstevel@tonic-gate 
910Sstevel@tonic-gate void
921618Srie Dbg_util_dbnotify(Lm_list *lml, rd_event_e event, r_state_e state)
930Sstevel@tonic-gate {
940Sstevel@tonic-gate 	const char	*estr;
950Sstevel@tonic-gate 	const char	*sstr;
960Sstevel@tonic-gate 
971618Srie 	if (DBG_NOTCLASS(DBG_C_FILES))
980Sstevel@tonic-gate 		return;
990Sstevel@tonic-gate 	if (DBG_NOTDETAIL())
1000Sstevel@tonic-gate 		return;
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	switch (event) {
1030Sstevel@tonic-gate 	case RD_PREINIT:
1040Sstevel@tonic-gate 		estr = MSG_ORIG(MSG_UTL_EVNT_PREINIT);
1050Sstevel@tonic-gate 		sstr = MSG_INTL(MSG_STR_NULL);
1060Sstevel@tonic-gate 		break;
1070Sstevel@tonic-gate 	case RD_POSTINIT:
1080Sstevel@tonic-gate 		estr = MSG_ORIG(MSG_UTL_EVNT_POSTINIT);
1090Sstevel@tonic-gate 		sstr = MSG_INTL(MSG_STR_NULL);
1100Sstevel@tonic-gate 		break;
1110Sstevel@tonic-gate 	case RD_DLACTIVITY:
1120Sstevel@tonic-gate 		estr = MSG_ORIG(MSG_UTL_EVNT_DLACT);
1130Sstevel@tonic-gate 		switch (state) {
1140Sstevel@tonic-gate 		case RT_CONSISTENT:
1150Sstevel@tonic-gate 			sstr = MSG_ORIG(MSG_UTL_STA_CONSIST);
1160Sstevel@tonic-gate 			break;
1170Sstevel@tonic-gate 		case RT_ADD:
1180Sstevel@tonic-gate 			sstr = MSG_ORIG(MSG_UTL_STA_ADD);
1190Sstevel@tonic-gate 			break;
1200Sstevel@tonic-gate 		case RT_DELETE:
1210Sstevel@tonic-gate 			sstr = MSG_ORIG(MSG_UTL_STA_DELETE);
1220Sstevel@tonic-gate 			break;
1230Sstevel@tonic-gate 		default:
1240Sstevel@tonic-gate 			sstr = MSG_INTL(MSG_STR_NULL);
1250Sstevel@tonic-gate 			break;
1260Sstevel@tonic-gate 		}
1270Sstevel@tonic-gate 		break;
1280Sstevel@tonic-gate 	default:
1290Sstevel@tonic-gate 		sstr = MSG_INTL(MSG_STR_NULL);
1300Sstevel@tonic-gate 		estr = MSG_INTL(MSG_STR_UNKNOWN);
1310Sstevel@tonic-gate 		break;
1320Sstevel@tonic-gate 	}
1330Sstevel@tonic-gate 
1341618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1351618Srie 	dbg_print(lml, MSG_INTL(MSG_UTL_DBNOTIFY), estr, sstr);
1361618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate void
1401618Srie Dbg_util_call_array(Rt_map *lmp, void *addr, int ndx, Word shtype)
1410Sstevel@tonic-gate {
1421618Srie 	Lm_list		*lml = LIST(lmp);
1430Sstevel@tonic-gate 	const char	*str;
1440Sstevel@tonic-gate 
1451618Srie 	if (DBG_NOTCLASS(DBG_C_INIT))
1460Sstevel@tonic-gate 		return;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	if (shtype == SHT_INIT_ARRAY)
1490Sstevel@tonic-gate 		str = MSG_ORIG(MSG_SCN_INITARRAY);
1500Sstevel@tonic-gate 	else if (shtype == SHT_FINI_ARRAY)
1510Sstevel@tonic-gate 		str = MSG_ORIG(MSG_SCN_FINIARRAY);
1520Sstevel@tonic-gate 	else
1530Sstevel@tonic-gate 		str = MSG_ORIG(MSG_SCN_PREINITARRAY);
1541618Srie 
1551618Srie 	dbg_print(lml, MSG_INTL(MSG_UTL_ARRAY), str, ndx, EC_NATPTR(addr),
1561618Srie 	    NAME(lmp));
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate void
1601618Srie Dbg_util_call_fini(Rt_map *lmp)
1610Sstevel@tonic-gate {
1621618Srie 	Lm_list	*lml = LIST(lmp);
1631618Srie 
1641618Srie 	if (DBG_NOTCLASS(DBG_C_INIT))
165280Srie 		return;
166280Srie 
1671618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1681618Srie 	dbg_print(lml, MSG_INTL(MSG_UTL_FINI), NAME(lmp));
1691618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1700Sstevel@tonic-gate }
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate void
1731618Srie Dbg_util_str(Lm_list *lml, const char *str)
1740Sstevel@tonic-gate {
1751618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1761618Srie 	Dbg_util_nl(lml, DBG_NL_FRC);
1771618Srie 	dbg_print(lml, MSG_ORIG(MSG_FMT_STR), str);
1781618Srie 	Dbg_util_nl(lml, DBG_NL_FRC);
1791618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate void
1831618Srie Dbg_util_scc_title(Lm_list *lml, int sec)
1840Sstevel@tonic-gate {
1850Sstevel@tonic-gate 	const char	*_sec;
1860Sstevel@tonic-gate 
1871618Srie 	if (DBG_NOTCLASS(DBG_C_INIT))
188280Srie 		return;
189280Srie 	if (DBG_NOTDETAIL())
190280Srie 		return;
191280Srie 
1920Sstevel@tonic-gate 	if (sec)
193280Srie 		_sec = MSG_INTL(MSG_UTL_SCC_SUBI);
1940Sstevel@tonic-gate 	else
195280Srie 		_sec = MSG_INTL(MSG_UTL_SCC_SUBF);
1960Sstevel@tonic-gate 
1971618Srie 	Dbg_util_nl(lml, DBG_NL_STD);
1981618Srie 	dbg_print(lml, MSG_INTL(MSG_UTL_SCC_TITLE), _sec);
1990Sstevel@tonic-gate }
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate void
2021618Srie Dbg_util_scc_entry(Rt_map *lmp, uint_t idx)
2030Sstevel@tonic-gate {
2041618Srie 	if (DBG_NOTCLASS(DBG_C_INIT))
205280Srie 		return;
206280Srie 	if (DBG_NOTDETAIL())
207280Srie 		return;
208280Srie 
2091618Srie 	dbg_print(LIST(lmp), MSG_ORIG(MSG_UTL_SCC_ENTRY), idx, NAME(lmp));
2100Sstevel@tonic-gate }
2110Sstevel@tonic-gate 
212280Srie static	int ectoggle = 0;
213280Srie 
214280Srie void
2151618Srie Dbg_util_edge_in(Lm_list *lml, Rt_map *clmp, uint_t flags, Rt_map *dlmp,
2161618Srie     int ndx, int flag)
217280Srie {
2184734Sab196087 	Conv_bnd_type_buf_t	bnd_type_buf;
2194734Sab196087 	const char		*str;
220280Srie 
2211618Srie 	if (DBG_NOTCLASS(DBG_C_INIT))
222280Srie 		return;
223280Srie 	if (DBG_NOTDETAIL())
224280Srie 		return;
225280Srie 
226280Srie 	if (flag & RT_SORT_REV)
227280Srie 		str = MSG_ORIG(MSG_SCN_INIT);
228280Srie 	else
229280Srie 		str = MSG_ORIG(MSG_SCN_FINI);
230280Srie 
231280Srie 	if ((clmp == 0) || (ectoggle == 0))
2321618Srie 		Dbg_util_nl(lml, DBG_NL_STD);
233280Srie 	if (clmp == 0) {
2343817Srie 		if (flag & RT_SORT_INTPOSE)
2353817Srie 			dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_I), str);
2363817Srie 		else
2373817Srie 			dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_S), str);
2383817Srie 
2391618Srie 		dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_START), ndx, NAME(dlmp));
240280Srie 	} else
2411618Srie 		dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_IN), ndx, NAME(dlmp),
2424734Sab196087 		    NAME(clmp), conv_bnd_type(flags, &bnd_type_buf));
243280Srie 
244280Srie 	ectoggle = 1;
245280Srie }
246280Srie 
247280Srie void
2481618Srie Dbg_util_edge_out(Rt_map *clmp, Rt_map *dlmp)
249280Srie {
2501618Srie 	if (DBG_NOTCLASS(DBG_C_INIT))
251280Srie 		return;
252280Srie 	if (DBG_NOTDETAIL())
253280Srie 		return;
254280Srie 
2551618Srie 	dbg_print(LIST(clmp), MSG_INTL(MSG_UTL_EDGE_OUT), SORTVAL(clmp),
2561618Srie 	    NAME(clmp), NAME(dlmp));
257280Srie }
258280Srie 
259280Srie void
2601618Srie Dbg_util_collect(Rt_map *lmp, int ndx, int flag)
261280Srie {
2621618Srie 	Lm_list		*lml = LIST(lmp);
263280Srie 	const char	*str;
264280Srie 
2651618Srie 	if (DBG_NOTCLASS(DBG_C_INIT))
266280Srie 		return;
267280Srie 	if (DBG_NOTDETAIL())
268280Srie 		return;
269280Srie 
270280Srie 	if (flag & RT_SORT_REV)
271280Srie 		str = MSG_ORIG(MSG_SCN_INIT);
272280Srie 	else
273280Srie 		str = MSG_ORIG(MSG_SCN_FINI);
274280Srie 
275280Srie 	if (ectoggle == 1) {
2761618Srie 		Dbg_util_nl(lml, DBG_NL_STD);
277280Srie 		ectoggle = 0;
278280Srie 	}
2791618Srie 	dbg_print(lml, MSG_INTL(MSG_UTL_COLLECT), ndx, NAME(lmp), str);
2801618Srie }
2811618Srie 
2821824Srie static const Msg	tags[] = {
2831824Srie 	MSG_CI_NULL,		/* MSG_ORIG(MSG_CI_NULL) */
2841824Srie 	MSG_CI_VERSION,		/* MSG_ORIG(MSG_CI_VERSION) */
2851824Srie 	MSG_CI_ATEXIT,		/* MSG_ORIG(MSG_CI_ATEXIT) */
2861824Srie 	MSG_CI_LCMESSAGES,	/* MSG_ORIG(MSG_CI_LCMESSAGES) */
2871824Srie 	MSG_CI_BIND_GUARD,	/* MSG_ORIG(MSG_CI_BIND_GUARD) */
2881824Srie 	MSG_CI_BIND_CLEAR,	/* MSG_ORIG(MSG_CI_BIND_CLEAR) */
2891824Srie 	MSG_CI_THR_SELF,	/* MSG_ORIG(MSG_CI_THR_SELF) */
2901824Srie 	MSG_CI_TLS_MODADD,	/* MSG_ORIG(MSG_CI_TLS_MODADD) */
2911824Srie 	MSG_CI_TLS_MODREM,	/* MSG_ORIG(MSG_CI_TLS_MODREM) */
2921824Srie 	MSG_CI_TLS_STATMOD,	/* MSG_ORIG(MSG_CI_TLS_STATMOD) */
293*9569SRod.Evans@Sun.COM 	MSG_CI_THRINIT,		/* MSG_ORIG(MSG_CI_THRINIT) */
294*9569SRod.Evans@Sun.COM 	MSG_CI_CRITICAL		/* MSG_ORIG(MSG_CI_CRITICAL) */
2951824Srie };
2961824Srie 
2971824Srie void
2981824Srie Dbg_util_lcinterface(Rt_map *lmp, int tag, char *val)
2991824Srie {
3004734Sab196087 	const char	*str;
3014734Sab196087 	Conv_inv_buf_t	inv_buf;
3021824Srie 
3031824Srie 	if (DBG_NOTDETAIL())
3041824Srie 		return;
3051824Srie 
3061824Srie 	if (tag < CI_MAX)
3071824Srie 		str = MSG_ORIG(tags[tag]);
3081824Srie 	else
3094734Sab196087 		str = conv_invalid_val(&inv_buf, tag, 0);
3101824Srie 
3111824Srie 	dbg_print(LIST(lmp), MSG_INTL(MSG_UTL_LCINTERFACE), NAME(lmp), str,
3121824Srie 	    EC_NATPTR(val));
3131824Srie }
3141824Srie 
3151824Srie void
3161824Srie Dbg_unused_lcinterface(Rt_map *nlmp, Rt_map *olmp, int tag)
3171824Srie {
3184734Sab196087 	const char	*str;
3194734Sab196087 	Conv_inv_buf_t	inv_buf;
3201824Srie 
3211824Srie 	if (DBG_NOTCLASS(DBG_C_UNUSED))
3221824Srie 		return;
3231824Srie 
3241824Srie 	if (tag < CI_MAX)
3251824Srie 		str = MSG_ORIG(tags[tag]);
3261824Srie 	else
3274734Sab196087 		str = conv_invalid_val(&inv_buf, tag, 0);
3281824Srie 
3291824Srie 	dbg_print(LIST(nlmp), MSG_INTL(MSG_USD_LCINTERFACE), NAME(nlmp), str,
3301824Srie 	    NAME(olmp));
3311824Srie }
3321824Srie 
3331618Srie /*
3341618Srie  * Generic new line generator.  To prevent multiple newlines from being
3351618Srie  * generated, a flag is maintained in the global debug descriptor.  This flag
3361618Srie  * is cleared by the callers dbg_print() function to indicate that a newline
3371618Srie  * (actually, any line) has been printed.  Multiple newlines can be generated
3381618Srie  * using the DBG_NL_FRC flag.
3391618Srie  */
3401618Srie void
3411618Srie Dbg_util_nl(Lm_list *lml, int flag)
3421618Srie {
3431618Srie 	if ((flag == DBG_NL_STD) && (dbg_desc->d_extra & DBG_E_STDNL))
3441618Srie 		return;
3451618Srie 
3461618Srie 	dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY));
3471618Srie 
3481618Srie 	if (flag == DBG_NL_STD)
3491618Srie 		dbg_desc->d_extra |= DBG_E_STDNL;
350280Srie }
3511618Srie 
3521618Srie /*
3531618Srie  * Define name demanglers.
3541618Srie  */
3551618Srie const char *
3561618Srie Dbg_demangle_name(const char *name)
3571618Srie {
3581618Srie 	if (DBG_NOTCLASS(DBG_C_DEMANGLE))
3591618Srie 		return (name);
3601618Srie 
3611618Srie 	return (conv_demangle_name(name));
3621618Srie }
3631618Srie 
3641618Srie const char *
3651618Srie Elf_demangle_name(const char *name)
3661618Srie {
3671618Srie 	if (DBG_ISDEMANGLE())
3681618Srie 		return (conv_demangle_name(name));
3691618Srie 	return (name);
3701618Srie }
371