version.c revision 11827:d7ef53deac3f
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 2010 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 */
36Ver_desc *
37ld_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 */
57Ver_desc *
58ld_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 */
82typedef struct {
83	Ver_desc	**ver_stk;
84	int 		ver_sp;
85	int 		ver_lmt;
86} Ver_Stack;
87
88static uintptr_t
89vers_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
171uintptr_t
172ld_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 */
309static void
310vers_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 */
338uintptr_t
339ld_vers_check_need(Ofl_desc *ofl)
340{
341	Aliste		idx1;
342	Ifl_desc	*ifl;
343	Half		needndx;
344	Str_tbl		*strtbl;
345
346
347	/*
348	 * Determine which string table is appropriate.
349	 */
350	strtbl = (OFL_IS_STATIC_OBJ(ofl)) ? ofl->ofl_strtab :
351	    ofl->ofl_dynstrtab;
352
353	/*
354	 * Versym indexes for needed versions start with the next
355	 * available version after the final definied version.
356	 * However, it can never be less than 2. 0 is always for local
357	 * scope, and 1 is always the first global definition.
358	 */
359	needndx = (ofl->ofl_vercnt > 0) ? (ofl->ofl_vercnt + 1) : 2;
360
361	/*
362	 * Traverse the shared object list looking for dependencies.
363	 */
364	for (APLIST_TRAVERSE(ofl->ofl_sos, idx1, ifl)) {
365		Aliste		idx2;
366		Ver_index	*vip;
367		Ver_desc	*vdp;
368		Byte		cnt, need = 0;
369
370		if (!(ifl->ifl_flags & FLG_IF_NEEDED))
371			continue;
372
373		if (ifl->ifl_vercnt <= VER_NDX_GLOBAL)
374			continue;
375
376		/*
377		 * Scan the version index list and if any weak version
378		 * definition has been referenced by the user promote the
379		 * dependency to be non-weak.  Weak version dependencies do not
380		 * cause fatal errors from the runtime linker, non-weak
381		 * dependencies do.
382		 */
383		for (cnt = 0; cnt <= ifl->ifl_vercnt; cnt++) {
384			vip = &ifl->ifl_verndx[cnt];
385			vdp = vip->vi_desc;
386
387			if ((vip->vi_flags & (FLG_VER_REFER | VER_FLG_WEAK)) ==
388			    (FLG_VER_REFER | VER_FLG_WEAK))
389				vdp->vd_flags &= ~VER_FLG_WEAK;
390
391			/*
392			 * Mark any weak reference as referred to so as to
393			 * simplify normalization and later version dependency
394			 * manipulation.
395			 */
396			if (vip->vi_flags & VER_FLG_WEAK)
397				vip->vi_flags |= FLG_VER_REFER;
398		}
399
400		/*
401		 * Scan the version dependency list to normalize the referenced
402		 * dependencies.  Any needed version that is inherited by
403		 * another like version is dereferenced as it is not necessary
404		 * to make this part of the version dependencies.
405		 */
406		for (APLIST_TRAVERSE(ifl->ifl_verdesc, idx2, vdp)) {
407			Aliste		idx3;
408			Ver_desc	*_vdp;
409			int		type;
410
411			vip = &ifl->ifl_verndx[vdp->vd_ndx];
412
413			if (!(vip->vi_flags & FLG_VER_REFER))
414				continue;
415
416			type = vdp->vd_flags & VER_FLG_WEAK;
417			for (APLIST_TRAVERSE(vdp->vd_deps, idx3, _vdp))
418				vers_derefer(ifl, _vdp, type);
419		}
420
421		/*
422		 * Finally, determine how many of the version dependencies need
423		 * to be recorded.
424		 */
425		for (cnt = 0; cnt <= ifl->ifl_vercnt; cnt++) {
426			vip = &ifl->ifl_verndx[cnt];
427
428			/*
429			 * If a version has been referenced then record it as a
430			 * version dependency.
431			 */
432			if (vip->vi_flags & FLG_VER_REFER) {
433				/* Assign a VERSYM index for it */
434				vip->vi_overndx = needndx++;
435
436				ofl->ofl_verneedsz += sizeof (Vernaux);
437				if (st_insert(strtbl, vip->vi_name) == -1)
438					return (S_ERROR);
439				need++;
440			}
441		}
442
443		if (need) {
444			ifl->ifl_flags |= FLG_IF_VERNEED;
445			ofl->ofl_verneedsz += sizeof (Verneed);
446			if (st_insert(strtbl, ifl->ifl_soname) == -1)
447				return (S_ERROR);
448		}
449	}
450
451	/*
452	 * If no version needed information is required unset the output file
453	 * flag.
454	 */
455	if (ofl->ofl_verneedsz == 0)
456		ofl->ofl_flags &= ~FLG_OF_VERNEED;
457
458	return (1);
459}
460
461/*
462 * Indicate dependency selection (allows recursion).
463 */
464static void
465vers_select(Ofl_desc *ofl, Ifl_desc *ifl, Ver_desc *vdp, const char *ref)
466{
467	Aliste		idx;
468	Ver_desc	*_vdp;
469	Ver_index	*vip = &ifl->ifl_verndx[vdp->vd_ndx];
470
471	vip->vi_flags |= FLG_VER_AVAIL;
472	DBG_CALL(Dbg_ver_avail_entry(ofl->ofl_lml, vip, ref));
473
474	for (APLIST_TRAVERSE(vdp->vd_deps, idx, _vdp))
475		vers_select(ofl, ifl, _vdp, ref);
476}
477
478static Ver_index *
479vers_index(Ofl_desc *ofl, Ifl_desc *ifl, int avail)
480{
481	Aliste		idx1;
482	Ver_desc	*vdp;
483	Ver_index	*vip;
484	Sdf_desc	*sdf = ifl->ifl_sdfdesc;
485	Word		count = ifl->ifl_vercnt;
486	Sdv_desc	*sdv;
487
488	/*
489	 * Allocate an index array large enough to hold all of the files
490	 * version descriptors.
491	 */
492	if ((vip = libld_calloc(sizeof (Ver_index), (count + 1))) == NULL)
493		return ((Ver_index *)S_ERROR);
494
495	for (APLIST_TRAVERSE(ifl->ifl_verdesc, idx1, vdp)) {
496		int	ndx = vdp->vd_ndx;
497
498		vip[ndx].vi_name = vdp->vd_name;
499		vip[ndx].vi_desc = vdp;
500
501		/*
502		 * Any relocatable object versions, and the `base' version are
503		 * always available.
504		 */
505		if (avail || (vdp->vd_flags & VER_FLG_BASE))
506			vip[ndx].vi_flags |= FLG_VER_AVAIL;
507
508		/*
509		 * If this is a weak version mark it as such.  Weak versions
510		 * are always dragged into any version dependencies created,
511		 * and if a weak version is referenced it will be promoted to
512		 * a non-weak version dependency.
513		 */
514		if (vdp->vd_flags & VER_FLG_WEAK)
515			vip[ndx].vi_flags |= VER_FLG_WEAK;
516		/*
517		 * If this version is mentioned in a mapfile using ADDVERS
518		 * syntax then check to see if it corresponds to an actual
519		 * version in the file.
520		 */
521		if (sdf && (sdf->sdf_flags & FLG_SDF_ADDVER)) {
522			Aliste	idx2;
523
524			for (ALIST_TRAVERSE(sdf->sdf_verneed, idx2, sdv)) {
525				if (strcmp(vip[ndx].vi_name, sdv->sdv_name))
526					continue;
527
528				vip[ndx].vi_flags |= FLG_VER_REFER;
529				sdv->sdv_flags |= FLG_SDV_MATCHED;
530				break;
531			}
532		}
533	}
534
535	/*
536	 * if $ADDVER was specified for this object verify that
537	 * all of it's dependent upon versions were refered to.
538	 */
539	if (sdf && (sdf->sdf_flags & FLG_SDF_ADDVER)) {
540		int	fail = 0;
541
542		for (ALIST_TRAVERSE(sdf->sdf_verneed, idx1, sdv)) {
543			if (sdv->sdv_flags & FLG_SDV_MATCHED)
544				continue;
545
546			if (fail++ == 0) {
547				eprintf(ofl->ofl_lml, ERR_NONE,
548				    MSG_INTL(MSG_VER_ADDVERS), sdf->sdf_rfile,
549				    sdf->sdf_name);
550			}
551			eprintf(ofl->ofl_lml, ERR_NONE,
552			    MSG_INTL(MSG_VER_ADDVER), sdv->sdv_name);
553		}
554		if (fail)
555			return ((Ver_index *)S_ERROR);
556	}
557
558	return (vip);
559}
560
561/*
562 * Process a version symbol index section.
563 */
564int
565ld_vers_sym_process(Lm_list *lml, Is_desc *isp, Ifl_desc *ifl)
566{
567	Shdr	*symshdr;
568	Shdr	*vershdr = isp->is_shdr;
569
570	/*
571	 * Verify that the versym is the same size as the linked symbol table.
572	 * If these two get out of sync the file is considered corrupted.
573	 */
574	symshdr = ifl->ifl_isdesc[vershdr->sh_link]->is_shdr;
575	if ((symshdr->sh_size / symshdr->sh_entsize) != (vershdr->sh_size /
576	    vershdr->sh_entsize)) {
577		Is_desc	*sym_isp = ifl->ifl_isdesc[vershdr->sh_link];
578
579		eprintf(lml, ERR_WARNING, MSG_INTL(MSG_ELF_VERSYM),
580		    ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name,
581		    EC_WORD(vershdr->sh_size / vershdr->sh_entsize),
582		    EC_WORD(sym_isp->is_scnndx), sym_isp->is_name,
583		    EC_WORD(symshdr->sh_size / symshdr->sh_entsize));
584		return (1);
585	}
586	ifl->ifl_versym = (Versym *)isp->is_indata->d_buf;
587	return (1);
588}
589
590/*
591 * Process a version definition section from an input file.  A list of version
592 * descriptors is created and associated with the input files descriptor.  If
593 * this is a shared object these descriptors will be used to indicate the
594 * availability of each version.  If this is a relocatable object then these
595 * descriptors will be promoted (concatenated) to the output files image.
596 */
597uintptr_t
598ld_vers_def_process(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl)
599{
600	const char	*str, *file = ifl->ifl_name;
601	Sdf_desc	*sdf = ifl->ifl_sdfdesc;
602	Sdv_desc	*sdv;
603	Word		num, _num;
604	Verdef		*vdf;
605	int		relobj;
606
607	/*
608	 * If there is no version section then simply indicate that all version
609	 * definitions asked for do not exist.
610	 */
611	if (isp == NULL) {
612		Aliste	idx;
613
614		for (ALIST_TRAVERSE(sdf->sdf_vers, idx, sdv)) {
615			eprintf(ofl->ofl_lml, ERR_FATAL,
616			    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
617			    sdv->sdv_name, sdv->sdv_ref);
618			ofl->ofl_flags |= FLG_OF_FATAL;
619		}
620		return (0);
621	}
622
623	vdf = (Verdef *)isp->is_indata->d_buf;
624
625	/*
626	 * Verify the version revision.  We only check the first version
627	 * structure as it is assumed all other version structures in this
628	 * data section will be of the same revision.
629	 */
630	if (vdf->vd_version > VER_DEF_CURRENT)
631		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
632		    MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vdf->vd_version,
633		    VER_DEF_CURRENT);
634
635
636	num = isp->is_shdr->sh_info;
637	str = (char *)ifl->ifl_isdesc[isp->is_shdr->sh_link]->is_indata->d_buf;
638
639	if (ifl->ifl_ehdr->e_type == ET_REL)
640		relobj = 1;
641	else
642		relobj = 0;
643
644	DBG_CALL(Dbg_ver_def_title(ofl->ofl_lml, file));
645
646	/*
647	 * Loop through the version information setting up a version descriptor
648	 * for each version definition.
649	 */
650	for (_num = 1; _num <= num; _num++,
651	    vdf = (Verdef *)((uintptr_t)vdf + vdf->vd_next)) {
652		const char	*name;
653		Ver_desc	*ivdp, *ovdp = NULL;
654		Word		hash;
655		Half 		cnt = vdf->vd_cnt;
656		Half		ndx = vdf->vd_ndx;
657		Verdaux		*vdap = (Verdaux *)((uintptr_t)vdf +
658		    vdf->vd_aux);
659
660		/*
661		 * Keep track of the largest index for use in creating a
662		 * version index array later, and create a version descriptor.
663		 */
664		if (ndx > ifl->ifl_vercnt)
665			ifl->ifl_vercnt = ndx;
666
667		name = (char *)(str + vdap->vda_name);
668		/* LINTED */
669		hash = (Word)elf_hash(name);
670		if (((ivdp = ld_vers_find(name, hash,
671		    ifl->ifl_verdesc)) == NULL) &&
672		    ((ivdp = ld_vers_desc(name, hash,
673		    &ifl->ifl_verdesc)) == (Ver_desc *)S_ERROR))
674			return (S_ERROR);
675
676		ivdp->vd_ndx = ndx;
677		ivdp->vd_file = ifl;
678		ivdp->vd_flags = vdf->vd_flags;
679
680		/*
681		 * If we're processing a relocatable object then this version
682		 * definition needs to be propagated to the output file.
683		 * Generate a new output file version and associated this input
684		 * version to it.  During symbol processing the version index of
685		 * the symbol will be promoted from the input file to the output
686		 * files version definition.
687		 */
688		if (relobj) {
689			if (!(ofl->ofl_flags & FLG_OF_RELOBJ))
690				ofl->ofl_flags |= FLG_OF_PROCRED;
691
692			if ((ivdp->vd_flags & VER_FLG_BASE) == 0) {
693				/*
694				 * If no version descriptors have yet been set
695				 * up, initialize a base version to represent
696				 * the output file itself.  This `base' version
697				 * catches any internally generated symbols
698				 * (_end, _etext, etc.) and
699				 * serves to initialize the output version
700				 * descriptor count.
701				 */
702				if (ofl->ofl_vercnt == 0) {
703					if (ld_vers_base(ofl) ==
704					    (Ver_desc *)S_ERROR)
705						return (S_ERROR);
706				}
707				ofl->ofl_flags |= FLG_OF_VERDEF;
708				if ((ovdp = ld_vers_find(name, hash,
709				    ofl->ofl_verdesc)) == NULL) {
710					if ((ovdp = ld_vers_desc(name, hash,
711					    &ofl->ofl_verdesc)) ==
712					    (Ver_desc *)S_ERROR)
713						return (S_ERROR);
714
715					/* LINTED */
716					ovdp->vd_ndx = (Half)++ofl->ofl_vercnt;
717					ovdp->vd_file = ifl;
718					ovdp->vd_flags = vdf->vd_flags;
719				}
720			}
721
722			/*
723			 * Maintain the association between the input version
724			 * descriptor and the output version descriptor so that
725			 * an associated symbols will be assigned to the
726			 * correct version.
727			 */
728			ivdp->vd_ref = ovdp;
729		}
730
731		/*
732		 * Process any dependencies this version may have.
733		 */
734		vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next);
735		for (cnt--; cnt; cnt--,
736		    vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next)) {
737			Ver_desc	*_ivdp;
738
739			name = (char *)(str + vdap->vda_name);
740			/* LINTED */
741			hash = (Word)elf_hash(name);
742
743			if (((_ivdp = ld_vers_find(name, hash,
744			    ifl->ifl_verdesc)) == NULL) &&
745			    ((_ivdp = ld_vers_desc(name, hash,
746			    &ifl->ifl_verdesc)) == (Ver_desc *)S_ERROR))
747				return (S_ERROR);
748
749			if (aplist_append(&ivdp->vd_deps, _ivdp,
750			    AL_CNT_VERDESCS) == NULL)
751				return (S_ERROR);
752		}
753		DBG_CALL(Dbg_ver_desc_entry(ofl->ofl_lml, ivdp));
754	}
755
756	/*
757	 * Now that we know the total number of version definitions for this
758	 * file, build an index array for fast access when processing symbols.
759	 */
760	if ((ifl->ifl_verndx =
761	    vers_index(ofl, ifl, relobj)) == (Ver_index *)S_ERROR)
762		return (S_ERROR);
763
764	if (relobj)
765		return (1);
766
767	/*
768	 * If this object has version control definitions against it then these
769	 * must be processed so as to select those version definitions to which
770	 * symbol bindings can occur.  Otherwise simply mark all versions as
771	 * available.
772	 */
773	DBG_CALL(Dbg_ver_avail_title(ofl->ofl_lml, file));
774
775	if (sdf && (sdf->sdf_flags & FLG_SDF_SELECT)) {
776		Aliste	idx1;
777
778		for (ALIST_TRAVERSE(sdf->sdf_vers, idx1, sdv)) {
779			Aliste		idx2;
780			Ver_desc	*vdp;
781			int		found = 0;
782
783			for (APLIST_TRAVERSE(ifl->ifl_verdesc, idx2, vdp)) {
784				if (strcmp(sdv->sdv_name, vdp->vd_name) == 0) {
785					found++;
786					break;
787				}
788			}
789			if (found)
790				vers_select(ofl, ifl, vdp, sdv->sdv_ref);
791			else {
792				eprintf(ofl->ofl_lml, ERR_FATAL,
793				    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
794				    sdv->sdv_name, sdv->sdv_ref);
795				ofl->ofl_flags |= FLG_OF_FATAL;
796			}
797		}
798	} else {
799		Ver_index	*vip;
800		int		cnt;
801
802		for (cnt = VER_NDX_GLOBAL; cnt <= ifl->ifl_vercnt; cnt++) {
803			vip = &ifl->ifl_verndx[cnt];
804			vip->vi_flags |= FLG_VER_AVAIL;
805			DBG_CALL(Dbg_ver_avail_entry(ofl->ofl_lml, vip, 0));
806		}
807	}
808
809	/*
810	 * If this is an explict dependency indicate that this file is a
811	 * candidate for requiring version needed information to be recorded in
812	 * the image we're creating.
813	 */
814	if (ifl->ifl_flags & FLG_IF_NEEDED)
815		ofl->ofl_flags |= FLG_OF_VERNEED;
816
817	return (1);
818}
819
820/*
821 * Process a version needed section.
822 */
823uintptr_t
824ld_vers_need_process(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl)
825{
826	const char	*str, *file = ifl->ifl_name;
827	Word		num, _num;
828	Verneed		*vnd;
829
830	vnd = (Verneed *)isp->is_indata->d_buf;
831
832	/*
833	 * Verify the version revision.  We only check the first version
834	 * structure as it is assumed all other version structures in this
835	 * data section will be of the same revision.
836	 */
837	if (vnd->vn_version > VER_DEF_CURRENT) {
838		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
839		    MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vnd->vn_version,
840		    VER_DEF_CURRENT);
841	}
842
843	num = isp->is_shdr->sh_info;
844	str = (char *)ifl->ifl_isdesc[isp->is_shdr->sh_link]->is_indata->d_buf;
845
846	DBG_CALL(Dbg_ver_need_title(ofl->ofl_lml, file));
847
848	/*
849	 * Loop through the version information setting up a version descriptor
850	 * for each version definition.
851	 */
852	for (_num = 1; _num <= num; _num++,
853	    vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) {
854		Sdf_desc	*sdf;
855		const char	*name;
856		Half		cnt = vnd->vn_cnt;
857		Vernaux		*vnap = (Vernaux *)((uintptr_t)vnd +
858		    vnd->vn_aux);
859		Half		_cnt;
860
861		name = (char *)(str + vnd->vn_file);
862
863		/*
864		 * Set up a shared object descriptor and add to it the necessary
865		 * needed versions.  This information may also have been added
866		 * by a mapfile (see map_dash()).
867		 */
868		if ((sdf = sdf_find(name, ofl->ofl_soneed)) == NULL) {
869			if ((sdf = sdf_add(name, &ofl->ofl_soneed)) ==
870			    (Sdf_desc *)S_ERROR)
871				return (S_ERROR);
872			sdf->sdf_rfile = file;
873			sdf->sdf_flags |= FLG_SDF_VERIFY;
874		}
875
876		for (_cnt = 0; cnt; _cnt++, cnt--,
877		    vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next)) {
878			Sdv_desc	sdv;
879
880			sdv.sdv_name = str + vnap->vna_name;
881			sdv.sdv_ref = file;
882			sdv.sdv_flags = 0;
883
884			if (alist_append(&sdf->sdf_vers, &sdv,
885			    sizeof (Sdv_desc), AL_CNT_SDF_VERSIONS) == NULL)
886				return (S_ERROR);
887
888			DBG_CALL(Dbg_ver_need_entry(ofl->ofl_lml, _cnt, name,
889			    sdv.sdv_name));
890		}
891	}
892	return (1);
893}
894
895/*
896 * If a symbol is obtained from a versioned relocatable object then the symbols
897 * version association must be promoted to the version definition as it will be
898 * represented in the output file.
899 */
900void
901ld_vers_promote(Sym_desc *sdp, Word ndx, Ifl_desc *ifl, Ofl_desc *ofl)
902{
903	Half 	vndx;
904
905	/*
906	 * A version symbol index of 0 implies the symbol is local.  A value of
907	 * VER_NDX_GLOBAL implies the symbol is global but has not been
908	 * assigned to a specfic version definition.
909	 */
910	vndx = ifl->ifl_versym[ndx];
911	if (vndx == 0) {
912		sdp->sd_flags |= (FLG_SY_REDUCED | FLG_SY_HIDDEN);
913		return;
914	}
915
916	if (vndx == VER_NDX_ELIMINATE) {
917		sdp->sd_flags |= (FLG_SY_REDUCED | FLG_SY_HIDDEN | FLG_SY_ELIM);
918		return;
919	}
920
921	if (vndx == VER_NDX_GLOBAL) {
922		if (!SYM_IS_HIDDEN(sdp))
923			sdp->sd_flags |= (FLG_SY_DEFAULT | FLG_SY_EXPDEF);
924		if (sdp->sd_aux->sa_overndx <= VER_NDX_GLOBAL)
925			sdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;
926		return;
927	}
928
929	/*
930	 * Any other version index requires association to the appropriate
931	 * version definition.
932	 */
933	if ((ifl->ifl_verndx == 0) || (vndx > ifl->ifl_vercnt)) {
934		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_VER_INVALNDX),
935		    sdp->sd_name, ifl->ifl_name, vndx);
936		ofl->ofl_flags |= FLG_OF_FATAL;
937		return;
938	}
939
940	if (!SYM_IS_HIDDEN(sdp))
941		sdp->sd_flags |= (FLG_SY_DEFAULT | FLG_SY_EXPDEF);
942
943	/*
944	 * Promote the symbols version index to the appropriate output version
945	 * definition.
946	 */
947	if (!(sdp->sd_flags & FLG_SY_VERSPROM)) {
948		Ver_index	*vip;
949
950		vip = &ifl->ifl_verndx[vndx];
951		sdp->sd_aux->sa_overndx = vip->vi_desc->vd_ref->vd_ndx;
952		sdp->sd_flags |= FLG_SY_VERSPROM;
953	}
954}
955
956/*
957 * If any versioning is called for make sure an initial version descriptor is
958 * assigned to represent the file itself.  Known as the base version.
959 */
960Ver_desc *
961ld_vers_base(Ofl_desc *ofl)
962{
963	Ver_desc	*vdp;
964	const char	*name;
965
966	/*
967	 * Determine the filename to associate to the version descriptor.  This
968	 * is either the SONAME (if one has been supplied) or the basename of
969	 * the output file.
970	 */
971	if ((name = ofl->ofl_soname) == NULL) {
972		const char	*str = ofl->ofl_name;
973
974		while (*str != '\0') {
975			if (*str++ == '/')
976				name = str;
977		}
978		if (name == NULL)
979			name = ofl->ofl_name;
980	}
981
982	/*
983	 * Generate the version descriptor.
984	 */
985	/* LINTED */
986	if ((vdp = ld_vers_desc(name, (Word)elf_hash(name),
987	    &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR)
988		return ((Ver_desc *)S_ERROR);
989
990	/*
991	 * Assign the base index to this version and initialize the output file
992	 * descriptor with the number of version descriptors presently in use.
993	 */
994	vdp->vd_ndx = ofl->ofl_vercnt = VER_NDX_GLOBAL;
995	vdp->vd_flags |= VER_FLG_BASE;
996
997	return (vdp);
998}
999
1000/*
1001 * Now that all input shared objects have been processed, verify that all
1002 * version requirements have been met.  Any version control requirements will
1003 * have been specified by the user (and placed on the ofl_oscntl list) and are
1004 * verified at the time the object was processed (see ver_def_process()).
1005 * Here we process all version requirements established from shared objects
1006 * themselves (ie,. NEEDED dependencies).
1007 */
1008int
1009ld_vers_verify(Ofl_desc *ofl)
1010{
1011	Aliste		idx1;
1012	Sdf_desc	*sdf;
1013	char		*nv;
1014
1015	/*
1016	 * As with the runtime environment, disable all version verification if
1017	 * requested.
1018	 */
1019#if	defined(_ELF64)
1020	if ((nv = getenv(MSG_ORIG(MSG_LD_NOVERSION_64))) == NULL)
1021#else
1022	if ((nv = getenv(MSG_ORIG(MSG_LD_NOVERSION_32))) == NULL)
1023#endif
1024		nv = getenv(MSG_ORIG(MSG_LD_NOVERSION));
1025
1026	if (nv && (*nv != '\0'))
1027		return (1);
1028
1029	for (APLIST_TRAVERSE(ofl->ofl_soneed, idx1, sdf)) {
1030		Aliste		idx2;
1031		Sdv_desc	*sdv;
1032		Ifl_desc	*ifl = sdf->sdf_file;
1033
1034		if (!(sdf->sdf_flags & FLG_SDF_VERIFY))
1035			continue;
1036
1037		/*
1038		 * If this file contains no version definitions then ignore
1039		 * any versioning verification.  This is the same model as
1040		 * carried out by ld.so.1 and is intended to allow backward
1041		 * compatibility should a shared object with a version
1042		 * requirement be returned to an older system on which a
1043		 * non-versioned shared object exists.
1044		 */
1045		if ((ifl == NULL) || (ifl->ifl_verdesc == NULL))
1046			continue;
1047
1048		/*
1049		 * If individual versions were specified for this file make
1050		 * sure that they actually exist in the appropriate file, and
1051		 * that they are available for binding.
1052		 */
1053		for (ALIST_TRAVERSE(sdf->sdf_vers, idx2, sdv)) {
1054			Aliste		idx3;
1055			Ver_desc	*vdp;
1056			int		found = 0;
1057
1058			for (APLIST_TRAVERSE(ifl->ifl_verdesc, idx3, vdp)) {
1059				if (strcmp(sdv->sdv_name, vdp->vd_name) == 0) {
1060					found++;
1061					break;
1062				}
1063			}
1064			if (found) {
1065				Ver_index	*vip;
1066
1067				vip = &ifl->ifl_verndx[vdp->vd_ndx];
1068				if (!(vip->vi_flags & FLG_VER_AVAIL)) {
1069					eprintf(ofl->ofl_lml, ERR_FATAL,
1070					    MSG_INTL(MSG_VER_UNAVAIL),
1071					    ifl->ifl_name, sdv->sdv_name,
1072					    sdv->sdv_ref);
1073					ofl->ofl_flags |= FLG_OF_FATAL;
1074				}
1075			} else {
1076				eprintf(ofl->ofl_lml, ERR_FATAL,
1077				    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
1078				    sdv->sdv_name, sdv->sdv_ref);
1079				ofl->ofl_flags |= FLG_OF_FATAL;
1080			}
1081		}
1082	}
1083	return (1);
1084}
1085