xref: /titanic_41/usr/src/cmd/sgs/libld/common/resolve.c (revision 88df2d76721d60b8b7cad14f9380446d06569f7c)
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 2006 Sun Microsystems, Inc.  All rights reserved.
27  * Use is subject to license terms.
28  */
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVR4 6.2/18.2 */
30 
31 /*
32  * Symbol table resolution
33  */
34 #include	<stdio.h>
35 #include	<debug.h>
36 #include	"msg.h"
37 #include	"_libld.h"
38 
39 
40 /*
41  * Categorize the symbol types that are applicable to the resolution process.
42  */
43 typedef	enum {
44 	SYM_DEFINED,		/* Defined symbol (SHN_ABS or shndx != 0) */
45 	SYM_UNDEFINED,		/* Undefined symbol (SHN_UNDEF) */
46 	SYM_TENTATIVE,		/* Tentative symbol (SHN_COMMON) */
47 	SYM_NUM			/* the number of symbol types */
48 } Symtype;
49 
50 /*
51  * Do nothing.
52  */
53 /* ARGSUSED0 */
54 static void
55 sym_null(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
56 	int ndx, Word nshndx, Word nsymflags)
57 {
58 }
59 
60 /*
61  * Check if two symbols types are compatible
62  */
63 /*ARGSUSED4*/
64 static void
65 sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
66 	int ndx, Word nshndx, Word nsymflags)
67 {
68 	unsigned char	otype = ELF_ST_TYPE(sdp->sd_sym->st_info);
69 	unsigned char	ntype = ELF_ST_TYPE(nsym->st_info);
70 
71 	/*
72 	 * Perform any machine specific type checking.
73 	 */
74 	if (ld_mach_sym_typecheck(sdp, nsym, ifl, ofl))
75 		return;
76 
77 	/*
78 	 * STV_VISIBILITY rules say that you must take the most restrictive
79 	 * value for a symbols reference.  If we see a reference from two
80 	 * objects, even if a symbol isn't promoted/overridden, make sure that
81 	 * the more restrictive visibility is saved.
82 	 */
83 	if (ifl->ifl_ehdr->e_type == ET_REL) {
84 		Sym *	osym = sdp->sd_sym;
85 		Half	ovis = ELF_ST_VISIBILITY(osym->st_other);
86 		Half	nvis = ELF_ST_VISIBILITY(nsym->st_other);
87 
88 		if ((nvis > STV_DEFAULT) &&
89 		    ((ovis == STV_DEFAULT) || (nvis < ovis))) {
90 			osym->st_other =
91 				(osym->st_other & ~MSK_SYM_VISIBILITY) | nvis;
92 		}
93 	}
94 
95 	/*
96 	 * NOTYPE's can be combind with other types, only give an error if
97 	 * combining two differing types without NOTYPE
98 	 */
99 	if ((otype == ntype) || (otype == STT_NOTYPE) || (ntype == STT_NOTYPE))
100 		return;
101 
102 	eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
103 	    demangle(sdp->sd_name));
104 	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
105 	    sdp->sd_file->ifl_name,
106 	    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype), ifl->ifl_name,
107 	    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype));
108 }
109 
110 /*ARGSUSED4*/
111 static void
112 sym_mach_check(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
113 	int ndx, Word nshndx, Word nsymflags)
114 {
115 	/*
116 	 * Perform any machine specific type checking.
117 	 */
118 	(void) ld_mach_sym_typecheck(sdp, nsym, ifl, ofl);
119 }
120 
121 /*
122  * Promote the symbols reference.
123  */
124 static void
125 /* ARGSUSED4 */
126 sym_promote(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
127     int ndx, Word nshndx, Word nsymflags)
128 {
129 	Word	shndx = nsym->st_shndx;
130 
131 	sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
132 
133 	/*
134 	 * If the old symbol is from a shared object and the new symbol is a
135 	 * reference from a relocatable object, promote the old symbols
136 	 * reference.
137 	 */
138 	if ((sdp->sd_ref == REF_DYN_SEEN) &&
139 	    (ifl->ifl_ehdr->e_type == ET_REL)) {
140 		sdp->sd_ref = REF_DYN_NEED;
141 
142 		/*
143 		 * If this is an undefined symbol it must be a relocatable
144 		 * object overriding a shared object.  In this case also
145 		 * override the reference name so that any undefined symbol
146 		 * diagnostics will refer to the relocatable object name.
147 		 */
148 		if (shndx == SHN_UNDEF)
149 			sdp->sd_aux->sa_rfile = ifl->ifl_name;
150 
151 		/*
152 		 * If this symbol is an undefined, or common, determine whether
153 		 * it is a global or weak reference (see build_osym(), where
154 		 * REF_DYN_NEED definitions are returned back to undefines).
155 		 */
156 		if (((shndx == SHN_UNDEF) || ((nsymflags & FLG_SY_SPECSEC) &&
157 		    (shndx == SHN_COMMON))) &&
158 		    (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
159 			sdp->sd_flags |= FLG_SY_GLOBREF;
160 
161 	} else if ((shndx != SHN_UNDEF) && (ofl->ofl_dtflags_1 & DF_1_TRANS) &&
162 	    (sdp->sd_aux->sa_bindto == 0) && (sdp->sd_ref == REF_REL_NEED) &&
163 	    (ifl->ifl_ehdr->e_type == ET_DYN)) {
164 		/*
165 		 * If building a translator then record the symbol
166 		 * we would 'bindto' with direct bindings.
167 		 */
168 		sdp->sd_aux->sa_bindto = ifl;
169 	}
170 }
171 
172 /*
173  * Override a symbol.
174  */
175 static void
176 sym_override(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
177 	int ndx, Word nshndx, Word nsymflags)
178 {
179 	Sym		*osym = sdp->sd_sym;
180 	Half		ovis = ELF_ST_VISIBILITY(osym->st_other);
181 	Half		nvis = ELF_ST_VISIBILITY(nsym->st_other);
182 	Word		link;
183 
184 	/*
185 	 * In the case of a WEAK UNDEF symbol don't let a symbol from an
186 	 * unavailable object override the symbol definition.  This is because
187 	 * this symbol *may* not be present in a future object and by promoting
188 	 * this symbol we are actually causing bindings (PLTS) to be formed
189 	 * to this symbol.  Instead let the 'generic' weak binding take place.
190 	 */
191 	if ((ELF_ST_BIND(osym->st_info) == STB_WEAK) &&
192 	    (sdp->sd_sym->st_shndx == SHN_UNDEF) &&
193 	    ((ifl->ifl_flags & FLG_IF_NEEDED) == 0))
194 		return;
195 
196 	sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
197 
198 	/*
199 	 * This symbol has already been compared to an SO definition,
200 	 * as per the runtime behavior, ignore extra definitions.
201 	 */
202 	if ((sdp->sd_flags & FLG_SY_SOFOUND) &&
203 	    (ifl->ifl_ehdr->e_type == ET_DYN))
204 		return;
205 
206 	/*
207 	 * Mark the symbol as available and copy the new symbols contents.
208 	 */
209 	sdp->sd_flags &= ~FLG_SY_NOTAVAIL;
210 	*osym = *nsym;
211 	sdp->sd_shndx = nshndx;
212 	sdp->sd_flags &= ~FLG_SY_SPECSEC;
213 	sdp->sd_flags |= (nsymflags & (FLG_SY_SPECSEC | FLG_SY_TENTSYM));
214 
215 	/*
216 	 * If the new symbol has PROTECTED visibility, mark it.  If a PROTECTED
217 	 * symbol is copy relocated, a warning message will be printed. See
218 	 * reloc_exec().
219 	 */
220 	if (ELF_ST_VISIBILITY(nsym->st_other) == STV_PROTECTED)
221 		sdp->sd_flags |= FLG_SY_PROT;
222 	else
223 		sdp->sd_flags &= ~FLG_SY_PROT;
224 
225 	/*
226 	 * Establish the symbols reference.  If the new symbol originates from a
227 	 * relocatable object then this reference becomes needed, otherwise
228 	 * the new symbol must be from a shared object.  In this case only
229 	 * promote the symbol to needed if we presently have a reference from a
230 	 * relocatable object.
231 	 */
232 	if (ifl->ifl_ehdr->e_type == ET_REL) {
233 		/*
234 		 * Maintain the more restrictive visiblity
235 		 */
236 		if ((ovis > STV_DEFAULT) &&
237 		    ((nvis == STV_DEFAULT) || (ovis < nvis))) {
238 			osym->st_other =
239 				(osym->st_other & ~MSK_SYM_VISIBILITY) | ovis;
240 		}
241 		sdp->sd_ref = REF_REL_NEED;
242 
243 		if (nsym->st_shndx == SHN_UNDEF) {
244 			/*
245 			 * If this is an undefined symbol it must be a
246 			 * relocatable object overriding a shared object.  In
247 			 * this case also override the reference name so that
248 			 * any undefined symbol diagnostics will refer to the
249 			 * relocatable object name.
250 			 */
251 			sdp->sd_aux->sa_rfile = ifl->ifl_name;
252 		} else {
253 			/*
254 			 * Under -Bnodirect, all exported interfaces are tagged
255 			 * to prevent direct binding to them.
256 			 */
257 			if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) &&
258 			    ((sdp->sd_flags1 & FLG_SY1_DIR) == 0))
259 				sdp->sd_flags1 |= FLG_SY1_NDIR;
260 		}
261 
262 		/*
263 		 * If this symbol is an undefined, or common, determine whether
264 		 * it is a global or weak reference (see build_osym(), where
265 		 * REF_DYN_NEED definitions are returned back to undefines).
266 		 */
267 		if (((nsym->st_shndx == SHN_UNDEF) ||
268 		    ((nsymflags & FLG_SY_SPECSEC) &&
269 		    (nsym->st_shndx == SHN_COMMON))) &&
270 		    (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
271 			sdp->sd_flags |= FLG_SY_GLOBREF;
272 		else
273 			sdp->sd_flags &= ~FLG_SY_GLOBREF;
274 	} else {
275 		if (sdp->sd_ref == REF_REL_NEED)
276 			sdp->sd_ref = REF_DYN_NEED;
277 
278 		/*
279 		 * Visibility from a DYN symbol does not override
280 		 * previous symbol visibility.
281 		 */
282 		osym->st_other = (osym->st_other & ~MSK_SYM_VISIBILITY) |
283 			ovis;
284 
285 		/*
286 		 * Determine the symbols availability.  A symbol is determined
287 		 * to be unavailable if it belongs to a version of a shared
288 		 * object that this user does not wish to use, or if it belongs
289 		 * to an implicit shared object.
290 		 */
291 		if (ifl->ifl_vercnt) {
292 			Ver_index *	vip;
293 			Half		vndx = ifl->ifl_versym[ndx];
294 
295 			sdp->sd_aux->sa_dverndx = vndx;
296 			vip = &ifl->ifl_verndx[vndx];
297 			if (!(vip->vi_flags & FLG_VER_AVAIL)) {
298 				sdp->sd_flags |= FLG_SY_NOTAVAIL;
299 				/*
300 				 * If this is the first occurance of an
301 				 * unavailable symbol record it for possible
302 				 * use in later error diagnostics
303 				 * (see sym_undef).
304 				 */
305 				if (!(sdp->sd_aux->sa_vfile))
306 					sdp->sd_aux->sa_vfile = ifl->ifl_name;
307 			}
308 		}
309 		if (!(ifl->ifl_flags & FLG_IF_NEEDED))
310 			sdp->sd_flags |= FLG_SY_NOTAVAIL;
311 	}
312 
313 	/*
314 	 * Make sure any symbol association maintained by the original symbol
315 	 * is cleared and then update the symbols file reference.
316 	 */
317 	if ((link = sdp->sd_aux->sa_linkndx) != 0) {
318 		Sym_desc *	_sdp;
319 
320 		_sdp = sdp->sd_file->ifl_oldndx[link];
321 		_sdp->sd_aux->sa_linkndx = 0;
322 		sdp->sd_aux->sa_linkndx = 0;
323 	}
324 	sdp->sd_file = ifl;
325 
326 	/*
327 	 * Update the input section descriptor to that of the new input file
328 	 */
329 	if (((nsymflags & FLG_SY_SPECSEC) == 0) &&
330 	    (nsym->st_shndx != SHN_UNDEF)) {
331 		if ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == 0) {
332 			eprintf(ofl->ofl_lml, ERR_FATAL,
333 			    MSG_INTL(MSG_SYM_NOSECDEF), demangle(sdp->sd_name),
334 			    ifl->ifl_name);
335 			ofl->ofl_flags |= FLG_OF_FATAL;
336 		}
337 	}
338 }
339 
340 /*
341  * Resolve two undefines (only called for two relocatable objects).
342  */
343 static void
344 sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
345 	int ndx, Word nshndx, Word nsymflags)
346 {
347 	Sym		*osym = sdp->sd_sym;
348 	unsigned char	obind = ELF_ST_BIND(osym->st_info);
349 	unsigned char	nbind = ELF_ST_BIND(nsym->st_info);
350 
351 	/*
352 	 * If two relocatable objects define a weak and non-weak undefined
353 	 * reference, take the non-weak definition.
354 	 *
355 	 *		-- or --
356 	 *
357 	 * If two relocatable objects define a NOTYPE & another, then
358 	 * take the other.
359 	 */
360 	if (((obind == STB_WEAK) && (nbind != STB_WEAK)) ||
361 	    (obind == STT_NOTYPE) && (nbind != STT_NOTYPE)) {
362 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
363 		return;
364 	}
365 	sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
366 }
367 
368 /*
369  * Resolve two real definitions.
370  */
371 static void
372 sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
373 	int ndx, Word nshndx, Word nsymflags)
374 {
375 	Sym		*osym = sdp->sd_sym;
376 	unsigned char   otype = ELF_ST_TYPE(osym->st_info);
377 	unsigned char   obind = ELF_ST_BIND(osym->st_info);
378 	unsigned char   ntype = ELF_ST_TYPE(nsym->st_info);
379 	unsigned char   nbind = ELF_ST_BIND(nsym->st_info);
380 	Half		ofile = sdp->sd_file->ifl_ehdr->e_type;
381 	Half		nfile = ifl->ifl_ehdr->e_type;
382 	int		warn = 0;
383 
384 	/*
385 	 * If both definitions are from relocatable objects, and have non-weak
386 	 * binding then this is a fatal condition.
387 	 */
388 	if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) &&
389 	    (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) {
390 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
391 		    demangle(sdp->sd_name));
392 		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
393 		    sdp->sd_file->ifl_name,
394 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype),
395 		    ifl->ifl_name,
396 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype));
397 		ofl->ofl_flags |= FLG_OF_FATAL;
398 		return;
399 	}
400 
401 	/*
402 	 * Perform any machine specific type checking.
403 	 */
404 	if (ld_mach_sym_typecheck(sdp, nsym, ifl, ofl))
405 		return;
406 
407 	/*
408 	 * Check the symbols type and size.
409 	 */
410 	if (otype != ntype) {
411 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
412 		    demangle(sdp->sd_name));
413 		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
414 		    sdp->sd_file->ifl_name,
415 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype),
416 		    ifl->ifl_name, conv_sym_info_type(ofl->ofl_dehdr->e_machine,
417 		    ntype));
418 		warn++;
419 	} else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) {
420 		if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
421 			eprintf(ofl->ofl_lml, ERR_WARNING,
422 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
423 			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
424 			    EC_XWORD(osym->st_size), ifl->ifl_name,
425 			    EC_XWORD(nsym->st_size));
426 			warn++;
427 		}
428 	}
429 
430 	/*
431 	 * Having provided the user with any necessary warnings, take the
432 	 * appropriate symbol:
433 	 *
434 	 *  o	if one symbol is from a shared object and the other is from a
435 	 *	relocatable object, take the relocatable objects symbol (the
436 	 *	run-time linker is always going to find the relocatable object
437 	 *	symbol regardless of the binding), else
438 	 *
439 	 * o	if both symbols are from relocatable objects and one symbol is
440 	 *	weak take the non-weak symbol (two non-weak symbols would have
441 	 *	generated the fatal error condition above unless -z muldefs is
442 	 *	in effect), else
443 	 *
444 	 *  o	take the first symbol definition encountered.
445 	 */
446 	if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
447 		if (warn)
448 			eprintf(ofl->ofl_lml, ERR_NONE,
449 			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
450 		return;
451 	} else if ((nfile == ET_REL) && ((ofile == ET_DYN) ||
452 	    ((obind == STB_WEAK) && (nbind != STB_WEAK)))) {
453 		if (warn)
454 			eprintf(ofl->ofl_lml, ERR_NONE,
455 			    MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name);
456 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
457 		return;
458 	} else {
459 		if (warn)
460 			eprintf(ofl->ofl_lml, ERR_NONE,
461 			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
462 		sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
463 		return;
464 	}
465 }
466 
467 /*
468  * Resolve a real and tentative definition.
469  */
470 static void
471 sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
472 	int ndx, Word nshndx, Word nsymflags)
473 {
474 	Sym		*osym = sdp->sd_sym;
475 	unsigned char	otype = ELF_ST_TYPE(osym->st_info);
476 	unsigned char   obind = ELF_ST_BIND(osym->st_info);
477 	unsigned char	ntype = ELF_ST_TYPE(nsym->st_info);
478 	unsigned char   nbind = ELF_ST_BIND(nsym->st_info);
479 	Boolean		otent = FALSE, ntent = FALSE;
480 	Half		ofile = sdp->sd_file->ifl_ehdr->e_type;
481 	Half		nfile = ifl->ifl_ehdr->e_type;
482 	int		warn = 0;
483 	Word		osymvis = ELF_ST_VISIBILITY(osym->st_other);
484 	Word		nsymvis = ELF_ST_VISIBILITY(nsym->st_other);
485 
486 	/*
487 	 * Special rules for functions.
488 	 *
489 	 *  o	If both definitions are from relocatable objects, have the same
490 	 *	binding (ie. two weaks or two non-weaks), and the real
491 	 *	definition is a function (the other must be tentative), treat
492 	 *	this as a multiply defined symbol error, else
493 	 *
494 	 *  o	if the real symbol definition is a function within a shared
495 	 *	library and the tentative symbol is a relocatable object, and
496 	 *	the tentative is not weak and the function real, then retain the
497 	 *	tentative definition.
498 	 */
499 	if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) &&
500 	    ((otype == STT_FUNC) || (ntype == STT_FUNC))) {
501 		if (ofl->ofl_flags & FLG_OF_MULDEFS) {
502 			eprintf(ofl->ofl_lml, ERR_WARNING,
503 			    MSG_INTL(MSG_SYM_DIFFTYPE), demangle(sdp->sd_name));
504 			sym_promote(sdp, nsym, ifl, ofl, ndx,
505 				nshndx, nsymflags);
506 		} else {
507 			eprintf(ofl->ofl_lml, ERR_FATAL,
508 			    MSG_INTL(MSG_SYM_MULDEF), demangle(sdp->sd_name));
509 			ofl->ofl_flags |= FLG_OF_FATAL;
510 		}
511 		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
512 		    sdp->sd_file->ifl_name,
513 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype),
514 		    ifl->ifl_name, conv_sym_info_type(ofl->ofl_dehdr->e_machine,
515 		    ntype));
516 		return;
517 	} else if (ofile != nfile) {
518 
519 
520 		if ((ofile == ET_DYN) && (otype == STT_FUNC)) {
521 			if ((otype != STB_WEAK) && (ntype == STB_WEAK))
522 				return;
523 			else {
524 				sym_override(sdp, nsym, ifl, ofl, ndx,
525 				    nshndx, nsymflags);
526 				return;
527 			}
528 		}
529 		if ((nfile == ET_DYN) && (ntype == STT_FUNC)) {
530 			if ((ntype != STB_WEAK) && (otype == STB_WEAK)) {
531 				sym_override(sdp, nsym, ifl, ofl, ndx,
532 					nshndx, nsymflags);
533 				return;
534 			} else
535 				return;
536 		}
537 	}
538 
539 	if (sdp->sd_flags & FLG_SY_TENTSYM)
540 		otent = TRUE;
541 	if (nsymflags & FLG_SY_TENTSYM)
542 		ntent = TRUE;
543 
544 
545 	/*
546 	 * Check the symbols type and size.
547 	 */
548 	if (otype != ntype) {
549 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
550 		    demangle(sdp->sd_name));
551 		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
552 		    sdp->sd_file->ifl_name,
553 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype),
554 		    ifl->ifl_name, conv_sym_info_type(ofl->ofl_dehdr->e_machine,
555 		    ntype));
556 		warn++;
557 	} else if (osym->st_size != nsym->st_size) {
558 		/*
559 		 * If both definitions are from relocatable objects we have a
560 		 * potential fatal error condition.  If the tentative is larger
561 		 * than the real definition treat this as a multiple definition.
562 		 * Note that if only one symbol is weak, the non-weak will be
563 		 * taken.
564 		 */
565 		if (((ofile == ET_REL) && (nfile == ET_REL) &&
566 		    (obind == nbind)) &&
567 		    ((otent && (osym->st_size > nsym->st_size)) ||
568 		    (ntent && (osym->st_size < nsym->st_size)))) {
569 			eprintf(ofl->ofl_lml, ERR_FATAL,
570 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
571 			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
572 			    EC_XWORD(osym->st_size), ifl->ifl_name,
573 			    EC_XWORD(nsym->st_size));
574 			eprintf(ofl->ofl_lml, ERR_NONE,
575 			    MSG_INTL(MSG_SYM_TENTERR));
576 			ofl->ofl_flags |= FLG_OF_FATAL;
577 		} else {
578 			if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
579 				eprintf(ofl->ofl_lml, ERR_WARNING,
580 				    MSG_INTL(MSG_SYM_DIFFATTR),
581 				    demangle(sdp->sd_name),
582 				    MSG_INTL(MSG_STR_SIZES),
583 				    sdp->sd_file->ifl_name,
584 				    EC_XWORD(osym->st_size),
585 				    ifl->ifl_name, EC_XWORD(nsym->st_size));
586 				warn++;
587 			}
588 		}
589 	}
590 
591 	/*
592 	 * Having provided the user with any necessary warnings, take the
593 	 * appropriate symbol:
594 	 *
595 	 *  o   if the original symbol is from relocatable file and it is
596 	 *	a protected tentative symbol, take the original one.
597 	 *
598 	 *  o 	if the original symbol is from shared object and the new
599 	 *	symbol is a protected tentative symbol from a relocatable file,
600 	 *	take the new one.
601 	 *
602 	 *  o	if the original symbol is tentative, and providing the original
603 	 *	symbol isn't strong and the new symbol weak, take the real
604 	 *	symbol, else
605 	 *
606 	 *  o	if the original symbol is weak and the new tentative symbol is
607 	 *	strong take the new symbol.
608 	 *
609 	 * Refer to the System V ABI Page 4-27 for a description of the binding
610 	 * requirements of tentative and weak symbols.
611 	 */
612 	if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) &&
613 	    (osymvis == STV_PROTECTED)) {
614 		return;
615 	}
616 
617 	if ((ofile == ET_DYN) && (nfile == ET_REL) && (ntent == TRUE) &&
618 	    (nsymvis == STV_PROTECTED)) {
619 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
620 		return;
621 	}
622 
623 	if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
624 		if (warn)
625 			eprintf(ofl->ofl_lml, ERR_NONE,
626 			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
627 		return;
628 	}
629 
630 	if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) ||
631 	    ((obind == STB_WEAK) && (nbind != STB_WEAK))) {
632 		if (warn)
633 			eprintf(ofl->ofl_lml, ERR_NONE,
634 			    MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name);
635 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
636 		return;
637 	} else {
638 		if (warn)
639 			eprintf(ofl->ofl_lml, ERR_NONE,
640 			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
641 		sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
642 		return;
643 	}
644 }
645 
646 /*
647  * Resolve two tentative symbols.
648  */
649 static void
650 sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
651 	int ndx, Word nshndx, Word nsymflags)
652 {
653 	Sym		*osym = sdp->sd_sym;
654 	unsigned char   obind = ELF_ST_BIND(osym->st_info);
655 	unsigned char   nbind = ELF_ST_BIND(nsym->st_info);
656 	Half		ofile = sdp->sd_file->ifl_ehdr->e_type;
657 	Half		nfile = ifl->ifl_ehdr->e_type;
658 	size_t		size = 0;
659 	Xword		value = 0;
660 
661 #if	(defined(__i386) || defined(__amd64)) && defined(_ELF64)
662 	/*
663 	 * If the original and new symbols are both COMMON, but of a different
664 	 * size model, take the small one.
665 	 */
666 	if ((sdp->sd_sym->st_shndx == SHN_COMMON) &&
667 	    (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
668 		/*
669 		 * Take the original symbol.
670 		 */
671 		return;
672 
673 	} else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
674 	    (nsym->st_shndx == SHN_COMMON)) {
675 		/*
676 		 * Take the new symbol.
677 		 */
678 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
679 		return;
680 	}
681 #endif
682 
683 	/*
684 	 * Check the alignment of the symbols.  This can only be tested for if
685 	 * the symbols are not real definitions to a SHT_NOBITS section (ie.
686 	 * they were originally tentative), as in this case the symbol would
687 	 * have a displacement value rather than an alignment.  In other words
688 	 * we can only test this for two relocatable objects.
689 	 */
690 	if ((osym->st_value != nsym->st_value) &&
691 	    ((sdp->sd_flags & FLG_SY_SPECSEC) &&
692 	    (sdp->sd_sym->st_shndx == SHN_COMMON) &&
693 	    (nsymflags & FLG_SY_SPECSEC) &&
694 #if	(defined(__i386) || defined(__amd64)) && defined(_ELF64)
695 	    (nsym->st_shndx == SHN_COMMON)) ||
696 	    ((sdp->sd_flags & FLG_SY_SPECSEC) &&
697 	    (sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
698 	    (nsymflags & FLG_SY_SPECSEC) &&
699 	    (nsym->st_shndx == SHN_X86_64_LCOMMON))) {
700 #else
701 	    (nsym->st_shndx == SHN_COMMON))) {
702 #endif
703 		const char	*emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
704 		const char	*file;
705 		Xword		salign;
706 		Xword		balign;
707 		uint_t		alignscompliment;
708 
709 		if (osym->st_value < nsym->st_value) {
710 			salign = osym->st_value;
711 			balign = nsym->st_value;
712 		} else {
713 			salign = nsym->st_value;
714 			balign = osym->st_value;
715 		}
716 
717 		/*
718 		 * If the smaller alignment fits smoothly into the
719 		 * larger alignment - we take it with no warning.
720 		 */
721 		if (S_ALIGN(balign, salign) == balign)
722 			alignscompliment = 1;
723 		else
724 			alignscompliment = 0;
725 
726 		if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
727 			eprintf(ofl->ofl_lml, ERR_WARNING,
728 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
729 			    MSG_INTL(MSG_STR_ALIGNMENTS),
730 			    sdp->sd_file->ifl_name, EC_XWORD(osym->st_value),
731 			    ifl->ifl_name, EC_XWORD(nsym->st_value));
732 
733 		/*
734 		 * Having provided the necessary warning indicate which
735 		 * relocatable object we are going to take.
736 		 *
737 		 *  o	if one symbol is weak and the other is non-weak
738 		 *	take the non-weak symbol, else
739 		 *
740 		 *  o	take the largest alignment (as we still have to check
741 		 *	the symbols size simply save the largest value for
742 		 *	updating later).
743 		 */
744 		if ((obind == STB_WEAK) && (nbind != STB_WEAK))
745 			file = ifl->ifl_name;
746 		else if (obind != nbind)
747 			file = sdp->sd_file->ifl_name;
748 		else {
749 			emsg = MSG_INTL(MSG_SYM_LARGER);
750 			value = balign;
751 		}
752 		if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
753 			eprintf(ofl->ofl_lml, ERR_NONE, emsg, file);
754 	}
755 
756 	/*
757 	 * Check the size of the symbols.
758 	 */
759 	if (osym->st_size != nsym->st_size) {
760 		const char	*emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
761 		const char	*file;
762 
763 		if (!(ofl->ofl_flags & FLG_OF_NOWARN))
764 			eprintf(ofl->ofl_lml, ERR_WARNING,
765 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
766 			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
767 			    EC_XWORD(osym->st_size), ifl->ifl_name,
768 			    EC_XWORD(nsym->st_size));
769 
770 
771 		/*
772 		 * This symbol has already been compared to an SO definition,
773 		 * as per the runtime behavior, ignore extra definitions.
774 		 */
775 		if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
776 			if (!(ofl->ofl_flags & FLG_OF_NOWARN))
777 				eprintf(ofl->ofl_lml, ERR_NONE, emsg,
778 				    sdp->sd_file->ifl_name);
779 			return;
780 		}
781 
782 		/*
783 		 * Having provided the necessary warning indicate what course
784 		 * of action we are going to take.
785 		 *
786 		 *  o	if the file types differ, take the relocatable object
787 		 *	and apply the largest symbol size, else
788 		 *  o	if one symbol is weak and the other is non-weak, take
789 		 *	the non-weak symbol, else
790 		 *  o	simply take the largest symbol reference.
791 		 */
792 		if (nfile != ofile) {
793 			if (nfile == ET_REL) {
794 				file = ifl->ifl_name;
795 				if (osym->st_size > nsym->st_size) {
796 					size = (size_t)osym->st_size;
797 					emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
798 				}
799 				sym_override(sdp, nsym, ifl, ofl, ndx,
800 				    nshndx, nsymflags);
801 			} else {
802 				file = sdp->sd_file->ifl_name;
803 				if (osym->st_size < nsym->st_size) {
804 					size = (size_t)nsym->st_size;
805 					emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
806 				}
807 				sym_promote(sdp, nsym, ifl, ofl, ndx,
808 				    nshndx, nsymflags);
809 			}
810 		} else if (obind != nbind) {
811 			if ((obind == STB_WEAK) && (nbind != STB_WEAK)) {
812 				sym_override(sdp, nsym, ifl, ofl, ndx,
813 				    nshndx, nsymflags);
814 				file = ifl->ifl_name;
815 			} else
816 				file = sdp->sd_file->ifl_name;
817 		} else {
818 			if (osym->st_size < nsym->st_size) {
819 				sym_override(sdp, nsym, ifl, ofl, ndx,
820 				    nshndx, nsymflags);
821 				file = ifl->ifl_name;
822 			} else
823 				file = sdp->sd_file->ifl_name;
824 		}
825 		if (!(ofl->ofl_flags & FLG_OF_NOWARN))
826 			eprintf(ofl->ofl_lml, ERR_NONE, emsg, file);
827 		if (size)
828 			sdp->sd_sym->st_size = (Xword)size;
829 	} else {
830 		/*
831 		 * If the sizes are the same
832 		 *
833 		 *  o	if the file types differ, take the relocatable object,
834 		 *	else
835 		 *
836 		 *  o	if one symbol is weak and the other is non-weak, take
837 		 *	the non-weak symbol, else
838 		 *
839 		 *  o	take the first reference.
840 		 */
841 		if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN))
842 			return;
843 		else if (((ofile != nfile) && (nfile == ET_REL)) ||
844 		    (((obind == STB_WEAK) && (nbind != STB_WEAK)) &&
845 		    (!((ofile != nfile) && (ofile == ET_REL)))))
846 			sym_override(sdp, nsym, ifl, ofl, ndx,
847 			    nshndx, nsymflags);
848 		else
849 			sym_promote(sdp, nsym, ifl, ofl, ndx,
850 			    nshndx, nsymflags);
851 	}
852 
853 	/*
854 	 * Enforce the largest alignment if necessary.
855 	 */
856 	if (value)
857 		sdp->sd_sym->st_value = value;
858 }
859 
860 /*
861  * Symbol resolution state table.  `Action' describes the required
862  * procedure to be called (if any).
863  */
864 static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *,
865 	Sym *, Ifl_desc *, Ofl_desc *, int, Word, Word) = {
866 
867 /*				defined		undef		tent	*/
868 /*				ET_REL		ET_REL		ET_REL	*/
869 
870 /*  0 defined REF_DYN_SEEN */	sym_tworeals,	sym_promote,	sym_realtent,
871 /*  1   undef REF_DYN_SEEN */	sym_override,	sym_override,	sym_override,
872 /*  2    tent REF_DYN_SEEN */	sym_realtent,	sym_promote,	sym_twotent,
873 /*  3 defined REF_DYN_NEED */	sym_tworeals,	sym_typecheck,	sym_realtent,
874 /*  4   undef REF_DYN_NEED */	sym_override,	sym_override,	sym_override,
875 /*  5    tent REF_DYN_NEED */	sym_realtent,	sym_typecheck,	sym_twotent,
876 /*  6 defined REF_REL_NEED */	sym_tworeals,	sym_typecheck,	sym_realtent,
877 /*  7   undef REF_REL_NEED */	sym_override,	sym_twoundefs,	sym_override,
878 /*  8    tent REF_REL_NEED */	sym_realtent,	sym_null,	sym_twotent,
879 
880 /*				defined		undef		tent	*/
881 /*				ET_DYN		ET_DYN		ET_DYN	*/
882 
883 /*  9 defined REF_DYN_SEEN */	sym_tworeals,	sym_null,	sym_realtent,
884 /* 10   undef REF_DYN_SEEN */	sym_override,	sym_mach_check,	sym_override,
885 /* 11    tent REF_DYN_SEEN */	sym_realtent,	sym_null,	sym_twotent,
886 /* 12 defined REF_DYN_NEED */	sym_tworeals,	sym_null,	sym_realtent,
887 /* 13   undef REF_DYN_NEED */	sym_override,	sym_null,	sym_override,
888 /* 14    tent REF_DYN_NEED */	sym_realtent,	sym_null,	sym_twotent,
889 /* 15 defined REF_REL_NEED */	sym_tworeals,	sym_null,	sym_realtent,
890 /* 16   undef REF_REL_NEED */	sym_override,	sym_mach_check,	sym_override,
891 /* 17    tent REF_REL_NEED */	sym_realtent,	sym_null,	sym_twotent
892 
893 };
894 
895 uintptr_t
896 ld_sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx,
897     Word nshndx, Word nsymflags)
898 {
899 	int		row, column;		/* State table coordinates */
900 	Sym		*osym = sdp->sd_sym;
901 	Is_desc		*isp;
902 	Half		nfile = ifl->ifl_ehdr->e_type;
903 
904 	/*
905 	 * Determine the original symbols definition (defines row in Action[]).
906 	 */
907 	if (sdp->sd_flags & FLG_SY_TENTSYM)
908 		row = SYM_TENTATIVE;
909 	else if ((sdp->sd_sym->st_shndx == SHN_UNDEF) ||
910 	    (sdp->sd_sym->st_shndx == SHN_SUNW_IGNORE))
911 		row = SYM_UNDEFINED;
912 	else
913 		row = SYM_DEFINED;
914 
915 	/*
916 	 * If the input file is an implicit shared object then we don't need
917 	 * to bind to any symbols within it other than to verify that any
918 	 * undefined references will be closed (implicit shared objects are only
919 	 * processed when no undefined symbols are required as a result of the
920 	 * link-edit (see process_dynamic())).
921 	 */
922 	if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) &&
923 	    (row != SYM_UNDEFINED))
924 		return (1);
925 
926 	/*
927 	 * Finish computing the Action[] row by applying the symbols reference
928 	 * together with the input files type.
929 	 */
930 	row = row + (REF_NUM * sdp->sd_ref);
931 	if (nfile == ET_DYN)
932 		row += (REF_NUM * SYM_NUM);
933 
934 	/*
935 	 * Determine the new symbols definition (defines column in Action[]).
936 	 */
937 	if ((nsymflags & FLG_SY_SPECSEC) &&
938 	    (nsym->st_shndx == SHN_COMMON)) {
939 		column = SYM_TENTATIVE;
940 		nsymflags |= FLG_SY_TENTSYM;
941 #if	(defined(__i386) || defined(__amd64)) && defined(_ELF64)
942 	} else if ((nsymflags & FLG_SY_SPECSEC) &&
943 	    (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
944 		column = SYM_TENTATIVE;
945 		nsymflags |= FLG_SY_TENTSYM;
946 #endif
947 	} else if ((nsym->st_shndx == SHN_UNDEF) ||
948 	    (nsym->st_shndx == SHN_SUNW_IGNORE)) {
949 		column = SYM_UNDEFINED;
950 		nshndx = SHN_UNDEF;
951 	} else {
952 		column = SYM_DEFINED;
953 		/*
954 		 * If the new symbol is from a shared library and it is
955 		 * associated with a SHT_NOBITS section then this symbol
956 		 * originated from a tentative symbol.
957 		 */
958 		if (((nsymflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) {
959 			isp = ifl->ifl_isdesc[nshndx];
960 			if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) {
961 				column = SYM_TENTATIVE;
962 				nsymflags |= FLG_SY_TENTSYM;
963 			}
964 		}
965 	}
966 
967 	DBG_CALL(Dbg_syms_resolving(ofl, ndx, sdp->sd_name, row, column,
968 	    osym, nsym, sdp, ifl));
969 
970 	/*
971 	 * Record the input filename on the defined files list for possible
972 	 * later diagnostics.  The `sa_dfiles' list is used to maintain the list
973 	 * of shared objects that define the same symbol.  This list is only
974 	 * generated when the -m option is in effect and is used to list
975 	 * multiple (interposed) definitions of a symbol (refer to ldmap_out()).
976 	 */
977 	if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nsym->st_shndx != SHN_UNDEF) &&
978 	    ((nsymflags & FLG_SY_SPECSEC) == 0))
979 		if (list_appendc(&sdp->sd_aux->sa_dfiles, ifl->ifl_name) == 0)
980 			return (S_ERROR);
981 
982 	/*
983 	 * Perform the required resolution.
984 	 */
985 	Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsymflags);
986 
987 	/*
988 	 * If the symbol has been resolved to the new input file, and this is
989 	 * a versioned relocatable object, then the version information of the
990 	 * new symbol must be promoted to the versioning of the output file.
991 	 */
992 	if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) &&
993 	    (nsym->st_shndx != SHN_UNDEF))
994 		ld_vers_promote(sdp, ndx, ifl, ofl);
995 
996 	/*
997 	 * Determine whether a mapfile reference has been satisfied.  Mapfile
998 	 * symbol references augment symbols that should be contributed from
999 	 * the relocatable objects used to build the output image.  If a
1000 	 * relocatable object doesn't provide one of the mapfile symbol
1001 	 * references then somethings amiss, and will be flagged during symbol
1002 	 * validation.
1003 	 */
1004 	if ((nfile == ET_REL) && ((sdp->sd_flags &
1005 	    (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) {
1006 		/*
1007 		 * Extern and parent references are satisfied by references from
1008 		 * a relocatable object.  Note that we let *any* symbol type
1009 		 * satisfy this reference, to be as flexible as possible with
1010 		 * user written mapfiles.  It could be questionable, for
1011 		 * example, if what a user expects to be an extern reference is
1012 		 * actually found to be a definition in a relocatable object.
1013 		 *
1014 		 * Any other mapfile reference (typically for versioning
1015 		 * information) simply augments a relocatables definition.
1016 		 */
1017 		if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) ||
1018 		    ((sdp->sd_sym->st_shndx != SHN_UNDEF) &&
1019 		    (sdp->sd_ref == REF_REL_NEED)))
1020 			sdp->sd_flags |= FLG_SY_MAPUSED;
1021 	}
1022 
1023 	DBG_CALL(Dbg_syms_resolved(ofl, sdp));
1024 
1025 	return (1);
1026 }
1027