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