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