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