xref: /illumos-gate/usr/src/cmd/sgs/libld/common/resolve.c (revision 6a634c9d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
55aefb655Srie  * Common Development and Distribution License (the "License").
65aefb655Srie  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
215aefb655Srie 
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate  *	Copyright (c) 1988 AT&T
247c478bd9Sstevel@tonic-gate  *	  All Rights Reserved
257c478bd9Sstevel@tonic-gate  *
26*1007fd6fSAli Bahrami  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * Symbol table resolution
317c478bd9Sstevel@tonic-gate  */
32ba2be530Sab #define	ELF_TARGET_AMD64
33ba2be530Sab 
347c478bd9Sstevel@tonic-gate #include	<stdio.h>
355aefb655Srie #include	<debug.h>
367c478bd9Sstevel@tonic-gate #include	"msg.h"
377c478bd9Sstevel@tonic-gate #include	"_libld.h"
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate /*
417c478bd9Sstevel@tonic-gate  * Categorize the symbol types that are applicable to the resolution process.
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate typedef	enum {
447c478bd9Sstevel@tonic-gate 	SYM_DEFINED,		/* Defined symbol (SHN_ABS or shndx != 0) */
457c478bd9Sstevel@tonic-gate 	SYM_UNDEFINED,		/* Undefined symbol (SHN_UNDEF) */
467c478bd9Sstevel@tonic-gate 	SYM_TENTATIVE,		/* Tentative symbol (SHN_COMMON) */
477c478bd9Sstevel@tonic-gate 	SYM_NUM			/* the number of symbol types */
487c478bd9Sstevel@tonic-gate } Symtype;
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate /*
517c478bd9Sstevel@tonic-gate  * Do nothing.
527c478bd9Sstevel@tonic-gate  */
537c478bd9Sstevel@tonic-gate /* ARGSUSED0 */
547c478bd9Sstevel@tonic-gate static void
sym_null(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)557c478bd9Sstevel@tonic-gate sym_null(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
56635216b6SRod Evans     int ndx, Word nshndx, sd_flag_t nsdflags)
577c478bd9Sstevel@tonic-gate {
587c478bd9Sstevel@tonic-gate }
597c478bd9Sstevel@tonic-gate 
6060758829Srie static void
sym_visibility_diag(Error err,Sym_desc * sdp,Sym * osym,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl)6160758829Srie sym_visibility_diag(Error err, Sym_desc *sdp, Sym *osym, Sym *nsym,
6260758829Srie     Ifl_desc *ifl, Ofl_desc *ofl)
6360758829Srie {
6460758829Srie 	Conv_inv_buf_t	inv_obuf, inv_nbuf;
6560758829Srie 
66d444b03eSAli Bahrami 	/* Warnings are only issued when -z verbose is specified */
67d444b03eSAli Bahrami 	if (!(ofl->ofl_flags & FLG_OF_VERBOSE) && (err != ERR_FATAL))
68d444b03eSAli Bahrami 		return;
69d444b03eSAli Bahrami 
70*1007fd6fSAli Bahrami 	ld_eprintf(ofl, err, MSG_INTL(MSG_SYM_CONFVIS), demangle(sdp->sd_name));
71*1007fd6fSAli Bahrami 	ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_VISTYPES),
7260758829Srie 	    sdp->sd_file->ifl_name, conv_sym_other(osym->st_other, &inv_obuf),
7360758829Srie 	    ifl->ifl_name, conv_sym_other(nsym->st_other, &inv_nbuf));
7460758829Srie 
75*1007fd6fSAli Bahrami 	if (err != ERR_FATAL)
76*1007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
7760758829Srie 		    ifl->ifl_name);
7860758829Srie }
7960758829Srie 
8060758829Srie /*
8160758829Srie  * STV_VISIBILITY rules for STV_DEFAULT/INTERNAL/HIDDEN/PROTECTED say that the
8260758829Srie  * most restrictive visibility value should be taken.  The precedence is:
8360758829Srie  *
8460758829Srie  *    (most restrictive) INTERNAL -> HIDDEN -> PROTECTED -> DEFAULT  (least)
8560758829Srie  *
8660758829Srie  * The STV_EXPORT and STV_SINGLETON visibilities are slightly different, in that
8760758829Srie  * the visibility must remain global and can not be reduced in any way.
8860758829Srie  *
8960758829Srie  * Resolution of different visibilities between two relocatable objects can
9060758829Srie  * take the following actions:
9160758829Srie  *
9260758829Srie  *  i.     if applicable, the most restrictive action is silently taken.
9360758829Srie  *  ii.    if a mapfile visibility definition competes with a more restrictive
9460758829Srie  *         relocatable object definition, then a warning is generated, but the
9560758829Srie  *         the more restrictive visibility is taken.
9660758829Srie  *  iii.   in the case of conflicts with an EXPORTED or SINGLETON symbol with
9760758829Srie  *	   any type of visibility between relocatable objects, the combination
9860758829Srie  *	   is deemed fatal.
9960758829Srie  *
10060758829Srie  *                                  new visibility
10160758829Srie  *                    D        I         H         P         X         S
10260758829Srie  *                 ------------------------------------------------------------
10360758829Srie  *              D |   D        I(mw)     H(mw)     P         X         S
10460758829Srie  *   original   I |   I        I         I         I         X(mw/of)  S(mw/of)
10560758829Srie  *  visibility  H |   H        I(mw)     H         H         X(mw/of)  S(mw/of)
10660758829Srie  *              P |   P        I(mw)     H(mw)     P         X(mw/of)  S(mw/of)
10760758829Srie  *              X |   X        I(mw/of)  H(mw/of)  P(mw/of)  X         S
10860758829Srie  *              S |   S        I(mw/of)  H(mw/of)  P(mw/of)  S         S
10960758829Srie  * where:
11060758829Srie  *
11160758829Srie  *  mw -  mapfile warning: if the original symbol originates from a mapfile
11260758829Srie  *        then warn the user that their scope definition is being overridden.
11360758829Srie  *  of -  object definitions are fatal: any combination of relocatable object
11460758829Srie  *        visibilities that conflict with a SINGLETON and EXPORTED are fatal.
11560758829Srie  *
11660758829Srie  * Note, an eliminate symbol (STV_ELIMINATE) is treated as hidden (STV_HIDDEN)
11760758829Srie  * for processing through this state table.
11860758829Srie  */
11960758829Srie static Half
sym_visibility(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl)12060758829Srie sym_visibility(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl)
12160758829Srie {
12260758829Srie 	Sym	*osym = sdp->sd_sym;
12360758829Srie 	uchar_t	wovis, ovis;
12460758829Srie 	uchar_t	wnvis, nvis;
12560758829Srie 
12660758829Srie 	wovis = ovis = ELF_ST_VISIBILITY(osym->st_other);
12760758829Srie 	wnvis = nvis = ELF_ST_VISIBILITY(nsym->st_other);
12860758829Srie 
12960758829Srie 	/*
13060758829Srie 	 * If the original visibilities are eliminate, assign them hidden for
13160758829Srie 	 * the state table processing.  The original visibility, rather than
13260758829Srie 	 * the working visibility, will be returned to the caller.
13360758829Srie 	 */
13460758829Srie 	if (wovis == STV_ELIMINATE)
13560758829Srie 		wovis = STV_HIDDEN;
13660758829Srie 	if (wnvis == STV_ELIMINATE)
13760758829Srie 		wnvis = STV_HIDDEN;
13860758829Srie 
13960758829Srie 	/*
14060758829Srie 	 * The most complex visibility resolution is between two relocatable
14160758829Srie 	 * objects.  However, in the case of SINGLETONS we also want to catch
14260758829Srie 	 * any singleton definitions within shared objects.  Relocatable objects
14360758829Srie 	 * that bind to these symbols inherit the singleton visibility as this
14460758829Srie 	 * efficiently triggers ld.so.1 into carrying out the appropriate
14560758829Srie 	 * runtime symbol search.  Any other resolution between a relocatable
14660758829Srie 	 * object and a shared object will retain the relocatable objects
14760758829Srie 	 * visibility.
14860758829Srie 	 */
14960758829Srie 	if ((sdp->sd_ref == REF_REL_NEED) &&
15060758829Srie 	    (ifl->ifl_ehdr->e_type == ET_DYN)) {
15160758829Srie 		if ((sdp->sd_sym->st_shndx == SHN_UNDEF) &&
15260758829Srie 		    (nsym->st_shndx != SHN_UNDEF) && (wnvis == STV_SINGLETON))
15360758829Srie 			return (STV_SINGLETON);
15460758829Srie 		else
15560758829Srie 			return (ovis);
15660758829Srie 	}
15760758829Srie 	if ((sdp->sd_ref != REF_REL_NEED) &&
15860758829Srie 	    (ifl->ifl_ehdr->e_type == ET_REL)) {
15960758829Srie 		if ((sdp->sd_sym->st_shndx != SHN_UNDEF) &&
16060758829Srie 		    (nsym->st_shndx == SHN_UNDEF) && (wovis == STV_SINGLETON))
16160758829Srie 			return (STV_SINGLETON);
16260758829Srie 		else
16360758829Srie 			return (nvis);
16460758829Srie 	}
16560758829Srie 
16660758829Srie 	/*
16760758829Srie 	 * If the visibilities are the same, we're done.  If the working
16860758829Srie 	 * visibilities differ from the original, then one must have been
16960758829Srie 	 * STV_HIDDEN and the other STV_ELIMINATE.
17060758829Srie 	 */
17160758829Srie 	if (wovis == wnvis) {
17260758829Srie 		if (ovis == nvis)
17360758829Srie 			return (nvis);
17460758829Srie 		else
17560758829Srie 			return (STV_ELIMINATE);
17660758829Srie 	}
17760758829Srie 
17860758829Srie 	/*
17960758829Srie 	 * An EXPORTED symbol or SINGLETON symbol can not be demoted, any
18060758829Srie 	 * conflicting visibility from another object is fatal.  A conflicting
18160758829Srie 	 * visibility from a mapfile produces a warning, as the mapfile
18260758829Srie 	 * definition can be overridden.
18360758829Srie 	 */
18460758829Srie 	if ((wnvis == STV_EXPORTED) || (wnvis == STV_SINGLETON)) {
18560758829Srie 		if ((wovis != STV_DEFAULT) && (wovis != STV_EXPORTED) &&
18660758829Srie 		    (wovis != STV_SINGLETON)) {
187635216b6SRod Evans 			if (sdp->sd_flags & FLG_SY_MAPFILE) {
18860758829Srie 				sym_visibility_diag(ERR_WARNING, sdp, osym,
18960758829Srie 				    nsym, ifl, ofl);
19060758829Srie 			} else {
19160758829Srie 				sym_visibility_diag(ERR_FATAL, sdp, osym,
19260758829Srie 				    nsym, ifl, ofl);
19360758829Srie 			}
19460758829Srie 		}
19560758829Srie 		return (nvis);
19660758829Srie 	}
19760758829Srie 	if (wovis == STV_SINGLETON) {
19860758829Srie 		if ((wnvis == STV_EXPORTED) || (wnvis == STV_DEFAULT))
19960758829Srie 			return (STV_SINGLETON);
200635216b6SRod Evans 		if (sdp->sd_flags & FLG_SY_MAPFILE) {
20160758829Srie 			sym_visibility_diag(ERR_WARNING, sdp, osym,
20260758829Srie 			    nsym, ifl, ofl);
20360758829Srie 		} else {
20460758829Srie 			sym_visibility_diag(ERR_FATAL, sdp, osym,
20560758829Srie 			    nsym, ifl, ofl);
20660758829Srie 		}
20760758829Srie 		return (nvis);
20860758829Srie 	}
20960758829Srie 	if (wovis == STV_EXPORTED) {
21060758829Srie 		if (wnvis == STV_SINGLETON)
21160758829Srie 			return (STV_SINGLETON);
21260758829Srie 		if (wnvis == STV_DEFAULT)
21360758829Srie 			return (STV_EXPORTED);
214635216b6SRod Evans 		if (sdp->sd_flags & FLG_SY_MAPFILE) {
21560758829Srie 			sym_visibility_diag(ERR_WARNING, sdp, osym,
21660758829Srie 			    nsym, ifl, ofl);
21760758829Srie 		} else {
21860758829Srie 			sym_visibility_diag(ERR_FATAL, sdp, osym,
21960758829Srie 			    nsym, ifl, ofl);
22060758829Srie 		}
22160758829Srie 		return (nvis);
22260758829Srie 	}
22360758829Srie 
22460758829Srie 	/*
22560758829Srie 	 * Now that symbols with the same visibility, and all instances of
22660758829Srie 	 * SINGLETON's have been dealt with, we're left with visibilities that
22760758829Srie 	 * differ, but can be dealt with in the order of how restrictive the
22860758829Srie 	 * visibilities are.  When a differing visibility originates from a
22960758829Srie 	 * mapfile definition, produces a warning, as the mapfile definition
23060758829Srie 	 * can be overridden by the relocatable object.
23160758829Srie 	 */
23260758829Srie 	if ((wnvis == STV_INTERNAL) || (wovis == STV_INTERNAL)) {
23360758829Srie 		if ((wnvis == STV_INTERNAL) &&
234635216b6SRod Evans 		    (sdp->sd_flags & FLG_SY_MAPFILE)) {
23560758829Srie 			sym_visibility_diag(ERR_WARNING, sdp, osym, nsym,
23660758829Srie 			    ifl, ofl);
23760758829Srie 		}
23860758829Srie 		return (STV_INTERNAL);
23960758829Srie 
24060758829Srie 	} else if ((wnvis == STV_HIDDEN) || (wovis == STV_HIDDEN)) {
24160758829Srie 		if ((wnvis == STV_HIDDEN) &&
242635216b6SRod Evans 		    (sdp->sd_flags & FLG_SY_MAPFILE)) {
24360758829Srie 			sym_visibility_diag(ERR_WARNING, sdp, osym, nsym,
24460758829Srie 			    ifl, ofl);
24560758829Srie 		}
24660758829Srie 
24760758829Srie 		/*
24860758829Srie 		 * In the case of STV_ELIMINATE and STV_HIDDEN, the working
24960758829Srie 		 * visibility can differ from the original visibility, so make
25060758829Srie 		 * sure to return the original visibility.
25160758829Srie 		 */
25260758829Srie 		if ((ovis == STV_ELIMINATE) || (nvis == STV_ELIMINATE))
25360758829Srie 			return (STV_ELIMINATE);
25460758829Srie 		else
25560758829Srie 			return (STV_HIDDEN);
25660758829Srie 
25760758829Srie 	} else if ((wnvis == STV_PROTECTED) || (wovis == STV_PROTECTED))
25860758829Srie 		return (STV_PROTECTED);
25960758829Srie 
26060758829Srie 	return (STV_DEFAULT);
26160758829Srie }
26260758829Srie 
2637c478bd9Sstevel@tonic-gate /*
2647c478bd9Sstevel@tonic-gate  * Check if two symbols types are compatible
2657c478bd9Sstevel@tonic-gate  */
2667c478bd9Sstevel@tonic-gate /*ARGSUSED4*/
2677c478bd9Sstevel@tonic-gate static void
sym_typecheck(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)2687c478bd9Sstevel@tonic-gate sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
269635216b6SRod Evans     int ndx, Word nshndx, sd_flag_t nsdflags)
2707c478bd9Sstevel@tonic-gate {
271de777a60Sab 	uchar_t		otype = ELF_ST_TYPE(sdp->sd_sym->st_info);
272de777a60Sab 	uchar_t		ntype = ELF_ST_TYPE(nsym->st_info);
273de777a60Sab 	Conv_inv_buf_t	inv_buf1, inv_buf2;
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 	/*
2767c478bd9Sstevel@tonic-gate 	 * Perform any machine specific type checking.
2777c478bd9Sstevel@tonic-gate 	 */
278ba2be530Sab 	if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) &&
279ba2be530Sab 	    (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl))
2807c478bd9Sstevel@tonic-gate 		return;
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate 	/*
28360758829Srie 	 * NOTYPE's can be combined with other types, only give an error if
28460758829Srie 	 * combining two differing types without NOTYPE.
2857c478bd9Sstevel@tonic-gate 	 */
2867c478bd9Sstevel@tonic-gate 	if ((otype == ntype) || (otype == STT_NOTYPE) || (ntype == STT_NOTYPE))
2877c478bd9Sstevel@tonic-gate 		return;
2887c478bd9Sstevel@tonic-gate 
289*1007fd6fSAli Bahrami 	ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
2907c478bd9Sstevel@tonic-gate 	    demangle(sdp->sd_name));
291*1007fd6fSAli Bahrami 	ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
2925aefb655Srie 	    sdp->sd_file->ifl_name,
293de777a60Sab 	    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 0, &inv_buf1),
294c13de8f6Sab 	    ifl->ifl_name,
295de777a60Sab 	    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 0, &inv_buf2));
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate /*ARGSUSED4*/
2997c478bd9Sstevel@tonic-gate static void
sym_mach_check(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)3007c478bd9Sstevel@tonic-gate sym_mach_check(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
301635216b6SRod Evans     int ndx, Word nshndx, sd_flag_t nsdflags)
3027c478bd9Sstevel@tonic-gate {
3037c478bd9Sstevel@tonic-gate 	/*
3047c478bd9Sstevel@tonic-gate 	 * Perform any machine specific type checking.
3057c478bd9Sstevel@tonic-gate 	 */
306ba2be530Sab 	if (ld_targ.t_ms.ms_mach_sym_typecheck != NULL)
307ba2be530Sab 		(void) (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym,
308ba2be530Sab 		    ifl, ofl);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate /*
3127c478bd9Sstevel@tonic-gate  * Promote the symbols reference.
3137c478bd9Sstevel@tonic-gate  */
3147c478bd9Sstevel@tonic-gate static void
3157c478bd9Sstevel@tonic-gate /* ARGSUSED4 */
sym_promote(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)3167c478bd9Sstevel@tonic-gate sym_promote(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
317635216b6SRod Evans     int ndx, Word nshndx, sd_flag_t nsdflags)
3187c478bd9Sstevel@tonic-gate {
3190bc07c75Srie 	Word	shndx = nsym->st_shndx;
3200bc07c75Srie 
321635216b6SRod Evans 	sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
3227c478bd9Sstevel@tonic-gate 
3237c478bd9Sstevel@tonic-gate 	/*
3247c478bd9Sstevel@tonic-gate 	 * If the old symbol is from a shared object and the new symbol is a
3257c478bd9Sstevel@tonic-gate 	 * reference from a relocatable object, promote the old symbols
3267c478bd9Sstevel@tonic-gate 	 * reference.
3277c478bd9Sstevel@tonic-gate 	 */
3287c478bd9Sstevel@tonic-gate 	if ((sdp->sd_ref == REF_DYN_SEEN) &&
3297c478bd9Sstevel@tonic-gate 	    (ifl->ifl_ehdr->e_type == ET_REL)) {
3307c478bd9Sstevel@tonic-gate 		sdp->sd_ref = REF_DYN_NEED;
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 		/*
3337c478bd9Sstevel@tonic-gate 		 * If this is an undefined symbol it must be a relocatable
3347c478bd9Sstevel@tonic-gate 		 * object overriding a shared object.  In this case also
3357c478bd9Sstevel@tonic-gate 		 * override the reference name so that any undefined symbol
3367c478bd9Sstevel@tonic-gate 		 * diagnostics will refer to the relocatable object name.
3377c478bd9Sstevel@tonic-gate 		 */
3380bc07c75Srie 		if (shndx == SHN_UNDEF)
3397c478bd9Sstevel@tonic-gate 			sdp->sd_aux->sa_rfile = ifl->ifl_name;
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 		/*
3427c478bd9Sstevel@tonic-gate 		 * If this symbol is an undefined, or common, determine whether
3437c478bd9Sstevel@tonic-gate 		 * it is a global or weak reference (see build_osym(), where
3447c478bd9Sstevel@tonic-gate 		 * REF_DYN_NEED definitions are returned back to undefines).
3457c478bd9Sstevel@tonic-gate 		 */
346635216b6SRod Evans 		if (((shndx == SHN_UNDEF) || ((nsdflags & FLG_SY_SPECSEC) &&
3470bc07c75Srie 		    (shndx == SHN_COMMON))) &&
3487c478bd9Sstevel@tonic-gate 		    (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
3497c478bd9Sstevel@tonic-gate 			sdp->sd_flags |= FLG_SY_GLOBREF;
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 	}
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate /*
3557c478bd9Sstevel@tonic-gate  * Override a symbol.
3567c478bd9Sstevel@tonic-gate  */
3577c478bd9Sstevel@tonic-gate static void
sym_override(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)3587c478bd9Sstevel@tonic-gate sym_override(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
359635216b6SRod Evans     int ndx, Word nshndx, sd_flag_t nsdflags)
3607c478bd9Sstevel@tonic-gate {
36160758829Srie 	Sym	*osym = sdp->sd_sym;
36260758829Srie 	Word	link;
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	/*
3657c478bd9Sstevel@tonic-gate 	 * In the case of a WEAK UNDEF symbol don't let a symbol from an
3667c478bd9Sstevel@tonic-gate 	 * unavailable object override the symbol definition.  This is because
3677c478bd9Sstevel@tonic-gate 	 * this symbol *may* not be present in a future object and by promoting
3687c478bd9Sstevel@tonic-gate 	 * this symbol we are actually causing bindings (PLTS) to be formed
3697c478bd9Sstevel@tonic-gate 	 * to this symbol.  Instead let the 'generic' weak binding take place.
3707c478bd9Sstevel@tonic-gate 	 */
3717c478bd9Sstevel@tonic-gate 	if ((ELF_ST_BIND(osym->st_info) == STB_WEAK) &&
3720bc07c75Srie 	    (sdp->sd_sym->st_shndx == SHN_UNDEF) &&
3730bc07c75Srie 	    ((ifl->ifl_flags & FLG_IF_NEEDED) == 0))
3747c478bd9Sstevel@tonic-gate 		return;
3757c478bd9Sstevel@tonic-gate 
376635216b6SRod Evans 	sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 	/*
3797c478bd9Sstevel@tonic-gate 	 * This symbol has already been compared to an SO definition,
3807c478bd9Sstevel@tonic-gate 	 * as per the runtime behavior, ignore extra definitions.
3817c478bd9Sstevel@tonic-gate 	 */
3827c478bd9Sstevel@tonic-gate 	if ((sdp->sd_flags & FLG_SY_SOFOUND) &&
3837c478bd9Sstevel@tonic-gate 	    (ifl->ifl_ehdr->e_type == ET_DYN))
3847c478bd9Sstevel@tonic-gate 		return;
3857c478bd9Sstevel@tonic-gate 
3867c478bd9Sstevel@tonic-gate 	/*
3877c478bd9Sstevel@tonic-gate 	 * Mark the symbol as available and copy the new symbols contents.
3887c478bd9Sstevel@tonic-gate 	 */
3897c478bd9Sstevel@tonic-gate 	sdp->sd_flags &= ~FLG_SY_NOTAVAIL;
3907c478bd9Sstevel@tonic-gate 	*osym = *nsym;
3917c478bd9Sstevel@tonic-gate 	sdp->sd_shndx = nshndx;
3927c478bd9Sstevel@tonic-gate 	sdp->sd_flags &= ~FLG_SY_SPECSEC;
393635216b6SRod Evans 	sdp->sd_flags |= (nsdflags & (FLG_SY_SPECSEC | FLG_SY_TENTSYM));
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 	/*
3967c478bd9Sstevel@tonic-gate 	 * If the new symbol has PROTECTED visibility, mark it.  If a PROTECTED
39760758829Srie 	 * symbol is copy relocated, a warning message will be printed.  See
3987c478bd9Sstevel@tonic-gate 	 * reloc_exec().
3997c478bd9Sstevel@tonic-gate 	 */
4007c478bd9Sstevel@tonic-gate 	if (ELF_ST_VISIBILITY(nsym->st_other) == STV_PROTECTED)
4017c478bd9Sstevel@tonic-gate 		sdp->sd_flags |= FLG_SY_PROT;
4027c478bd9Sstevel@tonic-gate 	else
4037c478bd9Sstevel@tonic-gate 		sdp->sd_flags &= ~FLG_SY_PROT;
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	/*
4067c478bd9Sstevel@tonic-gate 	 * Establish the symbols reference.  If the new symbol originates from a
4077c478bd9Sstevel@tonic-gate 	 * relocatable object then this reference becomes needed, otherwise
4087c478bd9Sstevel@tonic-gate 	 * the new symbol must be from a shared object.  In this case only
4097c478bd9Sstevel@tonic-gate 	 * promote the symbol to needed if we presently have a reference from a
4107c478bd9Sstevel@tonic-gate 	 * relocatable object.
4117c478bd9Sstevel@tonic-gate 	 */
4127c478bd9Sstevel@tonic-gate 	if (ifl->ifl_ehdr->e_type == ET_REL) {
4137c478bd9Sstevel@tonic-gate 		sdp->sd_ref = REF_REL_NEED;
4147c478bd9Sstevel@tonic-gate 
4150bc07c75Srie 		if (nsym->st_shndx == SHN_UNDEF) {
4167c478bd9Sstevel@tonic-gate 			/*
41708278a5eSRod Evans 			 * If this is an undefined symbol, then we can only be
41808278a5eSRod Evans 			 * attempting to override an existing undefined symbol.
41908278a5eSRod Evans 			 * The original symbol is either:
42008278a5eSRod Evans 			 *
42108278a5eSRod Evans 			 *  -	a mapfile definition
42208278a5eSRod Evans 			 *  -	a previous relocatable object whose visibility
42308278a5eSRod Evans 			 *	or type should be overridden by this new symbol
42408278a5eSRod Evans 			 *  -	a previous shared object
42508278a5eSRod Evans 			 *
42608278a5eSRod Evans 			 * If the original undefined symbol stems from a mapfile
42708278a5eSRod Evans 			 * then don't alter the reference file name.  Should we
42808278a5eSRod Evans 			 * end up with some form of 'undefined' symbol error,
42908278a5eSRod Evans 			 * the characteristics of that error are most likely to
43008278a5eSRod Evans 			 * have originated from a mapfile.
43108278a5eSRod Evans 			 *
43208278a5eSRod Evans 			 * Otherwise, update the reference file name to indicate
43308278a5eSRod Evans 			 * this symbol.
4347c478bd9Sstevel@tonic-gate 			 */
43508278a5eSRod Evans 			if ((sdp->sd_flags & FLG_SY_MAPREF) == 0)
43608278a5eSRod Evans 				sdp->sd_aux->sa_rfile = ifl->ifl_name;
4377c478bd9Sstevel@tonic-gate 		} else {
4387c478bd9Sstevel@tonic-gate 			/*
4399a411307Srie 			 * Under -Bnodirect, all exported interfaces that have
4409a411307Srie 			 * not explicitly been defined protected or directly
4419a411307Srie 			 * bound to, are tagged to prevent direct binding.
4427c478bd9Sstevel@tonic-gate 			 */
4437c478bd9Sstevel@tonic-gate 			if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) &&
444635216b6SRod Evans 			    ((sdp->sd_flags &
445635216b6SRod Evans 			    (FLG_SY_PROTECT | FLG_SY_DIR)) == 0))
446635216b6SRod Evans 				sdp->sd_flags |= FLG_SY_NDIR;
4477c478bd9Sstevel@tonic-gate 		}
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate 		/*
4507c478bd9Sstevel@tonic-gate 		 * If this symbol is an undefined, or common, determine whether
4517c478bd9Sstevel@tonic-gate 		 * it is a global or weak reference (see build_osym(), where
4527c478bd9Sstevel@tonic-gate 		 * REF_DYN_NEED definitions are returned back to undefines).
4537c478bd9Sstevel@tonic-gate 		 */
4540bc07c75Srie 		if (((nsym->st_shndx == SHN_UNDEF) ||
455635216b6SRod Evans 		    ((nsdflags & FLG_SY_SPECSEC) &&
4560bc07c75Srie 		    (nsym->st_shndx == SHN_COMMON))) &&
4577c478bd9Sstevel@tonic-gate 		    (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
4587c478bd9Sstevel@tonic-gate 			sdp->sd_flags |= FLG_SY_GLOBREF;
4597c478bd9Sstevel@tonic-gate 		else
4607c478bd9Sstevel@tonic-gate 			sdp->sd_flags &= ~FLG_SY_GLOBREF;
4617c478bd9Sstevel@tonic-gate 	} else {
4627c478bd9Sstevel@tonic-gate 		if (sdp->sd_ref == REF_REL_NEED)
4637c478bd9Sstevel@tonic-gate 			sdp->sd_ref = REF_DYN_NEED;
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 		/*
4667c478bd9Sstevel@tonic-gate 		 * Determine the symbols availability.  A symbol is determined
4677c478bd9Sstevel@tonic-gate 		 * to be unavailable if it belongs to a version of a shared
4687c478bd9Sstevel@tonic-gate 		 * object that this user does not wish to use, or if it belongs
4697c478bd9Sstevel@tonic-gate 		 * to an implicit shared object.
4707c478bd9Sstevel@tonic-gate 		 */
4717c478bd9Sstevel@tonic-gate 		if (ifl->ifl_vercnt) {
47260758829Srie 			Ver_index	*vip;
4737c478bd9Sstevel@tonic-gate 			Half		vndx = ifl->ifl_versym[ndx];
4747c478bd9Sstevel@tonic-gate 
4757c478bd9Sstevel@tonic-gate 			sdp->sd_aux->sa_dverndx = vndx;
4767c478bd9Sstevel@tonic-gate 			vip = &ifl->ifl_verndx[vndx];
4777c478bd9Sstevel@tonic-gate 			if (!(vip->vi_flags & FLG_VER_AVAIL)) {
4787c478bd9Sstevel@tonic-gate 				sdp->sd_flags |= FLG_SY_NOTAVAIL;
4797c478bd9Sstevel@tonic-gate 				/*
48060758829Srie 				 * If this is the first occurrence of an
4817c478bd9Sstevel@tonic-gate 				 * unavailable symbol record it for possible
4827c478bd9Sstevel@tonic-gate 				 * use in later error diagnostics
4837c478bd9Sstevel@tonic-gate 				 * (see sym_undef).
4847c478bd9Sstevel@tonic-gate 				 */
4857c478bd9Sstevel@tonic-gate 				if (!(sdp->sd_aux->sa_vfile))
4867c478bd9Sstevel@tonic-gate 					sdp->sd_aux->sa_vfile = ifl->ifl_name;
4877c478bd9Sstevel@tonic-gate 			}
4887c478bd9Sstevel@tonic-gate 		}
4897c478bd9Sstevel@tonic-gate 		if (!(ifl->ifl_flags & FLG_IF_NEEDED))
4907c478bd9Sstevel@tonic-gate 			sdp->sd_flags |= FLG_SY_NOTAVAIL;
4917c478bd9Sstevel@tonic-gate 	}
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate 	/*
4947c478bd9Sstevel@tonic-gate 	 * Make sure any symbol association maintained by the original symbol
4957c478bd9Sstevel@tonic-gate 	 * is cleared and then update the symbols file reference.
4967c478bd9Sstevel@tonic-gate 	 */
4977c478bd9Sstevel@tonic-gate 	if ((link = sdp->sd_aux->sa_linkndx) != 0) {
4987c478bd9Sstevel@tonic-gate 		Sym_desc *	_sdp;
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 		_sdp = sdp->sd_file->ifl_oldndx[link];
5017c478bd9Sstevel@tonic-gate 		_sdp->sd_aux->sa_linkndx = 0;
5027c478bd9Sstevel@tonic-gate 		sdp->sd_aux->sa_linkndx = 0;
5037c478bd9Sstevel@tonic-gate 	}
5047c478bd9Sstevel@tonic-gate 	sdp->sd_file = ifl;
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate 	/*
5077c478bd9Sstevel@tonic-gate 	 * Update the input section descriptor to that of the new input file
5087c478bd9Sstevel@tonic-gate 	 */
509635216b6SRod Evans 	if (((nsdflags & FLG_SY_SPECSEC) == 0) &&
510*1007fd6fSAli Bahrami 	    (nsym->st_shndx != SHN_UNDEF) &&
511*1007fd6fSAli Bahrami 	    ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == NULL))
512*1007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_NOSECDEF),
513*1007fd6fSAli Bahrami 		    demangle(sdp->sd_name), ifl->ifl_name);
5147c478bd9Sstevel@tonic-gate }
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate /*
5177c478bd9Sstevel@tonic-gate  * Resolve two undefines (only called for two relocatable objects).
5187c478bd9Sstevel@tonic-gate  */
5197c478bd9Sstevel@tonic-gate static void
sym_twoundefs(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)5207c478bd9Sstevel@tonic-gate sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
521635216b6SRod Evans     int ndx, Word nshndx, sd_flag_t nsdflags)
5227c478bd9Sstevel@tonic-gate {
52302ca3e02Srie 	Sym	*osym = sdp->sd_sym;
52402ca3e02Srie 	uchar_t	obind = ELF_ST_BIND(osym->st_info);
52508278a5eSRod Evans 	uchar_t	otype = ELF_ST_TYPE(osym->st_info);
52602ca3e02Srie 	uchar_t	nbind = ELF_ST_BIND(nsym->st_info);
52708278a5eSRod Evans 	uchar_t	ntype = ELF_ST_TYPE(nsym->st_info);
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate 	/*
5307c478bd9Sstevel@tonic-gate 	 * If two relocatable objects define a weak and non-weak undefined
5317c478bd9Sstevel@tonic-gate 	 * reference, take the non-weak definition.
5327c478bd9Sstevel@tonic-gate 	 *
5337c478bd9Sstevel@tonic-gate 	 *		-- or --
5347c478bd9Sstevel@tonic-gate 	 *
5357c478bd9Sstevel@tonic-gate 	 * If two relocatable objects define a NOTYPE & another, then
5367c478bd9Sstevel@tonic-gate 	 * take the other.
5377c478bd9Sstevel@tonic-gate 	 */
5387c478bd9Sstevel@tonic-gate 	if (((obind == STB_WEAK) && (nbind != STB_WEAK)) ||
53908278a5eSRod Evans 	    (otype == STT_NOTYPE) && (ntype != STT_NOTYPE)) {
540635216b6SRod Evans 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
5417c478bd9Sstevel@tonic-gate 		return;
5427c478bd9Sstevel@tonic-gate 	}
543635216b6SRod Evans 	sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate /*
5477c478bd9Sstevel@tonic-gate  * Resolve two real definitions.
5487c478bd9Sstevel@tonic-gate  */
5497c478bd9Sstevel@tonic-gate static void
sym_tworeals(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)5507c478bd9Sstevel@tonic-gate sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
551635216b6SRod Evans     int ndx, Word nshndx, sd_flag_t nsdflags)
5527c478bd9Sstevel@tonic-gate {
553de777a60Sab 	Conv_inv_buf_t inv_buf1, inv_buf2;
55402ca3e02Srie 	Sym	*osym = sdp->sd_sym;
55502ca3e02Srie 	uchar_t	otype = ELF_ST_TYPE(osym->st_info);
55602ca3e02Srie 	uchar_t	obind = ELF_ST_BIND(osym->st_info);
55702ca3e02Srie 	uchar_t	ntype = ELF_ST_TYPE(nsym->st_info);
55802ca3e02Srie 	uchar_t	nbind = ELF_ST_BIND(nsym->st_info);
55902ca3e02Srie 	Half	ofile = sdp->sd_file->ifl_ehdr->e_type;
56002ca3e02Srie 	Half	nfile = ifl->ifl_ehdr->e_type;
56102ca3e02Srie 	int	warn = 0;
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 	/*
5647c478bd9Sstevel@tonic-gate 	 * If both definitions are from relocatable objects, and have non-weak
5657c478bd9Sstevel@tonic-gate 	 * binding then this is a fatal condition.
5667c478bd9Sstevel@tonic-gate 	 */
5677c478bd9Sstevel@tonic-gate 	if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) &&
5687c478bd9Sstevel@tonic-gate 	    (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) {
569*1007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
5707c478bd9Sstevel@tonic-gate 		    demangle(sdp->sd_name));
571*1007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
5727c478bd9Sstevel@tonic-gate 		    sdp->sd_file->ifl_name,
573de777a60Sab 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
574de777a60Sab 		    0, &inv_buf1), ifl->ifl_name,
575de777a60Sab 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
576de777a60Sab 		    0, &inv_buf2));
5777c478bd9Sstevel@tonic-gate 		return;
5787c478bd9Sstevel@tonic-gate 	}
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 	/*
5817c478bd9Sstevel@tonic-gate 	 * Perform any machine specific type checking.
5827c478bd9Sstevel@tonic-gate 	 */
583ba2be530Sab 	if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) &&
584ba2be530Sab 	    (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl))
5857c478bd9Sstevel@tonic-gate 		return;
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate 	/*
5887c478bd9Sstevel@tonic-gate 	 * Check the symbols type and size.
5897c478bd9Sstevel@tonic-gate 	 */
5907c478bd9Sstevel@tonic-gate 	if (otype != ntype) {
591*1007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
5927c478bd9Sstevel@tonic-gate 		    demangle(sdp->sd_name));
593*1007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
5947c478bd9Sstevel@tonic-gate 		    sdp->sd_file->ifl_name,
595de777a60Sab 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
596de777a60Sab 		    0, &inv_buf1), ifl->ifl_name,
597de777a60Sab 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
598de777a60Sab 		    0, &inv_buf2));
5997c478bd9Sstevel@tonic-gate 		warn++;
6007c478bd9Sstevel@tonic-gate 	} else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) {
6017c478bd9Sstevel@tonic-gate 		if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
602*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_WARNING,
6035aefb655Srie 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
6045aefb655Srie 			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
6055aefb655Srie 			    EC_XWORD(osym->st_size), ifl->ifl_name,
6065aefb655Srie 			    EC_XWORD(nsym->st_size));
6077c478bd9Sstevel@tonic-gate 			warn++;
6087c478bd9Sstevel@tonic-gate 		}
6097c478bd9Sstevel@tonic-gate 	}
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	/*
6127c478bd9Sstevel@tonic-gate 	 * Having provided the user with any necessary warnings, take the
6137c478bd9Sstevel@tonic-gate 	 * appropriate symbol:
6147c478bd9Sstevel@tonic-gate 	 *
61528bda19cSRod Evans 	 *  -	if one symbol is from a shared object and the other is from a
6167c478bd9Sstevel@tonic-gate 	 *	relocatable object, take the relocatable objects symbol (the
6177c478bd9Sstevel@tonic-gate 	 *	run-time linker is always going to find the relocatable object
6187c478bd9Sstevel@tonic-gate 	 *	symbol regardless of the binding), else
6197c478bd9Sstevel@tonic-gate 	 *
62028bda19cSRod Evans 	 *  -	if both symbols are from relocatable objects and one symbol is
6217c478bd9Sstevel@tonic-gate 	 *	weak take the non-weak symbol (two non-weak symbols would have
6227c478bd9Sstevel@tonic-gate 	 *	generated the fatal error condition above unless -z muldefs is
6237c478bd9Sstevel@tonic-gate 	 *	in effect), else
6247c478bd9Sstevel@tonic-gate 	 *
62528bda19cSRod Evans 	 *  -	take the first symbol definition encountered.
6267c478bd9Sstevel@tonic-gate 	 */
6277c478bd9Sstevel@tonic-gate 	if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
6287c478bd9Sstevel@tonic-gate 		if (warn)
629*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
630*1007fd6fSAli Bahrami 			    sdp->sd_file->ifl_name);
6317c478bd9Sstevel@tonic-gate 		return;
6327c478bd9Sstevel@tonic-gate 	} else if ((nfile == ET_REL) && ((ofile == ET_DYN) ||
6337c478bd9Sstevel@tonic-gate 	    ((obind == STB_WEAK) && (nbind != STB_WEAK)))) {
6347c478bd9Sstevel@tonic-gate 		if (warn)
635*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
636*1007fd6fSAli Bahrami 			    ifl->ifl_name);
637635216b6SRod Evans 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
6387c478bd9Sstevel@tonic-gate 		return;
6397c478bd9Sstevel@tonic-gate 	} else {
6407c478bd9Sstevel@tonic-gate 		if (warn)
641*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
642*1007fd6fSAli Bahrami 			    sdp->sd_file->ifl_name);
643635216b6SRod Evans 		sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
6447c478bd9Sstevel@tonic-gate 		return;
6457c478bd9Sstevel@tonic-gate 	}
6467c478bd9Sstevel@tonic-gate }
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate /*
6497c478bd9Sstevel@tonic-gate  * Resolve a real and tentative definition.
6507c478bd9Sstevel@tonic-gate  */
6517c478bd9Sstevel@tonic-gate static void
sym_realtent(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)6527c478bd9Sstevel@tonic-gate sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
653635216b6SRod Evans     int ndx, Word nshndx, sd_flag_t nsdflags)
6547c478bd9Sstevel@tonic-gate {
655de777a60Sab 	Conv_inv_buf_t inv_buf1, inv_buf2;
65602ca3e02Srie 	Sym	*osym = sdp->sd_sym;
65702ca3e02Srie 	uchar_t otype = ELF_ST_TYPE(osym->st_info);
65802ca3e02Srie 	uchar_t obind = ELF_ST_BIND(osym->st_info);
65902ca3e02Srie 	uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
66002ca3e02Srie 	uchar_t nbind = ELF_ST_BIND(nsym->st_info);
66102ca3e02Srie 	Boolean	otent = FALSE, ntent = FALSE;
66202ca3e02Srie 	Half	ofile = sdp->sd_file->ifl_ehdr->e_type;
66302ca3e02Srie 	Half	nfile = ifl->ifl_ehdr->e_type;
66402ca3e02Srie 	int	warn = 0;
66560758829Srie 	uchar_t	ovis = ELF_ST_VISIBILITY(osym->st_other);
66660758829Srie 	uchar_t	nvis = ELF_ST_VISIBILITY(nsym->st_other);
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate 	/*
6697c478bd9Sstevel@tonic-gate 	 * Special rules for functions.
6707c478bd9Sstevel@tonic-gate 	 *
67128bda19cSRod Evans 	 *  -	If both definitions are from relocatable objects, have the same
6727c478bd9Sstevel@tonic-gate 	 *	binding (ie. two weaks or two non-weaks), and the real
6737c478bd9Sstevel@tonic-gate 	 *	definition is a function (the other must be tentative), treat
6747c478bd9Sstevel@tonic-gate 	 *	this as a multiply defined symbol error, else
6757c478bd9Sstevel@tonic-gate 	 *
67628bda19cSRod Evans 	 *  -	if the real symbol definition is a function within a shared
6777c478bd9Sstevel@tonic-gate 	 *	library and the tentative symbol is a relocatable object, and
6787c478bd9Sstevel@tonic-gate 	 *	the tentative is not weak and the function real, then retain the
6797c478bd9Sstevel@tonic-gate 	 *	tentative definition.
6807c478bd9Sstevel@tonic-gate 	 */
6817c478bd9Sstevel@tonic-gate 	if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) &&
6827c478bd9Sstevel@tonic-gate 	    ((otype == STT_FUNC) || (ntype == STT_FUNC))) {
6837c478bd9Sstevel@tonic-gate 		if (ofl->ofl_flags & FLG_OF_MULDEFS) {
684*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
685*1007fd6fSAli Bahrami 			    demangle(sdp->sd_name));
6867c478bd9Sstevel@tonic-gate 			sym_promote(sdp, nsym, ifl, ofl, ndx,
687635216b6SRod Evans 			    nshndx, nsdflags);
6887c478bd9Sstevel@tonic-gate 		} else {
689*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
690*1007fd6fSAli Bahrami 			    demangle(sdp->sd_name));
6917c478bd9Sstevel@tonic-gate 		}
692*1007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
6937c478bd9Sstevel@tonic-gate 		    sdp->sd_file->ifl_name,
694de777a60Sab 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
695de777a60Sab 		    0, &inv_buf1), ifl->ifl_name,
696de777a60Sab 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
697de777a60Sab 		    0, &inv_buf2));
6987c478bd9Sstevel@tonic-gate 		return;
6997c478bd9Sstevel@tonic-gate 	} else if (ofile != nfile) {
7007c478bd9Sstevel@tonic-gate 
7017c478bd9Sstevel@tonic-gate 
7027c478bd9Sstevel@tonic-gate 		if ((ofile == ET_DYN) && (otype == STT_FUNC)) {
7037c478bd9Sstevel@tonic-gate 			if ((otype != STB_WEAK) && (ntype == STB_WEAK))
7047c478bd9Sstevel@tonic-gate 				return;
7057c478bd9Sstevel@tonic-gate 			else {
7067c478bd9Sstevel@tonic-gate 				sym_override(sdp, nsym, ifl, ofl, ndx,
707635216b6SRod Evans 				    nshndx, nsdflags);
7087c478bd9Sstevel@tonic-gate 				return;
7097c478bd9Sstevel@tonic-gate 			}
7107c478bd9Sstevel@tonic-gate 		}
7117c478bd9Sstevel@tonic-gate 		if ((nfile == ET_DYN) && (ntype == STT_FUNC)) {
7127c478bd9Sstevel@tonic-gate 			if ((ntype != STB_WEAK) && (otype == STB_WEAK)) {
7137c478bd9Sstevel@tonic-gate 				sym_override(sdp, nsym, ifl, ofl, ndx,
714635216b6SRod Evans 				    nshndx, nsdflags);
7157c478bd9Sstevel@tonic-gate 				return;
7167c478bd9Sstevel@tonic-gate 			} else
7177c478bd9Sstevel@tonic-gate 				return;
7187c478bd9Sstevel@tonic-gate 		}
7197c478bd9Sstevel@tonic-gate 	}
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 	if (sdp->sd_flags & FLG_SY_TENTSYM)
7227c478bd9Sstevel@tonic-gate 		otent = TRUE;
723635216b6SRod Evans 	if (nsdflags & FLG_SY_TENTSYM)
7247c478bd9Sstevel@tonic-gate 		ntent = TRUE;
7257c478bd9Sstevel@tonic-gate 
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate 	/*
7287c478bd9Sstevel@tonic-gate 	 * Check the symbols type and size.
7297c478bd9Sstevel@tonic-gate 	 */
7307c478bd9Sstevel@tonic-gate 	if (otype != ntype) {
731*1007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
7327c478bd9Sstevel@tonic-gate 		    demangle(sdp->sd_name));
733*1007fd6fSAli Bahrami 		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
7347c478bd9Sstevel@tonic-gate 		    sdp->sd_file->ifl_name,
735de777a60Sab 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
736de777a60Sab 		    0, &inv_buf1), ifl->ifl_name,
737de777a60Sab 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
738de777a60Sab 		    0, &inv_buf2));
7397c478bd9Sstevel@tonic-gate 		warn++;
7407c478bd9Sstevel@tonic-gate 	} else if (osym->st_size != nsym->st_size) {
7417c478bd9Sstevel@tonic-gate 		/*
7427c478bd9Sstevel@tonic-gate 		 * If both definitions are from relocatable objects we have a
7437c478bd9Sstevel@tonic-gate 		 * potential fatal error condition.  If the tentative is larger
7447c478bd9Sstevel@tonic-gate 		 * than the real definition treat this as a multiple definition.
7457c478bd9Sstevel@tonic-gate 		 * Note that if only one symbol is weak, the non-weak will be
7467c478bd9Sstevel@tonic-gate 		 * taken.
7477c478bd9Sstevel@tonic-gate 		 */
7487c478bd9Sstevel@tonic-gate 		if (((ofile == ET_REL) && (nfile == ET_REL) &&
7497c478bd9Sstevel@tonic-gate 		    (obind == nbind)) &&
7507c478bd9Sstevel@tonic-gate 		    ((otent && (osym->st_size > nsym->st_size)) ||
7517c478bd9Sstevel@tonic-gate 		    (ntent && (osym->st_size < nsym->st_size)))) {
752*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_DIFFATTR),
753*1007fd6fSAli Bahrami 			    demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES),
754*1007fd6fSAli Bahrami 			    sdp->sd_file->ifl_name, EC_XWORD(osym->st_size),
755*1007fd6fSAli Bahrami 			    ifl->ifl_name, EC_XWORD(nsym->st_size));
756*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_TENTERR));
7577c478bd9Sstevel@tonic-gate 		} else {
7587c478bd9Sstevel@tonic-gate 			if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
759*1007fd6fSAli Bahrami 				ld_eprintf(ofl, ERR_WARNING,
7605aefb655Srie 				    MSG_INTL(MSG_SYM_DIFFATTR),
7617c478bd9Sstevel@tonic-gate 				    demangle(sdp->sd_name),
7627c478bd9Sstevel@tonic-gate 				    MSG_INTL(MSG_STR_SIZES),
7637c478bd9Sstevel@tonic-gate 				    sdp->sd_file->ifl_name,
7647c478bd9Sstevel@tonic-gate 				    EC_XWORD(osym->st_size),
7657c478bd9Sstevel@tonic-gate 				    ifl->ifl_name, EC_XWORD(nsym->st_size));
7667c478bd9Sstevel@tonic-gate 				warn++;
7677c478bd9Sstevel@tonic-gate 			}
7687c478bd9Sstevel@tonic-gate 		}
7697c478bd9Sstevel@tonic-gate 	}
7707c478bd9Sstevel@tonic-gate 
7717c478bd9Sstevel@tonic-gate 	/*
7727c478bd9Sstevel@tonic-gate 	 * Having provided the user with any necessary warnings, take the
7737c478bd9Sstevel@tonic-gate 	 * appropriate symbol:
7747c478bd9Sstevel@tonic-gate 	 *
77528bda19cSRod Evans 	 *  -	if the original symbol is from relocatable file and it is
7767c478bd9Sstevel@tonic-gate 	 *	a protected tentative symbol, take the original one.
7777c478bd9Sstevel@tonic-gate 	 *
77828bda19cSRod Evans 	 *  -	if the original symbol is from shared object and the new
7797c478bd9Sstevel@tonic-gate 	 *	symbol is a protected tentative symbol from a relocatable file,
7807c478bd9Sstevel@tonic-gate 	 *	take the new one.
7817c478bd9Sstevel@tonic-gate 	 *
78228bda19cSRod Evans 	 *  -	if the original symbol is tentative, and providing the original
7837c478bd9Sstevel@tonic-gate 	 *	symbol isn't strong and the new symbol weak, take the real
7847c478bd9Sstevel@tonic-gate 	 *	symbol, else
7857c478bd9Sstevel@tonic-gate 	 *
78628bda19cSRod Evans 	 *  -	if the original symbol is weak and the new tentative symbol is
7877c478bd9Sstevel@tonic-gate 	 *	strong take the new symbol.
7887c478bd9Sstevel@tonic-gate 	 *
7897c478bd9Sstevel@tonic-gate 	 * Refer to the System V ABI Page 4-27 for a description of the binding
7907c478bd9Sstevel@tonic-gate 	 * requirements of tentative and weak symbols.
7917c478bd9Sstevel@tonic-gate 	 */
7927c478bd9Sstevel@tonic-gate 	if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) &&
79360758829Srie 	    (ovis == STV_PROTECTED)) {
7947c478bd9Sstevel@tonic-gate 		return;
7957c478bd9Sstevel@tonic-gate 	}
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 	if ((ofile == ET_DYN) && (nfile == ET_REL) && (ntent == TRUE) &&
79860758829Srie 	    (nvis == STV_PROTECTED)) {
799635216b6SRod Evans 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
8007c478bd9Sstevel@tonic-gate 		return;
8017c478bd9Sstevel@tonic-gate 	}
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate 	if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
8047c478bd9Sstevel@tonic-gate 		if (warn)
805*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
806*1007fd6fSAli Bahrami 			    sdp->sd_file->ifl_name);
8077c478bd9Sstevel@tonic-gate 		return;
8087c478bd9Sstevel@tonic-gate 	}
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate 	if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) ||
8117c478bd9Sstevel@tonic-gate 	    ((obind == STB_WEAK) && (nbind != STB_WEAK))) {
8127c478bd9Sstevel@tonic-gate 		if (warn)
813*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
814*1007fd6fSAli Bahrami 			    ifl->ifl_name);
815635216b6SRod Evans 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
8167c478bd9Sstevel@tonic-gate 		return;
8177c478bd9Sstevel@tonic-gate 	} else {
8187c478bd9Sstevel@tonic-gate 		if (warn)
819*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
820*1007fd6fSAli Bahrami 			    sdp->sd_file->ifl_name);
821635216b6SRod Evans 		sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
8227c478bd9Sstevel@tonic-gate 		return;
8237c478bd9Sstevel@tonic-gate 	}
8247c478bd9Sstevel@tonic-gate }
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate /*
8277c478bd9Sstevel@tonic-gate  * Resolve two tentative symbols.
8287c478bd9Sstevel@tonic-gate  */
8297c478bd9Sstevel@tonic-gate static void
sym_twotent(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)8307c478bd9Sstevel@tonic-gate sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
831635216b6SRod Evans     int ndx, Word nshndx, sd_flag_t nsdflags)
8327c478bd9Sstevel@tonic-gate {
83302ca3e02Srie 	Sym	*osym = sdp->sd_sym;
83402ca3e02Srie 	uchar_t	obind = ELF_ST_BIND(osym->st_info);
83502ca3e02Srie 	uchar_t	nbind = ELF_ST_BIND(nsym->st_info);
83602ca3e02Srie 	Half	ofile = sdp->sd_file->ifl_ehdr->e_type;
83702ca3e02Srie 	Half	nfile = ifl->ifl_ehdr->e_type;
83802ca3e02Srie 	size_t	size = 0;
83902ca3e02Srie 	Xword	value = 0;
84002ca3e02Srie 
841ba2be530Sab #if	defined(_ELF64)
842ba2be530Sab 	if (ld_targ.t_m.m_mach == EM_AMD64) {
84354d82594Sseizo 		/*
844ba2be530Sab 		 * If the original and new symbols are both COMMON, but of
845ba2be530Sab 		 * a different size model, take the small one.
84654d82594Sseizo 		 */
847ba2be530Sab 		if ((sdp->sd_sym->st_shndx == SHN_COMMON) &&
848ba2be530Sab 		    (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
849ba2be530Sab 			/*
850ba2be530Sab 			 * Take the original symbol.
851ba2be530Sab 			 */
852ba2be530Sab 			return;
8530bc07c75Srie 
854ba2be530Sab 		} else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
855ba2be530Sab 		    (nsym->st_shndx == SHN_COMMON)) {
856ba2be530Sab 			/*
857ba2be530Sab 			 * Take the new symbol.
858ba2be530Sab 			 */
859ba2be530Sab 			sym_override(sdp, nsym, ifl, ofl, ndx, nshndx,
860635216b6SRod Evans 			    nsdflags);
861ba2be530Sab 			return;
862ba2be530Sab 		}
86354d82594Sseizo 	}
86454d82594Sseizo #endif
86554d82594Sseizo 
8667c478bd9Sstevel@tonic-gate 	/*
8677c478bd9Sstevel@tonic-gate 	 * Check the alignment of the symbols.  This can only be tested for if
8687c478bd9Sstevel@tonic-gate 	 * the symbols are not real definitions to a SHT_NOBITS section (ie.
8697c478bd9Sstevel@tonic-gate 	 * they were originally tentative), as in this case the symbol would
8707c478bd9Sstevel@tonic-gate 	 * have a displacement value rather than an alignment.  In other words
8717c478bd9Sstevel@tonic-gate 	 * we can only test this for two relocatable objects.
8727c478bd9Sstevel@tonic-gate 	 */
873de777a60Sab 	/* BEGIN CSTYLED */
8747c478bd9Sstevel@tonic-gate 	if ((osym->st_value != nsym->st_value) &&
8757c478bd9Sstevel@tonic-gate 	    ((sdp->sd_flags & FLG_SY_SPECSEC) &&
8760bc07c75Srie 	    (sdp->sd_sym->st_shndx == SHN_COMMON) &&
877635216b6SRod Evans 	    (nsdflags & FLG_SY_SPECSEC) &&
878ba2be530Sab #if	defined(_ELF64)
8790bc07c75Srie 	    (nsym->st_shndx == SHN_COMMON)) ||
880ba2be530Sab 	    ((ld_targ.t_m.m_mach == EM_AMD64) &&
881ba2be530Sab 	    (sdp->sd_flags & FLG_SY_SPECSEC) &&
8820bc07c75Srie 	    (sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
883635216b6SRod Evans 	    (nsdflags & FLG_SY_SPECSEC) &&
8840bc07c75Srie 	    (nsym->st_shndx == SHN_X86_64_LCOMMON))) {
88554d82594Sseizo #else
8860bc07c75Srie 	    (nsym->st_shndx == SHN_COMMON))) {
88754d82594Sseizo #endif
888de777a60Sab 	/* END CSTYLED */
889de777a60Sab 
8907c478bd9Sstevel@tonic-gate 		const char	*emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
8917c478bd9Sstevel@tonic-gate 		const char	*file;
8927c478bd9Sstevel@tonic-gate 		Xword		salign;
8937c478bd9Sstevel@tonic-gate 		Xword		balign;
8947c478bd9Sstevel@tonic-gate 		uint_t		alignscompliment;
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate 		if (osym->st_value < nsym->st_value) {
8977c478bd9Sstevel@tonic-gate 			salign = osym->st_value;
8987c478bd9Sstevel@tonic-gate 			balign = nsym->st_value;
8997c478bd9Sstevel@tonic-gate 		} else {
9007c478bd9Sstevel@tonic-gate 			salign = nsym->st_value;
9017c478bd9Sstevel@tonic-gate 			balign = osym->st_value;
9027c478bd9Sstevel@tonic-gate 		}
9037c478bd9Sstevel@tonic-gate 
9047c478bd9Sstevel@tonic-gate 		/*
9057c478bd9Sstevel@tonic-gate 		 * If the smaller alignment fits smoothly into the
9067c478bd9Sstevel@tonic-gate 		 * larger alignment - we take it with no warning.
9077c478bd9Sstevel@tonic-gate 		 */
9087c478bd9Sstevel@tonic-gate 		if (S_ALIGN(balign, salign) == balign)
9097c478bd9Sstevel@tonic-gate 			alignscompliment = 1;
9107c478bd9Sstevel@tonic-gate 		else
9117c478bd9Sstevel@tonic-gate 			alignscompliment = 0;
9127c478bd9Sstevel@tonic-gate 
9137c478bd9Sstevel@tonic-gate 		if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
914*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_WARNING,
9155aefb655Srie 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
9167c478bd9Sstevel@tonic-gate 			    MSG_INTL(MSG_STR_ALIGNMENTS),
9177c478bd9Sstevel@tonic-gate 			    sdp->sd_file->ifl_name, EC_XWORD(osym->st_value),
9187c478bd9Sstevel@tonic-gate 			    ifl->ifl_name, EC_XWORD(nsym->st_value));
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate 		/*
9217c478bd9Sstevel@tonic-gate 		 * Having provided the necessary warning indicate which
9227c478bd9Sstevel@tonic-gate 		 * relocatable object we are going to take.
9237c478bd9Sstevel@tonic-gate 		 *
92428bda19cSRod Evans 		 *  -	if one symbol is weak and the other is non-weak
9257c478bd9Sstevel@tonic-gate 		 *	take the non-weak symbol, else
9267c478bd9Sstevel@tonic-gate 		 *
92728bda19cSRod Evans 		 *  -	take the largest alignment (as we still have to check
9287c478bd9Sstevel@tonic-gate 		 *	the symbols size simply save the largest value for
9297c478bd9Sstevel@tonic-gate 		 *	updating later).
9307c478bd9Sstevel@tonic-gate 		 */
9317c478bd9Sstevel@tonic-gate 		if ((obind == STB_WEAK) && (nbind != STB_WEAK))
9327c478bd9Sstevel@tonic-gate 			file = ifl->ifl_name;
9337c478bd9Sstevel@tonic-gate 		else if (obind != nbind)
9347c478bd9Sstevel@tonic-gate 			file = sdp->sd_file->ifl_name;
9357c478bd9Sstevel@tonic-gate 		else {
9367c478bd9Sstevel@tonic-gate 			emsg = MSG_INTL(MSG_SYM_LARGER);
9377c478bd9Sstevel@tonic-gate 			value = balign;
9387c478bd9Sstevel@tonic-gate 		}
9397c478bd9Sstevel@tonic-gate 		if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
940*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_NONE, emsg, file);
9417c478bd9Sstevel@tonic-gate 	}
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 	/*
9447c478bd9Sstevel@tonic-gate 	 * Check the size of the symbols.
9457c478bd9Sstevel@tonic-gate 	 */
9467c478bd9Sstevel@tonic-gate 	if (osym->st_size != nsym->st_size) {
9477c478bd9Sstevel@tonic-gate 		const char	*emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
9487c478bd9Sstevel@tonic-gate 		const char	*file;
9497c478bd9Sstevel@tonic-gate 
9507c478bd9Sstevel@tonic-gate 		if (!(ofl->ofl_flags & FLG_OF_NOWARN))
951*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR),
952*1007fd6fSAli Bahrami 			    demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES),
953*1007fd6fSAli Bahrami 			    sdp->sd_file->ifl_name, EC_XWORD(osym->st_size),
954*1007fd6fSAli Bahrami 			    ifl->ifl_name, EC_XWORD(nsym->st_size));
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 		/*
9587c478bd9Sstevel@tonic-gate 		 * This symbol has already been compared to an SO definition,
9597c478bd9Sstevel@tonic-gate 		 * as per the runtime behavior, ignore extra definitions.
9607c478bd9Sstevel@tonic-gate 		 */
9617c478bd9Sstevel@tonic-gate 		if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
9627c478bd9Sstevel@tonic-gate 			if (!(ofl->ofl_flags & FLG_OF_NOWARN))
963*1007fd6fSAli Bahrami 				ld_eprintf(ofl, ERR_NONE, emsg,
9647c478bd9Sstevel@tonic-gate 				    sdp->sd_file->ifl_name);
9657c478bd9Sstevel@tonic-gate 			return;
9667c478bd9Sstevel@tonic-gate 		}
9677c478bd9Sstevel@tonic-gate 
9687c478bd9Sstevel@tonic-gate 		/*
9697c478bd9Sstevel@tonic-gate 		 * Having provided the necessary warning indicate what course
9707c478bd9Sstevel@tonic-gate 		 * of action we are going to take.
9717c478bd9Sstevel@tonic-gate 		 *
97228bda19cSRod Evans 		 *  -	if the file types differ, take the relocatable object
9737c478bd9Sstevel@tonic-gate 		 *	and apply the largest symbol size, else
97428bda19cSRod Evans 		 *  -	if one symbol is weak and the other is non-weak, take
9757c478bd9Sstevel@tonic-gate 		 *	the non-weak symbol, else
97628bda19cSRod Evans 		 *  -	simply take the largest symbol reference.
9777c478bd9Sstevel@tonic-gate 		 */
9787c478bd9Sstevel@tonic-gate 		if (nfile != ofile) {
9797c478bd9Sstevel@tonic-gate 			if (nfile == ET_REL) {
9807c478bd9Sstevel@tonic-gate 				file = ifl->ifl_name;
9817c478bd9Sstevel@tonic-gate 				if (osym->st_size > nsym->st_size) {
9827c478bd9Sstevel@tonic-gate 					size = (size_t)osym->st_size;
9837c478bd9Sstevel@tonic-gate 					emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
9847c478bd9Sstevel@tonic-gate 				}
9857c478bd9Sstevel@tonic-gate 				sym_override(sdp, nsym, ifl, ofl, ndx,
986635216b6SRod Evans 				    nshndx, nsdflags);
9877c478bd9Sstevel@tonic-gate 			} else {
9887c478bd9Sstevel@tonic-gate 				file = sdp->sd_file->ifl_name;
9897c478bd9Sstevel@tonic-gate 				if (osym->st_size < nsym->st_size) {
9907c478bd9Sstevel@tonic-gate 					size = (size_t)nsym->st_size;
9917c478bd9Sstevel@tonic-gate 					emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
9927c478bd9Sstevel@tonic-gate 				}
9937c478bd9Sstevel@tonic-gate 				sym_promote(sdp, nsym, ifl, ofl, ndx,
994635216b6SRod Evans 				    nshndx, nsdflags);
9957c478bd9Sstevel@tonic-gate 			}
9967c478bd9Sstevel@tonic-gate 		} else if (obind != nbind) {
9977c478bd9Sstevel@tonic-gate 			if ((obind == STB_WEAK) && (nbind != STB_WEAK)) {
9987c478bd9Sstevel@tonic-gate 				sym_override(sdp, nsym, ifl, ofl, ndx,
999635216b6SRod Evans 				    nshndx, nsdflags);
10007c478bd9Sstevel@tonic-gate 				file = ifl->ifl_name;
10017c478bd9Sstevel@tonic-gate 			} else
10027c478bd9Sstevel@tonic-gate 				file = sdp->sd_file->ifl_name;
10037c478bd9Sstevel@tonic-gate 		} else {
10047c478bd9Sstevel@tonic-gate 			if (osym->st_size < nsym->st_size) {
10057c478bd9Sstevel@tonic-gate 				sym_override(sdp, nsym, ifl, ofl, ndx,
1006635216b6SRod Evans 				    nshndx, nsdflags);
10077c478bd9Sstevel@tonic-gate 				file = ifl->ifl_name;
10087c478bd9Sstevel@tonic-gate 			} else
10097c478bd9Sstevel@tonic-gate 				file = sdp->sd_file->ifl_name;
10107c478bd9Sstevel@tonic-gate 		}
10117c478bd9Sstevel@tonic-gate 		if (!(ofl->ofl_flags & FLG_OF_NOWARN))
1012*1007fd6fSAli Bahrami 			ld_eprintf(ofl, ERR_NONE, emsg, file);
10137c478bd9Sstevel@tonic-gate 		if (size)
10147c478bd9Sstevel@tonic-gate 			sdp->sd_sym->st_size = (Xword)size;
10157c478bd9Sstevel@tonic-gate 	} else {
10167c478bd9Sstevel@tonic-gate 		/*
10177c478bd9Sstevel@tonic-gate 		 * If the sizes are the same
10187c478bd9Sstevel@tonic-gate 		 *
101928bda19cSRod Evans 		 *  -	if the file types differ, take the relocatable object,
10207c478bd9Sstevel@tonic-gate 		 *	else
10217c478bd9Sstevel@tonic-gate 		 *
102228bda19cSRod Evans 		 *  -	if one symbol is weak and the other is non-weak, take
10237c478bd9Sstevel@tonic-gate 		 *	the non-weak symbol, else
10247c478bd9Sstevel@tonic-gate 		 *
102528bda19cSRod Evans 		 *  -	take the first reference.
10267c478bd9Sstevel@tonic-gate 		 */
10277c478bd9Sstevel@tonic-gate 		if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN))
10287c478bd9Sstevel@tonic-gate 			return;
10297c478bd9Sstevel@tonic-gate 		else if (((ofile != nfile) && (nfile == ET_REL)) ||
10307c478bd9Sstevel@tonic-gate 		    (((obind == STB_WEAK) && (nbind != STB_WEAK)) &&
10317c478bd9Sstevel@tonic-gate 		    (!((ofile != nfile) && (ofile == ET_REL)))))
10327c478bd9Sstevel@tonic-gate 			sym_override(sdp, nsym, ifl, ofl, ndx,
1033635216b6SRod Evans 			    nshndx, nsdflags);
10347c478bd9Sstevel@tonic-gate 		else
10357c478bd9Sstevel@tonic-gate 			sym_promote(sdp, nsym, ifl, ofl, ndx,
1036635216b6SRod Evans 			    nshndx, nsdflags);
10377c478bd9Sstevel@tonic-gate 	}
10387c478bd9Sstevel@tonic-gate 
10397c478bd9Sstevel@tonic-gate 	/*
10407c478bd9Sstevel@tonic-gate 	 * Enforce the largest alignment if necessary.
10417c478bd9Sstevel@tonic-gate 	 */
10427c478bd9Sstevel@tonic-gate 	if (value)
10437c478bd9Sstevel@tonic-gate 		sdp->sd_sym->st_value = value;
10447c478bd9Sstevel@tonic-gate }
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate /*
10477c478bd9Sstevel@tonic-gate  * Symbol resolution state table.  `Action' describes the required
10487c478bd9Sstevel@tonic-gate  * procedure to be called (if any).
10497c478bd9Sstevel@tonic-gate  */
10507c478bd9Sstevel@tonic-gate static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *,
1051635216b6SRod Evans     Sym *, Ifl_desc *, Ofl_desc *, int, Word, sd_flag_t) = {
10527c478bd9Sstevel@tonic-gate 
10537c478bd9Sstevel@tonic-gate /*				defined		undef		tent	*/
10547c478bd9Sstevel@tonic-gate /*				ET_REL		ET_REL		ET_REL	*/
10557c478bd9Sstevel@tonic-gate 
10567c478bd9Sstevel@tonic-gate /*  0 defined REF_DYN_SEEN */	sym_tworeals,	sym_promote,	sym_realtent,
10577c478bd9Sstevel@tonic-gate /*  1   undef REF_DYN_SEEN */	sym_override,	sym_override,	sym_override,
10587c478bd9Sstevel@tonic-gate /*  2    tent REF_DYN_SEEN */	sym_realtent,	sym_promote,	sym_twotent,
10597c478bd9Sstevel@tonic-gate /*  3 defined REF_DYN_NEED */	sym_tworeals,	sym_typecheck,	sym_realtent,
10607c478bd9Sstevel@tonic-gate /*  4   undef REF_DYN_NEED */	sym_override,	sym_override,	sym_override,
10617c478bd9Sstevel@tonic-gate /*  5    tent REF_DYN_NEED */	sym_realtent,	sym_typecheck,	sym_twotent,
10627c478bd9Sstevel@tonic-gate /*  6 defined REF_REL_NEED */	sym_tworeals,	sym_typecheck,	sym_realtent,
10637c478bd9Sstevel@tonic-gate /*  7   undef REF_REL_NEED */	sym_override,	sym_twoundefs,	sym_override,
10647c478bd9Sstevel@tonic-gate /*  8    tent REF_REL_NEED */	sym_realtent,	sym_null,	sym_twotent,
10657c478bd9Sstevel@tonic-gate 
10667c478bd9Sstevel@tonic-gate /*				defined		undef		tent	*/
10677c478bd9Sstevel@tonic-gate /*				ET_DYN		ET_DYN		ET_DYN	*/
10687c478bd9Sstevel@tonic-gate 
10697c478bd9Sstevel@tonic-gate /*  9 defined REF_DYN_SEEN */	sym_tworeals,	sym_null,	sym_realtent,
10707c478bd9Sstevel@tonic-gate /* 10   undef REF_DYN_SEEN */	sym_override,	sym_mach_check,	sym_override,
10717c478bd9Sstevel@tonic-gate /* 11    tent REF_DYN_SEEN */	sym_realtent,	sym_null,	sym_twotent,
10727c478bd9Sstevel@tonic-gate /* 12 defined REF_DYN_NEED */	sym_tworeals,	sym_null,	sym_realtent,
10737c478bd9Sstevel@tonic-gate /* 13   undef REF_DYN_NEED */	sym_override,	sym_null,	sym_override,
10747c478bd9Sstevel@tonic-gate /* 14    tent REF_DYN_NEED */	sym_realtent,	sym_null,	sym_twotent,
10757c478bd9Sstevel@tonic-gate /* 15 defined REF_REL_NEED */	sym_tworeals,	sym_null,	sym_realtent,
10767c478bd9Sstevel@tonic-gate /* 16   undef REF_REL_NEED */	sym_override,	sym_mach_check,	sym_override,
10777c478bd9Sstevel@tonic-gate /* 17    tent REF_REL_NEED */	sym_realtent,	sym_null,	sym_twotent
10787c478bd9Sstevel@tonic-gate 
10797c478bd9Sstevel@tonic-gate };
10807c478bd9Sstevel@tonic-gate 
10817c478bd9Sstevel@tonic-gate uintptr_t
10825aefb655Srie ld_sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx,
1083635216b6SRod Evans     Word nshndx, sd_flag_t nsdflags)
10847c478bd9Sstevel@tonic-gate {
10857c478bd9Sstevel@tonic-gate 	int		row, column;		/* State table coordinates */
10867c478bd9Sstevel@tonic-gate 	Sym		*osym = sdp->sd_sym;
108708278a5eSRod Evans 	sd_flag_t	osdflags = sdp->sd_flags;
10887c478bd9Sstevel@tonic-gate 	Is_desc		*isp;
108960758829Srie 	Half		vis = 0, nfile = ifl->ifl_ehdr->e_type;
109060758829Srie 	Half		oref = sdp->sd_ref;
10917c478bd9Sstevel@tonic-gate 
10927c478bd9Sstevel@tonic-gate 	/*
10937c478bd9Sstevel@tonic-gate 	 * Determine the original symbols definition (defines row in Action[]).
10947c478bd9Sstevel@tonic-gate 	 */
109508278a5eSRod Evans 	if (osdflags & FLG_SY_TENTSYM)
10967c478bd9Sstevel@tonic-gate 		row = SYM_TENTATIVE;
10970bc07c75Srie 	else if ((sdp->sd_sym->st_shndx == SHN_UNDEF) ||
10980bc07c75Srie 	    (sdp->sd_sym->st_shndx == SHN_SUNW_IGNORE))
10997c478bd9Sstevel@tonic-gate 		row = SYM_UNDEFINED;
11007c478bd9Sstevel@tonic-gate 	else
11017c478bd9Sstevel@tonic-gate 		row = SYM_DEFINED;
11027c478bd9Sstevel@tonic-gate 
11037c478bd9Sstevel@tonic-gate 	/*
11047c478bd9Sstevel@tonic-gate 	 * If the input file is an implicit shared object then we don't need
11057c478bd9Sstevel@tonic-gate 	 * to bind to any symbols within it other than to verify that any
11067c478bd9Sstevel@tonic-gate 	 * undefined references will be closed (implicit shared objects are only
11077c478bd9Sstevel@tonic-gate 	 * processed when no undefined symbols are required as a result of the
11087c478bd9Sstevel@tonic-gate 	 * link-edit (see process_dynamic())).
11097c478bd9Sstevel@tonic-gate 	 */
11107c478bd9Sstevel@tonic-gate 	if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) &&
11117c478bd9Sstevel@tonic-gate 	    (row != SYM_UNDEFINED))
11127c478bd9Sstevel@tonic-gate 		return (1);
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate 	/*
11157c478bd9Sstevel@tonic-gate 	 * Finish computing the Action[] row by applying the symbols reference
11167c478bd9Sstevel@tonic-gate 	 * together with the input files type.
11177c478bd9Sstevel@tonic-gate 	 */
11187c478bd9Sstevel@tonic-gate 	row = row + (REF_NUM * sdp->sd_ref);
11197c478bd9Sstevel@tonic-gate 	if (nfile == ET_DYN)
11207c478bd9Sstevel@tonic-gate 		row += (REF_NUM * SYM_NUM);
11217c478bd9Sstevel@tonic-gate 
112260758829Srie 	/*
112360758829Srie 	 * If either the original or new symbol originates from a relocatable
112460758829Srie 	 * object, determine the appropriate visibility for the resolved symbol.
112560758829Srie 	 */
112660758829Srie 	if ((oref == REF_REL_NEED) || (nfile == ET_REL))
112760758829Srie 		vis = sym_visibility(sdp, nsym, ifl, ofl);
112860758829Srie 
11297c478bd9Sstevel@tonic-gate 	/*
11307c478bd9Sstevel@tonic-gate 	 * Determine the new symbols definition (defines column in Action[]).
11317c478bd9Sstevel@tonic-gate 	 */
1132635216b6SRod Evans 	if ((nsdflags & FLG_SY_SPECSEC) &&
11330bc07c75Srie 	    (nsym->st_shndx == SHN_COMMON)) {
11347c478bd9Sstevel@tonic-gate 		column = SYM_TENTATIVE;
1135635216b6SRod Evans 		nsdflags |= FLG_SY_TENTSYM;
1136ba2be530Sab #if	defined(_ELF64)
1137ba2be530Sab 	} else if ((ld_targ.t_m.m_mach == EM_AMD64) &&
1138635216b6SRod Evans 	    (nsdflags & FLG_SY_SPECSEC) &&
11390bc07c75Srie 	    (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
114054d82594Sseizo 		column = SYM_TENTATIVE;
1141635216b6SRod Evans 		nsdflags |= FLG_SY_TENTSYM;
114254d82594Sseizo #endif
11430bc07c75Srie 	} else if ((nsym->st_shndx == SHN_UNDEF) ||
11440bc07c75Srie 	    (nsym->st_shndx == SHN_SUNW_IGNORE)) {
11457c478bd9Sstevel@tonic-gate 		column = SYM_UNDEFINED;
11467c478bd9Sstevel@tonic-gate 		nshndx = SHN_UNDEF;
11477c478bd9Sstevel@tonic-gate 	} else {
11487c478bd9Sstevel@tonic-gate 		column = SYM_DEFINED;
11497c478bd9Sstevel@tonic-gate 		/*
11507c478bd9Sstevel@tonic-gate 		 * If the new symbol is from a shared library and it is
11517c478bd9Sstevel@tonic-gate 		 * associated with a SHT_NOBITS section then this symbol
11527c478bd9Sstevel@tonic-gate 		 * originated from a tentative symbol.
11537c478bd9Sstevel@tonic-gate 		 */
1154635216b6SRod Evans 		if (((nsdflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) {
11557c478bd9Sstevel@tonic-gate 			isp = ifl->ifl_isdesc[nshndx];
11567c478bd9Sstevel@tonic-gate 			if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) {
11577c478bd9Sstevel@tonic-gate 				column = SYM_TENTATIVE;
1158635216b6SRod Evans 				nsdflags |= FLG_SY_TENTSYM;
11597c478bd9Sstevel@tonic-gate 			}
11607c478bd9Sstevel@tonic-gate 		}
11617c478bd9Sstevel@tonic-gate 	}
11627c478bd9Sstevel@tonic-gate 
11635aefb655Srie 	DBG_CALL(Dbg_syms_resolving(ofl, ndx, sdp->sd_name, row, column,
11645aefb655Srie 	    osym, nsym, sdp, ifl));
11657c478bd9Sstevel@tonic-gate 
11667c478bd9Sstevel@tonic-gate 	/*
11677c478bd9Sstevel@tonic-gate 	 * Record the input filename on the defined files list for possible
11687c478bd9Sstevel@tonic-gate 	 * later diagnostics.  The `sa_dfiles' list is used to maintain the list
11697c478bd9Sstevel@tonic-gate 	 * of shared objects that define the same symbol.  This list is only
11707c478bd9Sstevel@tonic-gate 	 * generated when the -m option is in effect and is used to list
11717c478bd9Sstevel@tonic-gate 	 * multiple (interposed) definitions of a symbol (refer to ldmap_out()).
11727c478bd9Sstevel@tonic-gate 	 */
11730bc07c75Srie 	if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nsym->st_shndx != SHN_UNDEF) &&
1174635216b6SRod Evans 	    ((nsdflags & FLG_SY_SPECSEC) == 0))
117557ef7aa9SRod Evans 		if (aplist_append(&sdp->sd_aux->sa_dfiles, ifl->ifl_name,
117657ef7aa9SRod Evans 		    AL_CNT_SDP_DFILES) == NULL)
11777c478bd9Sstevel@tonic-gate 			return (S_ERROR);
11787c478bd9Sstevel@tonic-gate 
11797c478bd9Sstevel@tonic-gate 	/*
11807c478bd9Sstevel@tonic-gate 	 * Perform the required resolution.
11817c478bd9Sstevel@tonic-gate 	 */
1182635216b6SRod Evans 	Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
11837c478bd9Sstevel@tonic-gate 
118460758829Srie 	/*
118560758829Srie 	 * Apply any visibility requirements.  If a SINGLETON has been
118660758829Srie 	 * established, make sure no symbol reduction indicators remain
118760758829Srie 	 * associated with the symbol, and indicate that the symbol can not
118860758829Srie 	 * be directly bound to.
118960758829Srie 	 */
119060758829Srie 	if ((oref == REF_REL_NEED) || (nfile == ET_REL)) {
119160758829Srie 		if ((vis == STV_EXPORTED) || (vis == STV_SINGLETON)) {
1192635216b6SRod Evans 			sdp->sd_flags &= ~MSK_SY_LOCAL;
119360758829Srie 
119460758829Srie 			if (vis == STV_EXPORTED)
1195635216b6SRod Evans 				sdp->sd_flags |= FLG_SY_EXPORT;
119660758829Srie 			else {
1197635216b6SRod Evans 				sdp->sd_flags |= (FLG_SY_NDIR | FLG_SY_SINGLE);
119860758829Srie 
119928bda19cSRod Evans 				if (sdp->sd_ref == REF_REL_NEED) {
120028bda19cSRod Evans 					ofl->ofl_flags1 |=
120128bda19cSRod Evans 					    (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
120228bda19cSRod Evans 				}
120360758829Srie 			}
120460758829Srie 		} else if (vis == STV_PROTECTED) {
1205635216b6SRod Evans 			sdp->sd_flags |= FLG_SY_PROTECT;
120660758829Srie 		} else if ((vis == STV_INTERNAL) || (vis == STV_HIDDEN)) {
1207635216b6SRod Evans 			sdp->sd_flags |= FLG_SY_HIDDEN;
120860758829Srie 		} else if (vis == STV_ELIMINATE) {
1209635216b6SRod Evans 			sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
121060758829Srie 		}
121160758829Srie 
121260758829Srie 		sdp->sd_sym->st_other =
121360758829Srie 		    (sdp->sd_sym->st_other & ~MSK_SYM_VISIBILITY) | vis;
121460758829Srie 	}
121560758829Srie 
12167c478bd9Sstevel@tonic-gate 	/*
12177c478bd9Sstevel@tonic-gate 	 * If the symbol has been resolved to the new input file, and this is
12187c478bd9Sstevel@tonic-gate 	 * a versioned relocatable object, then the version information of the
12197c478bd9Sstevel@tonic-gate 	 * new symbol must be promoted to the versioning of the output file.
12207c478bd9Sstevel@tonic-gate 	 */
12217c478bd9Sstevel@tonic-gate 	if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) &&
12220bc07c75Srie 	    (nsym->st_shndx != SHN_UNDEF))
12235aefb655Srie 		ld_vers_promote(sdp, ndx, ifl, ofl);
12247c478bd9Sstevel@tonic-gate 
12257c478bd9Sstevel@tonic-gate 	/*
12267c478bd9Sstevel@tonic-gate 	 * Determine whether a mapfile reference has been satisfied.  Mapfile
12277c478bd9Sstevel@tonic-gate 	 * symbol references augment symbols that should be contributed from
12287c478bd9Sstevel@tonic-gate 	 * the relocatable objects used to build the output image.  If a
12297c478bd9Sstevel@tonic-gate 	 * relocatable object doesn't provide one of the mapfile symbol
12307c478bd9Sstevel@tonic-gate 	 * references then somethings amiss, and will be flagged during symbol
12317c478bd9Sstevel@tonic-gate 	 * validation.
12327c478bd9Sstevel@tonic-gate 	 */
12337c478bd9Sstevel@tonic-gate 	if ((nfile == ET_REL) && ((sdp->sd_flags &
12347c478bd9Sstevel@tonic-gate 	    (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) {
12357c478bd9Sstevel@tonic-gate 		/*
12367c478bd9Sstevel@tonic-gate 		 * Extern and parent references are satisfied by references from
12377c478bd9Sstevel@tonic-gate 		 * a relocatable object.  Note that we let *any* symbol type
12387c478bd9Sstevel@tonic-gate 		 * satisfy this reference, to be as flexible as possible with
12397c478bd9Sstevel@tonic-gate 		 * user written mapfiles.  It could be questionable, for
12407c478bd9Sstevel@tonic-gate 		 * example, if what a user expects to be an extern reference is
12417c478bd9Sstevel@tonic-gate 		 * actually found to be a definition in a relocatable object.
12427c478bd9Sstevel@tonic-gate 		 *
12437c478bd9Sstevel@tonic-gate 		 * Any other mapfile reference (typically for versioning
12447c478bd9Sstevel@tonic-gate 		 * information) simply augments a relocatables definition.
12457c478bd9Sstevel@tonic-gate 		 */
12467c478bd9Sstevel@tonic-gate 		if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) ||
12470bc07c75Srie 		    ((sdp->sd_sym->st_shndx != SHN_UNDEF) &&
12487c478bd9Sstevel@tonic-gate 		    (sdp->sd_ref == REF_REL_NEED)))
12497c478bd9Sstevel@tonic-gate 			sdp->sd_flags |= FLG_SY_MAPUSED;
12507c478bd9Sstevel@tonic-gate 	}
12517c478bd9Sstevel@tonic-gate 
125208278a5eSRod Evans 	/*
125308278a5eSRod Evans 	 * Make sure any special symbol requirements are carried over.
125408278a5eSRod Evans 	 */
125508278a5eSRod Evans 	if ((osdflags & FLG_SY_CAP) || (nsdflags & FLG_SY_CAP))
125608278a5eSRod Evans 		sdp->sd_flags |= FLG_SY_CAP;
125708278a5eSRod Evans 
12585aefb655Srie 	DBG_CALL(Dbg_syms_resolved(ofl, sdp));
12597c478bd9Sstevel@tonic-gate 
12607c478bd9Sstevel@tonic-gate 	return (1);
12617c478bd9Sstevel@tonic-gate }
1262