Home | History | Annotate | Download | only in common
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     27  * Use is subject to license terms.
     28  */
     29 
     30 /*
     31  * Library processing
     32  */
     33 #include	<stdio.h>
     34 #include	<string.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 static int
     60 process_member(Ar_mem *amp, const char *name, Sym_desc *sdp, Ofl_desc *ofl)
     61 {
     62 	Sym	*syms, *osym = sdp->sd_sym;
     63 	Xword	symn, cnt;
     64 	char 	*strs;
     65 
     66 	/*
     67 	 * Find the first symbol table in the archive member, obtain its
     68 	 * data buffer and determine the number of global symbols (Note,
     69 	 * there must be a symbol table present otherwise the archive would
     70 	 * never have been able to generate its own symbol entry for this
     71 	 * member).
     72 	 */
     73 	if (amp->am_syms == NULL) {
     74 		Elf_Scn		*scn = NULL;
     75 		Shdr		*shdr;
     76 		Elf_Data	*data;
     77 
     78 		while (scn = elf_nextscn(amp->am_elf, scn)) {
     79 			if ((shdr = elf_getshdr(scn)) == NULL) {
     80 				eprintf(ofl->ofl_lml, ERR_ELF,
     81 				    MSG_INTL(MSG_ELF_GETSHDR), amp->am_path);
     82 				ofl->ofl_flags |= FLG_OF_FATAL;
     83 				return (0);
     84 			}
     85 			if ((shdr->sh_type == SHT_SYMTAB) ||
     86 			    (shdr->sh_type == SHT_DYNSYM))
     87 				break;
     88 		}
     89 		if ((data = elf_getdata(scn, NULL)) == NULL) {
     90 			eprintf(ofl->ofl_lml, ERR_ELF,
     91 			    MSG_INTL(MSG_ELF_GETDATA), amp->am_path);
     92 			ofl->ofl_flags |= FLG_OF_FATAL;
     93 			return (0);
     94 		}
     95 		syms = (Sym *)data->d_buf;
     96 		syms += shdr->sh_info;
     97 		symn = shdr->sh_size / shdr->sh_entsize;
     98 		symn -= shdr->sh_info;
     99 
    100 		/*
    101 		 * Get the data for the associated string table.
    102 		 */
    103 		if ((scn = elf_getscn(amp->am_elf, (size_t)shdr->sh_link)) ==
    104 		    NULL) {
    105 			eprintf(ofl->ofl_lml, ERR_ELF,
    106 			    MSG_INTL(MSG_ELF_GETSCN), amp->am_path);
    107 			ofl->ofl_flags |= FLG_OF_FATAL;
    108 			return (0);
    109 		}
    110 		if ((data = elf_getdata(scn, NULL)) == NULL) {
    111 			eprintf(ofl->ofl_lml, ERR_ELF,
    112 			    MSG_INTL(MSG_ELF_GETDATA), amp->am_path);
    113 			ofl->ofl_flags |= FLG_OF_FATAL;
    114 			return (0);
    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 	 * Get the archive symbol table. If this fails, we will
    194 	 * ignore this file with a warning message.
    195 	 */
    196 	if ((start = elf_getarsym(elf, &number)) == NULL) {
    197 		if (elf_errno()) {
    198 			eprintf(ofl->ofl_lml, ERR_ELF,
    199 			    MSG_INTL(MSG_ELF_GETARSYM), name);
    200 			ofl->ofl_flags |= FLG_OF_FATAL;
    201 		} else
    202 			eprintf(ofl->ofl_lml, ERR_WARNING,
    203 			    MSG_INTL(MSG_ELF_ARSYM), name);
    204 
    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 ((adp->ad_aux = libld_calloc(sizeof (Ar_aux), number)) == NULL)
    217 		return ((Ar_desc *)S_ERROR);
    218 
    219 	/*
    220 	 * Retain any command line options that are applicable to archive
    221 	 * extraction in case we have to rescan this archive later.
    222 	 */
    223 	adp->ad_flags = ofl->ofl_flags1 & MSK_OF1_ARCHIVE;
    224 
    225 	ofl->ofl_arscnt++;
    226 
    227 	/*
    228 	 * Add this new descriptor to the list of archives.
    229 	 */
    230 	if (aplist_append(&ofl->ofl_ars, adp, AL_CNT_OFL_LIBS) == NULL)
    231 		return ((Ar_desc *)S_ERROR);
    232 	else
    233 		return (adp);
    234 }
    235 
    236 /*
    237  * For each archive descriptor, maintain an `Ar_aux' table to parallel the
    238  * archive symbol table (returned from elf_getarsym(3e)).  Use this table to
    239  * hold a `Sym_desc' for each symbol (thus reducing the number of
    240  * ld_sym_find()'s), and to hold the `Ar_mem' pointer.  The `Ar_mem' element
    241  * can have one of three values indicating the state of the archive member
    242  * associated with the offset for this symbol table entry:
    243  *
    244  *  0		indicates that the member has not been processed.
    245  *
    246  *  FLG_ARMEM_PROC
    247  *		indicates that the member has been processed.
    248  *
    249  *  addr	indicates that the member has been investigated to determine if
    250  *		it contained a symbol definition we need, but was found not to
    251  *		be a candidate for extraction.  In this case the members
    252  *		structure is maintained for possible later use.
    253  *
    254  * Each time we process an archive member we use its offset value to scan this
    255  * `Ar_aux' list.  If the member has been extracted, each entry with the same
    256  * offset has its `Ar_mem' pointer set to FLG_ARMEM_PROC.  Thus if we cycle back
    257  * through the archive symbol table we will ignore these symbols as they will
    258  * have already been added to the output image.  If a member has been processed
    259  * but found not to contain a symbol we need, each entry with the same offset
    260  * has its `Ar_mem' pointer set to the member structures address.
    261  */
    262 void
    263 ld_ar_member(Ar_desc * adp, Elf_Arsym * arsym, Ar_aux * aup, Ar_mem * amp)
    264 {
    265 	Elf_Arsym *	_arsym = arsym;
    266 	Ar_aux *	_aup = aup;
    267 	size_t		_off = arsym->as_off;
    268 
    269 	if (_arsym != adp->ad_start) {
    270 		do {
    271 			_arsym--;
    272 			_aup--;
    273 			if (_arsym->as_off != _off)
    274 				break;
    275 			_aup->au_mem = amp;
    276 		} while (_arsym != adp->ad_start);
    277 	}
    278 
    279 	_arsym = arsym;
    280 	_aup = aup;
    281 
    282 	do {
    283 		if (_arsym->as_off != _off)
    284 			break;
    285 		_aup->au_mem = amp;
    286 		_arsym++;
    287 		_aup++;
    288 	} while (_arsym->as_name);
    289 }
    290 
    291 /*
    292  * Data structure to indicate whether a symbol is visible for the purpose
    293  * of archive extraction.
    294  */
    295 static const Boolean
    296 sym_vis[STV_NUM] = {
    297 	TRUE,		/* STV_DEFAULT */
    298 	FALSE,		/* STV_INTERNAL */
    299 	FALSE,		/* STV_HIDDEN */
    300 	FALSE,		/* STV_PROTECTED */
    301 	TRUE,		/* STV_EXPORTED */
    302 	TRUE,		/* STV_SINGLETON */
    303 	FALSE		/* STV_ELIMINATE */
    304 };
    305 #if STV_NUM != (STV_ELIMINATE + 1)
    306 #error "STV_NUM has grown. Update sym_vis[]."
    307 #endif
    308 
    309 /*
    310  * Read the archive symbol table.  For each symbol in the table, determine
    311  * whether that symbol satisfies an unresolved reference, tentative reference,
    312  * or a reference that expects hidden or protected visibility.  If so, the
    313  * corresponding object from the archive is processed.  The archive symbol
    314  * table is searched until we go through a complete pass without satisfying any
    315  * unresolved symbols
    316  */
    317 uintptr_t
    318 ld_process_archive(const char *name, int fd, Ar_desc *adp, Ofl_desc *ofl)
    319 {
    320 	Elf_Arsym *	arsym;
    321 	Elf_Arhdr *	arhdr;
    322 	Elf *		arelf;
    323 	Ar_aux *	aup;
    324 	Sym_desc *	sdp;
    325 	char 		*arname, *arpath;
    326 	Xword		ndx;
    327 	int		found, again;
    328 	int		allexrt = (ofl->ofl_flags1 & FLG_OF1_ALLEXRT) != 0;
    329 	uintptr_t	err;
    330 	Rej_desc	rej = { 0 };
    331 
    332 	/*
    333 	 * If a fatal error condition has been set there's really no point in
    334 	 * processing the archive further.  Having got to this point we have at
    335 	 * least established that the archive exists (thus verifying that the
    336 	 * command line options that got us to this archive are correct).  Very
    337 	 * large archives can take a significant time to process, therefore
    338 	 * continuing on from here may significantly delay the fatal error
    339 	 * message the user is already set to receive.
    340 	 */
    341 	if (ofl->ofl_flags & FLG_OF_FATAL)
    342 		return (1);
    343 
    344 	/*
    345 	 * If this archive was processed with -z allextract, then all members
    346 	 * have already been extracted.
    347 	 */
    348 	if (adp->ad_elf == NULL)
    349 		return (1);
    350 
    351 	/*
    352 	 * Loop through archive symbol table until we make a complete pass
    353 	 * without satisfying an unresolved reference.  For each archive
    354 	 * symbol, see if there is a symbol with the same name in ld's
    355 	 * symbol table.  If so, and if that symbol is still unresolved or
    356 	 * tentative, process the corresponding archive member.
    357 	 */
    358 	found = again = 0;
    359 	do {
    360 		DBG_CALL(Dbg_file_ar(ofl->ofl_lml, name, again));
    361 		DBG_CALL(Dbg_syms_ar_title(ofl->ofl_lml, name, again));
    362 
    363 		ndx = again = 0;
    364 		for (arsym = adp->ad_start, aup = adp->ad_aux; arsym->as_name;
    365 		    ++arsym, ++aup, ndx++) {
    366 			Rej_desc	_rej = { 0 };
    367 			Ar_mem		*amp;
    368 			Sym		*sym;
    369 			Boolean		visible = TRUE;
    370 
    371 			/*
    372 			 * If the auxiliary members value indicates that this
    373 			 * member has been processed then this symbol will have
    374 			 * been added to the output file image already or the
    375 			 * object was rejected in which case we don't want to
    376 			 * process it again.
    377 			 */
    378 			if (aup->au_mem == FLG_ARMEM_PROC)
    379 				continue;
    380 
    381 			/*
    382 			 * If the auxiliary symbol element is non-zero lookup
    383 			 * the symbol from the internal symbol table.
    384 			 * (But you skip this if allextract is specified.)
    385 			 */
    386 			if ((allexrt == 0) && ((sdp = aup->au_syms) == NULL)) {
    387 				if ((sdp = ld_sym_find(arsym->as_name,
    388 				    /* LINTED */
    389 				    (Word)arsym->as_hash, NULL, ofl)) == NULL) {
    390 					DBG_CALL(Dbg_syms_ar_entry(ofl->ofl_lml,
    391 					    ndx, arsym));
    392 					continue;
    393 				}
    394 				aup->au_syms = sdp;
    395 			}
    396 
    397 			/*
    398 			 * With '-z allextract', all members will be extracted.
    399 			 *
    400 			 * This archive member is a candidate for extraction if
    401 			 * the internal symbol originates from an explicit file,
    402 			 * and represents an undefined or tentative symbol.
    403 			 *
    404 			 * By default, weak references do not cause archive
    405 			 * extraction, however the -zweakextract flag overrides
    406 			 * this default.
    407 			 *
    408 			 * If this symbol has already been bound to a versioned
    409 			 * shared object, but the shared objects version is not
    410 			 * available, then a definition of this symbol from
    411 			 * within the archive is a better candidate.  Similarly,
    412 			 * if this symbol has been bound to a shared object, but
    413 			 * the original reference expected hidden or protected
    414 			 * visibility, then a definition of this symbol from
    415 			 * within the archive is a better candidate.
    416 			 */
    417 			if (allexrt == 0) {
    418 				Boolean		vers = TRUE;
    419 				Ifl_desc	*ifl = sdp->sd_file;
    420 
    421 				sym = sdp->sd_sym;
    422 
    423 				if (sdp->sd_ref == REF_DYN_NEED) {
    424 					uchar_t	vis;
    425 
    426 					if (ifl->ifl_vercnt) {
    427 						Word		vndx;
    428 						Ver_index	*vip;
    429 
    430 						vndx = sdp->sd_aux->sa_dverndx;
    431 						vip = &ifl->ifl_verndx[vndx];
    432 						if ((vip->vi_flags &
    433 						    FLG_VER_AVAIL) == 0)
    434 							vers = FALSE;
    435 					}
    436 
    437 					vis = ELF_ST_VISIBILITY(sym->st_other);
    438 					visible = sym_vis[vis];
    439 				}
    440 
    441 				if (((ifl->ifl_flags & FLG_IF_NEEDED) == 0) ||
    442 				    (visible && vers &&
    443 				    (sym->st_shndx != SHN_UNDEF) &&
    444 				    (sym->st_shndx != SHN_COMMON)) ||
    445 				    ((ELF_ST_BIND(sym->st_info) == STB_WEAK) &&
    446 				    (!(ofl->ofl_flags1 & FLG_OF1_WEAKEXT)))) {
    447 					DBG_CALL(Dbg_syms_ar_entry(ofl->ofl_lml,
    448 					    ndx, arsym));
    449 					continue;
    450 				}
    451 			}
    452 
    453 			/*
    454 			 * Determine if we have already extracted this member,
    455 			 * and if so reuse the Ar_mem information.
    456 			 */
    457 			if ((amp = aup->au_mem) != 0) {
    458 				arelf = amp->am_elf;
    459 				arname = amp->am_name;
    460 				arpath = amp->am_path;
    461 			} else {
    462 				size_t	len;
    463 
    464 				/*
    465 				 * Set up a new elf descriptor for this member.
    466 				 */
    467 				if (elf_rand(adp->ad_elf, arsym->as_off) !=
    468 				    arsym->as_off) {
    469 					eprintf(ofl->ofl_lml, ERR_ELF,
    470 					    MSG_INTL(MSG_ELF_ARMEM), name,
    471 					    EC_WORD(arsym->as_off), ndx,
    472 					    demangle(arsym->as_name));
    473 					ofl->ofl_flags |= FLG_OF_FATAL;
    474 					return (0);
    475 				}
    476 
    477 				if ((arelf = elf_begin(fd, ELF_C_READ,
    478 				    adp->ad_elf)) == NULL) {
    479 					eprintf(ofl->ofl_lml, ERR_ELF,
    480 					    MSG_INTL(MSG_ELF_BEGIN), name);
    481 					ofl->ofl_flags |= FLG_OF_FATAL;
    482 					return (0);
    483 				}
    484 
    485 				/*
    486 				 * Construct the member filename.
    487 				 */
    488 				if ((arhdr = elf_getarhdr(arelf)) == NULL) {
    489 					eprintf(ofl->ofl_lml, ERR_ELF,
    490 					    MSG_INTL(MSG_ELF_GETARHDR), name);
    491 					ofl->ofl_flags |= FLG_OF_FATAL;
    492 					return (0);
    493 				}
    494 				arname = arhdr->ar_name;
    495 
    496 				/*
    497 				 * Construct the members full pathname, using
    498 				 * the format "%s(%s)".
    499 				 */
    500 				len = strlen(name) + strlen(arname) + 3;
    501 				if ((arpath = libld_malloc(len)) == NULL)
    502 					return (S_ERROR);
    503 				(void) snprintf(arpath, len,
    504 				    MSG_ORIG(MSG_FMT_ARMEM), name, arname);
    505 
    506 				/*
    507 				 * Determine whether the support library wishes
    508 				 * to process this open.  See comments in
    509 				 * ld_process_open().
    510 				 */
    511 				ld_sup_open(ofl, (const char **)&arpath,
    512 				    (const char **)&arname, &fd,
    513 				    (FLG_IF_EXTRACT | FLG_IF_NEEDED),
    514 				    &arelf, adp->ad_elf, arsym->as_off,
    515 				    elf_kind(arelf));
    516 
    517 				/*
    518 				 * An ELF descriptor of zero indicates that
    519 				 * the archive member should be ignored.
    520 				 */
    521 				if (arelf == NULL) {
    522 					aup->au_mem = FLG_ARMEM_PROC;
    523 					continue;
    524 				}
    525 			}
    526 
    527 			/*
    528 			 * The symbol for which this archive member is being
    529 			 * processed may provide a better alternative to the
    530 			 * symbol that is presently known.  Two cases are
    531 			 * covered:
    532 			 *
    533 			 *  i.	The present symbol represents tentative data.
    534 			 *	The archive member may provide a data
    535 			 *	definition symbol.
    536 			 *  ii.	The present symbol represents a reference that
    537 			 *	has seen a definition within a shared object
    538 			 *	dependency, but the reference expects to be
    539 			 *	reduced to hidden or protected visibility.
    540 			 */
    541 			if ((allexrt == 0) &&
    542 			    ((sym->st_shndx == SHN_COMMON) ||
    543 			    (visible == FALSE))) {
    544 				/*
    545 				 * If we don't already have a member structure
    546 				 * allocate one.
    547 				 */
    548 				if (!amp) {
    549 					if ((amp = libld_calloc(sizeof (Ar_mem),
    550 					    1)) == NULL)
    551 						return (S_ERROR);
    552 					amp->am_elf = arelf;
    553 					amp->am_name = arname;
    554 					amp->am_path = arpath;
    555 				}
    556 				DBG_CALL(Dbg_syms_ar_checking(ofl->ofl_lml,
    557 				    ndx, arsym, arname));
    558 				if ((err = process_member(amp, arsym->as_name,
    559 				    sdp, ofl)) == S_ERROR)
    560 					return (S_ERROR);
    561 
    562 				/*
    563 				 * If it turns out that we don't need this
    564 				 * member simply initialize all other auxiliary
    565 				 * entries that match this offset with this
    566 				 * members address.  In this way we can resuse
    567 				 * this information if we recurse back to this
    568 				 * symbol.
    569 				 */
    570 				if (err == 0) {
    571 					if (aup->au_mem == NULL)
    572 						ld_ar_member(adp, arsym,
    573 						    aup, amp);
    574 					continue;
    575 				}
    576 			}
    577 
    578 			/*
    579 			 * Process the archive member.  Retain any error for
    580 			 * return to the caller.
    581 			 */
    582 			DBG_CALL(Dbg_syms_ar_resolve(ofl->ofl_lml, ndx, arsym,
    583 			    arname, allexrt));
    584 			if ((err = (uintptr_t)ld_process_ifl(arpath, NULL, fd,
    585 			    arelf, (FLG_IF_EXTRACT | FLG_IF_NEEDED), ofl,
    586 			    &_rej)) == S_ERROR)
    587 				return (S_ERROR);
    588 
    589 			/*
    590 			 * If this member is rejected maintain the first
    591 			 * rejection error for possible later display.  Keep the
    592 			 * member as extracted so that we don't try and process
    593 			 * it again on a rescan.
    594 			 */
    595 			if (_rej.rej_type) {
    596 				if (rej.rej_type == 0) {
    597 					rej.rej_type = _rej.rej_type;
    598 					rej.rej_info = _rej.rej_info;
    599 					rej.rej_name = (const char *)arpath;
    600 				}
    601 				ld_ar_member(adp, arsym, aup, FLG_ARMEM_PROC);
    602 				continue;
    603 			}
    604 
    605 			/*
    606 			 * Indicate that the extracted member is in use.  This
    607 			 * enables debugging diags, and indicates that a further
    608 			 * rescan of all archives may be necessary.
    609 			 */
    610 			found = 1;
    611 			ofl->ofl_flags1 |= FLG_OF1_EXTRACT;
    612 			adp->ad_flags |= FLG_ARD_EXTRACT;
    613 
    614 			/*
    615 			 * If not under '-z allextract' signal the need to
    616 			 * rescan this archive.
    617 			 */
    618 			if (allexrt == 0)
    619 				again = 1;
    620 
    621 			ld_ar_member(adp, arsym, aup, FLG_ARMEM_PROC);
    622 			DBG_CALL(Dbg_util_nl(ofl->ofl_lml, DBG_NL_STD));
    623 		}
    624 	} while (again);
    625 
    626 	/*
    627 	 * If no objects have been found in the archive test for any rejections
    628 	 * and if one had occurred issue a warning - its possible a user has
    629 	 * pointed at an archive containing the wrong class of elf members.
    630 	 */
    631 	if ((found == 0) && rej.rej_type) {
    632 		Conv_reject_desc_buf_t rej_buf;
    633 
    634 		eprintf(ofl->ofl_lml, ERR_WARNING,
    635 		    MSG_INTL(reject[rej.rej_type]),
    636 		    rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN),
    637 		    conv_reject_desc(&rej, &rej_buf, ld_targ.t_m.m_mach));
    638 	}
    639 
    640 	/*
    641 	 * If this archive was extracted by -z allextract, the ar_aux table
    642 	 * and elf descriptor can be freed.  Set ad_elf to NULL to mark the
    643 	 * archive is completely processed.
    644 	 */
    645 	if (allexrt) {
    646 		(void) elf_end(adp->ad_elf);
    647 		adp->ad_elf = NULL;
    648 	}
    649 
    650 	return (1);
    651 }
    652