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