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
5*5aefb655Srie  * Common Development and Distribution License (the "License").
6*5aefb655Srie  * 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  */
21*5aefb655Srie 
227c478bd9Sstevel@tonic-gate /*
23*5aefb655Srie  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
28*5aefb655Srie #define		dgettext	_dgettext
29*5aefb655Srie 
30*5aefb655Srie #include	<libintl.h>
31*5aefb655Srie #include	<sys/varargs.h>
327c478bd9Sstevel@tonic-gate #include	<stdio.h>
337c478bd9Sstevel@tonic-gate #include	<string.h>
347c478bd9Sstevel@tonic-gate #include	<stdlib.h>
35*5aefb655Srie #include	<alist.h>
36*5aefb655Srie #include	<debug.h>
37*5aefb655Srie #include	<_debug.h>
38*5aefb655Srie #include	<msg.h>
397c478bd9Sstevel@tonic-gate 
40*5aefb655Srie /*
41*5aefb655Srie  * Define a debug descriptor.  Note, although this provides the default
42*5aefb655Srie  * definition to which most users bind, ld.so.1 must provide its own definition,
43*5aefb655Srie  * and thus interposition is expected.  This item should be defined NODIRECT.
44*5aefb655Srie  */
45*5aefb655Srie static Dbg_desc	_dbg_desc = { 0, 0, 0 };
46*5aefb655Srie Dbg_desc	*dbg_desc = &_dbg_desc;
477c478bd9Sstevel@tonic-gate 
48*5aefb655Srie int		_Dbg_cnt = 0;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate /*
51*5aefb655Srie  * Debugging initialization and processing.  The dbg_options[] array defines
527c478bd9Sstevel@tonic-gate  * a set of option strings that can be specified using the -D flag or from an
53*5aefb655Srie  * environment variable.  For each option, a class is enabled in the d_class
54*5aefb655Srie  * bit mask, or an extra flag is enabled in the d_extra bit mask.
557c478bd9Sstevel@tonic-gate  */
56*5aefb655Srie DBG_options _Dbg_options[] = {
57*5aefb655Srie 	{MSG_ORIG(MSG_TOK_DETAIL),	0,	DBG_E_DETAIL},
58*5aefb655Srie 	{MSG_ORIG(MSG_TOK_LONG),	0,	DBG_E_LONG},
59*5aefb655Srie 	{MSG_ORIG(MSG_TOK_NAME),	0,	DBG_E_SNAME},
60*5aefb655Srie 	{MSG_ORIG(MSG_TOK_FULLNAME),	0,	DBG_E_SNAME | DBG_E_FNAME},
61*5aefb655Srie 	{MSG_ORIG(MSG_TOK_CLASS),	0,	DBG_E_SNAME | DBG_E_CLASS},
62*5aefb655Srie 	{MSG_ORIG(MSG_TOK_LMID),	0,	DBG_E_LMID},
63*5aefb655Srie 
64*5aefb655Srie 	{MSG_ORIG(MSG_TOK_ALL),		DBG_C_ALL,	0},
65*5aefb655Srie 	{MSG_ORIG(MSG_TOK_ARGS),	DBG_C_ARGS,	0},
66*5aefb655Srie 	{MSG_ORIG(MSG_TOK_BASIC),	DBG_C_BASIC,	0},
67*5aefb655Srie 	{MSG_ORIG(MSG_TOK_BINDINGS),	DBG_C_BINDINGS,	0},
68*5aefb655Srie 	{MSG_ORIG(MSG_TOK_ENTRY),	DBG_C_ENTRY,	0},
69*5aefb655Srie 	{MSG_ORIG(MSG_TOK_FILES),	DBG_C_FILES,	0},
70*5aefb655Srie 	{MSG_ORIG(MSG_TOK_HELP),	DBG_C_HELP,	0},
71*5aefb655Srie 	{MSG_ORIG(MSG_TOK_LIBS),	DBG_C_LIBS,	0},
72*5aefb655Srie 	{MSG_ORIG(MSG_TOK_MAP),		DBG_C_MAP,	0},
73*5aefb655Srie 	{MSG_ORIG(MSG_TOK_RELOC),	DBG_C_RELOC,	0},
74*5aefb655Srie 	{MSG_ORIG(MSG_TOK_SECTIONS),	DBG_C_SECTIONS,	0},
75*5aefb655Srie 	{MSG_ORIG(MSG_TOK_SEGMENTS),	DBG_C_SEGMENTS,	0},
76*5aefb655Srie 	{MSG_ORIG(MSG_TOK_SUPPORT),	DBG_C_SUPPORT,	0},
77*5aefb655Srie 	{MSG_ORIG(MSG_TOK_SYMBOLS),	DBG_C_SYMBOLS,	0},
78*5aefb655Srie 	{MSG_ORIG(MSG_TOK_TLS),		DBG_C_TLS,	0},
79*5aefb655Srie 	{MSG_ORIG(MSG_TOK_AUDIT),	DBG_C_AUDITING,	0},
80*5aefb655Srie 	{MSG_ORIG(MSG_TOK_VERSIONS),	DBG_C_VERSIONS,	0},
81*5aefb655Srie 	{MSG_ORIG(MSG_TOK_GOT),		DBG_C_GOT,	0},
82*5aefb655Srie 	{MSG_ORIG(MSG_TOK_MOVE),	DBG_C_MOVE,	0},
83*5aefb655Srie 	{MSG_ORIG(MSG_TOK_STRTAB),	DBG_C_STRTAB,	0},
84*5aefb655Srie 	{MSG_ORIG(MSG_TOK_STATS),	DBG_C_STATS,	0},
85*5aefb655Srie 	{MSG_ORIG(MSG_TOK_UNUSED),	DBG_C_UNUSED,	0},
867c478bd9Sstevel@tonic-gate #ifdef	DEMANGLE
87*5aefb655Srie 	{MSG_ORIG(MSG_TOK_DEMANGLE),	DBG_C_DEMANGLE,	0},
887c478bd9Sstevel@tonic-gate #endif
89*5aefb655Srie 	{MSG_ORIG(MSG_TOK_CAP),		DBG_C_CAP,	0},
90*5aefb655Srie 	{MSG_ORIG(MSG_TOK_INIT),	DBG_C_INIT,	0},
917c478bd9Sstevel@tonic-gate 	{NULL,				NULL},
927c478bd9Sstevel@tonic-gate };
937c478bd9Sstevel@tonic-gate 
94*5aefb655Srie /*
95*5aefb655Srie  * Tokens may also define identifiers for diagnostics.  Presently, only ld.so.1
96*5aefb655Srie  * uses these strings to identify, or isolate its output to selected link-map
97*5aefb655Srie  * lists.  See ld.so.1:dbg_print().
98*5aefb655Srie  */
99*5aefb655Srie const char *_Dbg_strs[] = {
100*5aefb655Srie 	MSG_ORIG(MSG_TOK_BASE),		MSG_ORIG(MSG_TOK_LDSO),
101*5aefb655Srie 	MSG_ORIG(MSG_TOK_NEWLM),	NULL
102*5aefb655Srie };
103*5aefb655Srie 
1047c478bd9Sstevel@tonic-gate /*
1057c478bd9Sstevel@tonic-gate  * Provide a debugging usage message
1067c478bd9Sstevel@tonic-gate  */
107*5aefb655Srie void
108*5aefb655Srie Dbg_usage()
1097c478bd9Sstevel@tonic-gate {
110*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
111*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_A));
112*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_B));
113*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_C));
114*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_D));
115*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_E));
116*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_F));
117*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_G));
118*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_H));
119*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_I));
120*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
121*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_J));
122*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_K));
123*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_L));
124*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_M));
125*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
126*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_N));
127*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_O));
128*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
129*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_P));
130*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_Q));
131*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_R));
132*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RTLD_S));
133*5aefb655Srie 
134*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
135*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_A));
136*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_B));
137*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_C));
138*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_D));
139*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_E));
140*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_F));
141*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_G));
142*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_H));
143*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
144*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_I));
145*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
146*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_J));
147*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_K));
148*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
149*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_L));
150*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
151*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_M));
152*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_N));
153*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LD_O));
154*5aefb655Srie 
155*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
156*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
157*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_ARGS));
158*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_AUDIT));
159*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_BASIC));
160*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_BINDINGS));
161*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_BINDINGS_2));
162*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_CAP));
163*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_DETAIL));
1647c478bd9Sstevel@tonic-gate #ifdef	DEMANGLE
165*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_DEMANGLE));
1667c478bd9Sstevel@tonic-gate #endif
167*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_ENTRY));
168*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_FILES));
169*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_GOT));
170*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_HELP));
171*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_INIT));
172*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LIBS));
173*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LIBS_2));
174*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LMID));
175*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_LONG));
176*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_MAP));
177*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_MOVE));
178*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_RELOC));
179*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_SECTIONS));
180*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_SEGMENTS));
181*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_SEGMENTS_2));
182*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_STATS));
183*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_STRTAB));
184*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_STRTAB_2));
185*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_SUPPORT));
186*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_SYMBOLS));
187*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_SYMBOLS_2));
188*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_TLS));
189*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_UNUSED));
190*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_UNUSED_2));
191*5aefb655Srie 	dbg_print(0, MSG_INTL(MSG_USE_VERSIONS));
192*5aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
193*5aefb655Srie }
194*5aefb655Srie 
195*5aefb655Srie /*
196*5aefb655Srie  * Messaging support - funnel everything through dgettext() as this provides
197*5aefb655Srie  * the real binding to libc.
198*5aefb655Srie  */
199*5aefb655Srie const char *
200*5aefb655Srie _liblddbg_msg(Msg mid)
201*5aefb655Srie {
202*5aefb655Srie 	return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid)));
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate /*
2067c478bd9Sstevel@tonic-gate  * Validate and enable the appropriate debugging classes.
2077c478bd9Sstevel@tonic-gate  */
208*5aefb655Srie uintptr_t
209*5aefb655Srie Dbg_setup(const char *string, Dbg_desc *dbp)
2107c478bd9Sstevel@tonic-gate {
211*5aefb655Srie 	char		*name, *_name;	/* buffer in which to perform */
212*5aefb655Srie 					/* strtok_r() operations. */
2137c478bd9Sstevel@tonic-gate 	char		*lasts;
2147c478bd9Sstevel@tonic-gate 	const char	*delimit = MSG_ORIG(MSG_STR_DELIMIT);
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate 	if ((_name = (char *)malloc(strlen(string) + 1)) == 0)
217*5aefb655Srie 		return (S_ERROR);
2187c478bd9Sstevel@tonic-gate 	(void) strcpy(_name, string);
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 	/*
2217c478bd9Sstevel@tonic-gate 	 * The token should be of the form "-Dtok,tok,tok,...".  Separate the
2227c478bd9Sstevel@tonic-gate 	 * pieces and build up the appropriate mask, unrecognized options are
2237c478bd9Sstevel@tonic-gate 	 * flagged.
2247c478bd9Sstevel@tonic-gate 	 */
2257c478bd9Sstevel@tonic-gate 	if ((name = strtok_r(_name, delimit, &lasts)) != NULL) {
2267c478bd9Sstevel@tonic-gate 		do {
227*5aefb655Srie 			DBG_options	*opt;
228*5aefb655Srie 			const char	*str;
229*5aefb655Srie 			Boolean		set, found = FALSE;
230*5aefb655Srie 			int		ndx = 0;
231*5aefb655Srie 
2327c478bd9Sstevel@tonic-gate 			if (name[0] == '!') {
2337c478bd9Sstevel@tonic-gate 				set = FALSE;
2347c478bd9Sstevel@tonic-gate 				name++;
235*5aefb655Srie 			} else
236*5aefb655Srie 				set = TRUE;
237*5aefb655Srie 
238*5aefb655Srie 			/*
239*5aefb655Srie 			 * First, determine if the token represents a class or
240*5aefb655Srie 			 * extra.
241*5aefb655Srie 			 */
242*5aefb655Srie 			for (opt = _Dbg_options; opt->o_name != NULL; opt++) {
243*5aefb655Srie 				if (strcmp(name, opt->o_name) != 0)
244*5aefb655Srie 					continue;
245*5aefb655Srie 
246*5aefb655Srie 				if (set == TRUE) {
247*5aefb655Srie 				    if (opt->o_class)
248*5aefb655Srie 					dbp->d_class |= opt->o_class;
249*5aefb655Srie 				    if (opt->o_extra)
250*5aefb655Srie 					dbp->d_extra |= opt->o_extra;
251*5aefb655Srie 				} else {
252*5aefb655Srie 				    if (opt->o_class)
253*5aefb655Srie 					dbp->d_class &= ~(opt->o_class);
254*5aefb655Srie 				    if (opt->o_extra)
255*5aefb655Srie 					dbp->d_extra &= ~(opt->o_extra);
256*5aefb655Srie 				}
257*5aefb655Srie 				found = TRUE;
258*5aefb655Srie 				break;
2597c478bd9Sstevel@tonic-gate 			}
260*5aefb655Srie 			if (found == TRUE)
261*5aefb655Srie 				continue;
262*5aefb655Srie 
263*5aefb655Srie 			/*
264*5aefb655Srie 			 * Second, determine if the token represents a known
265*5aefb655Srie 			 * diagnostic identifier.  Note, newlm identifiers are
266*5aefb655Srie 			 * typically followed by a numeric id, for example
267*5aefb655Srie 			 * newlm1, newlm2 ...  Thus we only compare the
268*5aefb655Srie 			 * initial text of the string.
269*5aefb655Srie 			 */
270*5aefb655Srie 			while ((str = _Dbg_strs[ndx++]) != NULL)  {
271*5aefb655Srie 				char	*tup;
272*5aefb655Srie 
273*5aefb655Srie 				if (strncmp(name, str, strlen(str)) != 0)
274*5aefb655Srie 					continue;
275*5aefb655Srie 
276*5aefb655Srie 				/*
277*5aefb655Srie 				 * Translate lmid identifier to uppercase.
278*5aefb655Srie 				 */
279*5aefb655Srie 				for (tup = name; *tup; tup++) {
280*5aefb655Srie 					if ((*tup >= 'a') && (*tup <= 'z'))
281*5aefb655Srie 						*tup = *tup - ('a' - 'A');
2827c478bd9Sstevel@tonic-gate 				}
283*5aefb655Srie 
284*5aefb655Srie 				/*
285*5aefb655Srie 				 * Save this lmid.  The whole token buffer has
286*5aefb655Srie 				 * been reallocated, so these names will remain
287*5aefb655Srie 				 * once this routine returns.
288*5aefb655Srie 				 */
289*5aefb655Srie 				if (alist_append(&(dbp->d_list), &name,
290*5aefb655Srie 				    sizeof (char *), AL_CNT_DEBUG) == 0)
291*5aefb655Srie 					return (S_ERROR);
292*5aefb655Srie 
293*5aefb655Srie 				found = TRUE;
294*5aefb655Srie 				break;
2957c478bd9Sstevel@tonic-gate 			}
296*5aefb655Srie 
2977c478bd9Sstevel@tonic-gate 			if (found == FALSE)
298*5aefb655Srie 				dbg_print(0, MSG_INTL(MSG_USE_UNRECOG), name);
299*5aefb655Srie 
3007c478bd9Sstevel@tonic-gate 		} while ((name = strtok_r(NULL, delimit, &lasts)) != NULL);
3017c478bd9Sstevel@tonic-gate 	}
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	/*
3047c478bd9Sstevel@tonic-gate 	 * If the debug help option was specified dump a usage message.  If
305*5aefb655Srie 	 * this is the only debug class, return an indication that the user
3067c478bd9Sstevel@tonic-gate 	 * should exit.
3077c478bd9Sstevel@tonic-gate 	 */
308*5aefb655Srie 	if ((_Dbg_cnt++ == 0) && (dbp->d_class & DBG_C_HELP)) {
309*5aefb655Srie 		Dbg_usage();
310*5aefb655Srie 		if (dbp->d_class == DBG_C_HELP)
311*5aefb655Srie 			return (0);
3127c478bd9Sstevel@tonic-gate 	}
313*5aefb655Srie 	return (1);
3147c478bd9Sstevel@tonic-gate }
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate /*
317*5aefb655Srie  * Define our own printing routine.  This provides a basic fallback, as ld(1)
318*5aefb655Srie  * and ld.so.1(1) provide their own routines that augment their diagnostic
319*5aefb655Srie  * output, and direct the output to stderr.  This item should be defined
320*5aefb655Srie  * NODIRECT.
3217c478bd9Sstevel@tonic-gate  */
322*5aefb655Srie /* PRINTFLIKE2 */
3237c478bd9Sstevel@tonic-gate void
324*5aefb655Srie dbg_print(Lm_list *lml, const char *format, ...)
3257c478bd9Sstevel@tonic-gate {
326*5aefb655Srie 	va_list ap;
3277c478bd9Sstevel@tonic-gate 
328*5aefb655Srie #if	defined(lint)
329*5aefb655Srie 	/*
330*5aefb655Srie 	 * The lml argument is only meaningful for diagnostics sent to ld.so.1.
331*5aefb655Srie 	 * Supress the lint error by making a dummy assignment.
332*5aefb655Srie 	 */
333*5aefb655Srie 	lml = 0;
334*5aefb655Srie #endif
335*5aefb655Srie 	va_start(ap, format);
336*5aefb655Srie 	(void) vprintf(format, ap);
337*5aefb655Srie 	(void) printf(MSG_ORIG(MSG_STR_NL));
338*5aefb655Srie 	va_end(ap);
3397c478bd9Sstevel@tonic-gate }
340