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