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