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