debug.c revision 280:ffd6f0e5ac00
1139749Simp/*
212090Sgibbs * CDDL HEADER START
38012Sjulian *
415329Sgibbs * The contents of this file are subject to the terms of the
512090Sgibbs * Common Development and Distribution License, Version 1.0 only
615329Sgibbs * (the "License").  You may not use this file except in compliance
712090Sgibbs * with the License.
812090Sgibbs *
912090Sgibbs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1012090Sgibbs * or http://www.opensolaris.org/os/licensing.
1112090Sgibbs * See the License for the specific language governing permissions
1212090Sgibbs * and limitations under the License.
1312090Sgibbs *
1412090Sgibbs * When distributing Covered Code, include this CDDL HEADER in each
1512090Sgibbs * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1615329Sgibbs * If applicable, add the following below this CDDL HEADER, with the
1715329Sgibbs * fields enclosed by brackets "[]" replaced with your own identifying
188012Sjulian * information: Portions Copyright [yyyy] [name of copyright owner]
1915329Sgibbs *
2015329Sgibbs * CDDL HEADER END
2115329Sgibbs */
2215329Sgibbs/*
2315329Sgibbs * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
2415329Sgibbs * Use is subject to license terms.
2515329Sgibbs */
2615329Sgibbs#pragma ident	"%Z%%M%	%I%	%E% SMI"
2715329Sgibbs
2815329Sgibbs#include	<stdio.h>
2915329Sgibbs#include	<string.h>
3015329Sgibbs#include	<stdlib.h>
3150477Speter#include	"_debug.h"
328012Sjulian#include	"msg.h"
338012Sjulian
34130274Simpuint_t		_Dbg_mask;
35130274Simpstatic int	_Dbg_count = 0;
368012Sjulian
37130274Simp
3813691Sgibbs/*
3912090Sgibbs * Debugging initialization and processing.  The options structure defines
4012122Sgibbs * a set of option strings that can be specified using the -D flag or from an
4112122Sgibbs * environment variable.  For each option, a class is enabled in the _Dbg_mask
4212122Sgibbs * bit mask.
4312122Sgibbs */
4412122Sgibbsstatic DBG_options _Dbg_options[] = {
4512122Sgibbs	{MSG_ORIG(MSG_TOK_NAME),	DBG_G_SNAME},
4612090Sgibbs	{MSG_ORIG(MSG_TOK_FULLNAME),	DBG_G_SNAME | DBG_G_FNAME},
4723855Sjoerg	{MSG_ORIG(MSG_TOK_CLASS),	DBG_G_SNAME | DBG_G_CLASS},
4812090Sgibbs
4913691Sgibbs	{MSG_ORIG(MSG_TOK_ALL),		DBG_LOCAL},
5012090Sgibbs	{MSG_ORIG(MSG_TOK_ARGS),	DBG_ARGS},
5145791Speter	{MSG_ORIG(MSG_TOK_BASIC),	DBG_BASIC},
5245791Speter	{MSG_ORIG(MSG_TOK_BINDINGS),	DBG_BINDINGS},
5345791Speter	{MSG_ORIG(MSG_TOK_DETAIL),	DBG_DETAIL},
5445791Speter	{MSG_ORIG(MSG_TOK_ENTRY),	DBG_ENTRY},
5545791Speter	{MSG_ORIG(MSG_TOK_FILES),	DBG_FILES},
5645791Speter	{MSG_ORIG(MSG_TOK_HELP),	DBG_HELP},
5749360Smdodd	{MSG_ORIG(MSG_TOK_LIBS),	DBG_LIBS},
5849360Smdodd	{MSG_ORIG(MSG_TOK_LONG),	DBG_LONG},
5949360Smdodd	{MSG_ORIG(MSG_TOK_MAP),		DBG_MAP},
6045791Speter	{MSG_ORIG(MSG_TOK_RELOC),	DBG_RELOC},
6145791Speter	{MSG_ORIG(MSG_TOK_SECTIONS),	DBG_SECTIONS},
6245791Speter	{MSG_ORIG(MSG_TOK_SEGMENTS),	DBG_SEGMENTS},
63102177Smux	{MSG_ORIG(MSG_TOK_SUPPORT),	DBG_SUPPORT},
64102177Smux	{MSG_ORIG(MSG_TOK_SYMBOLS),	DBG_SYMBOLS},
6545791Speter	{MSG_ORIG(MSG_TOK_TLS),		DBG_TLS},
6645791Speter	{MSG_ORIG(MSG_TOK_AUDIT),	DBG_AUDITING},
6745791Speter	{MSG_ORIG(MSG_TOK_VERSIONS),	DBG_VERSIONS},
6845791Speter	{MSG_ORIG(MSG_TOK_GOT),		DBG_GOT},
6945791Speter	{MSG_ORIG(MSG_TOK_MOVE),	DBG_MOVE},
70102177Smux	{MSG_ORIG(MSG_TOK_STRTAB),	DBG_STRTAB},
71102177Smux	{MSG_ORIG(MSG_TOK_STATISTICS),	DBG_STATISTICS},
7213691Sgibbs	{MSG_ORIG(MSG_TOK_UNUSED),	DBG_UNUSED},
7313691Sgibbs#ifdef	DEMANGLE
7413691Sgibbs	{MSG_ORIG(MSG_TOK_DEMANGLE),	DBG_DEMANGLE},
7513691Sgibbs#endif
7613691Sgibbs	{MSG_ORIG(MSG_TOK_CAP),		DBG_CAP},
7713691Sgibbs	{MSG_ORIG(MSG_TOK_INIT),	DBG_INIT},
78130274Simp	{NULL,				NULL},
79130274Simp};
80130274Simp
81130274Simp/*
82130274Simp * Provide a debugging usage message
83130274Simp */
84130274Simpstatic void
85130274Simp_Dbg_usage()
86130274Simp{
87130274Simp	dbg_print(MSG_ORIG(MSG_STR_EMPTY));
88130274Simp	dbg_print(MSG_INTL(MSG_USE_RTLD_A));
89130274Simp	dbg_print(MSG_INTL(MSG_USE_RTLD_B));
90130274Simp	dbg_print(MSG_INTL(MSG_USE_RTLD_C));
91130274Simp	dbg_print(MSG_INTL(MSG_USE_RTLD_D));
92130274Simp	dbg_print(MSG_INTL(MSG_USE_RTLD_E));
93130274Simp	dbg_print(MSG_INTL(MSG_USE_RTLD_F));
94130274Simp	dbg_print(MSG_INTL(MSG_USE_RTLD_G));
95130274Simp
96130274Simp	dbg_print(MSG_ORIG(MSG_STR_EMPTY));
97130274Simp	dbg_print(MSG_INTL(MSG_USE_LD_A));
98130274Simp	dbg_print(MSG_INTL(MSG_USE_LD_B));
99	dbg_print(MSG_INTL(MSG_USE_LD_C));
100	dbg_print(MSG_INTL(MSG_USE_LD_D));
101	dbg_print(MSG_INTL(MSG_USE_LD_E));
102	dbg_print(MSG_INTL(MSG_USE_LD_F));
103	dbg_print(MSG_INTL(MSG_USE_LD_G));
104	dbg_print(MSG_INTL(MSG_USE_LD_H));
105	dbg_print(MSG_INTL(MSG_USE_LD_I));
106	dbg_print(MSG_INTL(MSG_USE_LD_J));
107
108	dbg_print(MSG_ORIG(MSG_STR_EMPTY));
109	dbg_print(MSG_ORIG(MSG_STR_EMPTY));
110	dbg_print(MSG_INTL(MSG_USE_ARGS));
111	dbg_print(MSG_INTL(MSG_USE_AUDIT));
112	dbg_print(MSG_INTL(MSG_USE_BASIC));
113	dbg_print(MSG_INTL(MSG_USE_BINDINGS));
114	dbg_print(MSG_INTL(MSG_USE_BINDINGS_2));
115	dbg_print(MSG_INTL(MSG_USE_CAP));
116	dbg_print(MSG_INTL(MSG_USE_DETAIL));
117#ifdef	DEMANGLE
118	dbg_print(MSG_INTL(MSG_USE_DEMANGLE));
119#endif
120	dbg_print(MSG_INTL(MSG_USE_ENTRY));
121	dbg_print(MSG_INTL(MSG_USE_FILES));
122	dbg_print(MSG_INTL(MSG_USE_GOT));
123	dbg_print(MSG_INTL(MSG_USE_HELP));
124	dbg_print(MSG_INTL(MSG_USE_INIT));
125	dbg_print(MSG_INTL(MSG_USE_LIBS));
126	dbg_print(MSG_INTL(MSG_USE_LIBS_2));
127	dbg_print(MSG_INTL(MSG_USE_LONG));
128	dbg_print(MSG_INTL(MSG_USE_MAP));
129	dbg_print(MSG_INTL(MSG_USE_MOVE));
130	dbg_print(MSG_INTL(MSG_USE_RELOC));
131	dbg_print(MSG_INTL(MSG_USE_SECTIONS));
132	dbg_print(MSG_INTL(MSG_USE_SEGMENTS));
133	dbg_print(MSG_INTL(MSG_USE_SEGMENTS_2));
134	dbg_print(MSG_INTL(MSG_USE_STATISTICS));
135	dbg_print(MSG_INTL(MSG_USE_STRTAB));
136	dbg_print(MSG_INTL(MSG_USE_STRTAB_2));
137	dbg_print(MSG_INTL(MSG_USE_SUPPORT));
138	dbg_print(MSG_INTL(MSG_USE_SYMBOLS));
139	dbg_print(MSG_INTL(MSG_USE_SYMBOLS_2));
140	dbg_print(MSG_INTL(MSG_USE_TLS));
141	dbg_print(MSG_INTL(MSG_USE_UNUSED));
142	dbg_print(MSG_INTL(MSG_USE_UNUSED_2));
143	dbg_print(MSG_INTL(MSG_USE_VERSIONS));
144}
145
146/*
147 * Validate and enable the appropriate debugging classes.
148 */
149uint_t
150Dbg_setup(const char *string)
151{
152	char		*name, *_name;	/* Temporary buffer in which to */
153					/* perform strtok_r() operations. */
154	char		*lasts;
155	DBG_opts 	opts;		/* Ptr to cycle thru _Dbg_options[]. */
156	const char	*delimit = MSG_ORIG(MSG_STR_DELIMIT);
157
158	if ((_name = (char *)malloc(strlen(string) + 1)) == 0)
159		return (0);
160	(void) strcpy(_name, string);
161
162	/*
163	 * The token should be of the form "-Dtok,tok,tok,...".  Separate the
164	 * pieces and build up the appropriate mask, unrecognized options are
165	 * flagged.
166	 */
167	if ((name = strtok_r(_name, delimit, &lasts)) != NULL) {
168		Boolean		found, set;
169		do {
170			found = FALSE;
171			set = TRUE;
172			if (name[0] == '!') {
173				set = FALSE;
174				name++;
175			}
176			for (opts = _Dbg_options; opts->o_name != NULL;
177				opts++) {
178				if (strcmp(name, opts->o_name) == 0) {
179					if (set == TRUE)
180						_Dbg_mask |= opts->o_mask;
181					else
182						_Dbg_mask &= ~(opts->o_mask);
183					found = TRUE;
184					break;
185				}
186			}
187			if (found == FALSE)
188				dbg_print(MSG_INTL(MSG_USE_UNRECOG), name);
189		} while ((name = strtok_r(NULL, delimit, &lasts)) != NULL);
190	}
191	(void) free(_name);
192
193	/*
194	 * If the debug help option was specified dump a usage message.  If
195	 * this is the only debug option return an indication that the user
196	 * should exit.
197	 */
198	if ((_Dbg_mask & DBG_HELP) && !_Dbg_count) {
199		_Dbg_usage();
200		if (_Dbg_mask == DBG_HELP)
201			/* LINTED */
202			return ((uint_t)S_ERROR);
203	}
204
205	_Dbg_count++;
206
207	return (_Dbg_mask);
208}
209
210/*
211 * Set the specified flags to _Dbg_mask.
212 */
213void
214Dbg_set(uint_t flags)
215{
216	_Dbg_mask = flags;
217}
218
219
220/*
221 * Messaging support - funnel everything through _dgettext() as this provides
222 * a stub binding to libc, or a real binding to libintl.
223 */
224extern char	*_dgettext(const char *, const char *);
225
226const char *
227_liblddbg_msg(Msg mid)
228{
229	return (_dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid)));
230}
231