xref: /illumos-gate/usr/src/cmd/sgs/liblddbg/common/syms.c (revision f48068addb8865f9338d23ffbe1043e369df37a1)
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 
36 void
37 Dbg_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 
47 void
48 Dbg_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 
59 void
60 Dbg_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 
72 void
73 Dbg_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 
101 void
102 Dbg_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 
111 void
112 Dbg_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 
122 void
123 Dbg_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 
132 void
133 Dbg_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 
143 void
144 Dbg_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 
161 void
162 Dbg_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 
171 void
172 Dbg_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 
188 void
189 Dbg_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 
205 void
206 Dbg_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 
218 void
219 Dbg_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 
228 void
229 Dbg_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 
238 void
239 Dbg_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 
250 void
251 Dbg_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 
262 void
263 Dbg_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 
275 void
276 Dbg_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 
288 void
289 Dbg_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 
301 void
302 Dbg_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 
317 void
318 Dbg_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 
337 void
338 Dbg_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 
346 void
347 Dbg_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 
370 void
371 Dbg_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 
386 void
387 Dbg_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 
414 void
415 Dbg_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 
456 void
457 Dbg_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 
467 void
468 Dbg_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 
480 void
481 Dbg_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  */
508 void
509 Elf_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 
528 void
529 Elf_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