Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  *	Copyright (c) 1988 AT&T
     24  *	  All Rights Reserved
     25  *
     26  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     27  * Use is subject to license terms.
     28  */
     29 
     30 /*
     31  * Symbol table resolution
     32  */
     33 #define	ELF_TARGET_AMD64
     34 
     35 #include	<stdio.h>
     36 #include	<debug.h>
     37 #include	"msg.h"
     38 #include	"_libld.h"
     39 
     40 
     41 /*
     42  * Categorize the symbol types that are applicable to the resolution process.
     43  */
     44 typedef	enum {
     45 	SYM_DEFINED,		/* Defined symbol (SHN_ABS or shndx != 0) */
     46 	SYM_UNDEFINED,		/* Undefined symbol (SHN_UNDEF) */
     47 	SYM_TENTATIVE,		/* Tentative symbol (SHN_COMMON) */
     48 	SYM_NUM			/* the number of symbol types */
     49 } Symtype;
     50 
     51 /*
     52  * Do nothing.
     53  */
     54 /* ARGSUSED0 */
     55 static void
     56 sym_null(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
     57     int ndx, Word nshndx, sd_flag_t nsdflags)
     58 {
     59 }
     60 
     61 static void
     62 sym_visibility_diag(Error err, Sym_desc *sdp, Sym *osym, Sym *nsym,
     63     Ifl_desc *ifl, Ofl_desc *ofl)
     64 {
     65 	Conv_inv_buf_t	inv_obuf, inv_nbuf;
     66 
     67 	eprintf(ofl->ofl_lml, err, MSG_INTL(MSG_SYM_CONFVIS),
     68 	    demangle(sdp->sd_name));
     69 	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_VISTYPES),
     70 	    sdp->sd_file->ifl_name, conv_sym_other(osym->st_other, &inv_obuf),
     71 	    ifl->ifl_name, conv_sym_other(nsym->st_other, &inv_nbuf));
     72 
     73 	if (err == ERR_FATAL)
     74 		ofl->ofl_flags |= FLG_OF_FATAL;
     75 	else
     76 		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
     77 		    ifl->ifl_name);
     78 }
     79 
     80 /*
     81  * STV_VISIBILITY rules for STV_DEFAULT/INTERNAL/HIDDEN/PROTECTED say that the
     82  * most restrictive visibility value should be taken.  The precedence is:
     83  *
     84  *    (most restrictive) INTERNAL -> HIDDEN -> PROTECTED -> DEFAULT  (least)
     85  *
     86  * The STV_EXPORT and STV_SINGLETON visibilities are slightly different, in that
     87  * the visibility must remain global and can not be reduced in any way.
     88  *
     89  * Resolution of different visibilities between two relocatable objects can
     90  * take the following actions:
     91  *
     92  *  i.     if applicable, the most restrictive action is silently taken.
     93  *  ii.    if a mapfile visibility definition competes with a more restrictive
     94  *         relocatable object definition, then a warning is generated, but the
     95  *         the more restrictive visibility is taken.
     96  *  iii.   in the case of conflicts with an EXPORTED or SINGLETON symbol with
     97  *	   any type of visibility between relocatable objects, the combination
     98  *	   is deemed fatal.
     99  *
    100  *                                  new visibility
    101  *                    D        I         H         P         X         S
    102  *                 ------------------------------------------------------------
    103  *              D |   D        I(mw)     H(mw)     P         X         S
    104  *   original   I |   I        I         I         I         X(mw/of)  S(mw/of)
    105  *  visibility  H |   H        I(mw)     H         H         X(mw/of)  S(mw/of)
    106  *              P |   P        I(mw)     H(mw)     P         X(mw/of)  S(mw/of)
    107  *              X |   X        I(mw/of)  H(mw/of)  P(mw/of)  X         S
    108  *              S |   S        I(mw/of)  H(mw/of)  P(mw/of)  S         S
    109  * where:
    110  *
    111  *  mw -  mapfile warning: if the original symbol originates from a mapfile
    112  *        then warn the user that their scope definition is being overridden.
    113  *  of -  object definitions are fatal: any combination of relocatable object
    114  *        visibilities that conflict with a SINGLETON and EXPORTED are fatal.
    115  *
    116  * Note, an eliminate symbol (STV_ELIMINATE) is treated as hidden (STV_HIDDEN)
    117  * for processing through this state table.
    118  */
    119 static Half
    120 sym_visibility(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl)
    121 {
    122 	Sym	*osym = sdp->sd_sym;
    123 	uchar_t	wovis, ovis;
    124 	uchar_t	wnvis, nvis;
    125 
    126 	wovis = ovis = ELF_ST_VISIBILITY(osym->st_other);
    127 	wnvis = nvis = ELF_ST_VISIBILITY(nsym->st_other);
    128 
    129 	/*
    130 	 * If the original visibilities are eliminate, assign them hidden for
    131 	 * the state table processing.  The original visibility, rather than
    132 	 * the working visibility, will be returned to the caller.
    133 	 */
    134 	if (wovis == STV_ELIMINATE)
    135 		wovis = STV_HIDDEN;
    136 	if (wnvis == STV_ELIMINATE)
    137 		wnvis = STV_HIDDEN;
    138 
    139 	/*
    140 	 * The most complex visibility resolution is between two relocatable
    141 	 * objects.  However, in the case of SINGLETONS we also want to catch
    142 	 * any singleton definitions within shared objects.  Relocatable objects
    143 	 * that bind to these symbols inherit the singleton visibility as this
    144 	 * efficiently triggers ld.so.1 into carrying out the appropriate
    145 	 * runtime symbol search.  Any other resolution between a relocatable
    146 	 * object and a shared object will retain the relocatable objects
    147 	 * visibility.
    148 	 */
    149 	if ((sdp->sd_ref == REF_REL_NEED) &&
    150 	    (ifl->ifl_ehdr->e_type == ET_DYN)) {
    151 		if ((sdp->sd_sym->st_shndx == SHN_UNDEF) &&
    152 		    (nsym->st_shndx != SHN_UNDEF) && (wnvis == STV_SINGLETON))
    153 			return (STV_SINGLETON);
    154 		else
    155 			return (ovis);
    156 	}
    157 	if ((sdp->sd_ref != REF_REL_NEED) &&
    158 	    (ifl->ifl_ehdr->e_type == ET_REL)) {
    159 		if ((sdp->sd_sym->st_shndx != SHN_UNDEF) &&
    160 		    (nsym->st_shndx == SHN_UNDEF) && (wovis == STV_SINGLETON))
    161 			return (STV_SINGLETON);
    162 		else
    163 			return (nvis);
    164 	}
    165 
    166 	/*
    167 	 * If the visibilities are the same, we're done.  If the working
    168 	 * visibilities differ from the original, then one must have been
    169 	 * STV_HIDDEN and the other STV_ELIMINATE.
    170 	 */
    171 	if (wovis == wnvis) {
    172 		if (ovis == nvis)
    173 			return (nvis);
    174 		else
    175 			return (STV_ELIMINATE);
    176 	}
    177 
    178 	/*
    179 	 * An EXPORTED symbol or SINGLETON symbol can not be demoted, any
    180 	 * conflicting visibility from another object is fatal.  A conflicting
    181 	 * visibility from a mapfile produces a warning, as the mapfile
    182 	 * definition can be overridden.
    183 	 */
    184 	if ((wnvis == STV_EXPORTED) || (wnvis == STV_SINGLETON)) {
    185 		if ((wovis != STV_DEFAULT) && (wovis != STV_EXPORTED) &&
    186 		    (wovis != STV_SINGLETON)) {
    187 			if (sdp->sd_flags & FLG_SY_MAPFILE) {
    188 				sym_visibility_diag(ERR_WARNING, sdp, osym,
    189 				    nsym, ifl, ofl);
    190 			} else {
    191 				sym_visibility_diag(ERR_FATAL, sdp, osym,
    192 				    nsym, ifl, ofl);
    193 			}
    194 		}
    195 		return (nvis);
    196 	}
    197 	if (wovis == STV_SINGLETON) {
    198 		if ((wnvis == STV_EXPORTED) || (wnvis == STV_DEFAULT))
    199 			return (STV_SINGLETON);
    200 		if (sdp->sd_flags & FLG_SY_MAPFILE) {
    201 			sym_visibility_diag(ERR_WARNING, sdp, osym,
    202 			    nsym, ifl, ofl);
    203 		} else {
    204 			sym_visibility_diag(ERR_FATAL, sdp, osym,
    205 			    nsym, ifl, ofl);
    206 		}
    207 		return (nvis);
    208 	}
    209 	if (wovis == STV_EXPORTED) {
    210 		if (wnvis == STV_SINGLETON)
    211 			return (STV_SINGLETON);
    212 		if (wnvis == STV_DEFAULT)
    213 			return (STV_EXPORTED);
    214 		if (sdp->sd_flags & FLG_SY_MAPFILE) {
    215 			sym_visibility_diag(ERR_WARNING, sdp, osym,
    216 			    nsym, ifl, ofl);
    217 		} else {
    218 			sym_visibility_diag(ERR_FATAL, sdp, osym,
    219 			    nsym, ifl, ofl);
    220 		}
    221 		return (nvis);
    222 	}
    223 
    224 	/*
    225 	 * Now that symbols with the same visibility, and all instances of
    226 	 * SINGLETON's have been dealt with, we're left with visibilities that
    227 	 * differ, but can be dealt with in the order of how restrictive the
    228 	 * visibilities are.  When a differing visibility originates from a
    229 	 * mapfile definition, produces a warning, as the mapfile definition
    230 	 * can be overridden by the relocatable object.
    231 	 */
    232 	if ((wnvis == STV_INTERNAL) || (wovis == STV_INTERNAL)) {
    233 		if ((wnvis == STV_INTERNAL) &&
    234 		    (sdp->sd_flags & FLG_SY_MAPFILE)) {
    235 			sym_visibility_diag(ERR_WARNING, sdp, osym, nsym,
    236 			    ifl, ofl);
    237 		}
    238 		return (STV_INTERNAL);
    239 
    240 	} else if ((wnvis == STV_HIDDEN) || (wovis == STV_HIDDEN)) {
    241 		if ((wnvis == STV_HIDDEN) &&
    242 		    (sdp->sd_flags & FLG_SY_MAPFILE)) {
    243 			sym_visibility_diag(ERR_WARNING, sdp, osym, nsym,
    244 			    ifl, ofl);
    245 		}
    246 
    247 		/*
    248 		 * In the case of STV_ELIMINATE and STV_HIDDEN, the working
    249 		 * visibility can differ from the original visibility, so make
    250 		 * sure to return the original visibility.
    251 		 */
    252 		if ((ovis == STV_ELIMINATE) || (nvis == STV_ELIMINATE))
    253 			return (STV_ELIMINATE);
    254 		else
    255 			return (STV_HIDDEN);
    256 
    257 	} else if ((wnvis == STV_PROTECTED) || (wovis == STV_PROTECTED))
    258 		return (STV_PROTECTED);
    259 
    260 	return (STV_DEFAULT);
    261 }
    262 
    263 /*
    264  * Check if two symbols types are compatible
    265  */
    266 /*ARGSUSED4*/
    267 static void
    268 sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
    269     int ndx, Word nshndx, sd_flag_t nsdflags)
    270 {
    271 	uchar_t		otype = ELF_ST_TYPE(sdp->sd_sym->st_info);
    272 	uchar_t		ntype = ELF_ST_TYPE(nsym->st_info);
    273 	Conv_inv_buf_t	inv_buf1, inv_buf2;
    274 
    275 	/*
    276 	 * Perform any machine specific type checking.
    277 	 */
    278 	if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) &&
    279 	    (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl))
    280 		return;
    281 
    282 	/*
    283 	 * NOTYPE's can be combined with other types, only give an error if
    284 	 * combining two differing types without NOTYPE.
    285 	 */
    286 	if ((otype == ntype) || (otype == STT_NOTYPE) || (ntype == STT_NOTYPE))
    287 		return;
    288 
    289 	eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
    290 	    demangle(sdp->sd_name));
    291 	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
    292 	    sdp->sd_file->ifl_name,
    293 	    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 0, &inv_buf1),
    294 	    ifl->ifl_name,
    295 	    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 0, &inv_buf2));
    296 }
    297 
    298 /*ARGSUSED4*/
    299 static void
    300 sym_mach_check(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
    301     int ndx, Word nshndx, sd_flag_t nsdflags)
    302 {
    303 	/*
    304 	 * Perform any machine specific type checking.
    305 	 */
    306 	if (ld_targ.t_ms.ms_mach_sym_typecheck != NULL)
    307 		(void) (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym,
    308 		    ifl, ofl);
    309 }
    310 
    311 /*
    312  * Promote the symbols reference.
    313  */
    314 static void
    315 /* ARGSUSED4 */
    316 sym_promote(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
    317     int ndx, Word nshndx, sd_flag_t nsdflags)
    318 {
    319 	Word	shndx = nsym->st_shndx;
    320 
    321 	sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
    322 
    323 	/*
    324 	 * If the old symbol is from a shared object and the new symbol is a
    325 	 * reference from a relocatable object, promote the old symbols
    326 	 * reference.
    327 	 */
    328 	if ((sdp->sd_ref == REF_DYN_SEEN) &&
    329 	    (ifl->ifl_ehdr->e_type == ET_REL)) {
    330 		sdp->sd_ref = REF_DYN_NEED;
    331 
    332 		/*
    333 		 * If this is an undefined symbol it must be a relocatable
    334 		 * object overriding a shared object.  In this case also
    335 		 * override the reference name so that any undefined symbol
    336 		 * diagnostics will refer to the relocatable object name.
    337 		 */
    338 		if (shndx == SHN_UNDEF)
    339 			sdp->sd_aux->sa_rfile = ifl->ifl_name;
    340 
    341 		/*
    342 		 * If this symbol is an undefined, or common, determine whether
    343 		 * it is a global or weak reference (see build_osym(), where
    344 		 * REF_DYN_NEED definitions are returned back to undefines).
    345 		 */
    346 		if (((shndx == SHN_UNDEF) || ((nsdflags & FLG_SY_SPECSEC) &&
    347 		    (shndx == SHN_COMMON))) &&
    348 		    (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
    349 			sdp->sd_flags |= FLG_SY_GLOBREF;
    350 
    351 	}
    352 }
    353 
    354 /*
    355  * Override a symbol.
    356  */
    357 static void
    358 sym_override(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
    359     int ndx, Word nshndx, sd_flag_t nsdflags)
    360 {
    361 	Sym	*osym = sdp->sd_sym;
    362 	Word	link;
    363 
    364 	/*
    365 	 * In the case of a WEAK UNDEF symbol don't let a symbol from an
    366 	 * unavailable object override the symbol definition.  This is because
    367 	 * this symbol *may* not be present in a future object and by promoting
    368 	 * this symbol we are actually causing bindings (PLTS) to be formed
    369 	 * to this symbol.  Instead let the 'generic' weak binding take place.
    370 	 */
    371 	if ((ELF_ST_BIND(osym->st_info) == STB_WEAK) &&
    372 	    (sdp->sd_sym->st_shndx == SHN_UNDEF) &&
    373 	    ((ifl->ifl_flags & FLG_IF_NEEDED) == 0))
    374 		return;
    375 
    376 	sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
    377 
    378 	/*
    379 	 * This symbol has already been compared to an SO definition,
    380 	 * as per the runtime behavior, ignore extra definitions.
    381 	 */
    382 	if ((sdp->sd_flags & FLG_SY_SOFOUND) &&
    383 	    (ifl->ifl_ehdr->e_type == ET_DYN))
    384 		return;
    385 
    386 	/*
    387 	 * Mark the symbol as available and copy the new symbols contents.
    388 	 */
    389 	sdp->sd_flags &= ~FLG_SY_NOTAVAIL;
    390 	*osym = *nsym;
    391 	sdp->sd_shndx = nshndx;
    392 	sdp->sd_flags &= ~FLG_SY_SPECSEC;
    393 	sdp->sd_flags |= (nsdflags & (FLG_SY_SPECSEC | FLG_SY_TENTSYM));
    394 
    395 	/*
    396 	 * If the new symbol has PROTECTED visibility, mark it.  If a PROTECTED
    397 	 * symbol is copy relocated, a warning message will be printed.  See
    398 	 * reloc_exec().
    399 	 */
    400 	if (ELF_ST_VISIBILITY(nsym->st_other) == STV_PROTECTED)
    401 		sdp->sd_flags |= FLG_SY_PROT;
    402 	else
    403 		sdp->sd_flags &= ~FLG_SY_PROT;
    404 
    405 	/*
    406 	 * Establish the symbols reference.  If the new symbol originates from a
    407 	 * relocatable object then this reference becomes needed, otherwise
    408 	 * the new symbol must be from a shared object.  In this case only
    409 	 * promote the symbol to needed if we presently have a reference from a
    410 	 * relocatable object.
    411 	 */
    412 	if (ifl->ifl_ehdr->e_type == ET_REL) {
    413 		sdp->sd_ref = REF_REL_NEED;
    414 
    415 		if (nsym->st_shndx == SHN_UNDEF) {
    416 			/*
    417 			 * If this is an undefined symbol it must be a
    418 			 * relocatable object overriding a shared object.  In
    419 			 * this case also override the reference name so that
    420 			 * any undefined symbol diagnostics will refer to the
    421 			 * relocatable object name.
    422 			 */
    423 			sdp->sd_aux->sa_rfile = ifl->ifl_name;
    424 		} else {
    425 			/*
    426 			 * Under -Bnodirect, all exported interfaces that have
    427 			 * not explicitly been defined protected or directly
    428 			 * bound to, are tagged to prevent direct binding.
    429 			 */
    430 			if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) &&
    431 			    ((sdp->sd_flags &
    432 			    (FLG_SY_PROTECT | FLG_SY_DIR)) == 0))
    433 				sdp->sd_flags |= FLG_SY_NDIR;
    434 		}
    435 
    436 		/*
    437 		 * If this symbol is an undefined, or common, determine whether
    438 		 * it is a global or weak reference (see build_osym(), where
    439 		 * REF_DYN_NEED definitions are returned back to undefines).
    440 		 */
    441 		if (((nsym->st_shndx == SHN_UNDEF) ||
    442 		    ((nsdflags & FLG_SY_SPECSEC) &&
    443 		    (nsym->st_shndx == SHN_COMMON))) &&
    444 		    (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
    445 			sdp->sd_flags |= FLG_SY_GLOBREF;
    446 		else
    447 			sdp->sd_flags &= ~FLG_SY_GLOBREF;
    448 	} else {
    449 		if (sdp->sd_ref == REF_REL_NEED)
    450 			sdp->sd_ref = REF_DYN_NEED;
    451 
    452 		/*
    453 		 * Determine the symbols availability.  A symbol is determined
    454 		 * to be unavailable if it belongs to a version of a shared
    455 		 * object that this user does not wish to use, or if it belongs
    456 		 * to an implicit shared object.
    457 		 */
    458 		if (ifl->ifl_vercnt) {
    459 			Ver_index	*vip;
    460 			Half		vndx = ifl->ifl_versym[ndx];
    461 
    462 			sdp->sd_aux->sa_dverndx = vndx;
    463 			vip = &ifl->ifl_verndx[vndx];
    464 			if (!(vip->vi_flags & FLG_VER_AVAIL)) {
    465 				sdp->sd_flags |= FLG_SY_NOTAVAIL;
    466 				/*
    467 				 * If this is the first occurrence of an
    468 				 * unavailable symbol record it for possible
    469 				 * use in later error diagnostics
    470 				 * (see sym_undef).
    471 				 */
    472 				if (!(sdp->sd_aux->sa_vfile))
    473 					sdp->sd_aux->sa_vfile = ifl->ifl_name;
    474 			}
    475 		}
    476 		if (!(ifl->ifl_flags & FLG_IF_NEEDED))
    477 			sdp->sd_flags |= FLG_SY_NOTAVAIL;
    478 	}
    479 
    480 	/*
    481 	 * Make sure any symbol association maintained by the original symbol
    482 	 * is cleared and then update the symbols file reference.
    483 	 */
    484 	if ((link = sdp->sd_aux->sa_linkndx) != 0) {
    485 		Sym_desc *	_sdp;
    486 
    487 		_sdp = sdp->sd_file->ifl_oldndx[link];
    488 		_sdp->sd_aux->sa_linkndx = 0;
    489 		sdp->sd_aux->sa_linkndx = 0;
    490 	}
    491 	sdp->sd_file = ifl;
    492 
    493 	/*
    494 	 * Update the input section descriptor to that of the new input file
    495 	 */
    496 	if (((nsdflags & FLG_SY_SPECSEC) == 0) &&
    497 	    (nsym->st_shndx != SHN_UNDEF)) {
    498 		if ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == 0) {
    499 			eprintf(ofl->ofl_lml, ERR_FATAL,
    500 			    MSG_INTL(MSG_SYM_NOSECDEF), demangle(sdp->sd_name),
    501 			    ifl->ifl_name);
    502 			ofl->ofl_flags |= FLG_OF_FATAL;
    503 		}
    504 	}
    505 }
    506 
    507 /*
    508  * Resolve two undefines (only called for two relocatable objects).
    509  */
    510 static void
    511 sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
    512     int ndx, Word nshndx, sd_flag_t nsdflags)
    513 {
    514 	Sym	*osym = sdp->sd_sym;
    515 	uchar_t	obind = ELF_ST_BIND(osym->st_info);
    516 	uchar_t	nbind = ELF_ST_BIND(nsym->st_info);
    517 
    518 	/*
    519 	 * If two relocatable objects define a weak and non-weak undefined
    520 	 * reference, take the non-weak definition.
    521 	 *
    522 	 *		-- or --
    523 	 *
    524 	 * If two relocatable objects define a NOTYPE & another, then
    525 	 * take the other.
    526 	 */
    527 	if (((obind == STB_WEAK) && (nbind != STB_WEAK)) ||
    528 	    (obind == STT_NOTYPE) && (nbind != STT_NOTYPE)) {
    529 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
    530 		return;
    531 	}
    532 	sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
    533 }
    534 
    535 /*
    536  * Resolve two real definitions.
    537  */
    538 static void
    539 sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
    540     int ndx, Word nshndx, sd_flag_t nsdflags)
    541 {
    542 	Conv_inv_buf_t inv_buf1, inv_buf2;
    543 	Sym	*osym = sdp->sd_sym;
    544 	uchar_t	otype = ELF_ST_TYPE(osym->st_info);
    545 	uchar_t	obind = ELF_ST_BIND(osym->st_info);
    546 	uchar_t	ntype = ELF_ST_TYPE(nsym->st_info);
    547 	uchar_t	nbind = ELF_ST_BIND(nsym->st_info);
    548 	Half	ofile = sdp->sd_file->ifl_ehdr->e_type;
    549 	Half	nfile = ifl->ifl_ehdr->e_type;
    550 	int	warn = 0;
    551 
    552 	/*
    553 	 * If both definitions are from relocatable objects, and have non-weak
    554 	 * binding then this is a fatal condition.
    555 	 */
    556 	if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) &&
    557 	    (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) {
    558 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
    559 		    demangle(sdp->sd_name));
    560 		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
    561 		    sdp->sd_file->ifl_name,
    562 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
    563 		    0, &inv_buf1), ifl->ifl_name,
    564 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
    565 		    0, &inv_buf2));
    566 		ofl->ofl_flags |= FLG_OF_FATAL;
    567 		return;
    568 	}
    569 
    570 	/*
    571 	 * Perform any machine specific type checking.
    572 	 */
    573 	if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) &&
    574 	    (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl))
    575 		return;
    576 
    577 	/*
    578 	 * Check the symbols type and size.
    579 	 */
    580 	if (otype != ntype) {
    581 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
    582 		    demangle(sdp->sd_name));
    583 		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
    584 		    sdp->sd_file->ifl_name,
    585 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
    586 		    0, &inv_buf1), ifl->ifl_name,
    587 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
    588 		    0, &inv_buf2));
    589 		warn++;
    590 	} else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) {
    591 		if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
    592 			eprintf(ofl->ofl_lml, ERR_WARNING,
    593 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
    594 			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
    595 			    EC_XWORD(osym->st_size), ifl->ifl_name,
    596 			    EC_XWORD(nsym->st_size));
    597 			warn++;
    598 		}
    599 	}
    600 
    601 	/*
    602 	 * Having provided the user with any necessary warnings, take the
    603 	 * appropriate symbol:
    604 	 *
    605 	 *  -	if one symbol is from a shared object and the other is from a
    606 	 *	relocatable object, take the relocatable objects symbol (the
    607 	 *	run-time linker is always going to find the relocatable object
    608 	 *	symbol regardless of the binding), else
    609 	 *
    610 	 *  -	if both symbols are from relocatable objects and one symbol is
    611 	 *	weak take the non-weak symbol (two non-weak symbols would have
    612 	 *	generated the fatal error condition above unless -z muldefs is
    613 	 *	in effect), else
    614 	 *
    615 	 *  -	take the first symbol definition encountered.
    616 	 */
    617 	if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
    618 		if (warn)
    619 			eprintf(ofl->ofl_lml, ERR_NONE,
    620 			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
    621 		return;
    622 	} else if ((nfile == ET_REL) && ((ofile == ET_DYN) ||
    623 	    ((obind == STB_WEAK) && (nbind != STB_WEAK)))) {
    624 		if (warn)
    625 			eprintf(ofl->ofl_lml, ERR_NONE,
    626 			    MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name);
    627 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
    628 		return;
    629 	} else {
    630 		if (warn)
    631 			eprintf(ofl->ofl_lml, ERR_NONE,
    632 			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
    633 		sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
    634 		return;
    635 	}
    636 }
    637 
    638 /*
    639  * Resolve a real and tentative definition.
    640  */
    641 static void
    642 sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
    643     int ndx, Word nshndx, sd_flag_t nsdflags)
    644 {
    645 	Conv_inv_buf_t inv_buf1, inv_buf2;
    646 	Sym	*osym = sdp->sd_sym;
    647 	uchar_t otype = ELF_ST_TYPE(osym->st_info);
    648 	uchar_t obind = ELF_ST_BIND(osym->st_info);
    649 	uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
    650 	uchar_t nbind = ELF_ST_BIND(nsym->st_info);
    651 	Boolean	otent = FALSE, ntent = FALSE;
    652 	Half	ofile = sdp->sd_file->ifl_ehdr->e_type;
    653 	Half	nfile = ifl->ifl_ehdr->e_type;
    654 	int	warn = 0;
    655 	uchar_t	ovis = ELF_ST_VISIBILITY(osym->st_other);
    656 	uchar_t	nvis = ELF_ST_VISIBILITY(nsym->st_other);
    657 
    658 	/*
    659 	 * Special rules for functions.
    660 	 *
    661 	 *  -	If both definitions are from relocatable objects, have the same
    662 	 *	binding (ie. two weaks or two non-weaks), and the real
    663 	 *	definition is a function (the other must be tentative), treat
    664 	 *	this as a multiply defined symbol error, else
    665 	 *
    666 	 *  -	if the real symbol definition is a function within a shared
    667 	 *	library and the tentative symbol is a relocatable object, and
    668 	 *	the tentative is not weak and the function real, then retain the
    669 	 *	tentative definition.
    670 	 */
    671 	if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) &&
    672 	    ((otype == STT_FUNC) || (ntype == STT_FUNC))) {
    673 		if (ofl->ofl_flags & FLG_OF_MULDEFS) {
    674 			eprintf(ofl->ofl_lml, ERR_WARNING,
    675 			    MSG_INTL(MSG_SYM_DIFFTYPE), demangle(sdp->sd_name));
    676 			sym_promote(sdp, nsym, ifl, ofl, ndx,
    677 			    nshndx, nsdflags);
    678 		} else {
    679 			eprintf(ofl->ofl_lml, ERR_FATAL,
    680 			    MSG_INTL(MSG_SYM_MULDEF), demangle(sdp->sd_name));
    681 			ofl->ofl_flags |= FLG_OF_FATAL;
    682 		}
    683 		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
    684 		    sdp->sd_file->ifl_name,
    685 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
    686 		    0, &inv_buf1), ifl->ifl_name,
    687 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
    688 		    0, &inv_buf2));
    689 		return;
    690 	} else if (ofile != nfile) {
    691 
    692 
    693 		if ((ofile == ET_DYN) && (otype == STT_FUNC)) {
    694 			if ((otype != STB_WEAK) && (ntype == STB_WEAK))
    695 				return;
    696 			else {
    697 				sym_override(sdp, nsym, ifl, ofl, ndx,
    698 				    nshndx, nsdflags);
    699 				return;
    700 			}
    701 		}
    702 		if ((nfile == ET_DYN) && (ntype == STT_FUNC)) {
    703 			if ((ntype != STB_WEAK) && (otype == STB_WEAK)) {
    704 				sym_override(sdp, nsym, ifl, ofl, ndx,
    705 				    nshndx, nsdflags);
    706 				return;
    707 			} else
    708 				return;
    709 		}
    710 	}
    711 
    712 	if (sdp->sd_flags & FLG_SY_TENTSYM)
    713 		otent = TRUE;
    714 	if (nsdflags & FLG_SY_TENTSYM)
    715 		ntent = TRUE;
    716 
    717 
    718 	/*
    719 	 * Check the symbols type and size.
    720 	 */
    721 	if (otype != ntype) {
    722 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
    723 		    demangle(sdp->sd_name));
    724 		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
    725 		    sdp->sd_file->ifl_name,
    726 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
    727 		    0, &inv_buf1), ifl->ifl_name,
    728 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
    729 		    0, &inv_buf2));
    730 		warn++;
    731 	} else if (osym->st_size != nsym->st_size) {
    732 		/*
    733 		 * If both definitions are from relocatable objects we have a
    734 		 * potential fatal error condition.  If the tentative is larger
    735 		 * than the real definition treat this as a multiple definition.
    736 		 * Note that if only one symbol is weak, the non-weak will be
    737 		 * taken.
    738 		 */
    739 		if (((ofile == ET_REL) && (nfile == ET_REL) &&
    740 		    (obind == nbind)) &&
    741 		    ((otent && (osym->st_size > nsym->st_size)) ||
    742 		    (ntent && (osym->st_size < nsym->st_size)))) {
    743 			eprintf(ofl->ofl_lml, ERR_FATAL,
    744 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
    745 			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
    746 			    EC_XWORD(osym->st_size), ifl->ifl_name,
    747 			    EC_XWORD(nsym->st_size));
    748 			eprintf(ofl->ofl_lml, ERR_NONE,
    749 			    MSG_INTL(MSG_SYM_TENTERR));
    750 			ofl->ofl_flags |= FLG_OF_FATAL;
    751 		} else {
    752 			if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
    753 				eprintf(ofl->ofl_lml, ERR_WARNING,
    754 				    MSG_INTL(MSG_SYM_DIFFATTR),
    755 				    demangle(sdp->sd_name),
    756 				    MSG_INTL(MSG_STR_SIZES),
    757 				    sdp->sd_file->ifl_name,
    758 				    EC_XWORD(osym->st_size),
    759 				    ifl->ifl_name, EC_XWORD(nsym->st_size));
    760 				warn++;
    761 			}
    762 		}
    763 	}
    764 
    765 	/*
    766 	 * Having provided the user with any necessary warnings, take the
    767 	 * appropriate symbol:
    768 	 *
    769 	 *  -	if the original symbol is from relocatable file and it is
    770 	 *	a protected tentative symbol, take the original one.
    771 	 *
    772 	 *  -	if the original symbol is from shared object and the new
    773 	 *	symbol is a protected tentative symbol from a relocatable file,
    774 	 *	take the new one.
    775 	 *
    776 	 *  -	if the original symbol is tentative, and providing the original
    777 	 *	symbol isn't strong and the new symbol weak, take the real
    778 	 *	symbol, else
    779 	 *
    780 	 *  -	if the original symbol is weak and the new tentative symbol is
    781 	 *	strong take the new symbol.
    782 	 *
    783 	 * Refer to the System V ABI Page 4-27 for a description of the binding
    784 	 * requirements of tentative and weak symbols.
    785 	 */
    786 	if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) &&
    787 	    (ovis == STV_PROTECTED)) {
    788 		return;
    789 	}
    790 
    791 	if ((ofile == ET_DYN) && (nfile == ET_REL) && (ntent == TRUE) &&
    792 	    (nvis == STV_PROTECTED)) {
    793 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
    794 		return;
    795 	}
    796 
    797 	if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
    798 		if (warn)
    799 			eprintf(ofl->ofl_lml, ERR_NONE,
    800 			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
    801 		return;
    802 	}
    803 
    804 	if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) ||
    805 	    ((obind == STB_WEAK) && (nbind != STB_WEAK))) {
    806 		if (warn)
    807 			eprintf(ofl->ofl_lml, ERR_NONE,
    808 			    MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name);
    809 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
    810 		return;
    811 	} else {
    812 		if (warn)
    813 			eprintf(ofl->ofl_lml, ERR_NONE,
    814 			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
    815 		sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
    816 		return;
    817 	}
    818 }
    819 
    820 /*
    821  * Resolve two tentative symbols.
    822  */
    823 static void
    824 sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
    825     int ndx, Word nshndx, sd_flag_t nsdflags)
    826 {
    827 	Sym	*osym = sdp->sd_sym;
    828 	uchar_t	obind = ELF_ST_BIND(osym->st_info);
    829 	uchar_t	nbind = ELF_ST_BIND(nsym->st_info);
    830 	Half	ofile = sdp->sd_file->ifl_ehdr->e_type;
    831 	Half	nfile = ifl->ifl_ehdr->e_type;
    832 	size_t	size = 0;
    833 	Xword	value = 0;
    834 
    835 #if	defined(_ELF64)
    836 	if (ld_targ.t_m.m_mach == EM_AMD64) {
    837 		/*
    838 		 * If the original and new symbols are both COMMON, but of
    839 		 * a different size model, take the small one.
    840 		 */
    841 		if ((sdp->sd_sym->st_shndx == SHN_COMMON) &&
    842 		    (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
    843 			/*
    844 			 * Take the original symbol.
    845 			 */
    846 			return;
    847 
    848 		} else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
    849 		    (nsym->st_shndx == SHN_COMMON)) {
    850 			/*
    851 			 * Take the new symbol.
    852 			 */
    853 			sym_override(sdp, nsym, ifl, ofl, ndx, nshndx,
    854 			    nsdflags);
    855 			return;
    856 		}
    857 	}
    858 #endif
    859 
    860 	/*
    861 	 * Check the alignment of the symbols.  This can only be tested for if
    862 	 * the symbols are not real definitions to a SHT_NOBITS section (ie.
    863 	 * they were originally tentative), as in this case the symbol would
    864 	 * have a displacement value rather than an alignment.  In other words
    865 	 * we can only test this for two relocatable objects.
    866 	 */
    867 	/* BEGIN CSTYLED */
    868 	if ((osym->st_value != nsym->st_value) &&
    869 	    ((sdp->sd_flags & FLG_SY_SPECSEC) &&
    870 	    (sdp->sd_sym->st_shndx == SHN_COMMON) &&
    871 	    (nsdflags & FLG_SY_SPECSEC) &&
    872 #if	defined(_ELF64)
    873 	    (nsym->st_shndx == SHN_COMMON)) ||
    874 	    ((ld_targ.t_m.m_mach == EM_AMD64) &&
    875 	    (sdp->sd_flags & FLG_SY_SPECSEC) &&
    876 	    (sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
    877 	    (nsdflags & FLG_SY_SPECSEC) &&
    878 	    (nsym->st_shndx == SHN_X86_64_LCOMMON))) {
    879 #else
    880 	    (nsym->st_shndx == SHN_COMMON))) {
    881 #endif
    882 	/* END CSTYLED */
    883 
    884 		const char	*emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
    885 		const char	*file;
    886 		Xword		salign;
    887 		Xword		balign;
    888 		uint_t		alignscompliment;
    889 
    890 		if (osym->st_value < nsym->st_value) {
    891 			salign = osym->st_value;
    892 			balign = nsym->st_value;
    893 		} else {
    894 			salign = nsym->st_value;
    895 			balign = osym->st_value;
    896 		}
    897 
    898 		/*
    899 		 * If the smaller alignment fits smoothly into the
    900 		 * larger alignment - we take it with no warning.
    901 		 */
    902 		if (S_ALIGN(balign, salign) == balign)
    903 			alignscompliment = 1;
    904 		else
    905 			alignscompliment = 0;
    906 
    907 		if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
    908 			eprintf(ofl->ofl_lml, ERR_WARNING,
    909 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
    910 			    MSG_INTL(MSG_STR_ALIGNMENTS),
    911 			    sdp->sd_file->ifl_name, EC_XWORD(osym->st_value),
    912 			    ifl->ifl_name, EC_XWORD(nsym->st_value));
    913 
    914 		/*
    915 		 * Having provided the necessary warning indicate which
    916 		 * relocatable object we are going to take.
    917 		 *
    918 		 *  -	if one symbol is weak and the other is non-weak
    919 		 *	take the non-weak symbol, else
    920 		 *
    921 		 *  -	take the largest alignment (as we still have to check
    922 		 *	the symbols size simply save the largest value for
    923 		 *	updating later).
    924 		 */
    925 		if ((obind == STB_WEAK) && (nbind != STB_WEAK))
    926 			file = ifl->ifl_name;
    927 		else if (obind != nbind)
    928 			file = sdp->sd_file->ifl_name;
    929 		else {
    930 			emsg = MSG_INTL(MSG_SYM_LARGER);
    931 			value = balign;
    932 		}
    933 		if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
    934 			eprintf(ofl->ofl_lml, ERR_NONE, emsg, file);
    935 	}
    936 
    937 	/*
    938 	 * Check the size of the symbols.
    939 	 */
    940 	if (osym->st_size != nsym->st_size) {
    941 		const char	*emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
    942 		const char	*file;
    943 
    944 		if (!(ofl->ofl_flags & FLG_OF_NOWARN))
    945 			eprintf(ofl->ofl_lml, ERR_WARNING,
    946 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
    947 			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
    948 			    EC_XWORD(osym->st_size), ifl->ifl_name,
    949 			    EC_XWORD(nsym->st_size));
    950 
    951 
    952 		/*
    953 		 * This symbol has already been compared to an SO definition,
    954 		 * as per the runtime behavior, ignore extra definitions.
    955 		 */
    956 		if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
    957 			if (!(ofl->ofl_flags & FLG_OF_NOWARN))
    958 				eprintf(ofl->ofl_lml, ERR_NONE, emsg,
    959 				    sdp->sd_file->ifl_name);
    960 			return;
    961 		}
    962 
    963 		/*
    964 		 * Having provided the necessary warning indicate what course
    965 		 * of action we are going to take.
    966 		 *
    967 		 *  -	if the file types differ, take the relocatable object
    968 		 *	and apply the largest symbol size, else
    969 		 *  -	if one symbol is weak and the other is non-weak, take
    970 		 *	the non-weak symbol, else
    971 		 *  -	simply take the largest symbol reference.
    972 		 */
    973 		if (nfile != ofile) {
    974 			if (nfile == ET_REL) {
    975 				file = ifl->ifl_name;
    976 				if (osym->st_size > nsym->st_size) {
    977 					size = (size_t)osym->st_size;
    978 					emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
    979 				}
    980 				sym_override(sdp, nsym, ifl, ofl, ndx,
    981 				    nshndx, nsdflags);
    982 			} else {
    983 				file = sdp->sd_file->ifl_name;
    984 				if (osym->st_size < nsym->st_size) {
    985 					size = (size_t)nsym->st_size;
    986 					emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
    987 				}
    988 				sym_promote(sdp, nsym, ifl, ofl, ndx,
    989 				    nshndx, nsdflags);
    990 			}
    991 		} else if (obind != nbind) {
    992 			if ((obind == STB_WEAK) && (nbind != STB_WEAK)) {
    993 				sym_override(sdp, nsym, ifl, ofl, ndx,
    994 				    nshndx, nsdflags);
    995 				file = ifl->ifl_name;
    996 			} else
    997 				file = sdp->sd_file->ifl_name;
    998 		} else {
    999 			if (osym->st_size < nsym->st_size) {
   1000 				sym_override(sdp, nsym, ifl, ofl, ndx,
   1001 				    nshndx, nsdflags);
   1002 				file = ifl->ifl_name;
   1003 			} else
   1004 				file = sdp->sd_file->ifl_name;
   1005 		}
   1006 		if (!(ofl->ofl_flags & FLG_OF_NOWARN))
   1007 			eprintf(ofl->ofl_lml, ERR_NONE, emsg, file);
   1008 		if (size)
   1009 			sdp->sd_sym->st_size = (Xword)size;
   1010 	} else {
   1011 		/*
   1012 		 * If the sizes are the same
   1013 		 *
   1014 		 *  -	if the file types differ, take the relocatable object,
   1015 		 *	else
   1016 		 *
   1017 		 *  -	if one symbol is weak and the other is non-weak, take
   1018 		 *	the non-weak symbol, else
   1019 		 *
   1020 		 *  -	take the first reference.
   1021 		 */
   1022 		if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN))
   1023 			return;
   1024 		else if (((ofile != nfile) && (nfile == ET_REL)) ||
   1025 		    (((obind == STB_WEAK) && (nbind != STB_WEAK)) &&
   1026 		    (!((ofile != nfile) && (ofile == ET_REL)))))
   1027 			sym_override(sdp, nsym, ifl, ofl, ndx,
   1028 			    nshndx, nsdflags);
   1029 		else
   1030 			sym_promote(sdp, nsym, ifl, ofl, ndx,
   1031 			    nshndx, nsdflags);
   1032 	}
   1033 
   1034 	/*
   1035 	 * Enforce the largest alignment if necessary.
   1036 	 */
   1037 	if (value)
   1038 		sdp->sd_sym->st_value = value;
   1039 }
   1040 
   1041 /*
   1042  * Symbol resolution state table.  `Action' describes the required
   1043  * procedure to be called (if any).
   1044  */
   1045 static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *,
   1046     Sym *, Ifl_desc *, Ofl_desc *, int, Word, sd_flag_t) = {
   1047 
   1048 /*				defined		undef		tent	*/
   1049 /*				ET_REL		ET_REL		ET_REL	*/
   1050 
   1051 /*  0 defined REF_DYN_SEEN */	sym_tworeals,	sym_promote,	sym_realtent,
   1052 /*  1   undef REF_DYN_SEEN */	sym_override,	sym_override,	sym_override,
   1053 /*  2    tent REF_DYN_SEEN */	sym_realtent,	sym_promote,	sym_twotent,
   1054 /*  3 defined REF_DYN_NEED */	sym_tworeals,	sym_typecheck,	sym_realtent,
   1055 /*  4   undef REF_DYN_NEED */	sym_override,	sym_override,	sym_override,
   1056 /*  5    tent REF_DYN_NEED */	sym_realtent,	sym_typecheck,	sym_twotent,
   1057 /*  6 defined REF_REL_NEED */	sym_tworeals,	sym_typecheck,	sym_realtent,
   1058 /*  7   undef REF_REL_NEED */	sym_override,	sym_twoundefs,	sym_override,
   1059 /*  8    tent REF_REL_NEED */	sym_realtent,	sym_null,	sym_twotent,
   1060 
   1061 /*				defined		undef		tent	*/
   1062 /*				ET_DYN		ET_DYN		ET_DYN	*/
   1063 
   1064 /*  9 defined REF_DYN_SEEN */	sym_tworeals,	sym_null,	sym_realtent,
   1065 /* 10   undef REF_DYN_SEEN */	sym_override,	sym_mach_check,	sym_override,
   1066 /* 11    tent REF_DYN_SEEN */	sym_realtent,	sym_null,	sym_twotent,
   1067 /* 12 defined REF_DYN_NEED */	sym_tworeals,	sym_null,	sym_realtent,
   1068 /* 13   undef REF_DYN_NEED */	sym_override,	sym_null,	sym_override,
   1069 /* 14    tent REF_DYN_NEED */	sym_realtent,	sym_null,	sym_twotent,
   1070 /* 15 defined REF_REL_NEED */	sym_tworeals,	sym_null,	sym_realtent,
   1071 /* 16   undef REF_REL_NEED */	sym_override,	sym_mach_check,	sym_override,
   1072 /* 17    tent REF_REL_NEED */	sym_realtent,	sym_null,	sym_twotent
   1073 
   1074 };
   1075 
   1076 uintptr_t
   1077 ld_sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx,
   1078     Word nshndx, sd_flag_t nsdflags)
   1079 {
   1080 	int		row, column;		/* State table coordinates */
   1081 	Sym		*osym = sdp->sd_sym;
   1082 	Is_desc		*isp;
   1083 	Half		vis = 0, nfile = ifl->ifl_ehdr->e_type;
   1084 	Half		oref = sdp->sd_ref;
   1085 
   1086 	/*
   1087 	 * Determine the original symbols definition (defines row in Action[]).
   1088 	 */
   1089 	if (sdp->sd_flags & FLG_SY_TENTSYM)
   1090 		row = SYM_TENTATIVE;
   1091 	else if ((sdp->sd_sym->st_shndx == SHN_UNDEF) ||
   1092 	    (sdp->sd_sym->st_shndx == SHN_SUNW_IGNORE))
   1093 		row = SYM_UNDEFINED;
   1094 	else
   1095 		row = SYM_DEFINED;
   1096 
   1097 	/*
   1098 	 * If the input file is an implicit shared object then we don't need
   1099 	 * to bind to any symbols within it other than to verify that any
   1100 	 * undefined references will be closed (implicit shared objects are only
   1101 	 * processed when no undefined symbols are required as a result of the
   1102 	 * link-edit (see process_dynamic())).
   1103 	 */
   1104 	if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) &&
   1105 	    (row != SYM_UNDEFINED))
   1106 		return (1);
   1107 
   1108 	/*
   1109 	 * Finish computing the Action[] row by applying the symbols reference
   1110 	 * together with the input files type.
   1111 	 */
   1112 	row = row + (REF_NUM * sdp->sd_ref);
   1113 	if (nfile == ET_DYN)
   1114 		row += (REF_NUM * SYM_NUM);
   1115 
   1116 	/*
   1117 	 * If either the original or new symbol originates from a relocatable
   1118 	 * object, determine the appropriate visibility for the resolved symbol.
   1119 	 */
   1120 	if ((oref == REF_REL_NEED) || (nfile == ET_REL))
   1121 		vis = sym_visibility(sdp, nsym, ifl, ofl);
   1122 
   1123 	/*
   1124 	 * Determine the new symbols definition (defines column in Action[]).
   1125 	 */
   1126 	if ((nsdflags & FLG_SY_SPECSEC) &&
   1127 	    (nsym->st_shndx == SHN_COMMON)) {
   1128 		column = SYM_TENTATIVE;
   1129 		nsdflags |= FLG_SY_TENTSYM;
   1130 #if	defined(_ELF64)
   1131 	} else if ((ld_targ.t_m.m_mach == EM_AMD64) &&
   1132 	    (nsdflags & FLG_SY_SPECSEC) &&
   1133 	    (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
   1134 		column = SYM_TENTATIVE;
   1135 		nsdflags |= FLG_SY_TENTSYM;
   1136 #endif
   1137 	} else if ((nsym->st_shndx == SHN_UNDEF) ||
   1138 	    (nsym->st_shndx == SHN_SUNW_IGNORE)) {
   1139 		column = SYM_UNDEFINED;
   1140 		nshndx = SHN_UNDEF;
   1141 	} else {
   1142 		column = SYM_DEFINED;
   1143 		/*
   1144 		 * If the new symbol is from a shared library and it is
   1145 		 * associated with a SHT_NOBITS section then this symbol
   1146 		 * originated from a tentative symbol.
   1147 		 */
   1148 		if (((nsdflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) {
   1149 			isp = ifl->ifl_isdesc[nshndx];
   1150 			if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) {
   1151 				column = SYM_TENTATIVE;
   1152 				nsdflags |= FLG_SY_TENTSYM;
   1153 			}
   1154 		}
   1155 	}
   1156 
   1157 	DBG_CALL(Dbg_syms_resolving(ofl, ndx, sdp->sd_name, row, column,
   1158 	    osym, nsym, sdp, ifl));
   1159 
   1160 	/*
   1161 	 * Record the input filename on the defined files list for possible
   1162 	 * later diagnostics.  The `sa_dfiles' list is used to maintain the list
   1163 	 * of shared objects that define the same symbol.  This list is only
   1164 	 * generated when the -m option is in effect and is used to list
   1165 	 * multiple (interposed) definitions of a symbol (refer to ldmap_out()).
   1166 	 */
   1167 	if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nsym->st_shndx != SHN_UNDEF) &&
   1168 	    ((nsdflags & FLG_SY_SPECSEC) == 0))
   1169 		if (aplist_append(&sdp->sd_aux->sa_dfiles, ifl->ifl_name,
   1170 		    AL_CNT_SDP_DFILES) == NULL)
   1171 			return (S_ERROR);
   1172 
   1173 	/*
   1174 	 * Perform the required resolution.
   1175 	 */
   1176 	Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
   1177 
   1178 	/*
   1179 	 * Apply any visibility requirements.  If a SINGLETON has been
   1180 	 * established, make sure no symbol reduction indicators remain
   1181 	 * associated with the symbol, and indicate that the symbol can not
   1182 	 * be directly bound to.
   1183 	 */
   1184 	if ((oref == REF_REL_NEED) || (nfile == ET_REL)) {
   1185 		if ((vis == STV_EXPORTED) || (vis == STV_SINGLETON)) {
   1186 			sdp->sd_flags &= ~MSK_SY_LOCAL;
   1187 
   1188 			if (vis == STV_EXPORTED)
   1189 				sdp->sd_flags |= FLG_SY_EXPORT;
   1190 			else {
   1191 				sdp->sd_flags |= (FLG_SY_NDIR | FLG_SY_SINGLE);
   1192 
   1193 				if (sdp->sd_ref == REF_REL_NEED) {
   1194 					ofl->ofl_flags1 |=
   1195 					    (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
   1196 				}
   1197 			}
   1198 		} else if (vis == STV_PROTECTED) {
   1199 			sdp->sd_flags |= FLG_SY_PROTECT;
   1200 		} else if ((vis == STV_INTERNAL) || (vis == STV_HIDDEN)) {
   1201 			sdp->sd_flags |= FLG_SY_HIDDEN;
   1202 		} else if (vis == STV_ELIMINATE) {
   1203 			sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
   1204 		}
   1205 
   1206 		sdp->sd_sym->st_other =
   1207 		    (sdp->sd_sym->st_other & ~MSK_SYM_VISIBILITY) | vis;
   1208 	}
   1209 
   1210 	/*
   1211 	 * If the symbol has been resolved to the new input file, and this is
   1212 	 * a versioned relocatable object, then the version information of the
   1213 	 * new symbol must be promoted to the versioning of the output file.
   1214 	 */
   1215 	if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) &&
   1216 	    (nsym->st_shndx != SHN_UNDEF))
   1217 		ld_vers_promote(sdp, ndx, ifl, ofl);
   1218 
   1219 	/*
   1220 	 * Determine whether a mapfile reference has been satisfied.  Mapfile
   1221 	 * symbol references augment symbols that should be contributed from
   1222 	 * the relocatable objects used to build the output image.  If a
   1223 	 * relocatable object doesn't provide one of the mapfile symbol
   1224 	 * references then somethings amiss, and will be flagged during symbol
   1225 	 * validation.
   1226 	 */
   1227 	if ((nfile == ET_REL) && ((sdp->sd_flags &
   1228 	    (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) {
   1229 		/*
   1230 		 * Extern and parent references are satisfied by references from
   1231 		 * a relocatable object.  Note that we let *any* symbol type
   1232 		 * satisfy this reference, to be as flexible as possible with
   1233 		 * user written mapfiles.  It could be questionable, for
   1234 		 * example, if what a user expects to be an extern reference is
   1235 		 * actually found to be a definition in a relocatable object.
   1236 		 *
   1237 		 * Any other mapfile reference (typically for versioning
   1238 		 * information) simply augments a relocatables definition.
   1239 		 */
   1240 		if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) ||
   1241 		    ((sdp->sd_sym->st_shndx != SHN_UNDEF) &&
   1242 		    (sdp->sd_ref == REF_REL_NEED)))
   1243 			sdp->sd_flags |= FLG_SY_MAPUSED;
   1244 	}
   1245 
   1246 	DBG_CALL(Dbg_syms_resolved(ofl, sdp));
   1247 
   1248 	return (1);
   1249 }
   1250