10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51618Srie * Common Development and Distribution License (the "License").
61618Srie * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
211618Srie
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate * Copyright (c) 1988 AT&T
240Sstevel@tonic-gate * All Rights Reserved
250Sstevel@tonic-gate *
26*13074SAli.Bahrami@Oracle.COM * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
270Sstevel@tonic-gate */
280Sstevel@tonic-gate
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate * Symbol table resolution
310Sstevel@tonic-gate */
326206Sab196087 #define ELF_TARGET_AMD64
336206Sab196087
340Sstevel@tonic-gate #include <stdio.h>
351618Srie #include <debug.h>
360Sstevel@tonic-gate #include "msg.h"
370Sstevel@tonic-gate #include "_libld.h"
380Sstevel@tonic-gate
390Sstevel@tonic-gate
400Sstevel@tonic-gate /*
410Sstevel@tonic-gate * Categorize the symbol types that are applicable to the resolution process.
420Sstevel@tonic-gate */
430Sstevel@tonic-gate typedef enum {
440Sstevel@tonic-gate SYM_DEFINED, /* Defined symbol (SHN_ABS or shndx != 0) */
450Sstevel@tonic-gate SYM_UNDEFINED, /* Undefined symbol (SHN_UNDEF) */
460Sstevel@tonic-gate SYM_TENTATIVE, /* Tentative symbol (SHN_COMMON) */
470Sstevel@tonic-gate SYM_NUM /* the number of symbol types */
480Sstevel@tonic-gate } Symtype;
490Sstevel@tonic-gate
500Sstevel@tonic-gate /*
510Sstevel@tonic-gate * Do nothing.
520Sstevel@tonic-gate */
530Sstevel@tonic-gate /* ARGSUSED0 */
540Sstevel@tonic-gate static void
sym_null(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)550Sstevel@tonic-gate sym_null(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
5610792SRod.Evans@Sun.COM int ndx, Word nshndx, sd_flag_t nsdflags)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate }
590Sstevel@tonic-gate
605220Srie static void
sym_visibility_diag(Error err,Sym_desc * sdp,Sym * osym,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl)615220Srie sym_visibility_diag(Error err, Sym_desc *sdp, Sym *osym, Sym *nsym,
625220Srie Ifl_desc *ifl, Ofl_desc *ofl)
635220Srie {
645220Srie Conv_inv_buf_t inv_obuf, inv_nbuf;
655220Srie
6611993SAli.Bahrami@Sun.COM /* Warnings are only issued when -z verbose is specified */
6711993SAli.Bahrami@Sun.COM if (!(ofl->ofl_flags & FLG_OF_VERBOSE) && (err != ERR_FATAL))
6811993SAli.Bahrami@Sun.COM return;
6911993SAli.Bahrami@Sun.COM
70*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, err, MSG_INTL(MSG_SYM_CONFVIS), demangle(sdp->sd_name));
71*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_VISTYPES),
725220Srie sdp->sd_file->ifl_name, conv_sym_other(osym->st_other, &inv_obuf),
735220Srie ifl->ifl_name, conv_sym_other(nsym->st_other, &inv_nbuf));
745220Srie
75*13074SAli.Bahrami@Oracle.COM if (err != ERR_FATAL)
76*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
775220Srie ifl->ifl_name);
785220Srie }
795220Srie
805220Srie /*
815220Srie * STV_VISIBILITY rules for STV_DEFAULT/INTERNAL/HIDDEN/PROTECTED say that the
825220Srie * most restrictive visibility value should be taken. The precedence is:
835220Srie *
845220Srie * (most restrictive) INTERNAL -> HIDDEN -> PROTECTED -> DEFAULT (least)
855220Srie *
865220Srie * The STV_EXPORT and STV_SINGLETON visibilities are slightly different, in that
875220Srie * the visibility must remain global and can not be reduced in any way.
885220Srie *
895220Srie * Resolution of different visibilities between two relocatable objects can
905220Srie * take the following actions:
915220Srie *
925220Srie * i. if applicable, the most restrictive action is silently taken.
935220Srie * ii. if a mapfile visibility definition competes with a more restrictive
945220Srie * relocatable object definition, then a warning is generated, but the
955220Srie * the more restrictive visibility is taken.
965220Srie * iii. in the case of conflicts with an EXPORTED or SINGLETON symbol with
975220Srie * any type of visibility between relocatable objects, the combination
985220Srie * is deemed fatal.
995220Srie *
1005220Srie * new visibility
1015220Srie * D I H P X S
1025220Srie * ------------------------------------------------------------
1035220Srie * D | D I(mw) H(mw) P X S
1045220Srie * original I | I I I I X(mw/of) S(mw/of)
1055220Srie * visibility H | H I(mw) H H X(mw/of) S(mw/of)
1065220Srie * P | P I(mw) H(mw) P X(mw/of) S(mw/of)
1075220Srie * X | X I(mw/of) H(mw/of) P(mw/of) X S
1085220Srie * S | S I(mw/of) H(mw/of) P(mw/of) S S
1095220Srie * where:
1105220Srie *
1115220Srie * mw - mapfile warning: if the original symbol originates from a mapfile
1125220Srie * then warn the user that their scope definition is being overridden.
1135220Srie * of - object definitions are fatal: any combination of relocatable object
1145220Srie * visibilities that conflict with a SINGLETON and EXPORTED are fatal.
1155220Srie *
1165220Srie * Note, an eliminate symbol (STV_ELIMINATE) is treated as hidden (STV_HIDDEN)
1175220Srie * for processing through this state table.
1185220Srie */
1195220Srie static Half
sym_visibility(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl)1205220Srie sym_visibility(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl)
1215220Srie {
1225220Srie Sym *osym = sdp->sd_sym;
1235220Srie uchar_t wovis, ovis;
1245220Srie uchar_t wnvis, nvis;
1255220Srie
1265220Srie wovis = ovis = ELF_ST_VISIBILITY(osym->st_other);
1275220Srie wnvis = nvis = ELF_ST_VISIBILITY(nsym->st_other);
1285220Srie
1295220Srie /*
1305220Srie * If the original visibilities are eliminate, assign them hidden for
1315220Srie * the state table processing. The original visibility, rather than
1325220Srie * the working visibility, will be returned to the caller.
1335220Srie */
1345220Srie if (wovis == STV_ELIMINATE)
1355220Srie wovis = STV_HIDDEN;
1365220Srie if (wnvis == STV_ELIMINATE)
1375220Srie wnvis = STV_HIDDEN;
1385220Srie
1395220Srie /*
1405220Srie * The most complex visibility resolution is between two relocatable
1415220Srie * objects. However, in the case of SINGLETONS we also want to catch
1425220Srie * any singleton definitions within shared objects. Relocatable objects
1435220Srie * that bind to these symbols inherit the singleton visibility as this
1445220Srie * efficiently triggers ld.so.1 into carrying out the appropriate
1455220Srie * runtime symbol search. Any other resolution between a relocatable
1465220Srie * object and a shared object will retain the relocatable objects
1475220Srie * visibility.
1485220Srie */
1495220Srie if ((sdp->sd_ref == REF_REL_NEED) &&
1505220Srie (ifl->ifl_ehdr->e_type == ET_DYN)) {
1515220Srie if ((sdp->sd_sym->st_shndx == SHN_UNDEF) &&
1525220Srie (nsym->st_shndx != SHN_UNDEF) && (wnvis == STV_SINGLETON))
1535220Srie return (STV_SINGLETON);
1545220Srie else
1555220Srie return (ovis);
1565220Srie }
1575220Srie if ((sdp->sd_ref != REF_REL_NEED) &&
1585220Srie (ifl->ifl_ehdr->e_type == ET_REL)) {
1595220Srie if ((sdp->sd_sym->st_shndx != SHN_UNDEF) &&
1605220Srie (nsym->st_shndx == SHN_UNDEF) && (wovis == STV_SINGLETON))
1615220Srie return (STV_SINGLETON);
1625220Srie else
1635220Srie return (nvis);
1645220Srie }
1655220Srie
1665220Srie /*
1675220Srie * If the visibilities are the same, we're done. If the working
1685220Srie * visibilities differ from the original, then one must have been
1695220Srie * STV_HIDDEN and the other STV_ELIMINATE.
1705220Srie */
1715220Srie if (wovis == wnvis) {
1725220Srie if (ovis == nvis)
1735220Srie return (nvis);
1745220Srie else
1755220Srie return (STV_ELIMINATE);
1765220Srie }
1775220Srie
1785220Srie /*
1795220Srie * An EXPORTED symbol or SINGLETON symbol can not be demoted, any
1805220Srie * conflicting visibility from another object is fatal. A conflicting
1815220Srie * visibility from a mapfile produces a warning, as the mapfile
1825220Srie * definition can be overridden.
1835220Srie */
1845220Srie if ((wnvis == STV_EXPORTED) || (wnvis == STV_SINGLETON)) {
1855220Srie if ((wovis != STV_DEFAULT) && (wovis != STV_EXPORTED) &&
1865220Srie (wovis != STV_SINGLETON)) {
18710792SRod.Evans@Sun.COM if (sdp->sd_flags & FLG_SY_MAPFILE) {
1885220Srie sym_visibility_diag(ERR_WARNING, sdp, osym,
1895220Srie nsym, ifl, ofl);
1905220Srie } else {
1915220Srie sym_visibility_diag(ERR_FATAL, sdp, osym,
1925220Srie nsym, ifl, ofl);
1935220Srie }
1945220Srie }
1955220Srie return (nvis);
1965220Srie }
1975220Srie if (wovis == STV_SINGLETON) {
1985220Srie if ((wnvis == STV_EXPORTED) || (wnvis == STV_DEFAULT))
1995220Srie return (STV_SINGLETON);
20010792SRod.Evans@Sun.COM if (sdp->sd_flags & FLG_SY_MAPFILE) {
2015220Srie sym_visibility_diag(ERR_WARNING, sdp, osym,
2025220Srie nsym, ifl, ofl);
2035220Srie } else {
2045220Srie sym_visibility_diag(ERR_FATAL, sdp, osym,
2055220Srie nsym, ifl, ofl);
2065220Srie }
2075220Srie return (nvis);
2085220Srie }
2095220Srie if (wovis == STV_EXPORTED) {
2105220Srie if (wnvis == STV_SINGLETON)
2115220Srie return (STV_SINGLETON);
2125220Srie if (wnvis == STV_DEFAULT)
2135220Srie return (STV_EXPORTED);
21410792SRod.Evans@Sun.COM if (sdp->sd_flags & FLG_SY_MAPFILE) {
2155220Srie sym_visibility_diag(ERR_WARNING, sdp, osym,
2165220Srie nsym, ifl, ofl);
2175220Srie } else {
2185220Srie sym_visibility_diag(ERR_FATAL, sdp, osym,
2195220Srie nsym, ifl, ofl);
2205220Srie }
2215220Srie return (nvis);
2225220Srie }
2235220Srie
2245220Srie /*
2255220Srie * Now that symbols with the same visibility, and all instances of
2265220Srie * SINGLETON's have been dealt with, we're left with visibilities that
2275220Srie * differ, but can be dealt with in the order of how restrictive the
2285220Srie * visibilities are. When a differing visibility originates from a
2295220Srie * mapfile definition, produces a warning, as the mapfile definition
2305220Srie * can be overridden by the relocatable object.
2315220Srie */
2325220Srie if ((wnvis == STV_INTERNAL) || (wovis == STV_INTERNAL)) {
2335220Srie if ((wnvis == STV_INTERNAL) &&
23410792SRod.Evans@Sun.COM (sdp->sd_flags & FLG_SY_MAPFILE)) {
2355220Srie sym_visibility_diag(ERR_WARNING, sdp, osym, nsym,
2365220Srie ifl, ofl);
2375220Srie }
2385220Srie return (STV_INTERNAL);
2395220Srie
2405220Srie } else if ((wnvis == STV_HIDDEN) || (wovis == STV_HIDDEN)) {
2415220Srie if ((wnvis == STV_HIDDEN) &&
24210792SRod.Evans@Sun.COM (sdp->sd_flags & FLG_SY_MAPFILE)) {
2435220Srie sym_visibility_diag(ERR_WARNING, sdp, osym, nsym,
2445220Srie ifl, ofl);
2455220Srie }
2465220Srie
2475220Srie /*
2485220Srie * In the case of STV_ELIMINATE and STV_HIDDEN, the working
2495220Srie * visibility can differ from the original visibility, so make
2505220Srie * sure to return the original visibility.
2515220Srie */
2525220Srie if ((ovis == STV_ELIMINATE) || (nvis == STV_ELIMINATE))
2535220Srie return (STV_ELIMINATE);
2545220Srie else
2555220Srie return (STV_HIDDEN);
2565220Srie
2575220Srie } else if ((wnvis == STV_PROTECTED) || (wovis == STV_PROTECTED))
2585220Srie return (STV_PROTECTED);
2595220Srie
2605220Srie return (STV_DEFAULT);
2615220Srie }
2625220Srie
2630Sstevel@tonic-gate /*
2640Sstevel@tonic-gate * Check if two symbols types are compatible
2650Sstevel@tonic-gate */
2660Sstevel@tonic-gate /*ARGSUSED4*/
2670Sstevel@tonic-gate static void
sym_typecheck(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)2680Sstevel@tonic-gate sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
26910792SRod.Evans@Sun.COM int ndx, Word nshndx, sd_flag_t nsdflags)
2700Sstevel@tonic-gate {
2714734Sab196087 uchar_t otype = ELF_ST_TYPE(sdp->sd_sym->st_info);
2724734Sab196087 uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
2734734Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2;
2740Sstevel@tonic-gate
2750Sstevel@tonic-gate /*
2760Sstevel@tonic-gate * Perform any machine specific type checking.
2770Sstevel@tonic-gate */
2786206Sab196087 if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) &&
2796206Sab196087 (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl))
2800Sstevel@tonic-gate return;
2810Sstevel@tonic-gate
2820Sstevel@tonic-gate /*
2835220Srie * NOTYPE's can be combined with other types, only give an error if
2845220Srie * combining two differing types without NOTYPE.
2850Sstevel@tonic-gate */
2860Sstevel@tonic-gate if ((otype == ntype) || (otype == STT_NOTYPE) || (ntype == STT_NOTYPE))
2870Sstevel@tonic-gate return;
2880Sstevel@tonic-gate
289*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
2900Sstevel@tonic-gate demangle(sdp->sd_name));
291*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
2921618Srie sdp->sd_file->ifl_name,
2934734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 0, &inv_buf1),
2941976Sab196087 ifl->ifl_name,
2954734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 0, &inv_buf2));
2960Sstevel@tonic-gate }
2970Sstevel@tonic-gate
2980Sstevel@tonic-gate /*ARGSUSED4*/
2990Sstevel@tonic-gate static void
sym_mach_check(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)3000Sstevel@tonic-gate sym_mach_check(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
30110792SRod.Evans@Sun.COM int ndx, Word nshndx, sd_flag_t nsdflags)
3020Sstevel@tonic-gate {
3030Sstevel@tonic-gate /*
3040Sstevel@tonic-gate * Perform any machine specific type checking.
3050Sstevel@tonic-gate */
3066206Sab196087 if (ld_targ.t_ms.ms_mach_sym_typecheck != NULL)
3076206Sab196087 (void) (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym,
3086206Sab196087 ifl, ofl);
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate
3110Sstevel@tonic-gate /*
3120Sstevel@tonic-gate * Promote the symbols reference.
3130Sstevel@tonic-gate */
3140Sstevel@tonic-gate static void
3150Sstevel@tonic-gate /* ARGSUSED4 */
sym_promote(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)3160Sstevel@tonic-gate sym_promote(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
31710792SRod.Evans@Sun.COM int ndx, Word nshndx, sd_flag_t nsdflags)
3180Sstevel@tonic-gate {
3191682Srie Word shndx = nsym->st_shndx;
3201682Srie
32110792SRod.Evans@Sun.COM sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
3220Sstevel@tonic-gate
3230Sstevel@tonic-gate /*
3240Sstevel@tonic-gate * If the old symbol is from a shared object and the new symbol is a
3250Sstevel@tonic-gate * reference from a relocatable object, promote the old symbols
3260Sstevel@tonic-gate * reference.
3270Sstevel@tonic-gate */
3280Sstevel@tonic-gate if ((sdp->sd_ref == REF_DYN_SEEN) &&
3290Sstevel@tonic-gate (ifl->ifl_ehdr->e_type == ET_REL)) {
3300Sstevel@tonic-gate sdp->sd_ref = REF_DYN_NEED;
3310Sstevel@tonic-gate
3320Sstevel@tonic-gate /*
3330Sstevel@tonic-gate * If this is an undefined symbol it must be a relocatable
3340Sstevel@tonic-gate * object overriding a shared object. In this case also
3350Sstevel@tonic-gate * override the reference name so that any undefined symbol
3360Sstevel@tonic-gate * diagnostics will refer to the relocatable object name.
3370Sstevel@tonic-gate */
3381682Srie if (shndx == SHN_UNDEF)
3390Sstevel@tonic-gate sdp->sd_aux->sa_rfile = ifl->ifl_name;
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate /*
3420Sstevel@tonic-gate * If this symbol is an undefined, or common, determine whether
3430Sstevel@tonic-gate * it is a global or weak reference (see build_osym(), where
3440Sstevel@tonic-gate * REF_DYN_NEED definitions are returned back to undefines).
3450Sstevel@tonic-gate */
34610792SRod.Evans@Sun.COM if (((shndx == SHN_UNDEF) || ((nsdflags & FLG_SY_SPECSEC) &&
3471682Srie (shndx == SHN_COMMON))) &&
3480Sstevel@tonic-gate (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
3490Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_GLOBREF;
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate }
3520Sstevel@tonic-gate }
3530Sstevel@tonic-gate
3540Sstevel@tonic-gate /*
3550Sstevel@tonic-gate * Override a symbol.
3560Sstevel@tonic-gate */
3570Sstevel@tonic-gate static void
sym_override(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)3580Sstevel@tonic-gate sym_override(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
35910792SRod.Evans@Sun.COM int ndx, Word nshndx, sd_flag_t nsdflags)
3600Sstevel@tonic-gate {
3615220Srie Sym *osym = sdp->sd_sym;
3625220Srie Word link;
3630Sstevel@tonic-gate
3640Sstevel@tonic-gate /*
3650Sstevel@tonic-gate * In the case of a WEAK UNDEF symbol don't let a symbol from an
3660Sstevel@tonic-gate * unavailable object override the symbol definition. This is because
3670Sstevel@tonic-gate * this symbol *may* not be present in a future object and by promoting
3680Sstevel@tonic-gate * this symbol we are actually causing bindings (PLTS) to be formed
3690Sstevel@tonic-gate * to this symbol. Instead let the 'generic' weak binding take place.
3700Sstevel@tonic-gate */
3710Sstevel@tonic-gate if ((ELF_ST_BIND(osym->st_info) == STB_WEAK) &&
3721682Srie (sdp->sd_sym->st_shndx == SHN_UNDEF) &&
3731682Srie ((ifl->ifl_flags & FLG_IF_NEEDED) == 0))
3740Sstevel@tonic-gate return;
3750Sstevel@tonic-gate
37610792SRod.Evans@Sun.COM sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
3770Sstevel@tonic-gate
3780Sstevel@tonic-gate /*
3790Sstevel@tonic-gate * This symbol has already been compared to an SO definition,
3800Sstevel@tonic-gate * as per the runtime behavior, ignore extra definitions.
3810Sstevel@tonic-gate */
3820Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) &&
3830Sstevel@tonic-gate (ifl->ifl_ehdr->e_type == ET_DYN))
3840Sstevel@tonic-gate return;
3850Sstevel@tonic-gate
3860Sstevel@tonic-gate /*
3870Sstevel@tonic-gate * Mark the symbol as available and copy the new symbols contents.
3880Sstevel@tonic-gate */
3890Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_NOTAVAIL;
3900Sstevel@tonic-gate *osym = *nsym;
3910Sstevel@tonic-gate sdp->sd_shndx = nshndx;
3920Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_SPECSEC;
39310792SRod.Evans@Sun.COM sdp->sd_flags |= (nsdflags & (FLG_SY_SPECSEC | FLG_SY_TENTSYM));
3940Sstevel@tonic-gate
3950Sstevel@tonic-gate /*
3960Sstevel@tonic-gate * If the new symbol has PROTECTED visibility, mark it. If a PROTECTED
3975220Srie * symbol is copy relocated, a warning message will be printed. See
3980Sstevel@tonic-gate * reloc_exec().
3990Sstevel@tonic-gate */
4000Sstevel@tonic-gate if (ELF_ST_VISIBILITY(nsym->st_other) == STV_PROTECTED)
4010Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_PROT;
4020Sstevel@tonic-gate else
4030Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_PROT;
4040Sstevel@tonic-gate
4050Sstevel@tonic-gate /*
4060Sstevel@tonic-gate * Establish the symbols reference. If the new symbol originates from a
4070Sstevel@tonic-gate * relocatable object then this reference becomes needed, otherwise
4080Sstevel@tonic-gate * the new symbol must be from a shared object. In this case only
4090Sstevel@tonic-gate * promote the symbol to needed if we presently have a reference from a
4100Sstevel@tonic-gate * relocatable object.
4110Sstevel@tonic-gate */
4120Sstevel@tonic-gate if (ifl->ifl_ehdr->e_type == ET_REL) {
4130Sstevel@tonic-gate sdp->sd_ref = REF_REL_NEED;
4140Sstevel@tonic-gate
4151682Srie if (nsym->st_shndx == SHN_UNDEF) {
4160Sstevel@tonic-gate /*
41711827SRod.Evans@Sun.COM * If this is an undefined symbol, then we can only be
41811827SRod.Evans@Sun.COM * attempting to override an existing undefined symbol.
41911827SRod.Evans@Sun.COM * The original symbol is either:
42011827SRod.Evans@Sun.COM *
42111827SRod.Evans@Sun.COM * - a mapfile definition
42211827SRod.Evans@Sun.COM * - a previous relocatable object whose visibility
42311827SRod.Evans@Sun.COM * or type should be overridden by this new symbol
42411827SRod.Evans@Sun.COM * - a previous shared object
42511827SRod.Evans@Sun.COM *
42611827SRod.Evans@Sun.COM * If the original undefined symbol stems from a mapfile
42711827SRod.Evans@Sun.COM * then don't alter the reference file name. Should we
42811827SRod.Evans@Sun.COM * end up with some form of 'undefined' symbol error,
42911827SRod.Evans@Sun.COM * the characteristics of that error are most likely to
43011827SRod.Evans@Sun.COM * have originated from a mapfile.
43111827SRod.Evans@Sun.COM *
43211827SRod.Evans@Sun.COM * Otherwise, update the reference file name to indicate
43311827SRod.Evans@Sun.COM * this symbol.
4340Sstevel@tonic-gate */
43511827SRod.Evans@Sun.COM if ((sdp->sd_flags & FLG_SY_MAPREF) == 0)
43611827SRod.Evans@Sun.COM sdp->sd_aux->sa_rfile = ifl->ifl_name;
4370Sstevel@tonic-gate } else {
4380Sstevel@tonic-gate /*
4393466Srie * Under -Bnodirect, all exported interfaces that have
4403466Srie * not explicitly been defined protected or directly
4413466Srie * bound to, are tagged to prevent direct binding.
4420Sstevel@tonic-gate */
4430Sstevel@tonic-gate if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) &&
44410792SRod.Evans@Sun.COM ((sdp->sd_flags &
44510792SRod.Evans@Sun.COM (FLG_SY_PROTECT | FLG_SY_DIR)) == 0))
44610792SRod.Evans@Sun.COM sdp->sd_flags |= FLG_SY_NDIR;
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate /*
4500Sstevel@tonic-gate * If this symbol is an undefined, or common, determine whether
4510Sstevel@tonic-gate * it is a global or weak reference (see build_osym(), where
4520Sstevel@tonic-gate * REF_DYN_NEED definitions are returned back to undefines).
4530Sstevel@tonic-gate */
4541682Srie if (((nsym->st_shndx == SHN_UNDEF) ||
45510792SRod.Evans@Sun.COM ((nsdflags & FLG_SY_SPECSEC) &&
4561682Srie (nsym->st_shndx == SHN_COMMON))) &&
4570Sstevel@tonic-gate (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL))
4580Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_GLOBREF;
4590Sstevel@tonic-gate else
4600Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_GLOBREF;
4610Sstevel@tonic-gate } else {
4620Sstevel@tonic-gate if (sdp->sd_ref == REF_REL_NEED)
4630Sstevel@tonic-gate sdp->sd_ref = REF_DYN_NEED;
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate /*
4660Sstevel@tonic-gate * Determine the symbols availability. A symbol is determined
4670Sstevel@tonic-gate * to be unavailable if it belongs to a version of a shared
4680Sstevel@tonic-gate * object that this user does not wish to use, or if it belongs
4690Sstevel@tonic-gate * to an implicit shared object.
4700Sstevel@tonic-gate */
4710Sstevel@tonic-gate if (ifl->ifl_vercnt) {
4725220Srie Ver_index *vip;
4730Sstevel@tonic-gate Half vndx = ifl->ifl_versym[ndx];
4740Sstevel@tonic-gate
4750Sstevel@tonic-gate sdp->sd_aux->sa_dverndx = vndx;
4760Sstevel@tonic-gate vip = &ifl->ifl_verndx[vndx];
4770Sstevel@tonic-gate if (!(vip->vi_flags & FLG_VER_AVAIL)) {
4780Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_NOTAVAIL;
4790Sstevel@tonic-gate /*
4805220Srie * If this is the first occurrence of an
4810Sstevel@tonic-gate * unavailable symbol record it for possible
4820Sstevel@tonic-gate * use in later error diagnostics
4830Sstevel@tonic-gate * (see sym_undef).
4840Sstevel@tonic-gate */
4850Sstevel@tonic-gate if (!(sdp->sd_aux->sa_vfile))
4860Sstevel@tonic-gate sdp->sd_aux->sa_vfile = ifl->ifl_name;
4870Sstevel@tonic-gate }
4880Sstevel@tonic-gate }
4890Sstevel@tonic-gate if (!(ifl->ifl_flags & FLG_IF_NEEDED))
4900Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_NOTAVAIL;
4910Sstevel@tonic-gate }
4920Sstevel@tonic-gate
4930Sstevel@tonic-gate /*
4940Sstevel@tonic-gate * Make sure any symbol association maintained by the original symbol
4950Sstevel@tonic-gate * is cleared and then update the symbols file reference.
4960Sstevel@tonic-gate */
4970Sstevel@tonic-gate if ((link = sdp->sd_aux->sa_linkndx) != 0) {
4980Sstevel@tonic-gate Sym_desc * _sdp;
4990Sstevel@tonic-gate
5000Sstevel@tonic-gate _sdp = sdp->sd_file->ifl_oldndx[link];
5010Sstevel@tonic-gate _sdp->sd_aux->sa_linkndx = 0;
5020Sstevel@tonic-gate sdp->sd_aux->sa_linkndx = 0;
5030Sstevel@tonic-gate }
5040Sstevel@tonic-gate sdp->sd_file = ifl;
5050Sstevel@tonic-gate
5060Sstevel@tonic-gate /*
5070Sstevel@tonic-gate * Update the input section descriptor to that of the new input file
5080Sstevel@tonic-gate */
50910792SRod.Evans@Sun.COM if (((nsdflags & FLG_SY_SPECSEC) == 0) &&
510*13074SAli.Bahrami@Oracle.COM (nsym->st_shndx != SHN_UNDEF) &&
511*13074SAli.Bahrami@Oracle.COM ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == NULL))
512*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_NOSECDEF),
513*13074SAli.Bahrami@Oracle.COM demangle(sdp->sd_name), ifl->ifl_name);
5140Sstevel@tonic-gate }
5150Sstevel@tonic-gate
5160Sstevel@tonic-gate /*
5170Sstevel@tonic-gate * Resolve two undefines (only called for two relocatable objects).
5180Sstevel@tonic-gate */
5190Sstevel@tonic-gate static void
sym_twoundefs(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)5200Sstevel@tonic-gate sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
52110792SRod.Evans@Sun.COM int ndx, Word nshndx, sd_flag_t nsdflags)
5220Sstevel@tonic-gate {
5233731Srie Sym *osym = sdp->sd_sym;
5243731Srie uchar_t obind = ELF_ST_BIND(osym->st_info);
52511827SRod.Evans@Sun.COM uchar_t otype = ELF_ST_TYPE(osym->st_info);
5263731Srie uchar_t nbind = ELF_ST_BIND(nsym->st_info);
52711827SRod.Evans@Sun.COM uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
5280Sstevel@tonic-gate
5290Sstevel@tonic-gate /*
5300Sstevel@tonic-gate * If two relocatable objects define a weak and non-weak undefined
5310Sstevel@tonic-gate * reference, take the non-weak definition.
5320Sstevel@tonic-gate *
5330Sstevel@tonic-gate * -- or --
5340Sstevel@tonic-gate *
5350Sstevel@tonic-gate * If two relocatable objects define a NOTYPE & another, then
5360Sstevel@tonic-gate * take the other.
5370Sstevel@tonic-gate */
5380Sstevel@tonic-gate if (((obind == STB_WEAK) && (nbind != STB_WEAK)) ||
53911827SRod.Evans@Sun.COM (otype == STT_NOTYPE) && (ntype != STT_NOTYPE)) {
54010792SRod.Evans@Sun.COM sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
5410Sstevel@tonic-gate return;
5420Sstevel@tonic-gate }
54310792SRod.Evans@Sun.COM sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
5440Sstevel@tonic-gate }
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate /*
5470Sstevel@tonic-gate * Resolve two real definitions.
5480Sstevel@tonic-gate */
5490Sstevel@tonic-gate static void
sym_tworeals(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)5500Sstevel@tonic-gate sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
55110792SRod.Evans@Sun.COM int ndx, Word nshndx, sd_flag_t nsdflags)
5520Sstevel@tonic-gate {
5534734Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2;
5543731Srie Sym *osym = sdp->sd_sym;
5553731Srie uchar_t otype = ELF_ST_TYPE(osym->st_info);
5563731Srie uchar_t obind = ELF_ST_BIND(osym->st_info);
5573731Srie uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
5583731Srie uchar_t nbind = ELF_ST_BIND(nsym->st_info);
5593731Srie Half ofile = sdp->sd_file->ifl_ehdr->e_type;
5603731Srie Half nfile = ifl->ifl_ehdr->e_type;
5613731Srie int warn = 0;
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate /*
5640Sstevel@tonic-gate * If both definitions are from relocatable objects, and have non-weak
5650Sstevel@tonic-gate * binding then this is a fatal condition.
5660Sstevel@tonic-gate */
5670Sstevel@tonic-gate if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) &&
5680Sstevel@tonic-gate (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) {
569*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
5700Sstevel@tonic-gate demangle(sdp->sd_name));
571*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
5720Sstevel@tonic-gate sdp->sd_file->ifl_name,
5734734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
5744734Sab196087 0, &inv_buf1), ifl->ifl_name,
5754734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
5764734Sab196087 0, &inv_buf2));
5770Sstevel@tonic-gate return;
5780Sstevel@tonic-gate }
5790Sstevel@tonic-gate
5800Sstevel@tonic-gate /*
5810Sstevel@tonic-gate * Perform any machine specific type checking.
5820Sstevel@tonic-gate */
5836206Sab196087 if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) &&
5846206Sab196087 (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl))
5850Sstevel@tonic-gate return;
5860Sstevel@tonic-gate
5870Sstevel@tonic-gate /*
5880Sstevel@tonic-gate * Check the symbols type and size.
5890Sstevel@tonic-gate */
5900Sstevel@tonic-gate if (otype != ntype) {
591*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
5920Sstevel@tonic-gate demangle(sdp->sd_name));
593*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
5940Sstevel@tonic-gate sdp->sd_file->ifl_name,
5954734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
5964734Sab196087 0, &inv_buf1), ifl->ifl_name,
5974734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
5984734Sab196087 0, &inv_buf2));
5990Sstevel@tonic-gate warn++;
6000Sstevel@tonic-gate } else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) {
6010Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
602*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_WARNING,
6031618Srie MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
6041618Srie MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
6051618Srie EC_XWORD(osym->st_size), ifl->ifl_name,
6061618Srie EC_XWORD(nsym->st_size));
6070Sstevel@tonic-gate warn++;
6080Sstevel@tonic-gate }
6090Sstevel@tonic-gate }
6100Sstevel@tonic-gate
6110Sstevel@tonic-gate /*
6120Sstevel@tonic-gate * Having provided the user with any necessary warnings, take the
6130Sstevel@tonic-gate * appropriate symbol:
6140Sstevel@tonic-gate *
61510167SRod.Evans@Sun.COM * - if one symbol is from a shared object and the other is from a
6160Sstevel@tonic-gate * relocatable object, take the relocatable objects symbol (the
6170Sstevel@tonic-gate * run-time linker is always going to find the relocatable object
6180Sstevel@tonic-gate * symbol regardless of the binding), else
6190Sstevel@tonic-gate *
62010167SRod.Evans@Sun.COM * - if both symbols are from relocatable objects and one symbol is
6210Sstevel@tonic-gate * weak take the non-weak symbol (two non-weak symbols would have
6220Sstevel@tonic-gate * generated the fatal error condition above unless -z muldefs is
6230Sstevel@tonic-gate * in effect), else
6240Sstevel@tonic-gate *
62510167SRod.Evans@Sun.COM * - take the first symbol definition encountered.
6260Sstevel@tonic-gate */
6270Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
6280Sstevel@tonic-gate if (warn)
629*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
630*13074SAli.Bahrami@Oracle.COM sdp->sd_file->ifl_name);
6310Sstevel@tonic-gate return;
6320Sstevel@tonic-gate } else if ((nfile == ET_REL) && ((ofile == ET_DYN) ||
6330Sstevel@tonic-gate ((obind == STB_WEAK) && (nbind != STB_WEAK)))) {
6340Sstevel@tonic-gate if (warn)
635*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
636*13074SAli.Bahrami@Oracle.COM ifl->ifl_name);
63710792SRod.Evans@Sun.COM sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
6380Sstevel@tonic-gate return;
6390Sstevel@tonic-gate } else {
6400Sstevel@tonic-gate if (warn)
641*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
642*13074SAli.Bahrami@Oracle.COM sdp->sd_file->ifl_name);
64310792SRod.Evans@Sun.COM sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
6440Sstevel@tonic-gate return;
6450Sstevel@tonic-gate }
6460Sstevel@tonic-gate }
6470Sstevel@tonic-gate
6480Sstevel@tonic-gate /*
6490Sstevel@tonic-gate * Resolve a real and tentative definition.
6500Sstevel@tonic-gate */
6510Sstevel@tonic-gate static void
sym_realtent(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)6520Sstevel@tonic-gate sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
65310792SRod.Evans@Sun.COM int ndx, Word nshndx, sd_flag_t nsdflags)
6540Sstevel@tonic-gate {
6554734Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2;
6563731Srie Sym *osym = sdp->sd_sym;
6573731Srie uchar_t otype = ELF_ST_TYPE(osym->st_info);
6583731Srie uchar_t obind = ELF_ST_BIND(osym->st_info);
6593731Srie uchar_t ntype = ELF_ST_TYPE(nsym->st_info);
6603731Srie uchar_t nbind = ELF_ST_BIND(nsym->st_info);
6613731Srie Boolean otent = FALSE, ntent = FALSE;
6623731Srie Half ofile = sdp->sd_file->ifl_ehdr->e_type;
6633731Srie Half nfile = ifl->ifl_ehdr->e_type;
6643731Srie int warn = 0;
6655220Srie uchar_t ovis = ELF_ST_VISIBILITY(osym->st_other);
6665220Srie uchar_t nvis = ELF_ST_VISIBILITY(nsym->st_other);
6670Sstevel@tonic-gate
6680Sstevel@tonic-gate /*
6690Sstevel@tonic-gate * Special rules for functions.
6700Sstevel@tonic-gate *
67110167SRod.Evans@Sun.COM * - If both definitions are from relocatable objects, have the same
6720Sstevel@tonic-gate * binding (ie. two weaks or two non-weaks), and the real
6730Sstevel@tonic-gate * definition is a function (the other must be tentative), treat
6740Sstevel@tonic-gate * this as a multiply defined symbol error, else
6750Sstevel@tonic-gate *
67610167SRod.Evans@Sun.COM * - if the real symbol definition is a function within a shared
6770Sstevel@tonic-gate * library and the tentative symbol is a relocatable object, and
6780Sstevel@tonic-gate * the tentative is not weak and the function real, then retain the
6790Sstevel@tonic-gate * tentative definition.
6800Sstevel@tonic-gate */
6810Sstevel@tonic-gate if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) &&
6820Sstevel@tonic-gate ((otype == STT_FUNC) || (ntype == STT_FUNC))) {
6830Sstevel@tonic-gate if (ofl->ofl_flags & FLG_OF_MULDEFS) {
684*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
685*13074SAli.Bahrami@Oracle.COM demangle(sdp->sd_name));
6860Sstevel@tonic-gate sym_promote(sdp, nsym, ifl, ofl, ndx,
68710792SRod.Evans@Sun.COM nshndx, nsdflags);
6880Sstevel@tonic-gate } else {
689*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
690*13074SAli.Bahrami@Oracle.COM demangle(sdp->sd_name));
6910Sstevel@tonic-gate }
692*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
6930Sstevel@tonic-gate sdp->sd_file->ifl_name,
6944734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
6954734Sab196087 0, &inv_buf1), ifl->ifl_name,
6964734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
6974734Sab196087 0, &inv_buf2));
6980Sstevel@tonic-gate return;
6990Sstevel@tonic-gate } else if (ofile != nfile) {
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate
7020Sstevel@tonic-gate if ((ofile == ET_DYN) && (otype == STT_FUNC)) {
7030Sstevel@tonic-gate if ((otype != STB_WEAK) && (ntype == STB_WEAK))
7040Sstevel@tonic-gate return;
7050Sstevel@tonic-gate else {
7060Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx,
70710792SRod.Evans@Sun.COM nshndx, nsdflags);
7080Sstevel@tonic-gate return;
7090Sstevel@tonic-gate }
7100Sstevel@tonic-gate }
7110Sstevel@tonic-gate if ((nfile == ET_DYN) && (ntype == STT_FUNC)) {
7120Sstevel@tonic-gate if ((ntype != STB_WEAK) && (otype == STB_WEAK)) {
7130Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx,
71410792SRod.Evans@Sun.COM nshndx, nsdflags);
7150Sstevel@tonic-gate return;
7160Sstevel@tonic-gate } else
7170Sstevel@tonic-gate return;
7180Sstevel@tonic-gate }
7190Sstevel@tonic-gate }
7200Sstevel@tonic-gate
7210Sstevel@tonic-gate if (sdp->sd_flags & FLG_SY_TENTSYM)
7220Sstevel@tonic-gate otent = TRUE;
72310792SRod.Evans@Sun.COM if (nsdflags & FLG_SY_TENTSYM)
7240Sstevel@tonic-gate ntent = TRUE;
7250Sstevel@tonic-gate
7260Sstevel@tonic-gate
7270Sstevel@tonic-gate /*
7280Sstevel@tonic-gate * Check the symbols type and size.
7290Sstevel@tonic-gate */
7300Sstevel@tonic-gate if (otype != ntype) {
731*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
7320Sstevel@tonic-gate demangle(sdp->sd_name));
733*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
7340Sstevel@tonic-gate sdp->sd_file->ifl_name,
7354734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
7364734Sab196087 0, &inv_buf1), ifl->ifl_name,
7374734Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
7384734Sab196087 0, &inv_buf2));
7390Sstevel@tonic-gate warn++;
7400Sstevel@tonic-gate } else if (osym->st_size != nsym->st_size) {
7410Sstevel@tonic-gate /*
7420Sstevel@tonic-gate * If both definitions are from relocatable objects we have a
7430Sstevel@tonic-gate * potential fatal error condition. If the tentative is larger
7440Sstevel@tonic-gate * than the real definition treat this as a multiple definition.
7450Sstevel@tonic-gate * Note that if only one symbol is weak, the non-weak will be
7460Sstevel@tonic-gate * taken.
7470Sstevel@tonic-gate */
7480Sstevel@tonic-gate if (((ofile == ET_REL) && (nfile == ET_REL) &&
7490Sstevel@tonic-gate (obind == nbind)) &&
7500Sstevel@tonic-gate ((otent && (osym->st_size > nsym->st_size)) ||
7510Sstevel@tonic-gate (ntent && (osym->st_size < nsym->st_size)))) {
752*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_DIFFATTR),
753*13074SAli.Bahrami@Oracle.COM demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES),
754*13074SAli.Bahrami@Oracle.COM sdp->sd_file->ifl_name, EC_XWORD(osym->st_size),
755*13074SAli.Bahrami@Oracle.COM ifl->ifl_name, EC_XWORD(nsym->st_size));
756*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_TENTERR));
7570Sstevel@tonic-gate } else {
7580Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
759*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_WARNING,
7601618Srie MSG_INTL(MSG_SYM_DIFFATTR),
7610Sstevel@tonic-gate demangle(sdp->sd_name),
7620Sstevel@tonic-gate MSG_INTL(MSG_STR_SIZES),
7630Sstevel@tonic-gate sdp->sd_file->ifl_name,
7640Sstevel@tonic-gate EC_XWORD(osym->st_size),
7650Sstevel@tonic-gate ifl->ifl_name, EC_XWORD(nsym->st_size));
7660Sstevel@tonic-gate warn++;
7670Sstevel@tonic-gate }
7680Sstevel@tonic-gate }
7690Sstevel@tonic-gate }
7700Sstevel@tonic-gate
7710Sstevel@tonic-gate /*
7720Sstevel@tonic-gate * Having provided the user with any necessary warnings, take the
7730Sstevel@tonic-gate * appropriate symbol:
7740Sstevel@tonic-gate *
77510167SRod.Evans@Sun.COM * - if the original symbol is from relocatable file and it is
7760Sstevel@tonic-gate * a protected tentative symbol, take the original one.
7770Sstevel@tonic-gate *
77810167SRod.Evans@Sun.COM * - if the original symbol is from shared object and the new
7790Sstevel@tonic-gate * symbol is a protected tentative symbol from a relocatable file,
7800Sstevel@tonic-gate * take the new one.
7810Sstevel@tonic-gate *
78210167SRod.Evans@Sun.COM * - if the original symbol is tentative, and providing the original
7830Sstevel@tonic-gate * symbol isn't strong and the new symbol weak, take the real
7840Sstevel@tonic-gate * symbol, else
7850Sstevel@tonic-gate *
78610167SRod.Evans@Sun.COM * - if the original symbol is weak and the new tentative symbol is
7870Sstevel@tonic-gate * strong take the new symbol.
7880Sstevel@tonic-gate *
7890Sstevel@tonic-gate * Refer to the System V ABI Page 4-27 for a description of the binding
7900Sstevel@tonic-gate * requirements of tentative and weak symbols.
7910Sstevel@tonic-gate */
7920Sstevel@tonic-gate if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) &&
7935220Srie (ovis == STV_PROTECTED)) {
7940Sstevel@tonic-gate return;
7950Sstevel@tonic-gate }
7960Sstevel@tonic-gate
7970Sstevel@tonic-gate if ((ofile == ET_DYN) && (nfile == ET_REL) && (ntent == TRUE) &&
7985220Srie (nvis == STV_PROTECTED)) {
79910792SRod.Evans@Sun.COM sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
8000Sstevel@tonic-gate return;
8010Sstevel@tonic-gate }
8020Sstevel@tonic-gate
8030Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
8040Sstevel@tonic-gate if (warn)
805*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
806*13074SAli.Bahrami@Oracle.COM sdp->sd_file->ifl_name);
8070Sstevel@tonic-gate return;
8080Sstevel@tonic-gate }
8090Sstevel@tonic-gate
8100Sstevel@tonic-gate if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) ||
8110Sstevel@tonic-gate ((obind == STB_WEAK) && (nbind != STB_WEAK))) {
8120Sstevel@tonic-gate if (warn)
813*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
814*13074SAli.Bahrami@Oracle.COM ifl->ifl_name);
81510792SRod.Evans@Sun.COM sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
8160Sstevel@tonic-gate return;
8170Sstevel@tonic-gate } else {
8180Sstevel@tonic-gate if (warn)
819*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
820*13074SAli.Bahrami@Oracle.COM sdp->sd_file->ifl_name);
82110792SRod.Evans@Sun.COM sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
8220Sstevel@tonic-gate return;
8230Sstevel@tonic-gate }
8240Sstevel@tonic-gate }
8250Sstevel@tonic-gate
8260Sstevel@tonic-gate /*
8270Sstevel@tonic-gate * Resolve two tentative symbols.
8280Sstevel@tonic-gate */
8290Sstevel@tonic-gate static void
sym_twotent(Sym_desc * sdp,Sym * nsym,Ifl_desc * ifl,Ofl_desc * ofl,int ndx,Word nshndx,sd_flag_t nsdflags)8300Sstevel@tonic-gate sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl,
83110792SRod.Evans@Sun.COM int ndx, Word nshndx, sd_flag_t nsdflags)
8320Sstevel@tonic-gate {
8333731Srie Sym *osym = sdp->sd_sym;
8343731Srie uchar_t obind = ELF_ST_BIND(osym->st_info);
8353731Srie uchar_t nbind = ELF_ST_BIND(nsym->st_info);
8363731Srie Half ofile = sdp->sd_file->ifl_ehdr->e_type;
8373731Srie Half nfile = ifl->ifl_ehdr->e_type;
8383731Srie size_t size = 0;
8393731Srie Xword value = 0;
8400Sstevel@tonic-gate
8416206Sab196087 #if defined(_ELF64)
8426206Sab196087 if (ld_targ.t_m.m_mach == EM_AMD64) {
843574Sseizo /*
8446206Sab196087 * If the original and new symbols are both COMMON, but of
8456206Sab196087 * a different size model, take the small one.
846574Sseizo */
8476206Sab196087 if ((sdp->sd_sym->st_shndx == SHN_COMMON) &&
8486206Sab196087 (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
8496206Sab196087 /*
8506206Sab196087 * Take the original symbol.
8516206Sab196087 */
8526206Sab196087 return;
8531682Srie
8546206Sab196087 } else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
8556206Sab196087 (nsym->st_shndx == SHN_COMMON)) {
8566206Sab196087 /*
8576206Sab196087 * Take the new symbol.
8586206Sab196087 */
8596206Sab196087 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx,
86010792SRod.Evans@Sun.COM nsdflags);
8616206Sab196087 return;
8626206Sab196087 }
863574Sseizo }
864574Sseizo #endif
865574Sseizo
8660Sstevel@tonic-gate /*
8670Sstevel@tonic-gate * Check the alignment of the symbols. This can only be tested for if
8680Sstevel@tonic-gate * the symbols are not real definitions to a SHT_NOBITS section (ie.
8690Sstevel@tonic-gate * they were originally tentative), as in this case the symbol would
8700Sstevel@tonic-gate * have a displacement value rather than an alignment. In other words
8710Sstevel@tonic-gate * we can only test this for two relocatable objects.
8720Sstevel@tonic-gate */
8734734Sab196087 /* BEGIN CSTYLED */
8740Sstevel@tonic-gate if ((osym->st_value != nsym->st_value) &&
8750Sstevel@tonic-gate ((sdp->sd_flags & FLG_SY_SPECSEC) &&
8761682Srie (sdp->sd_sym->st_shndx == SHN_COMMON) &&
87710792SRod.Evans@Sun.COM (nsdflags & FLG_SY_SPECSEC) &&
8786206Sab196087 #if defined(_ELF64)
8791682Srie (nsym->st_shndx == SHN_COMMON)) ||
8806206Sab196087 ((ld_targ.t_m.m_mach == EM_AMD64) &&
8816206Sab196087 (sdp->sd_flags & FLG_SY_SPECSEC) &&
8821682Srie (sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) &&
88310792SRod.Evans@Sun.COM (nsdflags & FLG_SY_SPECSEC) &&
8841682Srie (nsym->st_shndx == SHN_X86_64_LCOMMON))) {
885574Sseizo #else
8861682Srie (nsym->st_shndx == SHN_COMMON))) {
887574Sseizo #endif
8884734Sab196087 /* END CSTYLED */
8894734Sab196087
8900Sstevel@tonic-gate const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
8910Sstevel@tonic-gate const char *file;
8920Sstevel@tonic-gate Xword salign;
8930Sstevel@tonic-gate Xword balign;
8940Sstevel@tonic-gate uint_t alignscompliment;
8950Sstevel@tonic-gate
8960Sstevel@tonic-gate if (osym->st_value < nsym->st_value) {
8970Sstevel@tonic-gate salign = osym->st_value;
8980Sstevel@tonic-gate balign = nsym->st_value;
8990Sstevel@tonic-gate } else {
9000Sstevel@tonic-gate salign = nsym->st_value;
9010Sstevel@tonic-gate balign = osym->st_value;
9020Sstevel@tonic-gate }
9030Sstevel@tonic-gate
9040Sstevel@tonic-gate /*
9050Sstevel@tonic-gate * If the smaller alignment fits smoothly into the
9060Sstevel@tonic-gate * larger alignment - we take it with no warning.
9070Sstevel@tonic-gate */
9080Sstevel@tonic-gate if (S_ALIGN(balign, salign) == balign)
9090Sstevel@tonic-gate alignscompliment = 1;
9100Sstevel@tonic-gate else
9110Sstevel@tonic-gate alignscompliment = 0;
9120Sstevel@tonic-gate
9130Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
914*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_WARNING,
9151618Srie MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
9160Sstevel@tonic-gate MSG_INTL(MSG_STR_ALIGNMENTS),
9170Sstevel@tonic-gate sdp->sd_file->ifl_name, EC_XWORD(osym->st_value),
9180Sstevel@tonic-gate ifl->ifl_name, EC_XWORD(nsym->st_value));
9190Sstevel@tonic-gate
9200Sstevel@tonic-gate /*
9210Sstevel@tonic-gate * Having provided the necessary warning indicate which
9220Sstevel@tonic-gate * relocatable object we are going to take.
9230Sstevel@tonic-gate *
92410167SRod.Evans@Sun.COM * - if one symbol is weak and the other is non-weak
9250Sstevel@tonic-gate * take the non-weak symbol, else
9260Sstevel@tonic-gate *
92710167SRod.Evans@Sun.COM * - take the largest alignment (as we still have to check
9280Sstevel@tonic-gate * the symbols size simply save the largest value for
9290Sstevel@tonic-gate * updating later).
9300Sstevel@tonic-gate */
9310Sstevel@tonic-gate if ((obind == STB_WEAK) && (nbind != STB_WEAK))
9320Sstevel@tonic-gate file = ifl->ifl_name;
9330Sstevel@tonic-gate else if (obind != nbind)
9340Sstevel@tonic-gate file = sdp->sd_file->ifl_name;
9350Sstevel@tonic-gate else {
9360Sstevel@tonic-gate emsg = MSG_INTL(MSG_SYM_LARGER);
9370Sstevel@tonic-gate value = balign;
9380Sstevel@tonic-gate }
9390Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
940*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, emsg, file);
9410Sstevel@tonic-gate }
9420Sstevel@tonic-gate
9430Sstevel@tonic-gate /*
9440Sstevel@tonic-gate * Check the size of the symbols.
9450Sstevel@tonic-gate */
9460Sstevel@tonic-gate if (osym->st_size != nsym->st_size) {
9470Sstevel@tonic-gate const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN);
9480Sstevel@tonic-gate const char *file;
9490Sstevel@tonic-gate
9500Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN))
951*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR),
952*13074SAli.Bahrami@Oracle.COM demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES),
953*13074SAli.Bahrami@Oracle.COM sdp->sd_file->ifl_name, EC_XWORD(osym->st_size),
954*13074SAli.Bahrami@Oracle.COM ifl->ifl_name, EC_XWORD(nsym->st_size));
9550Sstevel@tonic-gate
9560Sstevel@tonic-gate
9570Sstevel@tonic-gate /*
9580Sstevel@tonic-gate * This symbol has already been compared to an SO definition,
9590Sstevel@tonic-gate * as per the runtime behavior, ignore extra definitions.
9600Sstevel@tonic-gate */
9610Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
9620Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN))
963*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, emsg,
9640Sstevel@tonic-gate sdp->sd_file->ifl_name);
9650Sstevel@tonic-gate return;
9660Sstevel@tonic-gate }
9670Sstevel@tonic-gate
9680Sstevel@tonic-gate /*
9690Sstevel@tonic-gate * Having provided the necessary warning indicate what course
9700Sstevel@tonic-gate * of action we are going to take.
9710Sstevel@tonic-gate *
97210167SRod.Evans@Sun.COM * - if the file types differ, take the relocatable object
9730Sstevel@tonic-gate * and apply the largest symbol size, else
97410167SRod.Evans@Sun.COM * - if one symbol is weak and the other is non-weak, take
9750Sstevel@tonic-gate * the non-weak symbol, else
97610167SRod.Evans@Sun.COM * - simply take the largest symbol reference.
9770Sstevel@tonic-gate */
9780Sstevel@tonic-gate if (nfile != ofile) {
9790Sstevel@tonic-gate if (nfile == ET_REL) {
9800Sstevel@tonic-gate file = ifl->ifl_name;
9810Sstevel@tonic-gate if (osym->st_size > nsym->st_size) {
9820Sstevel@tonic-gate size = (size_t)osym->st_size;
9830Sstevel@tonic-gate emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
9840Sstevel@tonic-gate }
9850Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx,
98610792SRod.Evans@Sun.COM nshndx, nsdflags);
9870Sstevel@tonic-gate } else {
9880Sstevel@tonic-gate file = sdp->sd_file->ifl_name;
9890Sstevel@tonic-gate if (osym->st_size < nsym->st_size) {
9900Sstevel@tonic-gate size = (size_t)nsym->st_size;
9910Sstevel@tonic-gate emsg = MSG_INTL(MSG_SYM_DEFUPDATE);
9920Sstevel@tonic-gate }
9930Sstevel@tonic-gate sym_promote(sdp, nsym, ifl, ofl, ndx,
99410792SRod.Evans@Sun.COM nshndx, nsdflags);
9950Sstevel@tonic-gate }
9960Sstevel@tonic-gate } else if (obind != nbind) {
9970Sstevel@tonic-gate if ((obind == STB_WEAK) && (nbind != STB_WEAK)) {
9980Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx,
99910792SRod.Evans@Sun.COM nshndx, nsdflags);
10000Sstevel@tonic-gate file = ifl->ifl_name;
10010Sstevel@tonic-gate } else
10020Sstevel@tonic-gate file = sdp->sd_file->ifl_name;
10030Sstevel@tonic-gate } else {
10040Sstevel@tonic-gate if (osym->st_size < nsym->st_size) {
10050Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx,
100610792SRod.Evans@Sun.COM nshndx, nsdflags);
10070Sstevel@tonic-gate file = ifl->ifl_name;
10080Sstevel@tonic-gate } else
10090Sstevel@tonic-gate file = sdp->sd_file->ifl_name;
10100Sstevel@tonic-gate }
10110Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN))
1012*13074SAli.Bahrami@Oracle.COM ld_eprintf(ofl, ERR_NONE, emsg, file);
10130Sstevel@tonic-gate if (size)
10140Sstevel@tonic-gate sdp->sd_sym->st_size = (Xword)size;
10150Sstevel@tonic-gate } else {
10160Sstevel@tonic-gate /*
10170Sstevel@tonic-gate * If the sizes are the same
10180Sstevel@tonic-gate *
101910167SRod.Evans@Sun.COM * - if the file types differ, take the relocatable object,
10200Sstevel@tonic-gate * else
10210Sstevel@tonic-gate *
102210167SRod.Evans@Sun.COM * - if one symbol is weak and the other is non-weak, take
10230Sstevel@tonic-gate * the non-weak symbol, else
10240Sstevel@tonic-gate *
102510167SRod.Evans@Sun.COM * - take the first reference.
10260Sstevel@tonic-gate */
10270Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN))
10280Sstevel@tonic-gate return;
10290Sstevel@tonic-gate else if (((ofile != nfile) && (nfile == ET_REL)) ||
10300Sstevel@tonic-gate (((obind == STB_WEAK) && (nbind != STB_WEAK)) &&
10310Sstevel@tonic-gate (!((ofile != nfile) && (ofile == ET_REL)))))
10320Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx,
103310792SRod.Evans@Sun.COM nshndx, nsdflags);
10340Sstevel@tonic-gate else
10350Sstevel@tonic-gate sym_promote(sdp, nsym, ifl, ofl, ndx,
103610792SRod.Evans@Sun.COM nshndx, nsdflags);
10370Sstevel@tonic-gate }
10380Sstevel@tonic-gate
10390Sstevel@tonic-gate /*
10400Sstevel@tonic-gate * Enforce the largest alignment if necessary.
10410Sstevel@tonic-gate */
10420Sstevel@tonic-gate if (value)
10430Sstevel@tonic-gate sdp->sd_sym->st_value = value;
10440Sstevel@tonic-gate }
10450Sstevel@tonic-gate
10460Sstevel@tonic-gate /*
10470Sstevel@tonic-gate * Symbol resolution state table. `Action' describes the required
10480Sstevel@tonic-gate * procedure to be called (if any).
10490Sstevel@tonic-gate */
10500Sstevel@tonic-gate static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *,
105110792SRod.Evans@Sun.COM Sym *, Ifl_desc *, Ofl_desc *, int, Word, sd_flag_t) = {
10520Sstevel@tonic-gate
10530Sstevel@tonic-gate /* defined undef tent */
10540Sstevel@tonic-gate /* ET_REL ET_REL ET_REL */
10550Sstevel@tonic-gate
10560Sstevel@tonic-gate /* 0 defined REF_DYN_SEEN */ sym_tworeals, sym_promote, sym_realtent,
10570Sstevel@tonic-gate /* 1 undef REF_DYN_SEEN */ sym_override, sym_override, sym_override,
10580Sstevel@tonic-gate /* 2 tent REF_DYN_SEEN */ sym_realtent, sym_promote, sym_twotent,
10590Sstevel@tonic-gate /* 3 defined REF_DYN_NEED */ sym_tworeals, sym_typecheck, sym_realtent,
10600Sstevel@tonic-gate /* 4 undef REF_DYN_NEED */ sym_override, sym_override, sym_override,
10610Sstevel@tonic-gate /* 5 tent REF_DYN_NEED */ sym_realtent, sym_typecheck, sym_twotent,
10620Sstevel@tonic-gate /* 6 defined REF_REL_NEED */ sym_tworeals, sym_typecheck, sym_realtent,
10630Sstevel@tonic-gate /* 7 undef REF_REL_NEED */ sym_override, sym_twoundefs, sym_override,
10640Sstevel@tonic-gate /* 8 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent,
10650Sstevel@tonic-gate
10660Sstevel@tonic-gate /* defined undef tent */
10670Sstevel@tonic-gate /* ET_DYN ET_DYN ET_DYN */
10680Sstevel@tonic-gate
10690Sstevel@tonic-gate /* 9 defined REF_DYN_SEEN */ sym_tworeals, sym_null, sym_realtent,
10700Sstevel@tonic-gate /* 10 undef REF_DYN_SEEN */ sym_override, sym_mach_check, sym_override,
10710Sstevel@tonic-gate /* 11 tent REF_DYN_SEEN */ sym_realtent, sym_null, sym_twotent,
10720Sstevel@tonic-gate /* 12 defined REF_DYN_NEED */ sym_tworeals, sym_null, sym_realtent,
10730Sstevel@tonic-gate /* 13 undef REF_DYN_NEED */ sym_override, sym_null, sym_override,
10740Sstevel@tonic-gate /* 14 tent REF_DYN_NEED */ sym_realtent, sym_null, sym_twotent,
10750Sstevel@tonic-gate /* 15 defined REF_REL_NEED */ sym_tworeals, sym_null, sym_realtent,
10760Sstevel@tonic-gate /* 16 undef REF_REL_NEED */ sym_override, sym_mach_check, sym_override,
10770Sstevel@tonic-gate /* 17 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent
10780Sstevel@tonic-gate
10790Sstevel@tonic-gate };
10800Sstevel@tonic-gate
10810Sstevel@tonic-gate uintptr_t
10821618Srie ld_sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx,
108310792SRod.Evans@Sun.COM Word nshndx, sd_flag_t nsdflags)
10840Sstevel@tonic-gate {
10850Sstevel@tonic-gate int row, column; /* State table coordinates */
10860Sstevel@tonic-gate Sym *osym = sdp->sd_sym;
108711827SRod.Evans@Sun.COM sd_flag_t osdflags = sdp->sd_flags;
10880Sstevel@tonic-gate Is_desc *isp;
10895220Srie Half vis = 0, nfile = ifl->ifl_ehdr->e_type;
10905220Srie Half oref = sdp->sd_ref;
10910Sstevel@tonic-gate
10920Sstevel@tonic-gate /*
10930Sstevel@tonic-gate * Determine the original symbols definition (defines row in Action[]).
10940Sstevel@tonic-gate */
109511827SRod.Evans@Sun.COM if (osdflags & FLG_SY_TENTSYM)
10960Sstevel@tonic-gate row = SYM_TENTATIVE;
10971682Srie else if ((sdp->sd_sym->st_shndx == SHN_UNDEF) ||
10981682Srie (sdp->sd_sym->st_shndx == SHN_SUNW_IGNORE))
10990Sstevel@tonic-gate row = SYM_UNDEFINED;
11000Sstevel@tonic-gate else
11010Sstevel@tonic-gate row = SYM_DEFINED;
11020Sstevel@tonic-gate
11030Sstevel@tonic-gate /*
11040Sstevel@tonic-gate * If the input file is an implicit shared object then we don't need
11050Sstevel@tonic-gate * to bind to any symbols within it other than to verify that any
11060Sstevel@tonic-gate * undefined references will be closed (implicit shared objects are only
11070Sstevel@tonic-gate * processed when no undefined symbols are required as a result of the
11080Sstevel@tonic-gate * link-edit (see process_dynamic())).
11090Sstevel@tonic-gate */
11100Sstevel@tonic-gate if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) &&
11110Sstevel@tonic-gate (row != SYM_UNDEFINED))
11120Sstevel@tonic-gate return (1);
11130Sstevel@tonic-gate
11140Sstevel@tonic-gate /*
11150Sstevel@tonic-gate * Finish computing the Action[] row by applying the symbols reference
11160Sstevel@tonic-gate * together with the input files type.
11170Sstevel@tonic-gate */
11180Sstevel@tonic-gate row = row + (REF_NUM * sdp->sd_ref);
11190Sstevel@tonic-gate if (nfile == ET_DYN)
11200Sstevel@tonic-gate row += (REF_NUM * SYM_NUM);
11210Sstevel@tonic-gate
11220Sstevel@tonic-gate /*
11235220Srie * If either the original or new symbol originates from a relocatable
11245220Srie * object, determine the appropriate visibility for the resolved symbol.
11255220Srie */
11265220Srie if ((oref == REF_REL_NEED) || (nfile == ET_REL))
11275220Srie vis = sym_visibility(sdp, nsym, ifl, ofl);
11285220Srie
11295220Srie /*
11300Sstevel@tonic-gate * Determine the new symbols definition (defines column in Action[]).
11310Sstevel@tonic-gate */
113210792SRod.Evans@Sun.COM if ((nsdflags & FLG_SY_SPECSEC) &&
11331682Srie (nsym->st_shndx == SHN_COMMON)) {
11340Sstevel@tonic-gate column = SYM_TENTATIVE;
113510792SRod.Evans@Sun.COM nsdflags |= FLG_SY_TENTSYM;
11366206Sab196087 #if defined(_ELF64)
11376206Sab196087 } else if ((ld_targ.t_m.m_mach == EM_AMD64) &&
113810792SRod.Evans@Sun.COM (nsdflags & FLG_SY_SPECSEC) &&
11391682Srie (nsym->st_shndx == SHN_X86_64_LCOMMON)) {
1140574Sseizo column = SYM_TENTATIVE;
114110792SRod.Evans@Sun.COM nsdflags |= FLG_SY_TENTSYM;
1142574Sseizo #endif
11431682Srie } else if ((nsym->st_shndx == SHN_UNDEF) ||
11441682Srie (nsym->st_shndx == SHN_SUNW_IGNORE)) {
11450Sstevel@tonic-gate column = SYM_UNDEFINED;
11460Sstevel@tonic-gate nshndx = SHN_UNDEF;
11470Sstevel@tonic-gate } else {
11480Sstevel@tonic-gate column = SYM_DEFINED;
11490Sstevel@tonic-gate /*
11500Sstevel@tonic-gate * If the new symbol is from a shared library and it is
11510Sstevel@tonic-gate * associated with a SHT_NOBITS section then this symbol
11520Sstevel@tonic-gate * originated from a tentative symbol.
11530Sstevel@tonic-gate */
115410792SRod.Evans@Sun.COM if (((nsdflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) {
11550Sstevel@tonic-gate isp = ifl->ifl_isdesc[nshndx];
11560Sstevel@tonic-gate if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) {
11570Sstevel@tonic-gate column = SYM_TENTATIVE;
115810792SRod.Evans@Sun.COM nsdflags |= FLG_SY_TENTSYM;
11590Sstevel@tonic-gate }
11600Sstevel@tonic-gate }
11610Sstevel@tonic-gate }
11620Sstevel@tonic-gate
11631618Srie DBG_CALL(Dbg_syms_resolving(ofl, ndx, sdp->sd_name, row, column,
11641618Srie osym, nsym, sdp, ifl));
11650Sstevel@tonic-gate
11660Sstevel@tonic-gate /*
11670Sstevel@tonic-gate * Record the input filename on the defined files list for possible
11680Sstevel@tonic-gate * later diagnostics. The `sa_dfiles' list is used to maintain the list
11690Sstevel@tonic-gate * of shared objects that define the same symbol. This list is only
11700Sstevel@tonic-gate * generated when the -m option is in effect and is used to list
11710Sstevel@tonic-gate * multiple (interposed) definitions of a symbol (refer to ldmap_out()).
11720Sstevel@tonic-gate */
11731682Srie if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nsym->st_shndx != SHN_UNDEF) &&
117410792SRod.Evans@Sun.COM ((nsdflags & FLG_SY_SPECSEC) == 0))
11759131SRod.Evans@Sun.COM if (aplist_append(&sdp->sd_aux->sa_dfiles, ifl->ifl_name,
11769131SRod.Evans@Sun.COM AL_CNT_SDP_DFILES) == NULL)
11770Sstevel@tonic-gate return (S_ERROR);
11780Sstevel@tonic-gate
11790Sstevel@tonic-gate /*
11800Sstevel@tonic-gate * Perform the required resolution.
11810Sstevel@tonic-gate */
118210792SRod.Evans@Sun.COM Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
11830Sstevel@tonic-gate
11840Sstevel@tonic-gate /*
11855220Srie * Apply any visibility requirements. If a SINGLETON has been
11865220Srie * established, make sure no symbol reduction indicators remain
11875220Srie * associated with the symbol, and indicate that the symbol can not
11885220Srie * be directly bound to.
11895220Srie */
11905220Srie if ((oref == REF_REL_NEED) || (nfile == ET_REL)) {
11915220Srie if ((vis == STV_EXPORTED) || (vis == STV_SINGLETON)) {
119210792SRod.Evans@Sun.COM sdp->sd_flags &= ~MSK_SY_LOCAL;
11935220Srie
11945220Srie if (vis == STV_EXPORTED)
119510792SRod.Evans@Sun.COM sdp->sd_flags |= FLG_SY_EXPORT;
11965220Srie else {
119710792SRod.Evans@Sun.COM sdp->sd_flags |= (FLG_SY_NDIR | FLG_SY_SINGLE);
11985220Srie
119910167SRod.Evans@Sun.COM if (sdp->sd_ref == REF_REL_NEED) {
120010167SRod.Evans@Sun.COM ofl->ofl_flags1 |=
120110167SRod.Evans@Sun.COM (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
120210167SRod.Evans@Sun.COM }
12035220Srie }
12045220Srie } else if (vis == STV_PROTECTED) {
120510792SRod.Evans@Sun.COM sdp->sd_flags |= FLG_SY_PROTECT;
12065220Srie } else if ((vis == STV_INTERNAL) || (vis == STV_HIDDEN)) {
120710792SRod.Evans@Sun.COM sdp->sd_flags |= FLG_SY_HIDDEN;
12085220Srie } else if (vis == STV_ELIMINATE) {
120910792SRod.Evans@Sun.COM sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
12105220Srie }
12115220Srie
12125220Srie sdp->sd_sym->st_other =
12135220Srie (sdp->sd_sym->st_other & ~MSK_SYM_VISIBILITY) | vis;
12145220Srie }
12155220Srie
12165220Srie /*
12170Sstevel@tonic-gate * If the symbol has been resolved to the new input file, and this is
12180Sstevel@tonic-gate * a versioned relocatable object, then the version information of the
12190Sstevel@tonic-gate * new symbol must be promoted to the versioning of the output file.
12200Sstevel@tonic-gate */
12210Sstevel@tonic-gate if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) &&
12221682Srie (nsym->st_shndx != SHN_UNDEF))
12231618Srie ld_vers_promote(sdp, ndx, ifl, ofl);
12240Sstevel@tonic-gate
12250Sstevel@tonic-gate /*
12260Sstevel@tonic-gate * Determine whether a mapfile reference has been satisfied. Mapfile
12270Sstevel@tonic-gate * symbol references augment symbols that should be contributed from
12280Sstevel@tonic-gate * the relocatable objects used to build the output image. If a
12290Sstevel@tonic-gate * relocatable object doesn't provide one of the mapfile symbol
12300Sstevel@tonic-gate * references then somethings amiss, and will be flagged during symbol
12310Sstevel@tonic-gate * validation.
12320Sstevel@tonic-gate */
12330Sstevel@tonic-gate if ((nfile == ET_REL) && ((sdp->sd_flags &
12340Sstevel@tonic-gate (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) {
12350Sstevel@tonic-gate /*
12360Sstevel@tonic-gate * Extern and parent references are satisfied by references from
12370Sstevel@tonic-gate * a relocatable object. Note that we let *any* symbol type
12380Sstevel@tonic-gate * satisfy this reference, to be as flexible as possible with
12390Sstevel@tonic-gate * user written mapfiles. It could be questionable, for
12400Sstevel@tonic-gate * example, if what a user expects to be an extern reference is
12410Sstevel@tonic-gate * actually found to be a definition in a relocatable object.
12420Sstevel@tonic-gate *
12430Sstevel@tonic-gate * Any other mapfile reference (typically for versioning
12440Sstevel@tonic-gate * information) simply augments a relocatables definition.
12450Sstevel@tonic-gate */
12460Sstevel@tonic-gate if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) ||
12471682Srie ((sdp->sd_sym->st_shndx != SHN_UNDEF) &&
12480Sstevel@tonic-gate (sdp->sd_ref == REF_REL_NEED)))
12490Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_MAPUSED;
12500Sstevel@tonic-gate }
12510Sstevel@tonic-gate
125211827SRod.Evans@Sun.COM /*
125311827SRod.Evans@Sun.COM * Make sure any special symbol requirements are carried over.
125411827SRod.Evans@Sun.COM */
125511827SRod.Evans@Sun.COM if ((osdflags & FLG_SY_CAP) || (nsdflags & FLG_SY_CAP))
125611827SRod.Evans@Sun.COM sdp->sd_flags |= FLG_SY_CAP;
125711827SRod.Evans@Sun.COM
12581618Srie DBG_CALL(Dbg_syms_resolved(ofl, sdp));
12590Sstevel@tonic-gate
12600Sstevel@tonic-gate return (1);
12610Sstevel@tonic-gate }
1262