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