syms.c revision 4734:a4708faa3e85
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	<stdio.h>
29#include	<dlfcn.h>
30#include	"msg.h"
31#include	"_debug.h"
32#include	"libld.h"
33
34#if	!(defined(_ELF64))
35
36void
37Dbg_syms_lookup_aout(Lm_list *lml, const char *name)
38{
39	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
40		return;
41
42	dbg_print(lml, MSG_INTL(MSG_SYM_AOUT), Dbg_demangle_name(name));
43}
44
45#endif
46
47void
48Dbg_syms_lookup(Rt_map *lmp, const char *name, const char *type)
49{
50	Lm_list	*lml = LIST(lmp);
51
52	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
53		return;
54
55	dbg_print(lml, MSG_INTL(MSG_SYM_LOOKUP), Dbg_demangle_name(name),
56	    NAME(lmp), type);
57}
58
59void
60Dbg_syms_ignore_gnuver(Rt_map *lmp, const char *name, Word symndx,
61    Versym verndx)
62{
63	Lm_list	*lml = LIST(lmp);
64
65	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
66		return;
67
68	dbg_print(lml, MSG_INTL(MSG_SYM_IGNGNUVER), Dbg_demangle_name(name),
69	    EC_WORD(symndx), EC_HALF(verndx), NAME(lmp));
70}
71
72void
73Dbg_syms_dlsym(Rt_map *clmp, const char *sym, const char *next, int flag)
74{
75	const char	*str, *from = NAME(clmp);
76	Lm_list		*lml = LIST(clmp);
77
78	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
79		return;
80
81	if (flag == DBG_DLSYM_NEXT)
82		str = MSG_ORIG(MSG_SYM_NEXT);
83	else if (flag == DBG_DLSYM_DEFAULT)
84		str = MSG_ORIG(MSG_SYM_DEFAULT);
85	else if (flag == DBG_DLSYM_SELF)
86		str = MSG_ORIG(MSG_SYM_SELF);
87	else if (flag == DBG_DLSYM_PROBE)
88		str = MSG_ORIG(MSG_SYM_PROBE);
89	else
90		str = MSG_ORIG(MSG_STR_EMPTY);
91
92	Dbg_util_nl(lml, DBG_NL_STD);
93	if (next == 0)
94		dbg_print(lml, MSG_INTL(MSG_SYM_DLSYM_1),
95		    Dbg_demangle_name(sym), from, str);
96	else
97		dbg_print(lml, MSG_INTL(MSG_SYM_DLSYM_2),
98		    Dbg_demangle_name(sym), from, next, str);
99}
100
101void
102Dbg_syms_lazy_rescan(Lm_list *lml, const char *name)
103{
104	if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_FILES))
105		return;
106
107	Dbg_util_nl(lml, DBG_NL_STD);
108	dbg_print(lml, MSG_INTL(MSG_SYM_LAZY_RESCAN), Dbg_demangle_name(name));
109}
110
111void
112Dbg_syms_ar_title(Lm_list *lml, const char *file, int again)
113{
114	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
115		return;
116
117	Dbg_util_nl(lml, DBG_NL_STD);
118	dbg_print(lml, MSG_INTL(MSG_SYM_AR_FILE), file,
119	    again ? MSG_INTL(MSG_STR_AGAIN) : MSG_ORIG(MSG_STR_EMPTY));
120}
121
122void
123Dbg_syms_ar_entry(Lm_list *lml, Xword ndx, Elf_Arsym *arsym)
124{
125	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
126		return;
127
128	dbg_print(lml, MSG_INTL(MSG_SYM_AR_ENTRY), EC_XWORD(ndx),
129	    Dbg_demangle_name(arsym->as_name));
130}
131
132void
133Dbg_syms_ar_checking(Lm_list *lml, Xword ndx, Elf_Arsym *arsym,
134    const char *name)
135{
136	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
137		return;
138
139	dbg_print(lml, MSG_INTL(MSG_SYM_AR_CHECK), EC_XWORD(ndx),
140	    Dbg_demangle_name(arsym->as_name), name);
141}
142
143void
144Dbg_syms_ar_resolve(Lm_list *lml, Xword ndx, Elf_Arsym *arsym,
145    const char *fname, int flag)
146{
147	const char	*fmt;
148
149	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
150		return;
151
152	if (flag)
153		fmt = MSG_INTL(MSG_SYM_AR_FORCEDEXRT);
154	else
155		fmt = MSG_INTL(MSG_SYM_AR_RESOLVE);
156
157	dbg_print(lml, fmt, EC_XWORD(ndx), Dbg_demangle_name(arsym->as_name),
158	    fname);
159}
160
161void
162Dbg_syms_spec_title(Lm_list *lml)
163{
164	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
165		return;
166
167	Dbg_util_nl(lml, DBG_NL_STD);
168	dbg_print(lml, MSG_INTL(MSG_SYM_SPECIAL));
169}
170
171void
172Dbg_syms_discarded(Lm_list *lml, Sym_desc *sdp, Is_desc *disp)
173{
174	const char	*sectname;
175
176	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
177		return;
178	if (DBG_NOTDETAIL())
179		return;
180
181	if ((sectname = disp->is_basename) == 0)
182		sectname = disp->is_name;
183
184	dbg_print(lml, MSG_INTL(MSG_SYM_DISCARDED),
185	    Dbg_demangle_name(sdp->sd_name), sectname, disp->is_file->ifl_name);
186}
187
188void
189Dbg_syms_entered(Ofl_desc *ofl, Sym *sym, Sym_desc *sdp)
190{
191	Conv_inv_buf_t	inv_buf;
192	Lm_list		*lml = ofl->ofl_lml;
193
194	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
195		return;
196	if (DBG_NOTDETAIL())
197		return;
198
199	Elf_syms_table_entry(lml, ELF_DBG_LD, MSG_INTL(MSG_STR_ENTERED),
200	    ofl->ofl_dehdr->e_machine, sym,
201	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL,
202	    conv_def_tag(sdp->sd_ref, &inv_buf));
203}
204
205void
206Dbg_syms_process(Lm_list *lml, Ifl_desc *ifl)
207{
208	Conv_inv_buf_t	inv_buf;
209
210	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
211		return;
212
213	Dbg_util_nl(lml, DBG_NL_STD);
214	dbg_print(lml, MSG_INTL(MSG_SYM_PROCESS), ifl->ifl_name,
215	    conv_ehdr_type(ifl->ifl_ehdr->e_type, 0, &inv_buf));
216}
217
218void
219Dbg_syms_entry(Lm_list *lml, Word ndx, Sym_desc *sdp)
220{
221	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
222		return;
223
224	dbg_print(lml, MSG_INTL(MSG_SYM_BASIC), EC_WORD(ndx),
225	    Dbg_demangle_name(sdp->sd_name));
226}
227
228void
229Dbg_syms_global(Lm_list *lml, Word ndx, const char *name)
230{
231	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
232		return;
233
234	dbg_print(lml, MSG_INTL(MSG_SYM_ADDING), EC_WORD(ndx),
235	    Dbg_demangle_name(name));
236}
237
238void
239Dbg_syms_sec_title(Lm_list *lml)
240{
241	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
242		return;
243	if (DBG_NOTDETAIL())
244		return;
245
246	Dbg_util_nl(lml, DBG_NL_STD);
247	dbg_print(lml, MSG_INTL(MSG_SYM_INDEX));
248}
249
250void
251Dbg_syms_sec_entry(Lm_list *lml, Word ndx, Sg_desc *sgp, Os_desc *osp)
252{
253	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
254		return;
255	if (DBG_NOTDETAIL())
256		return;
257
258	dbg_print(lml, MSG_INTL(MSG_SYM_SECTION), EC_WORD(ndx), osp->os_name,
259	    (*sgp->sg_name ? sgp->sg_name : MSG_INTL(MSG_STR_NULL)));
260}
261
262void
263Dbg_syms_up_title(Lm_list *lml)
264{
265	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
266		return;
267	if (DBG_NOTDETAIL())
268		return;
269
270	Dbg_util_nl(lml, DBG_NL_STD);
271	dbg_print(lml, MSG_INTL(MSG_SYM_FINAL));
272	Elf_syms_table_title(lml, ELF_DBG_LD);
273}
274
275void
276Dbg_syms_ignore(Ofl_desc *ofl, Sym_desc *sdp)
277{
278	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
279		return;
280	if (DBG_NOTDETAIL())
281		return;
282
283	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_IGNORE),
284	    ofl->ofl_dehdr->e_machine, sdp->sd_sym, 0, 0, NULL,
285	    MSG_INTL(MSG_STR_UNUSED));
286}
287
288void
289Dbg_syms_old(Ofl_desc *ofl, Sym_desc *sdp)
290{
291	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
292		return;
293	if (DBG_NOTDETAIL())
294		return;
295
296	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_OLD),
297	    ofl->ofl_dehdr->e_machine, sdp->sd_sym,
298	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL, sdp->sd_name);
299}
300
301void
302Dbg_syms_new(Ofl_desc *ofl, Sym *sym, Sym_desc *sdp)
303{
304	Conv_inv_buf_t	inv_buf;
305
306	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
307		return;
308	if (DBG_NOTDETAIL())
309		return;
310
311	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_NEW),
312	    ofl->ofl_dehdr->e_machine, sym,
313	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL,
314	    conv_def_tag(sdp->sd_ref, &inv_buf));
315}
316
317void
318Dbg_syms_updated(Ofl_desc *ofl, Sym_desc *sdp, const char *name)
319{
320	Conv_inv_buf_t	inv_buf;
321	Lm_list		*lml = ofl->ofl_lml;
322
323	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
324		return;
325
326	dbg_print(lml, MSG_INTL(MSG_SYM_UPDATE), name);
327
328	if (DBG_NOTDETAIL())
329		return;
330
331	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_ORIG(MSG_STR_EMPTY),
332	    ofl->ofl_dehdr->e_machine, sdp->sd_sym,
333	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL,
334	    conv_def_tag(sdp->sd_ref, &inv_buf));
335}
336
337void
338Dbg_syms_created(Lm_list *lml, const char *name)
339{
340	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
341		return;
342
343	dbg_print(lml, MSG_INTL(MSG_SYM_CREATE), Dbg_demangle_name(name));
344}
345
346void
347Dbg_syms_resolving(Ofl_desc *ofl, Word ndx, const char *name, int row,
348    int col, Sym *osym, Sym *nsym, Sym_desc *sdp, Ifl_desc *ifl)
349{
350	Lm_list	*lml = ofl->ofl_lml;
351	Half	mach = ofl->ofl_dehdr->e_machine;
352
353	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
354		return;
355
356	dbg_print(lml, MSG_INTL(MSG_SYM_RESOLVING), EC_WORD(ndx),
357	    Dbg_demangle_name(name), row, col);
358
359	if (DBG_NOTDETAIL())
360		return;
361
362	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_OLD),
363	    mach, osym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL,
364	    sdp->sd_file->ifl_name);
365
366	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_NEW),
367	    mach, nsym, 0, 0, NULL, ifl->ifl_name);
368}
369
370void
371Dbg_syms_resolved(Ofl_desc *ofl, Sym_desc *sdp)
372{
373	Conv_inv_buf_t	inv_buf;
374
375	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
376		return;
377	if (DBG_NOTDETAIL())
378		return;
379
380	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD,
381	    MSG_INTL(MSG_STR_RESOLVED), ofl->ofl_dehdr->e_machine, sdp->sd_sym,
382	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL,
383	    conv_def_tag(sdp->sd_ref, &inv_buf));
384}
385
386void
387Dbg_syms_reloc(Ofl_desc *ofl, Sym_desc *sdp)
388{
389	static Boolean	symbol_title = TRUE;
390	Conv_inv_buf_t	inv_buf;
391	Lm_list	*lml = ofl->ofl_lml;
392
393	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
394		return;
395
396	if (symbol_title) {
397		Dbg_util_nl(lml, DBG_NL_STD);
398		dbg_print(lml, MSG_INTL(MSG_SYM_BSS));
399
400		symbol_title = FALSE;
401	}
402	dbg_print(lml, MSG_INTL(MSG_SYM_UPDATE),
403	    Dbg_demangle_name(sdp->sd_name));
404
405	if (DBG_NOTDETAIL())
406		return;
407
408	Elf_syms_table_entry(lml, ELF_DBG_LD, MSG_ORIG(MSG_SYM_COPY),
409	    ofl->ofl_dehdr->e_machine, sdp->sd_sym,
410	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL,
411	    conv_def_tag(sdp->sd_ref, &inv_buf));
412}
413
414void
415Dbg_syms_reduce(Ofl_desc *ofl, int which, Sym_desc *sdp, int idx,
416    const char *sname)
417{
418	static Boolean	sym_reduce_title = TRUE;
419	static Boolean	sym_retain_title = TRUE;
420	Boolean		isfromglobal = (which == DBG_SYM_REDUCE_GLOBAL);
421	Boolean		isfromretain = (which == DBG_SYM_REDUCE_RETAIN);
422	Lm_list		*lml = ofl->ofl_lml;
423
424	if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_VERSIONS))
425		return;
426
427	if (sym_reduce_title && isfromglobal) {
428		sym_reduce_title = FALSE;
429		Dbg_util_nl(lml, DBG_NL_STD);
430		dbg_print(lml, MSG_INTL(MSG_SYM_REDUCED));
431	} else if (sym_retain_title && isfromretain) {
432		sym_retain_title = FALSE;
433		Dbg_util_nl(lml, DBG_NL_STD);
434		dbg_print(lml, MSG_INTL(MSG_SYM_RETAINING));
435	}
436
437	if ((sdp->sd_flags1 & FLG_SY1_ELIM) && isfromglobal)
438		dbg_print(lml, MSG_INTL(MSG_SYM_ELIMINATING),
439		    Dbg_demangle_name(sdp->sd_name));
440	else if (isfromglobal)
441		dbg_print(lml, MSG_INTL(MSG_SYM_REDUCING),
442		    Dbg_demangle_name(sdp->sd_name));
443	else
444		dbg_print(lml, MSG_INTL(MSG_SYM_NOTELIMINATE),
445		    Dbg_demangle_name(sdp->sd_name), sname, idx);
446
447	if (DBG_NOTDETAIL())
448		return;
449
450	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_ORIG(MSG_SYM_LOCAL),
451	    ofl->ofl_dehdr->e_machine, sdp->sd_sym,
452	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, 0, NULL,
453	    sdp->sd_file->ifl_name);
454}
455
456void
457Dbg_syms_dup_sort_addr(Lm_list *lml, const char *secname, const char *symname1,
458    const char *symname2, Addr addr)
459{
460	if (DBG_NOTCLASS(DBG_C_SYMBOLS) || DBG_NOTDETAIL())
461		return;
462
463	dbg_print(lml, MSG_INTL(MSG_SYM_DUPSORTADDR), secname,
464	    symname1, symname2, EC_ADDR(addr));
465}
466
467void
468Dbg_syminfo_title(Lm_list *lml)
469{
470	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
471		return;
472	if (DBG_NOTDETAIL())
473		return;
474
475	Dbg_util_nl(lml, DBG_NL_STD);
476	dbg_print(lml, MSG_INTL(MSG_SYMINFO_INFO));
477	Elf_syminfo_title(lml);
478}
479
480void
481Dbg_syminfo_entry(Lm_list *lml, Word ndx, Syminfo *sip, Sym *sym,
482    const char *strtab, Dyn *dyn)
483{
484	const char	*needed;
485
486	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
487		return;
488	if (DBG_NOTDETAIL())
489		return;
490
491	if (sip->si_boundto < SYMINFO_BT_LOWRESERVE)
492		needed = strtab + dyn[sip->si_boundto].d_un.d_val;
493	else
494		needed = 0;
495
496	Elf_syminfo_entry(lml, ndx, sip,
497	    Dbg_demangle_name(strtab + sym->st_name), needed);
498}
499
500/*
501 * Symbol table output can differ slightly depending on the caller.  However,
502 * the final diagnostic is maintained here so hat the various message strings
503 * remain consistent
504 *
505 * elfdump:   index    value       size     type bind oth ver shndx       name
506 * ld:                 value       size     type bind oth ver shndx
507 */
508void
509Elf_syms_table_title(Lm_list *lml, int caller)
510{
511	if (caller == ELF_DBG_ELFDUMP) {
512		if (DBG_NOTLONG())
513			dbg_print(lml, MSG_INTL(MSG_SYM_EFS_TITLE));
514		else
515			dbg_print(lml, MSG_INTL(MSG_SYM_EFL_TITLE));
516		return;
517	}
518
519	if (caller == ELF_DBG_LD) {
520		if (DBG_NOTLONG())
521			dbg_print(lml, MSG_INTL(MSG_SYM_LDS_TITLE));
522		else
523			dbg_print(lml, MSG_INTL(MSG_SYM_LDL_TITLE));
524		return;
525	}
526}
527
528void
529Elf_syms_table_entry(Lm_list *lml, int caller, const char *prestr, Half mach,
530    Sym *sym, Versym verndx, int gnuver, const char *sec, const char *poststr)
531{
532	Conv_inv_buf_t	inv_buf1, inv_buf2, inv_buf3;
533	Conv_inv_buf_t	inv_buf4, inv_buf5, inv_buf6;
534	uchar_t		type = ELF_ST_TYPE(sym->st_info);
535	uchar_t		bind = ELF_ST_BIND(sym->st_info);
536	const char	*msg;
537
538	if ((caller == ELF_DBG_ELFDUMP) ||
539	    (caller == ELF_DBG_LD)) {
540		if (DBG_NOTLONG())
541			msg = MSG_INTL(MSG_SYM_EFS_ENTRY);
542		else
543			msg = MSG_INTL(MSG_SYM_EFL_ENTRY);
544
545		dbg_print(lml, msg, prestr,
546		    conv_sym_value(mach, type, sym->st_value, &inv_buf1),
547		    sym->st_size, conv_sym_info_type(mach, type, 0, &inv_buf2),
548		    conv_sym_info_bind(bind, 0, &inv_buf3),
549		    conv_sym_other(sym->st_other, &inv_buf4),
550		    conv_ver_index(verndx, gnuver, &inv_buf5),
551		    sec ? sec : conv_sym_shndx(sym->st_shndx, &inv_buf6),
552		    Elf_demangle_name(poststr));
553	}
554}
555