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  */
215aefb655Srie 
227c478bd9Sstevel@tonic-gate /*
2356deab07SRod Evans  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277257d1b4Sraf #include <libintl.h>
287257d1b4Sraf #include <sys/varargs.h>
297257d1b4Sraf #include <stdio.h>
307257d1b4Sraf #include <string.h>
317257d1b4Sraf #include <stdlib.h>
327257d1b4Sraf #include <alist.h>
337257d1b4Sraf #include <debug.h>
347257d1b4Sraf #include <_debug.h>
357257d1b4Sraf #include <msg.h>
367c478bd9Sstevel@tonic-gate 
375aefb655Srie /*
385aefb655Srie  * Define a debug descriptor.  Note, although this provides the default
395aefb655Srie  * definition to which most users bind, ld.so.1 must provide its own definition,
405aefb655Srie  * and thus interposition is expected.  This item should be defined NODIRECT.
415aefb655Srie  */
425aefb655Srie static Dbg_desc	_dbg_desc = { 0, 0, 0 };
435aefb655Srie Dbg_desc	*dbg_desc = &_dbg_desc;
447c478bd9Sstevel@tonic-gate 
455aefb655Srie int		_Dbg_cnt = 0;
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate /*
485aefb655Srie  * Debugging initialization and processing.  The dbg_options[] array defines
497c478bd9Sstevel@tonic-gate  * a set of option strings that can be specified using the -D flag or from an
505aefb655Srie  * environment variable.  For each option, a class is enabled in the d_class
515aefb655Srie  * bit mask, or an extra flag is enabled in the d_extra bit mask.
527c478bd9Sstevel@tonic-gate  */
53*e23c41c9SAli Bahrami static DBG_options _Dbg_options[] = {	/* Options accepted by both linkers */
545aefb655Srie 	{MSG_ORIG(MSG_TOK_DETAIL),	0,	DBG_E_DETAIL},
555aefb655Srie 	{MSG_ORIG(MSG_TOK_LONG),	0,	DBG_E_LONG},
56*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_HELP),	0,	DBG_E_HELP},
575aefb655Srie 
585aefb655Srie 	{MSG_ORIG(MSG_TOK_ALL),		DBG_C_ALL,	0},
595aefb655Srie 	{MSG_ORIG(MSG_TOK_BASIC),	DBG_C_BASIC,	0},
60*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_CAP),		DBG_C_CAP,	0},
61*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_DEMANGLE),	DBG_C_DEMANGLE,	0},
625aefb655Srie 	{MSG_ORIG(MSG_TOK_FILES),	DBG_C_FILES,	0},
635aefb655Srie 	{MSG_ORIG(MSG_TOK_LIBS),	DBG_C_LIBS,	0},
64*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_MOVE),	DBG_C_MOVE,	0},
655aefb655Srie 	{MSG_ORIG(MSG_TOK_RELOC),	DBG_C_RELOC,	0},
665aefb655Srie 	{MSG_ORIG(MSG_TOK_SYMBOLS),	DBG_C_SYMBOLS,	0},
675aefb655Srie 	{MSG_ORIG(MSG_TOK_TLS),		DBG_C_TLS,	0},
68*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_UNUSED),	DBG_C_UNUSED,	0},
695aefb655Srie 	{MSG_ORIG(MSG_TOK_VERSIONS),	DBG_C_VERSIONS,	0},
70*e23c41c9SAli Bahrami 	{NULL,				NULL},
71*e23c41c9SAli Bahrami };
72*e23c41c9SAli Bahrami 
73*e23c41c9SAli Bahrami static DBG_options _Dbg_options_ld[] = {	/* ld only options */
74*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_CLASS),	0,	DBG_E_SNAME | DBG_E_CLASS},
75*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_FULLNAME),	0,	DBG_E_SNAME | DBG_E_FNAME},
76*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_NAME),	0,	DBG_E_SNAME},
77*e23c41c9SAli Bahrami 
78*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_ARGS),	DBG_C_ARGS,	0},
79*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_ENTRY),	DBG_C_ENTRY,	0},
805aefb655Srie 	{MSG_ORIG(MSG_TOK_GOT),		DBG_C_GOT,	0},
81*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_MAP),		DBG_C_MAP,	0},
82*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_SECTIONS),	DBG_C_SECTIONS,	0},
83*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_SEGMENTS),	DBG_C_SEGMENTS,	0},
845aefb655Srie 	{MSG_ORIG(MSG_TOK_STATS),	DBG_C_STATS,	0},
85*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_STRTAB),	DBG_C_STRTAB,	0},
86*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_SUPPORT),	DBG_C_SUPPORT,	0},
87*e23c41c9SAli Bahrami 	{NULL,				NULL},
88*e23c41c9SAli Bahrami };
89*e23c41c9SAli Bahrami 
90*e23c41c9SAli Bahrami static DBG_options _Dbg_options_rtld[] = {	/* ld.so.1 only options */
91*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_AUDIT),	DBG_C_AUDITING,	0},
92*e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_BINDINGS),	DBG_C_BINDINGS,	0},
935aefb655Srie 	{MSG_ORIG(MSG_TOK_INIT),	DBG_C_INIT,	0},
947c478bd9Sstevel@tonic-gate 	{NULL,				NULL},
957c478bd9Sstevel@tonic-gate };
967c478bd9Sstevel@tonic-gate 
975aefb655Srie /*
98*e23c41c9SAli Bahrami  * Compare name to the options found in optarr. If one matches,
99*e23c41c9SAli Bahrami  * update *dbp and return TRUE. Otherwise, FALSE.
1005aefb655Srie  */
101*e23c41c9SAli Bahrami static Boolean
102*e23c41c9SAli Bahrami process_options(const char *name, Boolean set, Dbg_desc *dbp,
103*e23c41c9SAli Bahrami     DBG_options *optarr)
104*e23c41c9SAli Bahrami {
105*e23c41c9SAli Bahrami 	DBG_options	*opt;
106*e23c41c9SAli Bahrami 
107*e23c41c9SAli Bahrami 	for (opt = optarr; opt->o_name != NULL; opt++) {
108*e23c41c9SAli Bahrami 		if (strcmp(name, opt->o_name) != 0)
109*e23c41c9SAli Bahrami 			continue;
110*e23c41c9SAli Bahrami 
111*e23c41c9SAli Bahrami 		if (set == TRUE) {
112*e23c41c9SAli Bahrami 			if (opt->o_class)
113*e23c41c9SAli Bahrami 				dbp->d_class |= opt->o_class;
114*e23c41c9SAli Bahrami 			if (opt->o_extra)
115*e23c41c9SAli Bahrami 				dbp->d_extra |= opt->o_extra;
116*e23c41c9SAli Bahrami 		} else {
117*e23c41c9SAli Bahrami 			if (opt->o_class)
118*e23c41c9SAli Bahrami 				dbp->d_class &= ~(opt->o_class);
119*e23c41c9SAli Bahrami 			if (opt->o_extra)
120*e23c41c9SAli Bahrami 				dbp->d_extra &= ~(opt->o_extra);
121*e23c41c9SAli Bahrami 		}
122*e23c41c9SAli Bahrami 		return (TRUE);
123*e23c41c9SAli Bahrami 	}
124*e23c41c9SAli Bahrami 
125*e23c41c9SAli Bahrami 	return (FALSE);
126*e23c41c9SAli Bahrami }
1275aefb655Srie 
1287c478bd9Sstevel@tonic-gate /*
1297c478bd9Sstevel@tonic-gate  * Provide a debugging usage message
1307c478bd9Sstevel@tonic-gate  */
1315aefb655Srie void
132*e23c41c9SAli Bahrami Dbg_help(void)
1337c478bd9Sstevel@tonic-gate {
1345aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
135*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_A));
136*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_B));
137*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_C));
138*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_D));
139*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_E));
140*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_F));
141*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_G));
142*e23c41c9SAli Bahrami 
1435aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
144*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_A));
145*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_B));
146*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_C));
147*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_D));
148*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_E));
149*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_F));
150*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_G));
151*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_H));
152*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_I));
153*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_J));
154*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_K));
155*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_L));
156*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_M));
157*e23c41c9SAli Bahrami 
1585aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
159*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_L));
160*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_M));
161*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_N));
162*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_O));
163*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_P));
164*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_Q));
165*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_R));
166*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_S));
167*e23c41c9SAli Bahrami 
168*e23c41c9SAli Bahrami 	Dbg_util_nl(0, DBG_NL_FRC);
169*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_A));
170*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_B));
171*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_C));
172*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_D));
173*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_E));
174*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_F));
175*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_G));
176*e23c41c9SAli Bahrami 
1775aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
178*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_H));
179*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_F));
180*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_I));
181*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_J));
182*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_K));
183*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_L));
184*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_M));
1855aefb655Srie 
1865aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
187*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_N));
188*e23c41c9SAli Bahrami 
1895aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
190*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_DCT));
191*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH));
192*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_A));
193*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_B));
194*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_B2));
195*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_C));
196*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_D));
197*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_D2));
198*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_D3));
199*e23c41c9SAli Bahrami 
2005aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
201*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD));
202*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A));
203*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A2));
204*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A3));
205*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A4));
206*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A5));
207*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A6));
208*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A7));
209*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A8));
210*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A9));
211*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A0));
212*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_B));
213*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_C));
214*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_D));
215*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_E));
216*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_F));
217*e23c41c9SAli Bahrami 
2185aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
219*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_LD));
220*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R6_A));
221*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R6_B));
222*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R6_C));
223*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R6_C2));
224*e23c41c9SAli Bahrami 
2255aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
226*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_CST));
227*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH));
228*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_A));
229*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_B));
230*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_C));
231*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_D));
232*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_E));
233*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_F));
234*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_F2));
235*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_G));
236*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_H));
237*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_I));
238*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_I2));
239*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_J));
240*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_K));
241*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_K2));
242*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_L));
2435aefb655Srie 
2445aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
245*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD));
246*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R8_A));
247*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R8_B));
248*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R8_B2));
249*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R8_C));
250*e23c41c9SAli Bahrami 
2515aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
252*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_LD));
253*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_A));
254*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_B));
255*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_C));
256*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_D));
257*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_E));
258*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_F));
259*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_F2));
260*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_G));
261*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_H));
262*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_H2));
263*e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_I));
264*e23c41c9SAli Bahrami 
2655aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
2665aefb655Srie }
2675aefb655Srie 
2685aefb655Srie /*
2695aefb655Srie  * Messaging support - funnel everything through dgettext() as this provides
2705aefb655Srie  * the real binding to libc.
2715aefb655Srie  */
2725aefb655Srie const char *
2735aefb655Srie _liblddbg_msg(Msg mid)
2745aefb655Srie {
2755aefb655Srie 	return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid)));
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate 
278*e23c41c9SAli Bahrami /*
279*e23c41c9SAli Bahrami  * Given a name starting with "lmid", finish processing it. Return TRUE
280*e23c41c9SAli Bahrami  * if a valid lmid token was seen, and FALSE for any error.
281*e23c41c9SAli Bahrami  *
282*e23c41c9SAli Bahrami  * exit:
283*e23c41c9SAli Bahrami  *	On failure, returns FALSE, indicating a syntax error
284*e23c41c9SAli Bahrami  *
285*e23c41c9SAli Bahrami  *	On success:
286*e23c41c9SAli Bahrami  *	-	Appropriate flags in dbg->d_extra have been set
287*e23c41c9SAli Bahrami  *	-	Any link-map list names specified have been added to
288*e23c41c9SAli Bahrami  *		d_list, for the rtld dbg_print() to compare against
289*e23c41c9SAli Bahrami  *		link-map list names.
290*e23c41c9SAli Bahrami  *	-	TRUE is returned.
291*e23c41c9SAli Bahrami  */
292*e23c41c9SAli Bahrami static Boolean
293*e23c41c9SAli Bahrami process_lmid(char *name, Dbg_desc *dbp)
294*e23c41c9SAli Bahrami {
295*e23c41c9SAli Bahrami 	/*
296*e23c41c9SAli Bahrami 	 * "lmid" can have an optional argument. Allowed values are "all",
297*e23c41c9SAli Bahrami 	 * "alt[0-9]+", "base", or "ldso". Alt has a variable ending, but
298*e23c41c9SAli Bahrami 	 * we can use process_options() to handle the other three.
299*e23c41c9SAli Bahrami 	 */
300*e23c41c9SAli Bahrami 	static DBG_options options_lmid[] = {
301*e23c41c9SAli Bahrami 		{MSG_ORIG(MSG_TOK_LMID_ALL),	0,	DBG_E_LMID_ALL},
302*e23c41c9SAli Bahrami 		{MSG_ORIG(MSG_TOK_LMID_BASE),	0,	DBG_E_LMID_BASE},
303*e23c41c9SAli Bahrami 		{MSG_ORIG(MSG_TOK_LMID_LDSO),	0,	DBG_E_LMID_LDSO},
304*e23c41c9SAli Bahrami 		{NULL,				NULL},
305*e23c41c9SAli Bahrami 	};
306*e23c41c9SAli Bahrami 
307*e23c41c9SAli Bahrami 	Dbg_desc	tmp_db;
308*e23c41c9SAli Bahrami 	const char	*lmid_opt;
309*e23c41c9SAli Bahrami 
310*e23c41c9SAli Bahrami 	/* If it's a plain "lmid", we can set the flag and return now */
311*e23c41c9SAli Bahrami 	if (name[MSG_TOK_LMID_SIZE] == '\0') {
312*e23c41c9SAli Bahrami 		dbp->d_extra |= DBG_E_LMID;
313*e23c41c9SAli Bahrami 		return (TRUE);
314*e23c41c9SAli Bahrami 	}
315*e23c41c9SAli Bahrami 
316*e23c41c9SAli Bahrami 	/* If there's no value, its an error */
317*e23c41c9SAli Bahrami 	if (conv_strproc_extract_value(name, MSG_TOK_LMID_SIZE,
318*e23c41c9SAli Bahrami 	    CONV_SPEXV_F_UCASE, &lmid_opt) == 0)
319*e23c41c9SAli Bahrami 		return (FALSE);
320*e23c41c9SAli Bahrami 
321*e23c41c9SAli Bahrami 	/*
322*e23c41c9SAli Bahrami 	 * ALL, BASE, or LDSO?
323*e23c41c9SAli Bahrami 	 */
324*e23c41c9SAli Bahrami 	tmp_db.d_extra = 0;
325*e23c41c9SAli Bahrami 	if (process_options(lmid_opt, TRUE, &tmp_db, options_lmid)) {
326*e23c41c9SAli Bahrami 		/*
327*e23c41c9SAli Bahrami 		 * If BASE, and we haven't already seen it, add it to the
328*e23c41c9SAli Bahrami 		 * rtld name matching list. For the others, setting the
329*e23c41c9SAli Bahrami 		 * e_extra bit suffices.
330*e23c41c9SAli Bahrami 		 */
331*e23c41c9SAli Bahrami 		if (((tmp_db.d_extra & DBG_E_LMID_BASE) != 0) &&
332*e23c41c9SAli Bahrami 		    ((dbp->d_extra & DBG_E_LMID_BASE) == 0) &&
333*e23c41c9SAli Bahrami 		    (aplist_append(&dbp->d_list, MSG_ORIG(MSG_TOK_LMID_BASE),
334*e23c41c9SAli Bahrami 		    AL_CNT_DEBUG) == NULL))
335*e23c41c9SAli Bahrami 			return (FALSE);
336*e23c41c9SAli Bahrami 
337*e23c41c9SAli Bahrami 		/* Add the resulting flags into the callers descriptor */
338*e23c41c9SAli Bahrami 		dbp->d_extra |= DBG_E_LMID | tmp_db.d_extra;
339*e23c41c9SAli Bahrami 		return (TRUE);
340*e23c41c9SAli Bahrami 	}
341*e23c41c9SAli Bahrami 
342*e23c41c9SAli Bahrami 	/*
343*e23c41c9SAli Bahrami 	 * ALT?
344*e23c41c9SAli Bahrami 	 */
345*e23c41c9SAli Bahrami 	if (strncmp(lmid_opt, MSG_ORIG(MSG_TOK_LMID_ALT),
346*e23c41c9SAli Bahrami 	    MSG_TOK_LMID_ALT_SIZE) == 0) {
347*e23c41c9SAli Bahrami 		const char *tail = lmid_opt + MSG_TOK_LMID_ALT_SIZE;
348*e23c41c9SAli Bahrami 
349*e23c41c9SAli Bahrami 		/* 'ALT' without a # means "all alternative link-map lists" */
350*e23c41c9SAli Bahrami 		if (*tail == '\0') {
351*e23c41c9SAli Bahrami 			dbp->d_extra |= DBG_E_LMID | DBG_E_LMID_ALT;
352*e23c41c9SAli Bahrami 			return (TRUE);
353*e23c41c9SAli Bahrami 		}
354*e23c41c9SAli Bahrami 
355*e23c41c9SAli Bahrami 		/*
356*e23c41c9SAli Bahrami 		 * It is ALT[0-9]+. Make sure the characters following 'ALT'
357*e23c41c9SAli Bahrami 		 * are numbers, and then add it to the rtld name matching list.
358*e23c41c9SAli Bahrami 		 */
359*e23c41c9SAli Bahrami 		for (; *tail; tail++)
360*e23c41c9SAli Bahrami 			if ((*tail < '0') || (*tail > '9'))
361*e23c41c9SAli Bahrami 				return (FALSE);
362*e23c41c9SAli Bahrami 
363*e23c41c9SAli Bahrami 		if (aplist_append(&dbp->d_list, lmid_opt, AL_CNT_DEBUG) == NULL)
364*e23c41c9SAli Bahrami 			return (FALSE);
365*e23c41c9SAli Bahrami 		dbp->d_extra |= DBG_E_LMID;
366*e23c41c9SAli Bahrami 		return (TRUE);
367*e23c41c9SAli Bahrami 	}
368*e23c41c9SAli Bahrami 
369*e23c41c9SAli Bahrami 	/* It's nothing we recognize */
370*e23c41c9SAli Bahrami 	return (FALSE);
371*e23c41c9SAli Bahrami }
372*e23c41c9SAli Bahrami 
3737c478bd9Sstevel@tonic-gate /*
3747c478bd9Sstevel@tonic-gate  * Validate and enable the appropriate debugging classes.
375*e23c41c9SAli Bahrami  *
376*e23c41c9SAli Bahrami  * entry:
377*e23c41c9SAli Bahrami  *	string - String to be analyzed for debugging options
378*e23c41c9SAli Bahrami  *	dbp - Pointer to debug descriptor to be initialized
379*e23c41c9SAli Bahrami  *	outfile_ret - NULL, or pointer to receive result of 'output='
380*e23c41c9SAli Bahrami  *		token. A NULL value means that the 'output=' token
381*e23c41c9SAli Bahrami  *		is not accepted. A non-NULL value means that it is.
382*e23c41c9SAli Bahrami  *
383*e23c41c9SAli Bahrami  * exit:
384*e23c41c9SAli Bahrami  *	On failure, False (0) is returned.
385*e23c41c9SAli Bahrami  *
386*e23c41c9SAli Bahrami  *	On success, string has been parsed, and the descriptor referenced
387*e23c41c9SAli Bahrami  *	by dbp has been initialized. If outfile is non-NULL, *outfile will
388*e23c41c9SAli Bahrami  *	be set to NULL if the 'output=' token is not present, and to the
389*e23c41c9SAli Bahrami  *	user supplied string otherwise. True (1) is returned.
3907c478bd9Sstevel@tonic-gate  */
391*e23c41c9SAli Bahrami int
392*e23c41c9SAli Bahrami Dbg_setup(dbg_setup_caller_t caller, const char *string, Dbg_desc *dbp,
393*e23c41c9SAli Bahrami     const char **outfile)
3947c478bd9Sstevel@tonic-gate {
3955aefb655Srie 	char		*name, *_name;	/* buffer in which to perform */
3965aefb655Srie 					/* strtok_r() operations. */
3977c478bd9Sstevel@tonic-gate 	char		*lasts;
3987c478bd9Sstevel@tonic-gate 	const char	*delimit = MSG_ORIG(MSG_STR_DELIMIT);
3997c478bd9Sstevel@tonic-gate 
400*e23c41c9SAli Bahrami 	/*
401*e23c41c9SAli Bahrami 	 * Clear the help flags --- these items only apply for a single
402*e23c41c9SAli Bahrami 	 * call to Dbg_setup().
403*e23c41c9SAli Bahrami 	 */
404*e23c41c9SAli Bahrami 	dbp->d_extra &= ~(DBG_E_HELP | DBG_E_HELP_EXIT);
405*e23c41c9SAli Bahrami 
406*e23c41c9SAli Bahrami 	if ((_name = (char *)malloc(strlen(string) + 1)) == NULL)
407*e23c41c9SAli Bahrami 		return (0);
4087c478bd9Sstevel@tonic-gate 	(void) strcpy(_name, string);
4097c478bd9Sstevel@tonic-gate 
410*e23c41c9SAli Bahrami 	if (outfile)
411*e23c41c9SAli Bahrami 		*outfile = NULL;   /* No output file yet */
412*e23c41c9SAli Bahrami 
4137c478bd9Sstevel@tonic-gate 	/*
4147c478bd9Sstevel@tonic-gate 	 * The token should be of the form "-Dtok,tok,tok,...".  Separate the
4157c478bd9Sstevel@tonic-gate 	 * pieces and build up the appropriate mask, unrecognized options are
4167c478bd9Sstevel@tonic-gate 	 * flagged.
4177c478bd9Sstevel@tonic-gate 	 */
4187c478bd9Sstevel@tonic-gate 	if ((name = strtok_r(_name, delimit, &lasts)) != NULL) {
4197c478bd9Sstevel@tonic-gate 		do {
420*e23c41c9SAli Bahrami 			Boolean		set;
421*e23c41c9SAli Bahrami 
422*e23c41c9SAli Bahrami 			/* Remove leading and trailing whitespace */
423*e23c41c9SAli Bahrami 			name = conv_strproc_trim(name);
4245aefb655Srie 
4257c478bd9Sstevel@tonic-gate 			if (name[0] == '!') {
4267c478bd9Sstevel@tonic-gate 				set = FALSE;
4277c478bd9Sstevel@tonic-gate 				name++;
4285aefb655Srie 			} else
4295aefb655Srie 				set = TRUE;
4305aefb655Srie 
431*e23c41c9SAli Bahrami 			if (*name == '\0')
432*e23c41c9SAli Bahrami 				continue;	/* Skip null token */
433*e23c41c9SAli Bahrami 
4345aefb655Srie 			/*
4355aefb655Srie 			 * First, determine if the token represents a class or
4365aefb655Srie 			 * extra.
4375aefb655Srie 			 */
438*e23c41c9SAli Bahrami 			if (process_options(name, set, dbp, _Dbg_options))
439*e23c41c9SAli Bahrami 				continue;
440*e23c41c9SAli Bahrami 			switch (caller) {
441*e23c41c9SAli Bahrami 			case DBG_CALLER_LD:	/* ld only tokens */
442*e23c41c9SAli Bahrami 				if (process_options(name, set, dbp,
443*e23c41c9SAli Bahrami 				    _Dbg_options_ld))
444*e23c41c9SAli Bahrami 					continue;
445*e23c41c9SAli Bahrami 				break;
446*e23c41c9SAli Bahrami 			case DBG_CALLER_RTLD:	/* rtld only tokens */
447*e23c41c9SAli Bahrami 				if (process_options(name, set, dbp,
448*e23c41c9SAli Bahrami 				    _Dbg_options_rtld))
4495aefb655Srie 					continue;
4505aefb655Srie 				break;
4517c478bd9Sstevel@tonic-gate 			}
452*e23c41c9SAli Bahrami 
453*e23c41c9SAli Bahrami 			/* The remaining options do not accept negation */
454*e23c41c9SAli Bahrami 			if (!set) {
455*e23c41c9SAli Bahrami 				dbg_print(0, MSG_INTL(MSG_USE_CNTNEGOPT), name);
4565aefb655Srie 				continue;
457*e23c41c9SAli Bahrami 			}
4585aefb655Srie 
4595aefb655Srie 			/*
460*e23c41c9SAli Bahrami 			 * Is it an 'output=' token? This item is a special
461*e23c41c9SAli Bahrami 			 * case because it depends on the presence of
462*e23c41c9SAli Bahrami 			 * a non-NULL outfile argument, and because the
463*e23c41c9SAli Bahrami 			 * part following the '=' is variable.
4645aefb655Srie 			 */
465*e23c41c9SAli Bahrami 			if ((outfile != NULL) &&
466*e23c41c9SAli Bahrami 			    strncmp(name, MSG_ORIG(MSG_TOK_OUTFILE),
467*e23c41c9SAli Bahrami 			    MSG_TOK_OUTFILE_SIZE) == 0) {
468*e23c41c9SAli Bahrami 				if (conv_strproc_extract_value(name,
469*e23c41c9SAli Bahrami 				    MSG_TOK_OUTFILE_SIZE, 0, outfile))
4705aefb655Srie 					continue;
4717c478bd9Sstevel@tonic-gate 			}
4725aefb655Srie 
473*e23c41c9SAli Bahrami 			/*
474*e23c41c9SAli Bahrami 			 * Only the rtld "lmid" token is left.
475*e23c41c9SAli Bahrami 			 */
476*e23c41c9SAli Bahrami 			if ((caller == DBG_CALLER_RTLD) && (strncmp(name,
477*e23c41c9SAli Bahrami 			    MSG_ORIG(MSG_TOK_LMID), MSG_TOK_LMID_SIZE) == 0) &&
478*e23c41c9SAli Bahrami 			    process_lmid(name, dbp))
479*e23c41c9SAli Bahrami 				continue;
480*e23c41c9SAli Bahrami 
481*e23c41c9SAli Bahrami 			/* If we make it here, the token is not understood */
482*e23c41c9SAli Bahrami 			dbg_print(0, MSG_INTL(MSG_USE_UNRECOG), name);
4835aefb655Srie 
4847c478bd9Sstevel@tonic-gate 		} while ((name = strtok_r(NULL, delimit, &lasts)) != NULL);
4857c478bd9Sstevel@tonic-gate 	}
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate 	/*
488*e23c41c9SAli Bahrami 	 * If the debug help option was specified and this is the only debug
489*e23c41c9SAli Bahrami 	 * class, return an indication that the user should exit.
4907c478bd9Sstevel@tonic-gate 	 */
491*e23c41c9SAli Bahrami 	if ((_Dbg_cnt++ == 0) && (dbp->d_extra & DBG_E_HELP) &&
492*e23c41c9SAli Bahrami 	    (dbp->d_class == 0))
493*e23c41c9SAli Bahrami 		dbp->d_extra |= DBG_E_HELP_EXIT;
494*e23c41c9SAli Bahrami 
4955aefb655Srie 	return (1);
4967c478bd9Sstevel@tonic-gate }
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate /*
4995aefb655Srie  * Define our own printing routine.  This provides a basic fallback, as ld(1)
5005aefb655Srie  * and ld.so.1(1) provide their own routines that augment their diagnostic
5015aefb655Srie  * output, and direct the output to stderr.  This item should be defined
5025aefb655Srie  * NODIRECT.
5037c478bd9Sstevel@tonic-gate  */
5045aefb655Srie /* PRINTFLIKE2 */
5057c478bd9Sstevel@tonic-gate void
5065aefb655Srie dbg_print(Lm_list *lml, const char *format, ...)
5077c478bd9Sstevel@tonic-gate {
5085aefb655Srie 	va_list ap;
5097c478bd9Sstevel@tonic-gate 
5105aefb655Srie #if	defined(lint)
5115aefb655Srie 	/*
5125aefb655Srie 	 * The lml argument is only meaningful for diagnostics sent to ld.so.1.
5135aefb655Srie 	 * Supress the lint error by making a dummy assignment.
5145aefb655Srie 	 */
5155aefb655Srie 	lml = 0;
5165aefb655Srie #endif
5175aefb655Srie 	va_start(ap, format);
5185aefb655Srie 	(void) vprintf(format, ap);
5195aefb655Srie 	(void) printf(MSG_ORIG(MSG_STR_NL));
5205aefb655Srie 	va_end(ap);
5217c478bd9Sstevel@tonic-gate }
522