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