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 (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * Library processing 33 */ 34 #include <stdio.h> 35 #include <string.h> 36 #include <debug.h> 37 #include "msg.h" 38 #include "_libld.h" 39 40 /* 41 * Archive members are typically extracted to resolve an existing undefined 42 * reference. However, other symbol definitions can cause archive members to 43 * be processed to determine if the archive member provides a more appropriate 44 * definition. This routine processes the archive member to determine if the 45 * member is really required. 46 * 47 * i. Tentative symbols may cause the extraction of an archive member. 48 * If the archive member has a strong defined symbol it will be used. 49 * If the archive member simply contains another tentative definition, 50 * or a defined function symbol, then it will not be used. 51 * 52 * ii. A symbol reference may define a hidden or protected visibility. The 53 * reference can only be bound to a definition within a relocatable object 54 * for this restricted visibility to be satisfied. If the archive member 55 * provides a definition of the same symbol type, this definition is 56 * taken. The visibility of the defined symbol is irrelevant, as the most 57 * restrictive visibility of the reference and the definition will be 58 * applied to the final symbol. 59 */ 60 static int 61 process_member(Ar_mem *amp, const char *name, Sym_desc *sdp, Ofl_desc *ofl) 62 { 63 Sym *syms, *osym = sdp->sd_sym; 64 Xword symn, cnt; 65 char *strs; 66 67 /* 68 * Find the first symbol table in the archive member, obtain its 69 * data buffer and determine the number of global symbols (Note, 70 * there must be a symbol table present otherwise the archive would 71 * never have been able to generate its own symbol entry for this 72 * member). 73 */ 74 if (amp->am_syms == 0) { 75 Elf_Scn *scn = NULL; 76 Shdr *shdr; 77 Elf_Data *data; 78 79 while (scn = elf_nextscn(amp->am_elf, scn)) { 80 if ((shdr = elf_getshdr(scn)) == NULL) { 81 eprintf(ofl->ofl_lml, ERR_ELF, 82 MSG_INTL(MSG_ELF_GETSHDR), amp->am_path); 83 ofl->ofl_flags |= FLG_OF_FATAL; 84 return (0); 85 } 86 if ((shdr->sh_type == SHT_SYMTAB) || 87 (shdr->sh_type == SHT_DYNSYM)) 88 break; 89 } 90 if ((data = elf_getdata(scn, NULL)) == NULL) { 91 eprintf(ofl->ofl_lml, ERR_ELF, 92 MSG_INTL(MSG_ELF_GETDATA), amp->am_path); 93 ofl->ofl_flags |= FLG_OF_FATAL; 94 return (0); 95 } 96 syms = (Sym *)data->d_buf; 97 syms += shdr->sh_info; 98 symn = shdr->sh_size / shdr->sh_entsize; 99 symn -= shdr->sh_info; 100 101 /* 102 * Get the data for the associated string table. 103 */ 104 if ((scn = elf_getscn(amp->am_elf, (size_t)shdr->sh_link)) == 105 NULL) { 106 eprintf(ofl->ofl_lml, ERR_ELF, 107 MSG_INTL(MSG_ELF_GETSCN), amp->am_path); 108 ofl->ofl_flags |= FLG_OF_FATAL; 109 return (0); 110 } 111 if ((data = elf_getdata(scn, NULL)) == NULL) { 112 eprintf(ofl->ofl_lml, ERR_ELF, 113 MSG_INTL(MSG_ELF_GETDATA), amp->am_path); 114 ofl->ofl_flags |= FLG_OF_FATAL; 115 return (0); 116 } 117 strs = data->d_buf; 118 119 /* 120 * Initialize the archive member structure in case we have to 121 * come through here again. 122 */ 123 amp->am_syms = syms; 124 amp->am_strs = strs; 125 amp->am_symn = symn; 126 } else { 127 syms = amp->am_syms; 128 strs = amp->am_strs; 129 symn = amp->am_symn; 130 } 131 132 /* 133 * Loop through the symbol table entries looking for a match for the 134 * original symbol. 135 */ 136 for (cnt = 0; cnt < symn; syms++, cnt++) { 137 Word shndx; 138 139 if ((shndx = syms->st_shndx) == SHN_UNDEF) 140 continue; 141 142 if (osym->st_shndx == SHN_COMMON) { 143 /* 144 * Determine whether a tentative symbol definition 145 * should be overridden. 146 */ 147 if ((shndx == SHN_ABS) || (shndx == SHN_COMMON) || 148 (ELF_ST_TYPE(syms->st_info) == STT_FUNC)) 149 continue; 150 151 /* 152 * A historic detail requires that a weak definition 153 * within an archive will not override a strong 154 * definition (see sym_realtent() resolution and ABI 155 * symbol binding description - page 4-27). 156 */ 157 if ((ELF_ST_BIND(syms->st_info) == STB_WEAK) && 158 (ELF_ST_BIND(osym->st_info) != STB_WEAK)) 159 continue; 160 } else { 161 /* 162 * Determine whether a restricted visibility reference 163 * should be overridden. Don't worry about the 164 * visibility of the archive member definition, nor 165 * whether it is weak or global. Any definition is 166 * better than a binding to an external shared object 167 * (which is the only event that must presently exist 168 * for us to be here looking for a better alternative). 169 */ 170 if (ELF_ST_TYPE(syms->st_info) != 171 ELF_ST_TYPE(osym->st_info)) 172 continue; 173 } 174 175 if (strcmp(strs + syms->st_name, name) == NULL) 176 return (1); 177 } 178 return (0); 179 } 180 181 /* 182 * Create an archive descriptor. By maintaining a list of archives any 183 * duplicate occurrences of the same archive specified by the user enable us to 184 * pick off where the last processing finished. 185 */ 186 Ar_desc * 187 ld_ar_setup(const char *name, Elf *elf, Ofl_desc *ofl) 188 { 189 Ar_desc * adp; 190 size_t number; 191 Elf_Arsym * start; 192 193 /* 194 * Get the archive symbol table. If this fails, we will 195 * ignore this file with a warning message. 196 */ 197 if ((start = elf_getarsym(elf, &number)) == 0) { 198 if (elf_errno()) { 199 eprintf(ofl->ofl_lml, ERR_ELF, 200 MSG_INTL(MSG_ELF_GETARSYM), name); 201 ofl->ofl_flags |= FLG_OF_FATAL; 202 } else 203 eprintf(ofl->ofl_lml, ERR_WARNING, 204 MSG_INTL(MSG_ELF_ARSYM), name); 205 206 return (0); 207 } 208 209 /* 210 * As this is a new archive reference establish a new descriptor. 211 */ 212 if ((adp = libld_malloc(sizeof (Ar_desc))) == 0) 213 return ((Ar_desc *)S_ERROR); 214 adp->ad_name = name; 215 adp->ad_elf = elf; 216 adp->ad_start = start; 217 if ((adp->ad_aux = libld_calloc(sizeof (Ar_aux), number)) == 0) 218 return ((Ar_desc *)S_ERROR); 219 220 /* 221 * Retain any command line options that are applicable to archive 222 * extraction in case we have to rescan this archive later. 223 */ 224 adp->ad_flags = ofl->ofl_flags1 & MSK_OF1_ARCHIVE; 225 226 ofl->ofl_arscnt++; 227 228 /* 229 * Add this new descriptor to the list of archives. 230 */ 231 if (list_appendc(&ofl->ofl_ars, adp) == 0) 232 return ((Ar_desc *)S_ERROR); 233 else 234 return (adp); 235 } 236 237 /* 238 * For each archive descriptor, maintain an `Ar_aux' table to parallel the 239 * archive symbol table (returned from elf_getarsym(3e)). Use this table to 240 * hold a `Sym_desc' for each symbol (thus reducing the number of 241 * ld_sym_find()'s), and to hold the `Ar_mem' pointer. The `Ar_mem' element 242 * can have one of three values indicating the state of the archive member 243 * associated with the offset for this symbol table entry: 244 * 245 * 0 indicates that the member has not been processed. 246 * 247 * FLG_ARMEM_PROC 248 * indicates that the member has been processed. 249 * 250 * addr indicates that the member has been investigated to determine if 251 * it contained a symbol definition we need, but was found not to 252 * be a candidate for extraction. In this case the members 253 * structure is maintained for possible later use. 254 * 255 * Each time we process an archive member we use its offset value to scan this 256 * `Ar_aux' list. If the member has been extracted, each entry with the same 257 * offset has its `Ar_mem' pointer set to FLG_AMMEM_PROC. Thus if we cycle back 258 * through the archive symbol table we will ignore these symbols as they will 259 * have already been added to the output image. If a member has been processed 260 * but found not to contain a symbol we need, each entry with the same offset 261 * has its `Ar_mem' pointer set to the member structures address. 262 */ 263 void 264 ld_ar_member(Ar_desc * adp, Elf_Arsym * arsym, Ar_aux * aup, Ar_mem * amp) 265 { 266 Elf_Arsym * _arsym = arsym; 267 Ar_aux * _aup = aup; 268 size_t _off = arsym->as_off; 269 270 if (_arsym != adp->ad_start) { 271 do { 272 _arsym--; 273 _aup--; 274 if (_arsym->as_off != _off) 275 break; 276 _aup->au_mem = amp; 277 } while (_arsym != adp->ad_start); 278 } 279 280 _arsym = arsym; 281 _aup = aup; 282 283 do { 284 if (_arsym->as_off != _off) 285 break; 286 _aup->au_mem = amp; 287 _arsym++; 288 _aup++; 289 } while (_arsym->as_name); 290 } 291 292 /* 293 * Data structure to indicate whether a symbol is visible for the purpose 294 * of archive extraction. 295 */ 296 static const Boolean 297 sym_vis[STV_NUM] = { 298 TRUE, /* STV_DEFAULT */ 299 FALSE, /* STV_INTERNAL */ 300 FALSE, /* STV_HIDDEN */ 301 FALSE, /* STV_PROTECTED */ 302 TRUE, /* STV_EXPORTED */ 303 TRUE, /* STV_SINGLETON */ 304 FALSE /* STV_ELIMINATE */ 305 }; 306 #if STV_NUM != (STV_ELIMINATE + 1) 307 #error "STV_NUM has grown. Update sym_vis[]." 308 #endif 309 310 /* 311 * Read the archive symbol table. For each symbol in the table, determine 312 * whether that symbol satisfies an unresolved reference, tentative reference, 313 * or a reference that expects hidden or protected visibility. If so, the 314 * corresponding object from the archive is processed. The archive symbol 315 * table is searched until we go through a complete pass without satisfying any 316 * unresolved symbols 317 */ 318 uintptr_t 319 ld_process_archive(const char *name, int fd, Ar_desc *adp, Ofl_desc *ofl) 320 { 321 Elf_Arsym * arsym; 322 Elf_Arhdr * arhdr; 323 Elf * arelf; 324 Ar_aux * aup; 325 Sym_desc * sdp; 326 char *arname, *arpath; 327 Xword ndx; 328 int found, again; 329 int allexrt = (ofl->ofl_flags1 & FLG_OF1_ALLEXRT) != 0; 330 uintptr_t err; 331 Rej_desc rej = { 0 }; 332 333 /* 334 * If a fatal error condition has been set there's really no point in 335 * processing the archive further. Having got to this point we have at 336 * least established that the archive exists (thus verifying that the 337 * command line options that got us to this archive are correct). Very 338 * large archives can take a significant time to process, therefore 339 * continuing on from here may significantly delay the fatal error 340 * message the user is already set to receive. 341 */ 342 if (ofl->ofl_flags & FLG_OF_FATAL) 343 return (1); 344 345 /* 346 * If this archive was processed with -z allextract, then all members 347 * have already been extracted. 348 */ 349 if (adp->ad_elf == (Elf *)NULL) 350 return (1); 351 352 /* 353 * Loop through archive symbol table until we make a complete pass 354 * without satisfying an unresolved reference. For each archive 355 * symbol, see if there is a symbol with the same name in ld's 356 * symbol table. If so, and if that symbol is still unresolved or 357 * tentative, process the corresponding archive member. 358 */ 359 found = again = 0; 360 do { 361 DBG_CALL(Dbg_file_ar(ofl->ofl_lml, name, again)); 362 DBG_CALL(Dbg_syms_ar_title(ofl->ofl_lml, name, again)); 363 364 ndx = again = 0; 365 for (arsym = adp->ad_start, aup = adp->ad_aux; arsym->as_name; 366 ++arsym, ++aup, ndx++) { 367 Rej_desc _rej = { 0 }; 368 Ar_mem *amp; 369 Sym *sym; 370 Boolean visible = TRUE; 371 372 /* 373 * If the auxiliary members value indicates that this 374 * member has been processed then this symbol will have 375 * been added to the output file image already or the 376 * object was rejected in which case we don't want to 377 * process it again. 378 */ 379 if (aup->au_mem == FLG_ARMEM_PROC) 380 continue; 381 382 /* 383 * If the auxiliary symbol element is non-zero lookup 384 * the symbol from the internal symbol table. 385 * (But you skip this if allextract is specified.) 386 */ 387 if ((allexrt == 0) && ((sdp = aup->au_syms) == 0)) { 388 if ((sdp = ld_sym_find(arsym->as_name, 389 /* LINTED */ 390 (Word)arsym->as_hash, 0, ofl)) == 0) { 391 DBG_CALL(Dbg_syms_ar_entry(ofl->ofl_lml, 392 ndx, arsym)); 393 continue; 394 } 395 aup->au_syms = sdp; 396 } 397 398 /* 399 * With '-z allextract', all members will be extracted. 400 * 401 * This archive member is a candidate for extraction if 402 * the internal symbol originates from an explicit file, 403 * and represents an undefined or tentative symbol. 404 * 405 * By default, weak references do not cause archive 406 * extraction, however the -zweakextract flag overrides 407 * this default. 408 * 409 * If this symbol has already been bound to a versioned 410 * shared object, but the shared objects version is not 411 * available, then a definition of this symbol from 412 * within the archive is a better candidate. Similarly, 413 * if this symbol has been bound to a shared object, but 414 * the original reference expected hidden or protected 415 * visibility, then a definition of this symbol from 416 * within the archive is a better candidate. 417 */ 418 if (allexrt == 0) { 419 Boolean vers = TRUE; 420 Ifl_desc *ifl = sdp->sd_file; 421 422 sym = sdp->sd_sym; 423 424 if (sdp->sd_ref == REF_DYN_NEED) { 425 uchar_t vis; 426 427 if (ifl->ifl_vercnt) { 428 Word vndx; 429 Ver_index *vip; 430 431 vndx = sdp->sd_aux->sa_dverndx; 432 vip = &ifl->ifl_verndx[vndx]; 433 if ((vip->vi_flags & 434 FLG_VER_AVAIL) == 0) 435 vers = FALSE; 436 } 437 438 vis = ELF_ST_VISIBILITY(sym->st_other); 439 visible = sym_vis[vis]; 440 } 441 442 if (((ifl->ifl_flags & FLG_IF_NEEDED) == 0) || 443 (visible && vers && 444 (sym->st_shndx != SHN_UNDEF) && 445 (sym->st_shndx != SHN_COMMON)) || 446 ((ELF_ST_BIND(sym->st_info) == STB_WEAK) && 447 (!(ofl->ofl_flags1 & FLG_OF1_WEAKEXT)))) { 448 DBG_CALL(Dbg_syms_ar_entry(ofl->ofl_lml, 449 ndx, arsym)); 450 continue; 451 } 452 } 453 454 /* 455 * Determine if we have already extracted this member, 456 * and if so reuse the Ar_mem information. 457 */ 458 if ((amp = aup->au_mem) != 0) { 459 arelf = amp->am_elf; 460 arname = amp->am_name; 461 arpath = amp->am_path; 462 } else { 463 size_t len; 464 465 /* 466 * Set up a new elf descriptor for this member. 467 */ 468 if (elf_rand(adp->ad_elf, arsym->as_off) != 469 arsym->as_off) { 470 eprintf(ofl->ofl_lml, ERR_ELF, 471 MSG_INTL(MSG_ELF_ARMEM), name, 472 EC_WORD(arsym->as_off), ndx, 473 demangle(arsym->as_name)); 474 ofl->ofl_flags |= FLG_OF_FATAL; 475 return (0); 476 } 477 478 if ((arelf = elf_begin(fd, ELF_C_READ, 479 adp->ad_elf)) == NULL) { 480 eprintf(ofl->ofl_lml, ERR_ELF, 481 MSG_INTL(MSG_ELF_BEGIN), name); 482 ofl->ofl_flags |= FLG_OF_FATAL; 483 return (0); 484 } 485 486 /* 487 * Construct the member filename. 488 */ 489 if ((arhdr = elf_getarhdr(arelf)) == NULL) { 490 eprintf(ofl->ofl_lml, ERR_ELF, 491 MSG_INTL(MSG_ELF_GETARHDR), name); 492 ofl->ofl_flags |= FLG_OF_FATAL; 493 return (0); 494 } 495 arname = arhdr->ar_name; 496 497 /* 498 * Construct the members full pathname, using 499 * the format "%s(%s)". 500 */ 501 len = strlen(name) + strlen(arname) + 3; 502 if ((arpath = libld_malloc(len)) == 0) 503 return (S_ERROR); 504 (void) snprintf(arpath, len, 505 MSG_ORIG(MSG_FMT_ARMEM), name, arname); 506 507 /* 508 * Determine whether the support library wishes 509 * to process this open. See comments in 510 * ld_process_open(). 511 */ 512 ld_sup_open(ofl, (const char **)&arpath, 513 (const char **)&arname, &fd, 514 (FLG_IF_EXTRACT | FLG_IF_NEEDED), 515 &arelf, adp->ad_elf, arsym->as_off, 516 elf_kind(arelf)); 517 } 518 519 /* 520 * The symbol for which this archive member is being 521 * processed may provide a better alternative to the 522 * symbol that is presently known. Two cases are 523 * covered: 524 * 525 * i. The present symbol represents tentative data. 526 * The archive member may provide a data 527 * definition symbol. 528 * ii. The present symbol represents a reference that 529 * has seen a definition within a shared object 530 * dependency, but the reference expects to be 531 * reduced to hidden or protected visibility. 532 */ 533 if ((allexrt == 0) && 534 ((sym->st_shndx == SHN_COMMON) || 535 (visible == FALSE))) { 536 /* 537 * If we don't already have a member structure 538 * allocate one. 539 */ 540 if (!amp) { 541 if ((amp = libld_calloc(sizeof (Ar_mem), 542 1)) == 0) 543 return (S_ERROR); 544 amp->am_elf = arelf; 545 amp->am_name = arname; 546 amp->am_path = arpath; 547 } 548 DBG_CALL(Dbg_syms_ar_checking(ofl->ofl_lml, 549 ndx, arsym, arname)); 550 if ((err = process_member(amp, arsym->as_name, 551 sdp, ofl)) == S_ERROR) 552 return (S_ERROR); 553 554 /* 555 * If it turns out that we don't need this 556 * member simply initialize all other auxiliary 557 * entries that match this offset with this 558 * members address. In this way we can resuse 559 * this information if we recurse back to this 560 * symbol. 561 */ 562 if (err == 0) { 563 if (aup->au_mem == 0) 564 ld_ar_member(adp, arsym, 565 aup, amp); 566 continue; 567 } 568 } 569 570 /* 571 * Process the archive member. Retain any error for 572 * return to the caller. 573 */ 574 DBG_CALL(Dbg_syms_ar_resolve(ofl->ofl_lml, ndx, arsym, 575 arname, allexrt)); 576 if ((err = (uintptr_t)ld_process_ifl(arpath, NULL, fd, 577 arelf, (FLG_IF_EXTRACT | FLG_IF_NEEDED), ofl, 578 &_rej)) == S_ERROR) 579 return (S_ERROR); 580 581 /* 582 * If this member is rejected maintain the first 583 * rejection error for possible later display. Keep the 584 * member as extracted so that we don't try and process 585 * it again on a rescan. 586 */ 587 if (_rej.rej_type) { 588 if (rej.rej_type == 0) { 589 rej.rej_type = _rej.rej_type; 590 rej.rej_info = _rej.rej_info; 591 rej.rej_name = (const char *)arpath; 592 } 593 ld_ar_member(adp, arsym, aup, FLG_ARMEM_PROC); 594 continue; 595 } 596 597 /* 598 * Indicate that the extracted member is in use. This 599 * enables debugging diags, and indicates that a further 600 * rescan of all archives may be necessary. 601 */ 602 found = 1; 603 ofl->ofl_flags1 |= FLG_OF1_EXTRACT; 604 adp->ad_flags |= FLG_ARD_EXTRACT; 605 606 /* 607 * If not under '-z allextract' signal the need to 608 * rescan this archive. 609 */ 610 if (allexrt == 0) 611 again = 1; 612 613 ld_ar_member(adp, arsym, aup, FLG_ARMEM_PROC); 614 DBG_CALL(Dbg_util_nl(ofl->ofl_lml, DBG_NL_STD)); 615 } 616 } while (again); 617 618 /* 619 * If no objects have been found in the archive test for any rejections 620 * and if one had occurred issue a warning - its possible a user has 621 * pointed at an archive containing the wrong class of elf members. 622 */ 623 if ((found == 0) && (rej.rej_type)) { 624 Conv_reject_desc_buf_t rej_buf; 625 626 eprintf(ofl->ofl_lml, ERR_WARNING, 627 MSG_INTL(reject[rej.rej_type]), 628 rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN), 629 conv_reject_desc(&rej, &rej_buf, ld_targ.t_m.m_mach)); 630 } 631 632 /* 633 * If this archive was extracted by -z allextract, the ar_aux table 634 * and elf descriptor can be freed. Set ad_elf to NULL to mark the 635 * archive is completely processed. 636 */ 637 if (allexrt) { 638 (void) elf_end(adp->ad_elf); 639 adp->ad_elf = (Elf *)NULL; 640 } 641 642 return (1); 643 } 644