Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #include	<string.h>
     28 #include	<stdio.h>
     29 #include	<debug.h>
     30 #include	"msg.h"
     31 #include	"_libld.h"
     32 
     33 /*
     34  * Locate a version descriptor.
     35  */
     36 Ver_desc *
     37 ld_vers_find(const char *name, Word hash, APlist *alp)
     38 {
     39 	Aliste		idx;
     40 	Ver_desc	*vdp;
     41 
     42 	for (APLIST_TRAVERSE(alp, idx, vdp)) {
     43 		if (vdp->vd_hash != hash)
     44 			continue;
     45 		if (strcmp(vdp->vd_name, name) == 0)
     46 			return (vdp);
     47 	}
     48 	return (NULL);
     49 }
     50 
     51 /*
     52  * Add a new version descriptor to a version descriptor list.  Note, users of
     53  * this are responsible for determining if the version descriptor already
     54  * exists (this can reduce the need to allocate storage for descriptor names
     55  * until it is determined a descriptor need be created (see map_symbol())).
     56  */
     57 Ver_desc *
     58 ld_vers_desc(const char *name, Word hash, APlist **alpp)
     59 {
     60 	Ver_desc	*vdp;
     61 
     62 	if ((vdp = libld_calloc(sizeof (Ver_desc), 1)) == NULL)
     63 		return ((Ver_desc *)S_ERROR);
     64 
     65 	vdp->vd_name = name;
     66 	vdp->vd_hash = hash;
     67 
     68 	if (aplist_append(alpp, vdp, AL_CNT_VERDESCS) == NULL)
     69 		return ((Ver_desc *)S_ERROR);
     70 
     71 	return (vdp);
     72 }
     73 
     74 /*
     75  * Now that all explict files have been processed validate any version
     76  * definitions.  Insure that any version references are available (a version
     77  * has been defined when it's been assigned an index).  Also calculate the
     78  * number of .version section entries that will be required to hold this
     79  * information.
     80  */
     81 #define	_NUM_OF_VERS_	40	/* twice as big as the depth for libc version */
     82 typedef struct {
     83 	Ver_desc	**ver_stk;
     84 	int 		ver_sp;
     85 	int 		ver_lmt;
     86 } Ver_Stack;
     87 
     88 static uintptr_t
     89 vers_visit_children(Ofl_desc *ofl, Ver_desc *vp, int flag)
     90 {
     91 	Aliste			idx;
     92 	Ver_desc		*vdp;
     93 	static int		err = 0;
     94 	static Ver_Stack	ver_stk = {0, 0, 0};
     95 	int			tmp_sp;
     96 
     97 	/*
     98 	 * If there was any fatal error,
     99 	 * just return.
    100 	 */
    101 	if (err == S_ERROR)
    102 		return (err);
    103 
    104 	/*
    105 	 * if this is called from, ver_check_defs(), initialize sp.
    106 	 */
    107 	if (flag == 0)
    108 		ver_stk.ver_sp = 0;
    109 
    110 	/*
    111 	 * Check if passed version pointer vp is already in the stack.
    112 	 */
    113 	for (tmp_sp = 0; tmp_sp < ver_stk.ver_sp; tmp_sp++) {
    114 		Ver_desc *v;
    115 
    116 		v = ver_stk.ver_stk[tmp_sp];
    117 		if (v == vp) {
    118 			/*
    119 			 * cyclic dependency.
    120 			 */
    121 			if (err == 0) {
    122 				eprintf(ofl->ofl_lml, ERR_FATAL,
    123 				    MSG_INTL(MSG_VER_CYCLIC));
    124 				err = 1;
    125 			}
    126 			for (tmp_sp = 0; tmp_sp < ver_stk.ver_sp; tmp_sp++) {
    127 				v = ver_stk.ver_stk[tmp_sp];
    128 				if ((v->vd_flags & FLG_VER_CYCLIC) == 0) {
    129 					v->vd_flags |= FLG_VER_CYCLIC;
    130 					eprintf(ofl->ofl_lml, ERR_NONE,
    131 					    MSG_INTL(MSG_VER_ADDVER),
    132 					    v->vd_name);
    133 				}
    134 			}
    135 			if ((vp->vd_flags & FLG_VER_CYCLIC) == 0) {
    136 				vp->vd_flags |= FLG_VER_CYCLIC;
    137 				eprintf(ofl->ofl_lml, ERR_NONE,
    138 				    MSG_INTL(MSG_VER_ADDVER), vp->vd_name);
    139 			}
    140 			return (err);
    141 		}
    142 	}
    143 
    144 	/*
    145 	 * Push version on the stack.
    146 	 */
    147 	if (ver_stk.ver_sp >= ver_stk.ver_lmt) {
    148 		ver_stk.ver_lmt += _NUM_OF_VERS_;
    149 		if ((ver_stk.ver_stk = (Ver_desc **)
    150 		    libld_realloc((void *)ver_stk.ver_stk,
    151 		    ver_stk.ver_lmt * sizeof (Ver_desc *))) == NULL)
    152 			return (S_ERROR);
    153 	}
    154 	ver_stk.ver_stk[(ver_stk.ver_sp)++] = vp;
    155 
    156 	/*
    157 	 * Now visit children.
    158 	 */
    159 	for (APLIST_TRAVERSE(vp->vd_deps, idx, vdp))
    160 		if (vers_visit_children(ofl, vdp, 1) == S_ERROR)
    161 			return (S_ERROR);
    162 
    163 	/*
    164 	 * Pop version from the stack.
    165 	 */
    166 	(ver_stk.ver_sp)--;
    167 
    168 	return (err);
    169 }
    170 
    171 uintptr_t
    172 ld_vers_check_defs(Ofl_desc *ofl)
    173 {
    174 	Aliste		idx1;
    175 	Ver_desc	*vdp;
    176 	uintptr_t 	is_cyclic = 0;
    177 
    178 	DBG_CALL(Dbg_ver_def_title(ofl->ofl_lml, ofl->ofl_name));
    179 
    180 	/*
    181 	 * First check if there are any cyclic dependency
    182 	 */
    183 	for (APLIST_TRAVERSE(ofl->ofl_verdesc, idx1, vdp))
    184 		if ((is_cyclic = vers_visit_children(ofl, vdp, 0)) == S_ERROR)
    185 			return (S_ERROR);
    186 
    187 	if (is_cyclic)
    188 		ofl->ofl_flags |= FLG_OF_FATAL;
    189 
    190 	for (APLIST_TRAVERSE(ofl->ofl_verdesc, idx1, vdp)) {
    191 		Byte		cnt;
    192 		Sym		*sym;
    193 		Sym_desc	*sdp;
    194 		const char	*name = vdp->vd_name;
    195 		uchar_t		bind;
    196 		Ver_desc	*_vdp;
    197 		avl_index_t	where;
    198 		Aliste		idx2;
    199 
    200 		if (vdp->vd_ndx == 0) {
    201 			eprintf(ofl->ofl_lml, ERR_FATAL,
    202 			    MSG_INTL(MSG_VER_UNDEF), name, vdp->vd_ref->vd_name,
    203 			    vdp->vd_ref->vd_file->ifl_name);
    204 			ofl->ofl_flags |= FLG_OF_FATAL;
    205 			continue;
    206 		}
    207 
    208 		DBG_CALL(Dbg_ver_desc_entry(ofl->ofl_lml, vdp));
    209 
    210 		/*
    211 		 * If a version definition contains no symbols this is possibly
    212 		 * a mapfile error.
    213 		 */
    214 		if ((vdp->vd_flags &
    215 		    (VER_FLG_BASE | VER_FLG_WEAK | FLG_VER_REFER)) == 0)
    216 			DBG_CALL(Dbg_ver_nointerface(ofl->ofl_lml,
    217 			    vdp->vd_name));
    218 
    219 		/*
    220 		 * Update the version entry count to account for this new
    221 		 * version descriptor (the count is the size in bytes).
    222 		 */
    223 		ofl->ofl_verdefsz += sizeof (Verdef);
    224 
    225 		/*
    226 		 * Traverse this versions dependency list to determine what
    227 		 * additional version dependencies we must account for against
    228 		 * this descriptor.
    229 		 */
    230 		cnt = 1;
    231 		for (APLIST_TRAVERSE(vdp->vd_deps, idx2, _vdp)) {
    232 #if	defined(__lint)
    233 			/* get lint to think `_vdp' is used... */
    234 			vdp = _vdp;
    235 #endif
    236 			cnt++;
    237 		}
    238 		ofl->ofl_verdefsz += (cnt * sizeof (Verdaux));
    239 
    240 		/*
    241 		 * Except for the base version descriptor, generate an absolute
    242 		 * symbol to reflect this version.
    243 		 */
    244 		if (vdp->vd_flags & VER_FLG_BASE)
    245 			continue;
    246 
    247 		if (vdp->vd_flags & VER_FLG_WEAK)
    248 			bind = STB_WEAK;
    249 		else
    250 			bind = STB_GLOBAL;
    251 
    252 		if (sdp = ld_sym_find(name, vdp->vd_hash, &where, ofl)) {
    253 			/*
    254 			 * If the symbol already exists and is undefined or was
    255 			 * defined in a shared library, convert it to an
    256 			 * absolute.
    257 			 */
    258 			if ((sdp->sd_sym->st_shndx == SHN_UNDEF) ||
    259 			    (sdp->sd_ref != REF_REL_NEED)) {
    260 				sdp->sd_shndx = sdp->sd_sym->st_shndx = SHN_ABS;
    261 				sdp->sd_sym->st_info =
    262 				    ELF_ST_INFO(bind, STT_OBJECT);
    263 				sdp->sd_ref = REF_REL_NEED;
    264 				sdp->sd_flags |= (FLG_SY_SPECSEC |
    265 				    FLG_SY_DEFAULT | FLG_SY_EXPDEF);
    266 				sdp->sd_aux->sa_overndx = vdp->vd_ndx;
    267 
    268 				/*
    269 				 * If the reference originated from a mapfile
    270 				 * insure we mark the symbol as used.
    271 				 */
    272 				if (sdp->sd_flags & FLG_SY_MAPREF)
    273 					sdp->sd_flags |= FLG_SY_MAPUSED;
    274 
    275 			} else if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
    276 			    (sdp->sd_sym->st_shndx != SHN_ABS) &&
    277 			    (sdp->sd_ref == REF_REL_NEED)) {
    278 				eprintf(ofl->ofl_lml, ERR_WARNING,
    279 				    MSG_INTL(MSG_VER_DEFINED), name,
    280 				    sdp->sd_file->ifl_name);
    281 			}
    282 		} else {
    283 			/*
    284 			 * If the symbol does not exist create it.
    285 			 */
    286 			if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
    287 				return (S_ERROR);
    288 
    289 			sym->st_shndx = SHN_ABS;
    290 			sym->st_info = ELF_ST_INFO(bind, STT_OBJECT);
    291 			DBG_CALL(Dbg_ver_symbol(ofl->ofl_lml, name));
    292 
    293 			if ((sdp = ld_sym_enter(name, sym, vdp->vd_hash,
    294 			    vdp->vd_file, ofl, 0, SHN_ABS,
    295 			    (FLG_SY_SPECSEC | FLG_SY_DEFAULT | FLG_SY_EXPDEF),
    296 			    &where)) == (Sym_desc *)S_ERROR)
    297 				return (S_ERROR);
    298 
    299 			sdp->sd_ref = REF_REL_NEED;
    300 			sdp->sd_aux->sa_overndx = vdp->vd_ndx;
    301 		}
    302 	}
    303 	return (1);
    304 }
    305 
    306 /*
    307  * Dereference dependencies as a part of normalizing (allows recursion).
    308  */
    309 static void
    310 vers_derefer(Ifl_desc *ifl, Ver_desc *vdp, int weak)
    311 {
    312 	Aliste		idx;
    313 	Ver_desc	*_vdp;
    314 	Ver_index	*vip = &ifl->ifl_verndx[vdp->vd_ndx];
    315 
    316 	/*
    317 	 * Set the INFO bit on all dependencies that ld.so.1
    318 	 * can skip verification for. These are the dependencies
    319 	 * that are inherited by others -- verifying the inheriting
    320 	 * version implicitily covers this one.
    321 	 *
    322 	 * If the head of the list was a weak then we only mark
    323 	 * weak dependencies, but if the head of the list was 'strong'
    324 	 * we set INFO on all dependencies.
    325 	 */
    326 	if ((weak && (vdp->vd_flags & VER_FLG_WEAK)) || (!weak))
    327 		vip->vi_flags |= VER_FLG_INFO;
    328 
    329 	for (APLIST_TRAVERSE(vdp->vd_deps, idx, _vdp))
    330 		vers_derefer(ifl, _vdp, weak);
    331 }
    332 
    333 /*
    334  * If we need to record the versions of any needed dependencies traverse the
    335  * shared object dependency list and calculate what version needed entries are
    336  * required.
    337  */
    338 uintptr_t
    339 ld_vers_check_need(Ofl_desc *ofl)
    340 {
    341 	Aliste		idx1;
    342 	Ifl_desc	*ifl;
    343 	Half		needndx;
    344 
    345 	/*
    346 	 * Versym indexes for needed versions start with the next
    347 	 * available version after the final definied version.
    348 	 * However, it can never be less than 2. 0 is always for local
    349 	 * scope, and 1 is always the first global definition.
    350 	 */
    351 	needndx = (ofl->ofl_vercnt > 0) ? (ofl->ofl_vercnt + 1) : 2;
    352 
    353 	/*
    354 	 * Traverse the shared object list looking for dependencies.
    355 	 */
    356 	for (APLIST_TRAVERSE(ofl->ofl_sos, idx1, ifl)) {
    357 		Aliste		idx2;
    358 		Ver_index	*vip;
    359 		Ver_desc	*vdp;
    360 		Byte		cnt, need = 0;
    361 
    362 		if (!(ifl->ifl_flags & FLG_IF_NEEDED))
    363 			continue;
    364 
    365 		if (ifl->ifl_vercnt <= VER_NDX_GLOBAL)
    366 			continue;
    367 
    368 		/*
    369 		 * Scan the version index list and if any weak version
    370 		 * definition has been referenced by the user promote the
    371 		 * dependency to be non-weak.  Weak version dependencies do not
    372 		 * cause fatal errors from the runtime linker, non-weak
    373 		 * dependencies do.
    374 		 */
    375 		for (cnt = 0; cnt <= ifl->ifl_vercnt; cnt++) {
    376 			vip = &ifl->ifl_verndx[cnt];
    377 			vdp = vip->vi_desc;
    378 
    379 			if ((vip->vi_flags & (FLG_VER_REFER | VER_FLG_WEAK)) ==
    380 			    (FLG_VER_REFER | VER_FLG_WEAK))
    381 				vdp->vd_flags &= ~VER_FLG_WEAK;
    382 
    383 			/*
    384 			 * Mark any weak reference as referred to so as to
    385 			 * simplify normalization and later version dependency
    386 			 * manipulation.
    387 			 */
    388 			if (vip->vi_flags & VER_FLG_WEAK)
    389 				vip->vi_flags |= FLG_VER_REFER;
    390 		}
    391 
    392 		/*
    393 		 * Scan the version dependency list to normalize the referenced
    394 		 * dependencies.  Any needed version that is inherited by
    395 		 * another like version is dereferenced as it is not necessary
    396 		 * to make this part of the version dependencies.
    397 		 */
    398 		for (APLIST_TRAVERSE(ifl->ifl_verdesc, idx2, vdp)) {
    399 			Aliste		idx3;
    400 			Ver_desc	*_vdp;
    401 			int		type;
    402 
    403 			vip = &ifl->ifl_verndx[vdp->vd_ndx];
    404 
    405 			if (!(vip->vi_flags & FLG_VER_REFER))
    406 				continue;
    407 
    408 			type = vdp->vd_flags & VER_FLG_WEAK;
    409 			for (APLIST_TRAVERSE(vdp->vd_deps, idx3, _vdp))
    410 				vers_derefer(ifl, _vdp, type);
    411 		}
    412 
    413 		/*
    414 		 * Finally, determine how many of the version dependencies need
    415 		 * to be recorded.
    416 		 */
    417 		for (cnt = 0; cnt <= ifl->ifl_vercnt; cnt++) {
    418 			vip = &ifl->ifl_verndx[cnt];
    419 
    420 			/*
    421 			 * If a version has been referenced then record it as a
    422 			 * version dependency.
    423 			 */
    424 			if (vip->vi_flags & FLG_VER_REFER) {
    425 				/* Assign a VERSYM index for it */
    426 				vip->vi_overndx = needndx++;
    427 
    428 				ofl->ofl_verneedsz += sizeof (Vernaux);
    429 				if (st_insert(ofl->ofl_dynstrtab,
    430 				    vip->vi_name) == -1)
    431 					return (S_ERROR);
    432 				need++;
    433 			}
    434 		}
    435 
    436 		if (need) {
    437 			ifl->ifl_flags |= FLG_IF_VERNEED;
    438 			ofl->ofl_verneedsz += sizeof (Verneed);
    439 			if (st_insert(ofl->ofl_dynstrtab,
    440 			    ifl->ifl_soname) == -1)
    441 				return (S_ERROR);
    442 		}
    443 	}
    444 
    445 	/*
    446 	 * If no version needed information is required unset the output file
    447 	 * flag.
    448 	 */
    449 	if (ofl->ofl_verneedsz == 0)
    450 		ofl->ofl_flags &= ~FLG_OF_VERNEED;
    451 
    452 	return (1);
    453 }
    454 
    455 /*
    456  * Indicate dependency selection (allows recursion).
    457  */
    458 static void
    459 vers_select(Ofl_desc *ofl, Ifl_desc *ifl, Ver_desc *vdp, const char *ref)
    460 {
    461 	Aliste		idx;
    462 	Ver_desc	*_vdp;
    463 	Ver_index	*vip = &ifl->ifl_verndx[vdp->vd_ndx];
    464 
    465 	vip->vi_flags |= FLG_VER_AVAIL;
    466 	DBG_CALL(Dbg_ver_avail_entry(ofl->ofl_lml, vip, ref));
    467 
    468 	for (APLIST_TRAVERSE(vdp->vd_deps, idx, _vdp))
    469 		vers_select(ofl, ifl, _vdp, ref);
    470 }
    471 
    472 static Ver_index *
    473 vers_index(Ofl_desc *ofl, Ifl_desc *ifl, int avail)
    474 {
    475 	Aliste		idx1;
    476 	Ver_desc	*vdp;
    477 	Ver_index	*vip;
    478 	Sdf_desc	*sdf = ifl->ifl_sdfdesc;
    479 	Word		count = ifl->ifl_vercnt;
    480 	Sdv_desc	*sdv;
    481 
    482 	/*
    483 	 * Allocate an index array large enough to hold all of the files
    484 	 * version descriptors.
    485 	 */
    486 	if ((vip = libld_calloc(sizeof (Ver_index), (count + 1))) == NULL)
    487 		return ((Ver_index *)S_ERROR);
    488 
    489 	for (APLIST_TRAVERSE(ifl->ifl_verdesc, idx1, vdp)) {
    490 		int	ndx = vdp->vd_ndx;
    491 
    492 		vip[ndx].vi_name = vdp->vd_name;
    493 		vip[ndx].vi_desc = vdp;
    494 
    495 		/*
    496 		 * Any relocatable object versions, and the `base' version are
    497 		 * always available.
    498 		 */
    499 		if (avail || (vdp->vd_flags & VER_FLG_BASE))
    500 			vip[ndx].vi_flags |= FLG_VER_AVAIL;
    501 
    502 		/*
    503 		 * If this is a weak version mark it as such.  Weak versions
    504 		 * are always dragged into any version dependencies created,
    505 		 * and if a weak version is referenced it will be promoted to
    506 		 * a non-weak version dependency.
    507 		 */
    508 		if (vdp->vd_flags & VER_FLG_WEAK)
    509 			vip[ndx].vi_flags |= VER_FLG_WEAK;
    510 		/*
    511 		 * If this version is mentioned in a mapfile using ADDVERS
    512 		 * syntax then check to see if it corresponds to an actual
    513 		 * version in the file.
    514 		 */
    515 		if (sdf && (sdf->sdf_flags & FLG_SDF_ADDVER)) {
    516 			Aliste	idx2;
    517 
    518 			for (ALIST_TRAVERSE(sdf->sdf_verneed, idx2, sdv)) {
    519 				if (strcmp(vip[ndx].vi_name, sdv->sdv_name))
    520 					continue;
    521 
    522 				vip[ndx].vi_flags |= FLG_VER_REFER;
    523 				sdv->sdv_flags |= FLG_SDV_MATCHED;
    524 				break;
    525 			}
    526 		}
    527 	}
    528 
    529 	/*
    530 	 * if $ADDVER was specified for this object verify that
    531 	 * all of it's dependent upon versions were refered to.
    532 	 */
    533 	if (sdf && (sdf->sdf_flags & FLG_SDF_ADDVER)) {
    534 		int	fail = 0;
    535 
    536 		for (ALIST_TRAVERSE(sdf->sdf_verneed, idx1, sdv)) {
    537 			if (sdv->sdv_flags & FLG_SDV_MATCHED)
    538 				continue;
    539 
    540 			if (fail++ == 0) {
    541 				eprintf(ofl->ofl_lml, ERR_NONE,
    542 				    MSG_INTL(MSG_VER_ADDVERS), sdf->sdf_rfile,
    543 				    sdf->sdf_name);
    544 			}
    545 			eprintf(ofl->ofl_lml, ERR_NONE,
    546 			    MSG_INTL(MSG_VER_ADDVER), sdv->sdv_name);
    547 		}
    548 		if (fail)
    549 			return ((Ver_index *)S_ERROR);
    550 	}
    551 
    552 	return (vip);
    553 }
    554 
    555 /*
    556  * Process a version symbol index section.
    557  */
    558 int
    559 ld_vers_sym_process(Lm_list *lml, Is_desc *isp, Ifl_desc *ifl)
    560 {
    561 	Shdr	*symshdr;
    562 	Shdr	*vershdr = isp->is_shdr;
    563 
    564 	/*
    565 	 * Verify that the versym is the same size as the linked symbol table.
    566 	 * If these two get out of sync the file is considered corrupted.
    567 	 */
    568 	symshdr = ifl->ifl_isdesc[vershdr->sh_link]->is_shdr;
    569 	if ((symshdr->sh_size / symshdr->sh_entsize) != (vershdr->sh_size /
    570 	    vershdr->sh_entsize)) {
    571 		Is_desc	*sym_isp = ifl->ifl_isdesc[vershdr->sh_link];
    572 
    573 		eprintf(lml, ERR_WARNING, MSG_INTL(MSG_ELF_VERSYM),
    574 		    ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name,
    575 		    EC_WORD(vershdr->sh_size / vershdr->sh_entsize),
    576 		    EC_WORD(sym_isp->is_scnndx), sym_isp->is_name,
    577 		    EC_WORD(symshdr->sh_size / symshdr->sh_entsize));
    578 		return (1);
    579 	}
    580 	ifl->ifl_versym = (Versym *)isp->is_indata->d_buf;
    581 	return (1);
    582 }
    583 
    584 /*
    585  * Process a version definition section from an input file.  A list of version
    586  * descriptors is created and associated with the input files descriptor.  If
    587  * this is a shared object these descriptors will be used to indicate the
    588  * availability of each version.  If this is a relocatable object then these
    589  * descriptors will be promoted (concatenated) to the output files image.
    590  */
    591 uintptr_t
    592 ld_vers_def_process(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl)
    593 {
    594 	const char	*str, *file = ifl->ifl_name;
    595 	Sdf_desc	*sdf = ifl->ifl_sdfdesc;
    596 	Sdv_desc	*sdv;
    597 	Word		num, _num;
    598 	Verdef		*vdf;
    599 	int		relobj;
    600 
    601 	/*
    602 	 * If there is no version section then simply indicate that all version
    603 	 * definitions asked for do not exist.
    604 	 */
    605 	if (isp == NULL) {
    606 		Aliste	idx;
    607 
    608 		for (ALIST_TRAVERSE(sdf->sdf_vers, idx, sdv)) {
    609 			eprintf(ofl->ofl_lml, ERR_FATAL,
    610 			    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
    611 			    sdv->sdv_name, sdv->sdv_ref);
    612 			ofl->ofl_flags |= FLG_OF_FATAL;
    613 		}
    614 		return (0);
    615 	}
    616 
    617 	vdf = (Verdef *)isp->is_indata->d_buf;
    618 
    619 	/*
    620 	 * Verify the version revision.  We only check the first version
    621 	 * structure as it is assumed all other version structures in this
    622 	 * data section will be of the same revision.
    623 	 */
    624 	if (vdf->vd_version > VER_DEF_CURRENT)
    625 		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
    626 		    MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vdf->vd_version,
    627 		    VER_DEF_CURRENT);
    628 
    629 
    630 	num = isp->is_shdr->sh_info;
    631 	str = (char *)ifl->ifl_isdesc[isp->is_shdr->sh_link]->is_indata->d_buf;
    632 
    633 	if (ifl->ifl_ehdr->e_type == ET_REL)
    634 		relobj = 1;
    635 	else
    636 		relobj = 0;
    637 
    638 	DBG_CALL(Dbg_ver_def_title(ofl->ofl_lml, file));
    639 
    640 	/*
    641 	 * Loop through the version information setting up a version descriptor
    642 	 * for each version definition.
    643 	 */
    644 	for (_num = 1; _num <= num; _num++,
    645 	    vdf = (Verdef *)((uintptr_t)vdf + vdf->vd_next)) {
    646 		const char	*name;
    647 		Ver_desc	*ivdp, *ovdp = NULL;
    648 		Word		hash;
    649 		Half 		cnt = vdf->vd_cnt;
    650 		Half		ndx = vdf->vd_ndx;
    651 		Verdaux		*vdap = (Verdaux *)((uintptr_t)vdf +
    652 		    vdf->vd_aux);
    653 
    654 		/*
    655 		 * Keep track of the largest index for use in creating a
    656 		 * version index array later, and create a version descriptor.
    657 		 */
    658 		if (ndx > ifl->ifl_vercnt)
    659 			ifl->ifl_vercnt = ndx;
    660 
    661 		name = (char *)(str + vdap->vda_name);
    662 		/* LINTED */
    663 		hash = (Word)elf_hash(name);
    664 		if (((ivdp = ld_vers_find(name, hash,
    665 		    ifl->ifl_verdesc)) == NULL) &&
    666 		    ((ivdp = ld_vers_desc(name, hash,
    667 		    &ifl->ifl_verdesc)) == (Ver_desc *)S_ERROR))
    668 			return (S_ERROR);
    669 
    670 		ivdp->vd_ndx = ndx;
    671 		ivdp->vd_file = ifl;
    672 		ivdp->vd_flags = vdf->vd_flags;
    673 
    674 		/*
    675 		 * If we're processing a relocatable object then this version
    676 		 * definition needs to be propagated to the output file.
    677 		 * Generate a new output file version and associated this input
    678 		 * version to it.  During symbol processing the version index of
    679 		 * the symbol will be promoted from the input file to the output
    680 		 * files version definition.
    681 		 */
    682 		if (relobj) {
    683 			if (!(ofl->ofl_flags & FLG_OF_RELOBJ))
    684 				ofl->ofl_flags |= FLG_OF_PROCRED;
    685 
    686 			if ((ivdp->vd_flags & VER_FLG_BASE) == 0) {
    687 				/*
    688 				 * If no version descriptors have yet been set
    689 				 * up, initialize a base version to represent
    690 				 * the output file itself.  This `base' version
    691 				 * catches any internally generated symbols
    692 				 * (_end, _etext, etc.) and
    693 				 * serves to initialize the output version
    694 				 * descriptor count.
    695 				 */
    696 				if (ofl->ofl_vercnt == 0) {
    697 					if (ld_vers_base(ofl) ==
    698 					    (Ver_desc *)S_ERROR)
    699 						return (S_ERROR);
    700 				}
    701 				ofl->ofl_flags |= FLG_OF_VERDEF;
    702 				if ((ovdp = ld_vers_find(name, hash,
    703 				    ofl->ofl_verdesc)) == NULL) {
    704 					if ((ovdp = ld_vers_desc(name, hash,
    705 					    &ofl->ofl_verdesc)) ==
    706 					    (Ver_desc *)S_ERROR)
    707 						return (S_ERROR);
    708 
    709 					/* LINTED */
    710 					ovdp->vd_ndx = (Half)++ofl->ofl_vercnt;
    711 					ovdp->vd_file = ifl;
    712 					ovdp->vd_flags = vdf->vd_flags;
    713 				}
    714 			}
    715 
    716 			/*
    717 			 * Maintain the association between the input version
    718 			 * descriptor and the output version descriptor so that
    719 			 * an associated symbols will be assigned to the
    720 			 * correct version.
    721 			 */
    722 			ivdp->vd_ref = ovdp;
    723 		}
    724 
    725 		/*
    726 		 * Process any dependencies this version may have.
    727 		 */
    728 		vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next);
    729 		for (cnt--; cnt; cnt--,
    730 		    vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next)) {
    731 			Ver_desc	*_ivdp;
    732 
    733 			name = (char *)(str + vdap->vda_name);
    734 			/* LINTED */
    735 			hash = (Word)elf_hash(name);
    736 
    737 			if (((_ivdp = ld_vers_find(name, hash,
    738 			    ifl->ifl_verdesc)) == NULL) &&
    739 			    ((_ivdp = ld_vers_desc(name, hash,
    740 			    &ifl->ifl_verdesc)) == (Ver_desc *)S_ERROR))
    741 				return (S_ERROR);
    742 
    743 			if (aplist_append(&ivdp->vd_deps, _ivdp,
    744 			    AL_CNT_VERDESCS) == NULL)
    745 				return (S_ERROR);
    746 		}
    747 		DBG_CALL(Dbg_ver_desc_entry(ofl->ofl_lml, ivdp));
    748 	}
    749 
    750 	/*
    751 	 * Now that we know the total number of version definitions for this
    752 	 * file, build an index array for fast access when processing symbols.
    753 	 */
    754 	if ((ifl->ifl_verndx =
    755 	    vers_index(ofl, ifl, relobj)) == (Ver_index *)S_ERROR)
    756 		return (S_ERROR);
    757 
    758 	if (relobj)
    759 		return (1);
    760 
    761 	/*
    762 	 * If this object has version control definitions against it then these
    763 	 * must be processed so as to select those version definitions to which
    764 	 * symbol bindings can occur.  Otherwise simply mark all versions as
    765 	 * available.
    766 	 */
    767 	DBG_CALL(Dbg_ver_avail_title(ofl->ofl_lml, file));
    768 
    769 	if (sdf && (sdf->sdf_flags & FLG_SDF_SELECT)) {
    770 		Aliste	idx1;
    771 
    772 		for (ALIST_TRAVERSE(sdf->sdf_vers, idx1, sdv)) {
    773 			Aliste		idx2;
    774 			Ver_desc	*vdp;
    775 			int		found = 0;
    776 
    777 			for (APLIST_TRAVERSE(ifl->ifl_verdesc, idx2, vdp)) {
    778 				if (strcmp(sdv->sdv_name, vdp->vd_name) == 0) {
    779 					found++;
    780 					break;
    781 				}
    782 			}
    783 			if (found)
    784 				vers_select(ofl, ifl, vdp, sdv->sdv_ref);
    785 			else {
    786 				eprintf(ofl->ofl_lml, ERR_FATAL,
    787 				    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
    788 				    sdv->sdv_name, sdv->sdv_ref);
    789 				ofl->ofl_flags |= FLG_OF_FATAL;
    790 			}
    791 		}
    792 	} else {
    793 		Ver_index	*vip;
    794 		int		cnt;
    795 
    796 		for (cnt = VER_NDX_GLOBAL; cnt <= ifl->ifl_vercnt; cnt++) {
    797 			vip = &ifl->ifl_verndx[cnt];
    798 			vip->vi_flags |= FLG_VER_AVAIL;
    799 			DBG_CALL(Dbg_ver_avail_entry(ofl->ofl_lml, vip, 0));
    800 		}
    801 	}
    802 
    803 	/*
    804 	 * If this is an explict dependency indicate that this file is a
    805 	 * candidate for requiring version needed information to be recorded in
    806 	 * the image we're creating.
    807 	 */
    808 	if (ifl->ifl_flags & FLG_IF_NEEDED)
    809 		ofl->ofl_flags |= FLG_OF_VERNEED;
    810 
    811 	return (1);
    812 }
    813 
    814 /*
    815  * Process a version needed section.
    816  */
    817 uintptr_t
    818 ld_vers_need_process(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl)
    819 {
    820 	const char	*str, *file = ifl->ifl_name;
    821 	Word		num, _num;
    822 	Verneed		*vnd;
    823 
    824 	vnd = (Verneed *)isp->is_indata->d_buf;
    825 
    826 	/*
    827 	 * Verify the version revision.  We only check the first version
    828 	 * structure as it is assumed all other version structures in this
    829 	 * data section will be of the same revision.
    830 	 */
    831 	if (vnd->vn_version > VER_DEF_CURRENT) {
    832 		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
    833 		    MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vnd->vn_version,
    834 		    VER_DEF_CURRENT);
    835 	}
    836 
    837 	num = isp->is_shdr->sh_info;
    838 	str = (char *)ifl->ifl_isdesc[isp->is_shdr->sh_link]->is_indata->d_buf;
    839 
    840 	DBG_CALL(Dbg_ver_need_title(ofl->ofl_lml, file));
    841 
    842 	/*
    843 	 * Loop through the version information setting up a version descriptor
    844 	 * for each version definition.
    845 	 */
    846 	for (_num = 1; _num <= num; _num++,
    847 	    vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) {
    848 		Sdf_desc	*sdf;
    849 		const char	*name;
    850 		Half		cnt = vnd->vn_cnt;
    851 		Vernaux		*vnap = (Vernaux *)((uintptr_t)vnd +
    852 		    vnd->vn_aux);
    853 		Half		_cnt;
    854 
    855 		name = (char *)(str + vnd->vn_file);
    856 
    857 		/*
    858 		 * Set up a shared object descriptor and add to it the necessary
    859 		 * needed versions.  This information may also have been added
    860 		 * by a mapfile (see map_dash()).
    861 		 */
    862 		if ((sdf = sdf_find(name, ofl->ofl_soneed)) == NULL) {
    863 			if ((sdf = sdf_add(name, &ofl->ofl_soneed)) ==
    864 			    (Sdf_desc *)S_ERROR)
    865 				return (S_ERROR);
    866 			sdf->sdf_rfile = file;
    867 			sdf->sdf_flags |= FLG_SDF_VERIFY;
    868 		}
    869 
    870 		for (_cnt = 0; cnt; _cnt++, cnt--,
    871 		    vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next)) {
    872 			Sdv_desc	sdv;
    873 
    874 			sdv.sdv_name = str + vnap->vna_name;
    875 			sdv.sdv_ref = file;
    876 			sdv.sdv_flags = 0;
    877 
    878 			if (alist_append(&sdf->sdf_vers, &sdv,
    879 			    sizeof (Sdv_desc), AL_CNT_SDF_VERSIONS) == NULL)
    880 				return (S_ERROR);
    881 
    882 			DBG_CALL(Dbg_ver_need_entry(ofl->ofl_lml, _cnt, name,
    883 			    sdv.sdv_name));
    884 		}
    885 	}
    886 	return (1);
    887 }
    888 
    889 /*
    890  * If a symbol is obtained from a versioned relocatable object then the symbols
    891  * version association must be promoted to the version definition as it will be
    892  * represented in the output file.
    893  */
    894 void
    895 ld_vers_promote(Sym_desc *sdp, Word ndx, Ifl_desc *ifl, Ofl_desc *ofl)
    896 {
    897 	Half 	vndx;
    898 
    899 	/*
    900 	 * A version symbol index of 0 implies the symbol is local.  A value of
    901 	 * VER_NDX_GLOBAL implies the symbol is global but has not been
    902 	 * assigned to a specfic version definition.
    903 	 */
    904 	vndx = ifl->ifl_versym[ndx];
    905 	if (vndx == 0) {
    906 		sdp->sd_flags |= (FLG_SY_REDUCED | FLG_SY_HIDDEN);
    907 		return;
    908 	}
    909 
    910 	if (vndx == VER_NDX_ELIMINATE) {
    911 		sdp->sd_flags |= (FLG_SY_REDUCED | FLG_SY_HIDDEN | FLG_SY_ELIM);
    912 		return;
    913 	}
    914 
    915 	if (vndx == VER_NDX_GLOBAL) {
    916 		if ((sdp->sd_flags & FLG_SY_HIDDEN) == 0)
    917 			sdp->sd_flags |= (FLG_SY_DEFAULT | FLG_SY_EXPDEF);
    918 		if (sdp->sd_aux->sa_overndx <= VER_NDX_GLOBAL)
    919 			sdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;
    920 		return;
    921 	}
    922 
    923 	/*
    924 	 * Any other version index requires association to the appropriate
    925 	 * version definition.
    926 	 */
    927 	if ((ifl->ifl_verndx == 0) || (vndx > ifl->ifl_vercnt)) {
    928 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_VER_INVALNDX),
    929 		    sdp->sd_name, ifl->ifl_name, vndx);
    930 		ofl->ofl_flags |= FLG_OF_FATAL;
    931 		return;
    932 	}
    933 
    934 	if ((sdp->sd_flags & FLG_SY_HIDDEN) == 0)
    935 		sdp->sd_flags |= (FLG_SY_DEFAULT | FLG_SY_EXPDEF);
    936 
    937 	/*
    938 	 * Promote the symbols version index to the appropriate output version
    939 	 * definition.
    940 	 */
    941 	if (!(sdp->sd_flags & FLG_SY_VERSPROM)) {
    942 		Ver_index	*vip;
    943 
    944 		vip = &ifl->ifl_verndx[vndx];
    945 		sdp->sd_aux->sa_overndx = vip->vi_desc->vd_ref->vd_ndx;
    946 		sdp->sd_flags |= FLG_SY_VERSPROM;
    947 	}
    948 }
    949 
    950 /*
    951  * If any versioning is called for make sure an initial version descriptor is
    952  * assigned to represent the file itself.  Known as the base version.
    953  */
    954 Ver_desc *
    955 ld_vers_base(Ofl_desc *ofl)
    956 {
    957 	Ver_desc	*vdp;
    958 	const char	*name;
    959 
    960 	/*
    961 	 * Determine the filename to associate to the version descriptor.  This
    962 	 * is either the SONAME (if one has been supplied) or the basename of
    963 	 * the output file.
    964 	 */
    965 	if ((name = ofl->ofl_soname) == NULL) {
    966 		const char	*str = ofl->ofl_name;
    967 
    968 		while (*str != '\0') {
    969 			if (*str++ == '/')
    970 				name = str;
    971 		}
    972 		if (name == NULL)
    973 			name = ofl->ofl_name;
    974 	}
    975 
    976 	/*
    977 	 * Generate the version descriptor.
    978 	 */
    979 	/* LINTED */
    980 	if ((vdp = ld_vers_desc(name, (Word)elf_hash(name),
    981 	    &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR)
    982 		return ((Ver_desc *)S_ERROR);
    983 
    984 	/*
    985 	 * Assign the base index to this version and initialize the output file
    986 	 * descriptor with the number of version descriptors presently in use.
    987 	 */
    988 	vdp->vd_ndx = ofl->ofl_vercnt = VER_NDX_GLOBAL;
    989 	vdp->vd_flags |= VER_FLG_BASE;
    990 
    991 	return (vdp);
    992 }
    993 
    994 /*
    995  * Now that all input shared objects have been processed, verify that all
    996  * version requirements have been met.  Any version control requirements will
    997  * have been specified by the user (and placed on the ofl_oscntl list) and are
    998  * verified at the time the object was processed (see ver_def_process()).
    999  * Here we process all version requirements established from shared objects
   1000  * themselves (ie,. NEEDED dependencies).
   1001  */
   1002 int
   1003 ld_vers_verify(Ofl_desc *ofl)
   1004 {
   1005 	Aliste		idx1;
   1006 	Sdf_desc	*sdf;
   1007 	char		*nv;
   1008 
   1009 	/*
   1010 	 * As with the runtime environment, disable all version verification if
   1011 	 * requested.
   1012 	 */
   1013 #if	defined(_ELF64)
   1014 	if ((nv = getenv(MSG_ORIG(MSG_LD_NOVERSION_64))) == NULL)
   1015 #else
   1016 	if ((nv = getenv(MSG_ORIG(MSG_LD_NOVERSION_32))) == NULL)
   1017 #endif
   1018 		nv = getenv(MSG_ORIG(MSG_LD_NOVERSION));
   1019 
   1020 	if (nv && (*nv != '\0'))
   1021 		return (1);
   1022 
   1023 	for (APLIST_TRAVERSE(ofl->ofl_soneed, idx1, sdf)) {
   1024 		Aliste		idx2;
   1025 		Sdv_desc	*sdv;
   1026 		Ifl_desc	*ifl = sdf->sdf_file;
   1027 
   1028 		if (!(sdf->sdf_flags & FLG_SDF_VERIFY))
   1029 			continue;
   1030 
   1031 		/*
   1032 		 * If this file contains no version definitions then ignore
   1033 		 * any versioning verification.  This is the same model as
   1034 		 * carried out by ld.so.1 and is intended to allow backward
   1035 		 * compatibility should a shared object with a version
   1036 		 * requirement be returned to an older system on which a
   1037 		 * non-versioned shared object exists.
   1038 		 */
   1039 		if ((ifl == NULL) || (ifl->ifl_verdesc == NULL))
   1040 			continue;
   1041 
   1042 		/*
   1043 		 * If individual versions were specified for this file make
   1044 		 * sure that they actually exist in the appropriate file, and
   1045 		 * that they are available for binding.
   1046 		 */
   1047 		for (ALIST_TRAVERSE(sdf->sdf_vers, idx2, sdv)) {
   1048 			Aliste		idx3;
   1049 			Ver_desc	*vdp;
   1050 			int		found = 0;
   1051 
   1052 			for (APLIST_TRAVERSE(ifl->ifl_verdesc, idx3, vdp)) {
   1053 				if (strcmp(sdv->sdv_name, vdp->vd_name) == 0) {
   1054 					found++;
   1055 					break;
   1056 				}
   1057 			}
   1058 			if (found) {
   1059 				Ver_index	*vip;
   1060 
   1061 				vip = &ifl->ifl_verndx[vdp->vd_ndx];
   1062 				if (!(vip->vi_flags & FLG_VER_AVAIL)) {
   1063 					eprintf(ofl->ofl_lml, ERR_FATAL,
   1064 					    MSG_INTL(MSG_VER_UNAVAIL),
   1065 					    ifl->ifl_name, sdv->sdv_name,
   1066 					    sdv->sdv_ref);
   1067 					ofl->ofl_flags |= FLG_OF_FATAL;
   1068 				}
   1069 			} else {
   1070 				eprintf(ofl->ofl_lml, ERR_FATAL,
   1071 				    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
   1072 				    sdv->sdv_name, sdv->sdv_ref);
   1073 				ofl->ofl_flags |= FLG_OF_FATAL;
   1074 			}
   1075 		}
   1076 	}
   1077 	return (1);
   1078 }
   1079