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 (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. 27 */ 28 29 /* 30 * Library processing 31 */ 32 #include <stdio.h> 33 #include <string.h> 34 #include <errno.h> 35 #include <ar.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 * exit: 61 * Returns 1 if there is a match, 0 if no match is seen, and S_ERROR if an 62 * error occurred. 63 */ 64 static uintptr_t 65 process_member(Ar_mem *amp, const char *name, Sym_desc *sdp, Ofl_desc *ofl) 66 { 67 Sym *syms, *osym = sdp->sd_sym; 68 Xword symn, cnt; 69 char *strs; 70 71 /* 72 * Find the first symbol table in the archive member, obtain its 73 * data buffer and determine the number of global symbols (Note, 74 * there must be a symbol table present otherwise the archive would 75 * never have been able to generate its own symbol entry for this 76 * member). 77 */ 78 if (amp->am_syms == NULL) { 79 Elf_Scn *scn = NULL; 80 Shdr *shdr; 81 Elf_Data *data; 82 83 while (scn = elf_nextscn(amp->am_elf, scn)) { 84 if ((shdr = elf_getshdr(scn)) == NULL) { 85 ld_eprintf(ofl, ERR_ELF, 86 MSG_INTL(MSG_ELF_GETSHDR), amp->am_path); 87 return (S_ERROR); 88 } 89 if ((shdr->sh_type == SHT_SYMTAB) || 90 (shdr->sh_type == SHT_DYNSYM)) 91 break; 92 } 93 if ((data = elf_getdata(scn, NULL)) == NULL) { 94 ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETDATA), 95 amp->am_path); 96 return (S_ERROR); 97 } 98 syms = (Sym *)data->d_buf; 99 syms += shdr->sh_info; 100 symn = shdr->sh_size / shdr->sh_entsize; 101 symn -= shdr->sh_info; 102 103 /* 104 * Get the data for the associated string table. 105 */ 106 if ((scn = elf_getscn(amp->am_elf, (size_t)shdr->sh_link)) == 107 NULL) { 108 ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN), 109 amp->am_path); 110 return (S_ERROR); 111 } 112 if ((data = elf_getdata(scn, NULL)) == NULL) { 113 ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETDATA), 114 amp->am_path); 115 return (S_ERROR); 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) == 0) 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 * Unless, -z allextract is specified, get the archive symbol table 195 * if one exists, and ignore the file with a warning message otherwise. 196 */ 197 if (ofl->ofl_flags1 & FLG_OF1_ALLEXRT) { 198 start = NULL; 199 } else if ((start = elf_getarsym(elf, &number)) == NULL) { 200 if (elf_errno()) 201 ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETARSYM), 202 name); 203 else 204 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ELF_ARSYM), 205 name); 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))) == NULL) 213 return ((Ar_desc *)S_ERROR); 214 adp->ad_name = name; 215 adp->ad_elf = elf; 216 adp->ad_start = start; 217 if (start) { 218 adp->ad_aux = libld_calloc(sizeof (Ar_aux), number); 219 if (adp->ad_aux == NULL) 220 return ((Ar_desc *)S_ERROR); 221 } else { 222 adp->ad_aux = NULL; 223 } 224 225 /* 226 * Retain any command line options that are applicable to archive 227 * extraction in case we have to rescan this archive later. 228 */ 229 adp->ad_flags = ofl->ofl_flags1 & MSK_OF1_ARCHIVE; 230 231 ofl->ofl_arscnt++; 232 233 /* 234 * Add this new descriptor to the list of archives. 235 */ 236 if (aplist_append(&ofl->ofl_ars, adp, AL_CNT_OFL_LIBS) == NULL) 237 return ((Ar_desc *)S_ERROR); 238 else 239 return (adp); 240 } 241 242 /* 243 * For each archive descriptor, maintain an `Ar_aux' table to parallel the 244 * archive symbol table (returned from elf_getarsym(3e)). Use this table to 245 * hold a `Sym_desc' for each symbol (thus reducing the number of 246 * ld_sym_find()'s), and to hold the `Ar_mem' pointer. The `Ar_mem' element 247 * can have one of three values indicating the state of the archive member 248 * associated with the offset for this symbol table entry: 249 * 250 * 0 indicates that the member has not been processed. 251 * 252 * FLG_ARMEM_PROC 253 * indicates that the member has been processed. 254 * 255 * addr indicates that the member has been investigated to determine if 256 * it contained a symbol definition we need, but was found not to 257 * be a candidate for extraction. In this case the members 258 * structure is maintained for possible later use. 259 * 260 * Each time we process an archive member we use its offset value to scan this 261 * `Ar_aux' list. If the member has been extracted, each entry with the same 262 * offset has its `Ar_mem' pointer set to FLG_ARMEM_PROC. Thus if we cycle back 263 * through the archive symbol table we will ignore these symbols as they will 264 * have already been added to the output image. If a member has been processed 265 * but found not to contain a symbol we need, each entry with the same offset 266 * has its `Ar_mem' pointer set to the member structures address. 267 */ 268 void 269 ld_ar_member(Ar_desc * adp, Elf_Arsym * arsym, Ar_aux * aup, Ar_mem * amp) 270 { 271 Elf_Arsym * _arsym = arsym; 272 Ar_aux * _aup = aup; 273 size_t _off = arsym->as_off; 274 275 if (adp->ad_start == NULL) 276 return; 277 278 /* 279 * Note: This algorithm assumes that the archive symbol table is 280 * built from the member objects, in the same order as those 281 * members are found in the archive. As such, the symbols for a 282 * given member will all cluster together. If this is not true, 283 * we will fail to mark some symbols. In that case, archive 284 * processing may be less efficient than it would be otherwise. 285 */ 286 287 if (_arsym != adp->ad_start) { 288 do { 289 _arsym--; 290 _aup--; 291 if (_arsym->as_off != _off) 292 break; 293 _aup->au_mem = amp; 294 } while (_arsym != adp->ad_start); 295 } 296 297 _arsym = arsym; 298 _aup = aup; 299 300 do { 301 if (_arsym->as_off != _off) 302 break; 303 _aup->au_mem = amp; 304 _arsym++; 305 _aup++; 306 } while (_arsym->as_name); 307 } 308 309 /* 310 * Return the archive member's name. 311 * 312 * entry: 313 * name - Name of archive 314 * arelf - ELF descriptor for archive member. 315 * ofl - output descriptor 316 * 317 * exit: 318 * Returns pointer to archive member name on success, NULL on error. 319 */ 320 static const char * 321 ar_member_name(const char *name, Elf *arelf, Ofl_desc *ofl) 322 { 323 Elf_Arhdr *arhdr; 324 325 if ((arhdr = elf_getarhdr(arelf)) == NULL) { 326 ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETARHDR), name); 327 return (NULL); 328 } 329 return (arhdr->ar_name); 330 } 331 332 /* 333 * Construct the member's full pathname, using the format "%s(%s)". 334 * 335 * entry: 336 * name - Name of archive 337 * arname - Name of archive member 338 * ofl - output descriptor 339 * exit: 340 * Returns pointer to constructed pathname on success, NULL on error. 341 */ 342 static const char * 343 ar_member_path(const char *name, const char *arname, Ofl_desc *ofl) 344 { 345 size_t len; 346 char *path; 347 348 len = strlen(name) + strlen(arname) + 3; 349 if ((path = libld_malloc(len)) == NULL) { 350 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_MALLOC), 351 strerror(errno)); 352 return (NULL); 353 } 354 (void) snprintf(path, len, MSG_ORIG(MSG_FMT_ARMEM), name, arname); 355 return (path); 356 } 357 358 /* 359 * Input the specified archive member to the link. 360 * 361 * entry: 362 * fd - Open file descriptor for archive 363 * adp - Archive descriptor 364 * ofl - output descriptor 365 * arelf - ELF descriptor for archive member. 366 * arpath - Address of pointer to be set to constructed path name 367 * for object. 368 * rej - Rejection descriptor to pass to ld_process_ifl(). 369 * 370 * exit: 371 * This routine can return one of the following: 372 * S_ERROR: Fatal error encountered. 373 * 0: Object was rejected, and should be ignored. 374 * rej will carry the rejection information. 375 * 1: The archive member has been input to the link. 376 */ 377 static uintptr_t 378 ar_input(int fd, Ar_desc *adp, Ofl_desc *ofl, Elf *arelf, 379 const char *arpath, Rej_desc *rej) 380 { 381 Rej_desc _rej = { 0 }; 382 383 switch (ld_process_ifl(arpath, NULL, fd, arelf, 384 (FLG_IF_EXTRACT | FLG_IF_NEEDED), ofl, &_rej, NULL)) { 385 case S_ERROR: 386 return (S_ERROR); 387 case 0: 388 /* 389 * If this member is rejected maintain the first rejection 390 * error for possible later display. 391 */ 392 if (_rej.rej_type) { 393 if (rej->rej_type == 0) { 394 rej->rej_type = _rej.rej_type; 395 rej->rej_info = _rej.rej_info; 396 rej->rej_name = arpath; 397 } 398 (void) elf_end(arelf); 399 return (0); 400 } 401 } 402 403 /* 404 * Indicate that the extracted member is in use. This 405 * enables debugging diags, and indicates that a further 406 * rescan of all archives may be necessary. 407 */ 408 ofl->ofl_flags1 |= FLG_OF1_EXTRACT; 409 adp->ad_flags |= FLG_ARD_EXTRACT; 410 return (1); 411 } 412 413 /* 414 * Data structure to indicate whether a symbol is visible for the purpose 415 * of archive extraction. 416 */ 417 static const Boolean 418 sym_vis[STV_NUM] = { 419 TRUE, /* STV_DEFAULT */ 420 FALSE, /* STV_INTERNAL */ 421 FALSE, /* STV_HIDDEN */ 422 FALSE, /* STV_PROTECTED */ 423 TRUE, /* STV_EXPORTED */ 424 TRUE, /* STV_SINGLETON */ 425 FALSE /* STV_ELIMINATE */ 426 }; 427 #if STV_NUM != (STV_ELIMINATE + 1) 428 #error "STV_NUM has grown. Update sym_vis[]." 429 #endif 430 431 /* 432 * Read the archive symbol table. For each symbol in the table, determine 433 * whether that symbol satisfies an unresolved reference, tentative reference, 434 * or a reference that expects hidden or protected visibility. If so, the 435 * corresponding object from the archive is processed. The archive symbol 436 * table is searched until we go through a complete pass without satisfying any 437 * unresolved symbols 438 * 439 * entry: 440 * name - Name of archive 441 * fd - Open file descriptor for archive 442 * adp - Archive descriptor 443 * ofl - output descriptor 444 * found - Address of variable to set to TRUE if any objects are extracted 445 * rej - Rejection descriptor to pass to ld_process_ifl(). 446 * 447 * exit: 448 * Returns FALSE on fatal error. On success, *found will be TRUE 449 * if any object was extracted, rej will be set if any object 450 * was rejected, and TRUE is returned. 451 */ 452 static Boolean 453 ar_extract_bysym(const char *name, int fd, Ar_desc *adp, 454 Ofl_desc *ofl, Boolean *found, Rej_desc *rej) 455 { 456 Elf_Arsym * arsym; 457 Elf * arelf; 458 Ar_aux * aup; 459 Sym_desc * sdp; 460 const char *arname, *arpath; 461 Boolean again = FALSE; 462 uintptr_t err; 463 464 /* 465 * An archive without a symbol table should not reach this function, 466 * because it can only get past ld_ar_setup() in the case where 467 * the archive is first seen under the influence of '-z allextract'. 468 * That will cause the entire archive to be extracted, and any 469 * subsequent reference to the archive will be ignored by 470 * ld_process_archive(). 471 */ 472 if (adp->ad_start == NULL) { 473 assert(adp->ad_start != NULL); 474 return (TRUE); 475 } 476 477 /* 478 * Loop through archive symbol table until we make a complete pass 479 * without satisfying an unresolved reference. For each archive 480 * symbol, see if there is a symbol with the same name in ld's 481 * symbol table. If so, and if that symbol is still unresolved or 482 * tentative, process the corresponding archive member. 483 */ 484 do { 485 DBG_CALL(Dbg_file_ar(ofl->ofl_lml, name, again)); 486 DBG_CALL(Dbg_syms_ar_title(ofl->ofl_lml, name, again)); 487 again = FALSE; 488 489 for (arsym = adp->ad_start, aup = adp->ad_aux; arsym->as_name; 490 ++arsym, ++aup) { 491 Ar_mem *amp; 492 Sym *sym; 493 Boolean visible = TRUE; 494 Boolean vers; 495 Ifl_desc *ifl; 496 497 /* 498 * If the auxiliary members value indicates that this 499 * member has been processed then this symbol will have 500 * been added to the output file image already or the 501 * object was rejected in which case we don't want to 502 * process it again. 503 */ 504 if (aup->au_mem == FLG_ARMEM_PROC) 505 continue; 506 507 /* 508 * If the auxiliary symbol element is non-zero lookup 509 * the symbol from the internal symbol table. 510 */ 511 if ((sdp = aup->au_syms) == NULL) { 512 if ((sdp = ld_sym_find(arsym->as_name, 513 /* LINTED */ 514 (Word)arsym->as_hash, NULL, ofl)) == NULL) { 515 DBG_CALL(Dbg_syms_ar_skip(ofl->ofl_lml, 516 name, arsym)); 517 continue; 518 } 519 aup->au_syms = sdp; 520 } 521 522 /* 523 * With '-z allextract', all members will be extracted. 524 * 525 * This archive member is a candidate for extraction if 526 * the internal symbol originates from an explicit file, 527 * and represents an undefined or tentative symbol. 528 * 529 * By default, weak references do not cause archive 530 * extraction, however the -zweakextract flag overrides 531 * this default. 532 * 533 * If this symbol has already been bound to a versioned 534 * shared object, but the shared objects version is not 535 * available, then a definition of this symbol from 536 * within the archive is a better candidate. Similarly, 537 * if this symbol has been bound to a shared object, but 538 * the original reference expected hidden or protected 539 * visibility, then a definition of this symbol from 540 * within the archive is a better candidate. 541 */ 542 vers = TRUE; 543 ifl = sdp->sd_file; 544 545 sym = sdp->sd_sym; 546 547 if (sdp->sd_ref == REF_DYN_NEED) { 548 uchar_t vis; 549 550 if (ifl->ifl_vercnt) { 551 Word vndx; 552 Ver_index *vip; 553 554 vndx = sdp->sd_aux->sa_dverndx; 555 vip = &ifl->ifl_verndx[vndx]; 556 if (!(vip->vi_flags & FLG_VER_AVAIL)) 557 vers = FALSE; 558 } 559 560 vis = ELF_ST_VISIBILITY(sym->st_other); 561 visible = sym_vis[vis]; 562 } 563 564 if (((ifl->ifl_flags & FLG_IF_NEEDED) == 0) || 565 (visible && vers && (sym->st_shndx != SHN_UNDEF) && 566 (sym->st_shndx != SHN_COMMON)) || 567 ((ELF_ST_BIND(sym->st_info) == STB_WEAK) && 568 (!(ofl->ofl_flags1 & FLG_OF1_WEAKEXT)))) { 569 DBG_CALL(Dbg_syms_ar_skip(ofl->ofl_lml, 570 name, arsym)); 571 continue; 572 } 573 574 /* 575 * Determine if we have already extracted this member, 576 * and if so reuse the Ar_mem information. 577 */ 578 if ((amp = aup->au_mem) != 0) { 579 arelf = amp->am_elf; 580 arname = amp->am_name; 581 arpath = amp->am_path; 582 } else { 583 /* 584 * Set up a new elf descriptor for this member. 585 */ 586 if (elf_rand(adp->ad_elf, arsym->as_off) != 587 arsym->as_off) { 588 ld_eprintf(ofl, ERR_ELF, 589 MSG_INTL(MSG_ELF_ARMEM), name, 590 EC_WORD(arsym->as_off), 591 demangle(arsym->as_name)); 592 return (FALSE); 593 } 594 595 if ((arelf = elf_begin(fd, ELF_C_READ, 596 adp->ad_elf)) == NULL) { 597 ld_eprintf(ofl, ERR_ELF, 598 MSG_INTL(MSG_ELF_BEGIN), name); 599 return (FALSE); 600 } 601 602 /* Get member filename */ 603 if ((arname = ar_member_name(name, arelf, 604 ofl)) == NULL) 605 return (FALSE); 606 607 /* Construct the member's full pathname */ 608 if ((arpath = ar_member_path(name, arname, 609 ofl)) == NULL) 610 return (FALSE); 611 612 /* 613 * Determine whether the support libraries wish 614 * to process this open. See comments in 615 * ld_process_open(). 616 */ 617 ld_sup_open(ofl, &arpath, &arname, &fd, 618 (FLG_IF_EXTRACT | FLG_IF_NEEDED), 619 &arelf, adp->ad_elf, arsym->as_off, 620 elf_kind(arelf)); 621 if (arelf == NULL) { 622 /* Ignore this archive member */ 623 aup->au_mem = FLG_ARMEM_PROC; 624 continue; 625 } 626 } 627 628 /* 629 * The symbol for which this archive member is being 630 * processed may provide a better alternative to the 631 * symbol that is presently known. Two cases are 632 * covered: 633 * 634 * i. The present symbol represents tentative data. 635 * The archive member may provide a data 636 * definition symbol. 637 * ii. The present symbol represents a reference that 638 * has seen a definition within a shared object 639 * dependency, but the reference expects to be 640 * reduced to hidden or protected visibility. 641 */ 642 if ((sym->st_shndx == SHN_COMMON) || 643 (visible == FALSE)) { 644 /* 645 * If we don't already have a member structure 646 * allocate one. 647 */ 648 if (!amp) { 649 if ((amp = libld_calloc(sizeof (Ar_mem), 650 1)) == NULL) 651 return (FALSE); 652 amp->am_elf = arelf; 653 amp->am_name = arname; 654 amp->am_path = arpath; 655 } 656 DBG_CALL(Dbg_syms_ar_checking(ofl->ofl_lml, 657 name, arname, arsym)); 658 if ((err = process_member(amp, arsym->as_name, 659 sdp, ofl)) == S_ERROR) 660 return (FALSE); 661 662 /* 663 * If it turns out that we don't need this 664 * member simply initialize all other auxiliary 665 * entries that match this offset with this 666 * members address. In this way we can resuse 667 * this information if we recurse back to this 668 * symbol. 669 */ 670 if (err == 0) { 671 if (aup->au_mem == NULL) 672 ld_ar_member(adp, arsym, 673 aup, amp); 674 continue; 675 } 676 } 677 678 /* 679 * Process the archive member. Retain any error for 680 * return to the caller. 681 */ 682 DBG_CALL(Dbg_syms_ar_resolve(ofl->ofl_lml, 683 name, arname, arsym)); 684 switch (ar_input(fd, adp, ofl, arelf, arpath, 685 rej)) { 686 case S_ERROR: 687 return (FALSE); 688 case 0: 689 /* 690 * Mark the member as extracted so that we 691 * don't try and process it again on a rescan. 692 */ 693 ld_ar_member(adp, arsym, aup, FLG_ARMEM_PROC); 694 continue; 695 } 696 697 /* 698 * Note that this archive has contributed something 699 * during this specific operation, and also signal 700 * the need to rescan the archive. 701 */ 702 *found = again = TRUE; 703 704 ld_ar_member(adp, arsym, aup, FLG_ARMEM_PROC); 705 } 706 } while (again); 707 708 return (TRUE); 709 } 710 711 712 /* 713 * Extract every object in the given archive directly without going through 714 * the symbol table. 715 * 716 * entry: 717 * name - Name of archive 718 * fd - Open file descriptor for archive 719 * adp - Archive descriptor 720 * ofl - output descriptor 721 * found - Address of variable to set to TRUE if any objects are extracted 722 * rej - Rejection descriptor to pass to ld_process_ifl(). 723 * 724 * exit: 725 * Returns FALSE on fatal error. On success, *found will be TRUE 726 * if any object was extracted, rej will be set if any object 727 * was rejected, and TRUE is returned. 728 */ 729 static Boolean 730 ar_extract_all(const char *name, int fd, Ar_desc *adp, Ofl_desc *ofl, 731 Boolean *found, Rej_desc *rej) 732 { 733 Elf_Cmd cmd = ELF_C_READ; 734 Elf *arelf; 735 const char *arname, *arpath; 736 size_t off, next_off; 737 738 DBG_CALL(Dbg_file_ar(ofl->ofl_lml, name, FALSE)); 739 740 while ((arelf = elf_begin(fd, cmd, adp->ad_elf)) != NULL) { 741 /* 742 * Call elf_next() so that the next call to elf_begin() will 743 * fetch the archive member following this one. We do this now 744 * because it simplifies the logic below, and because the 745 * support libraries called below can set our handle to NULL. 746 */ 747 cmd = elf_next(arelf); 748 749 /* Get member filename */ 750 if ((arname = ar_member_name(name, arelf, ofl)) == NULL) 751 return (FALSE); 752 753 /* 754 * Skip the symbol table, string table, or any other special 755 * archive member. These all start with a '/' character. 756 */ 757 if (*arname == '/') { 758 (void) elf_end(arelf); 759 continue; 760 } 761 762 /* Obtain archive member offset within the file */ 763 off = _elf_getarhdrbase(arelf); 764 765 /* 766 * ld_sup_open() will reset the current iteration point for 767 * the archive to point at this member rather than the next 768 * one for the benefit of the support libraries. Since 769 * this loop relies on the current position not changing 770 * underneath it, we save and restore the current 771 * position around the support library call. 772 */ 773 next_off = _elf_getnextoff(adp->ad_elf); 774 775 /* Construct the member's full pathname */ 776 if ((arpath = ar_member_path(name, arname, ofl)) == NULL) 777 return (FALSE); 778 779 /* 780 * Determine whether the support libraries wish to process 781 * this open. See comments in ld_process_open(). 782 */ 783 ld_sup_open(ofl, &arpath, &arname, &fd, 784 (FLG_IF_EXTRACT | FLG_IF_NEEDED), &arelf, adp->ad_elf, 785 off, elf_kind(arelf)); 786 (void) elf_rand(adp->ad_elf, next_off); 787 if (arelf == NULL) 788 continue; 789 790 DBG_CALL(Dbg_syms_ar_force(ofl->ofl_lml, name, arname)); 791 switch (ar_input(fd, adp, ofl, arelf, arpath, rej)) { 792 case S_ERROR: 793 return (FALSE); 794 case 0: 795 continue; 796 } 797 798 *found = TRUE; 799 800 } 801 802 /* 803 * As this archive was extracted by -z allextract, the ar_aux table 804 * and elf descriptor can be freed. Set ad_elf to NULL to mark the 805 * archive is completely processed. 806 */ 807 (void) elf_end(adp->ad_elf); 808 adp->ad_elf = NULL; 809 810 return (TRUE); 811 } 812 813 814 /* 815 * Process the given archive and extract objects for inclusion into 816 * the link. 817 * 818 * entry: 819 * name - Name of archive 820 * fd - Open file descriptor for archive 821 * adp - Archive descriptor 822 * ofl - output descriptor 823 * 824 * exit: 825 * Returns FALSE on fatal error, TRUE otherwise. 826 */ 827 Boolean 828 ld_process_archive(const char *name, int fd, Ar_desc *adp, Ofl_desc *ofl) 829 { 830 Boolean found = FALSE; 831 Rej_desc rej = { 0 }; 832 833 /* 834 * If a fatal error condition has been set there's really no point in 835 * processing the archive further. Having got to this point we have at 836 * least established that the archive exists (thus verifying that the 837 * command line options that got us to this archive are correct). Very 838 * large archives can take a significant time to process, therefore 839 * continuing on from here may significantly delay the fatal error 840 * message the user is already set to receive. 841 */ 842 if (ofl->ofl_flags & FLG_OF_FATAL) 843 return (TRUE); 844 845 /* 846 * If this archive was processed with -z allextract, then all members 847 * have already been extracted. 848 */ 849 if (adp->ad_elf == NULL) 850 return (TRUE); 851 852 if (ofl->ofl_flags1 & FLG_OF1_ALLEXRT) { 853 if (!ar_extract_all(name, fd, adp, ofl, &found, &rej)) 854 return (FALSE); 855 } else { 856 if (!ar_extract_bysym(name, fd, adp, ofl, &found, &rej)) 857 return (FALSE); 858 } 859 860 /* 861 * If no objects have been found in the archive test for any rejections 862 * and if one had occurred issue a warning - its possible a user has 863 * pointed at an archive containing the wrong class of elf members. 864 */ 865 if ((found == 0) && rej.rej_type) { 866 Conv_reject_desc_buf_t rej_buf; 867 868 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(reject[rej.rej_type]), 869 rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN), 870 conv_reject_desc(&rej, &rej_buf, ld_targ.t_m.m_mach)); 871 } 872 873 874 return (TRUE); 875 } 876