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 /*
2320272c2eSAli Bahrami  * Copyright 2010 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  */
422017c965SRod Evans static Dbg_desc	_dbg_desc = { 0, 0, NULL, { 0, 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  */
53e23c41c9SAli 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},
56e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_HELP),	0,	DBG_E_HELP},
572017c965SRod Evans 	{MSG_ORIG(MSG_TOK_TTIME),	0,	DBG_E_TTIME},
582017c965SRod Evans 	{MSG_ORIG(MSG_TOK_DTIME),	0,	DBG_E_DTIME},
595aefb655Srie 
60e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_ALL),		DBG_C_ALL & ~DBG_C_DEMANGLE,	0},
61e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_BASIC),	DBG_C_BASIC,			0},
62e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_CAP),		DBG_C_CAP,			0},
63e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_DEMANGLE),	DBG_C_DEMANGLE,			0},
64e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_FILES),	DBG_C_FILES,			0},
65e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_LIBS),	DBG_C_LIBS,			0},
66e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_MOVE),	DBG_C_MOVE,			0},
67e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_RELOC),	DBG_C_RELOC,			0},
68e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_SYMBOLS),	DBG_C_SYMBOLS,			0},
69e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_TLS),		DBG_C_TLS,			0},
70e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_UNUSED),	DBG_C_UNUSED,			0},
71e64d0ff9SAli Bahrami 	{MSG_ORIG(MSG_TOK_VERSIONS),	DBG_C_VERSIONS,			0},
72e64d0ff9SAli Bahrami 	{NULL,				0,				0},
73e23c41c9SAli Bahrami };
74e23c41c9SAli Bahrami 
75e23c41c9SAli Bahrami static DBG_options _Dbg_options_ld[] = {	/* ld only options */
76e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_CLASS),	0,	DBG_E_SNAME | DBG_E_CLASS},
77e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_FULLNAME),	0,	DBG_E_SNAME | DBG_E_FNAME},
78e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_NAME),	0,	DBG_E_SNAME},
79e23c41c9SAli Bahrami 
80e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_ARGS),	DBG_C_ARGS,	0},
81e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_ENTRY),	DBG_C_ENTRY,	0},
825aefb655Srie 	{MSG_ORIG(MSG_TOK_GOT),		DBG_C_GOT,	0},
83e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_MAP),		DBG_C_MAP,	0},
84e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_SECTIONS),	DBG_C_SECTIONS,	0},
85e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_SEGMENTS),	DBG_C_SEGMENTS,	0},
865aefb655Srie 	{MSG_ORIG(MSG_TOK_STATS),	DBG_C_STATS,	0},
87e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_STRTAB),	DBG_C_STRTAB,	0},
88e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_SUPPORT),	DBG_C_SUPPORT,	0},
89e64d0ff9SAli Bahrami 	{NULL,				0,		0},
90e23c41c9SAli Bahrami };
91e23c41c9SAli Bahrami 
92e23c41c9SAli Bahrami static DBG_options _Dbg_options_rtld[] = {	/* ld.so.1 only options */
93e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_AUDIT),	DBG_C_AUDITING,	0},
94e23c41c9SAli Bahrami 	{MSG_ORIG(MSG_TOK_BINDINGS),	DBG_C_BINDINGS,	0},
95*5f5c35baSToomas Soome 	{MSG_ORIG(MSG_TOK_DL),		DBG_C_DL,	0},
965aefb655Srie 	{MSG_ORIG(MSG_TOK_INIT),	DBG_C_INIT,	0},
97e64d0ff9SAli Bahrami 	{NULL,				0,		0},
987c478bd9Sstevel@tonic-gate };
997c478bd9Sstevel@tonic-gate 
1005aefb655Srie /*
101e23c41c9SAli Bahrami  * Compare name to the options found in optarr. If one matches,
102e23c41c9SAli Bahrami  * update *dbp and return TRUE. Otherwise, FALSE.
1035aefb655Srie  */
104e23c41c9SAli Bahrami static Boolean
process_options(const char * name,Boolean set,Dbg_desc * dbp,DBG_options * optarr)105e23c41c9SAli Bahrami process_options(const char *name, Boolean set, Dbg_desc *dbp,
106e23c41c9SAli Bahrami     DBG_options *optarr)
107e23c41c9SAli Bahrami {
108e23c41c9SAli Bahrami 	DBG_options	*opt;
109e23c41c9SAli Bahrami 
110e23c41c9SAli Bahrami 	for (opt = optarr; opt->o_name != NULL; opt++) {
111e23c41c9SAli Bahrami 		if (strcmp(name, opt->o_name) != 0)
112e23c41c9SAli Bahrami 			continue;
113e23c41c9SAli Bahrami 
114e23c41c9SAli Bahrami 		if (set == TRUE) {
115e23c41c9SAli Bahrami 			if (opt->o_class)
116e23c41c9SAli Bahrami 				dbp->d_class |= opt->o_class;
117e23c41c9SAli Bahrami 			if (opt->o_extra)
118e23c41c9SAli Bahrami 				dbp->d_extra |= opt->o_extra;
119e23c41c9SAli Bahrami 		} else {
120e23c41c9SAli Bahrami 			if (opt->o_class)
121e23c41c9SAli Bahrami 				dbp->d_class &= ~(opt->o_class);
122e23c41c9SAli Bahrami 			if (opt->o_extra)
123e23c41c9SAli Bahrami 				dbp->d_extra &= ~(opt->o_extra);
124e23c41c9SAli Bahrami 		}
125e23c41c9SAli Bahrami 		return (TRUE);
126e23c41c9SAli Bahrami 	}
127e23c41c9SAli Bahrami 
128e23c41c9SAli Bahrami 	return (FALSE);
129e23c41c9SAli Bahrami }
1305aefb655Srie 
1317c478bd9Sstevel@tonic-gate /*
1327c478bd9Sstevel@tonic-gate  * Provide a debugging usage message
1337c478bd9Sstevel@tonic-gate  */
1345aefb655Srie void
Dbg_help(void)135e23c41c9SAli Bahrami Dbg_help(void)
1367c478bd9Sstevel@tonic-gate {
13769112eddSAli Bahrami 	Dbg_util_nl(0, DBG_NL_STD);
138e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_A));
139e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_B));
140e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_C));
141e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_D));
142e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_E));
143e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_F));
144e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R1_G));
145e23c41c9SAli Bahrami 
1465aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
147e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_A));
148e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_B));
149e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_C));
150e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_D));
151e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_E));
152e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_F));
153e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_G));
154e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_H));
155e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_I));
156e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_J));
157e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_K));
158e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_L));
159e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_M));
160e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_N));
161e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_O));
162e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_P));
163e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_Q));
1641dd9d86fSAli Bahrami 
1651dd9d86fSAli Bahrami 	Dbg_util_nl(0, DBG_NL_FRC);
166e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_R));
167e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_S));
1681dd9d86fSAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_T));
1691dd9d86fSAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_U));
1701dd9d86fSAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_V));
1711dd9d86fSAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R2_W));
172e23c41c9SAli Bahrami 
173e23c41c9SAli Bahrami 	Dbg_util_nl(0, DBG_NL_FRC);
174e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_A));
175e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_B));
176e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_C));
177e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_D));
178e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_E));
179e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_F));
180e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_G));
181e23c41c9SAli Bahrami 
1825aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
183e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_H));
184e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_F));
185e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_I));
186e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_J));
187e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_K));
188e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_L));
189e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_M));
1905aefb655Srie 
1915aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
192e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R3_N));
193e23c41c9SAli Bahrami 
1945aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
195e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_DCT));
196e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH));
197e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_A));
198e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_B));
199e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_B2));
200e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_C));
2012017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_C2));
2022017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_C3));
203e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R4_D));
2042017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_E));
2052017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_E2));
2062017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_E3));
2072017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_F));
2082017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_F2));
2092017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_F3));
2102017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_F4));
2112017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_F5));
2122017c965SRod Evans 	dbg_print(0, MSG_INTL(MSG_USE_R4_F6));
213e23c41c9SAli Bahrami 
2145aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
215e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD));
216e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A));
217e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A2));
218e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A3));
219e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A4));
220e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A5));
221e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A6));
222e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A7));
223e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A8));
224e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A9));
225e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_A0));
226e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_B));
227e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_C));
228e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_D));
229e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_E));
230e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R5_F));
231e23c41c9SAli Bahrami 
2325aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
233e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_LD));
234e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R6_A));
235e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R6_B));
236e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R6_C));
237e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R6_C2));
238e23c41c9SAli Bahrami 
2395aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
240e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_CST));
241e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH));
242e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_A));
243e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_B));
244e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_C));
245e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_D));
246e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_E));
247e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_F));
248e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_F2));
249e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_G));
250e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_H));
251e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_I));
252e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_I2));
253e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_J));
254e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_K));
255e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_K2));
256e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R7_L));
2575aefb655Srie 
2585aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
259e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD));
260e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R8_A));
261e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R8_B));
262e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R8_B2));
263e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R8_C));
26420272c2eSAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R8_D));
265e23c41c9SAli Bahrami 
2665aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
267e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_HDR_LD));
268e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_A));
269e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_B));
270e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_C));
271e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_D));
272e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_E));
273e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_F));
274e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_F2));
275e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_G));
276e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_H));
277e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_H2));
278e23c41c9SAli Bahrami 	dbg_print(0, MSG_INTL(MSG_USE_R9_I));
279e23c41c9SAli Bahrami 
2805aefb655Srie 	Dbg_util_nl(0, DBG_NL_FRC);
2815aefb655Srie }
2825aefb655Srie 
28369112eddSAli Bahrami /*
28469112eddSAli Bahrami  * Provide a debugging message showing the version of the linker package
28569112eddSAli Bahrami  */
28669112eddSAli Bahrami void
Dbg_version(void)28769112eddSAli Bahrami Dbg_version(void)
28869112eddSAli Bahrami {
28969112eddSAli Bahrami 	Dbg_util_nl(0, DBG_NL_STD);
29069112eddSAli Bahrami 	dbg_print(0, MSG_ORIG(MSG_STR_LDVER), link_ver_string);
29169112eddSAli Bahrami 	Dbg_util_nl(0, DBG_NL_STD);
29269112eddSAli Bahrami }
29369112eddSAli Bahrami 
2945aefb655Srie /*
2955aefb655Srie  * Messaging support - funnel everything through dgettext() as this provides
2965aefb655Srie  * the real binding to libc.
2975aefb655Srie  */
2985aefb655Srie const char *
_liblddbg_msg(Msg mid)2995aefb655Srie _liblddbg_msg(Msg mid)
3005aefb655Srie {
3015aefb655Srie 	return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid)));
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate 
304e23c41c9SAli Bahrami /*
305e23c41c9SAli Bahrami  * Given a name starting with "lmid", finish processing it. Return TRUE
306e23c41c9SAli Bahrami  * if a valid lmid token was seen, and FALSE for any error.
307e23c41c9SAli Bahrami  *
308e23c41c9SAli Bahrami  * exit:
309e23c41c9SAli Bahrami  *	On failure, returns FALSE, indicating a syntax error
310e23c41c9SAli Bahrami  *
311e23c41c9SAli Bahrami  *	On success:
312e23c41c9SAli Bahrami  *	-	Appropriate flags in dbg->d_extra have been set
313e23c41c9SAli Bahrami  *	-	Any link-map list names specified have been added to
314e23c41c9SAli Bahrami  *		d_list, for the rtld dbg_print() to compare against
315e23c41c9SAli Bahrami  *		link-map list names.
316e23c41c9SAli Bahrami  *	-	TRUE is returned.
317e23c41c9SAli Bahrami  */
318e23c41c9SAli Bahrami static Boolean
process_lmid(char * name,Dbg_desc * dbp)319e23c41c9SAli Bahrami process_lmid(char *name, Dbg_desc *dbp)
320e23c41c9SAli Bahrami {
321e23c41c9SAli Bahrami 	/*
322e23c41c9SAli Bahrami 	 * "lmid" can have an optional argument. Allowed values are "all",
323e23c41c9SAli Bahrami 	 * "alt[0-9]+", "base", or "ldso". Alt has a variable ending, but
324e23c41c9SAli Bahrami 	 * we can use process_options() to handle the other three.
325e23c41c9SAli Bahrami 	 */
326e23c41c9SAli Bahrami 	static DBG_options options_lmid[] = {
327e23c41c9SAli Bahrami 		{MSG_ORIG(MSG_TOK_LMID_ALL),	0,	DBG_E_LMID_ALL},
328e23c41c9SAli Bahrami 		{MSG_ORIG(MSG_TOK_LMID_BASE),	0,	DBG_E_LMID_BASE},
329e23c41c9SAli Bahrami 		{MSG_ORIG(MSG_TOK_LMID_LDSO),	0,	DBG_E_LMID_LDSO},
330*5f5c35baSToomas Soome 		{NULL,				0,	0},
331e23c41c9SAli Bahrami 	};
332e23c41c9SAli Bahrami 
333e23c41c9SAli Bahrami 	Dbg_desc	tmp_db;
334e23c41c9SAli Bahrami 	const char	*lmid_opt;
335e23c41c9SAli Bahrami 
336e23c41c9SAli Bahrami 	/* If it's a plain "lmid", we can set the flag and return now */
337e23c41c9SAli Bahrami 	if (name[MSG_TOK_LMID_SIZE] == '\0') {
338e23c41c9SAli Bahrami 		dbp->d_extra |= DBG_E_LMID;
339e23c41c9SAli Bahrami 		return (TRUE);
340e23c41c9SAli Bahrami 	}
341e23c41c9SAli Bahrami 
342e23c41c9SAli Bahrami 	/* If there's no value, its an error */
343e23c41c9SAli Bahrami 	if (conv_strproc_extract_value(name, MSG_TOK_LMID_SIZE,
344e23c41c9SAli Bahrami 	    CONV_SPEXV_F_UCASE, &lmid_opt) == 0)
345e23c41c9SAli Bahrami 		return (FALSE);
346e23c41c9SAli Bahrami 
347e23c41c9SAli Bahrami 	/*
348e23c41c9SAli Bahrami 	 * ALL, BASE, or LDSO?
349e23c41c9SAli Bahrami 	 */
350e23c41c9SAli Bahrami 	tmp_db.d_extra = 0;
351e23c41c9SAli Bahrami 	if (process_options(lmid_opt, TRUE, &tmp_db, options_lmid)) {
352e23c41c9SAli Bahrami 		/*
353e23c41c9SAli Bahrami 		 * If BASE, and we haven't already seen it, add it to the
354e23c41c9SAli Bahrami 		 * rtld name matching list. For the others, setting the
355e23c41c9SAli Bahrami 		 * e_extra bit suffices.
356e23c41c9SAli Bahrami 		 */
357e23c41c9SAli Bahrami 		if (((tmp_db.d_extra & DBG_E_LMID_BASE) != 0) &&
358e23c41c9SAli Bahrami 		    ((dbp->d_extra & DBG_E_LMID_BASE) == 0) &&
359e23c41c9SAli Bahrami 		    (aplist_append(&dbp->d_list, MSG_ORIG(MSG_TOK_LMID_BASE),
360e23c41c9SAli Bahrami 		    AL_CNT_DEBUG) == NULL))
361e23c41c9SAli Bahrami 			return (FALSE);
362e23c41c9SAli Bahrami 
363e23c41c9SAli Bahrami 		/* Add the resulting flags into the callers descriptor */
364e23c41c9SAli Bahrami 		dbp->d_extra |= DBG_E_LMID | tmp_db.d_extra;
365e23c41c9SAli Bahrami 		return (TRUE);
366e23c41c9SAli Bahrami 	}
367e23c41c9SAli Bahrami 
368e23c41c9SAli Bahrami 	/*
369e23c41c9SAli Bahrami 	 * ALT?
370e23c41c9SAli Bahrami 	 */
371e23c41c9SAli Bahrami 	if (strncmp(lmid_opt, MSG_ORIG(MSG_TOK_LMID_ALT),
372e23c41c9SAli Bahrami 	    MSG_TOK_LMID_ALT_SIZE) == 0) {
373e23c41c9SAli Bahrami 		const char *tail = lmid_opt + MSG_TOK_LMID_ALT_SIZE;
374e23c41c9SAli Bahrami 
375e23c41c9SAli Bahrami 		/* 'ALT' without a # means "all alternative link-map lists" */
376e23c41c9SAli Bahrami 		if (*tail == '\0') {
377e23c41c9SAli Bahrami 			dbp->d_extra |= DBG_E_LMID | DBG_E_LMID_ALT;
378e23c41c9SAli Bahrami 			return (TRUE);
379e23c41c9SAli Bahrami 		}
380e23c41c9SAli Bahrami 
381e23c41c9SAli Bahrami 		/*
382e23c41c9SAli Bahrami 		 * It is ALT[0-9]+. Make sure the characters following 'ALT'
383e23c41c9SAli Bahrami 		 * are numbers, and then add it to the rtld name matching list.
384e23c41c9SAli Bahrami 		 */
385e23c41c9SAli Bahrami 		for (; *tail; tail++)
386e23c41c9SAli Bahrami 			if ((*tail < '0') || (*tail > '9'))
387e23c41c9SAli Bahrami 				return (FALSE);
388e23c41c9SAli Bahrami 
389e23c41c9SAli Bahrami 		if (aplist_append(&dbp->d_list, lmid_opt, AL_CNT_DEBUG) == NULL)
390e23c41c9SAli Bahrami 			return (FALSE);
391e23c41c9SAli Bahrami 		dbp->d_extra |= DBG_E_LMID;
392e23c41c9SAli Bahrami 		return (TRUE);
393e23c41c9SAli Bahrami 	}
394e23c41c9SAli Bahrami 
395e23c41c9SAli Bahrami 	/* It's nothing we recognize */
396e23c41c9SAli Bahrami 	return (FALSE);
397e23c41c9SAli Bahrami }
398e23c41c9SAli Bahrami 
3997c478bd9Sstevel@tonic-gate /*
4007c478bd9Sstevel@tonic-gate  * Validate and enable the appropriate debugging classes.
401e23c41c9SAli Bahrami  *
402e23c41c9SAli Bahrami  * entry:
403e23c41c9SAli Bahrami  *	string - String to be analyzed for debugging options
404e23c41c9SAli Bahrami  *	dbp - Pointer to debug descriptor to be initialized
405e23c41c9SAli Bahrami  *	outfile_ret - NULL, or pointer to receive result of 'output='
406e23c41c9SAli Bahrami  *		token. A NULL value means that the 'output=' token
407e23c41c9SAli Bahrami  *		is not accepted. A non-NULL value means that it is.
408e23c41c9SAli Bahrami  *
409e23c41c9SAli Bahrami  * exit:
410e23c41c9SAli Bahrami  *	On failure, False (0) is returned.
411e23c41c9SAli Bahrami  *
412e23c41c9SAli Bahrami  *	On success, string has been parsed, and the descriptor referenced
413e23c41c9SAli Bahrami  *	by dbp has been initialized. If outfile is non-NULL, *outfile will
414e23c41c9SAli Bahrami  *	be set to NULL if the 'output=' token is not present, and to the
415e23c41c9SAli Bahrami  *	user supplied string otherwise. True (1) is returned.
4167c478bd9Sstevel@tonic-gate  */
417e23c41c9SAli Bahrami int
Dbg_setup(dbg_setup_caller_t caller,const char * string,Dbg_desc * dbp,const char ** outfile)418e23c41c9SAli Bahrami Dbg_setup(dbg_setup_caller_t caller, const char *string, Dbg_desc *dbp,
419e23c41c9SAli Bahrami     const char **outfile)
4207c478bd9Sstevel@tonic-gate {
4215aefb655Srie 	char		*name, *_name;	/* buffer in which to perform */
4225aefb655Srie 					/* strtok_r() operations. */
4237c478bd9Sstevel@tonic-gate 	char		*lasts;
4247c478bd9Sstevel@tonic-gate 	const char	*delimit = MSG_ORIG(MSG_STR_DELIMIT);
4257c478bd9Sstevel@tonic-gate 
426e23c41c9SAli Bahrami 	/*
427e23c41c9SAli Bahrami 	 * Clear the help flags --- these items only apply for a single
428e23c41c9SAli Bahrami 	 * call to Dbg_setup().
429e23c41c9SAli Bahrami 	 */
430e23c41c9SAli Bahrami 	dbp->d_extra &= ~(DBG_E_HELP | DBG_E_HELP_EXIT);
431e23c41c9SAli Bahrami 
432e23c41c9SAli Bahrami 	if ((_name = (char *)malloc(strlen(string) + 1)) == NULL)
433e23c41c9SAli Bahrami 		return (0);
4347c478bd9Sstevel@tonic-gate 	(void) strcpy(_name, string);
4357c478bd9Sstevel@tonic-gate 
436e23c41c9SAli Bahrami 	if (outfile)
437e23c41c9SAli Bahrami 		*outfile = NULL;   /* No output file yet */
438e23c41c9SAli Bahrami 
4397c478bd9Sstevel@tonic-gate 	/*
4407c478bd9Sstevel@tonic-gate 	 * The token should be of the form "-Dtok,tok,tok,...".  Separate the
4417c478bd9Sstevel@tonic-gate 	 * pieces and build up the appropriate mask, unrecognized options are
4427c478bd9Sstevel@tonic-gate 	 * flagged.
4437c478bd9Sstevel@tonic-gate 	 */
4447c478bd9Sstevel@tonic-gate 	if ((name = strtok_r(_name, delimit, &lasts)) != NULL) {
4457c478bd9Sstevel@tonic-gate 		do {
446e23c41c9SAli Bahrami 			Boolean		set;
447e23c41c9SAli Bahrami 
448e23c41c9SAli Bahrami 			/* Remove leading and trailing whitespace */
449e23c41c9SAli Bahrami 			name = conv_strproc_trim(name);
4505aefb655Srie 
4517c478bd9Sstevel@tonic-gate 			if (name[0] == '!') {
4527c478bd9Sstevel@tonic-gate 				set = FALSE;
4537c478bd9Sstevel@tonic-gate 				name++;
4545aefb655Srie 			} else
4555aefb655Srie 				set = TRUE;
4565aefb655Srie 
457e23c41c9SAli Bahrami 			if (*name == '\0')
458e23c41c9SAli Bahrami 				continue;	/* Skip null token */
459e23c41c9SAli Bahrami 
4605aefb655Srie 			/*
4615aefb655Srie 			 * First, determine if the token represents a class or
4625aefb655Srie 			 * extra.
4635aefb655Srie 			 */
464e23c41c9SAli Bahrami 			if (process_options(name, set, dbp, _Dbg_options))
465e23c41c9SAli Bahrami 				continue;
466e23c41c9SAli Bahrami 			switch (caller) {
467e23c41c9SAli Bahrami 			case DBG_CALLER_LD:	/* ld only tokens */
468e23c41c9SAli Bahrami 				if (process_options(name, set, dbp,
469e23c41c9SAli Bahrami 				    _Dbg_options_ld))
470e23c41c9SAli Bahrami 					continue;
471e23c41c9SAli Bahrami 				break;
472e23c41c9SAli Bahrami 			case DBG_CALLER_RTLD:	/* rtld only tokens */
473e23c41c9SAli Bahrami 				if (process_options(name, set, dbp,
474e23c41c9SAli Bahrami 				    _Dbg_options_rtld))
4755aefb655Srie 					continue;
4765aefb655Srie 				break;
4777c478bd9Sstevel@tonic-gate 			}
478e23c41c9SAli Bahrami 
479e23c41c9SAli Bahrami 			/* The remaining options do not accept negation */
480e23c41c9SAli Bahrami 			if (!set) {
481e23c41c9SAli Bahrami 				dbg_print(0, MSG_INTL(MSG_USE_CNTNEGOPT), name);
4825aefb655Srie 				continue;
483e23c41c9SAli Bahrami 			}
4845aefb655Srie 
4855aefb655Srie 			/*
486e23c41c9SAli Bahrami 			 * Is it an 'output=' token? This item is a special
487e23c41c9SAli Bahrami 			 * case because it depends on the presence of
488e23c41c9SAli Bahrami 			 * a non-NULL outfile argument, and because the
489e23c41c9SAli Bahrami 			 * part following the '=' is variable.
4905aefb655Srie 			 */
491e23c41c9SAli Bahrami 			if ((outfile != NULL) &&
492e23c41c9SAli Bahrami 			    strncmp(name, MSG_ORIG(MSG_TOK_OUTFILE),
493e23c41c9SAli Bahrami 			    MSG_TOK_OUTFILE_SIZE) == 0) {
494e23c41c9SAli Bahrami 				if (conv_strproc_extract_value(name,
495e23c41c9SAli Bahrami 				    MSG_TOK_OUTFILE_SIZE, 0, outfile))
4965aefb655Srie 					continue;
4977c478bd9Sstevel@tonic-gate 			}
4985aefb655Srie 
499e23c41c9SAli Bahrami 			/*
500e23c41c9SAli Bahrami 			 * Only the rtld "lmid" token is left.
501e23c41c9SAli Bahrami 			 */
502e23c41c9SAli Bahrami 			if ((caller == DBG_CALLER_RTLD) && (strncmp(name,
503e23c41c9SAli Bahrami 			    MSG_ORIG(MSG_TOK_LMID), MSG_TOK_LMID_SIZE) == 0) &&
504e23c41c9SAli Bahrami 			    process_lmid(name, dbp))
505e23c41c9SAli Bahrami 				continue;
506e23c41c9SAli Bahrami 
507e23c41c9SAli Bahrami 			/* If we make it here, the token is not understood */
508e23c41c9SAli Bahrami 			dbg_print(0, MSG_INTL(MSG_USE_UNRECOG), name);
5095aefb655Srie 
5107c478bd9Sstevel@tonic-gate 		} while ((name = strtok_r(NULL, delimit, &lasts)) != NULL);
5117c478bd9Sstevel@tonic-gate 	}
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 	/*
514e23c41c9SAli Bahrami 	 * If the debug help option was specified and this is the only debug
515e23c41c9SAli Bahrami 	 * class, return an indication that the user should exit.
5167c478bd9Sstevel@tonic-gate 	 */
517e23c41c9SAli Bahrami 	if ((_Dbg_cnt++ == 0) && (dbp->d_extra & DBG_E_HELP) &&
518e23c41c9SAli Bahrami 	    (dbp->d_class == 0))
519e23c41c9SAli Bahrami 		dbp->d_extra |= DBG_E_HELP_EXIT;
520e23c41c9SAli Bahrami 
5215aefb655Srie 	return (1);
5227c478bd9Sstevel@tonic-gate }
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate /*
5255aefb655Srie  * Define our own printing routine.  This provides a basic fallback, as ld(1)
5265aefb655Srie  * and ld.so.1(1) provide their own routines that augment their diagnostic
5275aefb655Srie  * output, and direct the output to stderr.  This item should be defined
5285aefb655Srie  * NODIRECT.
5297c478bd9Sstevel@tonic-gate  */
5305aefb655Srie /* PRINTFLIKE2 */
5317c478bd9Sstevel@tonic-gate void
dbg_print(Lm_list * lml,const char * format,...)5325aefb655Srie dbg_print(Lm_list *lml, const char *format, ...)
5337c478bd9Sstevel@tonic-gate {
5345aefb655Srie 	va_list ap;
5357c478bd9Sstevel@tonic-gate 
5365aefb655Srie #if	defined(lint)
5375aefb655Srie 	/*
5385aefb655Srie 	 * The lml argument is only meaningful for diagnostics sent to ld.so.1.
5395aefb655Srie 	 * Supress the lint error by making a dummy assignment.
5405aefb655Srie 	 */
5415aefb655Srie 	lml = 0;
5425aefb655Srie #endif
5435aefb655Srie 	va_start(ap, format);
5445aefb655Srie 	(void) vprintf(format, ap);
5455aefb655Srie 	(void) printf(MSG_ORIG(MSG_STR_NL));
5465aefb655Srie 	va_end(ap);
5477c478bd9Sstevel@tonic-gate }
54869112eddSAli Bahrami 
54969112eddSAli Bahrami /*
55069112eddSAli Bahrami  * Return an internationalized state transition string. These are used by
55169112eddSAli Bahrami  * various debugging output.
55269112eddSAli Bahrami  */
55369112eddSAli Bahrami const char *
Dbg_state_str(dbg_state_t type)55469112eddSAli Bahrami Dbg_state_str(dbg_state_t type)
55569112eddSAli Bahrami {
55669112eddSAli Bahrami 	static const Msg state[DBG_STATE_NUM] = {
55769112eddSAli Bahrami 		MSG_STR_ADD,		/* MSG_INTL(MSG_STR_ADD)  */
55869112eddSAli Bahrami 		MSG_STR_CURRENT,	/* MSG_INTL(MSG_STR_CURRENT) */
55969112eddSAli Bahrami 		MSG_STR_EXCLUDE,	/* MSG_INTL(MSG_STR_EXCLUDE) */
56069112eddSAli Bahrami 		MSG_STR_IGNORE,		/* MSG_INTL(MSG_STR_IGNORE) */
56169112eddSAli Bahrami 		MSG_STR_MOD_BEFORE,	/* MSG_INTL(MSG_STR_MOD_BEFORE) */
56269112eddSAli Bahrami 		MSG_STR_MOD_AFTER,	/* MSG_INTL(MSG_STR_MOD_AFTER) */
56369112eddSAli Bahrami 		MSG_STR_NEW,		/* MSG_INTL(MSG_STR_NEW) */
56469112eddSAli Bahrami 		MSG_STR_NEW_IMPLICIT,	/* MSG_INTL(MSG_STR_NEW_IMPLICIT) */
56569112eddSAli Bahrami 		MSG_STR_RESET,		/* MSG_INTL(MSG_STR_RESET) */
56608278a5eSRod Evans 		MSG_STR_ORIGINAL,	/* MSG_INTL(MSG_STR_ORIGINAL) */
56769112eddSAli Bahrami 		MSG_STR_RESOLVED,	/* MSG_INTL(MSG_STR_RESOLVED) */
56869112eddSAli Bahrami 	};
56969112eddSAli Bahrami #if DBG_STATE_NUM != (DBG_STATE_RESOLVED + 1)
57069112eddSAli Bahrami #error DBG_SEG_NUM has changed. Update segtype[]
57169112eddSAli Bahrami #endif
57269112eddSAli Bahrami 
57369112eddSAli Bahrami 	assert(type < DBG_STATE_NUM);
57469112eddSAli Bahrami 	return (MSG_INTL(state[type]));
57569112eddSAli Bahrami }
576