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