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