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 */
35 Ver_desc *
ld_vers_find(const char * name,Word hash,APlist * alp)36 ld_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 */
56 Ver_desc *
ld_vers_desc(const char * name,Word hash,APlist ** alpp)57 ld_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 */
81 typedef struct {
82 Ver_desc **ver_stk;
83 int ver_sp;
84 int ver_lmt;
85 } Ver_Stack;
86
87 static uintptr_t
vers_visit_children(Ofl_desc * ofl,Ver_desc * vp,int flag)88 vers_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
170 uintptr_t
ld_vers_check_defs(Ofl_desc * ofl)171 ld_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 */
307 static void
vers_derefer(Ifl_desc * ifl,Ver_desc * vdp,int weak)308 vers_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 */
336 uintptr_t
ld_vers_check_need(Ofl_desc * ofl)337 ld_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 */
462 static void
vers_select(Ofl_desc * ofl,Ifl_desc * ifl,Ver_desc * vdp,const char * ref)463 vers_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
476 static Ver_index *
vers_index(Ofl_desc * ofl,Ifl_desc * ifl,int avail)477 vers_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 */
562 int
ld_vers_sym_process(Ofl_desc * ofl,Is_desc * isp,Ifl_desc * ifl)563 ld_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 */
595 uintptr_t
ld_vers_def_process(Is_desc * isp,Ifl_desc * ifl,Ofl_desc * ofl)596 ld_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 */
817 uintptr_t
ld_vers_need_process(Is_desc * isp,Ifl_desc * ifl,Ofl_desc * ofl)818 ld_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 */
893 void
ld_vers_promote(Sym_desc * sdp,Word ndx,Ifl_desc * ifl,Ofl_desc * ofl)894 ld_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 */
952 Ver_desc *
ld_vers_base(Ofl_desc * ofl)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) == 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 */
1000 int
ld_vers_verify(Ofl_desc * ofl)1001 ld_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