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.
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.
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]
23 * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
33 * Locate a version descriptor.
36 ld_vers_find(const char *name
, Word hash
, APlist
*alp
)
41 for (APLIST_TRAVERSE(alp
, idx
, vdp
)) {
42 if (vdp
->vd_hash
!= hash
)
44 if (strcmp(vdp
->vd_name
, name
) == 0)
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())).
57 ld_vers_desc(const char *name
, Word hash
, APlist
**alpp
)
61 if ((vdp
= libld_calloc(sizeof (Ver_desc
), 1)) == NULL
)
62 return ((Ver_desc
*)S_ERROR
);
67 if (aplist_append(alpp
, vdp
, AL_CNT_VERDESCS
) == NULL
)
68 return ((Ver_desc
*)S_ERROR
);
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
80 #define _NUM_OF_VERS_ 40 /* twice as big as the depth for libc version */
88 vers_visit_children(Ofl_desc
*ofl
, Ver_desc
*vp
, int flag
)
93 static Ver_Stack ver_stk
= {0, 0, 0};
97 * If there was any fatal error,
104 * if this is called from, ver_check_defs(), initialize sp.
110 * Check if passed version pointer vp is already in the stack.
112 for (tmp_sp
= 0; tmp_sp
< ver_stk
.ver_sp
; tmp_sp
++) {
115 v
= ver_stk
.ver_stk
[tmp_sp
];
121 ld_eprintf(ofl
, ERR_FATAL
,
122 MSG_INTL(MSG_VER_CYCLIC
));
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
),
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
);
144 * Push version on the stack.
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
)
153 ver_stk
.ver_stk
[(ver_stk
.ver_sp
)++] = vp
;
156 * Now visit children.
158 for (APLIST_TRAVERSE(vp
->vd_deps
, idx
, vdp
))
159 if (vers_visit_children(ofl
, vdp
, 1) == S_ERROR
)
163 * Pop version from the stack.
171 ld_vers_check_defs(Ofl_desc
*ofl
)
175 uintptr_t is_cyclic
= 0;
177 DBG_CALL(Dbg_ver_def_title(ofl
->ofl_lml
, ofl
->ofl_name
));
180 * First check if there are any cyclic dependency
182 for (APLIST_TRAVERSE(ofl
->ofl_verdesc
, idx1
, vdp
))
183 if ((is_cyclic
= vers_visit_children(ofl
, vdp
, 0)) == S_ERROR
)
187 ofl
->ofl_flags
|= FLG_OF_FATAL
;
189 for (APLIST_TRAVERSE(ofl
->ofl_verdesc
, idx1
, vdp
)) {
193 const char *name
= vdp
->vd_name
;
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
);
206 DBG_CALL(Dbg_ver_desc_entry(ofl
->ofl_lml
, vdp
));
209 * If a version definition contains no symbols this is possibly
213 (VER_FLG_BASE
| VER_FLG_WEAK
| FLG_VER_REFER
)) == 0)
214 DBG_CALL(Dbg_ver_nointerface(ofl
->ofl_lml
,
218 * Update the version entry count to account for this new
219 * version descriptor (the count is the size in bytes).
221 ofl
->ofl_verdefsz
+= sizeof (Verdef
);
224 * Traverse this versions dependency list to determine what
225 * additional version dependencies we must account for against
229 for (APLIST_TRAVERSE(vdp
->vd_deps
, idx2
, _vdp
)) {
231 /* get lint to think `_vdp' is used... */
236 ofl
->ofl_verdefsz
+= (cnt
* sizeof (Verdaux
));
239 * Except for the base version descriptor, generate an absolute
240 * symbol to reflect this version.
242 if (vdp
->vd_flags
& VER_FLG_BASE
)
245 if (vdp
->vd_flags
& VER_FLG_WEAK
)
250 if (sdp
= ld_sym_find(name
, vdp
->vd_hash
, &where
, ofl
)) {
252 * If the symbol already exists and is undefined or was
253 * defined in a shared library, convert it to an
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
;
267 * If the reference originated from a mapfile
268 * insure we mark the symbol as used.
270 if (sdp
->sd_flags
& FLG_SY_MAPREF
)
271 sdp
->sd_flags
|= FLG_SY_MAPUSED
;
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
);
282 * If the symbol does not exist create it.
284 if ((sym
= libld_calloc(sizeof (Sym
), 1)) == NULL
)
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
));
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
)
297 sdp
->sd_ref
= REF_REL_NEED
;
298 sdp
->sd_aux
->sa_overndx
= vdp
->vd_ndx
;
305 * Dereference dependencies as a part of normalizing (allows recursion).
308 vers_derefer(Ifl_desc
*ifl
, Ver_desc
*vdp
, int weak
)
312 Ver_index
*vip
= &ifl
->ifl_verndx
[vdp
->vd_ndx
];
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.
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.
324 if ((weak
&& (vdp
->vd_flags
& VER_FLG_WEAK
)) || (!weak
))
325 vip
->vi_flags
|= VER_FLG_INFO
;
327 for (APLIST_TRAVERSE(vdp
->vd_deps
, idx
, _vdp
))
328 vers_derefer(ifl
, _vdp
, weak
);
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
337 ld_vers_check_need(Ofl_desc
*ofl
)
346 * Determine which string table is appropriate.
348 strtbl
= (OFL_IS_STATIC_OBJ(ofl
)) ? ofl
->ofl_strtab
:
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.
357 needndx
= (ofl
->ofl_vercnt
> 0) ? (ofl
->ofl_vercnt
+ 1) : 2;
360 * Traverse the shared object list looking for dependencies.
362 for (APLIST_TRAVERSE(ofl
->ofl_sos
, idx1
, ifl
)) {
368 if (!(ifl
->ifl_flags
& FLG_IF_NEEDED
))
371 if (ifl
->ifl_vercnt
<= VER_NDX_GLOBAL
)
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
381 for (cnt
= 0; cnt
<= ifl
->ifl_vercnt
; cnt
++) {
382 vip
= &ifl
->ifl_verndx
[cnt
];
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
;
390 * Mark any weak reference as referred to so as to
391 * simplify normalization and later version dependency
394 if (vip
->vi_flags
& VER_FLG_WEAK
)
395 vip
->vi_flags
|= FLG_VER_REFER
;
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.
404 for (APLIST_TRAVERSE(ifl
->ifl_verdesc
, idx2
, vdp
)) {
409 vip
= &ifl
->ifl_verndx
[vdp
->vd_ndx
];
411 if (!(vip
->vi_flags
& FLG_VER_REFER
))
414 type
= vdp
->vd_flags
& VER_FLG_WEAK
;
415 for (APLIST_TRAVERSE(vdp
->vd_deps
, idx3
, _vdp
))
416 vers_derefer(ifl
, _vdp
, type
);
420 * Finally, determine how many of the version dependencies need
423 for (cnt
= 0; cnt
<= ifl
->ifl_vercnt
; cnt
++) {
424 vip
= &ifl
->ifl_verndx
[cnt
];
427 * If a version has been referenced then record it as a
428 * version dependency.
430 if (vip
->vi_flags
& FLG_VER_REFER
) {
431 /* Assign a VERSYM index for it */
432 vip
->vi_overndx
= needndx
++;
434 ofl
->ofl_verneedsz
+= sizeof (Vernaux
);
435 if (st_insert(strtbl
, vip
->vi_name
) == -1)
442 ifl
->ifl_flags
|= FLG_IF_VERNEED
;
443 ofl
->ofl_verneedsz
+= sizeof (Verneed
);
444 if (st_insert(strtbl
, ifl
->ifl_soname
) == -1)
450 * If no version needed information is required unset the output file
453 if (ofl
->ofl_verneedsz
== 0)
454 ofl
->ofl_flags
&= ~FLG_OF_VERNEED
;
460 * Indicate dependency selection (allows recursion).
463 vers_select(Ofl_desc
*ofl
, Ifl_desc
*ifl
, Ver_desc
*vdp
, const char *ref
)
467 Ver_index
*vip
= &ifl
->ifl_verndx
[vdp
->vd_ndx
];
469 vip
->vi_flags
|= FLG_VER_AVAIL
;
470 DBG_CALL(Dbg_ver_avail_entry(ofl
->ofl_lml
, vip
, ref
));
472 for (APLIST_TRAVERSE(vdp
->vd_deps
, idx
, _vdp
))
473 vers_select(ofl
, ifl
, _vdp
, ref
);
477 vers_index(Ofl_desc
*ofl
, Ifl_desc
*ifl
, int avail
)
482 Sdf_desc
*sdf
= ifl
->ifl_sdfdesc
;
483 Word count
= ifl
->ifl_vercnt
;
487 * Allocate an index array large enough to hold all of the files
488 * version descriptors.
490 if ((vip
= libld_calloc(sizeof (Ver_index
), (count
+ 1))) == NULL
)
491 return ((Ver_index
*)S_ERROR
);
493 for (APLIST_TRAVERSE(ifl
->ifl_verdesc
, idx1
, vdp
)) {
494 int ndx
= vdp
->vd_ndx
;
496 vip
[ndx
].vi_name
= vdp
->vd_name
;
497 vip
[ndx
].vi_desc
= vdp
;
500 * Any relocatable object versions, and the `base' version are
503 if (avail
|| (vdp
->vd_flags
& VER_FLG_BASE
))
504 vip
[ndx
].vi_flags
|= FLG_VER_AVAIL
;
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.
512 if (vdp
->vd_flags
& VER_FLG_WEAK
)
513 vip
[ndx
].vi_flags
|= VER_FLG_WEAK
;
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.
519 if (sdf
&& (sdf
->sdf_flags
& FLG_SDF_ADDVER
)) {
522 for (ALIST_TRAVERSE(sdf
->sdf_verneed
, idx2
, sdv
)) {
523 if (strcmp(vip
[ndx
].vi_name
, sdv
->sdv_name
))
526 vip
[ndx
].vi_flags
|= FLG_VER_REFER
;
527 sdv
->sdv_flags
|= FLG_SDV_MATCHED
;
534 * if $ADDVER was specified for this object verify that
535 * all of it's dependent upon versions were refered to.
537 if (sdf
&& (sdf
->sdf_flags
& FLG_SDF_ADDVER
)) {
540 for (ALIST_TRAVERSE(sdf
->sdf_verneed
, idx1
, sdv
)) {
541 if (sdv
->sdv_flags
& FLG_SDV_MATCHED
)
545 ld_eprintf(ofl
, ERR_NONE
,
546 MSG_INTL(MSG_VER_ADDVERS
), sdf
->sdf_rfile
,
549 ld_eprintf(ofl
, ERR_NONE
, MSG_INTL(MSG_VER_ADDVER
),
553 return ((Ver_index
*)S_ERROR
);
560 * Process a version symbol index section.
563 ld_vers_sym_process(Ofl_desc
*ofl
, Is_desc
*isp
, Ifl_desc
*ifl
)
566 Shdr
*vershdr
= isp
->is_shdr
;
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.
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
];
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
));
584 ifl
->ifl_versym
= (Versym
*)isp
->is_indata
->d_buf
;
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.
596 ld_vers_def_process(Is_desc
*isp
, Ifl_desc
*ifl
, Ofl_desc
*ofl
)
598 const char *str
, *file
= ifl
->ifl_name
;
599 Sdf_desc
*sdf
= ifl
->ifl_sdfdesc
;
606 * If there is no version section then simply indicate that all version
607 * definitions asked for do not exist.
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
);
620 vdf
= (Verdef
*)isp
->is_indata
->d_buf
;
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.
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
);
632 num
= isp
->is_shdr
->sh_info
;
633 str
= (char *)ifl
->ifl_isdesc
[isp
->is_shdr
->sh_link
]->is_indata
->d_buf
;
635 if (ifl
->ifl_ehdr
->e_type
== ET_REL
)
640 DBG_CALL(Dbg_ver_def_title(ofl
->ofl_lml
, file
));
643 * Loop through the version information setting up a version descriptor
644 * for each version definition.
646 for (_num
= 1; _num
<= num
; _num
++,
647 vdf
= (Verdef
*)((uintptr_t)vdf
+ vdf
->vd_next
)) {
649 Ver_desc
*ivdp
, *ovdp
= NULL
;
651 Half cnt
= vdf
->vd_cnt
;
652 Half ndx
= vdf
->vd_ndx
;
653 Verdaux
*vdap
= (Verdaux
*)((uintptr_t)vdf
+
657 * Keep track of the largest index for use in creating a
658 * version index array later, and create a version descriptor.
660 if (ndx
> ifl
->ifl_vercnt
)
661 ifl
->ifl_vercnt
= ndx
;
663 name
= (char *)(str
+ vdap
->vda_name
);
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
))
674 ivdp
->vd_flags
= vdf
->vd_flags
;
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.
685 if (!(ofl
->ofl_flags
& FLG_OF_RELOBJ
))
686 ofl
->ofl_flags
|= FLG_OF_PROCRED
;
688 if ((ivdp
->vd_flags
& VER_FLG_BASE
) == 0) {
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
698 if (ofl
->ofl_vercnt
== 0) {
699 if (ld_vers_base(ofl
) ==
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
)) ==
712 ovdp
->vd_ndx
= (Half
)++ofl
->ofl_vercnt
;
714 ovdp
->vd_flags
= vdf
->vd_flags
;
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
728 * Process any dependencies this version may have.
730 vdap
= (Verdaux
*)((uintptr_t)vdap
+ vdap
->vda_next
);
731 for (cnt
--; cnt
; cnt
--,
732 vdap
= (Verdaux
*)((uintptr_t)vdap
+ vdap
->vda_next
)) {
735 name
= (char *)(str
+ vdap
->vda_name
);
737 hash
= (Word
)elf_hash(name
);
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
))
745 if (aplist_append(&ivdp
->vd_deps
, _ivdp
,
746 AL_CNT_VERDESCS
) == NULL
)
749 DBG_CALL(Dbg_ver_desc_entry(ofl
->ofl_lml
, ivdp
));
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.
756 if ((ifl
->ifl_verndx
=
757 vers_index(ofl
, ifl
, relobj
)) == (Ver_index
*)S_ERROR
)
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
769 DBG_CALL(Dbg_ver_avail_title(ofl
->ofl_lml
, file
));
771 if (sdf
&& (sdf
->sdf_flags
& FLG_SDF_SELECT
)) {
774 for (ALIST_TRAVERSE(sdf
->sdf_vers
, idx1
, sdv
)) {
779 for (APLIST_TRAVERSE(ifl
->ifl_verdesc
, idx2
, vdp
)) {
780 if (strcmp(sdv
->sdv_name
, vdp
->vd_name
) == 0) {
786 vers_select(ofl
, ifl
, vdp
, sdv
->sdv_ref
);
788 ld_eprintf(ofl
, ERR_FATAL
,
789 MSG_INTL(MSG_VER_NOEXIST
), ifl
->ifl_name
,
790 sdv
->sdv_name
, sdv
->sdv_ref
);
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));
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.
808 if (ifl
->ifl_flags
& FLG_IF_NEEDED
)
809 ofl
->ofl_flags
|= FLG_OF_VERNEED
;
815 * Process a version needed section.
818 ld_vers_need_process(Is_desc
*isp
, Ifl_desc
*ifl
, Ofl_desc
*ofl
)
820 const char *str
, *file
= ifl
->ifl_name
;
824 vnd
= (Verneed
*)isp
->is_indata
->d_buf
;
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.
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
);
836 num
= isp
->is_shdr
->sh_info
;
837 str
= (char *)ifl
->ifl_isdesc
[isp
->is_shdr
->sh_link
]->is_indata
->d_buf
;
839 DBG_CALL(Dbg_ver_need_title(ofl
->ofl_lml
, file
));
842 * Loop through the version information setting up a version descriptor
843 * for each version definition.
845 for (_num
= 1; _num
<= num
; _num
++,
846 vnd
= (Verneed
*)((uintptr_t)vnd
+ vnd
->vn_next
)) {
849 Half cnt
= vnd
->vn_cnt
;
850 Vernaux
*vnap
= (Vernaux
*)((uintptr_t)vnd
+
854 name
= (char *)(str
+ vnd
->vn_file
);
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()).
861 if ((sdf
= sdf_find(name
, ofl
->ofl_soneed
)) == NULL
) {
862 if ((sdf
= sdf_add(name
, &ofl
->ofl_soneed
)) ==
865 sdf
->sdf_rfile
= file
;
866 sdf
->sdf_flags
|= FLG_SDF_VERIFY
;
869 for (_cnt
= 0; cnt
; _cnt
++, cnt
--,
870 vnap
= (Vernaux
*)((uintptr_t)vnap
+ vnap
->vna_next
)) {
873 sdv
.sdv_name
= str
+ vnap
->vna_name
;
877 if (alist_append(&sdf
->sdf_vers
, &sdv
,
878 sizeof (Sdv_desc
), AL_CNT_SDF_VERSIONS
) == NULL
)
881 DBG_CALL(Dbg_ver_need_entry(ofl
->ofl_lml
, _cnt
, name
,
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.
894 ld_vers_promote(Sym_desc
*sdp
, Word ndx
, Ifl_desc
*ifl
, Ofl_desc
*ofl
)
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.
903 vndx
= ifl
->ifl_versym
[ndx
];
905 sdp
->sd_flags
|= (FLG_SY_REDUCED
| FLG_SY_HIDDEN
);
909 if (vndx
== VER_NDX_ELIMINATE
) {
910 sdp
->sd_flags
|= (FLG_SY_REDUCED
| FLG_SY_HIDDEN
| FLG_SY_ELIM
);
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
;
923 * Any other version index requires association to the appropriate
924 * version definition.
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
);
932 if (!SYM_IS_HIDDEN(sdp
))
933 sdp
->sd_flags
|= (FLG_SY_DEFAULT
| FLG_SY_EXPDEF
);
936 * Promote the symbols version index to the appropriate output version
939 if (!(sdp
->sd_flags
& FLG_SY_VERSPROM
)) {
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
;
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.
953 ld_vers_base(Ofl_desc
*ofl
)
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
963 if ((name
= ofl
->ofl_soname
) == NULL
) {
964 const char *str
= ofl
->ofl_name
;
966 while (*str
!= '\0') {
971 name
= ofl
->ofl_name
;
975 * Generate the version descriptor.
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
);
983 * Assign the base index to this version and initialize the output file
984 * descriptor with the number of version descriptors presently in use.
986 vdp
->vd_ndx
= ofl
->ofl_vercnt
= VER_NDX_GLOBAL
;
987 vdp
->vd_flags
|= VER_FLG_BASE
;
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).
1001 ld_vers_verify(Ofl_desc
*ofl
)
1008 * As with the runtime environment, disable all version verification if
1012 if ((nv
= getenv(MSG_ORIG(MSG_LD_NOVERSION_64
))) == NULL
)
1014 if ((nv
= getenv(MSG_ORIG(MSG_LD_NOVERSION_32
))) == NULL
)
1016 nv
= getenv(MSG_ORIG(MSG_LD_NOVERSION
));
1021 for (APLIST_TRAVERSE(ofl
->ofl_soneed
, idx1
, sdf
)) {
1024 Ifl_desc
*ifl
= sdf
->sdf_file
;
1026 if (!(sdf
->sdf_flags
& FLG_SDF_VERIFY
))
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.
1037 if ((ifl
== NULL
) || (ifl
->ifl_verdesc
== NULL
))
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.
1045 for (ALIST_TRAVERSE(sdf
->sdf_vers
, idx2
, sdv
)) {
1050 for (APLIST_TRAVERSE(ifl
->ifl_verdesc
, idx3
, vdp
)) {
1051 if (strcmp(sdv
->sdv_name
, vdp
->vd_name
) == 0) {
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
,
1067 ld_eprintf(ofl
, ERR_FATAL
,
1068 MSG_INTL(MSG_VER_NOEXIST
), ifl
->ifl_name
,
1069 sdv
->sdv_name
, sdv
->sdv_ref
);