xref: /titanic_44/usr/src/cmd/sgs/libld/common/libs.c (revision 875546ac7519c97db0e3ce165c9b9d5147e27c8d)
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  */
64 static uintptr_t
process_member(Ar_mem * amp,const char * name,Sym_desc * sdp,Ofl_desc * ofl)65 process_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  */
186 Ar_desc *
ld_ar_setup(const char * name,Elf * elf,Ofl_desc * ofl)187 ld_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  */
268 void
ld_ar_member(Ar_desc * adp,Elf_Arsym * arsym,Ar_aux * aup,Ar_mem * amp)269 ld_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  */
320 static const char *
ar_member_name(const char * name,Elf * arelf,Ofl_desc * ofl)321 ar_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  */
342 static const char *
ar_member_path(const char * name,const char * arname,Ofl_desc * ofl)343 ar_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  */
377 static uintptr_t
ar_input(int fd,Ar_desc * adp,Ofl_desc * ofl,Elf * arelf,const char * arpath,Rej_desc * rej)378 ar_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  */
417 static const Boolean
418 sym_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  */
452 static Boolean
ar_extract_bysym(const char * name,int fd,Ar_desc * adp,Ofl_desc * ofl,Boolean * found,Rej_desc * rej)453 ar_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  */
729 static Boolean
ar_extract_all(const char * name,int fd,Ar_desc * adp,Ofl_desc * ofl,Boolean * found,Rej_desc * rej)730 ar_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  */
827 Boolean
ld_process_archive(const char * name,int fd,Ar_desc * adp,Ofl_desc * ofl)828 ld_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