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