xref: /titanic_44/usr/src/cmd/sgs/libld/common/version.c (revision 18c2aff776a775d34a4c9893a4c72e0434d68e36)
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 2006 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 ld_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 ld_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(Ofl_desc *ofl, 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(ofl->ofl_lml, ERR_FATAL,
125 				    MSG_INTL(MSG_VER_CYCLIC));
126 				err = 1;
127 			}
128 			for (tmp_sp = 0; tmp_sp < ver_stk.ver_sp; tmp_sp++) {
129 				v = ver_stk.ver_stk[tmp_sp];
130 				if ((v->vd_flags & FLG_VER_CYCLIC) == 0) {
131 					v->vd_flags |= FLG_VER_CYCLIC;
132 					eprintf(ofl->ofl_lml, ERR_NONE,
133 					    MSG_INTL(MSG_VER_ADDVER),
134 					    v->vd_name);
135 				}
136 			}
137 			if ((vp->vd_flags & FLG_VER_CYCLIC) == 0) {
138 				vp->vd_flags |= FLG_VER_CYCLIC;
139 				eprintf(ofl->ofl_lml, ERR_NONE,
140 				    MSG_INTL(MSG_VER_ADDVER), 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(ofl, 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 ld_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_lml, 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(ofl, 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(ofl->ofl_lml, ERR_FATAL,
203 			    MSG_INTL(MSG_VER_UNDEF), name, 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(ofl->ofl_lml, 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(ofl->ofl_lml,
218 			    vdp->vd_name));
219 
220 		/*
221 		 * Update the version entry count to account for this new
222 		 * version descriptor (the count is the size in bytes).
223 		 */
224 		ofl->ofl_verdefsz += sizeof (Verdef);
225 
226 		/*
227 		 * Traverse this versions dependency list to determine what
228 		 * additional version dependencies we must account for against
229 		 * this descriptor.
230 		 */
231 		cnt = 1;
232 		for (LIST_TRAVERSE(&vdp->vd_deps, lnp2, _vdp)) {
233 #if	defined(__lint)
234 			/* get lint to think `_vdp' is used... */
235 			lnp2 = (Listnode *)_vdp;
236 #endif
237 			cnt++;
238 		}
239 		ofl->ofl_verdefsz += (cnt * sizeof (Verdaux));
240 
241 		/*
242 		 * Except for the base version descriptor, generate an absolute
243 		 * symbol to reflect this version.
244 		 */
245 		if (vdp->vd_flags & VER_FLG_BASE)
246 			continue;
247 
248 		if (vdp->vd_flags & VER_FLG_WEAK)
249 			bind = STB_WEAK;
250 		else
251 			bind = STB_GLOBAL;
252 
253 		if (sdp = ld_sym_find(name, vdp->vd_hash, &where, ofl)) {
254 			/*
255 			 * If the symbol already exists and is undefined or was
256 			 * defined in a shared library, convert it to an
257 			 * absolute.
258 			 */
259 			if ((sdp->sd_sym->st_shndx == SHN_UNDEF) ||
260 			    (sdp->sd_ref != REF_REL_NEED)) {
261 				sdp->sd_shndx = sdp->sd_sym->st_shndx = SHN_ABS;
262 				sdp->sd_sym->st_info =
263 					ELF_ST_INFO(bind, STT_OBJECT);
264 				sdp->sd_ref = REF_REL_NEED;
265 				sdp->sd_flags |= FLG_SY_SPECSEC;
266 				sdp->sd_flags1 |= FLG_SY1_GLOB;
267 				sdp->sd_aux->sa_overndx = vdp->vd_ndx;
268 
269 				/*
270 				 * If the reference originated from a mapfile
271 				 * insure we mark the symbol as used.
272 				 */
273 				if (sdp->sd_flags & FLG_SY_MAPREF)
274 					sdp->sd_flags |= FLG_SY_MAPUSED;
275 
276 			} else if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
277 			    (sdp->sd_sym->st_shndx != SHN_ABS) &&
278 			    (sdp->sd_ref == REF_REL_NEED)) {
279 				eprintf(ofl->ofl_lml, ERR_WARNING,
280 				    MSG_INTL(MSG_VER_DEFINED), name,
281 				    sdp->sd_file->ifl_name);
282 			}
283 		} else {
284 			/*
285 			 * If the symbol does not exist create it.
286 			 */
287 			if ((sym = libld_calloc(sizeof (Sym), 1)) == 0)
288 				return (S_ERROR);
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 			if ((sdp = ld_sym_enter(name, sym, vdp->vd_hash,
293 			    vdp->vd_file, ofl, 0, SHN_ABS, FLG_SY_SPECSEC,
294 			    FLG_SY1_GLOB, &where)) == (Sym_desc *)S_ERROR)
295 				return (S_ERROR);
296 			sdp->sd_ref = REF_REL_NEED;
297 			sdp->sd_aux->sa_overndx = vdp->vd_ndx;
298 		}
299 	}
300 	return (1);
301 }
302 
303 /*
304  * Dereference dependencies as a part of normalizing (allows recursion).
305  */
306 static void
307 vers_derefer(Ifl_desc *ifl, Ver_desc *vdp, int weak)
308 {
309 	Listnode	*lnp;
310 	Ver_desc	*_vdp;
311 	Ver_index	*vip = &ifl->ifl_verndx[vdp->vd_ndx];
312 
313 	/*
314 	 * If the head of the list was a weak then we only clear out
315 	 * weak dependencies, but if the head of the list was 'strong'
316 	 * we clear the REFER bit on all dependencies.
317 	 */
318 	if ((weak && (vdp->vd_flags & VER_FLG_WEAK)) || (!weak))
319 		vip->vi_flags &= ~FLG_VER_REFER;
320 
321 	for (LIST_TRAVERSE(&vdp->vd_deps, lnp, _vdp))
322 		vers_derefer(ifl, _vdp, weak);
323 }
324 
325 /*
326  * If we need to record the versions of any needed dependencies traverse the
327  * shared object dependency list and calculate what version needed entries are
328  * required.
329  */
330 uintptr_t
331 ld_vers_check_need(Ofl_desc *ofl)
332 {
333 	Listnode	*lnp1;
334 	Ifl_desc	*ifl;
335 
336 	/*
337 	 * Traverse the shared object list looking for dependencies.
338 	 */
339 	for (LIST_TRAVERSE(&ofl->ofl_sos, lnp1, ifl)) {
340 		Listnode	*lnp2;
341 		Ver_index	*vip;
342 		Ver_desc	*vdp;
343 		Sdf_desc	*sdf = ifl->ifl_sdfdesc;
344 		Byte		cnt, need;
345 
346 		if (!(ifl->ifl_flags & FLG_IF_NEEDED))
347 			continue;
348 
349 		if (ifl->ifl_vercnt <= VER_NDX_GLOBAL)
350 			continue;
351 
352 		/*
353 		 * If version needed definitions were specified in
354 		 * a mapfile ($SPECVERS=) then record those definitions
355 		 */
356 		if (sdf && (sdf->sdf_flags & FLG_SDF_SPECVER)) {
357 			Sdv_desc	*sdv;
358 			for (LIST_TRAVERSE(&sdf->sdf_verneed, lnp2,
359 			    sdv)) {
360 				ofl->ofl_verneedsz += sizeof (Vernaux);
361 				if (st_insert(ofl->ofl_dynstrtab,
362 				    sdv->sdv_name) == -1)
363 					return (S_ERROR);
364 			}
365 			ifl->ifl_flags |= FLG_IF_VERNEED;
366 			ofl->ofl_verneedsz += sizeof (Verneed);
367 			if (st_insert(ofl->ofl_dynstrtab,
368 			    ifl->ifl_soname) == -1)
369 				return (S_ERROR);
370 			continue;
371 		}
372 
373 		/*
374 		 * Scan the version index list and if any weak version
375 		 * definition has been referenced by the user promote the
376 		 * dependency to be non-weak.  Weak version dependencies do not
377 		 * cause fatal errors from the runtime linker, non-weak
378 		 * dependencies do.
379 		 */
380 		for (need = 0, cnt = 0; cnt <= ifl->ifl_vercnt; cnt++) {
381 			vip = &ifl->ifl_verndx[cnt];
382 			vdp = vip->vi_desc;
383 
384 			if ((vip->vi_flags & (FLG_VER_REFER | VER_FLG_WEAK)) ==
385 			    (FLG_VER_REFER | VER_FLG_WEAK))
386 				vdp->vd_flags &= ~VER_FLG_WEAK;
387 
388 			/*
389 			 * Mark any weak reference as referred to so as to
390 			 * simplify normalization and later version dependency
391 			 * manipulation.
392 			 */
393 			if (vip->vi_flags & VER_FLG_WEAK)
394 				vip->vi_flags |= FLG_VER_REFER;
395 		}
396 
397 		/*
398 		 * Scan the version dependency list to normalize the referenced
399 		 * dependencies.  Any needed version that is inherited by
400 		 * another like version is derefereced as it is not necessary
401 		 * to make this part of the version dependencies.
402 		 */
403 		for (LIST_TRAVERSE(&ifl->ifl_verdesc, lnp2, vdp)) {
404 			Listnode	*lnp3;
405 			Ver_desc	*_vdp;
406 			int		type;
407 
408 			vip = &ifl->ifl_verndx[vdp->vd_ndx];
409 
410 			if (!(vip->vi_flags & FLG_VER_REFER))
411 				continue;
412 
413 			type = vdp->vd_flags & VER_FLG_WEAK;
414 			for (LIST_TRAVERSE(&vdp->vd_deps, lnp3, _vdp))
415 				vers_derefer(ifl, _vdp, type);
416 		}
417 
418 		/*
419 		 * Finally, determine how many of the version dependencies need
420 		 * to be recorded.
421 		 */
422 		for (need = 0, cnt = 0; cnt <= ifl->ifl_vercnt; cnt++) {
423 			vip = &ifl->ifl_verndx[cnt];
424 
425 			/*
426 			 * If a version has been referenced then record it as a
427 			 * version dependency.
428 			 */
429 			if (vip->vi_flags & FLG_VER_REFER) {
430 				ofl->ofl_verneedsz += sizeof (Vernaux);
431 				if (st_insert(ofl->ofl_dynstrtab,
432 				    vip->vi_name) == -1)
433 					return (S_ERROR);
434 				need++;
435 			}
436 		}
437 
438 		if (need) {
439 			ifl->ifl_flags |= FLG_IF_VERNEED;
440 			ofl->ofl_verneedsz += sizeof (Verneed);
441 			if (st_insert(ofl->ofl_dynstrtab,
442 			    ifl->ifl_soname) == -1)
443 				return (S_ERROR);
444 		}
445 	}
446 
447 	/*
448 	 * If no version needed information is required unset the output file
449 	 * flag.
450 	 */
451 	if (ofl->ofl_verneedsz == 0)
452 		ofl->ofl_flags &= ~FLG_OF_VERNEED;
453 
454 	return (1);
455 }
456 
457 /*
458  * Indicate dependency selection (allows recursion).
459  */
460 static void
461 vers_select(Ofl_desc *ofl, Ifl_desc *ifl, Ver_desc *vdp, const char *ref)
462 {
463 	Listnode	*lnp;
464 	Ver_desc	*_vdp;
465 	Ver_index	*vip = &ifl->ifl_verndx[vdp->vd_ndx];
466 
467 	vip->vi_flags |= FLG_VER_AVAIL;
468 	DBG_CALL(Dbg_ver_avail_entry(ofl->ofl_lml, vip, ref));
469 
470 	for (LIST_TRAVERSE(&vdp->vd_deps, lnp, _vdp))
471 		vers_select(ofl, ifl, _vdp, ref);
472 }
473 
474 static Ver_index *
475 vers_index(Ofl_desc *ofl, Ifl_desc *ifl, int avail)
476 {
477 	Listnode	*lnp;
478 	Ver_desc	*vdp;
479 	Ver_index	*vip;
480 	Sdf_desc	*sdf = ifl->ifl_sdfdesc;
481 	Word		count = ifl->ifl_vercnt;
482 	Sdv_desc	*sdv;
483 
484 	/*
485 	 * Allocate an index array large enough to hold all of the files
486 	 * version descriptors.
487 	 */
488 	if ((vip = libld_calloc(sizeof (Ver_index),
489 	    (count + 1))) == 0)
490 		return ((Ver_index *)S_ERROR);
491 
492 	for (LIST_TRAVERSE(&ifl->ifl_verdesc, lnp, vdp)) {
493 		int		ndx = vdp->vd_ndx;
494 
495 		vip[ndx].vi_name = vdp->vd_name;
496 		vip[ndx].vi_desc = vdp;
497 
498 		/*
499 		 * Any relocatable object versions, and the `base' version are
500 		 * always available.
501 		 */
502 		if (avail || (vdp->vd_flags & VER_FLG_BASE))
503 			vip[ndx].vi_flags |= FLG_VER_AVAIL;
504 
505 		/*
506 		 * If this is a weak version mark it as such.  Weak versions
507 		 * are always dragged into any version dependencies created,
508 		 * and if a weak version is referenced it will be promoted to
509 		 * a non-weak version dependency.
510 		 */
511 		if (vdp->vd_flags & VER_FLG_WEAK)
512 			vip[ndx].vi_flags |= VER_FLG_WEAK;
513 		/*
514 		 * If this version is mentioned in a mapfile
515 		 * $ADDVERS syntax then add a FLG_IF_NEEDED flag now
516 		 */
517 		if (sdf && (sdf->sdf_flags & FLG_SDF_ADDVER)) {
518 			Listnode *	lnp2;
519 			for (LIST_TRAVERSE(&sdf->sdf_verneed, lnp2, sdv)) {
520 				if (strcmp(vip[ndx].vi_name,
521 				    sdv->sdv_name) == 0) {
522 					vip[ndx].vi_flags |= FLG_VER_REFER;
523 					sdv->sdv_flags |= FLG_SDV_MATCHED;
524 					break;
525 				}
526 			}
527 		}
528 	}
529 
530 	/*
531 	 * if $ADDVER was specified for this object verify that
532 	 * all of it's dependent upon versions were refered to.
533 	 */
534 	if (sdf && (sdf->sdf_flags & FLG_SDF_ADDVER)) {
535 		int	fail = 0;
536 		for (LIST_TRAVERSE(&sdf->sdf_verneed, lnp, sdv)) {
537 			if (!(sdv->sdv_flags & FLG_SDV_MATCHED)) {
538 				if (fail == 0) {
539 					fail++;
540 					eprintf(ofl->ofl_lml, ERR_NONE,
541 					    MSG_INTL(MSG_VER_ADDVERS),
542 					    sdf->sdf_rfile, sdf->sdf_name);
543 				}
544 				eprintf(ofl->ofl_lml, ERR_NONE,
545 				    MSG_INTL(MSG_VER_ADDVER), sdv->sdv_name);
546 			}
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 		eprintf(lml, ERR_WARNING, MSG_INTL(MSG_ELF_VERSYM),
572 		    ifl->ifl_name, isp->is_name,
573 		    EC_WORD(vershdr->sh_size / vershdr->sh_entsize),
574 		    ifl->ifl_isdesc[vershdr->sh_link]->is_name,
575 		    EC_WORD(symshdr->sh_size / symshdr->sh_entsize));
576 		return (1);
577 	}
578 	ifl->ifl_versym = (Versym *)isp->is_indata->d_buf;
579 	return (1);
580 }
581 
582 /*
583  * Process a version definition section from an input file.  A list of version
584  * descriptors is created and associated with the input files descriptor.  If
585  * this is a shared object these descriptors will be used to indicate the
586  * availability of each version.  If this is a relocatable object then these
587  * descriptors will be promoted (concatenated) to the output files image.
588  */
589 uintptr_t
590 ld_vers_def_process(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl)
591 {
592 	const char	*str, *file = ifl->ifl_name;
593 	Sdf_desc	*sdf = ifl->ifl_sdfdesc;
594 	Sdv_desc	*sdv;
595 	Word		num, _num;
596 	Verdef		*vdf;
597 	int		relobj;
598 
599 	/*
600 	 * If there is no version section then simply indicate that all version
601 	 * definitions asked for do not exist.
602 	 */
603 	if (isp == 0) {
604 		Listnode	*lnp;
605 
606 		for (LIST_TRAVERSE(&sdf->sdf_vers, lnp, sdv)) {
607 			eprintf(ofl->ofl_lml, ERR_FATAL,
608 			    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
609 			    sdv->sdv_name, sdv->sdv_ref);
610 			ofl->ofl_flags |= FLG_OF_FATAL;
611 		}
612 		return (0);
613 	}
614 
615 	vdf = (Verdef *)isp->is_indata->d_buf;
616 
617 	/*
618 	 * Verify the version revision.  We only check the first version
619 	 * structure as it is assumed all other version structures in this
620 	 * data section will be of the same revision.
621 	 */
622 	if (vdf->vd_version > VER_DEF_CURRENT)
623 		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
624 		    MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vdf->vd_version,
625 		    VER_DEF_CURRENT);
626 
627 
628 	num = isp->is_shdr->sh_info;
629 	str = (char *)ifl->ifl_isdesc[isp->is_shdr->sh_link]->is_indata->d_buf;
630 
631 	if (ifl->ifl_ehdr->e_type == ET_REL)
632 		relobj = 1;
633 	else
634 		relobj = 0;
635 
636 	DBG_CALL(Dbg_ver_def_title(ofl->ofl_lml, file));
637 
638 	/*
639 	 * Loop through the version information setting up a version descriptor
640 	 * for each version definition.
641 	 */
642 	for (_num = 1; _num <= num; _num++,
643 	    vdf = (Verdef *)((uintptr_t)vdf + vdf->vd_next)) {
644 		const char	*name;
645 		Ver_desc	*ivdp, *ovdp = 0;
646 		Word		hash;
647 		Half 		cnt = vdf->vd_cnt;
648 		Half		ndx = vdf->vd_ndx;
649 		Verdaux		*vdap = (Verdaux *)((uintptr_t)vdf +
650 				    vdf->vd_aux);
651 
652 		/*
653 		 * Keep track of the largest index for use in creating a
654 		 * version index array later, and create a version descriptor.
655 		 */
656 		if (ndx > ifl->ifl_vercnt)
657 			ifl->ifl_vercnt = ndx;
658 
659 		name = (char *)(str + vdap->vda_name);
660 		/* LINTED */
661 		hash = (Word)elf_hash(name);
662 		if ((ivdp = ld_vers_find(name, hash, &ifl->ifl_verdesc)) == 0) {
663 			if ((ivdp = ld_vers_desc(name, hash,
664 			    &ifl->ifl_verdesc)) == (Ver_desc *)S_ERROR)
665 				return (S_ERROR);
666 		}
667 		ivdp->vd_ndx = ndx;
668 		ivdp->vd_file = ifl;
669 		ivdp->vd_flags = vdf->vd_flags;
670 
671 		/*
672 		 * If we're processing a relocatable object then this version
673 		 * definition needs to be propagated to the output file.
674 		 * Generate a new output file version and associated this input
675 		 * version to it.  During symbol processing the version index of
676 		 * the symbol will be promoted from the input file to the output
677 		 * files version definition.
678 		 */
679 		if (relobj) {
680 			if (!(ofl->ofl_flags & FLG_OF_RELOBJ))
681 				ofl->ofl_flags |= FLG_OF_PROCRED;
682 
683 			if ((ivdp->vd_flags & VER_FLG_BASE) == 0) {
684 				/*
685 				 * If no version descriptors have yet been set
686 				 * up, initialize a base version to represent
687 				 * the output file itself.  This `base' version
688 				 * catches any internally generated symbols
689 				 * (_end, _etext, etc.) and
690 				 * serves to initialize the output version
691 				 * descriptor count.
692 				 */
693 				if (ofl->ofl_vercnt == 0) {
694 					if (ld_vers_base(ofl) ==
695 					    (Ver_desc *)S_ERROR)
696 						return (S_ERROR);
697 				}
698 				ofl->ofl_flags |= FLG_OF_VERDEF;
699 				if ((ovdp = ld_vers_find(name, hash,
700 				    &ofl->ofl_verdesc)) == 0) {
701 					if ((ovdp = ld_vers_desc(name, hash,
702 					    &ofl->ofl_verdesc)) ==
703 					    (Ver_desc *)S_ERROR)
704 						return (S_ERROR);
705 
706 					/* LINTED */
707 					ovdp->vd_ndx = (Half)++ofl->ofl_vercnt;
708 					ovdp->vd_file = ifl;
709 					ovdp->vd_flags = vdf->vd_flags;
710 				}
711 			}
712 
713 			/*
714 			 * Maintain the association between the input version
715 			 * descriptor and the output version descriptor so that
716 			 * an associated symbols will be assigned to the
717 			 * correct version.
718 			 */
719 			ivdp->vd_ref = ovdp;
720 		}
721 
722 		/*
723 		 * Process any dependencies this version may have.
724 		 */
725 		vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next);
726 		for (cnt--; cnt; cnt--,
727 		    vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next)) {
728 			Ver_desc	*_ivdp;
729 
730 			name = (char *)(str + vdap->vda_name);
731 			/* LINTED */
732 			hash = (Word)elf_hash(name);
733 
734 			if ((_ivdp = ld_vers_find(name, hash,
735 			    &ifl->ifl_verdesc)) == 0) {
736 				if ((_ivdp = ld_vers_desc(name, hash,
737 				    &ifl->ifl_verdesc)) ==
738 				    (Ver_desc *)S_ERROR)
739 					return (S_ERROR);
740 			}
741 			if (list_appendc(&ivdp->vd_deps, _ivdp) == 0)
742 				return (S_ERROR);
743 		}
744 		DBG_CALL(Dbg_ver_desc_entry(ofl->ofl_lml, ivdp));
745 	}
746 
747 	/*
748 	 * Now that we know the total number of version definitions for this
749 	 * file, build an index array for fast access when processing symbols.
750 	 */
751 	if ((ifl->ifl_verndx =
752 	    vers_index(ofl, ifl, relobj)) == (Ver_index *)S_ERROR)
753 		return (S_ERROR);
754 
755 	if (relobj)
756 		return (1);
757 
758 	/*
759 	 * If this object has version control definitions against it then these
760 	 * must be processed so as to select those version definitions to which
761 	 * symbol bindings can occur.  Otherwise simply mark all versions as
762 	 * available.
763 	 */
764 	DBG_CALL(Dbg_ver_avail_title(ofl->ofl_lml, file));
765 
766 	if (sdf && (sdf->sdf_flags & FLG_SDF_SELECT)) {
767 		Listnode	*lnp1;
768 
769 		for (LIST_TRAVERSE(&sdf->sdf_vers, lnp1, sdv)) {
770 			Listnode	*lnp2;
771 			Ver_desc	*vdp;
772 			int		found = 0;
773 
774 			for (LIST_TRAVERSE(&ifl->ifl_verdesc, lnp2, vdp)) {
775 				if (strcmp(sdv->sdv_name, vdp->vd_name) == 0) {
776 					found++;
777 					break;
778 				}
779 			}
780 			if (found)
781 				vers_select(ofl, ifl, vdp, sdv->sdv_ref);
782 			else {
783 				eprintf(ofl->ofl_lml, ERR_FATAL,
784 				    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
785 				    sdv->sdv_name, sdv->sdv_ref);
786 				ofl->ofl_flags |= FLG_OF_FATAL;
787 			}
788 		}
789 	} else {
790 		Ver_index	*vip;
791 		int		cnt;
792 
793 		for (cnt = VER_NDX_GLOBAL; cnt <= ifl->ifl_vercnt; cnt++) {
794 			vip = &ifl->ifl_verndx[cnt];
795 			vip->vi_flags |= FLG_VER_AVAIL;
796 			DBG_CALL(Dbg_ver_avail_entry(ofl->ofl_lml, vip, 0));
797 		}
798 	}
799 
800 	/*
801 	 * If this is an explict dependency indicate that this file is a
802 	 * candidate for requiring version needed information to be recorded in
803 	 * the image we're creating.
804 	 */
805 	if (ifl->ifl_flags & FLG_IF_NEEDED)
806 		ofl->ofl_flags |= FLG_OF_VERNEED;
807 
808 	return (1);
809 }
810 
811 /*
812  * Process a version needed section.
813  */
814 uintptr_t
815 ld_vers_need_process(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl)
816 {
817 	const char	*str, *file = ifl->ifl_name;
818 	Word		num, _num;
819 	Verneed		*vnd;
820 
821 	vnd = (Verneed *)isp->is_indata->d_buf;
822 
823 	/*
824 	 * Verify the version revision.  We only check the first version
825 	 * structure as it is assumed all other version structures in this
826 	 * data section will be of the same revision.
827 	 */
828 	if (vnd->vn_version > VER_DEF_CURRENT) {
829 		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
830 		    MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vnd->vn_version,
831 		    VER_DEF_CURRENT);
832 	}
833 
834 	num = isp->is_shdr->sh_info;
835 	str = (char *)ifl->ifl_isdesc[isp->is_shdr->sh_link]->is_indata->d_buf;
836 
837 	DBG_CALL(Dbg_ver_need_title(ofl->ofl_lml, file));
838 
839 	/*
840 	 * Loop through the version information setting up a version descriptor
841 	 * for each version definition.
842 	 */
843 	for (_num = 1; _num <= num; _num++,
844 	    vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) {
845 		Sdf_desc	*sdf;
846 		Sdv_desc	*sdv;
847 		const char	*name;
848 		Half		cnt = vnd->vn_cnt;
849 		Vernaux		*vnap = (Vernaux *)((uintptr_t)vnd +
850 				    vnd->vn_aux);
851 		Half		_cnt;
852 
853 		name = (char *)(str + vnd->vn_file);
854 
855 		/*
856 		 * Set up a shared object descriptor and add to it the necessary
857 		 * needed versions.  This information may also have been added
858 		 * by a mapfile (see map_dash()).
859 		 */
860 		if ((sdf = sdf_find(name, &ofl->ofl_soneed)) == 0) {
861 			if ((sdf = sdf_add(name, &ofl->ofl_soneed)) ==
862 			    (Sdf_desc *)S_ERROR)
863 				return (S_ERROR);
864 			sdf->sdf_rfile = file;
865 			sdf->sdf_flags |= FLG_SDF_VERIFY;
866 		}
867 
868 		for (_cnt = 0; cnt; _cnt++, cnt--,
869 		    vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next)) {
870 			if (!(sdv =
871 			    libld_calloc(sizeof (Sdv_desc), 1)))
872 				return (S_ERROR);
873 			sdv->sdv_name = str + vnap->vna_name;
874 			sdv->sdv_ref = file;
875 			if (list_appendc(&sdf->sdf_vers, sdv) == 0)
876 				return (S_ERROR);
877 			DBG_CALL(Dbg_ver_need_entry(ofl->ofl_lml, _cnt, name,
878 			    sdv->sdv_name));
879 		}
880 	}
881 
882 	return (1);
883 }
884 
885 /*
886  * If a symbol is obtained from a versioned relocatable object then the symbols
887  * version association must be promoted to the version definition as it will be
888  * represented in the output file.
889  */
890 void
891 ld_vers_promote(Sym_desc *sdp, Word ndx, Ifl_desc *ifl, Ofl_desc *ofl)
892 {
893 	Half 	vndx;
894 
895 	/*
896 	 * A version symbol index of 0 implies the symbol is local.  A value of
897 	 * VER_NDX_GLOBAL implies the symbol is global but has not been
898 	 * assigned to a specfic version definition.
899 	 */
900 	vndx = ifl->ifl_versym[ndx];
901 	if (vndx == 0) {
902 		sdp->sd_flags |= FLG_SY_REDUCED;
903 		sdp->sd_flags1 |= FLG_SY1_LOCL;
904 		return;
905 	}
906 
907 	if (vndx == VER_NDX_ELIMINATE) {
908 		sdp->sd_flags |= FLG_SY_REDUCED;
909 		sdp->sd_flags1 |= (FLG_SY1_LOCL | FLG_SY1_ELIM);
910 		return;
911 	}
912 
913 	if (vndx == VER_NDX_GLOBAL) {
914 		if (!(sdp->sd_flags1 & FLG_SY1_LOCL)) {
915 			sdp->sd_flags1 |= FLG_SY1_GLOB;
916 			sdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;
917 		}
918 		return;
919 	}
920 
921 	/*
922 	 * Any other version index requires association to the appropriate
923 	 * version definition.
924 	 */
925 	if ((ifl->ifl_verndx == 0) || (vndx > ifl->ifl_vercnt)) {
926 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_VER_INVALNDX),
927 		    sdp->sd_name, ifl->ifl_name, vndx);
928 		ofl->ofl_flags |= FLG_OF_FATAL;
929 		return;
930 	}
931 
932 	if (!(sdp->sd_flags1 & FLG_SY1_LOCL))
933 		sdp->sd_flags1 |= FLG_SY1_GLOB;
934 
935 	/*
936 	 * Promote the symbols version index to the appropriate output version
937 	 * definition.
938 	 */
939 	if (!(sdp->sd_flags & FLG_SY_VERSPROM)) {
940 		Ver_index	*vip;
941 
942 		vip = &ifl->ifl_verndx[vndx];
943 		sdp->sd_aux->sa_overndx = vip->vi_desc->vd_ref->vd_ndx;
944 		sdp->sd_flags |= FLG_SY_VERSPROM;
945 	}
946 }
947 
948 /*
949  * If any versioning is called for make sure an initial version descriptor is
950  * assigned to represent the file itself.  Known as the base version.
951  */
952 Ver_desc *
953 ld_vers_base(Ofl_desc *ofl)
954 {
955 	Ver_desc	*vdp;
956 	const char	*name;
957 
958 	/*
959 	 * Determine the filename to associate to the version descriptor.  This
960 	 * is either the SONAME (if one has been supplied) or the basename of
961 	 * the output file.
962 	 */
963 	if ((name = ofl->ofl_soname) == 0) {
964 		const char	*str = ofl->ofl_name;
965 
966 		while (*str != '\0') {
967 			if (*str++ == '/')
968 				name = str;
969 		}
970 		if (name == 0)
971 			name = ofl->ofl_name;
972 	}
973 
974 	/*
975 	 * Generate the version descriptor.
976 	 */
977 	/* LINTED */
978 	if ((vdp = ld_vers_desc(name, (Word)elf_hash(name),
979 	    &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR)
980 		return ((Ver_desc *)S_ERROR);
981 
982 	/*
983 	 * Assign the base index to this version and initialize the output file
984 	 * descriptor with the number of version descriptors presently in use.
985 	 */
986 	vdp->vd_ndx = ofl->ofl_vercnt = VER_NDX_GLOBAL;
987 	vdp->vd_flags |= VER_FLG_BASE;
988 
989 	return (vdp);
990 }
991 
992 /*
993  * Now that all input shared objects have been processed, verify that all
994  * version requirements have been met.  Any version control requirements will
995  * have been specified by the user (and placed on the ofl_oscntl list) and are
996  * verified at the time the object was processed (see ver_def_process()).
997  * Here we process all version requirements established from shared objects
998  * themselves (ie,. NEEDED dependencies).
999  */
1000 int
1001 ld_vers_verify(Ofl_desc *ofl)
1002 {
1003 	Listnode	*lnp1;
1004 	Sdf_desc	*sdf;
1005 	char		*nv;
1006 
1007 	/*
1008 	 * As with the runtime environment, disable all version verification if
1009 	 * requested.
1010 	 */
1011 #if	defined(_ELF64)
1012 	if ((nv = getenv(MSG_ORIG(MSG_LD_NOVERSION_64))) == NULL)
1013 #else
1014 	if ((nv = getenv(MSG_ORIG(MSG_LD_NOVERSION_32))) == NULL)
1015 #endif
1016 	    nv = getenv(MSG_ORIG(MSG_LD_NOVERSION));
1017 
1018 	if (nv && (*nv != '\0'))
1019 		return (1);
1020 
1021 	for (LIST_TRAVERSE(&ofl->ofl_soneed, lnp1, sdf)) {
1022 		Listnode	*lnp2;
1023 		Sdv_desc	*sdv;
1024 		Ifl_desc	*ifl = sdf->sdf_file;
1025 
1026 		if (!(sdf->sdf_flags & FLG_SDF_VERIFY))
1027 			continue;
1028 
1029 		/*
1030 		 * If this file contains no version definitions then ignore
1031 		 * any versioning verification.  This is the same model as
1032 		 * carried out by ld.so.1 and is intended to allow backward
1033 		 * compatibility should a shared object with a version
1034 		 * requirment be returned to an older system on which a
1035 		 * non-versioned shared object exists.
1036 		 */
1037 		if ((ifl == 0) || (ifl->ifl_verdesc.head == 0))
1038 			continue;
1039 
1040 		/*
1041 		 * If individual versions were specified for this file make
1042 		 * sure that they actually exist in the appropriate file, and
1043 		 * that they are available for binding.
1044 		 */
1045 		for (LIST_TRAVERSE(&sdf->sdf_vers, lnp2, sdv)) {
1046 			Listnode	*lnp3;
1047 			Ver_desc	*vdp;
1048 			int		found = 0;
1049 
1050 			for (LIST_TRAVERSE(&ifl->ifl_verdesc, lnp3, vdp)) {
1051 				if (strcmp(sdv->sdv_name, vdp->vd_name) == 0) {
1052 					found++;
1053 					break;
1054 				}
1055 			}
1056 			if (found) {
1057 				Ver_index	*vip;
1058 
1059 				vip = &ifl->ifl_verndx[vdp->vd_ndx];
1060 				if (!(vip->vi_flags & FLG_VER_AVAIL)) {
1061 					eprintf(ofl->ofl_lml, ERR_FATAL,
1062 					    MSG_INTL(MSG_VER_UNAVAIL),
1063 					    ifl->ifl_name, sdv->sdv_name,
1064 					    sdv->sdv_ref);
1065 					ofl->ofl_flags |= FLG_OF_FATAL;
1066 				}
1067 			} else {
1068 				eprintf(ofl->ofl_lml, ERR_FATAL,
1069 				    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
1070 				    sdv->sdv_name, sdv->sdv_ref);
1071 				ofl->ofl_flags |= FLG_OF_FATAL;
1072 			}
1073 		}
1074 	}
1075 	return (1);
1076 }
1077