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