xref: /illumos-gate/usr/src/cmd/sgs/liblddbg/common/syms.c (revision 24da5b34f49324ed742a340010ed5bd3d4e06625)
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_badver(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_IGNBADVER), 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 	Lm_list	*lml = ofl->ofl_lml;
192 
193 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
194 		return;
195 	if (DBG_NOTDETAIL())
196 		return;
197 
198 	Elf_syms_table_entry(lml, ELF_DBG_LD, MSG_INTL(MSG_STR_ENTERED),
199 	    ofl->ofl_dehdr->e_machine, sym,
200 	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL,
201 	    conv_def_tag(sdp->sd_ref));
202 }
203 
204 void
205 Dbg_syms_process(Lm_list *lml, Ifl_desc *ifl)
206 {
207 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
208 		return;
209 
210 	Dbg_util_nl(lml, DBG_NL_STD);
211 	dbg_print(lml, MSG_INTL(MSG_SYM_PROCESS), ifl->ifl_name,
212 	    conv_ehdr_type(ifl->ifl_ehdr->e_type, 0));
213 }
214 
215 void
216 Dbg_syms_entry(Lm_list *lml, Word ndx, Sym_desc *sdp)
217 {
218 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
219 		return;
220 
221 	dbg_print(lml, MSG_INTL(MSG_SYM_BASIC), EC_WORD(ndx),
222 	    Dbg_demangle_name(sdp->sd_name));
223 }
224 
225 void
226 Dbg_syms_global(Lm_list *lml, Word ndx, const char *name)
227 {
228 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
229 		return;
230 
231 	dbg_print(lml, MSG_INTL(MSG_SYM_ADDING), EC_WORD(ndx),
232 	    Dbg_demangle_name(name));
233 }
234 
235 void
236 Dbg_syms_sec_title(Lm_list *lml)
237 {
238 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
239 		return;
240 	if (DBG_NOTDETAIL())
241 		return;
242 
243 	Dbg_util_nl(lml, DBG_NL_STD);
244 	dbg_print(lml, MSG_INTL(MSG_SYM_INDEX));
245 }
246 
247 void
248 Dbg_syms_sec_entry(Lm_list *lml, Word ndx, Sg_desc *sgp, Os_desc *osp)
249 {
250 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
251 		return;
252 	if (DBG_NOTDETAIL())
253 		return;
254 
255 	dbg_print(lml, MSG_INTL(MSG_SYM_SECTION), EC_WORD(ndx), osp->os_name,
256 	    (*sgp->sg_name ? sgp->sg_name : MSG_INTL(MSG_STR_NULL)));
257 }
258 
259 void
260 Dbg_syms_up_title(Lm_list *lml)
261 {
262 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
263 		return;
264 	if (DBG_NOTDETAIL())
265 		return;
266 
267 	Dbg_util_nl(lml, DBG_NL_STD);
268 	dbg_print(lml, MSG_INTL(MSG_SYM_FINAL));
269 	Elf_syms_table_title(lml, ELF_DBG_LD);
270 }
271 
272 void
273 Dbg_syms_ignore(Ofl_desc *ofl, Sym_desc *sdp)
274 {
275 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
276 		return;
277 	if (DBG_NOTDETAIL())
278 		return;
279 
280 	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_IGNORE),
281 	    ofl->ofl_dehdr->e_machine, sdp->sd_sym, 0, NULL,
282 	    MSG_INTL(MSG_STR_UNUSED));
283 }
284 
285 void
286 Dbg_syms_old(Ofl_desc *ofl, Sym_desc *sdp)
287 {
288 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
289 		return;
290 	if (DBG_NOTDETAIL())
291 		return;
292 
293 	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_OLD),
294 	    ofl->ofl_dehdr->e_machine, sdp->sd_sym,
295 	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL, sdp->sd_name);
296 }
297 
298 void
299 Dbg_syms_new(Ofl_desc *ofl, Sym *sym, Sym_desc *sdp)
300 {
301 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
302 		return;
303 	if (DBG_NOTDETAIL())
304 		return;
305 
306 	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_NEW),
307 	    ofl->ofl_dehdr->e_machine, sym,
308 	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL,
309 	    conv_def_tag(sdp->sd_ref));
310 }
311 
312 void
313 Dbg_syms_updated(Ofl_desc *ofl, Sym_desc *sdp, const char *name)
314 {
315 	Lm_list	*lml = ofl->ofl_lml;
316 
317 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
318 		return;
319 
320 	dbg_print(lml, MSG_INTL(MSG_SYM_UPDATE), name);
321 
322 	if (DBG_NOTDETAIL())
323 		return;
324 
325 	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_ORIG(MSG_STR_EMPTY),
326 	    ofl->ofl_dehdr->e_machine, sdp->sd_sym,
327 	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL,
328 	    conv_def_tag(sdp->sd_ref));
329 }
330 
331 void
332 Dbg_syms_created(Lm_list *lml, const char *name)
333 {
334 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
335 		return;
336 
337 	dbg_print(lml, MSG_INTL(MSG_SYM_CREATE), Dbg_demangle_name(name));
338 }
339 
340 void
341 Dbg_syms_resolving(Ofl_desc *ofl, Word ndx, const char *name, int row,
342     int col, Sym *osym, Sym *nsym, Sym_desc *sdp, Ifl_desc *ifl)
343 {
344 	Lm_list	*lml = ofl->ofl_lml;
345 	Half	mach = ofl->ofl_dehdr->e_machine;
346 
347 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
348 		return;
349 
350 	dbg_print(lml, MSG_INTL(MSG_SYM_RESOLVING), EC_WORD(ndx),
351 	    Dbg_demangle_name(name), row, col);
352 
353 	if (DBG_NOTDETAIL())
354 		return;
355 
356 	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_OLD),
357 	    mach, osym, sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL,
358 	    sdp->sd_file->ifl_name);
359 
360 	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_INTL(MSG_STR_NEW),
361 	    mach, nsym, 0, NULL, ifl->ifl_name);
362 }
363 
364 void
365 Dbg_syms_resolved(Ofl_desc *ofl, Sym_desc *sdp)
366 {
367 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
368 		return;
369 	if (DBG_NOTDETAIL())
370 		return;
371 
372 	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD,
373 	    MSG_INTL(MSG_STR_RESOLVED), ofl->ofl_dehdr->e_machine, sdp->sd_sym,
374 	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL,
375 	    conv_def_tag(sdp->sd_ref));
376 }
377 
378 void
379 Dbg_syms_reloc(Ofl_desc *ofl, Sym_desc *sdp)
380 {
381 	static Boolean	symbol_title = TRUE;
382 	Lm_list	*lml = ofl->ofl_lml;
383 
384 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
385 		return;
386 
387 	if (symbol_title) {
388 		Dbg_util_nl(lml, DBG_NL_STD);
389 		dbg_print(lml, MSG_INTL(MSG_SYM_BSS));
390 
391 		symbol_title = FALSE;
392 	}
393 	dbg_print(lml, MSG_INTL(MSG_SYM_UPDATE),
394 	    Dbg_demangle_name(sdp->sd_name));
395 
396 	if (DBG_NOTDETAIL())
397 		return;
398 
399 	Elf_syms_table_entry(lml, ELF_DBG_LD, MSG_ORIG(MSG_SYM_COPY),
400 	    ofl->ofl_dehdr->e_machine, sdp->sd_sym,
401 	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL,
402 	    conv_def_tag(sdp->sd_ref));
403 }
404 
405 void
406 Dbg_syms_reduce(Ofl_desc *ofl, int which, Sym_desc *sdp, int idx,
407     const char *sname)
408 {
409 	static Boolean	sym_reduce_title = TRUE;
410 	static Boolean	sym_retain_title = TRUE;
411 	Boolean		isfromglobal = (which == DBG_SYM_REDUCE_GLOBAL);
412 	Boolean		isfromretain = (which == DBG_SYM_REDUCE_RETAIN);
413 	Lm_list		*lml = ofl->ofl_lml;
414 
415 	if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_VERSIONS))
416 		return;
417 
418 	if (sym_reduce_title && isfromglobal) {
419 		sym_reduce_title = FALSE;
420 		Dbg_util_nl(lml, DBG_NL_STD);
421 		dbg_print(lml, MSG_INTL(MSG_SYM_REDUCED));
422 	} else if (sym_retain_title && isfromretain) {
423 		sym_retain_title = FALSE;
424 		Dbg_util_nl(lml, DBG_NL_STD);
425 		dbg_print(lml, MSG_INTL(MSG_SYM_RETAINING));
426 	}
427 
428 	if ((sdp->sd_flags1 & FLG_SY1_ELIM) && isfromglobal)
429 		dbg_print(lml, MSG_INTL(MSG_SYM_ELIMINATING),
430 		    Dbg_demangle_name(sdp->sd_name));
431 	else if (isfromglobal)
432 		dbg_print(lml, MSG_INTL(MSG_SYM_REDUCING),
433 		    Dbg_demangle_name(sdp->sd_name));
434 	else
435 		dbg_print(lml, MSG_INTL(MSG_SYM_NOTELIMINATE),
436 		    Dbg_demangle_name(sdp->sd_name), sname, idx);
437 
438 	if (DBG_NOTDETAIL())
439 		return;
440 
441 	Elf_syms_table_entry(ofl->ofl_lml, ELF_DBG_LD, MSG_ORIG(MSG_SYM_LOCAL),
442 	    ofl->ofl_dehdr->e_machine, sdp->sd_sym,
443 	    sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL,
444 	    sdp->sd_file->ifl_name);
445 }
446 
447 void
448 Dbg_syms_dup_sort_addr(Lm_list *lml, const char *secname, const char *symname1,
449     const char *symname2, Addr addr)
450 {
451 	if (DBG_NOTCLASS(DBG_C_SYMBOLS) || DBG_NOTDETAIL())
452 		return;
453 
454 	dbg_print(lml, MSG_INTL(MSG_SYM_DUPSORTADDR), secname,
455 	    symname1, symname2, EC_ADDR(addr));
456 }
457 
458 void
459 Dbg_syminfo_title(Lm_list *lml)
460 {
461 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
462 		return;
463 	if (DBG_NOTDETAIL())
464 		return;
465 
466 	Dbg_util_nl(lml, DBG_NL_STD);
467 	dbg_print(lml, MSG_INTL(MSG_SYMINFO_INFO));
468 	Elf_syminfo_title(lml);
469 }
470 
471 void
472 Dbg_syminfo_entry(Lm_list *lml, Word ndx, Syminfo *sip, Sym *sym,
473     const char *strtab, Dyn *dyn)
474 {
475 	const char	*needed;
476 
477 	if (DBG_NOTCLASS(DBG_C_SYMBOLS))
478 		return;
479 	if (DBG_NOTDETAIL())
480 		return;
481 
482 	if (sip->si_boundto < SYMINFO_BT_LOWRESERVE)
483 		needed = strtab + dyn[sip->si_boundto].d_un.d_val;
484 	else
485 		needed = 0;
486 
487 	Elf_syminfo_entry(lml, ndx, sip,
488 	    Dbg_demangle_name(strtab + sym->st_name), needed);
489 }
490 
491 /*
492  * Symbol table output can differ slightly depending on the caller.  However,
493  * the final diagnostic is maintained here so hat the various message strings
494  * remain consistent
495  *
496  * elfdump:   index    value       size     type bind oth ver shndx       name
497  * ld:                 value       size     type bind oth ver shndx
498  */
499 void
500 Elf_syms_table_title(Lm_list *lml, int caller)
501 {
502 	if (caller == ELF_DBG_ELFDUMP) {
503 		if (DBG_NOTLONG())
504 			dbg_print(lml, MSG_INTL(MSG_SYM_EFS_TITLE));
505 		else
506 			dbg_print(lml, MSG_INTL(MSG_SYM_EFL_TITLE));
507 		return;
508 	}
509 
510 	if (caller == ELF_DBG_LD) {
511 		if (DBG_NOTLONG())
512 			dbg_print(lml, MSG_INTL(MSG_SYM_LDS_TITLE));
513 		else
514 			dbg_print(lml, MSG_INTL(MSG_SYM_LDL_TITLE));
515 		return;
516 	}
517 }
518 
519 void
520 Elf_syms_table_entry(Lm_list *lml, int caller, const char *prestr, Half mach,
521     Sym *sym, Versym verndx, const char *sec, const char *poststr)
522 {
523 	uchar_t		type = ELF_ST_TYPE(sym->st_info);
524 	uchar_t		bind = ELF_ST_BIND(sym->st_info);
525 	const char	*msg;
526 
527 	if ((caller == ELF_DBG_ELFDUMP) ||
528 	    (caller == ELF_DBG_LD)) {
529 		if (DBG_NOTLONG())
530 			msg = MSG_INTL(MSG_SYM_EFS_ENTRY);
531 		else
532 			msg = MSG_INTL(MSG_SYM_EFL_ENTRY);
533 
534 		dbg_print(lml, msg, prestr,
535 		    conv_sym_value(mach, type, sym->st_value), sym->st_size,
536 		    conv_sym_info_type(mach, type, 0),
537 		    conv_sym_info_bind(bind, 0), conv_sym_other(sym->st_other),
538 		    conv_ver_index(verndx),
539 		    sec ? sec : conv_sym_shndx(sym->st_shndx),
540 		    Elf_demangle_name(poststr));
541 	}
542 }
543