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