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