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