xref: /illumos-gate/usr/src/cmd/sgs/liblddbg/common/util.c (revision 883c6d492b73694fbeba5348b7468609213b7a81)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include	"msg.h"
29 #include	"_debug.h"
30 #include	"libld.h"
31 
32 /*
33  * If any run-time linker debugging is being carried out always indicate the
34  * fact and specify the point at which we transfer control to the main program.
35  */
36 void
37 Dbg_util_call_main(Rt_map *lmp)
38 {
39 	Lm_list	*lml = LIST(lmp);
40 
41 	Dbg_util_nl(lml, DBG_NL_FRC);
42 	dbg_print(lml, MSG_INTL(MSG_UTL_TRANS), NAME(lmp));
43 	Dbg_util_nl(lml, DBG_NL_FRC);
44 }
45 
46 void
47 Dbg_util_call_init(Rt_map *lmp, int flag)
48 {
49 	Lm_list		*lml = LIST(lmp);
50 	const char	*str;
51 
52 	if (DBG_NOTCLASS(DBG_C_INIT))
53 		return;
54 
55 	if (flag == DBG_INIT_SORT)
56 		str = MSG_INTL(MSG_UTL_SORT);
57 	else if (flag == DBG_INIT_PEND)
58 		str = MSG_INTL(MSG_UTL_PEND);
59 	else if (flag == DBG_INIT_DYN)
60 		str = MSG_INTL(MSG_UTL_DYN);
61 	else
62 		str = MSG_INTL(MSG_UTL_DONE);
63 
64 	Dbg_util_nl(lml, DBG_NL_STD);
65 	dbg_print(lml, MSG_INTL(MSG_UTL_INIT), str, NAME(lmp));
66 	Dbg_util_nl(lml, DBG_NL_STD);
67 }
68 
69 void
70 Dbg_util_no_init(Rt_map *lmp)
71 {
72 	Lm_list	*lml = LIST(lmp);
73 
74 	if (DBG_NOTCLASS(DBG_C_INIT))
75 		return;
76 
77 	Dbg_util_nl(lml, DBG_NL_STD);
78 	dbg_print(lml, MSG_INTL(MSG_UTL_NOINIT), NAME(lmp));
79 	Dbg_util_nl(lml, DBG_NL_STD);
80 }
81 
82 void
83 Dbg_util_intoolate(Rt_map *lmp)
84 {
85 	Lm_list	*lml = LIST(lmp);
86 
87 	Dbg_util_nl(lml, DBG_NL_STD);
88 	dbg_print(lml, MSG_INTL(MSG_UTL_INTOOLATE), NAME(lmp));
89 	Dbg_util_nl(lml, DBG_NL_STD);
90 }
91 
92 void
93 Dbg_util_dbnotify(Lm_list *lml, rd_event_e event, r_state_e state)
94 {
95 	const char	*estr;
96 	const char	*sstr;
97 
98 	if (DBG_NOTCLASS(DBG_C_FILES))
99 		return;
100 	if (DBG_NOTDETAIL())
101 		return;
102 
103 	switch (event) {
104 	case RD_PREINIT:
105 		estr = MSG_ORIG(MSG_UTL_EVNT_PREINIT);
106 		sstr = MSG_INTL(MSG_STR_NULL);
107 		break;
108 	case RD_POSTINIT:
109 		estr = MSG_ORIG(MSG_UTL_EVNT_POSTINIT);
110 		sstr = MSG_INTL(MSG_STR_NULL);
111 		break;
112 	case RD_DLACTIVITY:
113 		estr = MSG_ORIG(MSG_UTL_EVNT_DLACT);
114 		switch (state) {
115 		case RT_CONSISTENT:
116 			sstr = MSG_ORIG(MSG_UTL_STA_CONSIST);
117 			break;
118 		case RT_ADD:
119 			sstr = MSG_ORIG(MSG_UTL_STA_ADD);
120 			break;
121 		case RT_DELETE:
122 			sstr = MSG_ORIG(MSG_UTL_STA_DELETE);
123 			break;
124 		default:
125 			sstr = MSG_INTL(MSG_STR_NULL);
126 			break;
127 		}
128 		break;
129 	default:
130 		sstr = MSG_INTL(MSG_STR_NULL);
131 		estr = MSG_INTL(MSG_STR_UNKNOWN);
132 		break;
133 	}
134 
135 	Dbg_util_nl(lml, DBG_NL_STD);
136 	dbg_print(lml, MSG_INTL(MSG_UTL_DBNOTIFY), estr, sstr);
137 	Dbg_util_nl(lml, DBG_NL_STD);
138 }
139 
140 void
141 Dbg_util_call_array(Rt_map *lmp, void *addr, int ndx, Word shtype)
142 {
143 	Lm_list		*lml = LIST(lmp);
144 	const char	*str;
145 
146 	if (DBG_NOTCLASS(DBG_C_INIT))
147 		return;
148 
149 	if (shtype == SHT_INIT_ARRAY)
150 		str = MSG_ORIG(MSG_SCN_INITARRAY);
151 	else if (shtype == SHT_FINI_ARRAY)
152 		str = MSG_ORIG(MSG_SCN_FINIARRAY);
153 	else
154 		str = MSG_ORIG(MSG_SCN_PREINITARRAY);
155 
156 	dbg_print(lml, MSG_INTL(MSG_UTL_ARRAY), str, ndx, EC_NATPTR(addr),
157 	    NAME(lmp));
158 }
159 
160 void
161 Dbg_util_call_fini(Rt_map *lmp)
162 {
163 	Lm_list	*lml = LIST(lmp);
164 
165 	if (DBG_NOTCLASS(DBG_C_INIT))
166 		return;
167 
168 	Dbg_util_nl(lml, DBG_NL_STD);
169 	dbg_print(lml, MSG_INTL(MSG_UTL_FINI), NAME(lmp));
170 	Dbg_util_nl(lml, DBG_NL_STD);
171 }
172 
173 void
174 Dbg_util_str(Lm_list *lml, const char *str)
175 {
176 	Dbg_util_nl(lml, DBG_NL_STD);
177 	Dbg_util_nl(lml, DBG_NL_FRC);
178 	dbg_print(lml, MSG_ORIG(MSG_FMT_STR), str);
179 	Dbg_util_nl(lml, DBG_NL_FRC);
180 	Dbg_util_nl(lml, DBG_NL_STD);
181 }
182 
183 void
184 Dbg_util_scc_title(Lm_list *lml, int sec)
185 {
186 	const char	*_sec;
187 
188 	if (DBG_NOTCLASS(DBG_C_INIT))
189 		return;
190 	if (DBG_NOTDETAIL())
191 		return;
192 
193 	if (sec)
194 		_sec = MSG_INTL(MSG_UTL_SCC_SUBI);
195 	else
196 		_sec = MSG_INTL(MSG_UTL_SCC_SUBF);
197 
198 	Dbg_util_nl(lml, DBG_NL_STD);
199 	dbg_print(lml, MSG_INTL(MSG_UTL_SCC_TITLE), _sec);
200 }
201 
202 void
203 Dbg_util_scc_entry(Rt_map *lmp, uint_t idx)
204 {
205 	if (DBG_NOTCLASS(DBG_C_INIT))
206 		return;
207 	if (DBG_NOTDETAIL())
208 		return;
209 
210 	dbg_print(LIST(lmp), MSG_ORIG(MSG_UTL_SCC_ENTRY), idx, NAME(lmp));
211 }
212 
213 void
214 Dbg_util_broadcast(Rt_map *lmp)
215 {
216 	Lm_list	*lml = LIST(lmp);
217 
218 	if (DBG_NOTCLASS(DBG_C_INIT))
219 		return;
220 	if (DBG_NOTDETAIL())
221 		return;
222 
223 	Dbg_util_nl(lml, DBG_NL_STD);
224 	dbg_print(lml, MSG_INTL(MSG_UTL_BROAD), NAME(lmp));
225 	Dbg_util_nl(lml, DBG_NL_STD);
226 }
227 
228 void
229 Dbg_util_wait(Rt_map *clmp, Rt_map *dlmp, int what)
230 {
231 	Lm_list		*lml = LIST(clmp);
232 	const char	*str;
233 
234 	if (DBG_NOTCLASS(DBG_C_INIT))
235 		return;
236 	if (DBG_NOTDETAIL())
237 		return;
238 
239 	if (what == DBG_WAIT_INIT)
240 		str = MSG_ORIG(MSG_SCN_INIT);
241 	else if (what == DBG_WAIT_FINI)
242 		str = MSG_ORIG(MSG_SCN_FINI);
243 	else
244 		str = MSG_INTL(MSG_STR_SYMBOL);
245 
246 	Dbg_util_nl(lml, DBG_NL_STD);
247 	dbg_print(lml, MSG_INTL(MSG_UTL_WAIT), str, NAME(clmp), NAME(dlmp));
248 	Dbg_util_nl(lml, DBG_NL_STD);
249 }
250 
251 static	int ectoggle = 0;
252 
253 void
254 Dbg_util_edge_in(Lm_list *lml, Rt_map *clmp, uint_t flags, Rt_map *dlmp,
255     int ndx, int flag)
256 {
257 	const char	*str;
258 
259 	if (DBG_NOTCLASS(DBG_C_INIT))
260 		return;
261 	if (DBG_NOTDETAIL())
262 		return;
263 
264 	if (flag & RT_SORT_REV)
265 		str = MSG_ORIG(MSG_SCN_INIT);
266 	else
267 		str = MSG_ORIG(MSG_SCN_FINI);
268 
269 	if ((clmp == 0) || (ectoggle == 0))
270 		Dbg_util_nl(lml, DBG_NL_STD);
271 	if (clmp == 0) {
272 		if (flag & RT_SORT_INTPOSE)
273 			dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_I), str);
274 		else
275 			dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_S), str);
276 
277 		dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_START), ndx, NAME(dlmp));
278 	} else
279 		dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_IN), ndx, NAME(dlmp),
280 		    NAME(clmp), conv_bnd_type(flags));
281 
282 	ectoggle = 1;
283 }
284 
285 void
286 Dbg_util_edge_out(Rt_map *clmp, Rt_map *dlmp)
287 {
288 	if (DBG_NOTCLASS(DBG_C_INIT))
289 		return;
290 	if (DBG_NOTDETAIL())
291 		return;
292 
293 	dbg_print(LIST(clmp), MSG_INTL(MSG_UTL_EDGE_OUT), SORTVAL(clmp),
294 	    NAME(clmp), NAME(dlmp));
295 }
296 
297 void
298 Dbg_util_collect(Rt_map *lmp, int ndx, int flag)
299 {
300 	Lm_list		*lml = LIST(lmp);
301 	const char	*str;
302 
303 	if (DBG_NOTCLASS(DBG_C_INIT))
304 		return;
305 	if (DBG_NOTDETAIL())
306 		return;
307 
308 	if (flag & RT_SORT_REV)
309 		str = MSG_ORIG(MSG_SCN_INIT);
310 	else
311 		str = MSG_ORIG(MSG_SCN_FINI);
312 
313 	if (ectoggle == 1) {
314 		Dbg_util_nl(lml, DBG_NL_STD);
315 		ectoggle = 0;
316 	}
317 	dbg_print(lml, MSG_INTL(MSG_UTL_COLLECT), ndx, NAME(lmp), str);
318 }
319 
320 static const Msg	tags[] = {
321 	MSG_CI_NULL,		/* MSG_ORIG(MSG_CI_NULL) */
322 	MSG_CI_VERSION,		/* MSG_ORIG(MSG_CI_VERSION) */
323 	MSG_CI_ATEXIT,		/* MSG_ORIG(MSG_CI_ATEXIT) */
324 	MSG_CI_LCMESSAGES,	/* MSG_ORIG(MSG_CI_LCMESSAGES) */
325 	MSG_CI_BIND_GUARD,	/* MSG_ORIG(MSG_CI_BIND_GUARD) */
326 	MSG_CI_BIND_CLEAR,	/* MSG_ORIG(MSG_CI_BIND_CLEAR) */
327 	MSG_CI_THR_SELF,	/* MSG_ORIG(MSG_CI_THR_SELF) */
328 	MSG_CI_TLS_MODADD,	/* MSG_ORIG(MSG_CI_TLS_MODADD) */
329 	MSG_CI_TLS_MODREM,	/* MSG_ORIG(MSG_CI_TLS_MODREM) */
330 	MSG_CI_TLS_STATMOD,	/* MSG_ORIG(MSG_CI_TLS_STATMOD) */
331 	MSG_CI_THRINIT		/* MSG_ORIG(MSG_CI_THRINIT) */
332 };
333 
334 void
335 Dbg_util_lcinterface(Rt_map *lmp, int tag, char *val)
336 {
337 	const char		*str;
338 	static Conv_inv_buf_t	string;
339 
340 	if (DBG_NOTDETAIL())
341 		return;
342 
343 	if (tag < CI_MAX)
344 		str = MSG_ORIG(tags[tag]);
345 	else
346 		str = conv_invalid_val(string, CONV_INV_STRSIZE, tag, 0);
347 
348 	dbg_print(LIST(lmp), MSG_INTL(MSG_UTL_LCINTERFACE), NAME(lmp), str,
349 	    EC_NATPTR(val));
350 }
351 
352 void
353 Dbg_unused_lcinterface(Rt_map *nlmp, Rt_map *olmp, int tag)
354 {
355 	const char		*str;
356 	static Conv_inv_buf_t	string;
357 
358 	if (DBG_NOTCLASS(DBG_C_UNUSED))
359 		return;
360 
361 	if (tag < CI_MAX)
362 		str = MSG_ORIG(tags[tag]);
363 	else
364 		str = conv_invalid_val(string, CONV_INV_STRSIZE, tag, 0);
365 
366 	dbg_print(LIST(nlmp), MSG_INTL(MSG_USD_LCINTERFACE), NAME(nlmp), str,
367 	    NAME(olmp));
368 }
369 
370 /*
371  * Generic new line generator.  To prevent multiple newlines from being
372  * generated, a flag is maintained in the global debug descriptor.  This flag
373  * is cleared by the callers dbg_print() function to indicate that a newline
374  * (actually, any line) has been printed.  Multiple newlines can be generated
375  * using the DBG_NL_FRC flag.
376  */
377 void
378 Dbg_util_nl(Lm_list *lml, int flag)
379 {
380 	if ((flag == DBG_NL_STD) && (dbg_desc->d_extra & DBG_E_STDNL))
381 		return;
382 
383 	dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY));
384 
385 	if (flag == DBG_NL_STD)
386 		dbg_desc->d_extra |= DBG_E_STDNL;
387 }
388 
389 /*
390  * Define name demanglers.
391  */
392 const char *
393 Dbg_demangle_name(const char *name)
394 {
395 	if (DBG_NOTCLASS(DBG_C_DEMANGLE))
396 		return (name);
397 
398 	return (conv_demangle_name(name));
399 }
400 
401 const char *
402 Elf_demangle_name(const char *name)
403 {
404 	if (DBG_ISDEMANGLE())
405 		return (conv_demangle_name(name));
406 	return (name);
407 }
408