1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1988 AT&T 24*7c478bd9Sstevel@tonic-gate * All Rights Reserved 25*7c478bd9Sstevel@tonic-gate * 26*7c478bd9Sstevel@tonic-gate * 27*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * Symbol table management routines 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate #include <stdio.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate #include "debug.h" 38*7c478bd9Sstevel@tonic-gate #include "msg.h" 39*7c478bd9Sstevel@tonic-gate #include "_libld.h" 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate /* 42*7c478bd9Sstevel@tonic-gate * AVL tree comparator function: 43*7c478bd9Sstevel@tonic-gate * 44*7c478bd9Sstevel@tonic-gate * The primary key is the 'sa_hashval' with a secondary 45*7c478bd9Sstevel@tonic-gate * key of the symbol name itself. 46*7c478bd9Sstevel@tonic-gate */ 47*7c478bd9Sstevel@tonic-gate int 48*7c478bd9Sstevel@tonic-gate sym_avl_comp(const void *elem1, const void *elem2) 49*7c478bd9Sstevel@tonic-gate { 50*7c478bd9Sstevel@tonic-gate int res; 51*7c478bd9Sstevel@tonic-gate Sym_avlnode *sav1 = (Sym_avlnode *)elem1; 52*7c478bd9Sstevel@tonic-gate Sym_avlnode *sav2 = (Sym_avlnode *)elem2; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate res = sav1->sav_hash - sav2->sav_hash; 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate if (res < 0) 57*7c478bd9Sstevel@tonic-gate return (-1); 58*7c478bd9Sstevel@tonic-gate if (res > 0) 59*7c478bd9Sstevel@tonic-gate return (1); 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate /* 62*7c478bd9Sstevel@tonic-gate * Hash is equal - now compare name 63*7c478bd9Sstevel@tonic-gate */ 64*7c478bd9Sstevel@tonic-gate res = strcmp(sav1->sav_name, sav2->sav_name); 65*7c478bd9Sstevel@tonic-gate if (res == 0) 66*7c478bd9Sstevel@tonic-gate return (0); 67*7c478bd9Sstevel@tonic-gate if (res > 0) 68*7c478bd9Sstevel@tonic-gate return (1); 69*7c478bd9Sstevel@tonic-gate return (-1); 70*7c478bd9Sstevel@tonic-gate } 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate /* 74*7c478bd9Sstevel@tonic-gate * Focal point for verifying symbol names. 75*7c478bd9Sstevel@tonic-gate */ 76*7c478bd9Sstevel@tonic-gate const char * 77*7c478bd9Sstevel@tonic-gate string(Ifl_desc *ifl, Sym *sym, const char *strs, size_t strsize, int symndx, 78*7c478bd9Sstevel@tonic-gate Word shndx, const char *symsecname, const char *strsecname, Word * flags) 79*7c478bd9Sstevel@tonic-gate { 80*7c478bd9Sstevel@tonic-gate const char *regname; 81*7c478bd9Sstevel@tonic-gate Word name = sym->st_name; 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate if (name) { 84*7c478bd9Sstevel@tonic-gate if ((ifl->ifl_flags & FLG_IF_HSTRTAB) == 0) { 85*7c478bd9Sstevel@tonic-gate eprintf(ERR_FATAL, MSG_INTL(MSG_FIL_NOSTRTABLE), 86*7c478bd9Sstevel@tonic-gate ifl->ifl_name, symsecname, symndx, EC_XWORD(name)); 87*7c478bd9Sstevel@tonic-gate return (0); 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate if (name >= (Word)strsize) { 90*7c478bd9Sstevel@tonic-gate eprintf(ERR_FATAL, MSG_INTL(MSG_FIL_EXCSTRTABLE), 91*7c478bd9Sstevel@tonic-gate ifl->ifl_name, symsecname, symndx, EC_XWORD(name), 92*7c478bd9Sstevel@tonic-gate strsecname, EC_XWORD(strsize)); 93*7c478bd9Sstevel@tonic-gate return (0); 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate /* 98*7c478bd9Sstevel@tonic-gate * Determine if we're dealing with a register and if so validate it. 99*7c478bd9Sstevel@tonic-gate * If it's a scratch register, a fabricated name will be returned. 100*7c478bd9Sstevel@tonic-gate */ 101*7c478bd9Sstevel@tonic-gate if ((regname = is_regsym(ifl, sym, strs, symndx, shndx, 102*7c478bd9Sstevel@tonic-gate symsecname, flags)) == (const char *)S_ERROR) { 103*7c478bd9Sstevel@tonic-gate return (0); 104*7c478bd9Sstevel@tonic-gate } 105*7c478bd9Sstevel@tonic-gate if (regname) 106*7c478bd9Sstevel@tonic-gate return (regname); 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate /* 109*7c478bd9Sstevel@tonic-gate * If this isn't a register, but we have a global symbol with a null 110*7c478bd9Sstevel@tonic-gate * name, we're not going to be able to hash this, search for it, or 111*7c478bd9Sstevel@tonic-gate * do anything interesting. However, we've been accepting a symbol of 112*7c478bd9Sstevel@tonic-gate * this kind for ages now, so give the user a warning (rather than a 113*7c478bd9Sstevel@tonic-gate * fatal error), just in case this instance exists somewhere in the 114*7c478bd9Sstevel@tonic-gate * world and hasn't, as yet, been a problem. 115*7c478bd9Sstevel@tonic-gate */ 116*7c478bd9Sstevel@tonic-gate if ((name == 0) && (ELF_ST_BIND(sym->st_info) != STB_LOCAL)) { 117*7c478bd9Sstevel@tonic-gate eprintf(ERR_WARNING, MSG_INTL(MSG_FIL_NONAMESYM), 118*7c478bd9Sstevel@tonic-gate ifl->ifl_name, symsecname, symndx, EC_XWORD(name)); 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate return (strs + name); 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate /* 124*7c478bd9Sstevel@tonic-gate * Shared objects can be built that define specific symbols that can not be 125*7c478bd9Sstevel@tonic-gate * directly bound to. These objects have a syminfo section (and an associated 126*7c478bd9Sstevel@tonic-gate * DF_1_NODIRECT dynamic flags entry). Scan this table looking for symbols 127*7c478bd9Sstevel@tonic-gate * that can't be bound to directly, and if this files symbol is presently 128*7c478bd9Sstevel@tonic-gate * referenced, mark it so that we don't directly bind to it. 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate uintptr_t 131*7c478bd9Sstevel@tonic-gate sym_nodirect(Is_desc * isp, Ifl_desc * ifl, Ofl_desc * ofl) 132*7c478bd9Sstevel@tonic-gate { 133*7c478bd9Sstevel@tonic-gate Shdr *sifshdr, *symshdr; 134*7c478bd9Sstevel@tonic-gate Syminfo *sifdata; 135*7c478bd9Sstevel@tonic-gate Sym *symdata; 136*7c478bd9Sstevel@tonic-gate char *strdata; 137*7c478bd9Sstevel@tonic-gate ulong_t cnt, _cnt; 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate /* 140*7c478bd9Sstevel@tonic-gate * Get the syminfo data, and determine the number of entries. 141*7c478bd9Sstevel@tonic-gate */ 142*7c478bd9Sstevel@tonic-gate sifshdr = isp->is_shdr; 143*7c478bd9Sstevel@tonic-gate sifdata = (Syminfo *)isp->is_indata->d_buf; 144*7c478bd9Sstevel@tonic-gate cnt = sifshdr->sh_size / sifshdr->sh_entsize; 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate /* 147*7c478bd9Sstevel@tonic-gate * Get the associated symbol table. 148*7c478bd9Sstevel@tonic-gate */ 149*7c478bd9Sstevel@tonic-gate symshdr = ifl->ifl_isdesc[sifshdr->sh_link]->is_shdr; 150*7c478bd9Sstevel@tonic-gate symdata = ifl->ifl_isdesc[sifshdr->sh_link]->is_indata->d_buf; 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate /* 153*7c478bd9Sstevel@tonic-gate * Get the string table associated with the symbol table. 154*7c478bd9Sstevel@tonic-gate */ 155*7c478bd9Sstevel@tonic-gate strdata = ifl->ifl_isdesc[symshdr->sh_link]->is_indata->d_buf; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * Traverse the syminfo data for symbols that can't be directly 159*7c478bd9Sstevel@tonic-gate * bound to. 160*7c478bd9Sstevel@tonic-gate */ 161*7c478bd9Sstevel@tonic-gate for (_cnt = 1, sifdata++; _cnt < cnt; _cnt++, sifdata++) { 162*7c478bd9Sstevel@tonic-gate Sym *sym; 163*7c478bd9Sstevel@tonic-gate char *str; 164*7c478bd9Sstevel@tonic-gate Sym_desc *sdp; 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate if (((sifdata->si_flags & SYMINFO_FLG_NOEXTDIRECT) == 0) || 167*7c478bd9Sstevel@tonic-gate (sifdata->si_boundto < SYMINFO_BT_LOWRESERVE)) 168*7c478bd9Sstevel@tonic-gate continue; 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate sym = (Sym *)(symdata + _cnt); 171*7c478bd9Sstevel@tonic-gate str = (char *)(strdata + sym->st_name); 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate if (sdp = sym_find(str, SYM_NOHASH, 0, ofl)) { 174*7c478bd9Sstevel@tonic-gate if (ifl != sdp->sd_file) 175*7c478bd9Sstevel@tonic-gate continue; 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 &= ~FLG_SY1_DIR; 178*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_NDIR; 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate return (0); 182*7c478bd9Sstevel@tonic-gate } 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate /* 185*7c478bd9Sstevel@tonic-gate * If, during symbol processing, it is necessary to update a local symbols 186*7c478bd9Sstevel@tonic-gate * contents before we have generated the symbol tables in the output image, 187*7c478bd9Sstevel@tonic-gate * create a new symbol structure and copy the original symbol contents. While 188*7c478bd9Sstevel@tonic-gate * we are processing the input files, their local symbols are part of the 189*7c478bd9Sstevel@tonic-gate * read-only mapped image. Commonly, these symbols are copied to the new output 190*7c478bd9Sstevel@tonic-gate * file image and then updated to reflect their new address and any change in 191*7c478bd9Sstevel@tonic-gate * attributes. However, sometimes during relocation counting, it is necessary 192*7c478bd9Sstevel@tonic-gate * to adjust the symbols information. This routine provides for the generation 193*7c478bd9Sstevel@tonic-gate * of a new symbol image so that this update can be performed. 194*7c478bd9Sstevel@tonic-gate * All global symbols are copied to an internal symbol table to improve locality 195*7c478bd9Sstevel@tonic-gate * of reference and hence performance, and thus this copying is not necessary. 196*7c478bd9Sstevel@tonic-gate */ 197*7c478bd9Sstevel@tonic-gate uintptr_t 198*7c478bd9Sstevel@tonic-gate sym_copy(Sym_desc *sdp) 199*7c478bd9Sstevel@tonic-gate { 200*7c478bd9Sstevel@tonic-gate Sym *nsym; 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate if (sdp->sd_flags & FLG_SY_CLEAN) { 203*7c478bd9Sstevel@tonic-gate if ((nsym = libld_malloc(sizeof (Sym))) == 0) 204*7c478bd9Sstevel@tonic-gate return (S_ERROR); 205*7c478bd9Sstevel@tonic-gate *nsym = *(sdp->sd_sym); 206*7c478bd9Sstevel@tonic-gate sdp->sd_sym = nsym; 207*7c478bd9Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_CLEAN; 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate return (1); 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate /* 213*7c478bd9Sstevel@tonic-gate * Finds a given name in the link editors internal symbol table. If no 214*7c478bd9Sstevel@tonic-gate * hash value is specified it is calculated. A pointer to the located 215*7c478bd9Sstevel@tonic-gate * Sym_desc entry is returned, or NULL if the symbol is not found. 216*7c478bd9Sstevel@tonic-gate */ 217*7c478bd9Sstevel@tonic-gate Sym_desc * 218*7c478bd9Sstevel@tonic-gate sym_find(const char *name, Word hash, avl_index_t *where, Ofl_desc *ofl) 219*7c478bd9Sstevel@tonic-gate { 220*7c478bd9Sstevel@tonic-gate Sym_avlnode qsav; 221*7c478bd9Sstevel@tonic-gate Sym_avlnode *sav; 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate if (hash == SYM_NOHASH) 224*7c478bd9Sstevel@tonic-gate /* LINTED */ 225*7c478bd9Sstevel@tonic-gate hash = (Word)elf_hash((const char *)name); 226*7c478bd9Sstevel@tonic-gate qsav.sav_hash = hash; 227*7c478bd9Sstevel@tonic-gate qsav.sav_name = name; 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate /* 230*7c478bd9Sstevel@tonic-gate * Perform search for symbol in AVL tree. Note that the 'where' field 231*7c478bd9Sstevel@tonic-gate * is passed in from the caller. If a 'where' is present, it can be 232*7c478bd9Sstevel@tonic-gate * used in subsequent 'sym_enter()' calls if required. 233*7c478bd9Sstevel@tonic-gate */ 234*7c478bd9Sstevel@tonic-gate sav = avl_find(&ofl->ofl_symavl, &qsav, where); 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate /* 237*7c478bd9Sstevel@tonic-gate * If symbol was not found in the avl tree, return null to show that. 238*7c478bd9Sstevel@tonic-gate */ 239*7c478bd9Sstevel@tonic-gate if (sav == 0) 240*7c478bd9Sstevel@tonic-gate return (0); 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate /* 243*7c478bd9Sstevel@tonic-gate * Return symbol found. 244*7c478bd9Sstevel@tonic-gate */ 245*7c478bd9Sstevel@tonic-gate return (sav->sav_symdesc); 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate /* 250*7c478bd9Sstevel@tonic-gate * Enter a new symbol into the link editors internal symbol table. 251*7c478bd9Sstevel@tonic-gate * If the symbol is from an input file, information regarding the input file 252*7c478bd9Sstevel@tonic-gate * and input section is also recorded. Otherwise (file == NULL) the symbol 253*7c478bd9Sstevel@tonic-gate * has been internally generated (ie. _etext, _edata, etc.). 254*7c478bd9Sstevel@tonic-gate */ 255*7c478bd9Sstevel@tonic-gate Sym_desc * 256*7c478bd9Sstevel@tonic-gate sym_enter(const char *name, Sym *osym, Word hash, Ifl_desc *ifl, Ofl_desc *ofl, 257*7c478bd9Sstevel@tonic-gate Word ndx, Word shndx, Word sdflags, Half sdflags1, avl_index_t *where) 258*7c478bd9Sstevel@tonic-gate { 259*7c478bd9Sstevel@tonic-gate Sym_desc *sdp; 260*7c478bd9Sstevel@tonic-gate Sym_aux *sap; 261*7c478bd9Sstevel@tonic-gate Sym_avlnode *savl; 262*7c478bd9Sstevel@tonic-gate char *_name; 263*7c478bd9Sstevel@tonic-gate Sym *nsym; 264*7c478bd9Sstevel@tonic-gate Half etype; 265*7c478bd9Sstevel@tonic-gate Ehdr *ehdr; 266*7c478bd9Sstevel@tonic-gate avl_index_t _where; 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate /* 269*7c478bd9Sstevel@tonic-gate * Establish the file type. 270*7c478bd9Sstevel@tonic-gate */ 271*7c478bd9Sstevel@tonic-gate if (ifl) 272*7c478bd9Sstevel@tonic-gate etype = ifl->ifl_ehdr->e_type; 273*7c478bd9Sstevel@tonic-gate else 274*7c478bd9Sstevel@tonic-gate etype = ET_NONE; 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate ofl->ofl_entercnt++; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate /* 279*7c478bd9Sstevel@tonic-gate * Allocate a Sym Descriptor, Auxiliary Descriptor, and a Sym AVLNode - 280*7c478bd9Sstevel@tonic-gate * contiguously. 281*7c478bd9Sstevel@tonic-gate */ 282*7c478bd9Sstevel@tonic-gate if ((savl = libld_calloc(sizeof (Sym_avlnode) + sizeof (Sym_desc) + 283*7c478bd9Sstevel@tonic-gate sizeof (Sym_aux), 1)) == 0) 284*7c478bd9Sstevel@tonic-gate return ((Sym_desc *)S_ERROR); 285*7c478bd9Sstevel@tonic-gate sdp = (Sym_desc *)((uintptr_t)savl + sizeof (Sym_avlnode)); 286*7c478bd9Sstevel@tonic-gate sap = (Sym_aux *)((uintptr_t)sdp + sizeof (Sym_desc)); 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate savl->sav_symdesc = sdp; 289*7c478bd9Sstevel@tonic-gate sdp->sd_file = ifl; 290*7c478bd9Sstevel@tonic-gate sdp->sd_aux = sap; 291*7c478bd9Sstevel@tonic-gate savl->sav_hash = sap->sa_hash = hash; 292*7c478bd9Sstevel@tonic-gate 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate /* 295*7c478bd9Sstevel@tonic-gate * Copy the symbol table entry from the input file into the internal 296*7c478bd9Sstevel@tonic-gate * entry and have the symbol descriptor use it. 297*7c478bd9Sstevel@tonic-gate */ 298*7c478bd9Sstevel@tonic-gate sdp->sd_sym = nsym = &sap->sa_sym; 299*7c478bd9Sstevel@tonic-gate *nsym = *osym; 300*7c478bd9Sstevel@tonic-gate sdp->sd_shndx = shndx; 301*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= sdflags; 302*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= sdflags1; 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate if ((_name = libld_malloc(strlen(name) + 1)) == 0) 305*7c478bd9Sstevel@tonic-gate return ((Sym_desc *)S_ERROR); 306*7c478bd9Sstevel@tonic-gate savl->sav_name = sdp->sd_name = (const char *)strcpy(_name, name); 307*7c478bd9Sstevel@tonic-gate 308*7c478bd9Sstevel@tonic-gate /* 309*7c478bd9Sstevel@tonic-gate * Enter Symbol in AVL tree. 310*7c478bd9Sstevel@tonic-gate */ 311*7c478bd9Sstevel@tonic-gate if (where == 0) { 312*7c478bd9Sstevel@tonic-gate /* LINTED */ 313*7c478bd9Sstevel@tonic-gate Sym_avlnode *_savl; 314*7c478bd9Sstevel@tonic-gate /* 315*7c478bd9Sstevel@tonic-gate * If a previous sym_find() hasn't initialized 'where' do it 316*7c478bd9Sstevel@tonic-gate * now. 317*7c478bd9Sstevel@tonic-gate */ 318*7c478bd9Sstevel@tonic-gate where = &_where; 319*7c478bd9Sstevel@tonic-gate _savl = avl_find(&ofl->ofl_symavl, savl, where); 320*7c478bd9Sstevel@tonic-gate assert(_savl == 0); 321*7c478bd9Sstevel@tonic-gate } 322*7c478bd9Sstevel@tonic-gate avl_insert(&ofl->ofl_symavl, savl, *where); 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate /* 325*7c478bd9Sstevel@tonic-gate * Record the section index. This is possible because the 326*7c478bd9Sstevel@tonic-gate * `ifl_isdesc' table is filled before we start symbol processing. 327*7c478bd9Sstevel@tonic-gate */ 328*7c478bd9Sstevel@tonic-gate if ((sdflags & FLG_SY_SPECSEC) || (shndx == SHN_UNDEF)) 329*7c478bd9Sstevel@tonic-gate sdp->sd_isc = NULL; 330*7c478bd9Sstevel@tonic-gate else { 331*7c478bd9Sstevel@tonic-gate sdp->sd_isc = ifl->ifl_isdesc[shndx]; 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate /* 334*7c478bd9Sstevel@tonic-gate * If this symbol is from a relocatable object, make sure that 335*7c478bd9Sstevel@tonic-gate * it is still associated with a section. For example, an 336*7c478bd9Sstevel@tonic-gate * unknown section type (SHT_NULL) would have been rejected on 337*7c478bd9Sstevel@tonic-gate * input with a warning. Here, we make the use of the symbol 338*7c478bd9Sstevel@tonic-gate * fatal. A symbol descriptor is still returned, so that the 339*7c478bd9Sstevel@tonic-gate * caller can continue processing all symbols, and hence flush 340*7c478bd9Sstevel@tonic-gate * out as many error conditions as possible. 341*7c478bd9Sstevel@tonic-gate */ 342*7c478bd9Sstevel@tonic-gate if ((etype == ET_REL) && (sdp->sd_isc == 0)) { 343*7c478bd9Sstevel@tonic-gate eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_INVSEC), name, 344*7c478bd9Sstevel@tonic-gate ifl->ifl_name, EC_XWORD(shndx)); 345*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_FATAL; 346*7c478bd9Sstevel@tonic-gate return (sdp); 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate } 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate /* 351*7c478bd9Sstevel@tonic-gate * Mark any COMMON symbols as 'tentative'. 352*7c478bd9Sstevel@tonic-gate */ 353*7c478bd9Sstevel@tonic-gate if ((sdflags & FLG_SY_SPECSEC) && (shndx == SHN_COMMON)) 354*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_TENTSYM; 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate /* 357*7c478bd9Sstevel@tonic-gate * Establish the symbols reference & visibility. 358*7c478bd9Sstevel@tonic-gate */ 359*7c478bd9Sstevel@tonic-gate if ((etype == ET_NONE) || (etype == ET_REL)) { 360*7c478bd9Sstevel@tonic-gate sdp->sd_ref = REF_REL_NEED; 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate /* 363*7c478bd9Sstevel@tonic-gate * Under -Bnodirect, all exported interfaces are tagged to 364*7c478bd9Sstevel@tonic-gate * prevent direct binding to them. 365*7c478bd9Sstevel@tonic-gate */ 366*7c478bd9Sstevel@tonic-gate if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) && (shndx != SHN_UNDEF)) 367*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_NDIR; 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate } else { 370*7c478bd9Sstevel@tonic-gate sdp->sd_ref = REF_DYN_SEEN; 371*7c478bd9Sstevel@tonic-gate 372*7c478bd9Sstevel@tonic-gate /* 373*7c478bd9Sstevel@tonic-gate * Record the binding file for this symbol in the sa_bindto 374*7c478bd9Sstevel@tonic-gate * field. If this symbol is ever overridden by a REF_REL_NEED 375*7c478bd9Sstevel@tonic-gate * definition, sa_bindto is used when building a 'translator'. 376*7c478bd9Sstevel@tonic-gate */ 377*7c478bd9Sstevel@tonic-gate if (shndx != SHN_UNDEF) 378*7c478bd9Sstevel@tonic-gate sdp->sd_aux->sa_bindto = ifl; 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate /* 381*7c478bd9Sstevel@tonic-gate * If this is a protected symbol, mark it. 382*7c478bd9Sstevel@tonic-gate */ 383*7c478bd9Sstevel@tonic-gate if (ELF_ST_VISIBILITY(nsym->st_other) == STV_PROTECTED) 384*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_PROT; 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate /* 387*7c478bd9Sstevel@tonic-gate * Mask out any visibility info from a DYN symbol. 388*7c478bd9Sstevel@tonic-gate */ 389*7c478bd9Sstevel@tonic-gate nsym->st_other = nsym->st_other & ~MSK_SYM_VISIBILITY; 390*7c478bd9Sstevel@tonic-gate 391*7c478bd9Sstevel@tonic-gate /* 392*7c478bd9Sstevel@tonic-gate * If the new symbol is from a shared library and it 393*7c478bd9Sstevel@tonic-gate * is associated with a SHT_NOBITS section then this 394*7c478bd9Sstevel@tonic-gate * symbol originated from a tentative symbol. 395*7c478bd9Sstevel@tonic-gate */ 396*7c478bd9Sstevel@tonic-gate if (sdp->sd_isc && 397*7c478bd9Sstevel@tonic-gate (sdp->sd_isc->is_shdr->sh_type == SHT_NOBITS)) 398*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_TENTSYM; 399*7c478bd9Sstevel@tonic-gate } 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate /* 402*7c478bd9Sstevel@tonic-gate * Reclassify any SHN_SUNW_IGNORE symbols to SHN_UNDEF so as to 403*7c478bd9Sstevel@tonic-gate * simplify fucture processing. 404*7c478bd9Sstevel@tonic-gate */ 405*7c478bd9Sstevel@tonic-gate if (shndx == SHN_SUNW_IGNORE) { 406*7c478bd9Sstevel@tonic-gate sdp->sd_shndx = shndx = SHN_UNDEF; 407*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_REDUCED; 408*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= 409*7c478bd9Sstevel@tonic-gate (FLG_SY1_IGNORE | FLG_SY1_LOCL | FLG_SY1_ELIM); 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate /* 413*7c478bd9Sstevel@tonic-gate * If this is an undefined, or common symbol from a relocatable object 414*7c478bd9Sstevel@tonic-gate * determine whether it is a global or weak reference (see build_osym(), 415*7c478bd9Sstevel@tonic-gate * where REF_DYN_NEED definitions are returned back to undefines). 416*7c478bd9Sstevel@tonic-gate */ 417*7c478bd9Sstevel@tonic-gate if ((etype == ET_REL) && ((shndx == SHN_UNDEF) || 418*7c478bd9Sstevel@tonic-gate ((sdflags & FLG_SY_SPECSEC) && (shndx == SHN_COMMON))) && 419*7c478bd9Sstevel@tonic-gate (ELF_ST_BIND(nsym->st_info) == STB_GLOBAL)) 420*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_GLOBREF; 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate /* 423*7c478bd9Sstevel@tonic-gate * Record the input filename on the referenced or defined files list 424*7c478bd9Sstevel@tonic-gate * for possible later diagnostics. The `sa_rfile' pointer contains the 425*7c478bd9Sstevel@tonic-gate * name of the file that first referenced this symbol and is used to 426*7c478bd9Sstevel@tonic-gate * generate undefined symbol diagnostics (refer to sym_undef_entry()). 427*7c478bd9Sstevel@tonic-gate * Note that this entry can be overridden if a reference from a 428*7c478bd9Sstevel@tonic-gate * relocatable object is found after a reference from a shared object 429*7c478bd9Sstevel@tonic-gate * (refer to sym_override()). 430*7c478bd9Sstevel@tonic-gate * The `sa_dfiles' list is used to maintain the list of files that 431*7c478bd9Sstevel@tonic-gate * define the same symbol. This list can be used for two reasons: 432*7c478bd9Sstevel@tonic-gate * 433*7c478bd9Sstevel@tonic-gate * o To save the first definition of a symbol that is not available 434*7c478bd9Sstevel@tonic-gate * for this link-edit. 435*7c478bd9Sstevel@tonic-gate * 436*7c478bd9Sstevel@tonic-gate * o To save all definitions of a symbol when the -m option is in 437*7c478bd9Sstevel@tonic-gate * effect. This is optional as it is used to list multiple 438*7c478bd9Sstevel@tonic-gate * (interposed) definitions of a symbol (refer to ldmap_out()), 439*7c478bd9Sstevel@tonic-gate * and can be quite expensive. 440*7c478bd9Sstevel@tonic-gate */ 441*7c478bd9Sstevel@tonic-gate if (shndx == SHN_UNDEF) { 442*7c478bd9Sstevel@tonic-gate sap->sa_rfile = ifl->ifl_name; 443*7c478bd9Sstevel@tonic-gate } else { 444*7c478bd9Sstevel@tonic-gate if (sdp->sd_ref == REF_DYN_SEEN) { 445*7c478bd9Sstevel@tonic-gate /* 446*7c478bd9Sstevel@tonic-gate * A symbol is determined to be unavailable if it 447*7c478bd9Sstevel@tonic-gate * belongs to a version of a shared object that this 448*7c478bd9Sstevel@tonic-gate * user does not wish to use, or if it belongs to an 449*7c478bd9Sstevel@tonic-gate * implicit shared object. 450*7c478bd9Sstevel@tonic-gate */ 451*7c478bd9Sstevel@tonic-gate if (ifl->ifl_vercnt) { 452*7c478bd9Sstevel@tonic-gate Ver_index * vip; 453*7c478bd9Sstevel@tonic-gate Half vndx = ifl->ifl_versym[ndx]; 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate sap->sa_dverndx = vndx; 456*7c478bd9Sstevel@tonic-gate vip = &ifl->ifl_verndx[vndx]; 457*7c478bd9Sstevel@tonic-gate if (!(vip->vi_flags & FLG_VER_AVAIL)) { 458*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_NOTAVAIL; 459*7c478bd9Sstevel@tonic-gate sap->sa_vfile = ifl->ifl_name; 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate } 462*7c478bd9Sstevel@tonic-gate if (!(ifl->ifl_flags & FLG_IF_NEEDED)) 463*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_NOTAVAIL; 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate } else if (etype == ET_REL) { 466*7c478bd9Sstevel@tonic-gate /* 467*7c478bd9Sstevel@tonic-gate * If this symbol has been obtained from a versioned 468*7c478bd9Sstevel@tonic-gate * input relocatable object then the new symbol must be 469*7c478bd9Sstevel@tonic-gate * promoted to the versioning of the output file. 470*7c478bd9Sstevel@tonic-gate */ 471*7c478bd9Sstevel@tonic-gate if (ifl->ifl_versym) 472*7c478bd9Sstevel@tonic-gate vers_promote(sdp, ndx, ifl, ofl); 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate if ((ofl->ofl_flags & FLG_OF_GENMAP) && 476*7c478bd9Sstevel@tonic-gate ((sdflags & FLG_SY_SPECSEC) == 0)) 477*7c478bd9Sstevel@tonic-gate if (list_appendc(&sap->sa_dfiles, ifl->ifl_name) == 0) 478*7c478bd9Sstevel@tonic-gate return ((Sym_desc *)S_ERROR); 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate if (sdp->sd_file) 482*7c478bd9Sstevel@tonic-gate ehdr = sdp->sd_file->ifl_ehdr; 483*7c478bd9Sstevel@tonic-gate else 484*7c478bd9Sstevel@tonic-gate ehdr = &def_ehdr; 485*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_entered(ehdr, nsym, sdp)); 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate return (sdp); 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate /* 491*7c478bd9Sstevel@tonic-gate * Add a special symbol to the symbol table. Takes special symbol name with 492*7c478bd9Sstevel@tonic-gate * and without underscores. This routine is called, after all other symbol 493*7c478bd9Sstevel@tonic-gate * resolution has completed, to generate a reserved absolute symbol (the 494*7c478bd9Sstevel@tonic-gate * underscore version). Special symbols are updated with the appropriate 495*7c478bd9Sstevel@tonic-gate * values in sym_update(). If the user has already defined this symbol 496*7c478bd9Sstevel@tonic-gate * issue a warning and leave the symbol as is. If the non-underscore symbol 497*7c478bd9Sstevel@tonic-gate * is referenced then turn it into a weak alias of the underscored symbol. 498*7c478bd9Sstevel@tonic-gate * 499*7c478bd9Sstevel@tonic-gate * If this is a global symbol, and it hasn't explicitly been defined as being 500*7c478bd9Sstevel@tonic-gate * directly bound to, indicate that it can't be directly bound to. 501*7c478bd9Sstevel@tonic-gate * Historically, most special symbols only have meaning to the object in which 502*7c478bd9Sstevel@tonic-gate * they exist, however, they've always been global. To insure compatibility 503*7c478bd9Sstevel@tonic-gate * with any unexpected use presently in effect, insure these symbols don't get 504*7c478bd9Sstevel@tonic-gate * directly bound to. Note, that establishing this state here isn't sufficient 505*7c478bd9Sstevel@tonic-gate * to create a syminfo table, only if a syminfo table is being created by some 506*7c478bd9Sstevel@tonic-gate * other symbol directives will the nodirect binding be recorded. This insures 507*7c478bd9Sstevel@tonic-gate * we don't create syminfo sections for all objects we create, as this might add 508*7c478bd9Sstevel@tonic-gate * unnecessary bloat to users who haven't explicitly requested extra symbol 509*7c478bd9Sstevel@tonic-gate * information. 510*7c478bd9Sstevel@tonic-gate */ 511*7c478bd9Sstevel@tonic-gate static uintptr_t 512*7c478bd9Sstevel@tonic-gate sym_add_spec(const char *name, const char *uname, Word sdaux_id, 513*7c478bd9Sstevel@tonic-gate Half flags1, Ofl_desc *ofl) 514*7c478bd9Sstevel@tonic-gate { 515*7c478bd9Sstevel@tonic-gate Sym_desc *sdp; 516*7c478bd9Sstevel@tonic-gate Sym_desc *usdp; 517*7c478bd9Sstevel@tonic-gate Sym *sym; 518*7c478bd9Sstevel@tonic-gate Word hash; 519*7c478bd9Sstevel@tonic-gate avl_index_t where; 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate /* LINTED */ 522*7c478bd9Sstevel@tonic-gate hash = (Word)elf_hash(uname); 523*7c478bd9Sstevel@tonic-gate if (usdp = sym_find(uname, hash, &where, ofl)) { 524*7c478bd9Sstevel@tonic-gate /* 525*7c478bd9Sstevel@tonic-gate * If the underscore symbol exists and is undefined, or was 526*7c478bd9Sstevel@tonic-gate * defined in a shared library, convert it to a local symbol. 527*7c478bd9Sstevel@tonic-gate * Otherwise leave it as is and warn the user. 528*7c478bd9Sstevel@tonic-gate */ 529*7c478bd9Sstevel@tonic-gate if ((usdp->sd_shndx == SHN_UNDEF) || 530*7c478bd9Sstevel@tonic-gate (usdp->sd_ref != REF_REL_NEED)) { 531*7c478bd9Sstevel@tonic-gate usdp->sd_ref = REF_REL_NEED; 532*7c478bd9Sstevel@tonic-gate usdp->sd_shndx = usdp->sd_sym->st_shndx = SHN_ABS; 533*7c478bd9Sstevel@tonic-gate usdp->sd_flags |= FLG_SY_SPECSEC; 534*7c478bd9Sstevel@tonic-gate usdp->sd_sym->st_info = 535*7c478bd9Sstevel@tonic-gate ELF_ST_INFO(STB_GLOBAL, STT_OBJECT); 536*7c478bd9Sstevel@tonic-gate usdp->sd_isc = NULL; 537*7c478bd9Sstevel@tonic-gate usdp->sd_sym->st_size = 0; 538*7c478bd9Sstevel@tonic-gate usdp->sd_sym->st_value = 0; 539*7c478bd9Sstevel@tonic-gate /* LINTED */ 540*7c478bd9Sstevel@tonic-gate usdp->sd_aux->sa_symspec = (Half)sdaux_id; 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate /* 543*7c478bd9Sstevel@tonic-gate * If a user hasn't specifically indicated the scope of 544*7c478bd9Sstevel@tonic-gate * this symbol be made local then leave it as global 545*7c478bd9Sstevel@tonic-gate * (ie. prevent automatic scoping). 546*7c478bd9Sstevel@tonic-gate */ 547*7c478bd9Sstevel@tonic-gate if (!(usdp->sd_flags1 & FLG_SY1_LOCL) && 548*7c478bd9Sstevel@tonic-gate (flags1 & FLG_SY1_GLOB)) { 549*7c478bd9Sstevel@tonic-gate usdp->sd_aux->sa_overndx = VER_NDX_GLOBAL; 550*7c478bd9Sstevel@tonic-gate if ((usdp->sd_flags1 & FLG_SY1_DIR) == 0) 551*7c478bd9Sstevel@tonic-gate usdp->sd_flags1 |= FLG_SY1_NDIR; 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate usdp->sd_flags1 |= flags1; 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate /* 556*7c478bd9Sstevel@tonic-gate * If the reference originated from a mapfile insure 557*7c478bd9Sstevel@tonic-gate * we mark the symbol as used. 558*7c478bd9Sstevel@tonic-gate */ 559*7c478bd9Sstevel@tonic-gate if (usdp->sd_flags & FLG_SY_MAPREF) 560*7c478bd9Sstevel@tonic-gate usdp->sd_flags |= FLG_SY_MAPUSED; 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_updated((ofl->ofl_ehdr) ? 563*7c478bd9Sstevel@tonic-gate ofl->ofl_ehdr : &def_ehdr, usdp, uname)); 564*7c478bd9Sstevel@tonic-gate } else 565*7c478bd9Sstevel@tonic-gate eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_RESERVE), uname, 566*7c478bd9Sstevel@tonic-gate usdp->sd_file->ifl_name); 567*7c478bd9Sstevel@tonic-gate } else { 568*7c478bd9Sstevel@tonic-gate /* 569*7c478bd9Sstevel@tonic-gate * If the symbol does not exist create it. 570*7c478bd9Sstevel@tonic-gate */ 571*7c478bd9Sstevel@tonic-gate if ((sym = libld_calloc(sizeof (Sym), 1)) == 0) 572*7c478bd9Sstevel@tonic-gate return (S_ERROR); 573*7c478bd9Sstevel@tonic-gate sym->st_shndx = SHN_ABS; 574*7c478bd9Sstevel@tonic-gate sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT); 575*7c478bd9Sstevel@tonic-gate sym->st_size = 0; 576*7c478bd9Sstevel@tonic-gate sym->st_value = 0; 577*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_created(uname)); 578*7c478bd9Sstevel@tonic-gate if ((usdp = sym_enter(uname, sym, hash, (Ifl_desc *)NULL, 579*7c478bd9Sstevel@tonic-gate ofl, 0, SHN_ABS, FLG_SY_SPECSEC, 0, &where)) == 580*7c478bd9Sstevel@tonic-gate (Sym_desc *)S_ERROR) 581*7c478bd9Sstevel@tonic-gate return (S_ERROR); 582*7c478bd9Sstevel@tonic-gate usdp->sd_ref = REF_REL_NEED; 583*7c478bd9Sstevel@tonic-gate /* LINTED */ 584*7c478bd9Sstevel@tonic-gate usdp->sd_aux->sa_symspec = (Half)sdaux_id; 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate usdp->sd_aux->sa_overndx = VER_NDX_GLOBAL; 587*7c478bd9Sstevel@tonic-gate if (flags1 & FLG_SY1_GLOB) 588*7c478bd9Sstevel@tonic-gate usdp->sd_flags1 |= FLG_SY1_NDIR; 589*7c478bd9Sstevel@tonic-gate usdp->sd_flags1 |= flags1; 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate if (name && (sdp = sym_find(name, SYM_NOHASH, 0, ofl)) && 593*7c478bd9Sstevel@tonic-gate (sdp->sd_shndx == SHN_UNDEF)) { 594*7c478bd9Sstevel@tonic-gate uchar_t bind; 595*7c478bd9Sstevel@tonic-gate 596*7c478bd9Sstevel@tonic-gate /* 597*7c478bd9Sstevel@tonic-gate * If the non-underscore symbol exists and is undefined 598*7c478bd9Sstevel@tonic-gate * convert it to be a local. If the underscore has 599*7c478bd9Sstevel@tonic-gate * sa_symspec set (ie. it was created above) then simulate this 600*7c478bd9Sstevel@tonic-gate * as a weak alias. 601*7c478bd9Sstevel@tonic-gate */ 602*7c478bd9Sstevel@tonic-gate sdp->sd_ref = REF_REL_NEED; 603*7c478bd9Sstevel@tonic-gate sdp->sd_shndx = sdp->sd_sym->st_shndx = SHN_ABS; 604*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_SPECSEC; 605*7c478bd9Sstevel@tonic-gate sdp->sd_isc = NULL; 606*7c478bd9Sstevel@tonic-gate sdp->sd_sym->st_size = 0; 607*7c478bd9Sstevel@tonic-gate sdp->sd_sym->st_value = 0; 608*7c478bd9Sstevel@tonic-gate /* LINTED */ 609*7c478bd9Sstevel@tonic-gate sdp->sd_aux->sa_symspec = (Half)sdaux_id; 610*7c478bd9Sstevel@tonic-gate if (usdp->sd_aux->sa_symspec) { 611*7c478bd9Sstevel@tonic-gate usdp->sd_aux->sa_linkndx = 0; 612*7c478bd9Sstevel@tonic-gate sdp->sd_aux->sa_linkndx = 0; 613*7c478bd9Sstevel@tonic-gate bind = STB_WEAK; 614*7c478bd9Sstevel@tonic-gate } else 615*7c478bd9Sstevel@tonic-gate bind = STB_GLOBAL; 616*7c478bd9Sstevel@tonic-gate sdp->sd_sym->st_info = ELF_ST_INFO(bind, STT_OBJECT); 617*7c478bd9Sstevel@tonic-gate 618*7c478bd9Sstevel@tonic-gate /* 619*7c478bd9Sstevel@tonic-gate * If a user hasn't specifically indicated the scope of 620*7c478bd9Sstevel@tonic-gate * this symbol be made local then leave it as global 621*7c478bd9Sstevel@tonic-gate * (ie. prevent automatic scoping). 622*7c478bd9Sstevel@tonic-gate */ 623*7c478bd9Sstevel@tonic-gate if (!(sdp->sd_flags1 & FLG_SY1_LOCL) && 624*7c478bd9Sstevel@tonic-gate (flags1 & FLG_SY1_GLOB)) { 625*7c478bd9Sstevel@tonic-gate sdp->sd_aux->sa_overndx = VER_NDX_GLOBAL; 626*7c478bd9Sstevel@tonic-gate if ((sdp->sd_flags1 & FLG_SY1_DIR) == 0) 627*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_NDIR; 628*7c478bd9Sstevel@tonic-gate } 629*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= flags1; 630*7c478bd9Sstevel@tonic-gate 631*7c478bd9Sstevel@tonic-gate /* 632*7c478bd9Sstevel@tonic-gate * If the reference originated from a mapfile insure 633*7c478bd9Sstevel@tonic-gate * we mark the symbol as used. 634*7c478bd9Sstevel@tonic-gate */ 635*7c478bd9Sstevel@tonic-gate if (sdp->sd_flags & FLG_SY_MAPREF) 636*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_MAPUSED; 637*7c478bd9Sstevel@tonic-gate 638*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_updated((ofl->ofl_ehdr) ? ofl->ofl_ehdr : 639*7c478bd9Sstevel@tonic-gate &def_ehdr, sdp, name)); 640*7c478bd9Sstevel@tonic-gate } 641*7c478bd9Sstevel@tonic-gate return (1); 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate /* 646*7c478bd9Sstevel@tonic-gate * Print undefined symbols. 647*7c478bd9Sstevel@tonic-gate */ 648*7c478bd9Sstevel@tonic-gate static Boolean undef_title = TRUE; 649*7c478bd9Sstevel@tonic-gate 650*7c478bd9Sstevel@tonic-gate void 651*7c478bd9Sstevel@tonic-gate sym_undef_title() 652*7c478bd9Sstevel@tonic-gate { 653*7c478bd9Sstevel@tonic-gate eprintf(ERR_NONE, MSG_INTL(MSG_SYM_FMT_UNDEF), 654*7c478bd9Sstevel@tonic-gate MSG_INTL(MSG_SYM_UNDEF_ITM_11), 655*7c478bd9Sstevel@tonic-gate MSG_INTL(MSG_SYM_UNDEF_ITM_21), 656*7c478bd9Sstevel@tonic-gate MSG_INTL(MSG_SYM_UNDEF_ITM_12), 657*7c478bd9Sstevel@tonic-gate MSG_INTL(MSG_SYM_UNDEF_ITM_22)); 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate undef_title = FALSE; 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate 662*7c478bd9Sstevel@tonic-gate /* 663*7c478bd9Sstevel@tonic-gate * Undefined symbols can fall into one of four types: 664*7c478bd9Sstevel@tonic-gate * 665*7c478bd9Sstevel@tonic-gate * o the symbol is really undefined (SHN_UNDEF). 666*7c478bd9Sstevel@tonic-gate * 667*7c478bd9Sstevel@tonic-gate * o versioning has been enabled, however this symbol has not been assigned 668*7c478bd9Sstevel@tonic-gate * to one of the defined versions. 669*7c478bd9Sstevel@tonic-gate * 670*7c478bd9Sstevel@tonic-gate * o the symbol has been defined by an implicitly supplied library, ie. one 671*7c478bd9Sstevel@tonic-gate * which was encounted because it was NEEDED by another library, rather 672*7c478bd9Sstevel@tonic-gate * than from a command line supplied library which would become the only 673*7c478bd9Sstevel@tonic-gate * dependency of the output file being produced. 674*7c478bd9Sstevel@tonic-gate * 675*7c478bd9Sstevel@tonic-gate * o the symbol has been defined by a version of a shared object that is 676*7c478bd9Sstevel@tonic-gate * not permitted for this link-edit. 677*7c478bd9Sstevel@tonic-gate * 678*7c478bd9Sstevel@tonic-gate * In all cases the file who made the first reference to this symbol will have 679*7c478bd9Sstevel@tonic-gate * been recorded via the `sa_rfile' pointer. 680*7c478bd9Sstevel@tonic-gate */ 681*7c478bd9Sstevel@tonic-gate typedef enum { 682*7c478bd9Sstevel@tonic-gate UNDEF, NOVERSION, IMPLICIT, NOTAVAIL, 683*7c478bd9Sstevel@tonic-gate BNDLOCAL 684*7c478bd9Sstevel@tonic-gate } Type; 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate static const Msg format[] = { 687*7c478bd9Sstevel@tonic-gate MSG_SYM_UND_UNDEF, /* MSG_INTL(MSG_SYM_UND_UNDEF) */ 688*7c478bd9Sstevel@tonic-gate MSG_SYM_UND_NOVER, /* MSG_INTL(MSG_SYM_UND_NOVER) */ 689*7c478bd9Sstevel@tonic-gate MSG_SYM_UND_IMPL, /* MSG_INTL(MSG_SYM_UND_IMPL) */ 690*7c478bd9Sstevel@tonic-gate MSG_SYM_UND_NOTA, /* MSG_INTL(MSG_SYM_UND_NOTA) */ 691*7c478bd9Sstevel@tonic-gate MSG_SYM_UND_BNDLOCAL /* MSG_INTL(MSG_SYM_UND_BNDLOCAL) */ 692*7c478bd9Sstevel@tonic-gate }; 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate void 695*7c478bd9Sstevel@tonic-gate sym_undef_entry(Sym_desc *sdp, Type type) 696*7c478bd9Sstevel@tonic-gate { 697*7c478bd9Sstevel@tonic-gate const char *name1, *name2, *name3; 698*7c478bd9Sstevel@tonic-gate Ifl_desc *ifl = sdp->sd_file; 699*7c478bd9Sstevel@tonic-gate Sym_aux *sap = sdp->sd_aux; 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate if (undef_title) 702*7c478bd9Sstevel@tonic-gate sym_undef_title(); 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate switch (type) { 705*7c478bd9Sstevel@tonic-gate case UNDEF: 706*7c478bd9Sstevel@tonic-gate case BNDLOCAL: 707*7c478bd9Sstevel@tonic-gate name1 = sap->sa_rfile; 708*7c478bd9Sstevel@tonic-gate break; 709*7c478bd9Sstevel@tonic-gate case NOVERSION: 710*7c478bd9Sstevel@tonic-gate name1 = ifl->ifl_name; 711*7c478bd9Sstevel@tonic-gate break; 712*7c478bd9Sstevel@tonic-gate case IMPLICIT: 713*7c478bd9Sstevel@tonic-gate name1 = sap->sa_rfile; 714*7c478bd9Sstevel@tonic-gate name2 = ifl->ifl_name; 715*7c478bd9Sstevel@tonic-gate break; 716*7c478bd9Sstevel@tonic-gate case NOTAVAIL: 717*7c478bd9Sstevel@tonic-gate name1 = sap->sa_rfile; 718*7c478bd9Sstevel@tonic-gate name2 = sap->sa_vfile; 719*7c478bd9Sstevel@tonic-gate name3 = ifl->ifl_verndx[sap->sa_dverndx].vi_name; 720*7c478bd9Sstevel@tonic-gate break; 721*7c478bd9Sstevel@tonic-gate default: 722*7c478bd9Sstevel@tonic-gate return; 723*7c478bd9Sstevel@tonic-gate } 724*7c478bd9Sstevel@tonic-gate 725*7c478bd9Sstevel@tonic-gate eprintf(ERR_NONE, MSG_INTL(format[type]), demangle(sdp->sd_name), 726*7c478bd9Sstevel@tonic-gate name1, name2, name3); 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate 729*7c478bd9Sstevel@tonic-gate /* 730*7c478bd9Sstevel@tonic-gate * At this point all symbol input processing has been completed, therefore 731*7c478bd9Sstevel@tonic-gate * complete the symbol table entries by generating any necessary internal 732*7c478bd9Sstevel@tonic-gate * symbols. 733*7c478bd9Sstevel@tonic-gate */ 734*7c478bd9Sstevel@tonic-gate uintptr_t 735*7c478bd9Sstevel@tonic-gate sym_spec(Ofl_desc *ofl) 736*7c478bd9Sstevel@tonic-gate { 737*7c478bd9Sstevel@tonic-gate Word flags = ofl->ofl_flags; 738*7c478bd9Sstevel@tonic-gate 739*7c478bd9Sstevel@tonic-gate if (!(flags & FLG_OF_RELOBJ)) { 740*7c478bd9Sstevel@tonic-gate 741*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_spec_title()); 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate if (sym_add_spec(MSG_ORIG(MSG_SYM_ETEXT), 744*7c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_SYM_ETEXT_U), SDAUX_ID_ETEXT, 745*7c478bd9Sstevel@tonic-gate FLG_SY1_GLOB, ofl) == S_ERROR) 746*7c478bd9Sstevel@tonic-gate return (S_ERROR); 747*7c478bd9Sstevel@tonic-gate if (sym_add_spec(MSG_ORIG(MSG_SYM_EDATA), 748*7c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_SYM_EDATA_U), SDAUX_ID_EDATA, 749*7c478bd9Sstevel@tonic-gate FLG_SY1_GLOB, ofl) == S_ERROR) 750*7c478bd9Sstevel@tonic-gate return (S_ERROR); 751*7c478bd9Sstevel@tonic-gate if (sym_add_spec(MSG_ORIG(MSG_SYM_END), 752*7c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_SYM_END_U), SDAUX_ID_END, 753*7c478bd9Sstevel@tonic-gate FLG_SY1_GLOB, ofl) == S_ERROR) 754*7c478bd9Sstevel@tonic-gate return (S_ERROR); 755*7c478bd9Sstevel@tonic-gate if (sym_add_spec(MSG_ORIG(MSG_SYM_L_END), 756*7c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_SYM_L_END_U), SDAUX_ID_END, 757*7c478bd9Sstevel@tonic-gate FLG_SY1_LOCL, ofl) == S_ERROR) 758*7c478bd9Sstevel@tonic-gate return (S_ERROR); 759*7c478bd9Sstevel@tonic-gate if (sym_add_spec(MSG_ORIG(MSG_SYM_L_START), 760*7c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_SYM_L_START_U), SDAUX_ID_START, 761*7c478bd9Sstevel@tonic-gate FLG_SY1_LOCL, ofl) == S_ERROR) 762*7c478bd9Sstevel@tonic-gate return (S_ERROR); 763*7c478bd9Sstevel@tonic-gate 764*7c478bd9Sstevel@tonic-gate /* 765*7c478bd9Sstevel@tonic-gate * Historically we've always produced a _DYNAMIC symbol, even 766*7c478bd9Sstevel@tonic-gate * for static executables (in which case its value will be 0). 767*7c478bd9Sstevel@tonic-gate */ 768*7c478bd9Sstevel@tonic-gate if (sym_add_spec(MSG_ORIG(MSG_SYM_DYNAMIC), 769*7c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_SYM_DYNAMIC_U), SDAUX_ID_DYN, 770*7c478bd9Sstevel@tonic-gate FLG_SY1_GLOB, ofl) == S_ERROR) 771*7c478bd9Sstevel@tonic-gate return (S_ERROR); 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate if ((flags & (FLG_OF_DYNAMIC | FLG_OF_RELOBJ)) == 774*7c478bd9Sstevel@tonic-gate FLG_OF_DYNAMIC) 775*7c478bd9Sstevel@tonic-gate if (sym_add_spec(MSG_ORIG(MSG_SYM_PLKTBL), 776*7c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_SYM_PLKTBL_U), SDAUX_ID_PLT, 777*7c478bd9Sstevel@tonic-gate FLG_SY1_GLOB, ofl) == S_ERROR) 778*7c478bd9Sstevel@tonic-gate return (S_ERROR); 779*7c478bd9Sstevel@tonic-gate 780*7c478bd9Sstevel@tonic-gate if (sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U), SYM_NOHASH, 0, ofl)) 781*7c478bd9Sstevel@tonic-gate if (sym_add_spec(MSG_ORIG(MSG_SYM_GOFTBL), 782*7c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_SYM_GOFTBL_U), SDAUX_ID_GOT, 783*7c478bd9Sstevel@tonic-gate FLG_SY1_GLOB, ofl) == S_ERROR) 784*7c478bd9Sstevel@tonic-gate return (S_ERROR); 785*7c478bd9Sstevel@tonic-gate } 786*7c478bd9Sstevel@tonic-gate return (1); 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate /* 790*7c478bd9Sstevel@tonic-gate * This routine checks to see if a symbols visibility needs to be reduced to 791*7c478bd9Sstevel@tonic-gate * either SYMBOLIC or LOCAL. This routine can be called from either 792*7c478bd9Sstevel@tonic-gate * reloc_init() or sym_validate(). 793*7c478bd9Sstevel@tonic-gate */ 794*7c478bd9Sstevel@tonic-gate void 795*7c478bd9Sstevel@tonic-gate sym_adjust_vis(Sym_desc *sdp, Ofl_desc *ofl) 796*7c478bd9Sstevel@tonic-gate { 797*7c478bd9Sstevel@tonic-gate Word symvis, oflags = ofl->ofl_flags, oflags1 = ofl->ofl_flags1; 798*7c478bd9Sstevel@tonic-gate Sym *sym = sdp->sd_sym; 799*7c478bd9Sstevel@tonic-gate 800*7c478bd9Sstevel@tonic-gate if ((sdp->sd_ref == REF_REL_NEED) && (sdp->sd_shndx != SHN_UNDEF)) { 801*7c478bd9Sstevel@tonic-gate /* 802*7c478bd9Sstevel@tonic-gate * If scoping is enabled, reduce any nonversioned global 803*7c478bd9Sstevel@tonic-gate * symbols (any symbol that has been processed for relocations 804*7c478bd9Sstevel@tonic-gate * will have already had this same reduction test applied). 805*7c478bd9Sstevel@tonic-gate * Indicate that the symbol has been reduced as it may be 806*7c478bd9Sstevel@tonic-gate * necessary to print these symbols later. 807*7c478bd9Sstevel@tonic-gate */ 808*7c478bd9Sstevel@tonic-gate if (((oflags & FLG_OF_AUTOLCL) || 809*7c478bd9Sstevel@tonic-gate (oflags1 & FLG_OF1_AUTOELM)) && 810*7c478bd9Sstevel@tonic-gate ((sdp->sd_flags1 & MSK_SY1_DEFINED) == 0)) { 811*7c478bd9Sstevel@tonic-gate 812*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_REDUCED; 813*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_LOCL; 814*7c478bd9Sstevel@tonic-gate 815*7c478bd9Sstevel@tonic-gate if (ELF_ST_VISIBILITY(sym->st_other) != STV_INTERNAL) 816*7c478bd9Sstevel@tonic-gate sym->st_other = STV_HIDDEN | 817*7c478bd9Sstevel@tonic-gate (sym->st_other & ~MSK_SYM_VISIBILITY); 818*7c478bd9Sstevel@tonic-gate 819*7c478bd9Sstevel@tonic-gate if (ofl->ofl_flags1 & 820*7c478bd9Sstevel@tonic-gate (FLG_OF1_REDLSYM | FLG_OF1_AUTOELM)) 821*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_ELIM; 822*7c478bd9Sstevel@tonic-gate } 823*7c478bd9Sstevel@tonic-gate 824*7c478bd9Sstevel@tonic-gate /* 825*7c478bd9Sstevel@tonic-gate * If '-Bsymbolic' is in effect - then bind all global symbols 826*7c478bd9Sstevel@tonic-gate * 'symbolically' and assign the STV_PROTECTED visibility 827*7c478bd9Sstevel@tonic-gate * attribute. 828*7c478bd9Sstevel@tonic-gate */ 829*7c478bd9Sstevel@tonic-gate if ((oflags & FLG_OF_SYMBOLIC) && 830*7c478bd9Sstevel@tonic-gate ((sdp->sd_flags1 & FLG_SY1_LOCL) == 0)) { 831*7c478bd9Sstevel@tonic-gate 832*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_PROT; 833*7c478bd9Sstevel@tonic-gate if (ELF_ST_VISIBILITY(sym->st_other) == STV_DEFAULT) 834*7c478bd9Sstevel@tonic-gate sym->st_other = STV_PROTECTED | 835*7c478bd9Sstevel@tonic-gate (sym->st_other & ~MSK_SYM_VISIBILITY); 836*7c478bd9Sstevel@tonic-gate } 837*7c478bd9Sstevel@tonic-gate } 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate /* 840*7c478bd9Sstevel@tonic-gate * Check to see if the symbol visibility needs to be adjusted due to any 841*7c478bd9Sstevel@tonic-gate * STV_* symbol attributes being set. 842*7c478bd9Sstevel@tonic-gate * 843*7c478bd9Sstevel@tonic-gate * STV_PROTECTED == symbolic binding 844*7c478bd9Sstevel@tonic-gate * STV_INTERNAL == reduce to local 845*7c478bd9Sstevel@tonic-gate * STV_HIDDEN == reduce to local 846*7c478bd9Sstevel@tonic-gate * 847*7c478bd9Sstevel@tonic-gate * Note, UNDEF symbols can be assigned a visibility, thus the refencing 848*7c478bd9Sstevel@tonic-gate * code can be dependent on this visibility. Here, by only ignoring 849*7c478bd9Sstevel@tonic-gate * REF_DYN_SEEN symbol definitions we can be assigning a visibility to 850*7c478bd9Sstevel@tonic-gate * REF_DYN_NEED. If the protected, or local assignment is made to 851*7c478bd9Sstevel@tonic-gate * a REF_DYN_NEED symbol, it will be caught later as an illegal 852*7c478bd9Sstevel@tonic-gate * visibility. 853*7c478bd9Sstevel@tonic-gate */ 854*7c478bd9Sstevel@tonic-gate if (!(oflags & FLG_OF_RELOBJ) && (sdp->sd_ref != REF_DYN_SEEN) && 855*7c478bd9Sstevel@tonic-gate (symvis = ELF_ST_VISIBILITY(sym->st_other))) { 856*7c478bd9Sstevel@tonic-gate if (symvis == STV_PROTECTED) 857*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_PROT; 858*7c478bd9Sstevel@tonic-gate else if ((symvis == STV_INTERNAL) || (symvis == STV_HIDDEN)) 859*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_LOCL; 860*7c478bd9Sstevel@tonic-gate } 861*7c478bd9Sstevel@tonic-gate 862*7c478bd9Sstevel@tonic-gate /* 863*7c478bd9Sstevel@tonic-gate * Indicate that this symbol has had it's visibility checked so that 864*7c478bd9Sstevel@tonic-gate * we don't need to do this investigation again. 865*7c478bd9Sstevel@tonic-gate */ 866*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_VISIBLE; 867*7c478bd9Sstevel@tonic-gate } 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate /* 870*7c478bd9Sstevel@tonic-gate * After all symbol table input processing has been finished, and all relocation 871*7c478bd9Sstevel@tonic-gate * counting has been carried out (ie. no more symbols will be read, generated, 872*7c478bd9Sstevel@tonic-gate * or modified), validate and count the relevant entries: 873*7c478bd9Sstevel@tonic-gate * 874*7c478bd9Sstevel@tonic-gate * o check and print any undefined symbols remaining. Note that 875*7c478bd9Sstevel@tonic-gate * if a symbol has been defined by virtue of the inclusion of 876*7c478bd9Sstevel@tonic-gate * an implicit shared library, it is still classed as undefined. 877*7c478bd9Sstevel@tonic-gate * 878*7c478bd9Sstevel@tonic-gate * o count the number of global needed symbols together with the 879*7c478bd9Sstevel@tonic-gate * size of their associated name strings (if scoping has been 880*7c478bd9Sstevel@tonic-gate * indicated these symbols may be reduced to locals). 881*7c478bd9Sstevel@tonic-gate * 882*7c478bd9Sstevel@tonic-gate * o establish the size and alignment requirements for the global 883*7c478bd9Sstevel@tonic-gate * .bss section (the alignment of this section is based on the 884*7c478bd9Sstevel@tonic-gate * first symbol that it will contain). 885*7c478bd9Sstevel@tonic-gate */ 886*7c478bd9Sstevel@tonic-gate uintptr_t 887*7c478bd9Sstevel@tonic-gate sym_validate(Ofl_desc *ofl) 888*7c478bd9Sstevel@tonic-gate { 889*7c478bd9Sstevel@tonic-gate Sym_avlnode *sav; 890*7c478bd9Sstevel@tonic-gate Sym_desc *sdp; 891*7c478bd9Sstevel@tonic-gate Sym *sym; 892*7c478bd9Sstevel@tonic-gate Word oflags = ofl->ofl_flags; 893*7c478bd9Sstevel@tonic-gate Word undef = 0, needed = 0, verdesc = 0; 894*7c478bd9Sstevel@tonic-gate Xword bssalign = 0, tlsalign = 0; 895*7c478bd9Sstevel@tonic-gate Xword bsssize = 0, tlssize = 0; 896*7c478bd9Sstevel@tonic-gate 897*7c478bd9Sstevel@tonic-gate /* 898*7c478bd9Sstevel@tonic-gate * If a symbol is undefined and this link-edit calls for no undefined 899*7c478bd9Sstevel@tonic-gate * symbols to remain (this is the default case when generating an 900*7c478bd9Sstevel@tonic-gate * executable but can be enforced for any object using -z defs), the 901*7c478bd9Sstevel@tonic-gate * symbol is classified as undefined and a fatal error condition will 902*7c478bd9Sstevel@tonic-gate * be indicated. 903*7c478bd9Sstevel@tonic-gate * 904*7c478bd9Sstevel@tonic-gate * If the symbol is undefined and we're creating a shared object with 905*7c478bd9Sstevel@tonic-gate * the -Bsymbolic flag, then the symbol is also classified as undefined 906*7c478bd9Sstevel@tonic-gate * and a warning condition will be indicated. 907*7c478bd9Sstevel@tonic-gate */ 908*7c478bd9Sstevel@tonic-gate if ((oflags & (FLG_OF_SHAROBJ | FLG_OF_SYMBOLIC)) == 909*7c478bd9Sstevel@tonic-gate (FLG_OF_SHAROBJ | FLG_OF_SYMBOLIC)) 910*7c478bd9Sstevel@tonic-gate undef = FLG_OF_WARN; 911*7c478bd9Sstevel@tonic-gate if (oflags & FLG_OF_NOUNDEF) 912*7c478bd9Sstevel@tonic-gate undef = FLG_OF_FATAL; 913*7c478bd9Sstevel@tonic-gate 914*7c478bd9Sstevel@tonic-gate /* 915*7c478bd9Sstevel@tonic-gate * If the symbol is referenced from an implicitly included shared object 916*7c478bd9Sstevel@tonic-gate * (ie. it's not on the NEEDED list) then the symbol is also classified 917*7c478bd9Sstevel@tonic-gate * as undefined and a fatal error condition will be indicated. 918*7c478bd9Sstevel@tonic-gate */ 919*7c478bd9Sstevel@tonic-gate if ((oflags & FLG_OF_NOUNDEF) || !(oflags & FLG_OF_SHAROBJ)) 920*7c478bd9Sstevel@tonic-gate needed = FLG_OF_FATAL; 921*7c478bd9Sstevel@tonic-gate 922*7c478bd9Sstevel@tonic-gate /* 923*7c478bd9Sstevel@tonic-gate * If the output image is being versioned all symbol definitions must be 924*7c478bd9Sstevel@tonic-gate * associated with a version. Any symbol that isn't is classified as 925*7c478bd9Sstevel@tonic-gate * undefined and a fatal error condition will be indicated. 926*7c478bd9Sstevel@tonic-gate */ 927*7c478bd9Sstevel@tonic-gate if ((oflags & FLG_OF_VERDEF) && (ofl->ofl_vercnt > VER_NDX_GLOBAL)) 928*7c478bd9Sstevel@tonic-gate verdesc = FLG_OF_FATAL; 929*7c478bd9Sstevel@tonic-gate 930*7c478bd9Sstevel@tonic-gate /* 931*7c478bd9Sstevel@tonic-gate * Collect and validate the globals from the internal symbol table. 932*7c478bd9Sstevel@tonic-gate */ 933*7c478bd9Sstevel@tonic-gate for (sav = avl_first(&ofl->ofl_symavl); sav; 934*7c478bd9Sstevel@tonic-gate sav = AVL_NEXT(&ofl->ofl_symavl, sav)) { 935*7c478bd9Sstevel@tonic-gate Is_desc * isp; 936*7c478bd9Sstevel@tonic-gate int shndx, undeferr = 0; 937*7c478bd9Sstevel@tonic-gate 938*7c478bd9Sstevel@tonic-gate sdp = sav->sav_symdesc; 939*7c478bd9Sstevel@tonic-gate 940*7c478bd9Sstevel@tonic-gate /* 941*7c478bd9Sstevel@tonic-gate * If undefined symbols are allowed ignore any symbols that are 942*7c478bd9Sstevel@tonic-gate * not needed. 943*7c478bd9Sstevel@tonic-gate */ 944*7c478bd9Sstevel@tonic-gate if (!(oflags & FLG_OF_NOUNDEF) && 945*7c478bd9Sstevel@tonic-gate (sdp->sd_ref == REF_DYN_SEEN)) 946*7c478bd9Sstevel@tonic-gate continue; 947*7c478bd9Sstevel@tonic-gate 948*7c478bd9Sstevel@tonic-gate /* 949*7c478bd9Sstevel@tonic-gate * If the symbol originates from an external or parent mapfile 950*7c478bd9Sstevel@tonic-gate * reference and hasn't been matched to a reference from a 951*7c478bd9Sstevel@tonic-gate * relocatable object, ignore it. 952*7c478bd9Sstevel@tonic-gate */ 953*7c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & (FLG_SY_EXTERN | FLG_SY_PARENT)) && 954*7c478bd9Sstevel@tonic-gate ((sdp->sd_flags & FLG_SY_MAPUSED) == 0)) { 955*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_INVALID; 956*7c478bd9Sstevel@tonic-gate continue; 957*7c478bd9Sstevel@tonic-gate } 958*7c478bd9Sstevel@tonic-gate 959*7c478bd9Sstevel@tonic-gate sym = sdp->sd_sym; 960*7c478bd9Sstevel@tonic-gate shndx = sdp->sd_shndx; 961*7c478bd9Sstevel@tonic-gate 962*7c478bd9Sstevel@tonic-gate /* 963*7c478bd9Sstevel@tonic-gate * Sanity check TLS. 964*7c478bd9Sstevel@tonic-gate */ 965*7c478bd9Sstevel@tonic-gate if ((ELF_ST_TYPE(sym->st_info) == STT_TLS) && 966*7c478bd9Sstevel@tonic-gate (sym->st_size != 0) && (shndx != SHN_UNDEF) && 967*7c478bd9Sstevel@tonic-gate (shndx != SHN_COMMON)) { 968*7c478bd9Sstevel@tonic-gate Is_desc * isp = sdp->sd_isc; 969*7c478bd9Sstevel@tonic-gate Ifl_desc * ifl = sdp->sd_file; 970*7c478bd9Sstevel@tonic-gate 971*7c478bd9Sstevel@tonic-gate if ((isp == 0) || (isp->is_shdr == 0) || 972*7c478bd9Sstevel@tonic-gate ((isp->is_shdr->sh_flags & SHF_TLS) == 0)) { 973*7c478bd9Sstevel@tonic-gate eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_TLS), 974*7c478bd9Sstevel@tonic-gate demangle(sdp->sd_name), ifl->ifl_name); 975*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_FATAL; 976*7c478bd9Sstevel@tonic-gate continue; 977*7c478bd9Sstevel@tonic-gate } 978*7c478bd9Sstevel@tonic-gate } 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_VISIBLE) == 0) 981*7c478bd9Sstevel@tonic-gate sym_adjust_vis(sdp, ofl); 982*7c478bd9Sstevel@tonic-gate 983*7c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & FLG_SY_REDUCED) && 984*7c478bd9Sstevel@tonic-gate (oflags & FLG_OF_PROCRED)) { 985*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_reduce(DBG_SYM_REDUCE_GLOBAL, 986*7c478bd9Sstevel@tonic-gate (ofl->ofl_ehdr) ? ofl->ofl_ehdr : 987*7c478bd9Sstevel@tonic-gate &def_ehdr, sdp, 0, 0)); 988*7c478bd9Sstevel@tonic-gate } 989*7c478bd9Sstevel@tonic-gate 990*7c478bd9Sstevel@tonic-gate /* 991*7c478bd9Sstevel@tonic-gate * If building a shared object or executable, and this is a 992*7c478bd9Sstevel@tonic-gate * non-weak UNDEF symbol with reduced visibility (STV_*), then 993*7c478bd9Sstevel@tonic-gate * give a fatal error. 994*7c478bd9Sstevel@tonic-gate */ 995*7c478bd9Sstevel@tonic-gate if (!(oflags & FLG_OF_RELOBJ) && 996*7c478bd9Sstevel@tonic-gate ELF_ST_VISIBILITY(sym->st_other) && (shndx == SHN_UNDEF) && 997*7c478bd9Sstevel@tonic-gate (ELF_ST_BIND(sym->st_info) != STB_WEAK)) { 998*7c478bd9Sstevel@tonic-gate sym_undef_entry(sdp, BNDLOCAL); 999*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_FATAL; 1000*7c478bd9Sstevel@tonic-gate continue; 1001*7c478bd9Sstevel@tonic-gate } 1002*7c478bd9Sstevel@tonic-gate 1003*7c478bd9Sstevel@tonic-gate /* 1004*7c478bd9Sstevel@tonic-gate * If this symbol is defined in a non-allocatable section, 1005*7c478bd9Sstevel@tonic-gate * reduce it to local symbol. 1006*7c478bd9Sstevel@tonic-gate */ 1007*7c478bd9Sstevel@tonic-gate if (((isp = sdp->sd_isc) != 0) && isp->is_shdr && 1008*7c478bd9Sstevel@tonic-gate ((isp->is_shdr->sh_flags & SHF_ALLOC) == 0)) { 1009*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_REDUCED; 1010*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_LOCL; 1011*7c478bd9Sstevel@tonic-gate } 1012*7c478bd9Sstevel@tonic-gate 1013*7c478bd9Sstevel@tonic-gate /* 1014*7c478bd9Sstevel@tonic-gate * If this symbol originated as a SHN_SUNW_IGNORE, it will have 1015*7c478bd9Sstevel@tonic-gate * been processed as an SHN_UNDEF. Return the symbol to its 1016*7c478bd9Sstevel@tonic-gate * original index for validation, and propagation to the output 1017*7c478bd9Sstevel@tonic-gate * file. 1018*7c478bd9Sstevel@tonic-gate */ 1019*7c478bd9Sstevel@tonic-gate if (sdp->sd_flags1 & FLG_SY1_IGNORE) 1020*7c478bd9Sstevel@tonic-gate sdp->sd_shndx = shndx = SHN_SUNW_IGNORE; 1021*7c478bd9Sstevel@tonic-gate 1022*7c478bd9Sstevel@tonic-gate if (undef) { 1023*7c478bd9Sstevel@tonic-gate /* 1024*7c478bd9Sstevel@tonic-gate * If an non-weak reference remains undefined, or if a 1025*7c478bd9Sstevel@tonic-gate * mapfile reference is not bound to the relocatable 1026*7c478bd9Sstevel@tonic-gate * objects that make up the object being built, we have 1027*7c478bd9Sstevel@tonic-gate * a fatal error. 1028*7c478bd9Sstevel@tonic-gate * 1029*7c478bd9Sstevel@tonic-gate * The exceptions are symbols which are defined to be 1030*7c478bd9Sstevel@tonic-gate * found in the parent (FLG_SY_PARENT), which is really 1031*7c478bd9Sstevel@tonic-gate * only meaningful for direct binding, or are defined 1032*7c478bd9Sstevel@tonic-gate * external (FLG_SY_EXTERN) so as to suppress -zdefs 1033*7c478bd9Sstevel@tonic-gate * errors. 1034*7c478bd9Sstevel@tonic-gate * 1035*7c478bd9Sstevel@tonic-gate * Register symbols are always allowed to be UNDEF. 1036*7c478bd9Sstevel@tonic-gate * 1037*7c478bd9Sstevel@tonic-gate * Note that we don't include references created via -u 1038*7c478bd9Sstevel@tonic-gate * in the same shared object binding test. This is for 1039*7c478bd9Sstevel@tonic-gate * backward compatibility, in that a number of archive 1040*7c478bd9Sstevel@tonic-gate * makefile rules used -u to cause archive extraction. 1041*7c478bd9Sstevel@tonic-gate * These same rules have been cut and pasted to apply 1042*7c478bd9Sstevel@tonic-gate * to shared objects, and thus although the -u reference 1043*7c478bd9Sstevel@tonic-gate * is redundant, flagging it as fatal could cause some 1044*7c478bd9Sstevel@tonic-gate * build to fail. Also we have documented the use of 1045*7c478bd9Sstevel@tonic-gate * -u as a mechanism to cause binding to weak version 1046*7c478bd9Sstevel@tonic-gate * definitions, thus giving users an error condition 1047*7c478bd9Sstevel@tonic-gate * would be incorrect. 1048*7c478bd9Sstevel@tonic-gate */ 1049*7c478bd9Sstevel@tonic-gate if (!(sdp->sd_flags & FLG_SY_REGSYM) && 1050*7c478bd9Sstevel@tonic-gate ((shndx == SHN_UNDEF) && 1051*7c478bd9Sstevel@tonic-gate ((ELF_ST_BIND(sym->st_info) != STB_WEAK) && 1052*7c478bd9Sstevel@tonic-gate ((sdp->sd_flags & 1053*7c478bd9Sstevel@tonic-gate (FLG_SY_PARENT | FLG_SY_EXTERN)) == 0)) || 1054*7c478bd9Sstevel@tonic-gate (((sdp->sd_flags & 1055*7c478bd9Sstevel@tonic-gate (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == 1056*7c478bd9Sstevel@tonic-gate FLG_SY_MAPREF) && 1057*7c478bd9Sstevel@tonic-gate ((sdp->sd_flags1 & (FLG_SY1_LOCL | 1058*7c478bd9Sstevel@tonic-gate FLG_SY1_PROT)) == 0)))) { 1059*7c478bd9Sstevel@tonic-gate sym_undef_entry(sdp, UNDEF); 1060*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= undef; 1061*7c478bd9Sstevel@tonic-gate undeferr = 1; 1062*7c478bd9Sstevel@tonic-gate } 1063*7c478bd9Sstevel@tonic-gate 1064*7c478bd9Sstevel@tonic-gate } else { 1065*7c478bd9Sstevel@tonic-gate /* 1066*7c478bd9Sstevel@tonic-gate * For building things like shared objects (or anything 1067*7c478bd9Sstevel@tonic-gate * -znodefs), undefined symbols are allowed. 1068*7c478bd9Sstevel@tonic-gate * 1069*7c478bd9Sstevel@tonic-gate * If a mapfile reference remains undefined the user 1070*7c478bd9Sstevel@tonic-gate * would probably like a warning at least (they've 1071*7c478bd9Sstevel@tonic-gate * usually mis-spelt the reference). Refer to the above 1072*7c478bd9Sstevel@tonic-gate * comments for discussion on -u references, which 1073*7c478bd9Sstevel@tonic-gate * are not tested for in the same manner. 1074*7c478bd9Sstevel@tonic-gate */ 1075*7c478bd9Sstevel@tonic-gate if ((sdp->sd_flags & 1076*7c478bd9Sstevel@tonic-gate (FLG_SY_MAPREF | FLG_SY_MAPUSED)) == 1077*7c478bd9Sstevel@tonic-gate FLG_SY_MAPREF) { 1078*7c478bd9Sstevel@tonic-gate sym_undef_entry(sdp, UNDEF); 1079*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_WARN; 1080*7c478bd9Sstevel@tonic-gate undeferr = 1; 1081*7c478bd9Sstevel@tonic-gate } 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate 1084*7c478bd9Sstevel@tonic-gate /* 1085*7c478bd9Sstevel@tonic-gate * If this symbol comes from a dependency mark the dependency 1086*7c478bd9Sstevel@tonic-gate * as required (-z ignore can result in unused dependencies 1087*7c478bd9Sstevel@tonic-gate * being dropped). If we need to record dependency versioning 1088*7c478bd9Sstevel@tonic-gate * information indicate what version of the needed shared object 1089*7c478bd9Sstevel@tonic-gate * this symbol is part of. Flag the symbol as undefined if it 1090*7c478bd9Sstevel@tonic-gate * has not been made available to us. 1091*7c478bd9Sstevel@tonic-gate */ 1092*7c478bd9Sstevel@tonic-gate if ((sdp->sd_ref == REF_DYN_NEED) && 1093*7c478bd9Sstevel@tonic-gate (!(sdp->sd_flags & FLG_SY_REFRSD))) { 1094*7c478bd9Sstevel@tonic-gate sdp->sd_file->ifl_flags |= FLG_IF_DEPREQD; 1095*7c478bd9Sstevel@tonic-gate 1096*7c478bd9Sstevel@tonic-gate /* 1097*7c478bd9Sstevel@tonic-gate * Capture that we've bound to a symbol that doesn't 1098*7c478bd9Sstevel@tonic-gate * allow being directly bound to. 1099*7c478bd9Sstevel@tonic-gate */ 1100*7c478bd9Sstevel@tonic-gate if (sdp->sd_flags1 & FLG_SY1_NDIR) 1101*7c478bd9Sstevel@tonic-gate ofl->ofl_flags1 |= FLG_OF1_NDIRECT; 1102*7c478bd9Sstevel@tonic-gate 1103*7c478bd9Sstevel@tonic-gate if (sdp->sd_file->ifl_vercnt) { 1104*7c478bd9Sstevel@tonic-gate int vndx; 1105*7c478bd9Sstevel@tonic-gate Ver_index * vip; 1106*7c478bd9Sstevel@tonic-gate 1107*7c478bd9Sstevel@tonic-gate vndx = sdp->sd_aux->sa_dverndx; 1108*7c478bd9Sstevel@tonic-gate vip = &sdp->sd_file->ifl_verndx[vndx]; 1109*7c478bd9Sstevel@tonic-gate if (vip->vi_flags & FLG_VER_AVAIL) { 1110*7c478bd9Sstevel@tonic-gate vip->vi_flags |= FLG_VER_REFER; 1111*7c478bd9Sstevel@tonic-gate } else { 1112*7c478bd9Sstevel@tonic-gate sym_undef_entry(sdp, NOTAVAIL); 1113*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_FATAL; 1114*7c478bd9Sstevel@tonic-gate continue; 1115*7c478bd9Sstevel@tonic-gate } 1116*7c478bd9Sstevel@tonic-gate } 1117*7c478bd9Sstevel@tonic-gate } 1118*7c478bd9Sstevel@tonic-gate 1119*7c478bd9Sstevel@tonic-gate /* 1120*7c478bd9Sstevel@tonic-gate * Test that we do not bind to symbol supplied from an implicit 1121*7c478bd9Sstevel@tonic-gate * shared object. If a binding is from a weak reference it can 1122*7c478bd9Sstevel@tonic-gate * be ignored. 1123*7c478bd9Sstevel@tonic-gate */ 1124*7c478bd9Sstevel@tonic-gate if (needed && !undeferr && (sdp->sd_flags & FLG_SY_GLOBREF) && 1125*7c478bd9Sstevel@tonic-gate (sdp->sd_ref == REF_DYN_NEED) && 1126*7c478bd9Sstevel@tonic-gate (sdp->sd_flags & FLG_SY_NOTAVAIL)) { 1127*7c478bd9Sstevel@tonic-gate sym_undef_entry(sdp, IMPLICIT); 1128*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= needed; 1129*7c478bd9Sstevel@tonic-gate continue; 1130*7c478bd9Sstevel@tonic-gate } 1131*7c478bd9Sstevel@tonic-gate 1132*7c478bd9Sstevel@tonic-gate /* 1133*7c478bd9Sstevel@tonic-gate * Test that a symbol isn't going to be reduced to local scope 1134*7c478bd9Sstevel@tonic-gate * which actually wants to bind to a shared object - if so it's 1135*7c478bd9Sstevel@tonic-gate * a fatal error. 1136*7c478bd9Sstevel@tonic-gate */ 1137*7c478bd9Sstevel@tonic-gate if ((sdp->sd_ref == REF_DYN_NEED) && 1138*7c478bd9Sstevel@tonic-gate (sdp->sd_flags1 & (FLG_SY1_LOCL | FLG_SY1_PROT))) { 1139*7c478bd9Sstevel@tonic-gate sym_undef_entry(sdp, BNDLOCAL); 1140*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_FATAL; 1141*7c478bd9Sstevel@tonic-gate continue; 1142*7c478bd9Sstevel@tonic-gate } 1143*7c478bd9Sstevel@tonic-gate 1144*7c478bd9Sstevel@tonic-gate /* 1145*7c478bd9Sstevel@tonic-gate * If the output image is to be versioned then all symbol 1146*7c478bd9Sstevel@tonic-gate * definitions must be associated with a version. 1147*7c478bd9Sstevel@tonic-gate */ 1148*7c478bd9Sstevel@tonic-gate if (verdesc && (sdp->sd_ref == REF_REL_NEED) && 1149*7c478bd9Sstevel@tonic-gate (shndx != SHN_UNDEF) && 1150*7c478bd9Sstevel@tonic-gate (!(sdp->sd_flags1 & FLG_SY1_LOCL)) && 1151*7c478bd9Sstevel@tonic-gate (sdp->sd_aux->sa_overndx == 0)) { 1152*7c478bd9Sstevel@tonic-gate sym_undef_entry(sdp, NOVERSION); 1153*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= verdesc; 1154*7c478bd9Sstevel@tonic-gate continue; 1155*7c478bd9Sstevel@tonic-gate } 1156*7c478bd9Sstevel@tonic-gate 1157*7c478bd9Sstevel@tonic-gate /* 1158*7c478bd9Sstevel@tonic-gate * If we don't need the symbol there's no need to process it 1159*7c478bd9Sstevel@tonic-gate * any further. 1160*7c478bd9Sstevel@tonic-gate */ 1161*7c478bd9Sstevel@tonic-gate if (sdp->sd_ref == REF_DYN_SEEN) 1162*7c478bd9Sstevel@tonic-gate continue; 1163*7c478bd9Sstevel@tonic-gate 1164*7c478bd9Sstevel@tonic-gate /* 1165*7c478bd9Sstevel@tonic-gate * Calculate the size and alignment requirements for the global 1166*7c478bd9Sstevel@tonic-gate * .bss and .tls sections. If we're building a relocatable 1167*7c478bd9Sstevel@tonic-gate * object only account for scoped COMMON symbols (these will 1168*7c478bd9Sstevel@tonic-gate * be converted to .bss references). 1169*7c478bd9Sstevel@tonic-gate * 1170*7c478bd9Sstevel@tonic-gate * For partially initialized symbol, 1171*7c478bd9Sstevel@tonic-gate * if it is expanded, it goes to sunwdata1. 1172*7c478bd9Sstevel@tonic-gate * if it is local, it goes to .bss. 1173*7c478bd9Sstevel@tonic-gate * if the output is shared object, it goes to .sunwbss. 1174*7c478bd9Sstevel@tonic-gate * 1175*7c478bd9Sstevel@tonic-gate * Also refer to make_mvsections() in sunwmove.c 1176*7c478bd9Sstevel@tonic-gate */ 1177*7c478bd9Sstevel@tonic-gate if ((shndx == SHN_COMMON) && ((!(oflags & FLG_OF_RELOBJ)) || 1178*7c478bd9Sstevel@tonic-gate ((sdp->sd_flags1 & FLG_SY1_LOCL) && 1179*7c478bd9Sstevel@tonic-gate (oflags & FLG_OF_PROCRED)))) { 1180*7c478bd9Sstevel@tonic-gate int countbss = 0; 1181*7c478bd9Sstevel@tonic-gate 1182*7c478bd9Sstevel@tonic-gate if (sdp->sd_psyminfo == 0) { 1183*7c478bd9Sstevel@tonic-gate countbss = 1; 1184*7c478bd9Sstevel@tonic-gate } else if ((sdp->sd_flags & FLG_SY_PAREXPN) != 0) { 1185*7c478bd9Sstevel@tonic-gate countbss = 0; 1186*7c478bd9Sstevel@tonic-gate } else if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) { 1187*7c478bd9Sstevel@tonic-gate countbss = 1; 1188*7c478bd9Sstevel@tonic-gate } else if ((ofl->ofl_flags & FLG_OF_SHAROBJ) != 0) { 1189*7c478bd9Sstevel@tonic-gate countbss = 0; 1190*7c478bd9Sstevel@tonic-gate } else 1191*7c478bd9Sstevel@tonic-gate countbss = 1; 1192*7c478bd9Sstevel@tonic-gate 1193*7c478bd9Sstevel@tonic-gate if (countbss) { 1194*7c478bd9Sstevel@tonic-gate Xword * size, * align; 1195*7c478bd9Sstevel@tonic-gate 1196*7c478bd9Sstevel@tonic-gate if (ELF_ST_TYPE(sym->st_info) != STT_TLS) { 1197*7c478bd9Sstevel@tonic-gate size = &bsssize; 1198*7c478bd9Sstevel@tonic-gate align = &bssalign; 1199*7c478bd9Sstevel@tonic-gate } else { 1200*7c478bd9Sstevel@tonic-gate size = &tlssize; 1201*7c478bd9Sstevel@tonic-gate align = &tlsalign; 1202*7c478bd9Sstevel@tonic-gate } 1203*7c478bd9Sstevel@tonic-gate *size = (Xword)S_ROUND(*size, sym->st_value) + 1204*7c478bd9Sstevel@tonic-gate sym->st_size; 1205*7c478bd9Sstevel@tonic-gate if (sym->st_value > *align) 1206*7c478bd9Sstevel@tonic-gate *align = sym->st_value; 1207*7c478bd9Sstevel@tonic-gate } 1208*7c478bd9Sstevel@tonic-gate } 1209*7c478bd9Sstevel@tonic-gate 1210*7c478bd9Sstevel@tonic-gate /* 1211*7c478bd9Sstevel@tonic-gate * If a symbol was referenced via the command line 1212*7c478bd9Sstevel@tonic-gate * (ld -u <>, ...), then this counts as a reference against the 1213*7c478bd9Sstevel@tonic-gate * symbol. Mark any section that symbol is defined in. 1214*7c478bd9Sstevel@tonic-gate */ 1215*7c478bd9Sstevel@tonic-gate if (((isp = sdp->sd_isc) != 0) && 1216*7c478bd9Sstevel@tonic-gate (sdp->sd_flags & FLG_SY_CMDREF)) { 1217*7c478bd9Sstevel@tonic-gate isp->is_flags |= FLG_IS_SECTREF; 1218*7c478bd9Sstevel@tonic-gate isp->is_file->ifl_flags |= FLG_IF_FILEREF; 1219*7c478bd9Sstevel@tonic-gate } 1220*7c478bd9Sstevel@tonic-gate 1221*7c478bd9Sstevel@tonic-gate /* 1222*7c478bd9Sstevel@tonic-gate * Update the symbol count and the associated name string size. 1223*7c478bd9Sstevel@tonic-gate * If scoping is in effect for this symbol assign it will be 1224*7c478bd9Sstevel@tonic-gate * assigned to the .symtab/.strtab sections. 1225*7c478bd9Sstevel@tonic-gate */ 1226*7c478bd9Sstevel@tonic-gate if ((sdp->sd_flags1 & FLG_SY1_LOCL) && 1227*7c478bd9Sstevel@tonic-gate (oflags & FLG_OF_PROCRED)) { 1228*7c478bd9Sstevel@tonic-gate /* 1229*7c478bd9Sstevel@tonic-gate * If symbol gets eliminated count it. 1230*7c478bd9Sstevel@tonic-gate * 1231*7c478bd9Sstevel@tonic-gate * If symbol gets reduced to local, 1232*7c478bd9Sstevel@tonic-gate * count it's size for the .symtab. 1233*7c478bd9Sstevel@tonic-gate */ 1234*7c478bd9Sstevel@tonic-gate if (sdp->sd_flags1 & FLG_SY1_ELIM) { 1235*7c478bd9Sstevel@tonic-gate ofl->ofl_elimcnt++; 1236*7c478bd9Sstevel@tonic-gate } else { 1237*7c478bd9Sstevel@tonic-gate ofl->ofl_scopecnt++; 1238*7c478bd9Sstevel@tonic-gate if ((((sdp->sd_flags & FLG_SY_REGSYM) == 0) || 1239*7c478bd9Sstevel@tonic-gate sym->st_name) && (st_insert(ofl->ofl_strtab, 1240*7c478bd9Sstevel@tonic-gate sdp->sd_name) == -1)) 1241*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1242*7c478bd9Sstevel@tonic-gate } 1243*7c478bd9Sstevel@tonic-gate } else { 1244*7c478bd9Sstevel@tonic-gate ofl->ofl_globcnt++; 1245*7c478bd9Sstevel@tonic-gate 1246*7c478bd9Sstevel@tonic-gate /* 1247*7c478bd9Sstevel@tonic-gate * If global direct bindings are in effect, or this 1248*7c478bd9Sstevel@tonic-gate * symbol has bound to a dependency which was specified 1249*7c478bd9Sstevel@tonic-gate * as requiring direct bindings, and it hasn't 1250*7c478bd9Sstevel@tonic-gate * explicitly been defined as a non-direct binding 1251*7c478bd9Sstevel@tonic-gate * symbol, mark it. 1252*7c478bd9Sstevel@tonic-gate */ 1253*7c478bd9Sstevel@tonic-gate if (((ofl->ofl_dtflags_1 & DF_1_DIRECT) || (isp && 1254*7c478bd9Sstevel@tonic-gate (isp->is_file->ifl_flags & FLG_IF_DIRECT))) && 1255*7c478bd9Sstevel@tonic-gate ((sdp->sd_flags1 & FLG_SY1_NDIR) == 0)) 1256*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= FLG_SY1_DIR; 1257*7c478bd9Sstevel@tonic-gate 1258*7c478bd9Sstevel@tonic-gate /* 1259*7c478bd9Sstevel@tonic-gate * Insert the symbol name. 1260*7c478bd9Sstevel@tonic-gate */ 1261*7c478bd9Sstevel@tonic-gate if (((sdp->sd_flags & FLG_SY_REGSYM) == 0) || 1262*7c478bd9Sstevel@tonic-gate sym->st_name) { 1263*7c478bd9Sstevel@tonic-gate if (st_insert(ofl->ofl_strtab, 1264*7c478bd9Sstevel@tonic-gate sdp->sd_name) == -1) 1265*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1266*7c478bd9Sstevel@tonic-gate 1267*7c478bd9Sstevel@tonic-gate if (!(ofl->ofl_flags & FLG_OF_RELOBJ) && 1268*7c478bd9Sstevel@tonic-gate (st_insert(ofl->ofl_dynstrtab, 1269*7c478bd9Sstevel@tonic-gate sdp->sd_name) == -1)) 1270*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1271*7c478bd9Sstevel@tonic-gate } 1272*7c478bd9Sstevel@tonic-gate 1273*7c478bd9Sstevel@tonic-gate /* 1274*7c478bd9Sstevel@tonic-gate * If this section offers a global symbol - record that 1275*7c478bd9Sstevel@tonic-gate * fact. 1276*7c478bd9Sstevel@tonic-gate */ 1277*7c478bd9Sstevel@tonic-gate if (isp) { 1278*7c478bd9Sstevel@tonic-gate isp->is_flags |= FLG_IS_SECTREF; 1279*7c478bd9Sstevel@tonic-gate isp->is_file->ifl_flags |= FLG_IF_FILEREF; 1280*7c478bd9Sstevel@tonic-gate } 1281*7c478bd9Sstevel@tonic-gate } 1282*7c478bd9Sstevel@tonic-gate } 1283*7c478bd9Sstevel@tonic-gate 1284*7c478bd9Sstevel@tonic-gate /* 1285*7c478bd9Sstevel@tonic-gate * If we've encountered a fatal error during symbol validation then 1286*7c478bd9Sstevel@tonic-gate * return now. 1287*7c478bd9Sstevel@tonic-gate */ 1288*7c478bd9Sstevel@tonic-gate if (ofl->ofl_flags & FLG_OF_FATAL) 1289*7c478bd9Sstevel@tonic-gate return (1); 1290*7c478bd9Sstevel@tonic-gate 1291*7c478bd9Sstevel@tonic-gate /* 1292*7c478bd9Sstevel@tonic-gate * Now that symbol resolution is completed, scan any register symbols. 1293*7c478bd9Sstevel@tonic-gate * From now on, we're only interested in those that contribute to the 1294*7c478bd9Sstevel@tonic-gate * output file. 1295*7c478bd9Sstevel@tonic-gate */ 1296*7c478bd9Sstevel@tonic-gate if (ofl->ofl_regsyms) { 1297*7c478bd9Sstevel@tonic-gate int ndx; 1298*7c478bd9Sstevel@tonic-gate 1299*7c478bd9Sstevel@tonic-gate for (ndx = 0; ndx < ofl->ofl_regsymsno; ndx++) { 1300*7c478bd9Sstevel@tonic-gate if ((sdp = ofl->ofl_regsyms[ndx]) == 0) 1301*7c478bd9Sstevel@tonic-gate continue; 1302*7c478bd9Sstevel@tonic-gate if (sdp->sd_ref != REF_REL_NEED) { 1303*7c478bd9Sstevel@tonic-gate ofl->ofl_regsyms[ndx] = 0; 1304*7c478bd9Sstevel@tonic-gate continue; 1305*7c478bd9Sstevel@tonic-gate } 1306*7c478bd9Sstevel@tonic-gate 1307*7c478bd9Sstevel@tonic-gate ofl->ofl_regsymcnt++; 1308*7c478bd9Sstevel@tonic-gate if (sdp->sd_sym->st_name == 0) 1309*7c478bd9Sstevel@tonic-gate sdp->sd_name = MSG_ORIG(MSG_STR_EMPTY); 1310*7c478bd9Sstevel@tonic-gate 1311*7c478bd9Sstevel@tonic-gate if ((sdp->sd_flags1 & FLG_SY1_LOCL) || 1312*7c478bd9Sstevel@tonic-gate (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL)) 1313*7c478bd9Sstevel@tonic-gate ofl->ofl_lregsymcnt++; 1314*7c478bd9Sstevel@tonic-gate } 1315*7c478bd9Sstevel@tonic-gate } 1316*7c478bd9Sstevel@tonic-gate 1317*7c478bd9Sstevel@tonic-gate /* 1318*7c478bd9Sstevel@tonic-gate * Generate the .bss section now that we know its size and alignment. 1319*7c478bd9Sstevel@tonic-gate */ 1320*7c478bd9Sstevel@tonic-gate if (bsssize || !(oflags & FLG_OF_RELOBJ)) { 1321*7c478bd9Sstevel@tonic-gate if (make_bss(ofl, bsssize, bssalign, 0) == S_ERROR) 1322*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1323*7c478bd9Sstevel@tonic-gate } 1324*7c478bd9Sstevel@tonic-gate if (tlssize) { 1325*7c478bd9Sstevel@tonic-gate if (make_bss(ofl, tlssize, tlsalign, 1) == S_ERROR) 1326*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1327*7c478bd9Sstevel@tonic-gate } 1328*7c478bd9Sstevel@tonic-gate 1329*7c478bd9Sstevel@tonic-gate /* 1330*7c478bd9Sstevel@tonic-gate * Determine what entry point symbol we need, and if found save its 1331*7c478bd9Sstevel@tonic-gate * symbol descriptor so that we can update the ELF header entry with the 1332*7c478bd9Sstevel@tonic-gate * symbols value later (see update_oehdr). Make sure the symbol is 1333*7c478bd9Sstevel@tonic-gate * tagged to insure its update in case -s is in effect. Use any -e 1334*7c478bd9Sstevel@tonic-gate * option first, or the default entry points `_start' and `main'. 1335*7c478bd9Sstevel@tonic-gate */ 1336*7c478bd9Sstevel@tonic-gate if (ofl->ofl_entry) { 1337*7c478bd9Sstevel@tonic-gate if (((sdp = sym_find(ofl->ofl_entry, SYM_NOHASH, 0, ofl)) == 1338*7c478bd9Sstevel@tonic-gate NULL) || (sdp->sd_ref != REF_REL_NEED)) { 1339*7c478bd9Sstevel@tonic-gate eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_ENTRY), 1340*7c478bd9Sstevel@tonic-gate demangle((char *)ofl->ofl_entry)); 1341*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1342*7c478bd9Sstevel@tonic-gate } 1343*7c478bd9Sstevel@tonic-gate ofl->ofl_entry = (void *)sdp; 1344*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_UPREQD; 1345*7c478bd9Sstevel@tonic-gate if (sdp->sd_isc) { 1346*7c478bd9Sstevel@tonic-gate sdp->sd_isc->is_flags |= FLG_IS_SECTREF; 1347*7c478bd9Sstevel@tonic-gate sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF; 1348*7c478bd9Sstevel@tonic-gate } 1349*7c478bd9Sstevel@tonic-gate } else if (((sdp = sym_find(MSG_ORIG(MSG_SYM_START), 1350*7c478bd9Sstevel@tonic-gate SYM_NOHASH, 0, ofl)) != NULL) && (sdp->sd_ref == REF_REL_NEED)) { 1351*7c478bd9Sstevel@tonic-gate ofl->ofl_entry = (void *)sdp; 1352*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_UPREQD; 1353*7c478bd9Sstevel@tonic-gate if (sdp->sd_isc) { 1354*7c478bd9Sstevel@tonic-gate sdp->sd_isc->is_flags |= FLG_IS_SECTREF; 1355*7c478bd9Sstevel@tonic-gate sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF; 1356*7c478bd9Sstevel@tonic-gate } 1357*7c478bd9Sstevel@tonic-gate } else if (((sdp = sym_find(MSG_ORIG(MSG_SYM_MAIN), 1358*7c478bd9Sstevel@tonic-gate SYM_NOHASH, 0, ofl)) != NULL) && (sdp->sd_ref == REF_REL_NEED)) { 1359*7c478bd9Sstevel@tonic-gate ofl->ofl_entry = (void *)sdp; 1360*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_UPREQD; 1361*7c478bd9Sstevel@tonic-gate if (sdp->sd_isc) { 1362*7c478bd9Sstevel@tonic-gate sdp->sd_isc->is_flags |= FLG_IS_SECTREF; 1363*7c478bd9Sstevel@tonic-gate sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF; 1364*7c478bd9Sstevel@tonic-gate } 1365*7c478bd9Sstevel@tonic-gate } 1366*7c478bd9Sstevel@tonic-gate 1367*7c478bd9Sstevel@tonic-gate /* 1368*7c478bd9Sstevel@tonic-gate * If ld -zdtrace=<sym> was given, then validate that the 1369*7c478bd9Sstevel@tonic-gate * symbol is defined within the current object being built. 1370*7c478bd9Sstevel@tonic-gate */ 1371*7c478bd9Sstevel@tonic-gate if ((sdp = ofl->ofl_dtracesym) != 0) { 1372*7c478bd9Sstevel@tonic-gate if ((sdp->sd_ref != REF_REL_NEED) || 1373*7c478bd9Sstevel@tonic-gate (sdp->sd_shndx == SHN_UNDEF)) { 1374*7c478bd9Sstevel@tonic-gate eprintf(ERR_FATAL, MSG_INTL(MSG_SYM_DTRACE), 1375*7c478bd9Sstevel@tonic-gate demangle((char *)sdp->sd_name)); 1376*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1377*7c478bd9Sstevel@tonic-gate } 1378*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_UPREQD; 1379*7c478bd9Sstevel@tonic-gate if (sdp->sd_isc) { 1380*7c478bd9Sstevel@tonic-gate sdp->sd_isc->is_flags |= FLG_IS_SECTREF; 1381*7c478bd9Sstevel@tonic-gate sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF; 1382*7c478bd9Sstevel@tonic-gate } 1383*7c478bd9Sstevel@tonic-gate } 1384*7c478bd9Sstevel@tonic-gate 1385*7c478bd9Sstevel@tonic-gate /* 1386*7c478bd9Sstevel@tonic-gate * If we're required to record any needed dependencies versioning 1387*7c478bd9Sstevel@tonic-gate * information calculate it now that all symbols have been validated. 1388*7c478bd9Sstevel@tonic-gate */ 1389*7c478bd9Sstevel@tonic-gate if ((oflags & (FLG_OF_VERNEED | FLG_OF_NOVERSEC)) == FLG_OF_VERNEED) 1390*7c478bd9Sstevel@tonic-gate return (vers_check_need(ofl)); 1391*7c478bd9Sstevel@tonic-gate else 1392*7c478bd9Sstevel@tonic-gate return (1); 1393*7c478bd9Sstevel@tonic-gate } 1394*7c478bd9Sstevel@tonic-gate 1395*7c478bd9Sstevel@tonic-gate /* 1396*7c478bd9Sstevel@tonic-gate * qsort(3c) comparison function. As an optimization for associating weak 1397*7c478bd9Sstevel@tonic-gate * symbols to their strong counterparts sort global symbols according to their 1398*7c478bd9Sstevel@tonic-gate * address and binding. 1399*7c478bd9Sstevel@tonic-gate */ 1400*7c478bd9Sstevel@tonic-gate static int 1401*7c478bd9Sstevel@tonic-gate compare(const void * sdpp1, const void * sdpp2) 1402*7c478bd9Sstevel@tonic-gate { 1403*7c478bd9Sstevel@tonic-gate Sym_desc * sdp1 = *((Sym_desc **)sdpp1); 1404*7c478bd9Sstevel@tonic-gate Sym_desc * sdp2 = *((Sym_desc **)sdpp2); 1405*7c478bd9Sstevel@tonic-gate Sym * sym1, * sym2; 1406*7c478bd9Sstevel@tonic-gate uchar_t bind1, bind2; 1407*7c478bd9Sstevel@tonic-gate 1408*7c478bd9Sstevel@tonic-gate /* 1409*7c478bd9Sstevel@tonic-gate * Symbol descriptors may be zero, move these to the front of the 1410*7c478bd9Sstevel@tonic-gate * sorted array. 1411*7c478bd9Sstevel@tonic-gate */ 1412*7c478bd9Sstevel@tonic-gate if (sdp1 == 0) 1413*7c478bd9Sstevel@tonic-gate return (-1); 1414*7c478bd9Sstevel@tonic-gate if (sdp2 == 0) 1415*7c478bd9Sstevel@tonic-gate return (1); 1416*7c478bd9Sstevel@tonic-gate 1417*7c478bd9Sstevel@tonic-gate sym1 = sdp1->sd_sym; 1418*7c478bd9Sstevel@tonic-gate sym2 = sdp2->sd_sym; 1419*7c478bd9Sstevel@tonic-gate 1420*7c478bd9Sstevel@tonic-gate /* 1421*7c478bd9Sstevel@tonic-gate * Compare the symbols value (address). 1422*7c478bd9Sstevel@tonic-gate */ 1423*7c478bd9Sstevel@tonic-gate if (sym1->st_value > sym2->st_value) 1424*7c478bd9Sstevel@tonic-gate return (1); 1425*7c478bd9Sstevel@tonic-gate if (sym1->st_value < sym2->st_value) 1426*7c478bd9Sstevel@tonic-gate return (-1); 1427*7c478bd9Sstevel@tonic-gate 1428*7c478bd9Sstevel@tonic-gate bind1 = ELF_ST_BIND(sym1->st_info); 1429*7c478bd9Sstevel@tonic-gate bind2 = ELF_ST_BIND(sym2->st_info); 1430*7c478bd9Sstevel@tonic-gate 1431*7c478bd9Sstevel@tonic-gate /* 1432*7c478bd9Sstevel@tonic-gate * If two symbols have the same address place the weak symbol before 1433*7c478bd9Sstevel@tonic-gate * any strong counterpart. 1434*7c478bd9Sstevel@tonic-gate */ 1435*7c478bd9Sstevel@tonic-gate if (bind1 > bind2) 1436*7c478bd9Sstevel@tonic-gate return (-1); 1437*7c478bd9Sstevel@tonic-gate if (bind1 < bind2) 1438*7c478bd9Sstevel@tonic-gate return (1); 1439*7c478bd9Sstevel@tonic-gate 1440*7c478bd9Sstevel@tonic-gate return (0); 1441*7c478bd9Sstevel@tonic-gate } 1442*7c478bd9Sstevel@tonic-gate 1443*7c478bd9Sstevel@tonic-gate 1444*7c478bd9Sstevel@tonic-gate /* 1445*7c478bd9Sstevel@tonic-gate * Process the symbol table for the specified input file. At this point all 1446*7c478bd9Sstevel@tonic-gate * input sections from this input file have been assigned an input section 1447*7c478bd9Sstevel@tonic-gate * descriptor which is saved in the `ifl_isdesc' array. 1448*7c478bd9Sstevel@tonic-gate * 1449*7c478bd9Sstevel@tonic-gate * o local symbols are saved (as is) if the input file is a 1450*7c478bd9Sstevel@tonic-gate * relocatable object 1451*7c478bd9Sstevel@tonic-gate * 1452*7c478bd9Sstevel@tonic-gate * o global symbols are added to the linkers internal symbol 1453*7c478bd9Sstevel@tonic-gate * table if they are not already present, otherwise a symbol 1454*7c478bd9Sstevel@tonic-gate * resolution function is called upon to resolve the conflict. 1455*7c478bd9Sstevel@tonic-gate */ 1456*7c478bd9Sstevel@tonic-gate uintptr_t 1457*7c478bd9Sstevel@tonic-gate sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl) 1458*7c478bd9Sstevel@tonic-gate { 1459*7c478bd9Sstevel@tonic-gate Sym *sym = (Sym *)isc->is_indata->d_buf; 1460*7c478bd9Sstevel@tonic-gate Word *symshndx = 0; 1461*7c478bd9Sstevel@tonic-gate Shdr *shdr = isc->is_shdr; 1462*7c478bd9Sstevel@tonic-gate Sym_desc *sdp; 1463*7c478bd9Sstevel@tonic-gate size_t strsize; 1464*7c478bd9Sstevel@tonic-gate char *strs; 1465*7c478bd9Sstevel@tonic-gate uchar_t type, bind; 1466*7c478bd9Sstevel@tonic-gate Word ndx, hash, local, total; 1467*7c478bd9Sstevel@tonic-gate Half etype = ifl->ifl_ehdr->e_type; 1468*7c478bd9Sstevel@tonic-gate const char *symsecname, *strsecname; 1469*7c478bd9Sstevel@tonic-gate avl_index_t where; 1470*7c478bd9Sstevel@tonic-gate 1471*7c478bd9Sstevel@tonic-gate /* 1472*7c478bd9Sstevel@tonic-gate * Its possible that a file may contain more that one symbol table, 1473*7c478bd9Sstevel@tonic-gate * ie. .dynsym and .symtab in a shared library. Only process the first 1474*7c478bd9Sstevel@tonic-gate * table (here, we assume .dynsym comes before .symtab). 1475*7c478bd9Sstevel@tonic-gate */ 1476*7c478bd9Sstevel@tonic-gate if (ifl->ifl_symscnt) 1477*7c478bd9Sstevel@tonic-gate return (1); 1478*7c478bd9Sstevel@tonic-gate 1479*7c478bd9Sstevel@tonic-gate if (isc->is_symshndx) 1480*7c478bd9Sstevel@tonic-gate symshndx = isc->is_symshndx->is_indata->d_buf; 1481*7c478bd9Sstevel@tonic-gate 1482*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_process(ifl)); 1483*7c478bd9Sstevel@tonic-gate 1484*7c478bd9Sstevel@tonic-gate if (isc->is_name) 1485*7c478bd9Sstevel@tonic-gate symsecname = isc->is_name; 1486*7c478bd9Sstevel@tonic-gate else 1487*7c478bd9Sstevel@tonic-gate symsecname = MSG_ORIG(MSG_STR_EMPTY); 1488*7c478bd9Sstevel@tonic-gate 1489*7c478bd9Sstevel@tonic-gate /* 1490*7c478bd9Sstevel@tonic-gate * From the symbol tables section header information determine which 1491*7c478bd9Sstevel@tonic-gate * strtab table is needed to locate the actual symbol names. 1492*7c478bd9Sstevel@tonic-gate */ 1493*7c478bd9Sstevel@tonic-gate if (ifl->ifl_flags & FLG_IF_HSTRTAB) { 1494*7c478bd9Sstevel@tonic-gate ndx = shdr->sh_link; 1495*7c478bd9Sstevel@tonic-gate if ((ndx == 0) || (ndx >= ifl->ifl_shnum)) { 1496*7c478bd9Sstevel@tonic-gate eprintf(ERR_FATAL, MSG_INTL(MSG_FIL_INVSHLINK), 1497*7c478bd9Sstevel@tonic-gate ifl->ifl_name, symsecname, EC_XWORD(ndx)); 1498*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1499*7c478bd9Sstevel@tonic-gate } 1500*7c478bd9Sstevel@tonic-gate strsize = ifl->ifl_isdesc[ndx]->is_shdr->sh_size; 1501*7c478bd9Sstevel@tonic-gate strs = ifl->ifl_isdesc[ndx]->is_indata->d_buf; 1502*7c478bd9Sstevel@tonic-gate if (ifl->ifl_isdesc[ndx]->is_name) 1503*7c478bd9Sstevel@tonic-gate strsecname = ifl->ifl_isdesc[ndx]->is_name; 1504*7c478bd9Sstevel@tonic-gate else 1505*7c478bd9Sstevel@tonic-gate strsecname = MSG_ORIG(MSG_STR_EMPTY); 1506*7c478bd9Sstevel@tonic-gate } else { 1507*7c478bd9Sstevel@tonic-gate /* 1508*7c478bd9Sstevel@tonic-gate * There is no string table section in this input file 1509*7c478bd9Sstevel@tonic-gate * although there are symbols in this symbol table section. 1510*7c478bd9Sstevel@tonic-gate * This means that these symbols do not have names. 1511*7c478bd9Sstevel@tonic-gate * Currently, only scratch register symbols are allowed 1512*7c478bd9Sstevel@tonic-gate * not to have names. 1513*7c478bd9Sstevel@tonic-gate */ 1514*7c478bd9Sstevel@tonic-gate strsize = 0; 1515*7c478bd9Sstevel@tonic-gate strs = (char *)MSG_ORIG(MSG_STR_EMPTY); 1516*7c478bd9Sstevel@tonic-gate strsecname = MSG_ORIG(MSG_STR_EMPTY); 1517*7c478bd9Sstevel@tonic-gate } 1518*7c478bd9Sstevel@tonic-gate 1519*7c478bd9Sstevel@tonic-gate /* 1520*7c478bd9Sstevel@tonic-gate * Determine the number of local symbols together with the total 1521*7c478bd9Sstevel@tonic-gate * number we have to process. 1522*7c478bd9Sstevel@tonic-gate */ 1523*7c478bd9Sstevel@tonic-gate total = (Word)(shdr->sh_size / shdr->sh_entsize); 1524*7c478bd9Sstevel@tonic-gate local = shdr->sh_info; 1525*7c478bd9Sstevel@tonic-gate 1526*7c478bd9Sstevel@tonic-gate /* 1527*7c478bd9Sstevel@tonic-gate * Allocate a symbol table index array and a local symbol array 1528*7c478bd9Sstevel@tonic-gate * (global symbols are processed and added to the ofl->ofl_symbkt[] 1529*7c478bd9Sstevel@tonic-gate * array). If we are dealing with a relocatable object, allocate the 1530*7c478bd9Sstevel@tonic-gate * local symbol descriptors. If this isn't a relocatable object we 1531*7c478bd9Sstevel@tonic-gate * still have to process any shared object locals to determine if any 1532*7c478bd9Sstevel@tonic-gate * register symbols exist. Although these aren't added to the output 1533*7c478bd9Sstevel@tonic-gate * image, they are used as part of symbol resolution. 1534*7c478bd9Sstevel@tonic-gate */ 1535*7c478bd9Sstevel@tonic-gate if ((ifl->ifl_oldndx = libld_malloc((size_t)(total * 1536*7c478bd9Sstevel@tonic-gate sizeof (Sym_desc *)))) == 0) 1537*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1538*7c478bd9Sstevel@tonic-gate if ((etype == ET_REL) && local) { 1539*7c478bd9Sstevel@tonic-gate if ((ifl->ifl_locs = 1540*7c478bd9Sstevel@tonic-gate libld_calloc(sizeof (Sym_desc), local)) == 0) 1541*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1542*7c478bd9Sstevel@tonic-gate /* LINTED */ 1543*7c478bd9Sstevel@tonic-gate ifl->ifl_locscnt = (Word)local; 1544*7c478bd9Sstevel@tonic-gate } 1545*7c478bd9Sstevel@tonic-gate ifl->ifl_symscnt = total; 1546*7c478bd9Sstevel@tonic-gate 1547*7c478bd9Sstevel@tonic-gate /* 1548*7c478bd9Sstevel@tonic-gate * If there are local symbols to save add them to the symbol table 1549*7c478bd9Sstevel@tonic-gate * index array. 1550*7c478bd9Sstevel@tonic-gate */ 1551*7c478bd9Sstevel@tonic-gate if (local) { 1552*7c478bd9Sstevel@tonic-gate for (sym++, ndx = 1; ndx < local; sym++, ndx++) { 1553*7c478bd9Sstevel@tonic-gate Word shndx, sdflags = FLG_SY_CLEAN; 1554*7c478bd9Sstevel@tonic-gate const char *name; 1555*7c478bd9Sstevel@tonic-gate Sym_desc *rsdp; 1556*7c478bd9Sstevel@tonic-gate 1557*7c478bd9Sstevel@tonic-gate /* 1558*7c478bd9Sstevel@tonic-gate * Determine the associated section index. 1559*7c478bd9Sstevel@tonic-gate */ 1560*7c478bd9Sstevel@tonic-gate if (symshndx && (sym->st_shndx == SHN_XINDEX)) 1561*7c478bd9Sstevel@tonic-gate shndx = symshndx[ndx]; 1562*7c478bd9Sstevel@tonic-gate else if ((shndx = sym->st_shndx) >= SHN_LORESERVE) 1563*7c478bd9Sstevel@tonic-gate sdflags |= FLG_SY_SPECSEC; 1564*7c478bd9Sstevel@tonic-gate 1565*7c478bd9Sstevel@tonic-gate /* 1566*7c478bd9Sstevel@tonic-gate * Check if st_name has a valid value or not. 1567*7c478bd9Sstevel@tonic-gate */ 1568*7c478bd9Sstevel@tonic-gate if ((name = string(ifl, sym, strs, strsize, ndx, 1569*7c478bd9Sstevel@tonic-gate shndx, symsecname, strsecname, &sdflags)) == 0) { 1570*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_FATAL; 1571*7c478bd9Sstevel@tonic-gate continue; 1572*7c478bd9Sstevel@tonic-gate } 1573*7c478bd9Sstevel@tonic-gate 1574*7c478bd9Sstevel@tonic-gate /* 1575*7c478bd9Sstevel@tonic-gate * If this local symbol table originates from a shared 1576*7c478bd9Sstevel@tonic-gate * object, then we're only interested in recording 1577*7c478bd9Sstevel@tonic-gate * register symbols. As local symbol descriptors aren't 1578*7c478bd9Sstevel@tonic-gate * allocated for shared objects, one will be allocated 1579*7c478bd9Sstevel@tonic-gate * to associated with the register symbol. This symbol 1580*7c478bd9Sstevel@tonic-gate * won't become part of the output image, but we must 1581*7c478bd9Sstevel@tonic-gate * process it to test for register conflicts. 1582*7c478bd9Sstevel@tonic-gate */ 1583*7c478bd9Sstevel@tonic-gate rsdp = sdp = 0; 1584*7c478bd9Sstevel@tonic-gate if (sdflags & FLG_SY_REGSYM) { 1585*7c478bd9Sstevel@tonic-gate if ((rsdp = reg_find(sym, ofl)) != 0) { 1586*7c478bd9Sstevel@tonic-gate /* 1587*7c478bd9Sstevel@tonic-gate * The fact that another register def- 1588*7c478bd9Sstevel@tonic-gate * inition has been found is fatal. 1589*7c478bd9Sstevel@tonic-gate * Call the verification routine to get 1590*7c478bd9Sstevel@tonic-gate * the error message and move on. 1591*7c478bd9Sstevel@tonic-gate */ 1592*7c478bd9Sstevel@tonic-gate (void) reg_check(rsdp, sym, name, 1593*7c478bd9Sstevel@tonic-gate ifl, ofl); 1594*7c478bd9Sstevel@tonic-gate continue; 1595*7c478bd9Sstevel@tonic-gate } 1596*7c478bd9Sstevel@tonic-gate 1597*7c478bd9Sstevel@tonic-gate if (etype == ET_DYN) { 1598*7c478bd9Sstevel@tonic-gate if ((sdp = libld_calloc( 1599*7c478bd9Sstevel@tonic-gate sizeof (Sym_desc), 1)) == 0) 1600*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1601*7c478bd9Sstevel@tonic-gate sdp->sd_ref = REF_DYN_SEEN; 1602*7c478bd9Sstevel@tonic-gate } 1603*7c478bd9Sstevel@tonic-gate } else if (etype == ET_DYN) 1604*7c478bd9Sstevel@tonic-gate continue; 1605*7c478bd9Sstevel@tonic-gate 1606*7c478bd9Sstevel@tonic-gate /* 1607*7c478bd9Sstevel@tonic-gate * Fill in the remaining symbol descriptor information. 1608*7c478bd9Sstevel@tonic-gate */ 1609*7c478bd9Sstevel@tonic-gate if (sdp == 0) { 1610*7c478bd9Sstevel@tonic-gate sdp = &(ifl->ifl_locs[ndx]); 1611*7c478bd9Sstevel@tonic-gate sdp->sd_ref = REF_REL_NEED; 1612*7c478bd9Sstevel@tonic-gate } 1613*7c478bd9Sstevel@tonic-gate if (rsdp == 0) { 1614*7c478bd9Sstevel@tonic-gate sdp->sd_name = name; 1615*7c478bd9Sstevel@tonic-gate sdp->sd_sym = sym; 1616*7c478bd9Sstevel@tonic-gate sdp->sd_shndx = shndx; 1617*7c478bd9Sstevel@tonic-gate sdp->sd_flags = sdflags; 1618*7c478bd9Sstevel@tonic-gate sdp->sd_file = ifl; 1619*7c478bd9Sstevel@tonic-gate ifl->ifl_oldndx[ndx] = sdp; 1620*7c478bd9Sstevel@tonic-gate } 1621*7c478bd9Sstevel@tonic-gate 1622*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_entry(ndx, sdp)); 1623*7c478bd9Sstevel@tonic-gate 1624*7c478bd9Sstevel@tonic-gate /* 1625*7c478bd9Sstevel@tonic-gate * Reclassify any SHN_SUNW_IGNORE symbols to SHN_UNDEF 1626*7c478bd9Sstevel@tonic-gate * so as to simplify future processing. 1627*7c478bd9Sstevel@tonic-gate */ 1628*7c478bd9Sstevel@tonic-gate if (shndx == SHN_SUNW_IGNORE) { 1629*7c478bd9Sstevel@tonic-gate sdp->sd_shndx = shndx = SHN_UNDEF; 1630*7c478bd9Sstevel@tonic-gate sdp->sd_flags1 |= 1631*7c478bd9Sstevel@tonic-gate (FLG_SY1_IGNORE | FLG_SY1_ELIM); 1632*7c478bd9Sstevel@tonic-gate } 1633*7c478bd9Sstevel@tonic-gate 1634*7c478bd9Sstevel@tonic-gate /* 1635*7c478bd9Sstevel@tonic-gate * Process any register symbols. 1636*7c478bd9Sstevel@tonic-gate */ 1637*7c478bd9Sstevel@tonic-gate if (sdp->sd_flags & FLG_SY_REGSYM) { 1638*7c478bd9Sstevel@tonic-gate /* 1639*7c478bd9Sstevel@tonic-gate * Add a diagnostic to indicate we've caught a 1640*7c478bd9Sstevel@tonic-gate * register symbol, as this can be useful if a 1641*7c478bd9Sstevel@tonic-gate * register conflict is later discovered. 1642*7c478bd9Sstevel@tonic-gate */ 1643*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_entered(ifl->ifl_ehdr, 1644*7c478bd9Sstevel@tonic-gate sym, sdp)); 1645*7c478bd9Sstevel@tonic-gate 1646*7c478bd9Sstevel@tonic-gate /* 1647*7c478bd9Sstevel@tonic-gate * If this register symbol hasn't already been 1648*7c478bd9Sstevel@tonic-gate * recorded, enter it now. 1649*7c478bd9Sstevel@tonic-gate */ 1650*7c478bd9Sstevel@tonic-gate if ((rsdp == 0) && (reg_enter(sdp, ofl) == 0)) 1651*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1652*7c478bd9Sstevel@tonic-gate } 1653*7c478bd9Sstevel@tonic-gate 1654*7c478bd9Sstevel@tonic-gate /* 1655*7c478bd9Sstevel@tonic-gate * Assign an input section. 1656*7c478bd9Sstevel@tonic-gate */ 1657*7c478bd9Sstevel@tonic-gate if ((shndx != SHN_UNDEF) && 1658*7c478bd9Sstevel@tonic-gate ((sdp->sd_flags & FLG_SY_SPECSEC) == 0)) 1659*7c478bd9Sstevel@tonic-gate sdp->sd_isc = ifl->ifl_isdesc[shndx]; 1660*7c478bd9Sstevel@tonic-gate 1661*7c478bd9Sstevel@tonic-gate /* 1662*7c478bd9Sstevel@tonic-gate * If this symbol falls within the range of a section 1663*7c478bd9Sstevel@tonic-gate * being discarded, then discard the symbol itself. 1664*7c478bd9Sstevel@tonic-gate * There is no reason to keep this local symbol. 1665*7c478bd9Sstevel@tonic-gate */ 1666*7c478bd9Sstevel@tonic-gate if (sdp->sd_isc && 1667*7c478bd9Sstevel@tonic-gate (sdp->sd_isc->is_flags & FLG_IS_DISCARD)) { 1668*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_ISDISC; 1669*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_discarded(sdp, sdp->sd_isc)); 1670*7c478bd9Sstevel@tonic-gate continue; 1671*7c478bd9Sstevel@tonic-gate } 1672*7c478bd9Sstevel@tonic-gate 1673*7c478bd9Sstevel@tonic-gate /* 1674*7c478bd9Sstevel@tonic-gate * Skip any section symbols as new versions of these 1675*7c478bd9Sstevel@tonic-gate * will be created. 1676*7c478bd9Sstevel@tonic-gate */ 1677*7c478bd9Sstevel@tonic-gate if ((type = ELF_ST_TYPE(sym->st_info)) == STT_SECTION) { 1678*7c478bd9Sstevel@tonic-gate if (shndx == SHN_UNDEF) { 1679*7c478bd9Sstevel@tonic-gate eprintf(ERR_WARNING, 1680*7c478bd9Sstevel@tonic-gate MSG_INTL(MSG_SYM_INVSHNDX), 1681*7c478bd9Sstevel@tonic-gate demangle(sdp->sd_name), 1682*7c478bd9Sstevel@tonic-gate ifl->ifl_name, 1683*7c478bd9Sstevel@tonic-gate conv_shndx_str(shndx)); 1684*7c478bd9Sstevel@tonic-gate } 1685*7c478bd9Sstevel@tonic-gate continue; 1686*7c478bd9Sstevel@tonic-gate } 1687*7c478bd9Sstevel@tonic-gate 1688*7c478bd9Sstevel@tonic-gate /* 1689*7c478bd9Sstevel@tonic-gate * Sanity check for TLS 1690*7c478bd9Sstevel@tonic-gate */ 1691*7c478bd9Sstevel@tonic-gate if ((sym->st_size != 0) && 1692*7c478bd9Sstevel@tonic-gate ((type == STT_TLS) && (shndx != SHN_COMMON))) { 1693*7c478bd9Sstevel@tonic-gate Is_desc *isp = sdp->sd_isc; 1694*7c478bd9Sstevel@tonic-gate 1695*7c478bd9Sstevel@tonic-gate if ((isp == 0) || (isp->is_shdr == 0) || 1696*7c478bd9Sstevel@tonic-gate ((isp->is_shdr->sh_flags & SHF_TLS) == 0)) { 1697*7c478bd9Sstevel@tonic-gate eprintf(ERR_FATAL, 1698*7c478bd9Sstevel@tonic-gate MSG_INTL(MSG_SYM_TLS), 1699*7c478bd9Sstevel@tonic-gate demangle(sdp->sd_name), 1700*7c478bd9Sstevel@tonic-gate ifl->ifl_name); 1701*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_FATAL; 1702*7c478bd9Sstevel@tonic-gate continue; 1703*7c478bd9Sstevel@tonic-gate } 1704*7c478bd9Sstevel@tonic-gate } 1705*7c478bd9Sstevel@tonic-gate 1706*7c478bd9Sstevel@tonic-gate /* 1707*7c478bd9Sstevel@tonic-gate * Carry our some basic sanity checks (these are just 1708*7c478bd9Sstevel@tonic-gate * some of the erroneous symbol entries we've come 1709*7c478bd9Sstevel@tonic-gate * across, there's probably a lot more). The symbol 1710*7c478bd9Sstevel@tonic-gate * will not be carried forward to the output file, which 1711*7c478bd9Sstevel@tonic-gate * won't be a problem unless a relocation is required 1712*7c478bd9Sstevel@tonic-gate * against it. 1713*7c478bd9Sstevel@tonic-gate */ 1714*7c478bd9Sstevel@tonic-gate if (((sdp->sd_flags & FLG_SY_SPECSEC) && 1715*7c478bd9Sstevel@tonic-gate ((shndx == SHN_COMMON)) || 1716*7c478bd9Sstevel@tonic-gate ((type == STT_FILE) && (shndx != SHN_ABS))) || 1717*7c478bd9Sstevel@tonic-gate (sdp->sd_isc && (sdp->sd_isc->is_osdesc == 0))) { 1718*7c478bd9Sstevel@tonic-gate eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_INVSHNDX), 1719*7c478bd9Sstevel@tonic-gate demangle(sdp->sd_name), ifl->ifl_name, 1720*7c478bd9Sstevel@tonic-gate conv_shndx_str(shndx)); 1721*7c478bd9Sstevel@tonic-gate sdp->sd_isc = NULL; 1722*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_INVALID; 1723*7c478bd9Sstevel@tonic-gate continue; 1724*7c478bd9Sstevel@tonic-gate } 1725*7c478bd9Sstevel@tonic-gate 1726*7c478bd9Sstevel@tonic-gate /* 1727*7c478bd9Sstevel@tonic-gate * As these local symbols will become part of the output 1728*7c478bd9Sstevel@tonic-gate * image, record their number and name string size. 1729*7c478bd9Sstevel@tonic-gate * Globals are counted after all input file processing 1730*7c478bd9Sstevel@tonic-gate * (and hence symbol resolution) is complete during 1731*7c478bd9Sstevel@tonic-gate * sym_validate(). 1732*7c478bd9Sstevel@tonic-gate */ 1733*7c478bd9Sstevel@tonic-gate if (!(ofl->ofl_flags1 & FLG_OF1_REDLSYM)) { 1734*7c478bd9Sstevel@tonic-gate ofl->ofl_locscnt++; 1735*7c478bd9Sstevel@tonic-gate 1736*7c478bd9Sstevel@tonic-gate if ((((sdp->sd_flags & FLG_SY_REGSYM) == 0) || 1737*7c478bd9Sstevel@tonic-gate sym->st_name) && (st_insert(ofl->ofl_strtab, 1738*7c478bd9Sstevel@tonic-gate sdp->sd_name) == -1)) 1739*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1740*7c478bd9Sstevel@tonic-gate } 1741*7c478bd9Sstevel@tonic-gate } 1742*7c478bd9Sstevel@tonic-gate } 1743*7c478bd9Sstevel@tonic-gate 1744*7c478bd9Sstevel@tonic-gate /* 1745*7c478bd9Sstevel@tonic-gate * Now scan the global symbols entering them in the internal symbol 1746*7c478bd9Sstevel@tonic-gate * table or resolving them as necessary. 1747*7c478bd9Sstevel@tonic-gate */ 1748*7c478bd9Sstevel@tonic-gate sym = (Sym *)isc->is_indata->d_buf; 1749*7c478bd9Sstevel@tonic-gate sym += local; 1750*7c478bd9Sstevel@tonic-gate /* LINTED */ 1751*7c478bd9Sstevel@tonic-gate for (ndx = (int)local; ndx < total; sym++, ndx++) { 1752*7c478bd9Sstevel@tonic-gate const char *name; 1753*7c478bd9Sstevel@tonic-gate Word shndx, sdflags = 0; 1754*7c478bd9Sstevel@tonic-gate 1755*7c478bd9Sstevel@tonic-gate /* 1756*7c478bd9Sstevel@tonic-gate * Determine the associated section index. 1757*7c478bd9Sstevel@tonic-gate */ 1758*7c478bd9Sstevel@tonic-gate if (symshndx && (sym->st_shndx == SHN_XINDEX)) { 1759*7c478bd9Sstevel@tonic-gate shndx = symshndx[ndx]; 1760*7c478bd9Sstevel@tonic-gate } else { 1761*7c478bd9Sstevel@tonic-gate shndx = sym->st_shndx; 1762*7c478bd9Sstevel@tonic-gate if (sym->st_shndx >= SHN_LORESERVE) 1763*7c478bd9Sstevel@tonic-gate sdflags |= FLG_SY_SPECSEC; 1764*7c478bd9Sstevel@tonic-gate } 1765*7c478bd9Sstevel@tonic-gate 1766*7c478bd9Sstevel@tonic-gate /* 1767*7c478bd9Sstevel@tonic-gate * Check if st_name has a valid value or not. 1768*7c478bd9Sstevel@tonic-gate */ 1769*7c478bd9Sstevel@tonic-gate if ((name = string(ifl, sym, strs, strsize, ndx, shndx, 1770*7c478bd9Sstevel@tonic-gate symsecname, strsecname, &sdflags)) == 0) { 1771*7c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_FATAL; 1772*7c478bd9Sstevel@tonic-gate continue; 1773*7c478bd9Sstevel@tonic-gate } 1774*7c478bd9Sstevel@tonic-gate 1775*7c478bd9Sstevel@tonic-gate /* 1776*7c478bd9Sstevel@tonic-gate * The linker itself will generate symbols for _end, _etext, 1777*7c478bd9Sstevel@tonic-gate * _edata, _DYNAMIC and _PROCEDURE_LINKAGE_TABLE_, so don't 1778*7c478bd9Sstevel@tonic-gate * bother entering these symbols from shared objects. This 1779*7c478bd9Sstevel@tonic-gate * results in some wasted resolution processing, which is hard 1780*7c478bd9Sstevel@tonic-gate * to feel, but if nothing else, pollutes diagnostic relocation 1781*7c478bd9Sstevel@tonic-gate * output. 1782*7c478bd9Sstevel@tonic-gate */ 1783*7c478bd9Sstevel@tonic-gate if (name[0] && (etype == ET_DYN) && (sym->st_size == 0) && 1784*7c478bd9Sstevel@tonic-gate (ELF_ST_TYPE(sym->st_info) == STT_OBJECT) && 1785*7c478bd9Sstevel@tonic-gate (name[0] == '_') && ((name[1] == 'e') || 1786*7c478bd9Sstevel@tonic-gate (name[1] == 'D') || (name[1] == 'P')) && 1787*7c478bd9Sstevel@tonic-gate ((strcmp(name, MSG_ORIG(MSG_SYM_ETEXT_U)) == 0) || 1788*7c478bd9Sstevel@tonic-gate (strcmp(name, MSG_ORIG(MSG_SYM_EDATA_U)) == 0) || 1789*7c478bd9Sstevel@tonic-gate (strcmp(name, MSG_ORIG(MSG_SYM_END_U)) == 0) || 1790*7c478bd9Sstevel@tonic-gate (strcmp(name, MSG_ORIG(MSG_SYM_DYNAMIC_U)) == 0) || 1791*7c478bd9Sstevel@tonic-gate (strcmp(name, MSG_ORIG(MSG_SYM_PLKTBL_U)) == 0))) { 1792*7c478bd9Sstevel@tonic-gate ifl->ifl_oldndx[ndx] = 0; 1793*7c478bd9Sstevel@tonic-gate continue; 1794*7c478bd9Sstevel@tonic-gate } 1795*7c478bd9Sstevel@tonic-gate 1796*7c478bd9Sstevel@tonic-gate /* 1797*7c478bd9Sstevel@tonic-gate * Determine and validate the symbols binding. 1798*7c478bd9Sstevel@tonic-gate */ 1799*7c478bd9Sstevel@tonic-gate bind = ELF_ST_BIND(sym->st_info); 1800*7c478bd9Sstevel@tonic-gate if ((bind != STB_GLOBAL) && (bind != STB_WEAK)) { 1801*7c478bd9Sstevel@tonic-gate eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_NONGLOB), 1802*7c478bd9Sstevel@tonic-gate demangle(name), ifl->ifl_name, 1803*7c478bd9Sstevel@tonic-gate conv_info_bind_str(bind)); 1804*7c478bd9Sstevel@tonic-gate continue; 1805*7c478bd9Sstevel@tonic-gate } 1806*7c478bd9Sstevel@tonic-gate 1807*7c478bd9Sstevel@tonic-gate /* 1808*7c478bd9Sstevel@tonic-gate * If this symbol falls within the range of a section being 1809*7c478bd9Sstevel@tonic-gate * discarded, then discard the symbol itself. 1810*7c478bd9Sstevel@tonic-gate */ 1811*7c478bd9Sstevel@tonic-gate if (((sdflags & FLG_SY_SPECSEC) == 0) && 1812*7c478bd9Sstevel@tonic-gate (shndx != SHN_UNDEF)) { 1813*7c478bd9Sstevel@tonic-gate Is_desc *isp; 1814*7c478bd9Sstevel@tonic-gate 1815*7c478bd9Sstevel@tonic-gate if (shndx >= ifl->ifl_shnum) { 1816*7c478bd9Sstevel@tonic-gate /* 1817*7c478bd9Sstevel@tonic-gate * Carry our some basic sanity checks 1818*7c478bd9Sstevel@tonic-gate * The symbol will not be carried forward to 1819*7c478bd9Sstevel@tonic-gate * the output file, which won't be a problem 1820*7c478bd9Sstevel@tonic-gate * unless a relocation is required against it. 1821*7c478bd9Sstevel@tonic-gate */ 1822*7c478bd9Sstevel@tonic-gate eprintf(ERR_WARNING, MSG_INTL(MSG_SYM_INVSHNDX), 1823*7c478bd9Sstevel@tonic-gate demangle(name), ifl->ifl_name, 1824*7c478bd9Sstevel@tonic-gate conv_shndx_str(shndx)); 1825*7c478bd9Sstevel@tonic-gate continue; 1826*7c478bd9Sstevel@tonic-gate } 1827*7c478bd9Sstevel@tonic-gate 1828*7c478bd9Sstevel@tonic-gate isp = ifl->ifl_isdesc[shndx]; 1829*7c478bd9Sstevel@tonic-gate if (isp && (isp->is_flags & FLG_IS_DISCARD)) { 1830*7c478bd9Sstevel@tonic-gate if ((sdp = 1831*7c478bd9Sstevel@tonic-gate libld_calloc(sizeof (Sym_desc), 1)) == 0) 1832*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1833*7c478bd9Sstevel@tonic-gate 1834*7c478bd9Sstevel@tonic-gate /* 1835*7c478bd9Sstevel@tonic-gate * Create a dummy symbol entry so that if we 1836*7c478bd9Sstevel@tonic-gate * find any references to this discarded symbol 1837*7c478bd9Sstevel@tonic-gate * we can compensate. 1838*7c478bd9Sstevel@tonic-gate */ 1839*7c478bd9Sstevel@tonic-gate sdp->sd_name = name; 1840*7c478bd9Sstevel@tonic-gate sdp->sd_sym = sym; 1841*7c478bd9Sstevel@tonic-gate sdp->sd_file = ifl; 1842*7c478bd9Sstevel@tonic-gate sdp->sd_isc = isp; 1843*7c478bd9Sstevel@tonic-gate sdp->sd_flags = FLG_SY_ISDISC; 1844*7c478bd9Sstevel@tonic-gate ifl->ifl_oldndx[ndx] = sdp; 1845*7c478bd9Sstevel@tonic-gate 1846*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_discarded(sdp, sdp->sd_isc)); 1847*7c478bd9Sstevel@tonic-gate continue; 1848*7c478bd9Sstevel@tonic-gate } 1849*7c478bd9Sstevel@tonic-gate } 1850*7c478bd9Sstevel@tonic-gate 1851*7c478bd9Sstevel@tonic-gate /* 1852*7c478bd9Sstevel@tonic-gate * If the symbol does not already exist in the internal symbol 1853*7c478bd9Sstevel@tonic-gate * table add it, otherwise resolve the conflict. If the symbol 1854*7c478bd9Sstevel@tonic-gate * from this file is kept, retain its symbol table index for 1855*7c478bd9Sstevel@tonic-gate * possible use in associating a global alias. 1856*7c478bd9Sstevel@tonic-gate */ 1857*7c478bd9Sstevel@tonic-gate /* LINTED */ 1858*7c478bd9Sstevel@tonic-gate hash = (Word)elf_hash((const char *)name); 1859*7c478bd9Sstevel@tonic-gate if ((sdp = sym_find(name, hash, &where, ofl)) == NULL) { 1860*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_global(ndx, name)); 1861*7c478bd9Sstevel@tonic-gate if ((sdp = sym_enter(name, sym, hash, ifl, ofl, ndx, 1862*7c478bd9Sstevel@tonic-gate shndx, sdflags, 0, &where)) == (Sym_desc *)S_ERROR) 1863*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1864*7c478bd9Sstevel@tonic-gate 1865*7c478bd9Sstevel@tonic-gate } else if (sym_resolve(sdp, sym, ifl, ofl, ndx, shndx, 1866*7c478bd9Sstevel@tonic-gate sdflags) == S_ERROR) 1867*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1868*7c478bd9Sstevel@tonic-gate 1869*7c478bd9Sstevel@tonic-gate /* 1870*7c478bd9Sstevel@tonic-gate * After we've compared a defined symbol in one shared 1871*7c478bd9Sstevel@tonic-gate * object, flag the symbol so we don't compare it again. 1872*7c478bd9Sstevel@tonic-gate */ 1873*7c478bd9Sstevel@tonic-gate if ((etype == ET_DYN) && (shndx != SHN_UNDEF) && 1874*7c478bd9Sstevel@tonic-gate ((sdp->sd_flags & FLG_SY_SOFOUND) == 0)) 1875*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_SOFOUND; 1876*7c478bd9Sstevel@tonic-gate 1877*7c478bd9Sstevel@tonic-gate /* 1878*7c478bd9Sstevel@tonic-gate * If the symbol is accepted from this file retain the symbol 1879*7c478bd9Sstevel@tonic-gate * index for possible use in aliasing. 1880*7c478bd9Sstevel@tonic-gate */ 1881*7c478bd9Sstevel@tonic-gate if (sdp->sd_file == ifl) 1882*7c478bd9Sstevel@tonic-gate sdp->sd_symndx = ndx; 1883*7c478bd9Sstevel@tonic-gate 1884*7c478bd9Sstevel@tonic-gate ifl->ifl_oldndx[ndx] = sdp; 1885*7c478bd9Sstevel@tonic-gate 1886*7c478bd9Sstevel@tonic-gate /* 1887*7c478bd9Sstevel@tonic-gate * If we've accepted a register symbol, continue to validate 1888*7c478bd9Sstevel@tonic-gate * it. 1889*7c478bd9Sstevel@tonic-gate */ 1890*7c478bd9Sstevel@tonic-gate if (sdp->sd_flags & FLG_SY_REGSYM) { 1891*7c478bd9Sstevel@tonic-gate Sym_desc *rsdp; 1892*7c478bd9Sstevel@tonic-gate 1893*7c478bd9Sstevel@tonic-gate if ((rsdp = reg_find(sdp->sd_sym, ofl)) == 0) { 1894*7c478bd9Sstevel@tonic-gate if (reg_enter(sdp, ofl) == 0) 1895*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1896*7c478bd9Sstevel@tonic-gate } else if (rsdp != sdp) { 1897*7c478bd9Sstevel@tonic-gate (void) reg_check(rsdp, sdp->sd_sym, 1898*7c478bd9Sstevel@tonic-gate sdp->sd_name, ifl, ofl); 1899*7c478bd9Sstevel@tonic-gate } 1900*7c478bd9Sstevel@tonic-gate } 1901*7c478bd9Sstevel@tonic-gate } 1902*7c478bd9Sstevel@tonic-gate 1903*7c478bd9Sstevel@tonic-gate /* 1904*7c478bd9Sstevel@tonic-gate * If this is a shared object scan the globals one more time and 1905*7c478bd9Sstevel@tonic-gate * associate any weak/global associations. This association is needed 1906*7c478bd9Sstevel@tonic-gate * should the weak definition satisfy a reference in the dynamic 1907*7c478bd9Sstevel@tonic-gate * executable: 1908*7c478bd9Sstevel@tonic-gate * 1909*7c478bd9Sstevel@tonic-gate * o if the symbol is a data item it will be copied to the 1910*7c478bd9Sstevel@tonic-gate * executables address space, thus we must also reassociate the 1911*7c478bd9Sstevel@tonic-gate * alias symbol with its new location in the executable. 1912*7c478bd9Sstevel@tonic-gate * 1913*7c478bd9Sstevel@tonic-gate * o if the symbol is a function then we may need to promote the 1914*7c478bd9Sstevel@tonic-gate * symbols binding from undefined weak to undefined, otherwise the 1915*7c478bd9Sstevel@tonic-gate * run-time linker will not generate the correct relocation error 1916*7c478bd9Sstevel@tonic-gate * should the symbol not be found. 1917*7c478bd9Sstevel@tonic-gate * 1918*7c478bd9Sstevel@tonic-gate * The true association between a weak/strong symbol pair is that both 1919*7c478bd9Sstevel@tonic-gate * symbol entries are identical, thus first we created a sorted symbol 1920*7c478bd9Sstevel@tonic-gate * list keyed off of the symbols value (if the value is the same chances 1921*7c478bd9Sstevel@tonic-gate * are the rest of the symbols data is). This list is then scanned for 1922*7c478bd9Sstevel@tonic-gate * weak symbols, and if one is found then any strong association will 1923*7c478bd9Sstevel@tonic-gate * exist in the following entries. Thus we just have to scan one 1924*7c478bd9Sstevel@tonic-gate * (typical single alias) or more (in the uncommon instance of multiple 1925*7c478bd9Sstevel@tonic-gate * weak to strong associations) entries to determine if a match exists. 1926*7c478bd9Sstevel@tonic-gate */ 1927*7c478bd9Sstevel@tonic-gate if (ifl->ifl_ehdr->e_type == ET_DYN) { 1928*7c478bd9Sstevel@tonic-gate Sym_desc ** sort; 1929*7c478bd9Sstevel@tonic-gate size_t size = (total - local) * sizeof (Sym_desc *); 1930*7c478bd9Sstevel@tonic-gate 1931*7c478bd9Sstevel@tonic-gate if ((sort = libld_malloc(size)) == 0) 1932*7c478bd9Sstevel@tonic-gate return (S_ERROR); 1933*7c478bd9Sstevel@tonic-gate (void) memcpy((void *)sort, &ifl->ifl_oldndx[local], size); 1934*7c478bd9Sstevel@tonic-gate 1935*7c478bd9Sstevel@tonic-gate qsort(sort, (total - local), sizeof (Sym_desc *), compare); 1936*7c478bd9Sstevel@tonic-gate 1937*7c478bd9Sstevel@tonic-gate for (ndx = 0; ndx < (total - local); ndx++) { 1938*7c478bd9Sstevel@tonic-gate Sym_desc * wsdp = sort[ndx]; 1939*7c478bd9Sstevel@tonic-gate Sym * wsym; 1940*7c478bd9Sstevel@tonic-gate int sndx; 1941*7c478bd9Sstevel@tonic-gate 1942*7c478bd9Sstevel@tonic-gate if (wsdp == 0) 1943*7c478bd9Sstevel@tonic-gate continue; 1944*7c478bd9Sstevel@tonic-gate 1945*7c478bd9Sstevel@tonic-gate wsym = wsdp->sd_sym; 1946*7c478bd9Sstevel@tonic-gate 1947*7c478bd9Sstevel@tonic-gate if ((ELF_ST_BIND(wsym->st_info) != STB_WEAK) || 1948*7c478bd9Sstevel@tonic-gate (wsdp->sd_shndx == SHN_UNDEF) || 1949*7c478bd9Sstevel@tonic-gate (wsdp->sd_flags & FLG_SY_SPECSEC)) 1950*7c478bd9Sstevel@tonic-gate continue; 1951*7c478bd9Sstevel@tonic-gate 1952*7c478bd9Sstevel@tonic-gate /* 1953*7c478bd9Sstevel@tonic-gate * We have a weak symbol, if it has a strong alias it 1954*7c478bd9Sstevel@tonic-gate * will have been sorted to one of the following sort 1955*7c478bd9Sstevel@tonic-gate * table entries. Note that we could have multiple weak 1956*7c478bd9Sstevel@tonic-gate * symbols aliased to one strong (if this occurs then 1957*7c478bd9Sstevel@tonic-gate * the strong symbol only maintains one alias back to 1958*7c478bd9Sstevel@tonic-gate * the last weak). 1959*7c478bd9Sstevel@tonic-gate */ 1960*7c478bd9Sstevel@tonic-gate for (sndx = ndx + 1; sndx < (total - local); sndx++) { 1961*7c478bd9Sstevel@tonic-gate Sym_desc * ssdp = sort[sndx]; 1962*7c478bd9Sstevel@tonic-gate Sym * ssym; 1963*7c478bd9Sstevel@tonic-gate 1964*7c478bd9Sstevel@tonic-gate if (ssdp == 0) 1965*7c478bd9Sstevel@tonic-gate break; 1966*7c478bd9Sstevel@tonic-gate 1967*7c478bd9Sstevel@tonic-gate ssym = ssdp->sd_sym; 1968*7c478bd9Sstevel@tonic-gate 1969*7c478bd9Sstevel@tonic-gate if (wsym->st_value != ssym->st_value) 1970*7c478bd9Sstevel@tonic-gate break; 1971*7c478bd9Sstevel@tonic-gate 1972*7c478bd9Sstevel@tonic-gate if ((ssdp->sd_file == ifl) && 1973*7c478bd9Sstevel@tonic-gate (wsdp->sd_file == ifl) && 1974*7c478bd9Sstevel@tonic-gate (wsym->st_size == ssym->st_size) && 1975*7c478bd9Sstevel@tonic-gate (ssdp->sd_shndx != SHN_UNDEF) && 1976*7c478bd9Sstevel@tonic-gate (ELF_ST_BIND(ssym->st_info) != STB_WEAK) && 1977*7c478bd9Sstevel@tonic-gate ((ssdp->sd_flags & FLG_SY_SPECSEC) == 0)) { 1978*7c478bd9Sstevel@tonic-gate ssdp->sd_aux->sa_linkndx = 1979*7c478bd9Sstevel@tonic-gate (Word)wsdp->sd_symndx; 1980*7c478bd9Sstevel@tonic-gate wsdp->sd_aux->sa_linkndx = 1981*7c478bd9Sstevel@tonic-gate (Word)ssdp->sd_symndx; 1982*7c478bd9Sstevel@tonic-gate break; 1983*7c478bd9Sstevel@tonic-gate } 1984*7c478bd9Sstevel@tonic-gate } 1985*7c478bd9Sstevel@tonic-gate } 1986*7c478bd9Sstevel@tonic-gate } 1987*7c478bd9Sstevel@tonic-gate return (1); 1988*7c478bd9Sstevel@tonic-gate } 1989*7c478bd9Sstevel@tonic-gate 1990*7c478bd9Sstevel@tonic-gate /* 1991*7c478bd9Sstevel@tonic-gate * Add an undefined symbol to the symbol table (ie. from -u name option) 1992*7c478bd9Sstevel@tonic-gate */ 1993*7c478bd9Sstevel@tonic-gate Sym_desc * 1994*7c478bd9Sstevel@tonic-gate sym_add_u(const char *name, Ofl_desc *ofl) 1995*7c478bd9Sstevel@tonic-gate { 1996*7c478bd9Sstevel@tonic-gate Sym *sym; 1997*7c478bd9Sstevel@tonic-gate Ifl_desc *ifl = 0, *_ifl; 1998*7c478bd9Sstevel@tonic-gate Sym_desc *sdp; 1999*7c478bd9Sstevel@tonic-gate Word hash; 2000*7c478bd9Sstevel@tonic-gate Listnode *lnp; 2001*7c478bd9Sstevel@tonic-gate avl_index_t where; 2002*7c478bd9Sstevel@tonic-gate const char *cmdline = MSG_INTL(MSG_STR_COMMAND); 2003*7c478bd9Sstevel@tonic-gate 2004*7c478bd9Sstevel@tonic-gate /* 2005*7c478bd9Sstevel@tonic-gate * If the symbol reference already exists indicate that a reference 2006*7c478bd9Sstevel@tonic-gate * also came from the command line. 2007*7c478bd9Sstevel@tonic-gate */ 2008*7c478bd9Sstevel@tonic-gate /* LINTED */ 2009*7c478bd9Sstevel@tonic-gate hash = (Word)elf_hash(name); 2010*7c478bd9Sstevel@tonic-gate if (sdp = sym_find(name, hash, &where, ofl)) { 2011*7c478bd9Sstevel@tonic-gate if (sdp->sd_ref == REF_DYN_SEEN) 2012*7c478bd9Sstevel@tonic-gate sdp->sd_ref = REF_DYN_NEED; 2013*7c478bd9Sstevel@tonic-gate return (sdp); 2014*7c478bd9Sstevel@tonic-gate } 2015*7c478bd9Sstevel@tonic-gate 2016*7c478bd9Sstevel@tonic-gate /* 2017*7c478bd9Sstevel@tonic-gate * Determine whether a pseudo input file descriptor exists to represent 2018*7c478bd9Sstevel@tonic-gate * the command line, as any global symbol needs an input file descriptor 2019*7c478bd9Sstevel@tonic-gate * during any symbol resolution (refer to map_ifl() which provides a 2020*7c478bd9Sstevel@tonic-gate * similar method for adding symbols from mapfiles). 2021*7c478bd9Sstevel@tonic-gate */ 2022*7c478bd9Sstevel@tonic-gate for (LIST_TRAVERSE(&ofl->ofl_objs, lnp, _ifl)) 2023*7c478bd9Sstevel@tonic-gate if (strcmp(_ifl->ifl_name, cmdline) == 0) { 2024*7c478bd9Sstevel@tonic-gate ifl = _ifl; 2025*7c478bd9Sstevel@tonic-gate break; 2026*7c478bd9Sstevel@tonic-gate } 2027*7c478bd9Sstevel@tonic-gate 2028*7c478bd9Sstevel@tonic-gate /* 2029*7c478bd9Sstevel@tonic-gate * If no descriptor exists create one. 2030*7c478bd9Sstevel@tonic-gate */ 2031*7c478bd9Sstevel@tonic-gate if (ifl == 0) { 2032*7c478bd9Sstevel@tonic-gate if ((ifl = libld_calloc(sizeof (Ifl_desc), 1)) == 2033*7c478bd9Sstevel@tonic-gate (Ifl_desc *)0) 2034*7c478bd9Sstevel@tonic-gate return ((Sym_desc *)S_ERROR); 2035*7c478bd9Sstevel@tonic-gate ifl->ifl_name = cmdline; 2036*7c478bd9Sstevel@tonic-gate ifl->ifl_flags = FLG_IF_NEEDED | FLG_IF_FILEREF; 2037*7c478bd9Sstevel@tonic-gate if ((ifl->ifl_ehdr = libld_calloc(sizeof (Ehdr), 2038*7c478bd9Sstevel@tonic-gate 1)) == 0) 2039*7c478bd9Sstevel@tonic-gate return ((Sym_desc *)S_ERROR); 2040*7c478bd9Sstevel@tonic-gate ifl->ifl_ehdr->e_type = ET_REL; 2041*7c478bd9Sstevel@tonic-gate 2042*7c478bd9Sstevel@tonic-gate if (list_appendc(&ofl->ofl_objs, ifl) == 0) 2043*7c478bd9Sstevel@tonic-gate return ((Sym_desc *)S_ERROR); 2044*7c478bd9Sstevel@tonic-gate } 2045*7c478bd9Sstevel@tonic-gate 2046*7c478bd9Sstevel@tonic-gate /* 2047*7c478bd9Sstevel@tonic-gate * Allocate a symbol structure and add it to the global symbol table. 2048*7c478bd9Sstevel@tonic-gate */ 2049*7c478bd9Sstevel@tonic-gate if ((sym = libld_calloc(sizeof (Sym), 1)) == 0) 2050*7c478bd9Sstevel@tonic-gate return ((Sym_desc *)S_ERROR); 2051*7c478bd9Sstevel@tonic-gate sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); 2052*7c478bd9Sstevel@tonic-gate sym->st_shndx = SHN_UNDEF; 2053*7c478bd9Sstevel@tonic-gate 2054*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_process(ifl)); 2055*7c478bd9Sstevel@tonic-gate DBG_CALL(Dbg_syms_global(0, name)); 2056*7c478bd9Sstevel@tonic-gate sdp = sym_enter(name, sym, hash, ifl, ofl, 0, SHN_UNDEF, 0, 0, &where); 2057*7c478bd9Sstevel@tonic-gate sdp->sd_flags &= ~FLG_SY_CLEAN; 2058*7c478bd9Sstevel@tonic-gate sdp->sd_flags |= FLG_SY_CMDREF; 2059*7c478bd9Sstevel@tonic-gate 2060*7c478bd9Sstevel@tonic-gate return (sdp); 2061*7c478bd9Sstevel@tonic-gate } 2062