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