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