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