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
275aefb655Srie #include <libintl.h>
285aefb655Srie #include <sys/varargs.h>
297c478bd9Sstevel@tonic-gate #include <stdio.h>
307c478bd9Sstevel@tonic-gate #include <string.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
325aefb655Srie #include <alist.h>
335aefb655Srie #include <debug.h>
345aefb655Srie #include <_debug.h>
355aefb655Srie #include <msg.h>
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate /*
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.
417c478bd9Sstevel@tonic-gate */
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;
465aefb655Srie
475aefb655Srie /*
485aefb655Srie * Debugging initialization and processing. The dbg_options[] array defines
495aefb655Srie * 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.
525aefb655Srie */
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},
615aefb655Srie {MSG_ORIG(MSG_TOK_BASIC), DBG_C_BASIC, 0},
62e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_CAP), DBG_C_CAP, 0},
63e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_DEMANGLE), DBG_C_DEMANGLE, 0},
645aefb655Srie {MSG_ORIG(MSG_TOK_FILES), DBG_C_FILES, 0},
655aefb655Srie {MSG_ORIG(MSG_TOK_LIBS), DBG_C_LIBS, 0},
66e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_MOVE), DBG_C_MOVE, 0},
675aefb655Srie {MSG_ORIG(MSG_TOK_RELOC), DBG_C_RELOC, 0},
685aefb655Srie {MSG_ORIG(MSG_TOK_SYMBOLS), DBG_C_SYMBOLS, 0},
695aefb655Srie {MSG_ORIG(MSG_TOK_TLS), DBG_C_TLS, 0},
705aefb655Srie {MSG_ORIG(MSG_TOK_UNUSED), DBG_C_UNUSED, 0},
71e23c41c9SAli 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},
82e23c41c9SAli Bahrami {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},
86e23c41c9SAli Bahrami {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*98c080d5SRod Evans {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
1007c478bd9Sstevel@tonic-gate /*
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)
1077c478bd9Sstevel@tonic-gate {
1085aefb655Srie DBG_options *opt;
1095aefb655Srie
110e23c41c9SAli Bahrami for (opt = optarr; opt->o_name != NULL; opt++) {
1115aefb655Srie if (strcmp(name, opt->o_name) != 0)
1125aefb655Srie continue;
1135aefb655Srie
1145aefb655Srie if (set == TRUE) {
1155aefb655Srie if (opt->o_class)
1165aefb655Srie dbp->d_class |= opt->o_class;
1175aefb655Srie if (opt->o_extra)
1185aefb655Srie dbp->d_extra |= opt->o_extra;
1195aefb655Srie } else {
1205aefb655Srie if (opt->o_class)
1215aefb655Srie dbp->d_class &= ~(opt->o_class);
1225aefb655Srie if (opt->o_extra)
1235aefb655Srie dbp->d_extra &= ~(opt->o_extra);
1247c478bd9Sstevel@tonic-gate }
125e23c41c9SAli Bahrami return (TRUE);
126e23c41c9SAli Bahrami }
127e23c41c9SAli Bahrami
128e23c41c9SAli Bahrami return (FALSE);
129e23c41c9SAli Bahrami }
130e23c41c9SAli Bahrami
131e23c41c9SAli Bahrami /*
132e23c41c9SAli Bahrami * Provide a debugging usage message
133e23c41c9SAli Bahrami */
134e23c41c9SAli Bahrami void
Dbg_help(void)135e23c41c9SAli Bahrami Dbg_help(void)
136e23c41c9SAli Bahrami {
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
146e23c41c9SAli Bahrami 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
182e23c41c9SAli Bahrami 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));
190e23c41c9SAli Bahrami
191e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC);
192e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_N));
193e23c41c9SAli Bahrami
194e23c41c9SAli Bahrami 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
214e23c41c9SAli Bahrami 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
232e23c41c9SAli Bahrami 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
239e23c41c9SAli Bahrami 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));
257e23c41c9SAli Bahrami
258e23c41c9SAli Bahrami 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
266e23c41c9SAli Bahrami 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
280e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC);
281e23c41c9SAli Bahrami }
282e23c41c9SAli Bahrami
283e23c41c9SAli 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
29469112eddSAli Bahrami /*
295e23c41c9SAli Bahrami * Messaging support - funnel everything through dgettext() as this provides
296e23c41c9SAli Bahrami * the real binding to libc.
297e23c41c9SAli Bahrami */
298e23c41c9SAli Bahrami const char *
_liblddbg_msg(Msg mid)299e23c41c9SAli Bahrami _liblddbg_msg(Msg mid)
300e23c41c9SAli Bahrami {
301e23c41c9SAli Bahrami return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid)));
302e23c41c9SAli Bahrami }
303e23c41c9SAli Bahrami
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},
330e23c41c9SAli Bahrami {NULL, NULL},
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
399e23c41c9SAli Bahrami /*
400e23c41c9SAli Bahrami * 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.
416e23c41c9SAli Bahrami */
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)
420e23c41c9SAli Bahrami {
421e23c41c9SAli Bahrami char *name, *_name; /* buffer in which to perform */
422e23c41c9SAli Bahrami /* strtok_r() operations. */
423e23c41c9SAli Bahrami char *lasts;
424e23c41c9SAli Bahrami const char *delimit = MSG_ORIG(MSG_STR_DELIMIT);
425e23c41c9SAli Bahrami
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);
434e23c41c9SAli Bahrami (void) strcpy(_name, string);
435e23c41c9SAli Bahrami
436e23c41c9SAli Bahrami if (outfile)
437e23c41c9SAli Bahrami *outfile = NULL; /* No output file yet */
438e23c41c9SAli Bahrami
439e23c41c9SAli Bahrami /*
440e23c41c9SAli Bahrami * The token should be of the form "-Dtok,tok,tok,...". Separate the
441e23c41c9SAli Bahrami * pieces and build up the appropriate mask, unrecognized options are
442e23c41c9SAli Bahrami * flagged.
443e23c41c9SAli Bahrami */
444e23c41c9SAli Bahrami if ((name = strtok_r(_name, delimit, &lasts)) != NULL) {
445e23c41c9SAli Bahrami do {
446e23c41c9SAli Bahrami Boolean set;
447e23c41c9SAli Bahrami
448e23c41c9SAli Bahrami /* Remove leading and trailing whitespace */
449e23c41c9SAli Bahrami name = conv_strproc_trim(name);
450e23c41c9SAli Bahrami
451e23c41c9SAli Bahrami if (name[0] == '!') {
452e23c41c9SAli Bahrami set = FALSE;
453e23c41c9SAli Bahrami name++;
454e23c41c9SAli Bahrami } else
455e23c41c9SAli Bahrami set = TRUE;
456e23c41c9SAli Bahrami
457e23c41c9SAli Bahrami if (*name == '\0')
458e23c41c9SAli Bahrami continue; /* Skip null token */
459e23c41c9SAli Bahrami
460e23c41c9SAli Bahrami /*
461e23c41c9SAli Bahrami * First, determine if the token represents a class or
462e23c41c9SAli Bahrami * extra.
463e23c41c9SAli Bahrami */
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;
4717c478bd9Sstevel@tonic-gate 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;
4775aefb655Srie }
4785aefb655Srie
479e23c41c9SAli Bahrami /* The remaining options do not accept negation */
480e23c41c9SAli Bahrami if (!set) {
481e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_CNTNEGOPT), name);
482e23c41c9SAli Bahrami continue;
483e23c41c9SAli Bahrami }
484e23c41c9SAli Bahrami
485e23c41c9SAli Bahrami /*
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.
490e23c41c9SAli Bahrami */
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))
496e23c41c9SAli Bahrami continue;
497e23c41c9SAli Bahrami }
498e23c41c9SAli Bahrami
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 */
5085aefb655Srie 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)
5377c478bd9Sstevel@tonic-gate /*
5385aefb655Srie * The lml argument is only meaningful for diagnostics sent to ld.so.1.
5395aefb655Srie * Supress the lint error by making a dummy assignment.
5407c478bd9Sstevel@tonic-gate */
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