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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright (c) 1988 AT&T 25 * All Rights Reserved 26 * 27 * 28 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 29 * Use is subject to license terms. 30 */ 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 /* 34 * set-up for relocations 35 */ 36 #include <string.h> 37 #include <stdio.h> 38 #include <alloca.h> 39 #include "debug.h" 40 #include "reloc.h" 41 #include "msg.h" 42 #include "_libld.h" 43 44 /* 45 * Structure to hold copy relocation items. 46 */ 47 typedef struct copy_rel { 48 Sym_desc * copyrel_symd; /* symbol descriptor to be copied */ 49 Addr copyrel_stval; /* Original symbol value */ 50 } Copy_rel; 51 52 /* 53 * For each copy relocation symbol, determine if the symbol is: 54 * 1) to be *disp* relocated at runtime 55 * 2) a reference symbol for *disp* relocation 56 * 3) possibly *disp* relocated at ld time. 57 * 58 * The first and the second are serious errors. 59 */ 60 static void 61 is_disp_copied(Ofl_desc *ofl, Copy_rel *cpy) 62 { 63 Ifl_desc *ifl = cpy->copyrel_symd->sd_file; 64 Sym_desc *sdp = cpy->copyrel_symd; 65 Is_desc *irel; 66 Addr symaddr = cpy->copyrel_stval; 67 Listnode *lnp1; 68 69 /* 70 * This symbol may not be *disp* relocated at run time, but could 71 * already have been *disp* relocated when the shared object was 72 * created. Warn the user. 73 */ 74 if ((ifl->ifl_flags & FLG_IF_DISPDONE) && 75 (ofl->ofl_flags & FLG_OF_VERBOSE)) 76 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_DISPREL2), 77 conv_reloc_type_str(ifl->ifl_ehdr->e_machine, M_R_COPY), 78 ifl->ifl_name, demangle(sdp->sd_name)); 79 80 if ((ifl->ifl_flags & FLG_IF_DISPPEND) == 0) 81 return; 82 83 /* 84 * Traverse the input relocation sections. 85 */ 86 for (LIST_TRAVERSE(&ifl->ifl_relsect, lnp1, irel)) { 87 Sym_desc *rsdp; 88 Is_desc *trel; 89 Rel *rend, *reloc; 90 Xword rsize, entsize; 91 92 trel = ifl->ifl_isdesc[irel->is_shdr->sh_info]; 93 rsize = irel->is_shdr->sh_size; 94 entsize = irel->is_shdr->sh_entsize; 95 reloc = (Rel *)irel->is_indata->d_buf; 96 97 /* 98 * Decide entry size 99 */ 100 if ((entsize == 0) || (entsize > rsize)) { 101 if (irel->is_shdr->sh_type == SHT_RELA) 102 entsize = sizeof (Rela); 103 else 104 entsize = sizeof (Rel); 105 } 106 107 /* 108 * Traverse the relocation entries. 109 */ 110 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize); 111 reloc < rend; 112 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) { 113 const char *str; 114 Word rstndx; 115 116 if (IS_PC_RELATIVE(ELF_R_TYPE(reloc->r_info)) == 0) 117 continue; 118 119 /* 120 * First, check if this symbol is reference symbol 121 * for this relocation entry. 122 */ 123 rstndx = (Word) ELF_R_SYM(reloc->r_info); 124 rsdp = ifl->ifl_oldndx[rstndx]; 125 if (rsdp == sdp) { 126 if ((str = demangle(rsdp->sd_name)) != 127 rsdp->sd_name) { 128 char *_str = alloca(strlen(str) + 1); 129 (void) strcpy(_str, str); 130 str = (const char *)_str; 131 } 132 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1), 133 conv_reloc_type_str( 134 ifl->ifl_ehdr->e_machine, 135 (uint_t)ELF_R_TYPE(reloc->r_info)), 136 ifl->ifl_name, str, 137 MSG_INTL(MSG_STR_UNKNOWN), 138 EC_XWORD(reloc->r_offset), 139 demangle(sdp->sd_name)); 140 } 141 142 /* 143 * Then check if this relocation entry is relocating 144 * this symbol. 145 */ 146 if ((sdp->sd_isc != trel) || 147 (reloc->r_offset < symaddr) || 148 (reloc->r_offset >= 149 (symaddr + sdp->sd_sym->st_size))) 150 continue; 151 152 /* 153 * This symbol is truely *disp* relocated, so should 154 * really be fixed by user. 155 */ 156 if ((str = demangle(sdp->sd_name)) != sdp->sd_name) { 157 char *_str = alloca(strlen(str) + 1); 158 (void) strcpy(_str, str); 159 str = (const char *)_str; 160 } 161 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1), 162 conv_reloc_type_str(ifl->ifl_ehdr->e_machine, 163 (uint_t)ELF_R_TYPE(reloc->r_info)), ifl->ifl_name, 164 demangle(rsdp->sd_name), str, 165 EC_XWORD(reloc->r_offset), str); 166 } 167 } 168 } 169 170 /* 171 * The number of symbols provided by some objects can be very large. Use a 172 * binary search to match the associated value to a symbol table entry. 173 */ 174 static int 175 disp_bsearch(const void *key, const void *array) 176 { 177 Addr kvalue, avalue; 178 Ssv_desc *ssvp = (Ssv_desc *)array; 179 180 kvalue = *((Addr *)key); 181 avalue = ssvp->ssv_value; 182 183 if (avalue > kvalue) 184 return (-1); 185 if ((avalue < kvalue) && 186 ((avalue + ssvp->ssv_sdp->sd_sym->st_size) <= kvalue)) 187 return (1); 188 return (0); 189 } 190 191 /* 192 * Given a sorted list of symbols, look for a symbol in which the relocation 193 * offset falls between the [sym.st_value - sym.st_value + sym.st_size]. Since 194 * the symbol list is maintained in sorted order, we can bail once the 195 * relocation offset becomes less than the symbol values. The symbol is 196 * returned for use in error diagnostics. 197 */ 198 static Sym_desc * 199 disp_scansyms(Ifl_desc * ifl, Rel_desc *rld, Boolean rlocal, int inspect, 200 Ofl_desc * ofl) 201 { 202 Sym_desc *tsdp, *rsdp; 203 Sym *rsym, *tsym; 204 Ssv_desc *ssvp; 205 uchar_t rtype, ttype; 206 Addr value; 207 208 /* 209 * Sorted symbol values have been uniquified by adding their associated 210 * section offset. Uniquify the relocation offset by adding its 211 * associated section offset, and search for the symbol. 212 */ 213 value = rld->rel_roffset; 214 if (rld->rel_isdesc->is_shdr) 215 value += rld->rel_isdesc->is_shdr->sh_offset; 216 217 if ((ssvp = bsearch((void *)&value, (void *)ifl->ifl_sortsyms, 218 ifl->ifl_sortcnt, sizeof (Ssv_desc), &disp_bsearch)) != 0) 219 tsdp = ssvp->ssv_sdp; 220 else 221 tsdp = 0; 222 223 if (inspect) 224 return (tsdp); 225 226 /* 227 * Determine the relocation reference symbol and its type. 228 */ 229 rsdp = rld->rel_sym; 230 rsym = rsdp->sd_sym; 231 rtype = ELF_ST_TYPE(rsym->st_info); 232 233 /* 234 * If there is no target symbol to match the relocation offset, then the 235 * offset is effectively local data. If the relocation symbol is global 236 * data we have a potential for this displacement relocation to be 237 * invalidated should the global symbol be copied. 238 */ 239 if (tsdp == 0) { 240 if ((rlocal == TRUE) || 241 ((rtype != STT_OBJECT) && (rtype != STT_SECTION))) 242 return (tsdp); 243 } else { 244 /* 245 * If both symbols are local, no copy relocations can occur to 246 * either. 247 */ 248 if ((rlocal == TRUE) && ((tsdp->sd_flags1 & FLG_SY1_LOCL) || 249 ((ofl->ofl_flags & FLG_OF_AUTOLCL) && 250 (tsdp->sd_flags1 & FLG_SY1_GLOB) == 0) || 251 (ELF_ST_BIND(tsdp->sd_sym->st_info) != STB_GLOBAL))) 252 return (tsdp); 253 254 /* 255 * Determine the relocation target symbols type. 256 */ 257 tsym = tsdp->sd_sym; 258 ttype = ELF_ST_TYPE(tsym->st_info); 259 260 /* 261 * One of the symbols must reference a data element. 262 */ 263 if ((rtype != STT_OBJECT) && (rtype != STT_SECTION) && 264 (ttype != STT_OBJECT) && (ttype != STT_SECTION)) 265 return (tsdp); 266 } 267 268 /* 269 * We have two global symbols, at least one of which is a data item. 270 * The last case where a displacement relocation can be ignored, is 271 * if the reference symbol is included in the target symbol. 272 */ 273 value = rsym->st_value; 274 value += rld->rel_raddend; 275 276 if ((rld->rel_roffset >= value) && 277 (rld->rel_roffset < (value + rsym->st_size))) 278 return (tsdp); 279 280 /* 281 * We have a displacement relocation that could be compromised by a 282 * copy relocation of one of the associated data items. 283 */ 284 rld->rel_flags |= FLG_REL_DISP; 285 return (tsdp); 286 } 287 288 void 289 disp_errmsg(const char *msg, Rel_desc *rsp, Ofl_desc *ofl) 290 { 291 Sym_desc *sdp; 292 const char *str; 293 Ifl_desc *ifl = rsp->rel_isdesc->is_file; 294 295 if ((sdp = disp_scansyms(ifl, rsp, 0, 1, ofl)) != 0) 296 str = demangle(sdp->sd_name); 297 else 298 str = MSG_INTL(MSG_STR_UNKNOWN); 299 300 eprintf(ERR_WARNING, msg, conv_reloc_type_str(ifl->ifl_ehdr->e_machine, 301 rsp->rel_rtype), ifl->ifl_name, rsp->rel_sname, str, 302 EC_OFF(rsp->rel_roffset)); 303 } 304 305 /* 306 * qsort(3C) comparison routine used for the disp_sortsyms(). 307 */ 308 static int 309 disp_qsort(const void * s1, const void * s2) 310 { 311 Ssv_desc *ssvp1 = ((Ssv_desc *)s1); 312 Ssv_desc *ssvp2 = ((Ssv_desc *)s2); 313 Addr val1 = ssvp1->ssv_value; 314 Addr val2 = ssvp2->ssv_value; 315 316 if (val1 > val2) 317 return (1); 318 if (val1 < val2) 319 return (-1); 320 return (0); 321 } 322 323 /* 324 * Determine whether a displacement relocation is between a local and global 325 * symbol pair. One symbol is used to perform the relocation, and the other 326 * is the destination offset of the relocation. 327 */ 328 static uintptr_t 329 disp_inspect(Ofl_desc *ofl, Rel_desc *rld, Boolean rlocal) 330 { 331 Is_desc *isp = rld->rel_isdesc; 332 Ifl_desc *ifl = rld->rel_isdesc->is_file; 333 334 /* 335 * If the input files symbols haven't been sorted yet, do so. 336 */ 337 if (ifl->ifl_sortsyms == 0) { 338 Word ondx, nndx; 339 340 if ((ifl->ifl_sortsyms = libld_malloc((ifl->ifl_symscnt + 1) * 341 sizeof (Ssv_desc))) == 0) 342 return (S_ERROR); 343 344 for (ondx = 0, nndx = 0; ondx < ifl->ifl_symscnt; ondx++) { 345 Sym_desc *sdp; 346 Addr value; 347 348 /* 349 * As symbol resolution has already occurred, various 350 * symbols from this object may have been satisfied 351 * from other objects. Only select symbols from this 352 * object. For the displacement test, we only really 353 * need to observe data definitions, however, later as 354 * part of providing warning disgnostics, relating the 355 * relocation offset to a symbol is desirable. Thus, 356 * collect all symbols that define a memory area. 357 */ 358 if (((sdp = ifl->ifl_oldndx[ondx]) == 0) || 359 (sdp->sd_shndx == SHN_UNDEF) || 360 (sdp->sd_shndx >= SHN_LORESERVE) || 361 (sdp->sd_ref != REF_REL_NEED) || 362 (sdp->sd_file != ifl) || 363 (sdp->sd_sym->st_size == 0)) 364 continue; 365 366 /* 367 * As a further optimization for later checking, mark 368 * this section if this a global data definition. 369 */ 370 if (sdp->sd_isc && (ondx >= ifl->ifl_locscnt)) 371 sdp->sd_isc->is_flags |= FLG_IS_GDATADEF; 372 373 /* 374 * Capture the symbol. Within relocatable objects, a 375 * symbols value is its offset within its associated 376 * section. Add the section offset to this value to 377 * uniquify the symbol. 378 */ 379 value = sdp->sd_sym->st_value; 380 if (sdp->sd_isc && sdp->sd_isc->is_shdr) 381 value += sdp->sd_isc->is_shdr->sh_offset; 382 383 ifl->ifl_sortsyms[nndx].ssv_value = value; 384 ifl->ifl_sortsyms[nndx].ssv_sdp = sdp; 385 nndx++; 386 } 387 388 /* 389 * Sort the list based on the symbols value (address). 390 */ 391 if ((ifl->ifl_sortcnt = nndx) != 0) 392 qsort(ifl->ifl_sortsyms, nndx, sizeof (Ssv_desc), 393 &disp_qsort); 394 } 395 396 /* 397 * If the reference symbol is local, and the section being relocated 398 * contains no global definitions, neither can be the target of a copy 399 * relocation. 400 */ 401 if ((rlocal == FALSE) && ((isp->is_flags & FLG_IS_GDATADEF) == 0)) 402 return (1); 403 404 /* 405 * Otherwise determine whether this relocation symbol and its offset 406 * could be candidates for a copy relocation. 407 */ 408 if (ifl->ifl_sortcnt) 409 (void) disp_scansyms(ifl, rld, rlocal, 0, ofl); 410 return (1); 411 } 412 413 uintptr_t 414 reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl) 415 { 416 Sym_desc *sdp; 417 Word flags = ofl->ofl_flags; 418 Gotndx *gnp; 419 420 sdp = rsp->rel_sym; 421 422 /* 423 * If this is the first time we've seen this symbol in a GOT 424 * relocation we need to assign it a GOT token. Once we've got 425 * all of the GOT's assigned we can assign the actual indexes. 426 */ 427 if ((gnp = find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_GENERIC, 428 ofl, rsp)) == 0) { 429 Word rtype = rsp->rel_rtype; 430 431 if (assign_gotndx(&(sdp->sd_GOTndxs), 0, GOT_REF_GENERIC, 432 ofl, rsp, sdp) == S_ERROR) 433 return (S_ERROR); 434 435 /* 436 * Now we initialize the GOT table entry. 437 * 438 * Pseudo code to describe the the decisions below: 439 * 440 * If (local) 441 * then 442 * enter symbol value in GOT table entry 443 * if (Shared Object) 444 * then 445 * create Relative relocation against symbol 446 * fi 447 * else 448 * clear GOT table entry 449 * create a GLOB_DAT relocation against symbol 450 * fi 451 */ 452 if (local == TRUE) { 453 if (flags & FLG_OF_SHAROBJ) { 454 if (add_actrel((FLG_REL_GOT | FLG_REL_GOTCL), 455 rsp, ofl) == S_ERROR) 456 return (S_ERROR); 457 458 /* 459 * Add a RELATIVE relocation if this is 460 * anything but a ABS symbol. 461 */ 462 if ((((sdp->sd_flags & FLG_SY_SPECSEC) == 0) || 463 (sdp->sd_shndx != SHN_ABS)) || 464 (sdp->sd_aux && sdp->sd_aux->sa_symspec)) { 465 rsp->rel_rtype = M_R_RELATIVE; 466 if (add_outrel((FLG_REL_GOT | 467 FLG_REL_ADVAL), rsp, 468 ofl) == S_ERROR) 469 return (S_ERROR); 470 rsp->rel_rtype = rtype; 471 } 472 } else { 473 if (add_actrel(FLG_REL_GOT, rsp, 474 ofl) == S_ERROR) 475 return (S_ERROR); 476 } 477 } else { 478 rsp->rel_rtype = M_R_GLOB_DAT; 479 if (add_outrel(FLG_REL_GOT, rsp, ofl) == S_ERROR) 480 return (S_ERROR); 481 rsp->rel_rtype = rtype; 482 } 483 } else { 484 if (assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_GENERIC, 485 ofl, rsp, sdp) == S_ERROR) 486 return (S_ERROR); 487 } 488 489 /* 490 * Perform relocation to GOT table entry. 491 */ 492 return (add_actrel(NULL, rsp, ofl)); 493 } 494 495 496 /* 497 * Perform relocations for PLT's 498 */ 499 uintptr_t 500 reloc_plt(Rel_desc *rsp, Ofl_desc *ofl) 501 { 502 Sym_desc *sdp = rsp->rel_sym; 503 504 #if defined(__i386) || defined(__amd64) 505 #if defined(_ELF64) 506 /* 507 * AMD64 TLS code sequences do not use a unique 508 * TLS relocation to reference the __tls_get_addr() 509 * function call. 510 */ 511 if ((ofl->ofl_flags & FLG_OF_EXEC) && 512 (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_U)) == 0)) { 513 return (add_actrel(FLG_REL_TLSFIX, rsp, ofl)); 514 } 515 #else 516 /* 517 * GNUC IA32 TLS code sequences do not use a unique 518 * TLS relocation to reference the ___tls_get_addr() 519 * function call. 520 */ 521 if ((ofl->ofl_flags & FLG_OF_EXEC) && 522 (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_UU)) == 0)) { 523 return (add_actrel(FLG_REL_TLSFIX, rsp, ofl)); 524 } 525 #endif 526 #endif /* __i386 && __amd64 */ 527 528 /* 529 * if (not PLT yet assigned) 530 * then 531 * assign PLT index to symbol 532 * build output JMP_SLOT relocation 533 * fi 534 */ 535 if (sdp->sd_aux->sa_PLTndx == 0) { 536 Word ortype = rsp->rel_rtype; 537 538 assign_plt_ndx(sdp, ofl); 539 540 /* 541 * If this symbol is binding to a LAZYLOADED object then 542 * set the LAZYLD symbol flag. 543 */ 544 if ((sdp->sd_aux->sa_bindto && 545 (sdp->sd_aux->sa_bindto->ifl_flags & FLG_IF_LAZYLD)) || 546 (sdp->sd_file && 547 (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD))) 548 sdp->sd_flags |= FLG_SY_LAZYLD; 549 550 rsp->rel_rtype = M_R_JMP_SLOT; 551 if (add_outrel(FLG_REL_PLT, rsp, ofl) == S_ERROR) 552 return (S_ERROR); 553 rsp->rel_rtype = ortype; 554 } 555 556 /* 557 * Perform relocation to PLT table entry. 558 */ 559 if ((ofl->ofl_flags & FLG_OF_SHAROBJ) && 560 IS_ADD_RELATIVE(rsp->rel_rtype)) { 561 Word ortype = rsp->rel_rtype; 562 563 rsp->rel_rtype = M_R_RELATIVE; 564 if (add_outrel(FLG_REL_ADVAL, rsp, ofl) == S_ERROR) 565 return (S_ERROR); 566 rsp->rel_rtype = ortype; 567 return (1); 568 } else 569 return (add_actrel(NULL, rsp, ofl)); 570 } 571 572 /* 573 * process GLOBAL undefined and ref_dyn_need symbols. 574 */ 575 uintptr_t 576 reloc_exec(Rel_desc *rsp, Ofl_desc *ofl) 577 { 578 Sym_desc *_sdp, *sdp = rsp->rel_sym; 579 Sym_aux *sap = sdp->sd_aux; 580 Sym *sym = sdp->sd_sym; 581 Addr stval; 582 583 /* 584 * Reference is to a function so simply create a plt entry for it. 585 */ 586 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) 587 return (reloc_plt(rsp, ofl)); 588 589 /* 590 * Catch absolutes - these may cause a text relocation. 591 */ 592 if ((sdp->sd_flags & FLG_SY_SPECSEC) && (sdp->sd_shndx == SHN_ABS)) { 593 if ((ofl->ofl_flags1 & FLG_OF1_ABSEXEC) == 0) 594 return (add_outrel(NULL, rsp, ofl)); 595 /* 596 * If -zabsexec is set then promote the ABSOLUTE 597 * symbol to current the current object and 598 * perform the relocation now. 599 */ 600 sdp->sd_ref = REF_REL_NEED; 601 return (add_actrel(NULL, rsp, ofl)); 602 } 603 604 /* 605 * If the relocation is against a writable section simply compute the 606 * necessary output relocation. As an optimization, if the symbol has 607 * already been transformed into a copy relocation then we can perform 608 * the relocation directly (copy relocations should only be generated 609 * for references from the text segment and these relocations are 610 * normally carried out before we get to the data segment relocations). 611 */ 612 if ((ELF_ST_TYPE(sym->st_info) == STT_OBJECT) && 613 (rsp->rel_osdesc->os_shdr->sh_flags & SHF_WRITE)) { 614 if (sdp->sd_flags & FLG_SY_MVTOCOMM) 615 return (add_actrel(NULL, rsp, ofl)); 616 else 617 return (add_outrel(NULL, rsp, ofl)); 618 } 619 620 /* 621 * If the reference isn't to an object (normally because some idiot 622 * hasn't defined a .type directive in some assembler source), then 623 * simply apply a generic relocation (this has a tendency to result in 624 * text relocations). 625 */ 626 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) { 627 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_UNEXPSYM), 628 conv_info_type_str(ofl->ofl_e_machine, 629 ELF_ST_TYPE(sym->st_info)), 630 rsp->rel_isdesc->is_file->ifl_name, 631 demangle(rsp->rel_sname), sdp->sd_file->ifl_name); 632 return (add_outrel(NULL, rsp, ofl)); 633 } 634 635 /* 636 * Prepare for generating a copy relocation. 637 * 638 * If this symbol is one of an alias pair, we need to insure both 639 * symbols become part of the output (the strong symbol will be used to 640 * maintain the symbols state). And, if we did raise the precedence of 641 * a symbol we need to check and see if this is a weak symbol. If it is 642 * we want to use it's strong counter part. 643 * 644 * The results of this logic should be: 645 * rel_usym: assigned to strong 646 * rel_sym: assigned to symbol to perform 647 * copy_reloc against (weak or strong). 648 */ 649 if (sap->sa_linkndx) { 650 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx]; 651 652 if (_sdp->sd_ref < sdp->sd_ref) { 653 _sdp->sd_ref = sdp->sd_ref; 654 _sdp->sd_flags |= FLG_SY_REFRSD; 655 656 /* 657 * As we're going to replicate a symbol from a shared 658 * object, retain its correct binding status. 659 */ 660 if (ELF_ST_BIND(_sdp->sd_sym->st_info) == STB_GLOBAL) 661 _sdp->sd_flags |= FLG_SY_GLOBREF; 662 663 } else if (_sdp->sd_ref > sdp->sd_ref) { 664 sdp->sd_ref = _sdp->sd_ref; 665 sdp->sd_flags |= FLG_SY_REFRSD; 666 667 /* 668 * As we're going to replicate a symbol from a shared 669 * object, retain its correct binding status. 670 */ 671 if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) 672 sdp->sd_flags |= FLG_SY_GLOBREF; 673 } 674 675 /* 676 * If this is a weak symbol then we want to move the strong 677 * symbol into local .bss. If there is a copy_reloc to be 678 * performed, that should still occur against the WEAK symbol. 679 */ 680 if ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) || 681 (sdp->sd_flags & FLG_SY_WEAKDEF)) 682 rsp->rel_usym = _sdp; 683 } else 684 _sdp = 0; 685 686 /* 687 * If the reference is to an object then allocate space for the object 688 * within the executables .bss. Relocations will now be performed from 689 * this new location. If the original shared objects data is 690 * initialized, then generate a copy relocation that will copy the data 691 * to the executables .bss at runtime. 692 */ 693 if (!(rsp->rel_usym->sd_flags & FLG_SY_MVTOCOMM)) { 694 Word rtype = rsp->rel_rtype; 695 Copy_rel *cpy_rel; 696 697 /* 698 * Indicate that the symbol(s) against which we're relocating 699 * have been moved to the executables common. Also, insure that 700 * the symbol(s) remain marked as global, as the shared object 701 * from which they are copied must be able to relocate to the 702 * new common location within the executable. 703 * 704 * Note that even though a new symbol has been generated in the 705 * output files' .bss, the symbol must remain REF_DYN_NEED and 706 * not be promoted to REF_REL_NEED. sym_validate() still needs 707 * to carry out a number of checks against the symbols binding 708 * that are triggered by the REF_DYN_NEED state. 709 */ 710 sdp->sd_flags |= FLG_SY_MVTOCOMM; 711 sdp->sd_flags1 |= FLG_SY1_GLOB; 712 sdp->sd_flags1 &= ~FLG_SY1_LOCL; 713 sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY; 714 if (_sdp) { 715 _sdp->sd_flags |= FLG_SY_MVTOCOMM; 716 _sdp->sd_flags1 |= FLG_SY1_GLOB; 717 _sdp->sd_flags1 &= ~FLG_SY1_LOCL; 718 _sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY; 719 720 /* 721 * Make sure the symbol has a reference in case of any 722 * error diagnostics against it (perhaps this belongs 723 * to a version that isn't allowable for this build). 724 * The resulting diagnostic (see sym_undef_entry()) 725 * might seem a little bogus, as the symbol hasn't 726 * really been referenced by this file, but has been 727 * promoted as a consequence of its alias reference. 728 */ 729 if (!(_sdp->sd_aux->sa_rfile)) 730 _sdp->sd_aux->sa_rfile = sdp->sd_aux->sa_rfile; 731 } 732 733 /* 734 * Assign the symbol to the bss and insure sufficient alignment 735 * (we don't know the real alignment so we have to make the 736 * worst case guess). 737 */ 738 _sdp = rsp->rel_usym; 739 stval = _sdp->sd_sym->st_value; 740 if (sym_copy(_sdp) == S_ERROR) 741 return (S_ERROR); 742 _sdp->sd_shndx = _sdp->sd_sym->st_shndx = SHN_COMMON; 743 _sdp->sd_flags |= FLG_SY_SPECSEC; 744 _sdp->sd_sym->st_value = 745 (_sdp->sd_sym->st_size < (M_WORD_ALIGN * 2)) ? 746 M_WORD_ALIGN : M_WORD_ALIGN * 2; 747 748 /* 749 * Whether or not the symbol references initialized 750 * data we generate a copy relocation - this differs 751 * from the past where we would not create the COPY_RELOC 752 * if we were binding against .bss. This is done 753 * for *two* reasons. 754 * 755 * o If the symbol in the shared object changes to 756 * a initialized data - we need the COPY to pick it 757 * up. 758 * o without the COPY RELOC we can't tell that the 759 * symbol from the COPY'd object has been moved 760 * and all bindings to it should bind here. 761 */ 762 763 /* 764 * Keep this symbol in the copy relocation list 765 * to check the validity later. 766 */ 767 if ((cpy_rel = libld_malloc(sizeof (Copy_rel))) == 0) 768 return (S_ERROR); 769 cpy_rel->copyrel_symd = _sdp; 770 cpy_rel->copyrel_stval = stval; 771 if (list_appendc(&ofl->ofl_copyrels, cpy_rel) == 0) 772 return (S_ERROR); 773 774 rsp->rel_rtype = M_R_COPY; 775 if (add_outrel(FLG_REL_BSS, rsp, ofl) == S_ERROR) 776 return (S_ERROR); 777 rsp->rel_rtype = rtype; 778 779 /* 780 * If this symbol is a protected symbol, warn it. 781 */ 782 if (_sdp->sd_flags & FLG_SY_PROT) 783 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_COPY), 784 conv_reloc_type_str(_sdp->sd_file->ifl_ehdr->e_machine, 785 M_R_COPY), _sdp->sd_file->ifl_name, _sdp->sd_name); 786 DBG_CALL(Dbg_syms_reloc(sdp->sd_file->ifl_ehdr, sdp)); 787 } 788 return (add_actrel(NULL, rsp, ofl)); 789 } 790 791 /* 792 * All relocations should have been handled by the other routines. This 793 * routine is hear as a catch all, if we do enter it we've goofed - but 794 * we'll try and to the best we can. 795 */ 796 uintptr_t 797 reloc_generic(Rel_desc *rsp, Ofl_desc *ofl) 798 { 799 Word flags = ofl->ofl_flags; 800 801 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_UNEXPREL), 802 conv_reloc_type_str(ofl->ofl_e_machine, rsp->rel_rtype), 803 rsp->rel_isdesc->is_file->ifl_name, demangle(rsp->rel_sname)); 804 805 /* 806 * If building a shared object then put the relocation off 807 * until runtime. 808 */ 809 if (flags & FLG_OF_SHAROBJ) 810 return (add_outrel(NULL, rsp, ofl)); 811 812 /* 813 * Otherwise process relocation now. 814 */ 815 return (add_actrel(NULL, rsp, ofl)); 816 } 817 818 819 uintptr_t 820 process_sym_reloc(Ofl_desc * ofl, Rel_desc * reld, Rel * reloc, 821 Is_desc * isp, const char *isname) 822 { 823 Word rtype = reld->rel_rtype; 824 Word flags = ofl->ofl_flags; 825 Sym_desc *sdp = reld->rel_sym; 826 Sym_aux *sap; 827 Boolean local; 828 829 DBG_CALL(Dbg_reloc_in(M_MACH, M_REL_SHT_TYPE, (void *)reloc, 830 reld->rel_sname, isname)); 831 832 /* 833 * Indicate this symbol is being used for relocation and therefore must 834 * have its output address updated accordingly (refer to update_osym()). 835 */ 836 sdp->sd_flags |= FLG_SY_UPREQD; 837 838 /* 839 * Indicate the section this symbol is defined in has been referenced, 840 * therefor it *is not* a candidate for elimination. 841 */ 842 if (sdp->sd_isc) { 843 sdp->sd_isc->is_flags |= FLG_IS_SECTREF; 844 sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF; 845 } 846 847 reld->rel_usym = sdp; 848 849 /* 850 * Determine if this symbol is actually an alias to another symbol. If 851 * so, and the alias is not REF_DYN_SEEN, set rel_usym to point to the 852 * weak symbols strong counter-part. The one exception is if the 853 * FLG_SY_MVTOCOMM flag is set on the weak symbol. If this is the case, 854 * the strong is only here because of its promotion, and the weak symbol 855 * should still be used for the relocation reference (see reloc_exec()). 856 */ 857 sap = sdp->sd_aux; 858 if (sap && sap->sa_linkndx && 859 ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) || 860 (sdp->sd_flags & FLG_SY_WEAKDEF)) && 861 (!(sdp->sd_flags & FLG_SY_MVTOCOMM))) { 862 Sym_desc * _sdp; 863 864 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx]; 865 if (_sdp->sd_ref != REF_DYN_SEEN) 866 reld->rel_usym = _sdp; 867 } 868 869 /* 870 * Determine whether this symbol should be bound locally or not. 871 * Symbols will be bound locally if one of the following is true: 872 * 873 * o the symbol is of type STB_LOCAL 874 * 875 * o the output image is not a relocatable object and the 876 * relocation is relative to the .got 877 * 878 * o the section being relocated is of type SHT_SUNW_dof; 879 * these sections are bound to the functions in the 880 * containing object and don't care about interpositioning 881 * 882 * o the symbol has been reduced (scoped to a local or 883 * symbolic) and reductions are being processed 884 * 885 * o the -Bsymbolic flag is in use when building a shared 886 * object or an executable (fixed address) is being created 887 * 888 * o Building an executable and the symbol is defined 889 * in the executable. 890 * 891 * o the relocation is against a segment which will not 892 * be loaded into memory. If that is the case we need 893 * to resolve the relocation now because ld.so.1 won't 894 * be able to. 895 */ 896 local = FALSE; 897 if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) { 898 local = TRUE; 899 } else if (!(reld->rel_flags & FLG_REL_LOAD)) { 900 local = TRUE; 901 } else if (sdp->sd_shndx != SHN_UNDEF) { 902 if (reld->rel_isdesc && 903 reld->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof) { 904 local = TRUE; 905 } else if (!(flags & FLG_OF_RELOBJ) && 906 (IS_LOCALBND(rtype) || IS_SEG_RELATIVE(rtype))) { 907 local = TRUE; 908 } else if (sdp->sd_ref == REF_REL_NEED) { 909 if ((sdp->sd_flags1 & (FLG_SY1_LOCL | FLG_SY1_PROT))) 910 local = TRUE; 911 else if (flags & (FLG_OF_SYMBOLIC | FLG_OF_EXEC)) 912 local = TRUE; 913 } 914 } 915 916 /* 917 * If this is a PC_RELATIVE relocation, the relocation could be 918 * compromised if the relocated address is later used as a copy 919 * relocated symbol (PSARC 1999/636, bugid 4187211). Scan the input 920 * files symbol table to cross reference this relocation offset. 921 */ 922 if ((ofl->ofl_flags & FLG_OF_SHAROBJ) && IS_PC_RELATIVE(rtype) && 923 (IS_GOT_PC(rtype) == 0) && (IS_PLT(rtype) == 0)) { 924 if (disp_inspect(ofl, reld, local) == S_ERROR) 925 return (S_ERROR); 926 } 927 928 /* 929 * GOT based relocations must bind to the object being built - since 930 * they are relevant to the current GOT. If not building a relocatable 931 * object - give a appropriate error message. 932 */ 933 if (!local && !(flags & FLG_OF_RELOBJ) && IS_GOT_BASED(rtype)) { 934 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED), 935 conv_reloc_type_str(ofl->ofl_e_machine, rtype), 936 reld->rel_isdesc->is_file->ifl_name, 937 demangle(sdp->sd_name)); 938 return (S_ERROR); 939 } 940 941 /* 942 * TLS symbols can only have TLS relocations. 943 */ 944 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_TLS) && !IS_TLS(rtype)) { 945 /* 946 * The above test is relaxed if the target section is 947 * non-allocable. 948 */ 949 if (reld->rel_osdesc->os_shdr->sh_flags & SHF_ALLOC) { 950 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_BADTLS), 951 conv_reloc_type_str(ofl->ofl_e_machine, rtype), 952 reld->rel_isdesc->is_file->ifl_name, 953 demangle(sdp->sd_name)); 954 return (S_ERROR); 955 } 956 } 957 958 /* 959 * Select the relocation to perform. 960 */ 961 if (IS_REGISTER(rtype)) 962 return (reloc_register(reld, isp, ofl)); 963 964 if (flags & FLG_OF_RELOBJ) 965 return (reloc_relobj(local, reld, ofl)); 966 967 if (IS_TLS_INS(rtype)) 968 return (reloc_TLS(local, reld, ofl)); 969 970 if (IS_GOT_INS(rtype)) 971 return (reloc_GOTOP(local, reld, ofl)); 972 973 if (IS_GOT_RELATIVE(rtype)) 974 return (reloc_GOT_relative(local, reld, ofl)); 975 976 if (local) 977 return (reloc_local(reld, ofl)); 978 979 if ((IS_PLT(rtype)) && ((flags & FLG_OF_BFLAG) == 0)) 980 return (reloc_plt(reld, ofl)); 981 982 if ((sdp->sd_ref == REF_REL_NEED) || 983 (flags & FLG_OF_BFLAG) || (flags & FLG_OF_SHAROBJ) || 984 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_NOTYPE)) 985 return (add_outrel(NULL, reld, ofl)); 986 987 if (sdp->sd_ref == REF_DYN_NEED) 988 return (reloc_exec(reld, ofl)); 989 990 /* 991 * IS_NOT_REL(rtype) 992 */ 993 return (reloc_generic(reld, ofl)); 994 } 995 996 /* 997 * Generate relocation descriptor and dispatch 998 */ 999 static uintptr_t 1000 process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx, 1001 Rel *reloc) 1002 { 1003 Ifl_desc *ifl = isp->is_file; 1004 Word rtype = reld->rel_rtype; 1005 Sym_desc *sdp; 1006 1007 /* 1008 * Make sure the relocation is in the valid range. 1009 */ 1010 if (rtype >= M_R_NUM) { 1011 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT), ifl->ifl_name, 1012 isp->is_name, rtype); 1013 return (S_ERROR); 1014 } 1015 1016 ofl->ofl_entrelscnt++; 1017 1018 /* 1019 * Special case: a register symbol associated with symbol index 0 is 1020 * initialized (i.e., relocated) to a constant from the r_addend field 1021 * rather than from a symbol value. 1022 */ 1023 if (IS_REGISTER(rtype) && (rsndx == 0)) { 1024 reld->rel_sym = 0; 1025 reld->rel_sname = MSG_ORIG(MSG_STR_EMPTY); 1026 1027 DBG_CALL(Dbg_reloc_in(M_MACH, isp->is_shdr->sh_type, 1028 (void *)reloc, reld->rel_sname, isp->is_name)); 1029 return (reloc_register(reld, isp, ofl)); 1030 } 1031 1032 /* 1033 * Determine whether we're dealing with a named symbol. Note, bogus 1034 * relocations can result in a null symbol descriptor (sdp), the error 1035 * condition should be caught below after determining whether a valid 1036 * symbol name exists. 1037 */ 1038 sdp = ifl->ifl_oldndx[rsndx]; 1039 if (sdp != NULL && sdp->sd_name && *sdp->sd_name) 1040 reld->rel_sname = sdp->sd_name; 1041 else { 1042 static char *strunknown; 1043 1044 if (strunknown == 0) 1045 strunknown = (char *)MSG_INTL(MSG_STR_UNKNOWN); 1046 reld->rel_sname = strunknown; 1047 } 1048 1049 /* 1050 * If for some reason we have a null relocation record issue a 1051 * warning and continue (the compiler folks can get into this 1052 * state some time). Normal users should never see this error. 1053 */ 1054 if (rtype == M_R_NONE) { 1055 DBG_CALL(Dbg_reloc_in(M_MACH, M_REL_SHT_TYPE, (void *)reloc, 1056 reld->rel_sname, isp->is_name)); 1057 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_NULL), ifl->ifl_name, 1058 isp->is_name); 1059 return (1); 1060 } 1061 1062 if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && IS_NOTSUP(rtype)) { 1063 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP), 1064 conv_reloc_type_str(ifl->ifl_ehdr->e_machine, rtype), 1065 ifl->ifl_name, isp->is_name); 1066 return (S_ERROR); 1067 } 1068 1069 /* 1070 * If we are here, we know that the relocation requires reference 1071 * symbol. If no symbol is assigned, this is a fatal error. 1072 */ 1073 if (sdp == NULL) { 1074 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL), 1075 conv_reloc_type_str(ifl->ifl_ehdr->e_machine, rtype), 1076 isp->is_name, ifl->ifl_name, EC_XWORD(reloc->r_offset)); 1077 return (S_ERROR); 1078 } 1079 1080 if (sdp->sd_flags1 & FLG_SY1_IGNORE) 1081 return (1); 1082 1083 /* 1084 * If this symbol is part of a DISCARDED section attempt to find another 1085 * definition. 1086 */ 1087 if (sdp->sd_flags & FLG_SY_ISDISC) { 1088 Sym_desc * nsdp; 1089 1090 if ((reld->rel_sname != sdp->sd_name) || 1091 (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) || 1092 ((nsdp = sym_find(sdp->sd_name, SYM_NOHASH, 0, 1093 ofl)) == 0)) { 1094 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_SYMDISC), 1095 ifl->ifl_name, isp->is_name, demangle(sdp->sd_name), 1096 sdp->sd_isc->is_name); 1097 return (S_ERROR); 1098 } 1099 ifl->ifl_oldndx[rsndx] = sdp = nsdp; 1100 } 1101 1102 /* 1103 * If this is a global symbol, determine whether its visibility needs 1104 * adjusting. 1105 */ 1106 if (sdp->sd_aux && ((sdp->sd_flags & FLG_SY_VISIBLE) == 0)) 1107 sym_adjust_vis(sdp, ofl); 1108 1109 /* 1110 * Ignore any relocation against a section that will not be in the 1111 * output file (has been stripped). 1112 */ 1113 if ((sdp->sd_isc == 0) && 1114 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) 1115 return (1); 1116 1117 /* 1118 * If the symbol for this relocation is invalid (which should have 1119 * generated a message during symbol processing), or the relocation 1120 * record's symbol reference is in any other way invalid, then it's 1121 * about time we gave up. 1122 */ 1123 if ((sdp->sd_flags & FLG_SY_INVALID) || (rsndx == 0) || 1124 (rsndx >= ifl->ifl_symscnt)) { 1125 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM), 1126 M_REL_CONTYPSTR(rtype), ifl->ifl_name, isp->is_name, 1127 demangle(reld->rel_sname), EC_XWORD(reloc->r_offset), 1128 EC_WORD(rsndx)); 1129 return (S_ERROR); 1130 } 1131 1132 reld->rel_sym = sdp; 1133 return (process_sym_reloc(ofl, reld, reloc, isp, isp->is_name)); 1134 } 1135 1136 static uintptr_t 1137 reloc_section(Ofl_desc *ofl, Is_desc *isect, Is_desc *rsect, Os_desc *osect) 1138 { 1139 Rel *rend; /* end of relocation section data */ 1140 Rel *reloc; /* current relocation entry */ 1141 Xword rsize; /* size of relocation section data */ 1142 Xword entsize; /* size of relocation entry */ 1143 Rel_desc reld; /* relocation descriptor */ 1144 Shdr * shdr; 1145 Word flags = 0; 1146 1147 shdr = rsect->is_shdr; 1148 rsize = shdr->sh_size; 1149 reloc = (Rel *)rsect->is_indata->d_buf; 1150 1151 /* 1152 * Decide entry size. 1153 */ 1154 if (((entsize = shdr->sh_entsize) == 0) || (entsize > rsize)) { 1155 if (shdr->sh_type == SHT_RELA) 1156 entsize = sizeof (Rela); 1157 else 1158 entsize = sizeof (Rel); 1159 } 1160 1161 /* 1162 * Build up the basic information in for the Rel_desc structure. 1163 */ 1164 reld.rel_osdesc = osect; 1165 reld.rel_isdesc = isect; 1166 reld.rel_move = 0; 1167 1168 if ((ofl->ofl_flags & FLG_OF_RELOBJ) || 1169 (osect && (osect->os_sgdesc->sg_phdr.p_type == PT_LOAD))) 1170 flags |= FLG_REL_LOAD; 1171 1172 if (shdr->sh_info == 0) 1173 flags |= FLG_REL_NOINFO; 1174 1175 DBG_CALL(Dbg_reloc_proc(osect, isect, rsect)); 1176 1177 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize); 1178 reloc < rend; 1179 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) { 1180 Word rsndx; 1181 1182 /* 1183 * Initialize the relocation record information and process 1184 * the individual relocation. Reinitialize the flags to 1185 * insure we don't carry any state over from the previous 1186 * relocation records processing. 1187 */ 1188 reld.rel_flags = flags; 1189 rsndx = init_rel(&reld, (void *)reloc); 1190 1191 if (process_reld(ofl, rsect, &reld, rsndx, reloc) == S_ERROR) 1192 return (S_ERROR); 1193 } 1194 return (1); 1195 } 1196 1197 1198 uintptr_t 1199 reloc_segments(int wr_flag, Ofl_desc *ofl) 1200 { 1201 Listnode *lnp1; 1202 Sg_desc *sgp; 1203 Is_desc *isp; 1204 1205 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { 1206 Os_desc *osp; 1207 Listnode *lnp2; 1208 1209 if ((sgp->sg_phdr.p_flags & PF_W) != wr_flag) 1210 continue; 1211 1212 for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp2, osp)) { 1213 Is_desc *risp; 1214 Listnode *lnp3; 1215 1216 osp->os_szoutrels = 0; 1217 for (LIST_TRAVERSE(&(osp->os_relisdescs), lnp3, risp)) { 1218 Word indx; 1219 1220 /* 1221 * Determine the input section that this 1222 * relocation information refers to. 1223 */ 1224 indx = risp->is_shdr->sh_info; 1225 isp = risp->is_file->ifl_isdesc[indx]; 1226 1227 /* 1228 * Do not process relocations against sections 1229 * which are being discarded (COMDAT) 1230 */ 1231 if (isp->is_flags & FLG_IS_DISCARD) 1232 continue; 1233 1234 if (reloc_section(ofl, isp, risp, osp) == 1235 S_ERROR) 1236 return (S_ERROR); 1237 } 1238 1239 /* 1240 * Check for relocations against non-writable 1241 * allocatable sections. 1242 */ 1243 if ((osp->os_szoutrels) && 1244 (sgp->sg_phdr.p_type == PT_LOAD) && 1245 ((sgp->sg_phdr.p_flags & PF_W) == 0)) { 1246 ofl->ofl_flags |= FLG_OF_TEXTREL; 1247 ofl->ofl_dtflags |= DF_TEXTREL; 1248 } 1249 } 1250 } 1251 1252 return (1); 1253 } 1254 1255 /* 1256 * Move Section related function 1257 * Get move entry 1258 */ 1259 static Move * 1260 get_move_entry(Is_desc *rsect, Xword roffset) 1261 { 1262 Ifl_desc *ifile = rsect->is_file; 1263 Shdr *rshdr = rsect->is_shdr; 1264 Is_desc *misp; 1265 Shdr *mshdr; 1266 Xword midx; 1267 Move *ret; 1268 1269 /* 1270 * Set info for the target move section 1271 */ 1272 misp = ifile->ifl_isdesc[rshdr->sh_info]; 1273 mshdr = (ifile->ifl_isdesc[rshdr->sh_info])->is_shdr; 1274 1275 if (mshdr->sh_entsize == 0) 1276 return ((Move *)0); 1277 midx = roffset / mshdr->sh_entsize; 1278 1279 ret = (Move *)misp->is_indata->d_buf; 1280 ret += midx; 1281 1282 /* 1283 * If this is an illgal entry, retun NULL. 1284 */ 1285 if ((midx * mshdr->sh_entsize) >= mshdr->sh_size) 1286 return ((Move *)0); 1287 return (ret); 1288 } 1289 1290 /* 1291 * Relocation against Move Table. 1292 */ 1293 static uintptr_t 1294 process_movereloc(Ofl_desc *ofl, Is_desc *rsect) 1295 { 1296 Ifl_desc *file = rsect->is_file; 1297 Rel *rend, *reloc; 1298 Xword rsize, entsize; 1299 static Rel_desc reld_zero; 1300 Rel_desc reld; 1301 1302 rsize = rsect->is_shdr->sh_size; 1303 reloc = (Rel *)rsect->is_indata->d_buf; 1304 1305 reld = reld_zero; 1306 1307 /* 1308 * Decide entry size 1309 */ 1310 entsize = rsect->is_shdr->sh_entsize; 1311 if ((entsize == 0) || 1312 (entsize > rsect->is_shdr->sh_size)) { 1313 if (rsect->is_shdr->sh_type == SHT_RELA) 1314 entsize = sizeof (Rela); 1315 else 1316 entsize = sizeof (Rel); 1317 } 1318 1319 /* 1320 * Go through the relocation entries. 1321 */ 1322 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize); 1323 reloc < rend; 1324 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) { 1325 Sym_desc * psdp; 1326 Move * mp; 1327 Word rsndx; 1328 1329 /* 1330 * Initialize the relocation record information. 1331 */ 1332 reld.rel_flags = FLG_REL_LOAD; 1333 rsndx = init_rel(&reld, (void *)reloc); 1334 1335 if (((mp = get_move_entry(rsect, reloc->r_offset)) == 0) || 1336 ((reld.rel_move = libld_malloc(sizeof (Mv_desc))) == 0)) 1337 return (S_ERROR); 1338 1339 psdp = file->ifl_oldndx[ELF_M_SYM(mp->m_info)]; 1340 reld.rel_move->mvd_move = mp; 1341 reld.rel_move->mvd_sym = psdp; 1342 1343 if (psdp->sd_flags & FLG_SY_PAREXPN) { 1344 int _num, num; 1345 1346 reld.rel_osdesc = ofl->ofl_issunwdata1->is_osdesc; 1347 reld.rel_isdesc = ofl->ofl_issunwdata1; 1348 reld.rel_roffset = mp->m_poffset; 1349 1350 for (num = mp->m_repeat, _num = 0; _num < num; _num++) { 1351 reld.rel_roffset += 1352 /* LINTED */ 1353 (_num * ELF_M_SIZE(mp->m_info)); 1354 /* 1355 * Generate Reld 1356 */ 1357 if (process_reld(ofl, 1358 rsect, &reld, rsndx, reloc) == S_ERROR) 1359 return (S_ERROR); 1360 } 1361 } else { 1362 /* 1363 * Generate Reld 1364 */ 1365 reld.rel_flags |= FLG_REL_MOVETAB; 1366 reld.rel_osdesc = ofl->ofl_osmove; 1367 reld.rel_isdesc = 1368 ofl->ofl_osmove->os_isdescs.head->data; 1369 if (process_reld(ofl, 1370 rsect, &reld, rsndx, reloc) == S_ERROR) 1371 return (S_ERROR); 1372 } 1373 } 1374 return (1); 1375 } 1376 1377 /* 1378 * This function is similar to reloc_init(). 1379 * 1380 * This function is called when the SHT_SUNW_move table is expanded 1381 * and there were relocation against the SHT_SUNW_move section. 1382 */ 1383 static uintptr_t 1384 reloc_movesections(Ofl_desc *ofl) 1385 { 1386 Listnode *lnp1; 1387 Is_desc *risp; 1388 1389 /* 1390 * Generate/Expand relocation entries 1391 */ 1392 for (LIST_TRAVERSE(&ofl->ofl_mvrelisdescs, lnp1, risp)) { 1393 if (process_movereloc(ofl, risp) == S_ERROR) 1394 return (S_ERROR); 1395 } 1396 1397 return (1); 1398 } 1399 1400 /* 1401 * Count the number of output relocation entries, global offset table entries, 1402 * and procedure linkage table entries. This function searches the segment and 1403 * outsect lists and passes each input reloc section to process_reloc(). 1404 * It allocates space for any output relocations needed. And builds up 1405 * the relocation structures for later processing. 1406 */ 1407 uintptr_t 1408 reloc_init(Ofl_desc *ofl) 1409 { 1410 Listnode *lnp; 1411 Is_desc *isp; 1412 1413 /* 1414 * At this point we have finished processing all input symbols. Make 1415 * sure we add any absolute (internal) symbols before continuing with 1416 * any relocation processing. 1417 */ 1418 if (sym_spec(ofl) == S_ERROR) 1419 return (S_ERROR); 1420 1421 ofl->ofl_gotcnt = M_GOT_XNumber; 1422 1423 /* 1424 * First process all of the relocations against NON-writable 1425 * segments followed by relocations against the writeable segments. 1426 * 1427 * This separation is so that when the writable segments are processed 1428 * we know whether or not a COPYRELOC will be produced for any symbols. 1429 * If relocations aren't processed in this order, a COPYRELOC and a 1430 * regular relocation can be produced against the same symbol. The 1431 * regular relocation would be redundant. 1432 */ 1433 if (reloc_segments(0, ofl) == S_ERROR) 1434 return (S_ERROR); 1435 1436 if (reloc_segments(PF_W, ofl) == S_ERROR) 1437 return (S_ERROR); 1438 1439 /* 1440 * Process any extra relocations. These are relocation sections that 1441 * have a NULL sh_info. 1442 */ 1443 for (LIST_TRAVERSE(&ofl->ofl_extrarels, lnp, isp)) { 1444 if (reloc_section(ofl, NULL, isp, NULL) == S_ERROR) 1445 return (S_ERROR); 1446 } 1447 1448 /* 1449 * If there were relocation against move table, 1450 * process the relocation sections. 1451 */ 1452 if (reloc_movesections(ofl) == S_ERROR) 1453 return (S_ERROR); 1454 1455 /* 1456 * Now all the relocations are pre-processed, 1457 * check the validity of copy relocations. 1458 */ 1459 if (ofl->ofl_copyrels.head != 0) { 1460 Copy_rel * cpyrel; 1461 1462 for (LIST_TRAVERSE(&ofl->ofl_copyrels, lnp, cpyrel)) { 1463 Sym_desc * sdp; 1464 1465 sdp = cpyrel->copyrel_symd; 1466 /* 1467 * If there were no displacement relocation 1468 * in this file, don't worry about it. 1469 */ 1470 if (sdp->sd_file->ifl_flags & 1471 (FLG_IF_DISPPEND | FLG_IF_DISPDONE)) 1472 is_disp_copied(ofl, cpyrel); 1473 } 1474 } 1475 1476 /* 1477 * Make a got section if: 1478 * 1479 * BLDGOT flag set 1480 * or 1481 * ofl_gotcnt != GOT_XNumber 1482 * or 1483 * not-relobj & GOT symbol referenced 1484 * 1485 */ 1486 if ((ofl->ofl_flags & FLG_OF_BLDGOT) || 1487 (ofl->ofl_gotcnt != M_GOT_XNumber) || 1488 (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && 1489 ((sym_find(MSG_ORIG(MSG_SYM_GOFTBL), SYM_NOHASH, 0, ofl) != 0) || 1490 (sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U), SYM_NOHASH, 0, ofl) != 0)))) { 1491 if (make_got(ofl) == S_ERROR) 1492 return (S_ERROR); 1493 1494 #if defined(sparc) || defined(__sparcv9) 1495 if (allocate_got(ofl) == S_ERROR) 1496 return (S_ERROR); 1497 #elif defined(i386) || defined(__amd64) 1498 /* nothing to do */ 1499 #else 1500 #error Unknown architecture! 1501 #endif 1502 } 1503 1504 return (1); 1505 } 1506 1507 /* 1508 * Simple comparison routine to be used by qsort() for 1509 * the sorting of the output relocation list. 1510 * 1511 * The reloc_compare() routine results in a relocation 1512 * table which is located on: 1513 * 1514 * file referenced (NEEDED NDX) 1515 * referenced symbol 1516 * relocation offset 1517 * 1518 * This provides the most efficient traversal of the relocation 1519 * table at run-time. 1520 */ 1521 int 1522 reloc_compare(Reloc_list *i, Reloc_list *j) 1523 { 1524 1525 /* 1526 * first - sort on neededndx 1527 */ 1528 if (i->rl_key1 > j->rl_key1) 1529 return (1); 1530 if (i->rl_key1 < j->rl_key1) 1531 return (-1); 1532 1533 /* 1534 * Then sort on symbol 1535 */ 1536 if ((uintptr_t)i->rl_key2 > (uintptr_t)j->rl_key2) 1537 return (1); 1538 if ((uintptr_t)i->rl_key2 < (uintptr_t)j->rl_key2) 1539 return (-1); 1540 1541 /* 1542 * i->key2 == j->key2 1543 * 1544 * At this point we fall back to key2 (offsets) to 1545 * sort the output relocations. Ideally this will 1546 * make for the most efficient processing of these 1547 * relocations at run-time. 1548 */ 1549 if (i->rl_key3 > j->rl_key3) 1550 return (1); 1551 if (i->rl_key3 < j->rl_key3) 1552 return (-1); 1553 return (0); 1554 } 1555 1556 1557 uintptr_t 1558 do_sorted_outrelocs(Ofl_desc *ofl) 1559 { 1560 Rel_desc *orsp; 1561 Rel_cache *rcp; 1562 Listnode *lnp; 1563 Reloc_list *sorted_list; 1564 Word index = 0; 1565 int debug = 0; 1566 uintptr_t error = 1; 1567 1568 if ((sorted_list = libld_malloc((size_t)(sizeof (Reloc_list) * 1569 ofl->ofl_reloccnt))) == NULL) 1570 return (S_ERROR); 1571 1572 /* 1573 * All but the PLT output relocations are sorted in the output file 1574 * based upon their sym_desc. By doing this multiple relocations 1575 * against the same symbol are grouped together, thus when the object 1576 * is later relocated by ld.so.1 it will take advantage of the symbol 1577 * cache that ld.so.1 has. This can significantly reduce the runtime 1578 * relocation cost of a dynamic object. 1579 * 1580 * PLT relocations are not sorted because the order of the PLT 1581 * relocations is used by ld.so.1 to determine what symbol a PLT 1582 * relocation is against. 1583 */ 1584 for (LIST_TRAVERSE(&ofl->ofl_outrels, lnp, rcp)) { 1585 /*LINTED*/ 1586 for (orsp = (Rel_desc *)(rcp + 1); 1587 orsp < rcp->rc_free; orsp++) { 1588 if (debug == 0) { 1589 DBG_CALL(Dbg_reloc_dooutrel(M_REL_SHT_TYPE)); 1590 debug = 1; 1591 } 1592 1593 /* 1594 * If it's a PLT relocation we output it now in the 1595 * order that it was originally processed. 1596 */ 1597 if (orsp->rel_flags & FLG_REL_PLT) { 1598 if (perform_outreloc(orsp, ofl) == S_ERROR) 1599 error = S_ERROR; 1600 continue; 1601 } 1602 1603 if ((orsp->rel_rtype == M_R_RELATIVE) || 1604 (orsp->rel_rtype == M_R_REGISTER)) { 1605 sorted_list[index].rl_key1 = 0; 1606 sorted_list[index].rl_key2 = 1607 /* LINTED */ 1608 (Sym_desc *)(uintptr_t)orsp->rel_rtype; 1609 } else { 1610 sorted_list[index].rl_key1 = 1611 orsp->rel_sym->sd_file->ifl_neededndx; 1612 sorted_list[index].rl_key2 = 1613 orsp->rel_sym; 1614 } 1615 1616 if (orsp->rel_flags & FLG_REL_GOT) 1617 sorted_list[index].rl_key3 = 1618 calc_got_offset(orsp, ofl); 1619 else { 1620 if (orsp->rel_rtype == M_R_REGISTER) 1621 sorted_list[index].rl_key3 = 0; 1622 else { 1623 sorted_list[index].rl_key3 = 1624 orsp->rel_roffset + 1625 (Xword)_elf_getxoff(orsp-> 1626 rel_isdesc-> 1627 is_indata) + 1628 orsp->rel_isdesc->is_osdesc-> 1629 os_shdr->sh_addr; 1630 } 1631 } 1632 1633 sorted_list[index++].rl_rsp = orsp; 1634 } 1635 } 1636 1637 qsort(sorted_list, (size_t)ofl->ofl_reloccnt, sizeof (Reloc_list), 1638 (int (*)(const void *, const void *))reloc_compare); 1639 1640 /* 1641 * All output relocations have now been sorted, go through 1642 * and process each relocation. 1643 */ 1644 for (index = 0; index < ofl->ofl_reloccnt; index++) { 1645 if (perform_outreloc(sorted_list[index].rl_rsp, ofl) == 1646 S_ERROR) 1647 error = S_ERROR; 1648 } 1649 1650 return (error); 1651 } 1652 1653 /* 1654 * Process relocations. Finds every input relocation section for each output 1655 * section and invokes reloc_sec() to relocate that section. 1656 */ 1657 uintptr_t 1658 reloc_process(Ofl_desc *ofl) 1659 { 1660 Listnode *lnp1; 1661 Sg_desc *sgp; 1662 Word ndx = 0, flags = ofl->ofl_flags; 1663 Shdr *shdr; 1664 1665 /* 1666 * Determine the index of the symbol table that will be referenced by 1667 * the relocation entries. 1668 */ 1669 if ((flags & (FLG_OF_DYNAMIC|FLG_OF_RELOBJ)) == FLG_OF_DYNAMIC) 1670 /* LINTED */ 1671 ndx = (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn); 1672 else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ)) 1673 /* LINTED */ 1674 ndx = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn); 1675 1676 /* 1677 * Re-initialize counters. These are used to provide relocation 1678 * offsets within the output buffers. 1679 */ 1680 ofl->ofl_relocpltsz = 0; 1681 ofl->ofl_relocgotsz = 0; 1682 ofl->ofl_relocbsssz = 0; 1683 1684 /* 1685 * Now that the output file is created and symbol update has occurred, 1686 * process the relocations collected in process_reloc(). 1687 */ 1688 if (do_sorted_outrelocs(ofl) == S_ERROR) 1689 return (S_ERROR); 1690 1691 if (do_activerelocs(ofl) == S_ERROR) 1692 return (S_ERROR); 1693 1694 if ((ofl->ofl_flags1 & FLG_OF1_RELCNT) == 0) { 1695 /* 1696 * Process the relocation sections: 1697 * 1698 * o for each relocation section generated for the output 1699 * image update its shdr information to reflect the 1700 * symbol table it needs (sh_link) and the section to 1701 * which the relocation must be applied (sh_info). 1702 */ 1703 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { 1704 Listnode * lnp2; 1705 Os_desc * osp; 1706 1707 for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp2, osp)) { 1708 if (osp->os_relosdesc == 0) 1709 continue; 1710 1711 shdr = osp->os_relosdesc->os_shdr; 1712 shdr->sh_link = ndx; 1713 /* LINTED */ 1714 shdr->sh_info = (Word)elf_ndxscn(osp->os_scn); 1715 } 1716 } 1717 1718 /* 1719 * Since the .rel[a] section is not tied to any specific 1720 * section, we'd of not found it above. 1721 */ 1722 if (ofl->ofl_osrel) { 1723 shdr = ofl->ofl_osrel->os_shdr; 1724 shdr->sh_link = ndx; 1725 shdr->sh_info = 0; 1726 } 1727 } else { 1728 /* 1729 * We only have two relocation sections here, (PLT's, 1730 * coalesced) so just hit them directly instead of stepping 1731 * over the output sections. 1732 */ 1733 if (ofl->ofl_osrelhead) { 1734 shdr = ofl->ofl_osrelhead->os_shdr; 1735 shdr->sh_link = ndx; 1736 shdr->sh_info = 0; 1737 } 1738 if (ofl->ofl_osplt && ofl->ofl_osplt->os_relosdesc) { 1739 shdr = ofl->ofl_osplt->os_relosdesc->os_shdr; 1740 shdr->sh_link = ndx; 1741 /* LINTED */ 1742 shdr->sh_info = 1743 (Word)elf_ndxscn(ofl->ofl_osplt->os_scn); 1744 } 1745 } 1746 1747 /* 1748 * If the -z text option was given, and we have output relocations 1749 * against a non-writable, allocatable section, issue a diagnostic and 1750 * return (the actual entries that caused this error would have been 1751 * output during the relocating section phase). 1752 */ 1753 if ((flags & (FLG_OF_PURETXT | FLG_OF_TEXTREL)) == 1754 (FLG_OF_PURETXT | FLG_OF_TEXTREL)) { 1755 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_REMAIN_3)); 1756 return (S_ERROR); 1757 } 1758 1759 /* 1760 * Finally, initialize the first got entry with the address of the 1761 * .dynamic section (_DYNAMIC). 1762 */ 1763 if (flags & FLG_OF_DYNAMIC) { 1764 if (fillin_gotplt1(ofl) == S_ERROR) 1765 return (S_ERROR); 1766 } 1767 1768 return (1); 1769 } 1770 1771 /* 1772 * If the -z text option was given, and we have output relocations against a 1773 * non-writable, allocatable section, issue a diagnostic. Print offending 1774 * symbols in tabular form similar to the way undefined symbols are presented. 1775 * Called from reloc_count(). The actual fatal error condition is triggered on 1776 * in reloc_process() above. 1777 * 1778 * Note. For historic reasons -ztext is not a default option (however all OS 1779 * shared object builds use this option). It can be argued that this option 1780 * should also be default when generating an a.out (see 1163979). However, if 1781 * an a.out contains text relocations it is either because the user is creating 1782 * something pretty weird (they've used the -b or -znodefs options), or because 1783 * the library against which they're building wasn't constructed correctly (ie. 1784 * a function has a NOTYPE type, in which case the a.out won't generate an 1785 * associated plt). In the latter case the builder of the a.out can't do 1786 * anything to fix the error - thus we've chosen not to give the user an error, 1787 * or warning, for this case. 1788 */ 1789 1790 void 1791 reloc_remain_title(int warning) 1792 { 1793 const char *str1; 1794 1795 if (warning) 1796 str1 = MSG_INTL(MSG_REL_RMN_ITM_13); 1797 else 1798 str1 = MSG_INTL(MSG_REL_RMN_ITM_11); 1799 1800 eprintf(ERR_NONE, MSG_INTL(MSG_REL_REMAIN_FMT_1), 1801 str1, 1802 MSG_INTL(MSG_REL_RMN_ITM_31), 1803 MSG_INTL(MSG_REL_RMN_ITM_12), 1804 MSG_INTL(MSG_REL_RMN_ITM_2), 1805 MSG_INTL(MSG_REL_RMN_ITM_32)); 1806 1807 } 1808 1809 void 1810 reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl) 1811 { 1812 static Boolean reloc_title = TRUE; 1813 1814 /* 1815 * -ztextoff 1816 */ 1817 if (ofl->ofl_flags1 & FLG_OF1_TEXTOFF) 1818 return; 1819 1820 /* 1821 * Only give relocation errors against loadable read-only segments. 1822 */ 1823 if ((orsp->rel_rtype == M_R_REGISTER) || (!osp) || 1824 (osp->os_sgdesc->sg_phdr.p_type != PT_LOAD) || 1825 (osp->os_sgdesc->sg_phdr.p_flags & PF_W)) 1826 return; 1827 1828 /* 1829 * If we are in -ztextwarn mode, it's a silent error if a relocation is 1830 * due to a 'WEAK REFERENCE'. This is because if the symbol is not 1831 * provided at run-time we will not perform a text-relocation. 1832 */ 1833 if (((ofl->ofl_flags & FLG_OF_PURETXT) == 0) && 1834 (ELF_ST_BIND(orsp->rel_sym->sd_sym->st_info) == STB_WEAK) && 1835 (orsp->rel_sym->sd_shndx == SHN_UNDEF)) 1836 return; 1837 1838 if (reloc_title) { 1839 /* 1840 * If building with '-ztext' then emit a fatal error. If 1841 * building a executable then only emit a 'warning'. 1842 */ 1843 if (ofl->ofl_flags & FLG_OF_PURETXT) 1844 reloc_remain_title(0); 1845 else 1846 reloc_remain_title(1); 1847 reloc_title = FALSE; 1848 } 1849 1850 eprintf(ERR_NONE, MSG_INTL(MSG_REL_REMAIN_2), demangle(orsp->rel_sname), 1851 EC_OFF(orsp->rel_roffset), orsp->rel_isdesc->is_file->ifl_name); 1852 } 1853 1854 /* 1855 * The following functions are called from 1856 * machine functions defined in {sparc,i386,sparcv9}/machrel.c 1857 */ 1858 1859 /* 1860 * Move Section related function 1861 */ 1862 static uintptr_t 1863 newroffset_for_move(Sym_desc *symd, 1864 Move *mventry, Xword offset1, Xword *offset2) 1865 { 1866 Psym_info *psym = symd->sd_psyminfo; 1867 Mv_itm *itm; 1868 Listnode *lnp1; 1869 int found = 0; 1870 1871 /* 1872 * Search for matching move entry 1873 */ 1874 found = 0; 1875 for (LIST_TRAVERSE(&psym->psym_mvs, lnp1, itm)) { 1876 if (itm->mv_ientry == mventry) { 1877 found = 1; 1878 break; 1879 } 1880 } 1881 if (found == 0) { 1882 /* 1883 * This should never happen. 1884 */ 1885 return (S_ERROR); 1886 } 1887 1888 /* 1889 * Update r_offset 1890 */ 1891 *offset2 = (Xword)((itm->mv_oidx - 1)*sizeof (Move) + 1892 offset1 % sizeof (Move)); 1893 return (1); 1894 } 1895 1896 void 1897 adj_movereloc(Ofl_desc *ofl, Rel_desc *arsp) 1898 { 1899 Move *move = arsp->rel_move->mvd_move; 1900 Sym_desc *psdp = arsp->rel_move->mvd_sym; 1901 Xword newoffset; 1902 1903 if (arsp->rel_flags & FLG_REL_MOVETAB) { 1904 /* 1905 * We are relocating the move table itself. 1906 */ 1907 (void) newroffset_for_move(psdp, move, arsp->rel_roffset, 1908 &newoffset); 1909 DBG_CALL(Dbg_move_adjmovereloc(arsp->rel_roffset, newoffset, 1910 psdp->sd_name)); 1911 arsp->rel_roffset = newoffset; 1912 } else { 1913 /* 1914 * We are expanding the partial symbol. So we are generating 1915 * the relocation entry relocating the expanded partial symbol. 1916 */ 1917 arsp->rel_roffset += 1918 psdp->sd_sym->st_value - 1919 ofl->ofl_issunwdata1->is_osdesc->os_shdr->sh_addr; 1920 DBG_CALL(Dbg_move_adjexpandreloc(arsp->rel_roffset, 1921 psdp->sd_name)); 1922 } 1923 } 1924 1925 /* 1926 * Partially Initialized Symbol Handling routines 1927 * For sparc architecture, the second argument is reld->rel_raddend. 1928 * For i386 acrchitecure, the second argument is the value stored 1929 * at the relocation target address. 1930 */ 1931 Sym_desc * 1932 am_I_partial(Rel_desc *reld, Xword val) 1933 { 1934 Ifl_desc * ifile = reld->rel_sym->sd_isc->is_file; 1935 int nlocs = ifile->ifl_locscnt, i; 1936 1937 for (i = 1; i < nlocs; i++) { 1938 Sym * osym; 1939 Sym_desc * symd = ifile->ifl_oldndx[i]; 1940 1941 if ((osym = symd->sd_osym) == 0) 1942 continue; 1943 if ((symd->sd_flags & FLG_SY_PAREXPN) == 0) 1944 continue; 1945 if ((osym->st_value <= val) && 1946 (osym->st_value + osym->st_size > val)) 1947 return (symd); 1948 } 1949 return ((Sym_desc *) 0); 1950 } 1951 1952 /* 1953 * Because of the combinations of 32-bit lib providing 64-bit support, and 1954 * visa-versa, the use of krtld's dorelocs can result in differing message 1955 * requirements that make msg.c/msg.h creation and chkmsg "interesting". 1956 * Thus the actual message files contain a couple of entries to satisfy 1957 * each architectures build. Here we add dummy calls to quieten chkmsg. 1958 * 1959 * chkmsg: MSG_INTL(MSG_REL_NOFIT) 1960 * chkmsg: MSG_INTL(MSG_REL_NONALIGN) 1961 */ 1962