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