17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 55aefb655Srie * Common Development and Distribution License (the "License"). 65aefb655Srie * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 215aefb655Srie 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright (c) 1988 AT&T 247c478bd9Sstevel@tonic-gate * All Rights Reserved 257c478bd9Sstevel@tonic-gate * 26*1007fd6fSAli Bahrami * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. 277c478bd9Sstevel@tonic-gate */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * Symbol table resolution 317c478bd9Sstevel@tonic-gate */ 32ba2be530Sab196087 #define ELF_TARGET_AMD64 33ba2be530Sab196087 347c478bd9Sstevel@tonic-gate #include <stdio.h> 355aefb655Srie #include <debug.h> 367c478bd9Sstevel@tonic-gate #include "msg.h" 377c478bd9Sstevel@tonic-gate #include "_libld.h" 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate /* 417c478bd9Sstevel@tonic-gate * Categorize the symbol types that are applicable to the resolution process. 427c478bd9Sstevel@tonic-gate */ 437c478bd9Sstevel@tonic-gate typedef enum { 447c478bd9Sstevel@tonic-gate SYM_DEFINED, /* Defined symbol (SHN_ABS or shndx != 0) */ 457c478bd9Sstevel@tonic-gate SYM_UNDEFINED, /* Undefined symbol (SHN_UNDEF) */ 467c478bd9Sstevel@tonic-gate SYM_TENTATIVE, /* Tentative symbol (SHN_COMMON) */ 477c478bd9Sstevel@tonic-gate SYM_NUM /* the number of symbol types */ 487c478bd9Sstevel@tonic-gate } Symtype; 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* 517c478bd9Sstevel@tonic-gate * Do nothing. 527c478bd9Sstevel@tonic-gate */ 537c478bd9Sstevel@tonic-gate /* ARGSUSED0 */ 547c478bd9Sstevel@tonic-gate static void 557c478bd9Sstevel@tonic-gate sym_null(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 56635216b6SRod Evans int ndx, Word nshndx, sd_flag_t nsdflags) 577c478bd9Sstevel@tonic-gate { 587c478bd9Sstevel@tonic-gate } 597c478bd9Sstevel@tonic-gate 6060758829Srie static void 6160758829Srie sym_visibility_diag(Error err, Sym_desc *sdp, Sym *osym, Sym *nsym, 6260758829Srie Ifl_desc *ifl, Ofl_desc *ofl) 6360758829Srie { 6460758829Srie Conv_inv_buf_t inv_obuf, inv_nbuf; 6560758829Srie 66d444b03eSAli Bahrami /* Warnings are only issued when -z verbose is specified */ 67d444b03eSAli Bahrami if (!(ofl->ofl_flags & FLG_OF_VERBOSE) && (err != ERR_FATAL)) 68d444b03eSAli Bahrami return; 69d444b03eSAli Bahrami 70*1007fd6fSAli Bahrami ld_eprintf(ofl, err, MSG_INTL(MSG_SYM_CONFVIS), demangle(sdp->sd_name)); 71*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_VISTYPES), 7260758829Srie sdp->sd_file->ifl_name, conv_sym_other(osym->st_other, &inv_obuf), 7360758829Srie ifl->ifl_name, conv_sym_other(nsym->st_other, &inv_nbuf)); 7460758829Srie 75*1007fd6fSAli Bahrami if (err != ERR_FATAL) 76*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 7760758829Srie ifl->ifl_name); 7860758829Srie } 7960758829Srie 8060758829Srie /* 8160758829Srie * STV_VISIBILITY rules for STV_DEFAULT/INTERNAL/HIDDEN/PROTECTED say that the 8260758829Srie * most restrictive visibility value should be taken. The precedence is: 8360758829Srie * 8460758829Srie * (most restrictive) INTERNAL -> HIDDEN -> PROTECTED -> DEFAULT (least) 8560758829Srie * 8660758829Srie * The STV_EXPORT and STV_SINGLETON visibilities are slightly different, in that 8760758829Srie * the visibility must remain global and can not be reduced in any way. 8860758829Srie * 8960758829Srie * Resolution of different visibilities between two relocatable objects can 9060758829Srie * take the following actions: 9160758829Srie * 9260758829Srie * i. if applicable, the most restrictive action is silently taken. 9360758829Srie * ii. if a mapfile visibility definition competes with a more restrictive 9460758829Srie * relocatable object definition, then a warning is generated, but the 9560758829Srie * the more restrictive visibility is taken. 9660758829Srie * iii. in the case of conflicts with an EXPORTED or SINGLETON symbol with 9760758829Srie * any type of visibility between relocatable objects, the combination 9860758829Srie * is deemed fatal. 9960758829Srie * 10060758829Srie * new visibility 10160758829Srie * D I H P X S 10260758829Srie * ------------------------------------------------------------ 10360758829Srie * D | D I(mw) H(mw) P X S 10460758829Srie * original I | I I I I X(mw/of) S(mw/of) 10560758829Srie * visibility H | H I(mw) H H X(mw/of) S(mw/of) 10660758829Srie * P | P I(mw) H(mw) P X(mw/of) S(mw/of) 10760758829Srie * X | X I(mw/of) H(mw/of) P(mw/of) X S 10860758829Srie * S | S I(mw/of) H(mw/of) P(mw/of) S S 10960758829Srie * where: 11060758829Srie * 11160758829Srie * mw - mapfile warning: if the original symbol originates from a mapfile 11260758829Srie * then warn the user that their scope definition is being overridden. 11360758829Srie * of - object definitions are fatal: any combination of relocatable object 11460758829Srie * visibilities that conflict with a SINGLETON and EXPORTED are fatal. 11560758829Srie * 11660758829Srie * Note, an eliminate symbol (STV_ELIMINATE) is treated as hidden (STV_HIDDEN) 11760758829Srie * for processing through this state table. 11860758829Srie */ 11960758829Srie static Half 12060758829Srie sym_visibility(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl) 12160758829Srie { 12260758829Srie Sym *osym = sdp->sd_sym; 12360758829Srie uchar_t wovis, ovis; 12460758829Srie uchar_t wnvis, nvis; 12560758829Srie 12660758829Srie wovis = ovis = ELF_ST_VISIBILITY(osym->st_other); 12760758829Srie wnvis = nvis = ELF_ST_VISIBILITY(nsym->st_other); 12860758829Srie 12960758829Srie /* 13060758829Srie * If the original visibilities are eliminate, assign them hidden for 13160758829Srie * the state table processing. The original visibility, rather than 13260758829Srie * the working visibility, will be returned to the caller. 13360758829Srie */ 13460758829Srie if (wovis == STV_ELIMINATE) 13560758829Srie wovis = STV_HIDDEN; 13660758829Srie if (wnvis == STV_ELIMINATE) 13760758829Srie wnvis = STV_HIDDEN; 13860758829Srie 13960758829Srie /* 14060758829Srie * The most complex visibility resolution is between two relocatable 14160758829Srie * objects. However, in the case of SINGLETONS we also want to catch 14260758829Srie * any singleton definitions within shared objects. Relocatable objects 14360758829Srie * that bind to these symbols inherit the singleton visibility as this 14460758829Srie * efficiently triggers ld.so.1 into carrying out the appropriate 14560758829Srie * runtime symbol search. Any other resolution between a relocatable 14660758829Srie * object and a shared object will retain the relocatable objects 14760758829Srie * visibility. 14860758829Srie */ 14960758829Srie if ((sdp->sd_ref == REF_REL_NEED) && 15060758829Srie (ifl->ifl_ehdr->e_type == ET_DYN)) { 15160758829Srie if ((sdp->sd_sym->st_shndx == SHN_UNDEF) && 15260758829Srie (nsym->st_shndx != SHN_UNDEF) && (wnvis == STV_SINGLETON)) 15360758829Srie return (STV_SINGLETON); 15460758829Srie else 15560758829Srie return (ovis); 15660758829Srie } 15760758829Srie if ((sdp->sd_ref != REF_REL_NEED) && 15860758829Srie (ifl->ifl_ehdr->e_type == ET_REL)) { 15960758829Srie if ((sdp->sd_sym->st_shndx != SHN_UNDEF) && 16060758829Srie (nsym->st_shndx == SHN_UNDEF) && (wovis == STV_SINGLETON)) 16160758829Srie return (STV_SINGLETON); 16260758829Srie else 16360758829Srie return (nvis); 16460758829Srie } 16560758829Srie 16660758829Srie /* 16760758829Srie * If the visibilities are the same, we're done. If the working 16860758829Srie * visibilities differ from the original, then one must have been 16960758829Srie * STV_HIDDEN and the other STV_ELIMINATE. 17060758829Srie */ 17160758829Srie if (wovis == wnvis) { 17260758829Srie if (ovis == nvis) 17360758829Srie return (nvis); 17460758829Srie else 17560758829Srie return (STV_ELIMINATE); 17660758829Srie } 17760758829Srie 17860758829Srie /* 17960758829Srie * An EXPORTED symbol or SINGLETON symbol can not be demoted, any 18060758829Srie * conflicting visibility from another object is fatal. A conflicting 18160758829Srie * visibility from a mapfile produces a warning, as the mapfile 18260758829Srie * definition can be overridden. 18360758829Srie */ 18460758829Srie if ((wnvis == STV_EXPORTED) || (wnvis == STV_SINGLETON)) { 18560758829Srie if ((wovis != STV_DEFAULT) && (wovis != STV_EXPORTED) && 18660758829Srie (wovis != STV_SINGLETON)) { 187635216b6SRod Evans if (sdp->sd_flags & FLG_SY_MAPFILE) { 18860758829Srie sym_visibility_diag(ERR_WARNING, sdp, osym, 18960758829Srie nsym, ifl, ofl); 19060758829Srie } else { 19160758829Srie sym_visibility_diag(ERR_FATAL, sdp, osym, 19260758829Srie nsym, ifl, ofl); 19360758829Srie } 19460758829Srie } 19560758829Srie return (nvis); 19660758829Srie } 19760758829Srie if (wovis == STV_SINGLETON) { 19860758829Srie if ((wnvis == STV_EXPORTED) || (wnvis == STV_DEFAULT)) 19960758829Srie return (STV_SINGLETON); 200635216b6SRod Evans if (sdp->sd_flags & FLG_SY_MAPFILE) { 20160758829Srie sym_visibility_diag(ERR_WARNING, sdp, osym, 20260758829Srie nsym, ifl, ofl); 20360758829Srie } else { 20460758829Srie sym_visibility_diag(ERR_FATAL, sdp, osym, 20560758829Srie nsym, ifl, ofl); 20660758829Srie } 20760758829Srie return (nvis); 20860758829Srie } 20960758829Srie if (wovis == STV_EXPORTED) { 21060758829Srie if (wnvis == STV_SINGLETON) 21160758829Srie return (STV_SINGLETON); 21260758829Srie if (wnvis == STV_DEFAULT) 21360758829Srie return (STV_EXPORTED); 214635216b6SRod Evans if (sdp->sd_flags & FLG_SY_MAPFILE) { 21560758829Srie sym_visibility_diag(ERR_WARNING, sdp, osym, 21660758829Srie nsym, ifl, ofl); 21760758829Srie } else { 21860758829Srie sym_visibility_diag(ERR_FATAL, sdp, osym, 21960758829Srie nsym, ifl, ofl); 22060758829Srie } 22160758829Srie return (nvis); 22260758829Srie } 22360758829Srie 22460758829Srie /* 22560758829Srie * Now that symbols with the same visibility, and all instances of 22660758829Srie * SINGLETON's have been dealt with, we're left with visibilities that 22760758829Srie * differ, but can be dealt with in the order of how restrictive the 22860758829Srie * visibilities are. When a differing visibility originates from a 22960758829Srie * mapfile definition, produces a warning, as the mapfile definition 23060758829Srie * can be overridden by the relocatable object. 23160758829Srie */ 23260758829Srie if ((wnvis == STV_INTERNAL) || (wovis == STV_INTERNAL)) { 23360758829Srie if ((wnvis == STV_INTERNAL) && 234635216b6SRod Evans (sdp->sd_flags & FLG_SY_MAPFILE)) { 23560758829Srie sym_visibility_diag(ERR_WARNING, sdp, osym, nsym, 23660758829Srie ifl, ofl); 23760758829Srie } 23860758829Srie return (STV_INTERNAL); 23960758829Srie 24060758829Srie } else if ((wnvis == STV_HIDDEN) || (wovis == STV_HIDDEN)) { 24160758829Srie if ((wnvis == STV_HIDDEN) && 242635216b6SRod Evans (sdp->sd_flags & FLG_SY_MAPFILE)) { 24360758829Srie sym_visibility_diag(ERR_WARNING, sdp, osym, nsym, 24460758829Srie ifl, ofl); 24560758829Srie } 24660758829Srie 24760758829Srie /* 24860758829Srie * In the case of STV_ELIMINATE and STV_HIDDEN, the working 24960758829Srie * visibility can differ from the original visibility, so make 25060758829Srie * sure to return the original visibility. 25160758829Srie */ 25260758829Srie if ((ovis == STV_ELIMINATE) || (nvis == STV_ELIMINATE)) 25360758829Srie return (STV_ELIMINATE); 25460758829Srie else 25560758829Srie return (STV_HIDDEN); 25660758829Srie 25760758829Srie } else if ((wnvis == STV_PROTECTED) || (wovis == STV_PROTECTED)) 25860758829Srie return (STV_PROTECTED); 25960758829Srie 26060758829Srie return (STV_DEFAULT); 26160758829Srie } 26260758829Srie 2637c478bd9Sstevel@tonic-gate /* 2647c478bd9Sstevel@tonic-gate * Check if two symbols types are compatible 2657c478bd9Sstevel@tonic-gate */ 2667c478bd9Sstevel@tonic-gate /*ARGSUSED4*/ 2677c478bd9Sstevel@tonic-gate static void 2687c478bd9Sstevel@tonic-gate sym_typecheck(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 269635216b6SRod Evans int ndx, Word nshndx, sd_flag_t nsdflags) 2707c478bd9Sstevel@tonic-gate { 27102ca3e02Srie uchar_t otype = ELF_ST_TYPE(sdp->sd_sym->st_info); 27202ca3e02Srie uchar_t ntype = ELF_ST_TYPE(nsym->st_info); 273de777a60Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2; 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate /* 2767c478bd9Sstevel@tonic-gate * Perform any machine specific type checking. 2777c478bd9Sstevel@tonic-gate */ 278ba2be530Sab196087 if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) && 279ba2be530Sab196087 (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl)) 2807c478bd9Sstevel@tonic-gate return; 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate /* 28360758829Srie * NOTYPE's can be combined with other types, only give an error if 28460758829Srie * combining two differing types without NOTYPE. 2857c478bd9Sstevel@tonic-gate */ 2867c478bd9Sstevel@tonic-gate if ((otype == ntype) || (otype == STT_NOTYPE) || (ntype == STT_NOTYPE)) 2877c478bd9Sstevel@tonic-gate return; 2887c478bd9Sstevel@tonic-gate 289*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 2907c478bd9Sstevel@tonic-gate demangle(sdp->sd_name)); 291*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 2925aefb655Srie sdp->sd_file->ifl_name, 293de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 0, &inv_buf1), 294c13de8f6Sab196087 ifl->ifl_name, 295de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 0, &inv_buf2)); 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate /*ARGSUSED4*/ 2997c478bd9Sstevel@tonic-gate static void 3007c478bd9Sstevel@tonic-gate sym_mach_check(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 301635216b6SRod Evans int ndx, Word nshndx, sd_flag_t nsdflags) 3027c478bd9Sstevel@tonic-gate { 3037c478bd9Sstevel@tonic-gate /* 3047c478bd9Sstevel@tonic-gate * Perform any machine specific type checking. 3057c478bd9Sstevel@tonic-gate */ 306ba2be530Sab196087 if (ld_targ.t_ms.ms_mach_sym_typecheck != NULL) 307ba2be530Sab196087 (void) (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, 308ba2be530Sab196087 ifl, ofl); 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate /* 3127c478bd9Sstevel@tonic-gate * Promote the symbols reference. 3137c478bd9Sstevel@tonic-gate */ 3147c478bd9Sstevel@tonic-gate static void 3157c478bd9Sstevel@tonic-gate /* ARGSUSED4 */ 3167c478bd9Sstevel@tonic-gate sym_promote(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 317635216b6SRod Evans int ndx, Word nshndx, sd_flag_t nsdflags) 3187c478bd9Sstevel@tonic-gate { 3190bc07c75Srie Word shndx = nsym->st_shndx; 3200bc07c75Srie 321635216b6SRod Evans sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate /* 3247c478bd9Sstevel@tonic-gate * If the old symbol is from a shared object and the new symbol is a 3257c478bd9Sstevel@tonic-gate * reference from a relocatable object, promote the old symbols 3267c478bd9Sstevel@tonic-gate * reference. 3277c478bd9Sstevel@tonic-gate */ 3287c478bd9Sstevel@tonic-gate if ((sdp->sd_ref == REF_DYN_SEEN) && 3297c478bd9Sstevel@tonic-gate (ifl->ifl_ehdr->e_type == ET_REL)) { 3307c478bd9Sstevel@tonic-gate sdp->sd_ref = REF_DYN_NEED; 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate /* 3337c478bd9Sstevel@tonic-gate * If this is an undefined symbol it must be a relocatable 3347c478bd9Sstevel@tonic-gate * object overriding a shared object. In this case also 3357c478bd9Sstevel@tonic-gate * override the reference name so that any undefined symbol 3367c478bd9Sstevel@tonic-gate * diagnostics will refer to the relocatable object name. 3377c478bd9Sstevel@tonic-gate */ 3380bc07c75Srie if (shndx == SHN_UNDEF) 3397c478bd9Sstevel@tonic-gate sdp->sd_aux->sa_rfile = ifl->ifl_name; 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate /* 3427c478bd9Sstevel@tonic-gate * If this symbol is an undefined, or common, determine whether 3437c478bd9Sstevel@tonic-gate * it is a global or weak reference (see build_osym(), where 3447c478bd9Sstevel@tonic-gate * REF_DYN_NEED definitions are returned back to undefines). 3457c478bd9Sstevel@tonic-gate */ 346635216b6SRod Evans if (((shndx == SHN_UNDEF) || ((nsdflags & FLG_SY_SPECSEC) && 3470bc07c75Srie (shndx == SHN_COMMON))) && 3487c478bd9Sstevel@tonic-gate (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL)) 3497c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_GLOBREF; 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate /* 3557c478bd9Sstevel@tonic-gate * Override a symbol. 3567c478bd9Sstevel@tonic-gate */ 3577c478bd9Sstevel@tonic-gate static void 3587c478bd9Sstevel@tonic-gate sym_override(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 359635216b6SRod Evans int ndx, Word nshndx, sd_flag_t nsdflags) 3607c478bd9Sstevel@tonic-gate { 3617c478bd9Sstevel@tonic-gate Sym *osym = sdp->sd_sym; 3627c478bd9Sstevel@tonic-gate Word link; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate /* 3657c478bd9Sstevel@tonic-gate * In the case of a WEAK UNDEF symbol don't let a symbol from an 3667c478bd9Sstevel@tonic-gate * unavailable object override the symbol definition. This is because 3677c478bd9Sstevel@tonic-gate * this symbol *may* not be present in a future object and by promoting 3687c478bd9Sstevel@tonic-gate * this symbol we are actually causing bindings (PLTS) to be formed 3697c478bd9Sstevel@tonic-gate * to this symbol. Instead let the 'generic' weak binding take place. 3707c478bd9Sstevel@tonic-gate */ 3717c478bd9Sstevel@tonic-gate if ((ELF_ST_BIND(osym->st_info) == STB_WEAK) && 3720bc07c75Srie (sdp->sd_sym->st_shndx == SHN_UNDEF) && 3730bc07c75Srie ((ifl->ifl_flags & FLG_IF_NEEDED) == 0)) 3747c478bd9Sstevel@tonic-gate return; 3757c478bd9Sstevel@tonic-gate 376635216b6SRod Evans sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate /* 3797c478bd9Sstevel@tonic-gate * This symbol has already been compared to an SO definition, 3807c478bd9Sstevel@tonic-gate * as per the runtime behavior, ignore extra definitions. 3817c478bd9Sstevel@tonic-gate */ 3827c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) && 3837c478bd9Sstevel@tonic-gate (ifl->ifl_ehdr->e_type == ET_DYN)) 3847c478bd9Sstevel@tonic-gate return; 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate /* 3877c478bd9Sstevel@tonic-gate * Mark the symbol as available and copy the new symbols contents. 3887c478bd9Sstevel@tonic-gate */ 3897c478bd9Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_NOTAVAIL; 3907c478bd9Sstevel@tonic-gate *osym = *nsym; 3917c478bd9Sstevel@tonic-gate sdp->sd_shndx = nshndx; 3927c478bd9Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_SPECSEC; 393635216b6SRod Evans sdp->sd_flags |= (nsdflags & (FLG_SY_SPECSEC | FLG_SY_TENTSYM)); 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate /* 3967c478bd9Sstevel@tonic-gate * If the new symbol has PROTECTED visibility, mark it. If a PROTECTED 3977c478bd9Sstevel@tonic-gate * symbol is copy relocated, a warning message will be printed. See 3987c478bd9Sstevel@tonic-gate * reloc_exec(). 3997c478bd9Sstevel@tonic-gate */ 4007c478bd9Sstevel@tonic-gate if (ELF_ST_VISIBILITY(nsym->st_other) == STV_PROTECTED) 4017c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_PROT; 4027c478bd9Sstevel@tonic-gate else 4037c478bd9Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_PROT; 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate /* 4067c478bd9Sstevel@tonic-gate * Establish the symbols reference. If the new symbol originates from a 4077c478bd9Sstevel@tonic-gate * relocatable object then this reference becomes needed, otherwise 4087c478bd9Sstevel@tonic-gate * the new symbol must be from a shared object. In this case only 4097c478bd9Sstevel@tonic-gate * promote the symbol to needed if we presently have a reference from a 4107c478bd9Sstevel@tonic-gate * relocatable object. 4117c478bd9Sstevel@tonic-gate */ 4127c478bd9Sstevel@tonic-gate if (ifl->ifl_ehdr->e_type == ET_REL) { 4137c478bd9Sstevel@tonic-gate sdp->sd_ref = REF_REL_NEED; 4147c478bd9Sstevel@tonic-gate 4150bc07c75Srie if (nsym->st_shndx == SHN_UNDEF) { 4167c478bd9Sstevel@tonic-gate /* 41708278a5eSRod Evans * If this is an undefined symbol, then we can only be 41808278a5eSRod Evans * attempting to override an existing undefined symbol. 41908278a5eSRod Evans * The original symbol is either: 42008278a5eSRod Evans * 42108278a5eSRod Evans * - a mapfile definition 42208278a5eSRod Evans * - a previous relocatable object whose visibility 42308278a5eSRod Evans * or type should be overridden by this new symbol 42408278a5eSRod Evans * - a previous shared object 42508278a5eSRod Evans * 42608278a5eSRod Evans * If the original undefined symbol stems from a mapfile 42708278a5eSRod Evans * then don't alter the reference file name. Should we 42808278a5eSRod Evans * end up with some form of 'undefined' symbol error, 42908278a5eSRod Evans * the characteristics of that error are most likely to 43008278a5eSRod Evans * have originated from a mapfile. 43108278a5eSRod Evans * 43208278a5eSRod Evans * Otherwise, update the reference file name to indicate 43308278a5eSRod Evans * this symbol. 4347c478bd9Sstevel@tonic-gate */ 43508278a5eSRod Evans if ((sdp->sd_flags & FLG_SY_MAPREF) == 0) 4367c478bd9Sstevel@tonic-gate sdp->sd_aux->sa_rfile = ifl->ifl_name; 4377c478bd9Sstevel@tonic-gate } else { 4387c478bd9Sstevel@tonic-gate /* 4399a411307Srie * Under -Bnodirect, all exported interfaces that have 4409a411307Srie * not explicitly been defined protected or directly 4419a411307Srie * bound to, are tagged to prevent direct binding. 4427c478bd9Sstevel@tonic-gate */ 4437c478bd9Sstevel@tonic-gate if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) && 444635216b6SRod Evans ((sdp->sd_flags & 445635216b6SRod Evans (FLG_SY_PROTECT | FLG_SY_DIR)) == 0)) 446635216b6SRod Evans sdp->sd_flags |= FLG_SY_NDIR; 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate /* 4507c478bd9Sstevel@tonic-gate * If this symbol is an undefined, or common, determine whether 4517c478bd9Sstevel@tonic-gate * it is a global or weak reference (see build_osym(), where 4527c478bd9Sstevel@tonic-gate * REF_DYN_NEED definitions are returned back to undefines). 4537c478bd9Sstevel@tonic-gate */ 4540bc07c75Srie if (((nsym->st_shndx == SHN_UNDEF) || 455635216b6SRod Evans ((nsdflags & FLG_SY_SPECSEC) && 4560bc07c75Srie (nsym->st_shndx == SHN_COMMON))) && 4577c478bd9Sstevel@tonic-gate (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL)) 4587c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_GLOBREF; 4597c478bd9Sstevel@tonic-gate else 4607c478bd9Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_GLOBREF; 4617c478bd9Sstevel@tonic-gate } else { 4627c478bd9Sstevel@tonic-gate if (sdp->sd_ref == REF_REL_NEED) 4637c478bd9Sstevel@tonic-gate sdp->sd_ref = REF_DYN_NEED; 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate /* 4667c478bd9Sstevel@tonic-gate * Determine the symbols availability. A symbol is determined 4677c478bd9Sstevel@tonic-gate * to be unavailable if it belongs to a version of a shared 4687c478bd9Sstevel@tonic-gate * object that this user does not wish to use, or if it belongs 4697c478bd9Sstevel@tonic-gate * to an implicit shared object. 4707c478bd9Sstevel@tonic-gate */ 4717c478bd9Sstevel@tonic-gate if (ifl->ifl_vercnt) { 4727c478bd9Sstevel@tonic-gate Ver_index *vip; 4737c478bd9Sstevel@tonic-gate Half vndx = ifl->ifl_versym[ndx]; 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate sdp->sd_aux->sa_dverndx = vndx; 4767c478bd9Sstevel@tonic-gate vip = &ifl->ifl_verndx[vndx]; 4777c478bd9Sstevel@tonic-gate if (!(vip->vi_flags & FLG_VER_AVAIL)) { 4787c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_NOTAVAIL; 4797c478bd9Sstevel@tonic-gate /* 48060758829Srie * If this is the first occurrence of an 4817c478bd9Sstevel@tonic-gate * unavailable symbol record it for possible 4827c478bd9Sstevel@tonic-gate * use in later error diagnostics 4837c478bd9Sstevel@tonic-gate * (see sym_undef). 4847c478bd9Sstevel@tonic-gate */ 4857c478bd9Sstevel@tonic-gate if (!(sdp->sd_aux->sa_vfile)) 4867c478bd9Sstevel@tonic-gate sdp->sd_aux->sa_vfile = ifl->ifl_name; 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate } 4897c478bd9Sstevel@tonic-gate if (!(ifl->ifl_flags & FLG_IF_NEEDED)) 4907c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_NOTAVAIL; 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate /* 4947c478bd9Sstevel@tonic-gate * Make sure any symbol association maintained by the original symbol 4957c478bd9Sstevel@tonic-gate * is cleared and then update the symbols file reference. 4967c478bd9Sstevel@tonic-gate */ 4977c478bd9Sstevel@tonic-gate if ((link = sdp->sd_aux->sa_linkndx) != 0) { 4987c478bd9Sstevel@tonic-gate Sym_desc * _sdp; 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate _sdp = sdp->sd_file->ifl_oldndx[link]; 5017c478bd9Sstevel@tonic-gate _sdp->sd_aux->sa_linkndx = 0; 5027c478bd9Sstevel@tonic-gate sdp->sd_aux->sa_linkndx = 0; 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate sdp->sd_file = ifl; 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate /* 5077c478bd9Sstevel@tonic-gate * Update the input section descriptor to that of the new input file 5087c478bd9Sstevel@tonic-gate */ 509635216b6SRod Evans if (((nsdflags & FLG_SY_SPECSEC) == 0) && 510*1007fd6fSAli Bahrami (nsym->st_shndx != SHN_UNDEF) && 511*1007fd6fSAli Bahrami ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == NULL)) 512*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_NOSECDEF), 513*1007fd6fSAli Bahrami demangle(sdp->sd_name), ifl->ifl_name); 5140bc07c75Srie } 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate /* 5177c478bd9Sstevel@tonic-gate * Resolve two undefines (only called for two relocatable objects). 5187c478bd9Sstevel@tonic-gate */ 5197c478bd9Sstevel@tonic-gate static void 5207c478bd9Sstevel@tonic-gate sym_twoundefs(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 521635216b6SRod Evans int ndx, Word nshndx, sd_flag_t nsdflags) 5227c478bd9Sstevel@tonic-gate { 5237c478bd9Sstevel@tonic-gate Sym *osym = sdp->sd_sym; 52402ca3e02Srie uchar_t obind = ELF_ST_BIND(osym->st_info); 52508278a5eSRod Evans uchar_t otype = ELF_ST_TYPE(osym->st_info); 52602ca3e02Srie uchar_t nbind = ELF_ST_BIND(nsym->st_info); 52708278a5eSRod Evans uchar_t ntype = ELF_ST_TYPE(nsym->st_info); 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate /* 5307c478bd9Sstevel@tonic-gate * If two relocatable objects define a weak and non-weak undefined 5317c478bd9Sstevel@tonic-gate * reference, take the non-weak definition. 5327c478bd9Sstevel@tonic-gate * 5337c478bd9Sstevel@tonic-gate * -- or -- 5347c478bd9Sstevel@tonic-gate * 5357c478bd9Sstevel@tonic-gate * If two relocatable objects define a NOTYPE & another, then 5367c478bd9Sstevel@tonic-gate * take the other. 5377c478bd9Sstevel@tonic-gate */ 5387c478bd9Sstevel@tonic-gate if (((obind == STB_WEAK) && (nbind != STB_WEAK)) || 53908278a5eSRod Evans (otype == STT_NOTYPE) && (ntype != STT_NOTYPE)) { 540635216b6SRod Evans sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 5417c478bd9Sstevel@tonic-gate return; 5427c478bd9Sstevel@tonic-gate } 543635216b6SRod Evans sym_typecheck(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 5447c478bd9Sstevel@tonic-gate } 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate /* 5477c478bd9Sstevel@tonic-gate * Resolve two real definitions. 5487c478bd9Sstevel@tonic-gate */ 5497c478bd9Sstevel@tonic-gate static void 5507c478bd9Sstevel@tonic-gate sym_tworeals(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 551635216b6SRod Evans int ndx, Word nshndx, sd_flag_t nsdflags) 5527c478bd9Sstevel@tonic-gate { 553de777a60Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2; 5547c478bd9Sstevel@tonic-gate Sym *osym = sdp->sd_sym; 55502ca3e02Srie uchar_t otype = ELF_ST_TYPE(osym->st_info); 55602ca3e02Srie uchar_t obind = ELF_ST_BIND(osym->st_info); 55702ca3e02Srie uchar_t ntype = ELF_ST_TYPE(nsym->st_info); 55802ca3e02Srie uchar_t nbind = ELF_ST_BIND(nsym->st_info); 5597c478bd9Sstevel@tonic-gate Half ofile = sdp->sd_file->ifl_ehdr->e_type; 5607c478bd9Sstevel@tonic-gate Half nfile = ifl->ifl_ehdr->e_type; 5617c478bd9Sstevel@tonic-gate int warn = 0; 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate /* 5647c478bd9Sstevel@tonic-gate * If both definitions are from relocatable objects, and have non-weak 5657c478bd9Sstevel@tonic-gate * binding then this is a fatal condition. 5667c478bd9Sstevel@tonic-gate */ 5677c478bd9Sstevel@tonic-gate if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) && 5687c478bd9Sstevel@tonic-gate (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) { 569*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF), 5707c478bd9Sstevel@tonic-gate demangle(sdp->sd_name)); 571*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 5727c478bd9Sstevel@tonic-gate sdp->sd_file->ifl_name, 573de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 574de777a60Sab196087 0, &inv_buf1), ifl->ifl_name, 575de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 576de777a60Sab196087 0, &inv_buf2)); 5777c478bd9Sstevel@tonic-gate return; 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate /* 5817c478bd9Sstevel@tonic-gate * Perform any machine specific type checking. 5827c478bd9Sstevel@tonic-gate */ 583ba2be530Sab196087 if ((ld_targ.t_ms.ms_mach_sym_typecheck != NULL) && 584ba2be530Sab196087 (*ld_targ.t_ms.ms_mach_sym_typecheck)(sdp, nsym, ifl, ofl)) 5857c478bd9Sstevel@tonic-gate return; 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate /* 5887c478bd9Sstevel@tonic-gate * Check the symbols type and size. 5897c478bd9Sstevel@tonic-gate */ 5907c478bd9Sstevel@tonic-gate if (otype != ntype) { 591*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 5927c478bd9Sstevel@tonic-gate demangle(sdp->sd_name)); 593*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 5947c478bd9Sstevel@tonic-gate sdp->sd_file->ifl_name, 595de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 596de777a60Sab196087 0, &inv_buf1), ifl->ifl_name, 597de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 598de777a60Sab196087 0, &inv_buf2)); 5997c478bd9Sstevel@tonic-gate warn++; 6007c478bd9Sstevel@tonic-gate } else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) { 6017c478bd9Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN)) { 602*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_WARNING, 6035aefb655Srie MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 6045aefb655Srie MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name, 6055aefb655Srie EC_XWORD(osym->st_size), ifl->ifl_name, 6065aefb655Srie EC_XWORD(nsym->st_size)); 6077c478bd9Sstevel@tonic-gate warn++; 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate 6117c478bd9Sstevel@tonic-gate /* 6127c478bd9Sstevel@tonic-gate * Having provided the user with any necessary warnings, take the 6137c478bd9Sstevel@tonic-gate * appropriate symbol: 6147c478bd9Sstevel@tonic-gate * 61528bda19cSRod Evans * - if one symbol is from a shared object and the other is from a 6167c478bd9Sstevel@tonic-gate * relocatable object, take the relocatable objects symbol (the 6177c478bd9Sstevel@tonic-gate * run-time linker is always going to find the relocatable object 6187c478bd9Sstevel@tonic-gate * symbol regardless of the binding), else 6197c478bd9Sstevel@tonic-gate * 62028bda19cSRod Evans * - if both symbols are from relocatable objects and one symbol is 6217c478bd9Sstevel@tonic-gate * weak take the non-weak symbol (two non-weak symbols would have 6227c478bd9Sstevel@tonic-gate * generated the fatal error condition above unless -z muldefs is 6237c478bd9Sstevel@tonic-gate * in effect), else 6247c478bd9Sstevel@tonic-gate * 62528bda19cSRod Evans * - take the first symbol definition encountered. 6267c478bd9Sstevel@tonic-gate */ 6277c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 6287c478bd9Sstevel@tonic-gate if (warn) 629*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 630*1007fd6fSAli Bahrami sdp->sd_file->ifl_name); 6317c478bd9Sstevel@tonic-gate return; 6327c478bd9Sstevel@tonic-gate } else if ((nfile == ET_REL) && ((ofile == ET_DYN) || 6337c478bd9Sstevel@tonic-gate ((obind == STB_WEAK) && (nbind != STB_WEAK)))) { 6347c478bd9Sstevel@tonic-gate if (warn) 635*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 636*1007fd6fSAli Bahrami ifl->ifl_name); 637635216b6SRod Evans sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 6387c478bd9Sstevel@tonic-gate return; 6397c478bd9Sstevel@tonic-gate } else { 6407c478bd9Sstevel@tonic-gate if (warn) 641*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 642*1007fd6fSAli Bahrami sdp->sd_file->ifl_name); 643635216b6SRod Evans sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 6447c478bd9Sstevel@tonic-gate return; 6457c478bd9Sstevel@tonic-gate } 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate /* 6497c478bd9Sstevel@tonic-gate * Resolve a real and tentative definition. 6507c478bd9Sstevel@tonic-gate */ 6517c478bd9Sstevel@tonic-gate static void 6527c478bd9Sstevel@tonic-gate sym_realtent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 653635216b6SRod Evans int ndx, Word nshndx, sd_flag_t nsdflags) 6547c478bd9Sstevel@tonic-gate { 655de777a60Sab196087 Conv_inv_buf_t inv_buf1, inv_buf2; 6567c478bd9Sstevel@tonic-gate Sym *osym = sdp->sd_sym; 65702ca3e02Srie uchar_t otype = ELF_ST_TYPE(osym->st_info); 65802ca3e02Srie uchar_t obind = ELF_ST_BIND(osym->st_info); 65902ca3e02Srie uchar_t ntype = ELF_ST_TYPE(nsym->st_info); 66002ca3e02Srie uchar_t nbind = ELF_ST_BIND(nsym->st_info); 6617c478bd9Sstevel@tonic-gate Boolean otent = FALSE, ntent = FALSE; 6627c478bd9Sstevel@tonic-gate Half ofile = sdp->sd_file->ifl_ehdr->e_type; 6637c478bd9Sstevel@tonic-gate Half nfile = ifl->ifl_ehdr->e_type; 6647c478bd9Sstevel@tonic-gate int warn = 0; 66560758829Srie uchar_t ovis = ELF_ST_VISIBILITY(osym->st_other); 66660758829Srie uchar_t nvis = ELF_ST_VISIBILITY(nsym->st_other); 6677c478bd9Sstevel@tonic-gate 6687c478bd9Sstevel@tonic-gate /* 6697c478bd9Sstevel@tonic-gate * Special rules for functions. 6707c478bd9Sstevel@tonic-gate * 67128bda19cSRod Evans * - If both definitions are from relocatable objects, have the same 6727c478bd9Sstevel@tonic-gate * binding (ie. two weaks or two non-weaks), and the real 6737c478bd9Sstevel@tonic-gate * definition is a function (the other must be tentative), treat 6747c478bd9Sstevel@tonic-gate * this as a multiply defined symbol error, else 6757c478bd9Sstevel@tonic-gate * 67628bda19cSRod Evans * - if the real symbol definition is a function within a shared 6777c478bd9Sstevel@tonic-gate * library and the tentative symbol is a relocatable object, and 6787c478bd9Sstevel@tonic-gate * the tentative is not weak and the function real, then retain the 6797c478bd9Sstevel@tonic-gate * tentative definition. 6807c478bd9Sstevel@tonic-gate */ 6817c478bd9Sstevel@tonic-gate if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) && 6827c478bd9Sstevel@tonic-gate ((otype == STT_FUNC) || (ntype == STT_FUNC))) { 6837c478bd9Sstevel@tonic-gate if (ofl->ofl_flags & FLG_OF_MULDEFS) { 684*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 685*1007fd6fSAli Bahrami demangle(sdp->sd_name)); 6867c478bd9Sstevel@tonic-gate sym_promote(sdp, nsym, ifl, ofl, ndx, 687635216b6SRod Evans nshndx, nsdflags); 6887c478bd9Sstevel@tonic-gate } else { 689*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF), 690*1007fd6fSAli Bahrami demangle(sdp->sd_name)); 6917c478bd9Sstevel@tonic-gate } 692*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 6937c478bd9Sstevel@tonic-gate sdp->sd_file->ifl_name, 694de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 695de777a60Sab196087 0, &inv_buf1), ifl->ifl_name, 696de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 697de777a60Sab196087 0, &inv_buf2)); 6987c478bd9Sstevel@tonic-gate return; 6997c478bd9Sstevel@tonic-gate } else if (ofile != nfile) { 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate if ((ofile == ET_DYN) && (otype == STT_FUNC)) { 7037c478bd9Sstevel@tonic-gate if ((otype != STB_WEAK) && (ntype == STB_WEAK)) 7047c478bd9Sstevel@tonic-gate return; 7057c478bd9Sstevel@tonic-gate else { 7067c478bd9Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx, 707635216b6SRod Evans nshndx, nsdflags); 7087c478bd9Sstevel@tonic-gate return; 7097c478bd9Sstevel@tonic-gate } 7107c478bd9Sstevel@tonic-gate } 7117c478bd9Sstevel@tonic-gate if ((nfile == ET_DYN) && (ntype == STT_FUNC)) { 7127c478bd9Sstevel@tonic-gate if ((ntype != STB_WEAK) && (otype == STB_WEAK)) { 7137c478bd9Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx, 714635216b6SRod Evans nshndx, nsdflags); 7157c478bd9Sstevel@tonic-gate return; 7167c478bd9Sstevel@tonic-gate } else 7177c478bd9Sstevel@tonic-gate return; 7187c478bd9Sstevel@tonic-gate } 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate if (sdp->sd_flags & FLG_SY_TENTSYM) 7227c478bd9Sstevel@tonic-gate otent = TRUE; 723635216b6SRod Evans if (nsdflags & FLG_SY_TENTSYM) 7247c478bd9Sstevel@tonic-gate ntent = TRUE; 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate /* 7287c478bd9Sstevel@tonic-gate * Check the symbols type and size. 7297c478bd9Sstevel@tonic-gate */ 7307c478bd9Sstevel@tonic-gate if (otype != ntype) { 731*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE), 7327c478bd9Sstevel@tonic-gate demangle(sdp->sd_name)); 733*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES), 7347c478bd9Sstevel@tonic-gate sdp->sd_file->ifl_name, 735de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 736de777a60Sab196087 0, &inv_buf1), ifl->ifl_name, 737de777a60Sab196087 conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype, 738de777a60Sab196087 0, &inv_buf2)); 7397c478bd9Sstevel@tonic-gate warn++; 7407c478bd9Sstevel@tonic-gate } else if (osym->st_size != nsym->st_size) { 7417c478bd9Sstevel@tonic-gate /* 7427c478bd9Sstevel@tonic-gate * If both definitions are from relocatable objects we have a 7437c478bd9Sstevel@tonic-gate * potential fatal error condition. If the tentative is larger 7447c478bd9Sstevel@tonic-gate * than the real definition treat this as a multiple definition. 7457c478bd9Sstevel@tonic-gate * Note that if only one symbol is weak, the non-weak will be 7467c478bd9Sstevel@tonic-gate * taken. 7477c478bd9Sstevel@tonic-gate */ 7487c478bd9Sstevel@tonic-gate if (((ofile == ET_REL) && (nfile == ET_REL) && 7497c478bd9Sstevel@tonic-gate (obind == nbind)) && 7507c478bd9Sstevel@tonic-gate ((otent && (osym->st_size > nsym->st_size)) || 7517c478bd9Sstevel@tonic-gate (ntent && (osym->st_size < nsym->st_size)))) { 752*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_DIFFATTR), 753*1007fd6fSAli Bahrami demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES), 754*1007fd6fSAli Bahrami sdp->sd_file->ifl_name, EC_XWORD(osym->st_size), 755*1007fd6fSAli Bahrami ifl->ifl_name, EC_XWORD(nsym->st_size)); 756*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_TENTERR)); 7577c478bd9Sstevel@tonic-gate } else { 7587c478bd9Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN)) { 759*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_WARNING, 7605aefb655Srie MSG_INTL(MSG_SYM_DIFFATTR), 7617c478bd9Sstevel@tonic-gate demangle(sdp->sd_name), 7627c478bd9Sstevel@tonic-gate MSG_INTL(MSG_STR_SIZES), 7637c478bd9Sstevel@tonic-gate sdp->sd_file->ifl_name, 7647c478bd9Sstevel@tonic-gate EC_XWORD(osym->st_size), 7657c478bd9Sstevel@tonic-gate ifl->ifl_name, EC_XWORD(nsym->st_size)); 7667c478bd9Sstevel@tonic-gate warn++; 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate } 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate 7717c478bd9Sstevel@tonic-gate /* 7727c478bd9Sstevel@tonic-gate * Having provided the user with any necessary warnings, take the 7737c478bd9Sstevel@tonic-gate * appropriate symbol: 7747c478bd9Sstevel@tonic-gate * 77528bda19cSRod Evans * - if the original symbol is from relocatable file and it is 7767c478bd9Sstevel@tonic-gate * a protected tentative symbol, take the original one. 7777c478bd9Sstevel@tonic-gate * 77828bda19cSRod Evans * - if the original symbol is from shared object and the new 7797c478bd9Sstevel@tonic-gate * symbol is a protected tentative symbol from a relocatable file, 7807c478bd9Sstevel@tonic-gate * take the new one. 7817c478bd9Sstevel@tonic-gate * 78228bda19cSRod Evans * - if the original symbol is tentative, and providing the original 7837c478bd9Sstevel@tonic-gate * symbol isn't strong and the new symbol weak, take the real 7847c478bd9Sstevel@tonic-gate * symbol, else 7857c478bd9Sstevel@tonic-gate * 78628bda19cSRod Evans * - if the original symbol is weak and the new tentative symbol is 7877c478bd9Sstevel@tonic-gate * strong take the new symbol. 7887c478bd9Sstevel@tonic-gate * 7897c478bd9Sstevel@tonic-gate * Refer to the System V ABI Page 4-27 for a description of the binding 7907c478bd9Sstevel@tonic-gate * requirements of tentative and weak symbols. 7917c478bd9Sstevel@tonic-gate */ 7927c478bd9Sstevel@tonic-gate if ((ofile == ET_REL) && (nfile == ET_DYN) && (otent == TRUE) && 79360758829Srie (ovis == STV_PROTECTED)) { 7947c478bd9Sstevel@tonic-gate return; 7957c478bd9Sstevel@tonic-gate } 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate if ((ofile == ET_DYN) && (nfile == ET_REL) && (ntent == TRUE) && 79860758829Srie (nvis == STV_PROTECTED)) { 799635216b6SRod Evans sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 8007c478bd9Sstevel@tonic-gate return; 8017c478bd9Sstevel@tonic-gate } 8027c478bd9Sstevel@tonic-gate 8037c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 8047c478bd9Sstevel@tonic-gate if (warn) 805*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 806*1007fd6fSAli Bahrami sdp->sd_file->ifl_name); 8077c478bd9Sstevel@tonic-gate return; 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) || 8117c478bd9Sstevel@tonic-gate ((obind == STB_WEAK) && (nbind != STB_WEAK))) { 8127c478bd9Sstevel@tonic-gate if (warn) 813*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 814*1007fd6fSAli Bahrami ifl->ifl_name); 815635216b6SRod Evans sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 8167c478bd9Sstevel@tonic-gate return; 8177c478bd9Sstevel@tonic-gate } else { 8187c478bd9Sstevel@tonic-gate if (warn) 819*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN), 820*1007fd6fSAli Bahrami sdp->sd_file->ifl_name); 821635216b6SRod Evans sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 8227c478bd9Sstevel@tonic-gate return; 8237c478bd9Sstevel@tonic-gate } 8247c478bd9Sstevel@tonic-gate } 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate /* 8277c478bd9Sstevel@tonic-gate * Resolve two tentative symbols. 8287c478bd9Sstevel@tonic-gate */ 8297c478bd9Sstevel@tonic-gate static void 8307c478bd9Sstevel@tonic-gate sym_twotent(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, 831635216b6SRod Evans int ndx, Word nshndx, sd_flag_t nsdflags) 8327c478bd9Sstevel@tonic-gate { 8337c478bd9Sstevel@tonic-gate Sym *osym = sdp->sd_sym; 83402ca3e02Srie uchar_t obind = ELF_ST_BIND(osym->st_info); 83502ca3e02Srie uchar_t nbind = ELF_ST_BIND(nsym->st_info); 8367c478bd9Sstevel@tonic-gate Half ofile = sdp->sd_file->ifl_ehdr->e_type; 8377c478bd9Sstevel@tonic-gate Half nfile = ifl->ifl_ehdr->e_type; 8387c478bd9Sstevel@tonic-gate size_t size = 0; 8397c478bd9Sstevel@tonic-gate Xword value = 0; 8407c478bd9Sstevel@tonic-gate 841ba2be530Sab196087 #if defined(_ELF64) 842ba2be530Sab196087 if (ld_targ.t_m.m_mach == EM_AMD64) { 84354d82594Sseizo /* 844ba2be530Sab196087 * If the original and new symbols are both COMMON, but of 845ba2be530Sab196087 * a different size model, take the small one. 84654d82594Sseizo */ 8470bc07c75Srie if ((sdp->sd_sym->st_shndx == SHN_COMMON) && 8480bc07c75Srie (nsym->st_shndx == SHN_X86_64_LCOMMON)) { 84954d82594Sseizo /* 8500bc07c75Srie * Take the original symbol. 85154d82594Sseizo */ 85254d82594Sseizo return; 8530bc07c75Srie 8540bc07c75Srie } else if ((sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) && 8550bc07c75Srie (nsym->st_shndx == SHN_COMMON)) { 85654d82594Sseizo /* 85754d82594Sseizo * Take the new symbol. 85854d82594Sseizo */ 859ba2be530Sab196087 sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, 860635216b6SRod Evans nsdflags); 86154d82594Sseizo return; 86254d82594Sseizo } 863ba2be530Sab196087 } 86454d82594Sseizo #endif 86554d82594Sseizo 8667c478bd9Sstevel@tonic-gate /* 8677c478bd9Sstevel@tonic-gate * Check the alignment of the symbols. This can only be tested for if 8687c478bd9Sstevel@tonic-gate * the symbols are not real definitions to a SHT_NOBITS section (ie. 8697c478bd9Sstevel@tonic-gate * they were originally tentative), as in this case the symbol would 8707c478bd9Sstevel@tonic-gate * have a displacement value rather than an alignment. In other words 8717c478bd9Sstevel@tonic-gate * we can only test this for two relocatable objects. 8727c478bd9Sstevel@tonic-gate */ 873de777a60Sab196087 /* BEGIN CSTYLED */ 8747c478bd9Sstevel@tonic-gate if ((osym->st_value != nsym->st_value) && 8757c478bd9Sstevel@tonic-gate ((sdp->sd_flags & FLG_SY_SPECSEC) && 8760bc07c75Srie (sdp->sd_sym->st_shndx == SHN_COMMON) && 877635216b6SRod Evans (nsdflags & FLG_SY_SPECSEC) && 878ba2be530Sab196087 #if defined(_ELF64) 8790bc07c75Srie (nsym->st_shndx == SHN_COMMON)) || 880ba2be530Sab196087 ((ld_targ.t_m.m_mach == EM_AMD64) && 881ba2be530Sab196087 (sdp->sd_flags & FLG_SY_SPECSEC) && 8820bc07c75Srie (sdp->sd_sym->st_shndx == SHN_X86_64_LCOMMON) && 883635216b6SRod Evans (nsdflags & FLG_SY_SPECSEC) && 8840bc07c75Srie (nsym->st_shndx == SHN_X86_64_LCOMMON))) { 88554d82594Sseizo #else 8860bc07c75Srie (nsym->st_shndx == SHN_COMMON))) { 88754d82594Sseizo #endif 888de777a60Sab196087 /* END CSTYLED */ 889de777a60Sab196087 8907c478bd9Sstevel@tonic-gate const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 8917c478bd9Sstevel@tonic-gate const char *file; 8927c478bd9Sstevel@tonic-gate Xword salign; 8937c478bd9Sstevel@tonic-gate Xword balign; 8947c478bd9Sstevel@tonic-gate uint_t alignscompliment; 8957c478bd9Sstevel@tonic-gate 8967c478bd9Sstevel@tonic-gate if (osym->st_value < nsym->st_value) { 8977c478bd9Sstevel@tonic-gate salign = osym->st_value; 8987c478bd9Sstevel@tonic-gate balign = nsym->st_value; 8997c478bd9Sstevel@tonic-gate } else { 9007c478bd9Sstevel@tonic-gate salign = nsym->st_value; 9017c478bd9Sstevel@tonic-gate balign = osym->st_value; 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate /* 9057c478bd9Sstevel@tonic-gate * If the smaller alignment fits smoothly into the 9067c478bd9Sstevel@tonic-gate * larger alignment - we take it with no warning. 9077c478bd9Sstevel@tonic-gate */ 9087c478bd9Sstevel@tonic-gate if (S_ALIGN(balign, salign) == balign) 9097c478bd9Sstevel@tonic-gate alignscompliment = 1; 9107c478bd9Sstevel@tonic-gate else 9117c478bd9Sstevel@tonic-gate alignscompliment = 0; 9127c478bd9Sstevel@tonic-gate 9137c478bd9Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 914*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_WARNING, 9155aefb655Srie MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name), 9167c478bd9Sstevel@tonic-gate MSG_INTL(MSG_STR_ALIGNMENTS), 9177c478bd9Sstevel@tonic-gate sdp->sd_file->ifl_name, EC_XWORD(osym->st_value), 9187c478bd9Sstevel@tonic-gate ifl->ifl_name, EC_XWORD(nsym->st_value)); 9197c478bd9Sstevel@tonic-gate 9207c478bd9Sstevel@tonic-gate /* 9217c478bd9Sstevel@tonic-gate * Having provided the necessary warning indicate which 9227c478bd9Sstevel@tonic-gate * relocatable object we are going to take. 9237c478bd9Sstevel@tonic-gate * 92428bda19cSRod Evans * - if one symbol is weak and the other is non-weak 9257c478bd9Sstevel@tonic-gate * take the non-weak symbol, else 9267c478bd9Sstevel@tonic-gate * 92728bda19cSRod Evans * - take the largest alignment (as we still have to check 9287c478bd9Sstevel@tonic-gate * the symbols size simply save the largest value for 9297c478bd9Sstevel@tonic-gate * updating later). 9307c478bd9Sstevel@tonic-gate */ 9317c478bd9Sstevel@tonic-gate if ((obind == STB_WEAK) && (nbind != STB_WEAK)) 9327c478bd9Sstevel@tonic-gate file = ifl->ifl_name; 9337c478bd9Sstevel@tonic-gate else if (obind != nbind) 9347c478bd9Sstevel@tonic-gate file = sdp->sd_file->ifl_name; 9357c478bd9Sstevel@tonic-gate else { 9367c478bd9Sstevel@tonic-gate emsg = MSG_INTL(MSG_SYM_LARGER); 9377c478bd9Sstevel@tonic-gate value = balign; 9387c478bd9Sstevel@tonic-gate } 9397c478bd9Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment) 940*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, emsg, file); 9417c478bd9Sstevel@tonic-gate } 9427c478bd9Sstevel@tonic-gate 9437c478bd9Sstevel@tonic-gate /* 9447c478bd9Sstevel@tonic-gate * Check the size of the symbols. 9457c478bd9Sstevel@tonic-gate */ 9467c478bd9Sstevel@tonic-gate if (osym->st_size != nsym->st_size) { 9477c478bd9Sstevel@tonic-gate const char *emsg = MSG_INTL(MSG_SYM_DEFTAKEN); 9487c478bd9Sstevel@tonic-gate const char *file; 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 951*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR), 952*1007fd6fSAli Bahrami demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES), 953*1007fd6fSAli Bahrami sdp->sd_file->ifl_name, EC_XWORD(osym->st_size), 954*1007fd6fSAli Bahrami ifl->ifl_name, EC_XWORD(nsym->st_size)); 9557c478bd9Sstevel@tonic-gate 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate /* 9587c478bd9Sstevel@tonic-gate * This symbol has already been compared to an SO definition, 9597c478bd9Sstevel@tonic-gate * as per the runtime behavior, ignore extra definitions. 9607c478bd9Sstevel@tonic-gate */ 9617c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) { 9627c478bd9Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 963*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, emsg, 9647c478bd9Sstevel@tonic-gate sdp->sd_file->ifl_name); 9657c478bd9Sstevel@tonic-gate return; 9667c478bd9Sstevel@tonic-gate } 9677c478bd9Sstevel@tonic-gate 9687c478bd9Sstevel@tonic-gate /* 9697c478bd9Sstevel@tonic-gate * Having provided the necessary warning indicate what course 9707c478bd9Sstevel@tonic-gate * of action we are going to take. 9717c478bd9Sstevel@tonic-gate * 97228bda19cSRod Evans * - if the file types differ, take the relocatable object 9737c478bd9Sstevel@tonic-gate * and apply the largest symbol size, else 97428bda19cSRod Evans * - if one symbol is weak and the other is non-weak, take 9757c478bd9Sstevel@tonic-gate * the non-weak symbol, else 97628bda19cSRod Evans * - simply take the largest symbol reference. 9777c478bd9Sstevel@tonic-gate */ 9787c478bd9Sstevel@tonic-gate if (nfile != ofile) { 9797c478bd9Sstevel@tonic-gate if (nfile == ET_REL) { 9807c478bd9Sstevel@tonic-gate file = ifl->ifl_name; 9817c478bd9Sstevel@tonic-gate if (osym->st_size > nsym->st_size) { 9827c478bd9Sstevel@tonic-gate size = (size_t)osym->st_size; 9837c478bd9Sstevel@tonic-gate emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 9847c478bd9Sstevel@tonic-gate } 9857c478bd9Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx, 986635216b6SRod Evans nshndx, nsdflags); 9877c478bd9Sstevel@tonic-gate } else { 9887c478bd9Sstevel@tonic-gate file = sdp->sd_file->ifl_name; 9897c478bd9Sstevel@tonic-gate if (osym->st_size < nsym->st_size) { 9907c478bd9Sstevel@tonic-gate size = (size_t)nsym->st_size; 9917c478bd9Sstevel@tonic-gate emsg = MSG_INTL(MSG_SYM_DEFUPDATE); 9927c478bd9Sstevel@tonic-gate } 9937c478bd9Sstevel@tonic-gate sym_promote(sdp, nsym, ifl, ofl, ndx, 994635216b6SRod Evans nshndx, nsdflags); 9957c478bd9Sstevel@tonic-gate } 9967c478bd9Sstevel@tonic-gate } else if (obind != nbind) { 9977c478bd9Sstevel@tonic-gate if ((obind == STB_WEAK) && (nbind != STB_WEAK)) { 9987c478bd9Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx, 999635216b6SRod Evans nshndx, nsdflags); 10007c478bd9Sstevel@tonic-gate file = ifl->ifl_name; 10017c478bd9Sstevel@tonic-gate } else 10027c478bd9Sstevel@tonic-gate file = sdp->sd_file->ifl_name; 10037c478bd9Sstevel@tonic-gate } else { 10047c478bd9Sstevel@tonic-gate if (osym->st_size < nsym->st_size) { 10057c478bd9Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx, 1006635216b6SRod Evans nshndx, nsdflags); 10077c478bd9Sstevel@tonic-gate file = ifl->ifl_name; 10087c478bd9Sstevel@tonic-gate } else 10097c478bd9Sstevel@tonic-gate file = sdp->sd_file->ifl_name; 10107c478bd9Sstevel@tonic-gate } 10117c478bd9Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_NOWARN)) 1012*1007fd6fSAli Bahrami ld_eprintf(ofl, ERR_NONE, emsg, file); 10137c478bd9Sstevel@tonic-gate if (size) 10147c478bd9Sstevel@tonic-gate sdp->sd_sym->st_size = (Xword)size; 10157c478bd9Sstevel@tonic-gate } else { 10167c478bd9Sstevel@tonic-gate /* 10177c478bd9Sstevel@tonic-gate * If the sizes are the same 10187c478bd9Sstevel@tonic-gate * 101928bda19cSRod Evans * - if the file types differ, take the relocatable object, 10207c478bd9Sstevel@tonic-gate * else 10217c478bd9Sstevel@tonic-gate * 102228bda19cSRod Evans * - if one symbol is weak and the other is non-weak, take 10237c478bd9Sstevel@tonic-gate * the non-weak symbol, else 10247c478bd9Sstevel@tonic-gate * 102528bda19cSRod Evans * - take the first reference. 10267c478bd9Sstevel@tonic-gate */ 10277c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) 10287c478bd9Sstevel@tonic-gate return; 10297c478bd9Sstevel@tonic-gate else if (((ofile != nfile) && (nfile == ET_REL)) || 10307c478bd9Sstevel@tonic-gate (((obind == STB_WEAK) && (nbind != STB_WEAK)) && 10317c478bd9Sstevel@tonic-gate (!((ofile != nfile) && (ofile == ET_REL))))) 10327c478bd9Sstevel@tonic-gate sym_override(sdp, nsym, ifl, ofl, ndx, 1033635216b6SRod Evans nshndx, nsdflags); 10347c478bd9Sstevel@tonic-gate else 10357c478bd9Sstevel@tonic-gate sym_promote(sdp, nsym, ifl, ofl, ndx, 1036635216b6SRod Evans nshndx, nsdflags); 10377c478bd9Sstevel@tonic-gate } 10387c478bd9Sstevel@tonic-gate 10397c478bd9Sstevel@tonic-gate /* 10407c478bd9Sstevel@tonic-gate * Enforce the largest alignment if necessary. 10417c478bd9Sstevel@tonic-gate */ 10427c478bd9Sstevel@tonic-gate if (value) 10437c478bd9Sstevel@tonic-gate sdp->sd_sym->st_value = value; 10447c478bd9Sstevel@tonic-gate } 10457c478bd9Sstevel@tonic-gate 10467c478bd9Sstevel@tonic-gate /* 10477c478bd9Sstevel@tonic-gate * Symbol resolution state table. `Action' describes the required 10487c478bd9Sstevel@tonic-gate * procedure to be called (if any). 10497c478bd9Sstevel@tonic-gate */ 10507c478bd9Sstevel@tonic-gate static void (*Action[REF_NUM * SYM_NUM * 2][SYM_NUM])(Sym_desc *, 1051635216b6SRod Evans Sym *, Ifl_desc *, Ofl_desc *, int, Word, sd_flag_t) = { 10527c478bd9Sstevel@tonic-gate 10537c478bd9Sstevel@tonic-gate /* defined undef tent */ 10547c478bd9Sstevel@tonic-gate /* ET_REL ET_REL ET_REL */ 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate /* 0 defined REF_DYN_SEEN */ sym_tworeals, sym_promote, sym_realtent, 10577c478bd9Sstevel@tonic-gate /* 1 undef REF_DYN_SEEN */ sym_override, sym_override, sym_override, 10587c478bd9Sstevel@tonic-gate /* 2 tent REF_DYN_SEEN */ sym_realtent, sym_promote, sym_twotent, 10597c478bd9Sstevel@tonic-gate /* 3 defined REF_DYN_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 10607c478bd9Sstevel@tonic-gate /* 4 undef REF_DYN_NEED */ sym_override, sym_override, sym_override, 10617c478bd9Sstevel@tonic-gate /* 5 tent REF_DYN_NEED */ sym_realtent, sym_typecheck, sym_twotent, 10627c478bd9Sstevel@tonic-gate /* 6 defined REF_REL_NEED */ sym_tworeals, sym_typecheck, sym_realtent, 10637c478bd9Sstevel@tonic-gate /* 7 undef REF_REL_NEED */ sym_override, sym_twoundefs, sym_override, 10647c478bd9Sstevel@tonic-gate /* 8 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent, 10657c478bd9Sstevel@tonic-gate 10667c478bd9Sstevel@tonic-gate /* defined undef tent */ 10677c478bd9Sstevel@tonic-gate /* ET_DYN ET_DYN ET_DYN */ 10687c478bd9Sstevel@tonic-gate 10697c478bd9Sstevel@tonic-gate /* 9 defined REF_DYN_SEEN */ sym_tworeals, sym_null, sym_realtent, 10707c478bd9Sstevel@tonic-gate /* 10 undef REF_DYN_SEEN */ sym_override, sym_mach_check, sym_override, 10717c478bd9Sstevel@tonic-gate /* 11 tent REF_DYN_SEEN */ sym_realtent, sym_null, sym_twotent, 10727c478bd9Sstevel@tonic-gate /* 12 defined REF_DYN_NEED */ sym_tworeals, sym_null, sym_realtent, 10737c478bd9Sstevel@tonic-gate /* 13 undef REF_DYN_NEED */ sym_override, sym_null, sym_override, 10747c478bd9Sstevel@tonic-gate /* 14 tent REF_DYN_NEED */ sym_realtent, sym_null, sym_twotent, 10757c478bd9Sstevel@tonic-gate /* 15 defined REF_REL_NEED */ sym_tworeals, sym_null, sym_realtent, 10767c478bd9Sstevel@tonic-gate /* 16 undef REF_REL_NEED */ sym_override, sym_mach_check, sym_override, 10777c478bd9Sstevel@tonic-gate /* 17 tent REF_REL_NEED */ sym_realtent, sym_null, sym_twotent 10787c478bd9Sstevel@tonic-gate 10797c478bd9Sstevel@tonic-gate }; 10807c478bd9Sstevel@tonic-gate 10817c478bd9Sstevel@tonic-gate uintptr_t 10825aefb655Srie ld_sym_resolve(Sym_desc *sdp, Sym *nsym, Ifl_desc *ifl, Ofl_desc *ofl, int ndx, 1083635216b6SRod Evans Word nshndx, sd_flag_t nsdflags) 10847c478bd9Sstevel@tonic-gate { 10857c478bd9Sstevel@tonic-gate int row, column; /* State table coordinates */ 10867c478bd9Sstevel@tonic-gate Sym *osym = sdp->sd_sym; 108708278a5eSRod Evans sd_flag_t osdflags = sdp->sd_flags; 10887c478bd9Sstevel@tonic-gate Is_desc *isp; 108960758829Srie Half vis = 0, nfile = ifl->ifl_ehdr->e_type; 109060758829Srie Half oref = sdp->sd_ref; 10917c478bd9Sstevel@tonic-gate 10927c478bd9Sstevel@tonic-gate /* 10937c478bd9Sstevel@tonic-gate * Determine the original symbols definition (defines row in Action[]). 10947c478bd9Sstevel@tonic-gate */ 109508278a5eSRod Evans if (osdflags & FLG_SY_TENTSYM) 10967c478bd9Sstevel@tonic-gate row = SYM_TENTATIVE; 10970bc07c75Srie else if ((sdp->sd_sym->st_shndx == SHN_UNDEF) || 10980bc07c75Srie (sdp->sd_sym->st_shndx == SHN_SUNW_IGNORE)) 10997c478bd9Sstevel@tonic-gate row = SYM_UNDEFINED; 11007c478bd9Sstevel@tonic-gate else 11017c478bd9Sstevel@tonic-gate row = SYM_DEFINED; 11027c478bd9Sstevel@tonic-gate 11037c478bd9Sstevel@tonic-gate /* 11047c478bd9Sstevel@tonic-gate * If the input file is an implicit shared object then we don't need 11057c478bd9Sstevel@tonic-gate * to bind to any symbols within it other than to verify that any 11067c478bd9Sstevel@tonic-gate * undefined references will be closed (implicit shared objects are only 11077c478bd9Sstevel@tonic-gate * processed when no undefined symbols are required as a result of the 11087c478bd9Sstevel@tonic-gate * link-edit (see process_dynamic())). 11097c478bd9Sstevel@tonic-gate */ 11107c478bd9Sstevel@tonic-gate if ((nfile == ET_DYN) && !(ifl->ifl_flags & FLG_IF_NEEDED) && 11117c478bd9Sstevel@tonic-gate (row != SYM_UNDEFINED)) 11127c478bd9Sstevel@tonic-gate return (1); 11137c478bd9Sstevel@tonic-gate 11147c478bd9Sstevel@tonic-gate /* 11157c478bd9Sstevel@tonic-gate * Finish computing the Action[] row by applying the symbols reference 11167c478bd9Sstevel@tonic-gate * together with the input files type. 11177c478bd9Sstevel@tonic-gate */ 11187c478bd9Sstevel@tonic-gate row = row + (REF_NUM * sdp->sd_ref); 11197c478bd9Sstevel@tonic-gate if (nfile == ET_DYN) 11207c478bd9Sstevel@tonic-gate row += (REF_NUM * SYM_NUM); 11217c478bd9Sstevel@tonic-gate 11227c478bd9Sstevel@tonic-gate /* 112360758829Srie * If either the original or new symbol originates from a relocatable 112460758829Srie * object, determine the appropriate visibility for the resolved symbol. 112560758829Srie */ 112660758829Srie if ((oref == REF_REL_NEED) || (nfile == ET_REL)) 112760758829Srie vis = sym_visibility(sdp, nsym, ifl, ofl); 112860758829Srie 112960758829Srie /* 11307c478bd9Sstevel@tonic-gate * Determine the new symbols definition (defines column in Action[]). 11317c478bd9Sstevel@tonic-gate */ 1132635216b6SRod Evans if ((nsdflags & FLG_SY_SPECSEC) && 11330bc07c75Srie (nsym->st_shndx == SHN_COMMON)) { 11347c478bd9Sstevel@tonic-gate column = SYM_TENTATIVE; 1135635216b6SRod Evans nsdflags |= FLG_SY_TENTSYM; 1136ba2be530Sab196087 #if defined(_ELF64) 1137ba2be530Sab196087 } else if ((ld_targ.t_m.m_mach == EM_AMD64) && 1138635216b6SRod Evans (nsdflags & FLG_SY_SPECSEC) && 11390bc07c75Srie (nsym->st_shndx == SHN_X86_64_LCOMMON)) { 114054d82594Sseizo column = SYM_TENTATIVE; 1141635216b6SRod Evans nsdflags |= FLG_SY_TENTSYM; 114254d82594Sseizo #endif 11430bc07c75Srie } else if ((nsym->st_shndx == SHN_UNDEF) || 11440bc07c75Srie (nsym->st_shndx == SHN_SUNW_IGNORE)) { 11457c478bd9Sstevel@tonic-gate column = SYM_UNDEFINED; 11467c478bd9Sstevel@tonic-gate nshndx = SHN_UNDEF; 11477c478bd9Sstevel@tonic-gate } else { 11487c478bd9Sstevel@tonic-gate column = SYM_DEFINED; 11497c478bd9Sstevel@tonic-gate /* 11507c478bd9Sstevel@tonic-gate * If the new symbol is from a shared library and it is 11517c478bd9Sstevel@tonic-gate * associated with a SHT_NOBITS section then this symbol 11527c478bd9Sstevel@tonic-gate * originated from a tentative symbol. 11537c478bd9Sstevel@tonic-gate */ 1154635216b6SRod Evans if (((nsdflags & FLG_SY_SPECSEC) == 0) && (nfile == ET_DYN)) { 11557c478bd9Sstevel@tonic-gate isp = ifl->ifl_isdesc[nshndx]; 11567c478bd9Sstevel@tonic-gate if (isp && (isp->is_shdr->sh_type == SHT_NOBITS)) { 11577c478bd9Sstevel@tonic-gate column = SYM_TENTATIVE; 1158635216b6SRod Evans nsdflags |= FLG_SY_TENTSYM; 11597c478bd9Sstevel@tonic-gate } 11607c478bd9Sstevel@tonic-gate } 11617c478bd9Sstevel@tonic-gate } 11627c478bd9Sstevel@tonic-gate 11635aefb655Srie DBG_CALL(Dbg_syms_resolving(ofl, ndx, sdp->sd_name, row, column, 11645aefb655Srie osym, nsym, sdp, ifl)); 11657c478bd9Sstevel@tonic-gate 11667c478bd9Sstevel@tonic-gate /* 11677c478bd9Sstevel@tonic-gate * Record the input filename on the defined files list for possible 11687c478bd9Sstevel@tonic-gate * later diagnostics. The `sa_dfiles' list is used to maintain the list 11697c478bd9Sstevel@tonic-gate * of shared objects that define the same symbol. This list is only 11707c478bd9Sstevel@tonic-gate * generated when the -m option is in effect and is used to list 11717c478bd9Sstevel@tonic-gate * multiple (interposed) definitions of a symbol (refer to ldmap_out()). 11727c478bd9Sstevel@tonic-gate */ 11730bc07c75Srie if ((ofl->ofl_flags & FLG_OF_GENMAP) && (nsym->st_shndx != SHN_UNDEF) && 1174635216b6SRod Evans ((nsdflags & FLG_SY_SPECSEC) == 0)) 117557ef7aa9SRod Evans if (aplist_append(&sdp->sd_aux->sa_dfiles, ifl->ifl_name, 117657ef7aa9SRod Evans AL_CNT_SDP_DFILES) == NULL) 11777c478bd9Sstevel@tonic-gate return (S_ERROR); 11787c478bd9Sstevel@tonic-gate 11797c478bd9Sstevel@tonic-gate /* 11807c478bd9Sstevel@tonic-gate * Perform the required resolution. 11817c478bd9Sstevel@tonic-gate */ 1182635216b6SRod Evans Action[row][column](sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags); 11837c478bd9Sstevel@tonic-gate 11847c478bd9Sstevel@tonic-gate /* 118560758829Srie * Apply any visibility requirements. If a SINGLETON has been 118660758829Srie * established, make sure no symbol reduction indicators remain 118760758829Srie * associated with the symbol, and indicate that the symbol can not 118860758829Srie * be directly bound to. 118960758829Srie */ 119060758829Srie if ((oref == REF_REL_NEED) || (nfile == ET_REL)) { 119160758829Srie if ((vis == STV_EXPORTED) || (vis == STV_SINGLETON)) { 1192635216b6SRod Evans sdp->sd_flags &= ~MSK_SY_LOCAL; 119360758829Srie 119460758829Srie if (vis == STV_EXPORTED) 1195635216b6SRod Evans sdp->sd_flags |= FLG_SY_EXPORT; 119660758829Srie else { 1197635216b6SRod Evans sdp->sd_flags |= (FLG_SY_NDIR | FLG_SY_SINGLE); 119860758829Srie 119928bda19cSRod Evans if (sdp->sd_ref == REF_REL_NEED) { 120028bda19cSRod Evans ofl->ofl_flags1 |= 120128bda19cSRod Evans (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR); 120228bda19cSRod Evans } 120360758829Srie } 120460758829Srie } else if (vis == STV_PROTECTED) { 1205635216b6SRod Evans sdp->sd_flags |= FLG_SY_PROTECT; 120660758829Srie } else if ((vis == STV_INTERNAL) || (vis == STV_HIDDEN)) { 1207635216b6SRod Evans sdp->sd_flags |= FLG_SY_HIDDEN; 120860758829Srie } else if (vis == STV_ELIMINATE) { 1209635216b6SRod Evans sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM); 121060758829Srie } 121160758829Srie 121260758829Srie sdp->sd_sym->st_other = 121360758829Srie (sdp->sd_sym->st_other & ~MSK_SYM_VISIBILITY) | vis; 121460758829Srie } 121560758829Srie 121660758829Srie /* 12177c478bd9Sstevel@tonic-gate * If the symbol has been resolved to the new input file, and this is 12187c478bd9Sstevel@tonic-gate * a versioned relocatable object, then the version information of the 12197c478bd9Sstevel@tonic-gate * new symbol must be promoted to the versioning of the output file. 12207c478bd9Sstevel@tonic-gate */ 12217c478bd9Sstevel@tonic-gate if ((sdp->sd_file == ifl) && (nfile == ET_REL) && (ifl->ifl_versym) && 12220bc07c75Srie (nsym->st_shndx != SHN_UNDEF)) 12235aefb655Srie ld_vers_promote(sdp, ndx, ifl, ofl); 12247c478bd9Sstevel@tonic-gate 12257c478bd9Sstevel@tonic-gate /* 12267c478bd9Sstevel@tonic-gate * Determine whether a mapfile reference has been satisfied. Mapfile 12277c478bd9Sstevel@tonic-gate * symbol references augment symbols that should be contributed from 12287c478bd9Sstevel@tonic-gate * the relocatable objects used to build the output image. If a 12297c478bd9Sstevel@tonic-gate * relocatable object doesn't provide one of the mapfile symbol 12307c478bd9Sstevel@tonic-gate * references then somethings amiss, and will be flagged during symbol 12317c478bd9Sstevel@tonic-gate * validation. 12327c478bd9Sstevel@tonic-gate */ 12337c478bd9Sstevel@tonic-gate if ((nfile == ET_REL) && ((sdp->sd_flags & 12347c478bd9Sstevel@tonic-gate (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == FLG_SY_MAPREF)) { 12357c478bd9Sstevel@tonic-gate /* 12367c478bd9Sstevel@tonic-gate * Extern and parent references are satisfied by references from 12377c478bd9Sstevel@tonic-gate * a relocatable object. Note that we let *any* symbol type 12387c478bd9Sstevel@tonic-gate * satisfy this reference, to be as flexible as possible with 12397c478bd9Sstevel@tonic-gate * user written mapfiles. It could be questionable, for 12407c478bd9Sstevel@tonic-gate * example, if what a user expects to be an extern reference is 12417c478bd9Sstevel@tonic-gate * actually found to be a definition in a relocatable object. 12427c478bd9Sstevel@tonic-gate * 12437c478bd9Sstevel@tonic-gate * Any other mapfile reference (typically for versioning 12447c478bd9Sstevel@tonic-gate * information) simply augments a relocatables definition. 12457c478bd9Sstevel@tonic-gate */ 12467c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) || 12470bc07c75Srie ((sdp->sd_sym->st_shndx != SHN_UNDEF) && 12487c478bd9Sstevel@tonic-gate (sdp->sd_ref == REF_REL_NEED))) 12497c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_MAPUSED; 12507c478bd9Sstevel@tonic-gate } 12517c478bd9Sstevel@tonic-gate 125208278a5eSRod Evans /* 125308278a5eSRod Evans * Make sure any special symbol requirements are carried over. 125408278a5eSRod Evans */ 125508278a5eSRod Evans if ((osdflags & FLG_SY_CAP) || (nsdflags & FLG_SY_CAP)) 125608278a5eSRod Evans sdp->sd_flags |= FLG_SY_CAP; 125708278a5eSRod Evans 12585aefb655Srie DBG_CALL(Dbg_syms_resolved(ofl, sdp)); 12597c478bd9Sstevel@tonic-gate 12607c478bd9Sstevel@tonic-gate return (1); 12617c478bd9Sstevel@tonic-gate } 1262