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 2008 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 ifl->ifl_flags |= FLG_IF_VERNEED; 465 ofl->ofl_verneedsz += sizeof (Verneed); 466 if (st_insert(ofl->ofl_dynstrtab, 467 ifl->ifl_soname) == -1) 468 return (S_ERROR); 469 } 470 } 471 472 /* 473 * If no version needed information is required unset the output file 474 * flag. 475 */ 476 if (ofl->ofl_verneedsz == 0) 477 ofl->ofl_flags &= ~FLG_OF_VERNEED; 478 479 return (1); 480 } 481 482 /* 483 * Indicate dependency selection (allows recursion). 484 */ 485 static void 486 vers_select(Ofl_desc *ofl, Ifl_desc *ifl, Ver_desc *vdp, const char *ref) 487 { 488 Listnode *lnp; 489 Ver_desc *_vdp; 490 Ver_index *vip = &ifl->ifl_verndx[vdp->vd_ndx]; 491 492 vip->vi_flags |= FLG_VER_AVAIL; 493 DBG_CALL(Dbg_ver_avail_entry(ofl->ofl_lml, vip, ref)); 494 495 for (LIST_TRAVERSE(&vdp->vd_deps, lnp, _vdp)) 496 vers_select(ofl, ifl, _vdp, ref); 497 } 498 499 static Ver_index * 500 vers_index(Ofl_desc *ofl, Ifl_desc *ifl, int avail) 501 { 502 Listnode *lnp; 503 Ver_desc *vdp; 504 Ver_index *vip; 505 Sdf_desc *sdf = ifl->ifl_sdfdesc; 506 Word count = ifl->ifl_vercnt; 507 Sdv_desc *sdv; 508 509 /* 510 * Allocate an index array large enough to hold all of the files 511 * version descriptors. 512 */ 513 if ((vip = libld_calloc(sizeof (Ver_index), 514 (count + 1))) == 0) 515 return ((Ver_index *)S_ERROR); 516 517 for (LIST_TRAVERSE(&ifl->ifl_verdesc, lnp, vdp)) { 518 int ndx = vdp->vd_ndx; 519 520 vip[ndx].vi_name = vdp->vd_name; 521 vip[ndx].vi_desc = vdp; 522 523 /* 524 * Any relocatable object versions, and the `base' version are 525 * always available. 526 */ 527 if (avail || (vdp->vd_flags & VER_FLG_BASE)) 528 vip[ndx].vi_flags |= FLG_VER_AVAIL; 529 530 /* 531 * If this is a weak version mark it as such. Weak versions 532 * are always dragged into any version dependencies created, 533 * and if a weak version is referenced it will be promoted to 534 * a non-weak version dependency. 535 */ 536 if (vdp->vd_flags & VER_FLG_WEAK) 537 vip[ndx].vi_flags |= VER_FLG_WEAK; 538 /* 539 * If this version is mentioned in a mapfile using 540 * $ADDVERS or $SPECVERS syntax then check to see if 541 * it corresponds to an actual version in the file. 542 */ 543 if (sdf && 544 (sdf->sdf_flags & (FLG_SDF_SPECVER|FLG_SDF_ADDVER))) { 545 Listnode * lnp2; 546 for (LIST_TRAVERSE(&sdf->sdf_verneed, lnp2, sdv)) { 547 if (strcmp(vip[ndx].vi_name, 548 sdv->sdv_name) == 0) { 549 vip[ndx].vi_flags |= FLG_VER_REFER; 550 if (sdf->sdf_flags & FLG_SDF_SPECVER) 551 vip[ndx].vi_flags |= 552 FLG_VER_SPECVER; 553 sdv->sdv_flags |= FLG_SDV_MATCHED; 554 break; 555 } 556 } 557 } 558 } 559 560 /* 561 * if $ADDVER was specified for this object verify that 562 * all of it's dependent upon versions were refered to. 563 */ 564 if (sdf && (sdf->sdf_flags & FLG_SDF_ADDVER)) { 565 int fail = 0; 566 for (LIST_TRAVERSE(&sdf->sdf_verneed, lnp, sdv)) { 567 if (!(sdv->sdv_flags & FLG_SDV_MATCHED)) { 568 if (fail == 0) { 569 fail++; 570 eprintf(ofl->ofl_lml, ERR_NONE, 571 MSG_INTL(MSG_VER_ADDVERS), 572 sdf->sdf_rfile, sdf->sdf_name); 573 } 574 eprintf(ofl->ofl_lml, ERR_NONE, 575 MSG_INTL(MSG_VER_ADDVER), sdv->sdv_name); 576 } 577 } 578 if (fail) 579 return ((Ver_index *)S_ERROR); 580 } 581 582 return (vip); 583 } 584 585 /* 586 * Process a version symbol index section. 587 */ 588 int 589 ld_vers_sym_process(Lm_list *lml, Is_desc *isp, Ifl_desc *ifl) 590 { 591 Shdr *symshdr; 592 Shdr *vershdr = isp->is_shdr; 593 594 /* 595 * Verify that the versym is the same size as the linked symbol table. 596 * If these two get out of sync the file is considered corrupted. 597 */ 598 symshdr = ifl->ifl_isdesc[vershdr->sh_link]->is_shdr; 599 if ((symshdr->sh_size / symshdr->sh_entsize) != (vershdr->sh_size / 600 vershdr->sh_entsize)) { 601 eprintf(lml, ERR_WARNING, MSG_INTL(MSG_ELF_VERSYM), 602 ifl->ifl_name, isp->is_name, 603 EC_WORD(vershdr->sh_size / vershdr->sh_entsize), 604 ifl->ifl_isdesc[vershdr->sh_link]->is_name, 605 EC_WORD(symshdr->sh_size / symshdr->sh_entsize)); 606 return (1); 607 } 608 ifl->ifl_versym = (Versym *)isp->is_indata->d_buf; 609 return (1); 610 } 611 612 /* 613 * Process a version definition section from an input file. A list of version 614 * descriptors is created and associated with the input files descriptor. If 615 * this is a shared object these descriptors will be used to indicate the 616 * availability of each version. If this is a relocatable object then these 617 * descriptors will be promoted (concatenated) to the output files image. 618 */ 619 uintptr_t 620 ld_vers_def_process(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl) 621 { 622 const char *str, *file = ifl->ifl_name; 623 Sdf_desc *sdf = ifl->ifl_sdfdesc; 624 Sdv_desc *sdv; 625 Word num, _num; 626 Verdef *vdf; 627 int relobj; 628 629 /* 630 * If there is no version section then simply indicate that all version 631 * definitions asked for do not exist. 632 */ 633 if (isp == 0) { 634 Listnode *lnp; 635 636 for (LIST_TRAVERSE(&sdf->sdf_vers, lnp, sdv)) { 637 eprintf(ofl->ofl_lml, ERR_FATAL, 638 MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name, 639 sdv->sdv_name, sdv->sdv_ref); 640 ofl->ofl_flags |= FLG_OF_FATAL; 641 } 642 return (0); 643 } 644 645 vdf = (Verdef *)isp->is_indata->d_buf; 646 647 /* 648 * Verify the version revision. We only check the first version 649 * structure as it is assumed all other version structures in this 650 * data section will be of the same revision. 651 */ 652 if (vdf->vd_version > VER_DEF_CURRENT) 653 (void) eprintf(ofl->ofl_lml, ERR_WARNING, 654 MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vdf->vd_version, 655 VER_DEF_CURRENT); 656 657 658 num = isp->is_shdr->sh_info; 659 str = (char *)ifl->ifl_isdesc[isp->is_shdr->sh_link]->is_indata->d_buf; 660 661 if (ifl->ifl_ehdr->e_type == ET_REL) 662 relobj = 1; 663 else 664 relobj = 0; 665 666 DBG_CALL(Dbg_ver_def_title(ofl->ofl_lml, file)); 667 668 /* 669 * Loop through the version information setting up a version descriptor 670 * for each version definition. 671 */ 672 for (_num = 1; _num <= num; _num++, 673 vdf = (Verdef *)((uintptr_t)vdf + vdf->vd_next)) { 674 const char *name; 675 Ver_desc *ivdp, *ovdp = 0; 676 Word hash; 677 Half cnt = vdf->vd_cnt; 678 Half ndx = vdf->vd_ndx; 679 Verdaux *vdap = (Verdaux *)((uintptr_t)vdf + 680 vdf->vd_aux); 681 682 /* 683 * Keep track of the largest index for use in creating a 684 * version index array later, and create a version descriptor. 685 */ 686 if (ndx > ifl->ifl_vercnt) 687 ifl->ifl_vercnt = ndx; 688 689 name = (char *)(str + vdap->vda_name); 690 /* LINTED */ 691 hash = (Word)elf_hash(name); 692 if ((ivdp = ld_vers_find(name, hash, &ifl->ifl_verdesc)) == 0) { 693 if ((ivdp = ld_vers_desc(name, hash, 694 &ifl->ifl_verdesc)) == (Ver_desc *)S_ERROR) 695 return (S_ERROR); 696 } 697 ivdp->vd_ndx = ndx; 698 ivdp->vd_file = ifl; 699 ivdp->vd_flags = vdf->vd_flags; 700 701 /* 702 * If we're processing a relocatable object then this version 703 * definition needs to be propagated to the output file. 704 * Generate a new output file version and associated this input 705 * version to it. During symbol processing the version index of 706 * the symbol will be promoted from the input file to the output 707 * files version definition. 708 */ 709 if (relobj) { 710 if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) 711 ofl->ofl_flags |= FLG_OF_PROCRED; 712 713 if ((ivdp->vd_flags & VER_FLG_BASE) == 0) { 714 /* 715 * If no version descriptors have yet been set 716 * up, initialize a base version to represent 717 * the output file itself. This `base' version 718 * catches any internally generated symbols 719 * (_end, _etext, etc.) and 720 * serves to initialize the output version 721 * descriptor count. 722 */ 723 if (ofl->ofl_vercnt == 0) { 724 if (ld_vers_base(ofl) == 725 (Ver_desc *)S_ERROR) 726 return (S_ERROR); 727 } 728 ofl->ofl_flags |= FLG_OF_VERDEF; 729 if ((ovdp = ld_vers_find(name, hash, 730 &ofl->ofl_verdesc)) == 0) { 731 if ((ovdp = ld_vers_desc(name, hash, 732 &ofl->ofl_verdesc)) == 733 (Ver_desc *)S_ERROR) 734 return (S_ERROR); 735 736 /* LINTED */ 737 ovdp->vd_ndx = (Half)++ofl->ofl_vercnt; 738 ovdp->vd_file = ifl; 739 ovdp->vd_flags = vdf->vd_flags; 740 } 741 } 742 743 /* 744 * Maintain the association between the input version 745 * descriptor and the output version descriptor so that 746 * an associated symbols will be assigned to the 747 * correct version. 748 */ 749 ivdp->vd_ref = ovdp; 750 } 751 752 /* 753 * Process any dependencies this version may have. 754 */ 755 vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next); 756 for (cnt--; cnt; cnt--, 757 vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next)) { 758 Ver_desc *_ivdp; 759 760 name = (char *)(str + vdap->vda_name); 761 /* LINTED */ 762 hash = (Word)elf_hash(name); 763 764 if ((_ivdp = ld_vers_find(name, hash, 765 &ifl->ifl_verdesc)) == 0) { 766 if ((_ivdp = ld_vers_desc(name, hash, 767 &ifl->ifl_verdesc)) == 768 (Ver_desc *)S_ERROR) 769 return (S_ERROR); 770 } 771 if (list_appendc(&ivdp->vd_deps, _ivdp) == 0) 772 return (S_ERROR); 773 } 774 DBG_CALL(Dbg_ver_desc_entry(ofl->ofl_lml, ivdp)); 775 } 776 777 /* 778 * Now that we know the total number of version definitions for this 779 * file, build an index array for fast access when processing symbols. 780 */ 781 if ((ifl->ifl_verndx = 782 vers_index(ofl, ifl, relobj)) == (Ver_index *)S_ERROR) 783 return (S_ERROR); 784 785 if (relobj) 786 return (1); 787 788 /* 789 * If this object has version control definitions against it then these 790 * must be processed so as to select those version definitions to which 791 * symbol bindings can occur. Otherwise simply mark all versions as 792 * available. 793 */ 794 DBG_CALL(Dbg_ver_avail_title(ofl->ofl_lml, file)); 795 796 if (sdf && (sdf->sdf_flags & FLG_SDF_SELECT)) { 797 Listnode *lnp1; 798 799 for (LIST_TRAVERSE(&sdf->sdf_vers, lnp1, sdv)) { 800 Listnode *lnp2; 801 Ver_desc *vdp; 802 int found = 0; 803 804 for (LIST_TRAVERSE(&ifl->ifl_verdesc, lnp2, vdp)) { 805 if (strcmp(sdv->sdv_name, vdp->vd_name) == 0) { 806 found++; 807 break; 808 } 809 } 810 if (found) 811 vers_select(ofl, ifl, vdp, sdv->sdv_ref); 812 else { 813 eprintf(ofl->ofl_lml, ERR_FATAL, 814 MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name, 815 sdv->sdv_name, sdv->sdv_ref); 816 ofl->ofl_flags |= FLG_OF_FATAL; 817 } 818 } 819 } else { 820 Ver_index *vip; 821 int cnt; 822 823 for (cnt = VER_NDX_GLOBAL; cnt <= ifl->ifl_vercnt; cnt++) { 824 vip = &ifl->ifl_verndx[cnt]; 825 vip->vi_flags |= FLG_VER_AVAIL; 826 DBG_CALL(Dbg_ver_avail_entry(ofl->ofl_lml, vip, 0)); 827 } 828 } 829 830 /* 831 * If this is an explict dependency indicate that this file is a 832 * candidate for requiring version needed information to be recorded in 833 * the image we're creating. 834 */ 835 if (ifl->ifl_flags & FLG_IF_NEEDED) 836 ofl->ofl_flags |= FLG_OF_VERNEED; 837 838 return (1); 839 } 840 841 /* 842 * Process a version needed section. 843 */ 844 uintptr_t 845 ld_vers_need_process(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl) 846 { 847 const char *str, *file = ifl->ifl_name; 848 Word num, _num; 849 Verneed *vnd; 850 851 vnd = (Verneed *)isp->is_indata->d_buf; 852 853 /* 854 * Verify the version revision. We only check the first version 855 * structure as it is assumed all other version structures in this 856 * data section will be of the same revision. 857 */ 858 if (vnd->vn_version > VER_DEF_CURRENT) { 859 (void) eprintf(ofl->ofl_lml, ERR_WARNING, 860 MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vnd->vn_version, 861 VER_DEF_CURRENT); 862 } 863 864 num = isp->is_shdr->sh_info; 865 str = (char *)ifl->ifl_isdesc[isp->is_shdr->sh_link]->is_indata->d_buf; 866 867 DBG_CALL(Dbg_ver_need_title(ofl->ofl_lml, file)); 868 869 /* 870 * Loop through the version information setting up a version descriptor 871 * for each version definition. 872 */ 873 for (_num = 1; _num <= num; _num++, 874 vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) { 875 Sdf_desc *sdf; 876 Sdv_desc *sdv; 877 const char *name; 878 Half cnt = vnd->vn_cnt; 879 Vernaux *vnap = (Vernaux *)((uintptr_t)vnd + 880 vnd->vn_aux); 881 Half _cnt; 882 883 name = (char *)(str + vnd->vn_file); 884 885 /* 886 * Set up a shared object descriptor and add to it the necessary 887 * needed versions. This information may also have been added 888 * by a mapfile (see map_dash()). 889 */ 890 if ((sdf = sdf_find(name, &ofl->ofl_soneed)) == 0) { 891 if ((sdf = sdf_add(name, &ofl->ofl_soneed)) == 892 (Sdf_desc *)S_ERROR) 893 return (S_ERROR); 894 sdf->sdf_rfile = file; 895 sdf->sdf_flags |= FLG_SDF_VERIFY; 896 } 897 898 for (_cnt = 0; cnt; _cnt++, cnt--, 899 vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next)) { 900 if (!(sdv = 901 libld_calloc(sizeof (Sdv_desc), 1))) 902 return (S_ERROR); 903 sdv->sdv_name = str + vnap->vna_name; 904 sdv->sdv_ref = file; 905 if (list_appendc(&sdf->sdf_vers, sdv) == 0) 906 return (S_ERROR); 907 DBG_CALL(Dbg_ver_need_entry(ofl->ofl_lml, _cnt, name, 908 sdv->sdv_name)); 909 } 910 } 911 912 return (1); 913 } 914 915 /* 916 * If a symbol is obtained from a versioned relocatable object then the symbols 917 * version association must be promoted to the version definition as it will be 918 * represented in the output file. 919 */ 920 void 921 ld_vers_promote(Sym_desc *sdp, Word ndx, Ifl_desc *ifl, Ofl_desc *ofl) 922 { 923 Half vndx; 924 925 /* 926 * A version symbol index of 0 implies the symbol is local. A value of 927 * VER_NDX_GLOBAL implies the symbol is global but has not been 928 * assigned to a specfic version definition. 929 */ 930 vndx = ifl->ifl_versym[ndx]; 931 if (vndx == 0) { 932 sdp->sd_flags |= FLG_SY_REDUCED; 933 sdp->sd_flags1 |= FLG_SY1_HIDDEN; 934 return; 935 } 936 937 if (vndx == VER_NDX_ELIMINATE) { 938 sdp->sd_flags |= FLG_SY_REDUCED; 939 sdp->sd_flags1 |= (FLG_SY1_HIDDEN | FLG_SY1_ELIM); 940 return; 941 } 942 943 if (vndx == VER_NDX_GLOBAL) { 944 if ((sdp->sd_flags1 & FLG_SY1_HIDDEN) == 0) 945 sdp->sd_flags1 |= (FLG_SY1_DEFAULT | FLG_SY1_EXPDEF); 946 if (sdp->sd_aux->sa_overndx <= VER_NDX_GLOBAL) 947 sdp->sd_aux->sa_overndx = VER_NDX_GLOBAL; 948 return; 949 } 950 951 /* 952 * Any other version index requires association to the appropriate 953 * version definition. 954 */ 955 if ((ifl->ifl_verndx == 0) || (vndx > ifl->ifl_vercnt)) { 956 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_VER_INVALNDX), 957 sdp->sd_name, ifl->ifl_name, vndx); 958 ofl->ofl_flags |= FLG_OF_FATAL; 959 return; 960 } 961 962 if ((sdp->sd_flags1 & FLG_SY1_HIDDEN) == 0) 963 sdp->sd_flags1 |= (FLG_SY1_DEFAULT | FLG_SY1_EXPDEF); 964 965 /* 966 * Promote the symbols version index to the appropriate output version 967 * definition. 968 */ 969 if (!(sdp->sd_flags & FLG_SY_VERSPROM)) { 970 Ver_index *vip; 971 972 vip = &ifl->ifl_verndx[vndx]; 973 sdp->sd_aux->sa_overndx = vip->vi_desc->vd_ref->vd_ndx; 974 sdp->sd_flags |= FLG_SY_VERSPROM; 975 } 976 } 977 978 /* 979 * If any versioning is called for make sure an initial version descriptor is 980 * assigned to represent the file itself. Known as the base version. 981 */ 982 Ver_desc * 983 ld_vers_base(Ofl_desc *ofl) 984 { 985 Ver_desc *vdp; 986 const char *name; 987 988 /* 989 * Determine the filename to associate to the version descriptor. This 990 * is either the SONAME (if one has been supplied) or the basename of 991 * the output file. 992 */ 993 if ((name = ofl->ofl_soname) == 0) { 994 const char *str = ofl->ofl_name; 995 996 while (*str != '\0') { 997 if (*str++ == '/') 998 name = str; 999 } 1000 if (name == 0) 1001 name = ofl->ofl_name; 1002 } 1003 1004 /* 1005 * Generate the version descriptor. 1006 */ 1007 /* LINTED */ 1008 if ((vdp = ld_vers_desc(name, (Word)elf_hash(name), 1009 &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR) 1010 return ((Ver_desc *)S_ERROR); 1011 1012 /* 1013 * Assign the base index to this version and initialize the output file 1014 * descriptor with the number of version descriptors presently in use. 1015 */ 1016 vdp->vd_ndx = ofl->ofl_vercnt = VER_NDX_GLOBAL; 1017 vdp->vd_flags |= VER_FLG_BASE; 1018 1019 return (vdp); 1020 } 1021 1022 /* 1023 * Now that all input shared objects have been processed, verify that all 1024 * version requirements have been met. Any version control requirements will 1025 * have been specified by the user (and placed on the ofl_oscntl list) and are 1026 * verified at the time the object was processed (see ver_def_process()). 1027 * Here we process all version requirements established from shared objects 1028 * themselves (ie,. NEEDED dependencies). 1029 */ 1030 int 1031 ld_vers_verify(Ofl_desc *ofl) 1032 { 1033 Listnode *lnp1; 1034 Sdf_desc *sdf; 1035 char *nv; 1036 1037 /* 1038 * As with the runtime environment, disable all version verification if 1039 * requested. 1040 */ 1041 #if defined(_ELF64) 1042 if ((nv = getenv(MSG_ORIG(MSG_LD_NOVERSION_64))) == NULL) 1043 #else 1044 if ((nv = getenv(MSG_ORIG(MSG_LD_NOVERSION_32))) == NULL) 1045 #endif 1046 nv = getenv(MSG_ORIG(MSG_LD_NOVERSION)); 1047 1048 if (nv && (*nv != '\0')) 1049 return (1); 1050 1051 for (LIST_TRAVERSE(&ofl->ofl_soneed, lnp1, sdf)) { 1052 Listnode *lnp2; 1053 Sdv_desc *sdv; 1054 Ifl_desc *ifl = sdf->sdf_file; 1055 1056 if (!(sdf->sdf_flags & FLG_SDF_VERIFY)) 1057 continue; 1058 1059 /* 1060 * If this file contains no version definitions then ignore 1061 * any versioning verification. This is the same model as 1062 * carried out by ld.so.1 and is intended to allow backward 1063 * compatibility should a shared object with a version 1064 * requirment be returned to an older system on which a 1065 * non-versioned shared object exists. 1066 */ 1067 if ((ifl == 0) || (ifl->ifl_verdesc.head == 0)) 1068 continue; 1069 1070 /* 1071 * If individual versions were specified for this file make 1072 * sure that they actually exist in the appropriate file, and 1073 * that they are available for binding. 1074 */ 1075 for (LIST_TRAVERSE(&sdf->sdf_vers, lnp2, sdv)) { 1076 Listnode *lnp3; 1077 Ver_desc *vdp; 1078 int found = 0; 1079 1080 for (LIST_TRAVERSE(&ifl->ifl_verdesc, lnp3, vdp)) { 1081 if (strcmp(sdv->sdv_name, vdp->vd_name) == 0) { 1082 found++; 1083 break; 1084 } 1085 } 1086 if (found) { 1087 Ver_index *vip; 1088 1089 vip = &ifl->ifl_verndx[vdp->vd_ndx]; 1090 if (!(vip->vi_flags & FLG_VER_AVAIL)) { 1091 eprintf(ofl->ofl_lml, ERR_FATAL, 1092 MSG_INTL(MSG_VER_UNAVAIL), 1093 ifl->ifl_name, sdv->sdv_name, 1094 sdv->sdv_ref); 1095 ofl->ofl_flags |= FLG_OF_FATAL; 1096 } 1097 } else { 1098 eprintf(ofl->ofl_lml, ERR_FATAL, 1099 MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name, 1100 sdv->sdv_name, sdv->sdv_ref); 1101 ofl->ofl_flags |= FLG_OF_FATAL; 1102 } 1103 } 1104 } 1105 return (1); 1106 } 1107