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 2005 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 "_synonyms.h" 29 30 #include <string.h> 31 #include <unistd.h> 32 #include <fcntl.h> 33 #include <limits.h> 34 #include <stdio.h> 35 #include "msg.h" 36 #include "_debug.h" 37 #include "libld.h" 38 39 40 void 41 Dbg_file_generic(Ifl_desc *ifl) 42 { 43 if (DBG_NOTCLASS(DBG_FILES)) 44 return; 45 46 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 47 dbg_print(MSG_INTL(MSG_FIL_BASIC), ifl->ifl_name, 48 conv_etype_str(ifl->ifl_ehdr->e_type)); 49 } 50 51 void 52 Dbg_file_skip(const char *nname, const char *oname) 53 { 54 if (DBG_NOTCLASS(DBG_FILES)) 55 return; 56 57 if (oname && strcmp(nname, oname)) 58 dbg_print(MSG_INTL(MSG_FIL_SKIP_1), nname, oname); 59 else 60 dbg_print(MSG_INTL(MSG_FIL_SKIP_2), nname); 61 } 62 63 void 64 Dbg_file_reuse(const char *nname, const char *oname) 65 { 66 if (DBG_NOTCLASS(DBG_FILES)) 67 return; 68 69 dbg_print(MSG_INTL(MSG_FIL_REUSE), nname, oname); 70 } 71 72 void 73 Dbg_file_archive(const char *name, int again) 74 { 75 const char *str; 76 77 if (DBG_NOTCLASS(DBG_FILES)) 78 return; 79 80 if (again) 81 str = MSG_INTL(MSG_STR_AGAIN); 82 else 83 str = MSG_ORIG(MSG_STR_EMPTY); 84 85 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 86 dbg_print(MSG_INTL(MSG_FIL_ARCHIVE), name, str); 87 } 88 89 void 90 Dbg_file_analyze(Rt_map * lmp) 91 { 92 if (DBG_NOTCLASS(DBG_FILES)) 93 return; 94 95 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 96 dbg_print(MSG_INTL(MSG_FIL_ANALYZE), NAME(lmp), 97 conv_dlmode_str(MODE(lmp), 1)); 98 } 99 100 void 101 Dbg_file_aout(const char *name, ulong_t dynamic, ulong_t base, ulong_t size) 102 { 103 if (DBG_NOTCLASS(DBG_FILES)) 104 return; 105 106 dbg_print(MSG_INTL(MSG_FIL_AOUT), name); 107 dbg_print(MSG_INTL(MSG_FIL_DATA_1), EC_XWORD(dynamic), 108 EC_ADDR(base), EC_XWORD(size)); 109 } 110 111 void 112 Dbg_file_elf(const char *name, ulong_t dynamic, ulong_t base, 113 ulong_t size, ulong_t entry, Lmid_t lmid, Aliste lmco) 114 { 115 const char *str; 116 117 if (DBG_NOTCLASS(DBG_FILES)) 118 return; 119 120 if (base == 0) 121 str = MSG_INTL(MSG_STR_TEMPORARY); 122 else 123 str = MSG_ORIG(MSG_STR_EMPTY); 124 125 dbg_print(MSG_INTL(MSG_FIL_ELF), name, str); 126 dbg_print(MSG_INTL(MSG_FIL_DATA_1), EC_XWORD(dynamic), 127 EC_ADDR(base), EC_XWORD(size)); 128 dbg_print(MSG_INTL(MSG_FIL_DATA_2), EC_XWORD(entry), 129 EC_XWORD(lmid), EC_XWORD(lmco)); 130 } 131 132 void 133 Dbg_file_ldso(const char *name, ulong_t dynamic, ulong_t base, ulong_t envp, 134 ulong_t auxv) 135 { 136 if (DBG_NOTCLASS(DBG_FILES)) 137 return; 138 139 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 140 dbg_print(MSG_INTL(MSG_FIL_LDSO), name); 141 dbg_print(MSG_INTL(MSG_FIL_DATA_3), EC_XWORD(dynamic), 142 EC_ADDR(base)); 143 dbg_print(MSG_INTL(MSG_FIL_DATA_4), EC_ADDR(envp), EC_ADDR(auxv)); 144 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 145 } 146 147 void 148 Dbg_file_prot(const char *name, int prot) 149 { 150 if (DBG_NOTCLASS(DBG_FILES)) 151 return; 152 153 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 154 dbg_print(MSG_INTL(MSG_FIL_PROT), name, (prot ? '+' : '-')); 155 } 156 157 void 158 Dbg_file_delete(const char *name) 159 { 160 if (DBG_NOTCLASS(DBG_FILES)) 161 return; 162 163 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 164 dbg_print(MSG_INTL(MSG_FIL_DELETE), name); 165 } 166 167 static int hdl_title = 0; 168 static Msg hdl_str = 0; 169 170 void 171 Dbg_file_hdl_title(int type) 172 { 173 if (DBG_NOTCLASS(DBG_FILES)) 174 return; 175 if (DBG_NOTDETAIL()) 176 return; 177 178 hdl_title = 1; 179 180 /* 181 * Establish a binding title for later use in Dbg_file_bind_entry. 182 */ 183 if (type == DBG_DEP_CREATE) 184 hdl_str = MSG_FIL_HDL_CREATE; /* MSG_INTL(MSG_FIL_HDL_CREATE) */ 185 else if (type == DBG_DEP_ADD) 186 hdl_str = MSG_FIL_HDL_ADD; /* MSG_INTL(MSG_FIL_HDL_ADD) */ 187 else if (type == DBG_DEP_DELETE) 188 hdl_str = MSG_FIL_HDL_DELETE; /* MSG_INTL(MSG_FIL_HDL_DELETE) */ 189 else if (type == DBG_DEP_ORPHAN) 190 hdl_str = MSG_FIL_HDL_ORPHAN; /* MSG_INTL(MSG_FIL_HDL_ORPHAN) */ 191 else if (type == DBG_DEP_REINST) 192 hdl_str = MSG_FIL_HDL_REINST; /* MSG_INTL(MSG_FIL_HDL_REINST) */ 193 else 194 hdl_str = 0; 195 } 196 197 void 198 Dbg_file_hdl_collect(Grp_hdl * ghp, const char *name) 199 { 200 const char *str; 201 202 if (DBG_NOTCLASS(DBG_FILES)) 203 return; 204 if (DBG_NOTDETAIL()) 205 return; 206 207 if (ghp->gh_owner) 208 str = NAME(ghp->gh_owner); 209 else 210 str = MSG_INTL(MSG_STR_ORPHAN); 211 212 if (hdl_title) { 213 hdl_title = 0; 214 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 215 } 216 if (name) 217 dbg_print(MSG_INTL(MSG_FIL_HDL_RETAIN), str, name); 218 else 219 dbg_print(MSG_INTL(MSG_FIL_HDL_COLLECT), str, 220 conv_grphdrflags_str(ghp->gh_flags)); 221 } 222 223 void 224 Dbg_file_hdl_action(Grp_hdl * ghp, Rt_map * lmp, int type) 225 { 226 Msg str; 227 228 if (DBG_NOTCLASS(DBG_FILES)) 229 return; 230 if (DBG_NOTDETAIL()) 231 return; 232 233 if (hdl_title) { 234 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 235 if (hdl_str) { 236 const char *name; 237 238 /* 239 * Protect ourselves in case this handle has no 240 * originating owner. 241 */ 242 if (ghp->gh_owner) 243 name = NAME(ghp->gh_owner); 244 else 245 name = MSG_INTL(MSG_STR_UNKNOWN); 246 247 dbg_print(MSG_INTL(hdl_str), name); 248 } 249 hdl_title = 0; 250 } 251 252 if (type == DBG_DEP_ADD) 253 str = MSG_FIL_DEP_ADD; /* MSG_INTL(MSG_FIL_DEP_ADD) */ 254 else if (type == DBG_DEP_DELETE) 255 str = MSG_FIL_DEP_DELETE; /* MSG_INTL(MSG_FIL_DEP_DELETE) */ 256 else if (type == DBG_DEP_REMOVE) 257 str = MSG_FIL_DEP_REMOVE; /* MSG_INTL(MSG_FIL_DEP_REMOVE) */ 258 else if (type == DBG_DEP_REMAIN) 259 str = MSG_FIL_DEP_REMAIN; /* MSG_INTL(MSG_FIL_DEP_REMAIN) */ 260 else 261 str = 0; 262 263 if (str) { 264 const char *mode; 265 266 if ((MODE(lmp) & (RTLD_GLOBAL | RTLD_NODELETE)) == 267 (RTLD_GLOBAL | RTLD_NODELETE)) 268 mode = MSG_ORIG(MSG_MODE_GLOBNODEL); 269 else if (MODE(lmp) & RTLD_GLOBAL) 270 mode = MSG_ORIG(MSG_MODE_GLOB); 271 272 else if (MODE(lmp) & RTLD_NODELETE) 273 mode = MSG_ORIG(MSG_MODE_NODEL); 274 else 275 mode = MSG_ORIG(MSG_STR_EMPTY); 276 277 dbg_print(MSG_INTL(str), NAME(lmp), mode); 278 } 279 } 280 281 #define BINDSZ MSG_STR_OSQBRKT_SIZE + \ 282 MSG_BND_NEEDED_SIZE + \ 283 MSG_BND_REFER_SIZE + \ 284 MSG_STR_CSQBRKT_SIZE 285 286 void 287 Dbg_file_bind_entry(Bnd_desc *bdp) 288 { 289 char string[BINDSZ]; 290 Rt_map *clmp, *dlmp; 291 uint_t flags; 292 293 if (DBG_NOTCLASS(DBG_FILES)) 294 return; 295 if (DBG_NOTDETAIL()) 296 return; 297 298 clmp = bdp->b_caller; 299 dlmp = bdp->b_depend; 300 flags = bdp->b_flags; 301 302 /* 303 * Evaluate the binding descriptors flags. 304 */ 305 if (flags) { 306 (void) strcpy(string, MSG_ORIG(MSG_STR_OSQBRKT)); 307 if (flags & BND_NEEDED) 308 (void) strcat(string, MSG_ORIG(MSG_BND_NEEDED)); 309 if (flags & BND_REFER) 310 (void) strcat(string, MSG_ORIG(MSG_BND_REFER)); 311 (void) strcat(string, MSG_ORIG(MSG_STR_CSQBRKT)); 312 } else 313 (void) strcpy(string, MSG_ORIG(MSG_STR_EMPTY)); 314 315 /* 316 * Print the dependency together with the modes of the binding. 317 */ 318 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 319 dbg_print(MSG_INTL(MSG_FIL_BND_ADD), NAME(clmp)); 320 dbg_print(MSG_INTL(MSG_FIL_BND_FILE), NAME(dlmp), string); 321 } 322 323 void 324 Dbg_file_dlopen(const char *name, const char *from, int mode) 325 { 326 if (DBG_NOTCLASS(DBG_FILES)) 327 return; 328 329 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 330 dbg_print(MSG_INTL(MSG_FIL_DLOPEN), name, from, 331 conv_dlmode_str(mode, 1)); 332 } 333 334 void 335 Dbg_file_dlclose(const char *name, int flag) 336 { 337 const char *str; 338 339 if (DBG_NOTCLASS(DBG_FILES)) 340 return; 341 342 if (flag == DBG_DLCLOSE_IGNORE) 343 str = MSG_INTL(MSG_STR_IGNORE); 344 else 345 str = MSG_ORIG(MSG_STR_EMPTY); 346 347 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 348 dbg_print(MSG_INTL(MSG_FIL_DLCLOSE), name, str); 349 } 350 351 void 352 Dbg_file_dldump(const char *ipath, const char *opath, int flags) 353 { 354 if (DBG_NOTCLASS(DBG_FILES)) 355 return; 356 357 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 358 dbg_print(MSG_INTL(MSG_FIL_DLDUMP), ipath, opath, 359 conv_dlflag_str(flags, 0)); 360 } 361 362 void 363 Dbg_file_lazyload(const char *file, const char *from, const char *symname) 364 { 365 if (DBG_NOTCLASS(DBG_FILES)) 366 return; 367 368 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 369 dbg_print(MSG_INTL(MSG_FIL_LAZYLOAD), file, from, 370 _Dbg_sym_dem(symname)); 371 } 372 373 void 374 Dbg_file_nl() 375 { 376 if (DBG_NOTCLASS(DBG_FILES)) 377 return; 378 if (DBG_NOTDETAIL()) 379 return; 380 381 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 382 } 383 384 void 385 Dbg_file_preload(const char *name) 386 { 387 if (DBG_NOTCLASS(DBG_FILES)) 388 return; 389 390 dbg_print(MSG_INTL(MSG_FIL_PRELOAD), name); 391 } 392 393 void 394 Dbg_file_needed(const char *name, const char *parent) 395 { 396 if (DBG_NOTCLASS(DBG_FILES)) 397 return; 398 399 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 400 dbg_print(MSG_INTL(MSG_FIL_NEEDED), name, parent); 401 } 402 403 void 404 Dbg_file_filter(const char *filter, const char *filtee, int config) 405 { 406 if (DBG_NOTCLASS(DBG_FILES)) 407 return; 408 409 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 410 if (config) 411 dbg_print(MSG_INTL(MSG_FIL_FILTER_1), filter, filtee); 412 else 413 dbg_print(MSG_INTL(MSG_FIL_FILTER_2), filter, filtee); 414 } 415 416 void 417 Dbg_file_filtee(const char *filter, const char *filtee, int audit) 418 { 419 if (audit) { 420 if (DBG_NOTCLASS(DBG_AUDITING | DBG_FILES)) 421 return; 422 423 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 424 dbg_print(MSG_INTL(MSG_FIL_FILTEE_3), filtee); 425 } else { 426 if (DBG_NOTCLASS(DBG_FILES)) 427 return; 428 429 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 430 if (filter) 431 dbg_print(MSG_INTL(MSG_FIL_FILTEE_1), filtee, filter); 432 else 433 dbg_print(MSG_INTL(MSG_FIL_FILTEE_2), filtee); 434 } 435 } 436 437 void 438 Dbg_file_fixname(const char *oname, const char *nname) 439 { 440 if (DBG_NOTCLASS(DBG_FILES)) 441 return; 442 443 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 444 dbg_print(MSG_INTL(MSG_FIL_FIXNAME), oname, nname); 445 } 446 447 void 448 Dbg_file_output(Ofl_desc *ofl) 449 { 450 const char *prefix = MSG_ORIG(MSG_PTH_OBJECT); 451 char *oname, *nname, *ofile; 452 int fd; 453 454 if (DBG_NOTCLASS(DBG_FILES)) 455 return; 456 if (DBG_NOTDETAIL()) 457 return; 458 459 /* 460 * Obtain the present input object filename for concatenation to the 461 * prefix name. 462 */ 463 oname = (char *)ofl->ofl_name; 464 if ((ofile = strrchr(oname, '/')) == NULL) 465 ofile = oname; 466 else 467 ofile++; 468 469 /* 470 * Concatenate the prefix with the object filename, open the file and 471 * write out the present Elf memory image. As this is debugging we 472 * ignore all errors. 473 */ 474 if ((nname = (char *)malloc(strlen(prefix) + strlen(ofile) + 1)) != 0) { 475 (void) strcpy(nname, prefix); 476 (void) strcat(nname, ofile); 477 if ((fd = open(nname, O_RDWR | O_CREAT | O_TRUNC, 478 0666)) != -1) { 479 (void) write(fd, ofl->ofl_ehdr, ofl->ofl_size); 480 close(fd); 481 } 482 free(nname); 483 } 484 } 485 486 void 487 Dbg_file_config_dis(const char *config, int features) 488 { 489 const char *str; 490 int error = features & ~CONF_FEATMSK; 491 492 if (error == DBG_CONF_IGNORE) 493 str = MSG_INTL(MSG_FIL_CONFIG_ERR_1); 494 else if (error == DBG_CONF_VERSION) 495 str = MSG_INTL(MSG_FIL_CONFIG_ERR_2); 496 else if (error == DBG_CONF_PRCFAIL) 497 str = MSG_INTL(MSG_FIL_CONFIG_ERR_3); 498 else if (error == DBG_CONF_CORRUPT) 499 str = MSG_INTL(MSG_FIL_CONFIG_ERR_4); 500 else 501 str = conv_config_str(features); 502 503 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 504 dbg_print(MSG_INTL(MSG_FIL_CONFIG_ERR), config, str); 505 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 506 } 507 508 void 509 Dbg_file_config_obj(const char *dir, const char *file, const char *config) 510 { 511 char *name, _name[PATH_MAX]; 512 513 if (DBG_NOTCLASS(DBG_FILES)) 514 return; 515 516 if (file) { 517 (void) snprintf(_name, PATH_MAX, MSG_ORIG(MSG_FMT_PATH), 518 dir, file); 519 name = _name; 520 } else 521 name = (char *)dir; 522 523 dbg_print(MSG_INTL(MSG_FIL_CONFIG), name, config); 524 } 525 526 #if !defined(_ELF64) 527 528 const Msg 529 reject[] = { 530 MSG_STR_EMPTY, 531 MSG_REJ_MACH, /* MSG_INTL(MSG_REJ_MACH) */ 532 MSG_REJ_CLASS, /* MSG_INTL(MSG_REJ_CLASS) */ 533 MSG_REJ_DATA, /* MSG_INTL(MSG_REJ_DATA) */ 534 MSG_REJ_TYPE, /* MSG_INTL(MSG_REJ_TYPE) */ 535 MSG_REJ_BADFLAG, /* MSG_INTL(MSG_REJ_BADFLAG) */ 536 MSG_REJ_MISFLAG, /* MSG_INTL(MSG_REJ_MISFLAG) */ 537 MSG_REJ_VERSION, /* MSG_INTL(MSG_REJ_VERSION) */ 538 MSG_REJ_HAL, /* MSG_INTL(MSG_REJ_HAL) */ 539 MSG_REJ_US3, /* MSG_INTL(MSG_REJ_US3) */ 540 MSG_REJ_STR, /* MSG_INTL(MSG_REJ_STR) */ 541 MSG_REJ_UNKFILE, /* MSG_INTL(MSG_REJ_UNKFILE) */ 542 MSG_REJ_HWCAP_1, /* MSG_INTL(MSG_REJ_HWCAP_1) */ 543 }; 544 545 void 546 Dbg_file_rejected(Rej_desc *rej) 547 { 548 if (DBG_NOTCLASS(DBG_FILES)) 549 return; 550 551 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 552 dbg_print(MSG_INTL(reject[rej->rej_type]), rej->rej_name ? 553 rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN), conv_reject_str(rej)); 554 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 555 } 556 557 void 558 Dbg_file_del_rescan(void) 559 { 560 if (DBG_NOTCLASS(DBG_FILES)) 561 return; 562 563 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 564 dbg_print(MSG_INTL(MSG_FIL_DEL_RESCAN)); 565 } 566 567 void 568 Dbg_file_ar_rescan(void) 569 { 570 if (DBG_NOTCLASS(DBG_FILES)) 571 return; 572 573 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 574 dbg_print(MSG_INTL(MSG_FIL_AR_RESCAN)); 575 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 576 } 577 578 void 579 Dbg_file_mode_promote(const char *file, int mode) 580 { 581 if (DBG_NOTCLASS(DBG_FILES)) 582 return; 583 584 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 585 dbg_print(MSG_INTL(MSG_FIL_PROMOTE), file, conv_dlmode_str(mode, 0)); 586 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 587 } 588 589 void 590 Dbg_file_cntl(Lm_list *lml, Aliste flmco, Aliste tlmco) 591 { 592 Lm_cntl *lmc; 593 Aliste off; 594 595 if (DBG_NOTCLASS(DBG_FILES)) 596 return; 597 if (DBG_NOTDETAIL()) 598 return; 599 600 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 601 dbg_print(MSG_INTL(MSG_CNTL_TITLE), EC_XWORD(flmco), EC_XWORD(tlmco)); 602 603 for (ALIST_TRAVERSE(lml->lm_lists, off, lmc)) { 604 Rt_map *lmp; 605 606 for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) 607 dbg_print(MSG_ORIG(MSG_CNTL_ENTRY), EC_XWORD(off), 608 NAME(lmp)); 609 } 610 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 611 } 612 #endif 613