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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 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 <strings.h> 31 #include "msg.h" 32 #include "_debug.h" 33 #include "libld.h" 34 35 /* 36 * Print out a single `symbol table node' entry. 37 */ 38 #if !defined(_ELF64) 39 void 40 Gelf_sym_table_title(GElf_Ehdr *ehdr, const char *index, const char *name) 41 { 42 if ((int)ehdr->e_ident[EI_CLASS] == ELFCLASS64) { 43 if (DBG_NOTLONG()) 44 dbg_print(MSG_ORIG(MSG_SYM_TITLE_64), index, name); 45 else 46 dbg_print(MSG_ORIG(MSG_SYM_L_TITLE_64), index, name); 47 } else { 48 if (DBG_NOTLONG()) 49 dbg_print(MSG_ORIG(MSG_SYM_TITLE), index, name); 50 else 51 dbg_print(MSG_ORIG(MSG_SYM_L_TITLE), index, name); 52 } 53 } 54 void 55 Elf_sym_table_entry(const char *prestr, Elf32_Ehdr *ehdr, Elf32_Sym *sym, 56 Elf32_Word verndx, const char *sec, const char *poststr) 57 { 58 const char *msg; 59 60 if (DBG_NOTLONG()) 61 msg = MSG_ORIG(MSG_SYM_ENTRY); 62 else 63 msg = MSG_ORIG(MSG_SYM_L_ENTRY); 64 65 dbg_print(msg, prestr, 66 conv_sym_value_str(ehdr->e_machine, ELF32_ST_TYPE(sym->st_info), 67 EC_XWORD(sym->st_value)), EC_XWORD(sym->st_size), 68 conv_info_type_str(ehdr->e_machine, ELF32_ST_TYPE(sym->st_info)), 69 conv_info_bind_str(ELF32_ST_BIND(sym->st_info)), 70 conv_sym_stother(sym->st_other), EC_WORD(verndx), 71 sec ? sec : conv_shndx_str(sym->st_shndx), 72 _Dbg_sym_dem(poststr)); 73 } 74 75 void 76 Gelf_sym_table_entry(const char *prestr, GElf_Ehdr *ehdr, GElf_Sym *sym, 77 GElf_Word verndx, const char *sec, const char *poststr) 78 { 79 const char *msg; 80 81 if ((int)ehdr->e_ident[EI_CLASS] == ELFCLASS64) { 82 if (DBG_NOTLONG()) 83 msg = MSG_ORIG(MSG_SYM_ENTRY_64); 84 else 85 msg = MSG_ORIG(MSG_SYM_L_ENTRY_64); 86 } else { 87 if (DBG_NOTLONG()) 88 msg = MSG_ORIG(MSG_SYM_ENTRY); 89 else 90 msg = MSG_ORIG(MSG_SYM_L_ENTRY); 91 } 92 93 dbg_print(msg, prestr, conv_sym_value_str(ehdr->e_machine, 94 GELF_ST_TYPE(sym->st_info), EC_XWORD(sym->st_value)), 95 EC_XWORD(sym->st_size), 96 conv_info_type_str(ehdr->e_machine, GELF_ST_TYPE(sym->st_info)), 97 conv_info_bind_str(GELF_ST_BIND(sym->st_info)), 98 conv_sym_stother(sym->st_other), EC_WORD(verndx), 99 sec ? sec : conv_shndx_str(sym->st_shndx), 100 _Dbg_sym_dem(poststr)); 101 } 102 103 void 104 Gelf_syminfo_title() 105 { 106 dbg_print(MSG_INTL(MSG_SYMI_TITLE2)); 107 } 108 109 void 110 Gelf_syminfo_entry(int ndx, GElf_Syminfo *sip, const char *sname, 111 const char *needed) 112 { 113 const char *bind_str; 114 char flags[16], index[32], bind_index[32] = " "; 115 int flgndx = 0; 116 Half symflags; 117 118 symflags = sip->si_flags; 119 120 if (symflags & SYMINFO_FLG_DIRECT) { 121 if (sip->si_boundto == SYMINFO_BT_SELF) 122 bind_str = MSG_INTL(MSG_SYMI_SELF); 123 else if (sip->si_boundto == SYMINFO_BT_PARENT) 124 bind_str = MSG_INTL(MSG_SYMI_PARENT); 125 else { 126 bind_str = needed; 127 (void) sprintf(bind_index, MSG_ORIG(MSG_FMT_INDEX), 128 sip->si_boundto); 129 } 130 flags[flgndx++] = 'D'; 131 symflags &= ~SYMINFO_FLG_DIRECT; 132 133 } else if (symflags & (SYMINFO_FLG_FILTER | SYMINFO_FLG_AUXILIARY)) { 134 bind_str = needed; 135 (void) sprintf(bind_index, MSG_ORIG(MSG_FMT_INDEX), 136 sip->si_boundto); 137 138 if (symflags & SYMINFO_FLG_FILTER) { 139 flags[flgndx++] = 'F'; 140 symflags &= ~SYMINFO_FLG_FILTER; 141 } 142 if (symflags & SYMINFO_FLG_AUXILIARY) { 143 flags[flgndx++] = 'A'; 144 symflags &= ~SYMINFO_FLG_AUXILIARY; 145 } 146 } else if (sip->si_boundto == SYMINFO_BT_EXTERN) { 147 bind_str = MSG_INTL(MSG_SYMI_EXTERN); 148 } else 149 bind_str = MSG_ORIG(MSG_STR_EMPTY); 150 151 if (symflags & SYMINFO_FLG_DIRECTBIND) { 152 flags[flgndx++] = 'B'; 153 symflags &= ~SYMINFO_FLG_DIRECTBIND; 154 } 155 if (symflags & SYMINFO_FLG_COPY) { 156 flags[flgndx++] = 'C'; 157 symflags &= ~SYMINFO_FLG_COPY; 158 } 159 if (symflags & SYMINFO_FLG_LAZYLOAD) { 160 flags[flgndx++] = 'L'; 161 symflags &= ~SYMINFO_FLG_LAZYLOAD; 162 } 163 if (symflags & SYMINFO_FLG_NOEXTDIRECT) { 164 flags[flgndx++] = 'N'; 165 symflags &= ~SYMINFO_FLG_NOEXTDIRECT; 166 } 167 168 /* 169 * Did we account for all of the flags? 170 */ 171 if (symflags) 172 (void) sprintf(&flags[flgndx], " 0x%x", symflags); 173 else 174 flags[flgndx] = '\0'; 175 176 (void) sprintf(index, MSG_ORIG(MSG_FMT_INDEX), ndx); 177 dbg_print(MSG_ORIG(MSG_SYMI_FMT), index, flags, bind_index, bind_str, 178 _Dbg_sym_dem(sname)); 179 } 180 181 182 const char * 183 Gelf_sym_dem(const char *name) 184 { 185 return (conv_sym_dem(name)); 186 } 187 188 const char * 189 _Dbg_sym_dem(const char *name) 190 { 191 if (DBG_NOTCLASS(DBG_DEMANGLE)) 192 return (name); 193 194 return (conv_sym_dem(name)); 195 } 196 197 void 198 Dbg_syms_ar_title(const char *file, int again) 199 { 200 if (DBG_NOTCLASS(DBG_SYMBOLS)) 201 return; 202 203 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 204 dbg_print(MSG_INTL(MSG_SYM_AR_FILE), file, 205 again ? MSG_INTL(MSG_STR_AGAIN) : MSG_ORIG(MSG_STR_EMPTY)); 206 } 207 208 void 209 Dbg_syms_lazy_rescan(const char *name) 210 { 211 if (DBG_NOTCLASS(DBG_SYMBOLS | DBG_FILES)) 212 return; 213 214 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 215 dbg_print(MSG_INTL(MSG_SYM_LAZY_RESCAN), _Dbg_sym_dem(name)); 216 } 217 218 #endif /* !defined(_ELF64) */ 219 220 void 221 Dbg_syms_ar_entry(Xword ndx, Elf_Arsym *arsym) 222 { 223 if (DBG_NOTCLASS(DBG_SYMBOLS)) 224 return; 225 226 dbg_print(MSG_INTL(MSG_SYM_AR_ENTRY), EC_XWORD(ndx), 227 _Dbg_sym_dem(arsym->as_name)); 228 } 229 230 void 231 Dbg_syms_ar_checking(Xword ndx, Elf_Arsym *arsym, const char *name) 232 { 233 if (DBG_NOTCLASS(DBG_SYMBOLS)) 234 return; 235 236 dbg_print(MSG_INTL(MSG_SYM_AR_CHECK), EC_XWORD(ndx), 237 _Dbg_sym_dem(arsym->as_name), name); 238 } 239 240 void 241 Dbg_syms_ar_resolve(Xword ndx, Elf_Arsym *arsym, const char *fname, int flag) 242 { 243 const char *fmt; 244 245 if (DBG_NOTCLASS(DBG_SYMBOLS)) 246 return; 247 248 if (flag) 249 fmt = MSG_INTL(MSG_SYM_AR_FORCEDEXRT); 250 else 251 fmt = MSG_INTL(MSG_SYM_AR_RESOLVE); 252 253 dbg_print(fmt, EC_XWORD(ndx), _Dbg_sym_dem(arsym->as_name), fname); 254 } 255 256 void 257 Dbg_syms_spec_title() 258 { 259 if (DBG_NOTCLASS(DBG_SYMBOLS)) 260 return; 261 262 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 263 dbg_print(MSG_INTL(MSG_SYM_SPECIAL)); 264 } 265 266 void 267 Dbg_syms_discarded(Sym_desc *sdp, Is_desc *disp) 268 { 269 const char *sectname; 270 if (DBG_NOTCLASS(DBG_SYMBOLS)) 271 return; 272 if (DBG_NOTDETAIL()) 273 return; 274 275 if ((sectname = disp->is_basename) == 0) 276 sectname = disp->is_name; 277 278 dbg_print(MSG_INTL(MSG_SYM_DISCARDED), _Dbg_sym_dem(sdp->sd_name), 279 sectname, disp->is_file->ifl_name); 280 } 281 282 283 void 284 Dbg_syms_entered(Ehdr *ehdr, Sym *sym, Sym_desc *sdp) 285 { 286 if (DBG_NOTCLASS(DBG_SYMBOLS)) 287 return; 288 if (DBG_NOTDETAIL()) 289 return; 290 291 Elf_sym_table_entry(MSG_INTL(MSG_STR_ENTERED), ehdr, sym, sdp->sd_aux ? 292 sdp->sd_aux->sa_overndx : 0, NULL, conv_deftag_str(sdp->sd_ref)); 293 } 294 295 void 296 Dbg_syms_process(Ifl_desc *ifl) 297 { 298 if (DBG_NOTCLASS(DBG_SYMBOLS)) 299 return; 300 301 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 302 dbg_print(MSG_INTL(MSG_SYM_PROCESS), ifl->ifl_name, 303 conv_etype_str(ifl->ifl_ehdr->e_type)); 304 } 305 306 void 307 Dbg_syms_entry(Xword ndx, Sym_desc *sdp) 308 { 309 if (DBG_NOTCLASS(DBG_SYMBOLS)) 310 return; 311 312 dbg_print(MSG_INTL(MSG_SYM_BASIC), EC_XWORD(ndx), 313 _Dbg_sym_dem(sdp->sd_name)); 314 } 315 316 void 317 Dbg_syms_global(Xword ndx, const char *name) 318 { 319 if (DBG_NOTCLASS(DBG_SYMBOLS)) 320 return; 321 322 dbg_print(MSG_INTL(MSG_SYM_ADDING), EC_XWORD(ndx), _Dbg_sym_dem(name)); 323 } 324 325 void 326 Dbg_syms_sec_title() 327 { 328 if (DBG_NOTCLASS(DBG_SYMBOLS)) 329 return; 330 if (DBG_NOTDETAIL()) 331 return; 332 333 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 334 dbg_print(MSG_INTL(MSG_SYM_INDEX)); 335 } 336 337 void 338 Dbg_syms_sec_entry(int ndx, Sg_desc *sgp, Os_desc *osp) 339 { 340 if (DBG_NOTCLASS(DBG_SYMBOLS)) 341 return; 342 if (DBG_NOTDETAIL()) 343 return; 344 345 dbg_print(MSG_INTL(MSG_SYM_SECTION), ndx, osp->os_name, 346 (*sgp->sg_name ? sgp->sg_name : MSG_INTL(MSG_STR_NULL))); 347 } 348 349 void 350 Dbg_syms_up_title(Ehdr *ehdr) 351 { 352 if (DBG_NOTCLASS(DBG_SYMBOLS)) 353 return; 354 if (DBG_NOTDETAIL()) 355 return; 356 357 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 358 dbg_print(MSG_INTL(MSG_SYM_FINAL)); 359 /* LINTED */ 360 Gelf_sym_table_title((GElf_Ehdr *)ehdr, 361 MSG_ORIG(MSG_STR_EMPTY), MSG_ORIG(MSG_STR_EMPTY)); 362 } 363 364 void 365 Dbg_syms_ignore(Ehdr *ehdr, Sym_desc *sdp) 366 { 367 if (DBG_NOTCLASS(DBG_SYMBOLS)) 368 return; 369 if (DBG_NOTDETAIL()) 370 return; 371 372 Elf_sym_table_entry(MSG_INTL(MSG_STR_IGNORE), ehdr, sdp->sd_sym, 373 0, NULL, MSG_INTL(MSG_STR_UNUSED)); 374 } 375 376 void 377 Dbg_syms_old(Ehdr *ehdr, Sym_desc *sdp) 378 { 379 if (DBG_NOTCLASS(DBG_SYMBOLS)) 380 return; 381 if (DBG_NOTDETAIL()) 382 return; 383 384 Elf_sym_table_entry(MSG_INTL(MSG_STR_OLD), ehdr, sdp->sd_sym, 385 sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL, sdp->sd_name); 386 } 387 388 void 389 Dbg_syms_new(Ehdr *ehdr, Sym *sym, Sym_desc *sdp) 390 { 391 if (DBG_NOTCLASS(DBG_SYMBOLS)) 392 return; 393 if (DBG_NOTDETAIL()) 394 return; 395 396 Elf_sym_table_entry(MSG_INTL(MSG_STR_NEW), ehdr, sym, 397 sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL, 398 conv_deftag_str(sdp->sd_ref)); 399 } 400 401 void 402 Dbg_syms_updated(Ehdr *ehdr, Sym_desc *sdp, const char *name) 403 { 404 if (DBG_NOTCLASS(DBG_SYMBOLS)) 405 return; 406 407 dbg_print(MSG_INTL(MSG_SYM_UPDATE), name); 408 409 if (DBG_NOTDETAIL()) 410 return; 411 412 Elf_sym_table_entry(MSG_ORIG(MSG_STR_EMPTY), ehdr, sdp->sd_sym, 413 sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL, 414 conv_deftag_str(sdp->sd_ref)); 415 } 416 417 void 418 Dbg_syms_created(const char *name) 419 { 420 if (DBG_NOTCLASS(DBG_SYMBOLS)) 421 return; 422 423 dbg_print(MSG_INTL(MSG_SYM_CREATE), _Dbg_sym_dem(name)); 424 } 425 426 void 427 Dbg_syms_resolving1(Xword ndx, const char *name, int row, int col) 428 { 429 if (DBG_NOTCLASS(DBG_SYMBOLS)) 430 return; 431 432 dbg_print(MSG_INTL(MSG_SYM_RESOLVING), EC_XWORD(ndx), 433 _Dbg_sym_dem(name), row, col); 434 } 435 436 void 437 Dbg_syms_resolving2(Ehdr *ehdr, Sym *osym, Sym *nsym, Sym_desc *sdp, 438 Ifl_desc *ifl) 439 { 440 if (DBG_NOTCLASS(DBG_SYMBOLS)) 441 return; 442 if (DBG_NOTDETAIL()) 443 return; 444 445 Elf_sym_table_entry(MSG_INTL(MSG_STR_OLD), ehdr, osym, sdp->sd_aux ? 446 sdp->sd_aux->sa_overndx : 0, NULL, sdp->sd_file->ifl_name); 447 Elf_sym_table_entry(MSG_INTL(MSG_STR_NEW), ehdr, nsym, 0, NULL, 448 ifl->ifl_name); 449 } 450 451 void 452 Dbg_syms_resolved(Ehdr *ehdr, Sym_desc *sdp) 453 { 454 if (DBG_NOTCLASS(DBG_SYMBOLS)) 455 return; 456 if (DBG_NOTDETAIL()) 457 return; 458 459 Elf_sym_table_entry(MSG_INTL(MSG_STR_RESOLVED), ehdr, sdp->sd_sym, 460 sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL, 461 conv_deftag_str(sdp->sd_ref)); 462 } 463 464 void 465 Dbg_syms_nl() 466 { 467 if (DBG_NOTCLASS(DBG_SYMBOLS)) 468 return; 469 470 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 471 } 472 473 static Boolean symbol_title = TRUE; 474 475 static void 476 _Dbg_syms_reloc_title() 477 { 478 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 479 dbg_print(MSG_INTL(MSG_SYM_BSS)); 480 481 symbol_title = FALSE; 482 } 483 void 484 Dbg_syms_reloc(Ehdr *ehdr, Sym_desc *sdp) 485 { 486 if (DBG_NOTCLASS(DBG_SYMBOLS)) 487 return; 488 489 if (symbol_title) 490 _Dbg_syms_reloc_title(); 491 dbg_print(MSG_INTL(MSG_SYM_UPDATE), _Dbg_sym_dem(sdp->sd_name)); 492 493 if (DBG_NOTDETAIL()) 494 return; 495 496 Elf_sym_table_entry(MSG_ORIG(MSG_SYM_COPY), ehdr, sdp->sd_sym, 497 sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL, 498 conv_deftag_str(sdp->sd_ref)); 499 } 500 501 void 502 Dbg_syms_lookup_aout(const char *name) 503 { 504 if (DBG_NOTCLASS(DBG_SYMBOLS)) 505 return; 506 507 dbg_print(MSG_INTL(MSG_SYM_AOUT), _Dbg_sym_dem(name)); 508 } 509 510 void 511 Dbg_syms_lookup(const char *name, const char *file, const char *type) 512 { 513 if (DBG_NOTCLASS(DBG_SYMBOLS)) 514 return; 515 516 dbg_print(MSG_INTL(MSG_SYM_LOOKUP), _Dbg_sym_dem(name), file, type); 517 } 518 519 void 520 Dbg_syms_dlsym(const char *sym, const char *from, const char *next, int flag) 521 { 522 const char *str; 523 524 if (DBG_NOTCLASS(DBG_SYMBOLS)) 525 return; 526 527 if (flag == DBG_DLSYM_NEXT) 528 str = MSG_ORIG(MSG_SYM_NEXT); 529 else if (flag == DBG_DLSYM_DEFAULT) 530 str = MSG_ORIG(MSG_SYM_DEFAULT); 531 else if (flag == DBG_DLSYM_SELF) 532 str = MSG_ORIG(MSG_SYM_SELF); 533 else if (flag == DBG_DLSYM_PROBE) 534 str = MSG_ORIG(MSG_SYM_PROBE); 535 else 536 str = MSG_ORIG(MSG_STR_EMPTY); 537 538 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 539 if (next == 0) 540 dbg_print(MSG_INTL(MSG_SYM_DLSYM_1), _Dbg_sym_dem(sym), 541 from, str); 542 else 543 dbg_print(MSG_INTL(MSG_SYM_DLSYM_2), _Dbg_sym_dem(sym), 544 from, next, str); 545 } 546 547 void 548 Dbg_syms_reduce(int which, Ehdr *ehdr, Sym_desc *sdp, 549 int idx, const char *sname) 550 { 551 static Boolean sym_reduce_title = TRUE; 552 static Boolean sym_retain_title = TRUE; 553 Boolean isfromglobal = (which == DBG_SYM_REDUCE_GLOBAL); 554 Boolean isfromretain = (which == DBG_SYM_REDUCE_RETAIN); 555 556 if (DBG_NOTCLASS(DBG_SYMBOLS | DBG_VERSIONS)) 557 return; 558 559 if (sym_reduce_title && isfromglobal) { 560 sym_reduce_title = FALSE; 561 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 562 dbg_print(MSG_INTL(MSG_SYM_REDUCED)); 563 } else if (sym_retain_title && isfromretain) { 564 sym_retain_title = FALSE; 565 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 566 dbg_print(MSG_INTL(MSG_SYM_RETAINING)); 567 } 568 569 if ((sdp->sd_flags1 & FLG_SY1_ELIM) && isfromglobal) 570 dbg_print(MSG_INTL(MSG_SYM_ELIMINATING), 571 _Dbg_sym_dem(sdp->sd_name)); 572 else if (isfromglobal) 573 dbg_print(MSG_INTL(MSG_SYM_REDUCING), 574 _Dbg_sym_dem(sdp->sd_name)); 575 else 576 dbg_print(MSG_INTL(MSG_SYM_NOTELIMINATE), 577 _Dbg_sym_dem(sdp->sd_name), sname, idx); 578 579 if (DBG_NOTDETAIL()) 580 return; 581 582 Elf_sym_table_entry(MSG_ORIG(MSG_SYM_LOCAL), ehdr, sdp->sd_sym, 583 sdp->sd_aux ? sdp->sd_aux->sa_overndx : 0, NULL, 584 sdp->sd_file->ifl_name); 585 } 586 587 588 void 589 Dbg_syminfo_title() 590 { 591 if (DBG_NOTCLASS(DBG_SYMBOLS)) 592 return; 593 if (DBG_NOTDETAIL()) 594 return; 595 596 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 597 dbg_print(MSG_INTL(MSG_SYMI_TITLE1)); 598 Gelf_syminfo_title(); 599 } 600 601 void 602 Dbg_syminfo_entry(int ndx, Syminfo *sip, Sym *sym, const char *strtab, 603 Dyn *dyn) 604 { 605 const char *needed; 606 607 if (DBG_NOTCLASS(DBG_SYMBOLS)) 608 return; 609 if (DBG_NOTDETAIL()) 610 return; 611 612 if (sip->si_boundto < SYMINFO_BT_LOWRESERVE) 613 needed = strtab + dyn[sip->si_boundto].d_un.d_val; 614 else 615 needed = 0; 616 617 Gelf_syminfo_entry(ndx, (GElf_Syminfo *)sip, 618 _Dbg_sym_dem(strtab + sym->st_name), needed); 619 } 620