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