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