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