1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * set-up for relocations 33 */ 34 #include <string.h> 35 #include <stdio.h> 36 #include <alloca.h> 37 #include <reloc.h> 38 #include <debug.h> 39 #include "msg.h" 40 #include "_libld.h" 41 42 /* 43 * Structure to hold copy relocation items. 44 */ 45 typedef struct copy_rel { 46 Sym_desc * copyrel_symd; /* symbol descriptor to be copied */ 47 Addr copyrel_stval; /* Original symbol value */ 48 } Copy_rel; 49 50 /* 51 * For each copy relocation symbol, determine if the symbol is: 52 * 1) to be *disp* relocated at runtime 53 * 2) a reference symbol for *disp* relocation 54 * 3) possibly *disp* relocated at ld time. 55 * 56 * The first and the second are serious errors. 57 */ 58 static void 59 is_disp_copied(Ofl_desc *ofl, Copy_rel *cpy) 60 { 61 Ifl_desc *ifl = cpy->copyrel_symd->sd_file; 62 Sym_desc *sdp = cpy->copyrel_symd; 63 Is_desc *irel; 64 Addr symaddr = cpy->copyrel_stval; 65 Listnode *lnp1; 66 67 /* 68 * This symbol may not be *disp* relocated at run time, but could 69 * already have been *disp* relocated when the shared object was 70 * created. Warn the user. 71 */ 72 if ((ifl->ifl_flags & FLG_IF_DISPDONE) && 73 (ofl->ofl_flags & FLG_OF_VERBOSE)) 74 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL2), 75 conv_reloc_type(ifl->ifl_ehdr->e_machine, M_R_COPY, 0), 76 ifl->ifl_name, demangle(sdp->sd_name)); 77 78 if ((ifl->ifl_flags & FLG_IF_DISPPEND) == 0) 79 return; 80 81 /* 82 * Traverse the input relocation sections. 83 */ 84 for (LIST_TRAVERSE(&ifl->ifl_relsect, lnp1, irel)) { 85 Sym_desc *rsdp; 86 Is_desc *trel; 87 Rel *rend, *reloc; 88 Xword rsize, entsize; 89 90 trel = ifl->ifl_isdesc[irel->is_shdr->sh_info]; 91 rsize = irel->is_shdr->sh_size; 92 entsize = irel->is_shdr->sh_entsize; 93 reloc = (Rel *)irel->is_indata->d_buf; 94 95 /* 96 * Decide entry size 97 */ 98 if ((entsize == 0) || (entsize > rsize)) { 99 if (irel->is_shdr->sh_type == SHT_RELA) 100 entsize = sizeof (Rela); 101 else 102 entsize = sizeof (Rel); 103 } 104 105 /* 106 * Traverse the relocation entries. 107 */ 108 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize); 109 reloc < rend; 110 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) { 111 const char *str; 112 Word rstndx; 113 114 if (IS_PC_RELATIVE(ELF_R_TYPE(reloc->r_info)) == 0) 115 continue; 116 117 /* 118 * First, check if this symbol is reference symbol 119 * for this relocation entry. 120 */ 121 rstndx = (Word) ELF_R_SYM(reloc->r_info); 122 rsdp = ifl->ifl_oldndx[rstndx]; 123 if (rsdp == sdp) { 124 if ((str = demangle(rsdp->sd_name)) != 125 rsdp->sd_name) { 126 char *_str = alloca(strlen(str) + 1); 127 (void) strcpy(_str, str); 128 str = (const char *)_str; 129 } 130 eprintf(ofl->ofl_lml, 131 ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1), 132 conv_reloc_type(ifl->ifl_ehdr->e_machine, 133 (uint_t)ELF_R_TYPE(reloc->r_info), 0), 134 ifl->ifl_name, str, 135 MSG_INTL(MSG_STR_UNKNOWN), 136 EC_XWORD(reloc->r_offset), 137 demangle(sdp->sd_name)); 138 } 139 140 /* 141 * Then check if this relocation entry is relocating 142 * this symbol. 143 */ 144 if ((sdp->sd_isc != trel) || 145 (reloc->r_offset < symaddr) || 146 (reloc->r_offset >= 147 (symaddr + sdp->sd_sym->st_size))) 148 continue; 149 150 /* 151 * This symbol is truely *disp* relocated, so should 152 * really be fixed by user. 153 */ 154 if ((str = demangle(sdp->sd_name)) != sdp->sd_name) { 155 char *_str = alloca(strlen(str) + 1); 156 (void) strcpy(_str, str); 157 str = (const char *)_str; 158 } 159 eprintf(ofl->ofl_lml, ERR_WARNING, 160 MSG_INTL(MSG_REL_DISPREL1), 161 conv_reloc_type(ifl->ifl_ehdr->e_machine, 162 (uint_t)ELF_R_TYPE(reloc->r_info), 0), 163 ifl->ifl_name, 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 symbol. 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 * If the reference symbol is local, and the target isn't a 261 * data element, then no copy relocations can occur to either 262 * symbol. Note, this catches pc-relative relocations against 263 * the _GLOBAL_OFFSET_TABLE_, which is effectively treated as 264 * a local symbol. 265 */ 266 if ((rlocal == TRUE) && (ttype != STT_OBJECT) && 267 (ttype != STT_SECTION)) 268 return (tsdp); 269 270 /* 271 * Finally, one of the symbols must reference a data element. 272 */ 273 if ((rtype != STT_OBJECT) && (rtype != STT_SECTION) && 274 (ttype != STT_OBJECT) && (ttype != STT_SECTION)) 275 return (tsdp); 276 } 277 278 /* 279 * We have two global symbols, at least one of which is a data item. 280 * The last case where a displacement relocation can be ignored, is 281 * if the reference symbol is included in the target symbol. 282 */ 283 value = rsym->st_value; 284 value += rld->rel_raddend; 285 286 if ((rld->rel_roffset >= value) && 287 (rld->rel_roffset < (value + rsym->st_size))) 288 return (tsdp); 289 290 /* 291 * We have a displacement relocation that could be compromised by a 292 * copy relocation of one of the associated data items. 293 */ 294 rld->rel_flags |= FLG_REL_DISP; 295 return (tsdp); 296 } 297 298 void 299 ld_disp_errmsg(const char *msg, Rel_desc *rsp, Ofl_desc *ofl) 300 { 301 Sym_desc *sdp; 302 const char *str; 303 Ifl_desc *ifl = rsp->rel_isdesc->is_file; 304 305 if ((sdp = disp_scansyms(ifl, rsp, 0, 1, ofl)) != 0) 306 str = demangle(sdp->sd_name); 307 else 308 str = MSG_INTL(MSG_STR_UNKNOWN); 309 310 eprintf(ofl->ofl_lml, ERR_WARNING, msg, 311 conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype, 0), 312 ifl->ifl_name, rsp->rel_sname, str, EC_OFF(rsp->rel_roffset)); 313 } 314 315 /* 316 * qsort(3C) comparison routine used for the disp_sortsyms(). 317 */ 318 static int 319 disp_qsort(const void * s1, const void * s2) 320 { 321 Ssv_desc *ssvp1 = ((Ssv_desc *)s1); 322 Ssv_desc *ssvp2 = ((Ssv_desc *)s2); 323 Addr val1 = ssvp1->ssv_value; 324 Addr val2 = ssvp2->ssv_value; 325 326 if (val1 > val2) 327 return (1); 328 if (val1 < val2) 329 return (-1); 330 return (0); 331 } 332 333 /* 334 * Determine whether a displacement relocation is between a local and global 335 * symbol pair. One symbol is used to perform the relocation, and the other 336 * is the destination offset of the relocation. 337 */ 338 static uintptr_t 339 disp_inspect(Ofl_desc *ofl, Rel_desc *rld, Boolean rlocal) 340 { 341 Is_desc *isp = rld->rel_isdesc; 342 Ifl_desc *ifl = rld->rel_isdesc->is_file; 343 344 /* 345 * If the input files symbols haven't been sorted yet, do so. 346 */ 347 if (ifl->ifl_sortsyms == 0) { 348 Word ondx, nndx; 349 350 if ((ifl->ifl_sortsyms = libld_malloc((ifl->ifl_symscnt + 1) * 351 sizeof (Ssv_desc))) == 0) 352 return (S_ERROR); 353 354 for (ondx = 0, nndx = 0; ondx < ifl->ifl_symscnt; ondx++) { 355 Sym_desc *sdp; 356 Addr value; 357 358 /* 359 * As symbol resolution has already occurred, various 360 * symbols from this object may have been satisfied 361 * from other objects. Only select symbols from this 362 * object. For the displacement test, we only really 363 * need to observe data definitions, however, later as 364 * part of providing warning disgnostics, relating the 365 * relocation offset to a symbol is desirable. Thus, 366 * collect all symbols that define a memory area. 367 */ 368 if (((sdp = ifl->ifl_oldndx[ondx]) == 0) || 369 (sdp->sd_sym->st_shndx == SHN_UNDEF) || 370 (sdp->sd_sym->st_shndx >= SHN_LORESERVE) || 371 (sdp->sd_ref != REF_REL_NEED) || 372 (sdp->sd_file != ifl) || 373 (sdp->sd_sym->st_size == 0)) 374 continue; 375 376 /* 377 * As a further optimization for later checking, mark 378 * this section if this a global data definition. 379 */ 380 if (sdp->sd_isc && (ondx >= ifl->ifl_locscnt)) 381 sdp->sd_isc->is_flags |= FLG_IS_GDATADEF; 382 383 /* 384 * Capture the symbol. Within relocatable objects, a 385 * symbols value is its offset within its associated 386 * section. Add the section offset to this value to 387 * uniquify the symbol. 388 */ 389 value = sdp->sd_sym->st_value; 390 if (sdp->sd_isc && sdp->sd_isc->is_shdr) 391 value += sdp->sd_isc->is_shdr->sh_offset; 392 393 ifl->ifl_sortsyms[nndx].ssv_value = value; 394 ifl->ifl_sortsyms[nndx].ssv_sdp = sdp; 395 nndx++; 396 } 397 398 /* 399 * Sort the list based on the symbols value (address). 400 */ 401 if ((ifl->ifl_sortcnt = nndx) != 0) 402 qsort(ifl->ifl_sortsyms, nndx, sizeof (Ssv_desc), 403 &disp_qsort); 404 } 405 406 /* 407 * If the reference symbol is local, and the section being relocated 408 * contains no global definitions, neither can be the target of a copy 409 * relocation. 410 */ 411 if ((rlocal == FALSE) && ((isp->is_flags & FLG_IS_GDATADEF) == 0)) 412 return (1); 413 414 /* 415 * Otherwise determine whether this relocation symbol and its offset 416 * could be candidates for a copy relocation. 417 */ 418 if (ifl->ifl_sortcnt) 419 (void) disp_scansyms(ifl, rld, rlocal, 0, ofl); 420 return (1); 421 } 422 423 /* 424 * Add an active relocation record. 425 */ 426 uintptr_t 427 ld_add_actrel(Word flags, Rel_desc *rsp, Ofl_desc *ofl) 428 { 429 Rel_desc *arsp; 430 Rel_cache *rcp; 431 432 /* 433 * If no relocation cache structures are available, allocate a new 434 * one and link it into the bucket list. 435 */ 436 if ((ofl->ofl_actrels.tail == 0) || 437 ((rcp = (Rel_cache *)ofl->ofl_actrels.tail->data) == 0) || 438 ((arsp = rcp->rc_free) == rcp->rc_end)) { 439 static size_t nextsize = 0; 440 size_t size; 441 442 /* 443 * Typically, when generating an executable or shared object 444 * there will be an active relocation for every input 445 * relocation. 446 */ 447 if (nextsize == 0) { 448 if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) { 449 if ((size = ofl->ofl_relocincnt) == 0) 450 size = REL_LAIDESCNO; 451 if (size > REL_HAIDESCNO) 452 nextsize = REL_HAIDESCNO; 453 else 454 nextsize = REL_LAIDESCNO; 455 } else 456 nextsize = size = REL_HAIDESCNO; 457 } else 458 size = nextsize; 459 460 size = size * sizeof (Rel_desc); 461 462 if (((rcp = libld_malloc(sizeof (Rel_cache) + size)) == 0) || 463 (list_appendc(&ofl->ofl_actrels, rcp) == 0)) 464 return (S_ERROR); 465 466 /* LINTED */ 467 rcp->rc_free = arsp = (Rel_desc *)(rcp + 1); 468 /* LINTED */ 469 rcp->rc_end = (Rel_desc *)((char *)rcp->rc_free + size); 470 } 471 472 *arsp = *rsp; 473 arsp->rel_flags |= flags; 474 475 rcp->rc_free++; 476 ofl->ofl_actrelscnt++; 477 478 /* 479 * Any GOT relocation reference requires the creation of a .got table. 480 * Most references to a .got require a .got entry, which is accounted 481 * for with the ofl_gotcnt counter. However, some references are 482 * relative to the .got table, but require no .got entry. This test 483 * insures a .got is created regardless of the type of reference. 484 */ 485 if (IS_GOT_REQUIRED(arsp->rel_rtype)) 486 ofl->ofl_flags |= FLG_OF_BLDGOT; 487 488 /* 489 * If this is a displacement relocation generate a warning. 490 */ 491 if (arsp->rel_flags & FLG_REL_DISP) { 492 ofl->ofl_dtflags_1 |= DF_1_DISPRELDNE; 493 494 if (ofl->ofl_flags & FLG_OF_VERBOSE) 495 ld_disp_errmsg(MSG_INTL(MSG_REL_DISPREL3), arsp, ofl); 496 } 497 498 DBG_CALL(Dbg_reloc_ars_entry(ofl->ofl_lml, ELF_DBG_LD, 499 arsp->rel_isdesc->is_shdr->sh_type, M_MACH, arsp)); 500 return (1); 501 } 502 503 uintptr_t 504 ld_reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl) 505 { 506 Sym_desc *sdp; 507 Word flags = ofl->ofl_flags; 508 Gotndx *gnp; 509 510 sdp = rsp->rel_sym; 511 512 /* 513 * If this is the first time we've seen this symbol in a GOT 514 * relocation we need to assign it a GOT token. Once we've got 515 * all of the GOT's assigned we can assign the actual indexes. 516 */ 517 if ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_GENERIC, 518 ofl, rsp)) == 0) { 519 Word rtype = rsp->rel_rtype; 520 521 if (ld_assign_got_ndx(&(sdp->sd_GOTndxs), 0, GOT_REF_GENERIC, 522 ofl, rsp, sdp) == S_ERROR) 523 return (S_ERROR); 524 525 /* 526 * Now we initialize the GOT table entry. 527 * 528 * Pseudo code to describe the the decisions below: 529 * 530 * If (local) 531 * then 532 * enter symbol value in GOT table entry 533 * if (Shared Object) 534 * then 535 * create Relative relocation against symbol 536 * fi 537 * else 538 * clear GOT table entry 539 * create a GLOB_DAT relocation against symbol 540 * fi 541 */ 542 if (local == TRUE) { 543 if (flags & FLG_OF_SHAROBJ) { 544 if (ld_add_actrel((FLG_REL_GOT | FLG_REL_GOTCL), 545 rsp, ofl) == S_ERROR) 546 return (S_ERROR); 547 548 /* 549 * Add a RELATIVE relocation if this is 550 * anything but a ABS symbol. 551 */ 552 if ((((sdp->sd_flags & FLG_SY_SPECSEC) == 0) || 553 (sdp->sd_sym->st_shndx != SHN_ABS)) || 554 (sdp->sd_aux && sdp->sd_aux->sa_symspec)) { 555 rsp->rel_rtype = M_R_RELATIVE; 556 if (ld_add_outrel((FLG_REL_GOT | 557 FLG_REL_ADVAL), rsp, 558 ofl) == S_ERROR) 559 return (S_ERROR); 560 rsp->rel_rtype = rtype; 561 } 562 } else { 563 if (ld_add_actrel(FLG_REL_GOT, rsp, 564 ofl) == S_ERROR) 565 return (S_ERROR); 566 } 567 } else { 568 rsp->rel_rtype = M_R_GLOB_DAT; 569 if (ld_add_outrel(FLG_REL_GOT, rsp, ofl) == S_ERROR) 570 return (S_ERROR); 571 rsp->rel_rtype = rtype; 572 } 573 } else { 574 if (ld_assign_got_ndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_GENERIC, 575 ofl, rsp, sdp) == S_ERROR) 576 return (S_ERROR); 577 } 578 579 /* 580 * Perform relocation to GOT table entry. 581 */ 582 return (ld_add_actrel(NULL, rsp, ofl)); 583 } 584 585 586 /* 587 * Perform relocations for PLT's 588 */ 589 uintptr_t 590 ld_reloc_plt(Rel_desc *rsp, Ofl_desc *ofl) 591 { 592 Sym_desc *sdp = rsp->rel_sym; 593 594 #if defined(__i386) || defined(__amd64) 595 #if defined(_ELF64) 596 /* 597 * AMD64 TLS code sequences do not use a unique TLS relocation to 598 * reference the __tls_get_addr() function call. 599 */ 600 if ((ofl->ofl_flags & FLG_OF_EXEC) && 601 (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_U)) == 0)) { 602 return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl)); 603 } 604 #else 605 /* 606 * GNUC IA32 TLS code sequences do not use a unique TLS relocation to 607 * reference the ___tls_get_addr() function call. 608 */ 609 if ((ofl->ofl_flags & FLG_OF_EXEC) && 610 (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_UU)) == 0)) { 611 return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl)); 612 } 613 #endif 614 #endif /* __i386 && __amd64 */ 615 616 /* 617 * if (not PLT yet assigned) 618 * then 619 * assign PLT index to symbol 620 * build output JMP_SLOT relocation 621 * fi 622 */ 623 if (sdp->sd_aux->sa_PLTndx == 0) { 624 Word ortype = rsp->rel_rtype; 625 626 ld_assign_plt_ndx(sdp, ofl); 627 628 /* 629 * If this symbol is binding to a LAZYLOADED object then 630 * set the LAZYLD symbol flag. 631 */ 632 if ((sdp->sd_aux->sa_bindto && 633 (sdp->sd_aux->sa_bindto->ifl_flags & FLG_IF_LAZYLD)) || 634 (sdp->sd_file && 635 (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD))) 636 sdp->sd_flags |= FLG_SY_LAZYLD; 637 638 rsp->rel_rtype = M_R_JMP_SLOT; 639 if (ld_add_outrel(FLG_REL_PLT, rsp, ofl) == S_ERROR) 640 return (S_ERROR); 641 rsp->rel_rtype = ortype; 642 } 643 644 /* 645 * Perform relocation to PLT table entry. 646 */ 647 if ((ofl->ofl_flags & FLG_OF_SHAROBJ) && 648 IS_ADD_RELATIVE(rsp->rel_rtype)) { 649 Word ortype = rsp->rel_rtype; 650 651 rsp->rel_rtype = M_R_RELATIVE; 652 if (ld_add_outrel(FLG_REL_ADVAL, rsp, ofl) == S_ERROR) 653 return (S_ERROR); 654 rsp->rel_rtype = ortype; 655 return (1); 656 } else 657 return (ld_add_actrel(NULL, rsp, ofl)); 658 } 659 660 /* 661 * process GLOBAL undefined and ref_dyn_need symbols. 662 */ 663 static uintptr_t 664 reloc_exec(Rel_desc *rsp, Ofl_desc *ofl) 665 { 666 Sym_desc *_sdp, *sdp = rsp->rel_sym; 667 Sym_aux *sap = sdp->sd_aux; 668 Sym *sym = sdp->sd_sym; 669 Addr stval; 670 671 /* 672 * Reference is to a function so simply create a plt entry for it. 673 */ 674 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) 675 return (ld_reloc_plt(rsp, ofl)); 676 677 /* 678 * Catch absolutes - these may cause a text relocation. 679 */ 680 if ((sdp->sd_flags & FLG_SY_SPECSEC) && (sym->st_shndx == SHN_ABS)) { 681 if ((ofl->ofl_flags1 & FLG_OF1_ABSEXEC) == 0) 682 return (ld_add_outrel(NULL, rsp, ofl)); 683 684 /* 685 * If -zabsexec is set then promote the ABSOLUTE symbol to 686 * current the current object and perform the relocation now. 687 */ 688 sdp->sd_ref = REF_REL_NEED; 689 return (ld_add_actrel(NULL, rsp, ofl)); 690 } 691 692 /* 693 * If the relocation is against a writable section simply compute the 694 * necessary output relocation. As an optimization, if the symbol has 695 * already been transformed into a copy relocation then we can perform 696 * the relocation directly (copy relocations should only be generated 697 * for references from the text segment and these relocations are 698 * normally carried out before we get to the data segment relocations). 699 */ 700 if ((ELF_ST_TYPE(sym->st_info) == STT_OBJECT) && 701 (rsp->rel_osdesc->os_shdr->sh_flags & SHF_WRITE)) { 702 if (sdp->sd_flags & FLG_SY_MVTOCOMM) 703 return (ld_add_actrel(NULL, rsp, ofl)); 704 else 705 return (ld_add_outrel(NULL, rsp, ofl)); 706 } 707 708 /* 709 * If the reference isn't to an object (normally because a .type 710 * directive hasn't defined in some assembler source), then simply apply 711 * a generic relocation (this has a tendency to result in text 712 * relocations). 713 */ 714 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) { 715 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPSYM), 716 conv_sym_info_type(sdp->sd_file->ifl_ehdr->e_machine, 717 ELF_ST_TYPE(sym->st_info), 0), 718 rsp->rel_isdesc->is_file->ifl_name, 719 demangle(rsp->rel_sname), sdp->sd_file->ifl_name); 720 return (ld_add_outrel(NULL, rsp, ofl)); 721 } 722 723 /* 724 * Prepare for generating a copy relocation. 725 * 726 * If this symbol is one of an alias pair, we need to insure both 727 * symbols become part of the output (the strong symbol will be used to 728 * maintain the symbols state). And, if we did raise the precedence of 729 * a symbol we need to check and see if this is a weak symbol. If it is 730 * we want to use it's strong counter part. 731 * 732 * The results of this logic should be: 733 * rel_usym: assigned to strong 734 * rel_sym: assigned to symbol to perform 735 * copy_reloc against (weak or strong). 736 */ 737 if (sap->sa_linkndx) { 738 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx]; 739 740 if (_sdp->sd_ref < sdp->sd_ref) { 741 _sdp->sd_ref = sdp->sd_ref; 742 _sdp->sd_flags |= FLG_SY_REFRSD; 743 744 /* 745 * As we're going to replicate a symbol from a shared 746 * object, retain its correct binding status. 747 */ 748 if (ELF_ST_BIND(_sdp->sd_sym->st_info) == STB_GLOBAL) 749 _sdp->sd_flags |= FLG_SY_GLOBREF; 750 751 } else if (_sdp->sd_ref > sdp->sd_ref) { 752 sdp->sd_ref = _sdp->sd_ref; 753 sdp->sd_flags |= FLG_SY_REFRSD; 754 755 /* 756 * As we're going to replicate a symbol from a shared 757 * object, retain its correct binding status. 758 */ 759 if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) 760 sdp->sd_flags |= FLG_SY_GLOBREF; 761 } 762 763 /* 764 * If this is a weak symbol then we want to move the strong 765 * symbol into local .bss. If there is a copy_reloc to be 766 * performed, that should still occur against the WEAK symbol. 767 */ 768 if ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) || 769 (sdp->sd_flags & FLG_SY_WEAKDEF)) 770 rsp->rel_usym = _sdp; 771 } else 772 _sdp = 0; 773 774 /* 775 * If the reference is to an object then allocate space for the object 776 * within the executables .bss. Relocations will now be performed from 777 * this new location. If the original shared objects data is 778 * initialized, then generate a copy relocation that will copy the data 779 * to the executables .bss at runtime. 780 */ 781 if (!(rsp->rel_usym->sd_flags & FLG_SY_MVTOCOMM)) { 782 Word rtype = rsp->rel_rtype; 783 Copy_rel *cpy_rel; 784 785 /* 786 * Indicate that the symbol(s) against which we're relocating 787 * have been moved to the executables common. Also, insure that 788 * the symbol(s) remain marked as global, as the shared object 789 * from which they are copied must be able to relocate to the 790 * new common location within the executable. 791 * 792 * Note that even though a new symbol has been generated in the 793 * output files' .bss, the symbol must remain REF_DYN_NEED and 794 * not be promoted to REF_REL_NEED. sym_validate() still needs 795 * to carry out a number of checks against the symbols binding 796 * that are triggered by the REF_DYN_NEED state. 797 */ 798 sdp->sd_flags |= FLG_SY_MVTOCOMM; 799 sdp->sd_flags1 |= FLG_SY1_GLOB; 800 sdp->sd_flags1 &= ~FLG_SY1_LOCL; 801 sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY; 802 if (_sdp) { 803 _sdp->sd_flags |= FLG_SY_MVTOCOMM; 804 _sdp->sd_flags1 |= FLG_SY1_GLOB; 805 _sdp->sd_flags1 &= ~FLG_SY1_LOCL; 806 _sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY; 807 808 /* 809 * Make sure the symbol has a reference in case of any 810 * error diagnostics against it (perhaps this belongs 811 * to a version that isn't allowable for this build). 812 * The resulting diagnostic (see sym_undef_entry()) 813 * might seem a little bogus, as the symbol hasn't 814 * really been referenced by this file, but has been 815 * promoted as a consequence of its alias reference. 816 */ 817 if (!(_sdp->sd_aux->sa_rfile)) 818 _sdp->sd_aux->sa_rfile = sdp->sd_aux->sa_rfile; 819 } 820 821 /* 822 * Assign the symbol to the bss and insure sufficient alignment 823 * (we don't know the real alignment so we have to make the 824 * worst case guess). 825 */ 826 _sdp = rsp->rel_usym; 827 stval = _sdp->sd_sym->st_value; 828 if (ld_sym_copy(_sdp) == S_ERROR) 829 return (S_ERROR); 830 _sdp->sd_shndx = _sdp->sd_sym->st_shndx = SHN_COMMON; 831 _sdp->sd_flags |= FLG_SY_SPECSEC; 832 _sdp->sd_sym->st_value = 833 (_sdp->sd_sym->st_size < (M_WORD_ALIGN * 2)) ? 834 M_WORD_ALIGN : M_WORD_ALIGN * 2; 835 836 /* 837 * Whether or not the symbol references initialized 838 * data we generate a copy relocation - this differs 839 * from the past where we would not create the COPY_RELOC 840 * if we were binding against .bss. This is done 841 * for *two* reasons. 842 * 843 * o If the symbol in the shared object changes to 844 * a initialized data - we need the COPY to pick it 845 * up. 846 * o without the COPY RELOC we can't tell that the 847 * symbol from the COPY'd object has been moved 848 * and all bindings to it should bind here. 849 */ 850 851 /* 852 * Keep this symbol in the copy relocation list 853 * to check the validity later. 854 */ 855 if ((cpy_rel = libld_malloc(sizeof (Copy_rel))) == 0) 856 return (S_ERROR); 857 cpy_rel->copyrel_symd = _sdp; 858 cpy_rel->copyrel_stval = stval; 859 if (list_appendc(&ofl->ofl_copyrels, cpy_rel) == 0) 860 return (S_ERROR); 861 862 rsp->rel_rtype = M_R_COPY; 863 if (ld_add_outrel(FLG_REL_BSS, rsp, ofl) == S_ERROR) 864 return (S_ERROR); 865 rsp->rel_rtype = rtype; 866 867 /* 868 * If this symbol is a protected symbol, warn it. 869 */ 870 if (_sdp->sd_flags & FLG_SY_PROT) 871 eprintf(ofl->ofl_lml, ERR_WARNING, 872 MSG_INTL(MSG_REL_COPY), 873 conv_reloc_type(_sdp->sd_file->ifl_ehdr->e_machine, 874 M_R_COPY, 0), _sdp->sd_file->ifl_name, _sdp->sd_name); 875 DBG_CALL(Dbg_syms_reloc(ofl, sdp)); 876 } 877 return (ld_add_actrel(NULL, rsp, ofl)); 878 } 879 880 /* 881 * All relocations should have been handled by the other routines. This 882 * routine is here as a catch all, if we do enter it we've goofed - but 883 * we'll try and to the best we can. 884 */ 885 static uintptr_t 886 reloc_generic(Rel_desc *rsp, Ofl_desc *ofl) 887 { 888 Ifl_desc *ifl = rsp->rel_isdesc->is_file; 889 890 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPREL), 891 conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype, 0), 892 ifl->ifl_name, demangle(rsp->rel_sname)); 893 894 /* 895 * If building a shared object then put the relocation off 896 * until runtime. 897 */ 898 if (ofl->ofl_flags & FLG_OF_SHAROBJ) 899 return (ld_add_outrel(NULL, rsp, ofl)); 900 901 /* 902 * Otherwise process relocation now. 903 */ 904 return (ld_add_actrel(NULL, rsp, ofl)); 905 } 906 907 /* 908 * Process relocations when building a relocatable object. Typically, there 909 * aren't many relocations that can be caught at this point, most are simply 910 * passed through to the output relocatable object. 911 */ 912 static uintptr_t 913 reloc_relobj(Boolean local, Rel_desc *rsp, Ofl_desc *ofl) 914 { 915 Word rtype = rsp->rel_rtype; 916 Sym_desc *sdp = rsp->rel_sym; 917 Is_desc *isp = rsp->rel_isdesc; 918 Word oflags = NULL; 919 920 /* 921 * Determine if we can do any relocations at this point. We can if: 922 * 923 * this is local_symbol and a non-GOT relocation, and 924 * the relocation is pc-relative, and 925 * the relocation is against a symbol in same section 926 */ 927 if (local && !IS_GOT_RELATIVE(rtype) && !IS_GOT_BASED(rtype) && 928 !IS_GOT_PC(rtype) && IS_PC_RELATIVE(rtype) && 929 ((sdp->sd_isc) && (sdp->sd_isc->is_osdesc == isp->is_osdesc))) 930 return (ld_add_actrel(NULL, rsp, ofl)); 931 932 /* 933 * If -zredlocsym is in effect, translate all local symbol relocations 934 * to be against against section symbols, since section symbols are 935 * the only symbols which will be added to the .symtab. 936 */ 937 if (local && (((ofl->ofl_flags1 & FLG_OF1_REDLSYM) && 938 (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL)) || 939 ((sdp->sd_flags1 & FLG_SY1_ELIM) && 940 (ofl->ofl_flags & FLG_OF_PROCRED)))) { 941 /* 942 * But if this is PIC code, don't allow it for now. 943 */ 944 if (IS_GOT_RELATIVE(rsp->rel_rtype)) { 945 Ifl_desc *ifl = rsp->rel_isdesc->is_file; 946 947 eprintf(ofl->ofl_lml, ERR_FATAL, 948 MSG_INTL(MSG_REL_PICREDLOC), 949 demangle(rsp->rel_sname), ifl->ifl_name, 950 conv_reloc_type(ifl->ifl_ehdr->e_machine, 951 rsp->rel_rtype, 0)); 952 return (S_ERROR); 953 } 954 955 /* 956 * Indicate that this relocation should be processed the same 957 * as a section symbol. For SPARC and AMD64 (Rela), indicate 958 * that the addend also needs to be applied to this relocation. 959 */ 960 #if (defined(__i386) || defined(__amd64)) && !defined(_ELF64) 961 oflags = FLG_REL_SCNNDX; 962 #else 963 oflags = FLG_REL_SCNNDX | FLG_REL_ADVAL; 964 #endif 965 } 966 967 #if (defined(__i386) || defined(__amd64)) && !defined(_ELF64) 968 /* 969 * Intel (Rel) relocations do not contain an addend. Any addend is 970 * contained within the file at the location identified by the 971 * relocation offset. Therefore, if we're processing a section symbol, 972 * or a -zredlocsym relocation (that basically transforms a local symbol 973 * reference into a section reference), perform an active relocation to 974 * propagate any addend. 975 */ 976 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) || 977 (oflags == FLG_REL_SCNNDX)) 978 if (ld_add_actrel(NULL, rsp, ofl) == S_ERROR) 979 return (S_ERROR); 980 #endif 981 return (ld_add_outrel(oflags, rsp, ofl)); 982 } 983 984 /* 985 * Perform any generic TLS validations before passing control to machine 986 * specific routines. At this point we know we are dealing with an executable 987 * or shared object - relocatable objects have already been processed. 988 */ 989 static uintptr_t 990 reloc_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl) 991 { 992 Word rtype = rsp->rel_rtype, flags = ofl->ofl_flags; 993 Ifl_desc *ifl = rsp->rel_isdesc->is_file; 994 Half mach = ifl->ifl_ehdr->e_machine; 995 Sym_desc *sdp = rsp->rel_sym; 996 unsigned char type; 997 998 /* 999 * All TLS relocations are illegal in a static executable. 1000 */ 1001 if ((flags & (FLG_OF_STATIC | FLG_OF_EXEC)) == 1002 (FLG_OF_STATIC | FLG_OF_EXEC)) { 1003 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT), 1004 conv_reloc_type(mach, rtype, 0), ifl->ifl_name, 1005 demangle(rsp->rel_sname)); 1006 return (S_ERROR); 1007 } 1008 1009 /* 1010 * Any TLS relocation must be against a STT_TLS symbol, all others 1011 * are illegal. 1012 */ 1013 if ((type = ELF_ST_TYPE(sdp->sd_sym->st_info)) != STT_TLS) { 1014 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM), 1015 conv_reloc_type(mach, rtype, 0), ifl->ifl_name, 1016 demangle(rsp->rel_sname), 1017 conv_sym_info_type(mach, type, 0)); 1018 return (S_ERROR); 1019 } 1020 1021 /* 1022 * A dynamic executable can not use the LD or LE reference models to 1023 * reference an external symbol. A shared object can not use the LD 1024 * reference model to reference an external symbol. 1025 */ 1026 if (!local && (IS_TLS_LD(rtype) || 1027 ((flags & FLG_OF_EXEC) && IS_TLS_LE(rtype)))) { 1028 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND), 1029 conv_reloc_type(mach, rtype, 0), ifl->ifl_name, 1030 demangle(rsp->rel_sname), sdp->sd_file->ifl_name); 1031 return (S_ERROR); 1032 } 1033 1034 /* 1035 * The TLS LE model is only allowed for dynamic executables. The TLS IE 1036 * model is allowed for shared objects, but this model has restrictions. 1037 * This model can only be used freely in dependencies that are loaded 1038 * immediately as part of process initialization. However, during the 1039 * initial runtime handshake with libc that establishes the thread 1040 * pointer, a small backup TLS reservation is created. This area can 1041 * be used by objects that are loaded after threads are initialized. 1042 * However, this area is limited in size and may have already been 1043 * used. This area is intended for specialized applications, and does 1044 * not provide the degree of flexibility dynamic TLS can offer. Under 1045 * -z verbose indicate this restriction to the user. 1046 */ 1047 if ((flags & FLG_OF_EXEC) == 0) { 1048 if (IS_TLS_LE(rtype)) { 1049 eprintf(ofl->ofl_lml, ERR_FATAL, 1050 MSG_INTL(MSG_REL_TLSLE), 1051 conv_reloc_type(mach, rtype, 0), ifl->ifl_name, 1052 demangle(rsp->rel_sname)); 1053 return (S_ERROR); 1054 1055 } else if ((IS_TLS_IE(rtype)) && (flags & FLG_OF_VERBOSE)) { 1056 eprintf(ofl->ofl_lml, ERR_WARNING, 1057 MSG_INTL(MSG_REL_TLSIE), 1058 conv_reloc_type(mach, rtype, 0), ifl->ifl_name, 1059 demangle(rsp->rel_sname)); 1060 } 1061 } 1062 1063 return (ld_reloc_TLS(local, rsp, ofl)); 1064 } 1065 1066 uintptr_t 1067 ld_process_sym_reloc(Ofl_desc *ofl, Rel_desc *reld, Rel *reloc, Is_desc *isp, 1068 const char *isname) 1069 { 1070 Word rtype = reld->rel_rtype; 1071 Word flags = ofl->ofl_flags; 1072 Sym_desc *sdp = reld->rel_sym; 1073 Sym_aux *sap; 1074 Boolean local; 1075 1076 DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, M_MACH, M_REL_SHT_TYPE, 1077 (void *)reloc, isname, reld->rel_sname)); 1078 1079 /* 1080 * Indicate this symbol is being used for relocation and therefore must 1081 * have its output address updated accordingly (refer to update_osym()). 1082 */ 1083 sdp->sd_flags |= FLG_SY_UPREQD; 1084 1085 /* 1086 * Indicate the section this symbol is defined in has been referenced, 1087 * therefor it *is not* a candidate for elimination. 1088 */ 1089 if (sdp->sd_isc) { 1090 sdp->sd_isc->is_flags |= FLG_IS_SECTREF; 1091 sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF; 1092 } 1093 1094 reld->rel_usym = sdp; 1095 1096 /* 1097 * Determine if this symbol is actually an alias to another symbol. If 1098 * so, and the alias is not REF_DYN_SEEN, set rel_usym to point to the 1099 * weak symbols strong counter-part. The one exception is if the 1100 * FLG_SY_MVTOCOMM flag is set on the weak symbol. If this is the case, 1101 * the strong is only here because of its promotion, and the weak symbol 1102 * should still be used for the relocation reference (see reloc_exec()). 1103 */ 1104 sap = sdp->sd_aux; 1105 if (sap && sap->sa_linkndx && 1106 ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) || 1107 (sdp->sd_flags & FLG_SY_WEAKDEF)) && 1108 (!(sdp->sd_flags & FLG_SY_MVTOCOMM))) { 1109 Sym_desc * _sdp; 1110 1111 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx]; 1112 if (_sdp->sd_ref != REF_DYN_SEEN) 1113 reld->rel_usym = _sdp; 1114 } 1115 1116 /* 1117 * Determine whether this symbol should be bound locally or not. 1118 * Symbols are bound locally if one of the following is true: 1119 * 1120 * o the symbol is of type STB_LOCAL. 1121 * 1122 * o the output image is not a relocatable object and the relocation 1123 * is relative to the .got. 1124 * 1125 * o the section being relocated is of type SHT_SUNW_dof. These 1126 * sections must be bound to the functions in the containing 1127 * object and can not be interposed upon. 1128 * 1129 * o the symbol has been reduced (scoped to a local or symbolic) and 1130 * reductions are being processed. 1131 * 1132 * o the -Bsymbolic flag is in use when building a shared object, 1133 * and the symbol hasn't explicitly been defined as nodirect. 1134 * 1135 * o an executable (fixed address) is being created, and the symbol 1136 * is defined in the executable. 1137 * 1138 * o the relocation is against a segment which will not be loaded 1139 * into memory. In this case, the relocation must be resolved 1140 * now, as ld.so.1 can not process relocations against unmapped 1141 * segments. 1142 */ 1143 local = FALSE; 1144 if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) { 1145 local = TRUE; 1146 } else if (!(reld->rel_flags & FLG_REL_LOAD)) { 1147 local = TRUE; 1148 } else if (sdp->sd_sym->st_shndx != SHN_UNDEF) { 1149 if (reld->rel_isdesc && 1150 reld->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof) { 1151 local = TRUE; 1152 } else if (!(flags & FLG_OF_RELOBJ) && 1153 (IS_LOCALBND(rtype) || IS_SEG_RELATIVE(rtype))) { 1154 local = TRUE; 1155 } else if (sdp->sd_ref == REF_REL_NEED) { 1156 /* 1157 * Global symbols may have been individually reduced in 1158 * scope. If the whole object is to be self contained, 1159 * such as when generating an executable or a symbolic 1160 * shared object, make sure all relocation symbol 1161 * references (sections too) are treated locally. Note, 1162 * explicit no-direct symbols should not be bound to 1163 * locally. 1164 */ 1165 if ((sdp->sd_flags1 & (FLG_SY1_LOCL | FLG_SY1_PROT))) 1166 local = TRUE; 1167 else if ((flags & FLG_OF_EXEC) || 1168 ((flags & FLG_OF_SYMBOLIC) && 1169 ((sdp->sd_flags1 & FLG_SY1_NDIR) == 0))) 1170 local = TRUE; 1171 } 1172 } 1173 1174 /* 1175 * If this is a PC_RELATIVE relocation, the relocation could be 1176 * compromised if the relocated address is later used as a copy 1177 * relocated symbol (PSARC 1999/636, bugid 4187211). Scan the input 1178 * files symbol table to cross reference this relocation offset. 1179 */ 1180 if ((ofl->ofl_flags & FLG_OF_SHAROBJ) && IS_PC_RELATIVE(rtype) && 1181 (IS_GOT_PC(rtype) == 0) && (IS_PLT(rtype) == 0)) { 1182 if (disp_inspect(ofl, reld, local) == S_ERROR) 1183 return (S_ERROR); 1184 } 1185 1186 /* 1187 * GOT based relocations must bind to the object being built - since 1188 * they are relevant to the current GOT. If not building a relocatable 1189 * object - give a appropriate error message. 1190 */ 1191 if (!local && !(flags & FLG_OF_RELOBJ) && IS_GOT_BASED(rtype)) { 1192 Ifl_desc *ifl = reld->rel_isdesc->is_file; 1193 1194 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED), 1195 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype, 0), 1196 ifl->ifl_name, demangle(sdp->sd_name)); 1197 return (S_ERROR); 1198 } 1199 1200 /* 1201 * TLS symbols can only have TLS relocations. 1202 */ 1203 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_TLS) && 1204 (IS_TLS_INS(rtype) == 0)) { 1205 /* 1206 * The above test is relaxed if the target section is 1207 * non-allocable. 1208 */ 1209 if (reld->rel_osdesc->os_shdr->sh_flags & SHF_ALLOC) { 1210 Ifl_desc *ifl = reld->rel_isdesc->is_file; 1211 1212 eprintf(ofl->ofl_lml, ERR_FATAL, 1213 MSG_INTL(MSG_REL_BADTLS), 1214 conv_reloc_type(ifl->ifl_ehdr->e_machine, 1215 rtype, 0), ifl->ifl_name, demangle(sdp->sd_name)); 1216 return (S_ERROR); 1217 } 1218 } 1219 1220 /* 1221 * Select the relocation to perform. 1222 */ 1223 if (IS_REGISTER(rtype)) 1224 return (ld_reloc_register(reld, isp, ofl)); 1225 1226 if (flags & FLG_OF_RELOBJ) 1227 return (reloc_relobj(local, reld, ofl)); 1228 1229 if (IS_TLS_INS(rtype)) 1230 return (reloc_TLS(local, reld, ofl)); 1231 1232 if (IS_GOT_OPINS(rtype)) 1233 return (ld_reloc_GOTOP(local, reld, ofl)); 1234 1235 if (IS_GOT_RELATIVE(rtype)) 1236 return (ld_reloc_GOT_relative(local, reld, ofl)); 1237 1238 if (local) 1239 return (ld_reloc_local(reld, ofl)); 1240 1241 if ((IS_PLT(rtype)) && ((flags & FLG_OF_BFLAG) == 0)) 1242 return (ld_reloc_plt(reld, ofl)); 1243 1244 if ((sdp->sd_ref == REF_REL_NEED) || 1245 (flags & FLG_OF_BFLAG) || (flags & FLG_OF_SHAROBJ) || 1246 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_NOTYPE)) 1247 return (ld_add_outrel(NULL, reld, ofl)); 1248 1249 if (sdp->sd_ref == REF_DYN_NEED) 1250 return (reloc_exec(reld, ofl)); 1251 1252 /* 1253 * IS_NOT_REL(rtype) 1254 */ 1255 return (reloc_generic(reld, ofl)); 1256 } 1257 1258 /* 1259 * Given a relocation that references a local symbol from a discarded 1260 * COMDAT (or SHF_GROUP) section, replace the symbol with the 1261 * corresponding symbol from the section that was kept. 1262 * 1263 * entry: 1264 * reld - Relocation 1265 * orig_sdp - Symbol to be replaced. Must be a local symbol (STB_LOCAL). 1266 * 1267 * exit: 1268 * Returns address of replacement symbol descriptor if one was 1269 * found, and NULL otherwise. 1270 * 1271 * note: 1272 * [Note that I'm using the word "COMDAT" here loosely, to refer 1273 * to actual COMDAT sections as well as to groups tied together 1274 * with an SHF_GROUP section. SHF_GROUP is simply a more advanced 1275 * version of the same idea: That multiple versions of the same thing 1276 * can come in, but only one of them is used for the output.] 1277 * 1278 * In principle, this sort of sloppy relocation remapping is 1279 * a questionable practice. All self-referential sections should 1280 * be in a common SHF_GROUP so that they are all kept or removed 1281 * together. The problem is that there is no way to ensure that the 1282 * two sections are similar enough that the replacement section will 1283 * really supply the correct information. However, we see a couple of 1284 * situations where it is useful to do this: (1) Older Sun C compilers 1285 * generated DWARF sections that would refer to one of the COMDAT 1286 * sections, and (2) gcc, when its COMDAT feature is enabled. 1287 * It turns out that the GNU ld does these sloppy remappings. 1288 * 1289 * The GNU ld takes an approach that hard wires special section 1290 * names and treats them specially. We avoid that practice and 1291 * try to get the necessary work done relying only on the ELF 1292 * attributes of the sections and symbols involved. This means 1293 * that our heuristic is somewhat different than theirs, but the 1294 * end result is close enough to solve the same problem. 1295 * 1296 * It is our hope that gcc will eventually phase out the need 1297 * for sloppy relocations, and this won't be needed. In the 1298 * meantime, the option allows us to interoperate. 1299 * 1300 * Here is how we do it: The symbol points at the input section, 1301 * and the input section points at the output section to which it 1302 * is assigned. The output section contains a list of all of the 1303 * input sections that have been mapped to it, including the 1304 * corresponding COMDAT section that was kept. The kept COMDAT 1305 * section contains a reference to its input file, where we can find 1306 * the array of all the symbols in that file. From the input file, 1307 * we then locate the corresponding symbol that references the kept 1308 * COMDAT section. 1309 * 1310 */ 1311 static Sym_desc * 1312 sloppy_comdat_reloc(Ofl_desc *ofl, Rel_desc *reld, Sym_desc *sdp) 1313 { 1314 Listnode *lnp; 1315 Is_desc *rep_isp; 1316 const char *is_name; 1317 Sym *sym = sdp->sd_sym; 1318 Is_desc *isp = sdp->sd_isc; 1319 1320 /* 1321 * ld_place_section() can alter the section name if it contains 1322 * a '%' character. We need to use the original name in this 1323 * case. 1324 */ 1325 is_name = isp->is_basename ? isp->is_basename : isp->is_name; 1326 1327 /* 1328 * 1) The caller is required to ensure that the input symbol is 1329 * local. We don't check for that here. 1330 * 2) If the discarded section has not been assigned to an 1331 * output section, we won't be able to continue. 1332 * 3) This operation only applies to SHT_SUNW_COMDAT sections 1333 * or sections contained within a COMDAT group (SHF_GROUP). 1334 */ 1335 if ((isp->is_osdesc == NULL) || 1336 ((isp->is_shdr->sh_type != SHT_SUNW_COMDAT) && 1337 ((isp->is_shdr->sh_flags & SHF_GROUP) == 0))) 1338 return (NULL); 1339 1340 /* 1341 * Examine each input section assigned to this output section. 1342 * The replacement section must: 1343 * - Have the same name as the original 1344 * - Not have been discarded 1345 * - Have the same size 1346 * - Have the same section type (and note that this type may 1347 * be SHT_SUNW_COMDAT). 1348 * - Have the same SHF_GROUP flag setting (either on or off) 1349 * - Must be a COMDAT section of one form or the other. 1350 */ 1351 for (LIST_TRAVERSE(&isp->is_osdesc->os_isdescs, lnp, rep_isp)) { 1352 const char *rep_is_name = rep_isp->is_basename ? 1353 rep_isp->is_basename : rep_isp->is_name; 1354 1355 if (!(rep_isp->is_flags & FLG_IS_DISCARD) && 1356 (isp->is_indata->d_size == rep_isp->is_indata->d_size) && 1357 (isp->is_shdr->sh_type == rep_isp->is_shdr->sh_type) && 1358 ((isp->is_shdr->sh_flags & SHF_GROUP) == 1359 (rep_isp->is_shdr->sh_flags & SHF_GROUP)) && 1360 (strcmp(rep_is_name, is_name) == 0)) { 1361 /* 1362 * We found the kept COMDAT section. Now, look at all of the 1363 * symbols from the input file that contains it to find the 1364 * symbol that corresponds to the one we started with: 1365 * - Hasn't been discarded 1366 * - Has section index of kept section 1367 * - If one symbol has a name, the other must have 1368 * the same name. The st_name field of a symbol 1369 * is 0 if there is no name, and is a string 1370 * table offset otherwise. The string table 1371 * offsets may well not agree --- it is the 1372 * actual string that matters. 1373 * - Type and binding attributes match (st_info) 1374 * - Values match (st_value) 1375 * - Sizes match (st_size) 1376 * - Visibility matches (st_other) 1377 */ 1378 Word scnndx = rep_isp->is_scnndx; 1379 Sym_desc **oldndx = rep_isp->is_file->ifl_oldndx; 1380 Word symscnt = rep_isp->is_file->ifl_symscnt; 1381 Sym_desc *rep_sdp; 1382 Sym *rep_sym; 1383 1384 while (symscnt--) { 1385 rep_sdp = *oldndx++; 1386 if (rep_sdp && !(rep_sdp->sd_flags & FLG_SY_ISDISC) && 1387 ((rep_sym = rep_sdp->sd_sym)->st_shndx == scnndx) && 1388 ((sym->st_name == 0) == (rep_sym->st_name == 0)) && 1389 !((sym->st_name != 0) && 1390 (strcmp(sdp->sd_name, rep_sdp->sd_name) != 0)) && 1391 (sym->st_info == rep_sym->st_info) && 1392 (sym->st_value == rep_sym->st_value) && 1393 (sym->st_size == rep_sym->st_size) && 1394 (sym->st_other == rep_sym->st_other)) { 1395 1396 if (ofl->ofl_flags & FLG_OF_VERBOSE) { 1397 Ifl_desc *ifl = sdp->sd_file; 1398 1399 if (sym->st_name != 0) { 1400 eprintf(ofl->ofl_lml, ERR_WARNING, 1401 MSG_INTL(MSG_REL_SLOPCDATNAM), 1402 conv_reloc_type(ifl->ifl_ehdr->e_machine, 1403 reld->rel_rtype, 0), 1404 ifl->ifl_name, reld->rel_isdesc->is_name, 1405 rep_sdp->sd_name, is_name, 1406 rep_sdp->sd_file->ifl_name); 1407 } else { 1408 eprintf(ofl->ofl_lml, ERR_WARNING, 1409 MSG_INTL(MSG_REL_SLOPCDATNONAM), 1410 conv_reloc_type( 1411 ifl->ifl_ehdr->e_machine, 1412 reld->rel_rtype, 0), 1413 ifl->ifl_name, reld->rel_isdesc->is_name, 1414 is_name, rep_sdp->sd_file->ifl_name); 1415 } 1416 } 1417 DBG_CALL(Dbg_reloc_sloppycomdat(ofl->ofl_lml, 1418 is_name, rep_sdp)); 1419 return (rep_sdp); 1420 } 1421 } 1422 } 1423 } 1424 1425 1426 /* If didn't return above, we didn't find it */ 1427 return (NULL); 1428 } 1429 1430 /* 1431 * Generate relocation descriptor and dispatch 1432 */ 1433 static uintptr_t 1434 process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx, 1435 Rel *reloc) 1436 { 1437 Ifl_desc *ifl = isp->is_file; 1438 Word rtype = reld->rel_rtype; 1439 Sym_desc *sdp; 1440 1441 /* 1442 * Make sure the relocation is in the valid range. 1443 */ 1444 if (rtype >= M_R_NUM) { 1445 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT), 1446 ifl->ifl_name, isp->is_name, rtype); 1447 return (S_ERROR); 1448 } 1449 1450 ofl->ofl_entrelscnt++; 1451 1452 /* 1453 * Special case: a register symbol associated with symbol index 0 is 1454 * initialized (i.e., relocated) to a constant from the r_addend field 1455 * rather than from a symbol value. 1456 */ 1457 if (IS_REGISTER(rtype) && (rsndx == 0)) { 1458 reld->rel_sym = 0; 1459 reld->rel_sname = MSG_ORIG(MSG_STR_EMPTY); 1460 1461 DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, M_MACH, 1462 isp->is_shdr->sh_type, (void *)reloc, isp->is_name, 1463 reld->rel_sname)); 1464 return (ld_reloc_register(reld, isp, ofl)); 1465 } 1466 1467 /* 1468 * Determine whether we're dealing with a named symbol. Note, bogus 1469 * relocations can result in a null symbol descriptor (sdp), the error 1470 * condition should be caught below after determining whether a valid 1471 * symbol name exists. 1472 */ 1473 sdp = ifl->ifl_oldndx[rsndx]; 1474 if (sdp != NULL && sdp->sd_name && *sdp->sd_name) 1475 reld->rel_sname = sdp->sd_name; 1476 else { 1477 static char *strunknown; 1478 1479 if (strunknown == 0) 1480 strunknown = (char *)MSG_INTL(MSG_STR_UNKNOWN); 1481 reld->rel_sname = strunknown; 1482 } 1483 1484 /* 1485 * If for some reason we have a null relocation record issue a 1486 * warning and continue (the compiler folks can get into this 1487 * state some time). Normal users should never see this error. 1488 */ 1489 if (rtype == M_R_NONE) { 1490 DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, M_MACH, 1491 M_REL_SHT_TYPE, (void *)reloc, isp->is_name, 1492 reld->rel_sname)); 1493 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_NULL), 1494 ifl->ifl_name, isp->is_name); 1495 return (1); 1496 } 1497 1498 if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && IS_NOTSUP(rtype)) { 1499 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP), 1500 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype, 0), 1501 ifl->ifl_name, isp->is_name); 1502 return (S_ERROR); 1503 } 1504 1505 /* 1506 * If we are here, we know that the relocation requires reference 1507 * symbol. If no symbol is assigned, this is a fatal error. 1508 */ 1509 if (sdp == NULL) { 1510 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL), 1511 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype, 0), 1512 isp->is_name, ifl->ifl_name, EC_XWORD(reloc->r_offset)); 1513 return (S_ERROR); 1514 } 1515 1516 if (sdp->sd_flags1 & FLG_SY1_IGNORE) 1517 return (1); 1518 1519 /* 1520 * If this symbol is part of a DISCARDED section attempt to find another 1521 * definition. 1522 */ 1523 if (sdp->sd_flags & FLG_SY_ISDISC) { 1524 Sym_desc *nsdp = NULL; 1525 1526 if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) { 1527 /* 1528 * If "-z relaxreloc", then check to see if 1529 * this is a reference to a discarded COMDAT 1530 * section that can be replaced with the 1531 * one that was kept. 1532 */ 1533 if (ofl->ofl_flags1 & FLG_OF1_RLXREL) 1534 nsdp = sloppy_comdat_reloc(ofl, reld, sdp); 1535 } else if (reld->rel_sname == sdp->sd_name) { 1536 nsdp = ld_sym_find(sdp->sd_name, SYM_NOHASH, 0, ofl); 1537 } 1538 if (nsdp == 0) { 1539 eprintf(ofl->ofl_lml, ERR_FATAL, 1540 MSG_INTL(MSG_REL_SYMDISC), 1541 ifl->ifl_name, isp->is_name, 1542 demangle(sdp->sd_name), 1543 sdp->sd_isc->is_name); 1544 return (S_ERROR); 1545 } 1546 ifl->ifl_oldndx[rsndx] = sdp = nsdp; 1547 } 1548 1549 /* 1550 * If this is a global symbol, determine whether its visibility needs 1551 * adjusting. 1552 */ 1553 if (sdp->sd_aux && ((sdp->sd_flags & FLG_SY_VISIBLE) == 0)) 1554 ld_sym_adjust_vis(sdp, ofl); 1555 1556 /* 1557 * Ignore any relocation against a section that will not be in the 1558 * output file (has been stripped). 1559 */ 1560 if ((sdp->sd_isc == 0) && 1561 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) 1562 return (1); 1563 1564 /* 1565 * If the input section exists, but the section has not been associated 1566 * to an output section, then this is a little suspicious. 1567 */ 1568 if (sdp->sd_isc && (sdp->sd_isc->is_osdesc == 0) && 1569 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) { 1570 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_RELINVSEC), 1571 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype, 0), 1572 ifl->ifl_name, isp->is_name, sdp->sd_isc->is_name); 1573 return (1); 1574 } 1575 1576 /* 1577 * If the symbol for this relocation is invalid (which should have 1578 * generated a message during symbol processing), or the relocation 1579 * record's symbol reference is in any other way invalid, then it's 1580 * about time we gave up. 1581 */ 1582 if ((sdp->sd_flags & FLG_SY_INVALID) || (rsndx == 0) || 1583 (rsndx >= ifl->ifl_symscnt)) { 1584 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM), 1585 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype, 0), 1586 ifl->ifl_name, isp->is_name, demangle(reld->rel_sname), 1587 EC_XWORD(reloc->r_offset), EC_WORD(rsndx)); 1588 return (S_ERROR); 1589 } 1590 1591 /* 1592 * Size relocations against section symbols are presently unsupported. 1593 * There is a question as to whether the input section size, or output 1594 * section size would be used. Until an explicit requirement is 1595 * established for either case, we'll punt. 1596 */ 1597 if (IS_SIZE(rtype) && 1598 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) { 1599 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSIZE), 1600 conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype, 0), 1601 ifl->ifl_name, isp->is_name); 1602 return (S_ERROR); 1603 } 1604 1605 reld->rel_sym = sdp; 1606 return (ld_process_sym_reloc(ofl, reld, reloc, isp, isp->is_name)); 1607 } 1608 1609 static uintptr_t 1610 reloc_section(Ofl_desc *ofl, Is_desc *isect, Is_desc *rsect, Os_desc *osect) 1611 { 1612 Rel *rend; /* end of relocation section data */ 1613 Rel *reloc; /* current relocation entry */ 1614 Xword rsize; /* size of relocation section data */ 1615 Xword entsize; /* size of relocation entry */ 1616 Rel_desc reld; /* relocation descriptor */ 1617 Shdr * shdr; 1618 Word flags = 0; 1619 1620 shdr = rsect->is_shdr; 1621 rsize = shdr->sh_size; 1622 reloc = (Rel *)rsect->is_indata->d_buf; 1623 1624 /* 1625 * Decide entry size. 1626 */ 1627 if (((entsize = shdr->sh_entsize) == 0) || (entsize > rsize)) { 1628 if (shdr->sh_type == SHT_RELA) 1629 entsize = sizeof (Rela); 1630 else 1631 entsize = sizeof (Rel); 1632 } 1633 1634 /* 1635 * Build up the basic information in for the Rel_desc structure. 1636 */ 1637 reld.rel_osdesc = osect; 1638 reld.rel_isdesc = isect; 1639 reld.rel_move = 0; 1640 1641 if ((ofl->ofl_flags & FLG_OF_RELOBJ) || 1642 (osect && (osect->os_sgdesc->sg_phdr.p_type == PT_LOAD))) 1643 flags |= FLG_REL_LOAD; 1644 1645 if (shdr->sh_info == 0) 1646 flags |= FLG_REL_NOINFO; 1647 1648 DBG_CALL(Dbg_reloc_proc(ofl->ofl_lml, osect, isect, rsect)); 1649 1650 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize); 1651 reloc < rend; 1652 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) { 1653 Word rsndx; 1654 1655 /* 1656 * Initialize the relocation record information and process 1657 * the individual relocation. Reinitialize the flags to 1658 * insure we don't carry any state over from the previous 1659 * relocation records processing. 1660 */ 1661 reld.rel_flags = flags; 1662 rsndx = ld_init_rel(&reld, (void *)reloc); 1663 1664 if (process_reld(ofl, rsect, &reld, rsndx, reloc) == S_ERROR) 1665 return (S_ERROR); 1666 } 1667 return (1); 1668 } 1669 1670 static uintptr_t 1671 reloc_segments(int wr_flag, Ofl_desc *ofl) 1672 { 1673 Listnode *lnp1; 1674 Sg_desc *sgp; 1675 Is_desc *isp; 1676 1677 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { 1678 Os_desc **ospp; 1679 Aliste off; 1680 1681 if ((sgp->sg_phdr.p_flags & PF_W) != wr_flag) 1682 continue; 1683 1684 for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { 1685 Is_desc *risp; 1686 Listnode *lnp3; 1687 Os_desc *osp = *ospp; 1688 1689 osp->os_szoutrels = 0; 1690 for (LIST_TRAVERSE(&(osp->os_relisdescs), lnp3, risp)) { 1691 Word indx; 1692 1693 /* 1694 * Determine the input section that this 1695 * relocation information refers to. 1696 */ 1697 indx = risp->is_shdr->sh_info; 1698 isp = risp->is_file->ifl_isdesc[indx]; 1699 1700 /* 1701 * Do not process relocations against sections 1702 * which are being discarded (COMDAT) 1703 */ 1704 if (isp->is_flags & FLG_IS_DISCARD) 1705 continue; 1706 1707 if (reloc_section(ofl, isp, risp, osp) == 1708 S_ERROR) 1709 return (S_ERROR); 1710 } 1711 1712 /* 1713 * Check for relocations against non-writable 1714 * allocatable sections. 1715 */ 1716 if ((osp->os_szoutrels) && 1717 (sgp->sg_phdr.p_type == PT_LOAD) && 1718 ((sgp->sg_phdr.p_flags & PF_W) == 0)) { 1719 ofl->ofl_flags |= FLG_OF_TEXTREL; 1720 ofl->ofl_dtflags |= DF_TEXTREL; 1721 } 1722 } 1723 } 1724 1725 return (1); 1726 } 1727 1728 /* 1729 * Move Section related function 1730 * Get move entry 1731 */ 1732 static Move * 1733 get_move_entry(Is_desc *rsect, Xword roffset) 1734 { 1735 Ifl_desc *ifile = rsect->is_file; 1736 Shdr *rshdr = rsect->is_shdr; 1737 Is_desc *misp; 1738 Shdr *mshdr; 1739 Xword midx; 1740 Move *ret; 1741 1742 /* 1743 * Set info for the target move section 1744 */ 1745 misp = ifile->ifl_isdesc[rshdr->sh_info]; 1746 mshdr = (ifile->ifl_isdesc[rshdr->sh_info])->is_shdr; 1747 1748 if (mshdr->sh_entsize == 0) 1749 return ((Move *)0); 1750 midx = roffset / mshdr->sh_entsize; 1751 1752 ret = (Move *)misp->is_indata->d_buf; 1753 ret += midx; 1754 1755 /* 1756 * If this is an illgal entry, retun NULL. 1757 */ 1758 if ((midx * mshdr->sh_entsize) >= mshdr->sh_size) 1759 return ((Move *)0); 1760 return (ret); 1761 } 1762 1763 /* 1764 * Relocation against Move Table. 1765 */ 1766 static uintptr_t 1767 process_movereloc(Ofl_desc *ofl, Is_desc *rsect) 1768 { 1769 Ifl_desc *file = rsect->is_file; 1770 Rel *rend, *reloc; 1771 Xword rsize, entsize; 1772 static Rel_desc reld_zero; 1773 Rel_desc reld; 1774 1775 rsize = rsect->is_shdr->sh_size; 1776 reloc = (Rel *)rsect->is_indata->d_buf; 1777 1778 reld = reld_zero; 1779 1780 /* 1781 * Decide entry size 1782 */ 1783 entsize = rsect->is_shdr->sh_entsize; 1784 if ((entsize == 0) || 1785 (entsize > rsect->is_shdr->sh_size)) { 1786 if (rsect->is_shdr->sh_type == SHT_RELA) 1787 entsize = sizeof (Rela); 1788 else 1789 entsize = sizeof (Rel); 1790 } 1791 1792 /* 1793 * Go through the relocation entries. 1794 */ 1795 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize); 1796 reloc < rend; 1797 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) { 1798 Sym_desc * psdp; 1799 Move * mp; 1800 Word rsndx; 1801 1802 /* 1803 * Initialize the relocation record information. 1804 */ 1805 reld.rel_flags = FLG_REL_LOAD; 1806 rsndx = ld_init_rel(&reld, (void *)reloc); 1807 1808 if (((mp = get_move_entry(rsect, reloc->r_offset)) == 0) || 1809 ((reld.rel_move = libld_malloc(sizeof (Mv_desc))) == 0)) 1810 return (S_ERROR); 1811 1812 psdp = file->ifl_oldndx[ELF_M_SYM(mp->m_info)]; 1813 reld.rel_move->mvd_move = mp; 1814 reld.rel_move->mvd_sym = psdp; 1815 1816 if (psdp->sd_flags & FLG_SY_PAREXPN) { 1817 int _num, num; 1818 1819 reld.rel_osdesc = ofl->ofl_issunwdata1->is_osdesc; 1820 reld.rel_isdesc = ofl->ofl_issunwdata1; 1821 reld.rel_roffset = mp->m_poffset; 1822 1823 for (num = mp->m_repeat, _num = 0; _num < num; _num++) { 1824 reld.rel_roffset += 1825 /* LINTED */ 1826 (_num * ELF_M_SIZE(mp->m_info)); 1827 /* 1828 * Generate Reld 1829 */ 1830 if (process_reld(ofl, 1831 rsect, &reld, rsndx, reloc) == S_ERROR) 1832 return (S_ERROR); 1833 } 1834 } else { 1835 /* 1836 * Generate Reld 1837 */ 1838 reld.rel_flags |= FLG_REL_MOVETAB; 1839 reld.rel_osdesc = ofl->ofl_osmove; 1840 reld.rel_isdesc = 1841 ofl->ofl_osmove->os_isdescs.head->data; 1842 if (process_reld(ofl, 1843 rsect, &reld, rsndx, reloc) == S_ERROR) 1844 return (S_ERROR); 1845 } 1846 } 1847 return (1); 1848 } 1849 1850 /* 1851 * This function is similar to reloc_init(). 1852 * 1853 * This function is called when the SHT_SUNW_move table is expanded 1854 * and there were relocation against the SHT_SUNW_move section. 1855 */ 1856 static uintptr_t 1857 reloc_movesections(Ofl_desc *ofl) 1858 { 1859 Listnode *lnp1; 1860 Is_desc *risp; 1861 1862 /* 1863 * Generate/Expand relocation entries 1864 */ 1865 for (LIST_TRAVERSE(&ofl->ofl_mvrelisdescs, lnp1, risp)) { 1866 if (process_movereloc(ofl, risp) == S_ERROR) 1867 return (S_ERROR); 1868 } 1869 1870 return (1); 1871 } 1872 1873 /* 1874 * Count the number of output relocation entries, global offset table entries, 1875 * and procedure linkage table entries. This function searches the segment and 1876 * outsect lists and passes each input reloc section to process_reloc(). 1877 * It allocates space for any output relocations needed. And builds up 1878 * the relocation structures for later processing. 1879 */ 1880 uintptr_t 1881 ld_reloc_init(Ofl_desc *ofl) 1882 { 1883 Listnode *lnp; 1884 Is_desc *isp; 1885 Sym_desc *sdp; 1886 1887 /* 1888 * At this point we have finished processing all input symbols. Make 1889 * sure we add any absolute (internal) symbols before continuing with 1890 * any relocation processing. 1891 */ 1892 if (ld_sym_spec(ofl) == S_ERROR) 1893 return (S_ERROR); 1894 1895 ofl->ofl_gotcnt = M_GOT_XNumber; 1896 1897 /* 1898 * First process all of the relocations against NON-writable 1899 * segments followed by relocations against the writeable segments. 1900 * 1901 * This separation is so that when the writable segments are processed 1902 * we know whether or not a COPYRELOC will be produced for any symbols. 1903 * If relocations aren't processed in this order, a COPYRELOC and a 1904 * regular relocation can be produced against the same symbol. The 1905 * regular relocation would be redundant. 1906 */ 1907 if (reloc_segments(0, ofl) == S_ERROR) 1908 return (S_ERROR); 1909 1910 if (reloc_segments(PF_W, ofl) == S_ERROR) 1911 return (S_ERROR); 1912 1913 /* 1914 * Process any extra relocations. These are relocation sections that 1915 * have a NULL sh_info. 1916 */ 1917 for (LIST_TRAVERSE(&ofl->ofl_extrarels, lnp, isp)) { 1918 if (reloc_section(ofl, NULL, isp, NULL) == S_ERROR) 1919 return (S_ERROR); 1920 } 1921 1922 /* 1923 * If there were relocation against move table, 1924 * process the relocation sections. 1925 */ 1926 if (reloc_movesections(ofl) == S_ERROR) 1927 return (S_ERROR); 1928 1929 /* 1930 * Now all the relocations are pre-processed, 1931 * check the validity of copy relocations. 1932 */ 1933 if (ofl->ofl_copyrels.head != 0) { 1934 Copy_rel *cpyrel; 1935 1936 for (LIST_TRAVERSE(&ofl->ofl_copyrels, lnp, cpyrel)) { 1937 sdp = cpyrel->copyrel_symd; 1938 1939 /* 1940 * If there were no displacement relocation 1941 * in this file, don't worry about it. 1942 */ 1943 if (sdp->sd_file->ifl_flags & 1944 (FLG_IF_DISPPEND | FLG_IF_DISPDONE)) 1945 is_disp_copied(ofl, cpyrel); 1946 } 1947 } 1948 1949 /* 1950 * GOT sections are created for dynamic executables and shared objects 1951 * if the FLG_OF_BLDGOT is set, or explicit reference has been made to 1952 * a GOT symbol. 1953 */ 1954 if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && 1955 ((ofl->ofl_flags & FLG_OF_BLDGOT) || 1956 ((((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL), 1957 SYM_NOHASH, 0, ofl)) != 0) || 1958 ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U), 1959 SYM_NOHASH, 0, ofl)) != 0)) && (sdp->sd_ref != REF_DYN_SEEN)))) { 1960 if (ld_make_got(ofl) == S_ERROR) 1961 return (S_ERROR); 1962 1963 #if defined(sparc) || defined(__sparcv9) 1964 if (ld_allocate_got(ofl) == S_ERROR) 1965 return (S_ERROR); 1966 #elif defined(i386) || defined(__amd64) 1967 /* nothing to do */ 1968 #else 1969 #error Unknown architecture! 1970 #endif 1971 } 1972 1973 return (1); 1974 } 1975 1976 /* 1977 * Simple comparison routine to be used by qsort() for 1978 * the sorting of the output relocation list. 1979 * 1980 * The reloc_compare() routine results in a relocation 1981 * table which is located on: 1982 * 1983 * file referenced (NEEDED NDX) 1984 * referenced symbol 1985 * relocation offset 1986 * 1987 * This provides the most efficient traversal of the relocation 1988 * table at run-time. 1989 */ 1990 static int 1991 reloc_compare(Reloc_list *i, Reloc_list *j) 1992 { 1993 1994 /* 1995 * first - sort on neededndx 1996 */ 1997 if (i->rl_key1 > j->rl_key1) 1998 return (1); 1999 if (i->rl_key1 < j->rl_key1) 2000 return (-1); 2001 2002 /* 2003 * Then sort on symbol 2004 */ 2005 if ((uintptr_t)i->rl_key2 > (uintptr_t)j->rl_key2) 2006 return (1); 2007 if ((uintptr_t)i->rl_key2 < (uintptr_t)j->rl_key2) 2008 return (-1); 2009 2010 /* 2011 * i->key2 == j->key2 2012 * 2013 * At this point we fall back to key2 (offsets) to 2014 * sort the output relocations. Ideally this will 2015 * make for the most efficient processing of these 2016 * relocations at run-time. 2017 */ 2018 if (i->rl_key3 > j->rl_key3) 2019 return (1); 2020 if (i->rl_key3 < j->rl_key3) 2021 return (-1); 2022 return (0); 2023 } 2024 2025 static uintptr_t 2026 do_sorted_outrelocs(Ofl_desc *ofl) 2027 { 2028 Rel_desc *orsp; 2029 Rel_cache *rcp; 2030 Listnode *lnp; 2031 Reloc_list *sorted_list; 2032 Word index = 0; 2033 int debug = 0; 2034 uintptr_t error = 1; 2035 2036 if ((sorted_list = libld_malloc((size_t)(sizeof (Reloc_list) * 2037 ofl->ofl_reloccnt))) == NULL) 2038 return (S_ERROR); 2039 2040 /* 2041 * All but the PLT output relocations are sorted in the output file 2042 * based upon their sym_desc. By doing this multiple relocations 2043 * against the same symbol are grouped together, thus when the object 2044 * is later relocated by ld.so.1 it will take advantage of the symbol 2045 * cache that ld.so.1 has. This can significantly reduce the runtime 2046 * relocation cost of a dynamic object. 2047 * 2048 * PLT relocations are not sorted because the order of the PLT 2049 * relocations is used by ld.so.1 to determine what symbol a PLT 2050 * relocation is against. 2051 */ 2052 for (LIST_TRAVERSE(&ofl->ofl_outrels, lnp, rcp)) { 2053 /*LINTED*/ 2054 for (orsp = (Rel_desc *)(rcp + 1); 2055 orsp < rcp->rc_free; orsp++) { 2056 if (debug == 0) { 2057 DBG_CALL(Dbg_reloc_dooutrel(ofl->ofl_lml, 2058 M_REL_SHT_TYPE)); 2059 debug = 1; 2060 } 2061 2062 /* 2063 * If it's a PLT relocation we output it now in the 2064 * order that it was originally processed. 2065 */ 2066 if (orsp->rel_flags & FLG_REL_PLT) { 2067 if (ld_perform_outreloc(orsp, ofl) == S_ERROR) 2068 error = S_ERROR; 2069 continue; 2070 } 2071 2072 if ((orsp->rel_rtype == M_R_RELATIVE) || 2073 (orsp->rel_rtype == M_R_REGISTER)) { 2074 sorted_list[index].rl_key1 = 0; 2075 sorted_list[index].rl_key2 = 2076 /* LINTED */ 2077 (Sym_desc *)(uintptr_t)orsp->rel_rtype; 2078 } else { 2079 sorted_list[index].rl_key1 = 2080 orsp->rel_sym->sd_file->ifl_neededndx; 2081 sorted_list[index].rl_key2 = 2082 orsp->rel_sym; 2083 } 2084 2085 if (orsp->rel_flags & FLG_REL_GOT) 2086 sorted_list[index].rl_key3 = 2087 ld_calc_got_offset(orsp, ofl); 2088 else { 2089 if (orsp->rel_rtype == M_R_REGISTER) 2090 sorted_list[index].rl_key3 = 0; 2091 else { 2092 sorted_list[index].rl_key3 = 2093 orsp->rel_roffset + 2094 (Xword)_elf_getxoff(orsp-> 2095 rel_isdesc-> 2096 is_indata) + 2097 orsp->rel_isdesc->is_osdesc-> 2098 os_shdr->sh_addr; 2099 } 2100 } 2101 2102 sorted_list[index++].rl_rsp = orsp; 2103 } 2104 } 2105 2106 qsort(sorted_list, (size_t)ofl->ofl_reloccnt, sizeof (Reloc_list), 2107 (int (*)(const void *, const void *))reloc_compare); 2108 2109 /* 2110 * All output relocations have now been sorted, go through 2111 * and process each relocation. 2112 */ 2113 for (index = 0; index < ofl->ofl_reloccnt; index++) { 2114 if (ld_perform_outreloc(sorted_list[index].rl_rsp, ofl) == 2115 S_ERROR) 2116 error = S_ERROR; 2117 } 2118 2119 return (error); 2120 } 2121 2122 /* 2123 * Process relocations. Finds every input relocation section for each output 2124 * section and invokes reloc_sec() to relocate that section. 2125 */ 2126 uintptr_t 2127 ld_reloc_process(Ofl_desc *ofl) 2128 { 2129 Listnode *lnp1; 2130 Sg_desc *sgp; 2131 Os_desc *osp; 2132 Word ndx = 0, flags = ofl->ofl_flags; 2133 Shdr *shdr; 2134 2135 /* 2136 * Determine the index of the symbol table that will be referenced by 2137 * the relocation entries. 2138 */ 2139 if ((flags & (FLG_OF_DYNAMIC|FLG_OF_RELOBJ)) == FLG_OF_DYNAMIC) 2140 /* LINTED */ 2141 ndx = (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn); 2142 else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ)) 2143 /* LINTED */ 2144 ndx = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn); 2145 2146 /* 2147 * Re-initialize counters. These are used to provide relocation 2148 * offsets within the output buffers. 2149 */ 2150 ofl->ofl_relocpltsz = 0; 2151 ofl->ofl_relocgotsz = 0; 2152 ofl->ofl_relocbsssz = 0; 2153 2154 /* 2155 * Now that the output file is created and symbol update has occurred, 2156 * process the relocations collected in process_reloc(). 2157 */ 2158 if (do_sorted_outrelocs(ofl) == S_ERROR) 2159 return (S_ERROR); 2160 2161 if (ld_do_activerelocs(ofl) == S_ERROR) 2162 return (S_ERROR); 2163 2164 if ((ofl->ofl_flags1 & FLG_OF1_RELCNT) == 0) { 2165 /* 2166 * Process the relocation sections: 2167 * 2168 * o for each relocation section generated for the output 2169 * image update its shdr information to reflect the 2170 * symbol table it needs (sh_link) and the section to 2171 * which the relocation must be applied (sh_info). 2172 */ 2173 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { 2174 Os_desc **ospp; 2175 Aliste off; 2176 2177 for (ALIST_TRAVERSE(sgp->sg_osdescs, off, ospp)) { 2178 osp = *ospp; 2179 2180 if (osp->os_relosdesc == 0) 2181 continue; 2182 2183 shdr = osp->os_relosdesc->os_shdr; 2184 shdr->sh_link = ndx; 2185 /* LINTED */ 2186 shdr->sh_info = (Word)elf_ndxscn(osp->os_scn); 2187 } 2188 } 2189 2190 /* 2191 * Since the .rel[a] section is not tied to any specific 2192 * section, we'd not have found it above. 2193 */ 2194 if ((osp = ofl->ofl_osrel) != NULL) { 2195 shdr = osp->os_shdr; 2196 shdr->sh_link = ndx; 2197 shdr->sh_info = 0; 2198 } 2199 } else { 2200 /* 2201 * We only have two relocation sections here, (PLT's, 2202 * coalesced) so just hit them directly instead of stepping 2203 * over the output sections. 2204 */ 2205 if ((osp = ofl->ofl_osrelhead) != NULL) { 2206 shdr = osp->os_shdr; 2207 shdr->sh_link = ndx; 2208 shdr->sh_info = 0; 2209 } 2210 if (((osp = ofl->ofl_osplt) != NULL) && osp->os_relosdesc) { 2211 shdr = osp->os_relosdesc->os_shdr; 2212 shdr->sh_link = ndx; 2213 /* LINTED */ 2214 shdr->sh_info = (Word)elf_ndxscn(osp->os_scn); 2215 } 2216 } 2217 2218 /* 2219 * If the -z text option was given, and we have output relocations 2220 * against a non-writable, allocatable section, issue a diagnostic and 2221 * return (the actual entries that caused this error would have been 2222 * output during the relocating section phase). 2223 */ 2224 if ((flags & (FLG_OF_PURETXT | FLG_OF_TEXTREL)) == 2225 (FLG_OF_PURETXT | FLG_OF_TEXTREL)) { 2226 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_REMAIN_3)); 2227 return (S_ERROR); 2228 } 2229 2230 /* 2231 * Finally, initialize the first got entry with the address of the 2232 * .dynamic section (_DYNAMIC). 2233 */ 2234 if (flags & FLG_OF_DYNAMIC) { 2235 if (ld_fillin_gotplt(ofl) == S_ERROR) 2236 return (S_ERROR); 2237 } 2238 2239 /* 2240 * Now that any GOT information has been written, display the debugging 2241 * information if required. 2242 */ 2243 if ((osp = ofl->ofl_osgot) != NULL) 2244 DBG_CALL(Dbg_got_display(ofl, osp->os_shdr->sh_addr, 1)); 2245 2246 return (1); 2247 } 2248 2249 /* 2250 * If the -z text option was given, and we have output relocations against a 2251 * non-writable, allocatable section, issue a diagnostic. Print offending 2252 * symbols in tabular form similar to the way undefined symbols are presented. 2253 * Called from reloc_count(). The actual fatal error condition is triggered on 2254 * in reloc_process() above. 2255 * 2256 * Note. For historic reasons -ztext is not a default option (however all OS 2257 * shared object builds use this option). It can be argued that this option 2258 * should also be default when generating an a.out (see 1163979). However, if 2259 * an a.out contains text relocations it is either because the user is creating 2260 * something pretty weird (they've used the -b or -znodefs options), or because 2261 * the library against which they're building wasn't constructed correctly (ie. 2262 * a function has a NOTYPE type, in which case the a.out won't generate an 2263 * associated plt). In the latter case the builder of the a.out can't do 2264 * anything to fix the error - thus we've chosen not to give the user an error, 2265 * or warning, for this case. 2266 */ 2267 static void 2268 reloc_remain_title(Ofl_desc *ofl, int warning) 2269 { 2270 const char *str1; 2271 2272 if (warning) 2273 str1 = MSG_INTL(MSG_REL_RMN_ITM_13); 2274 else 2275 str1 = MSG_INTL(MSG_REL_RMN_ITM_11); 2276 2277 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_FMT_1), 2278 str1, 2279 MSG_INTL(MSG_REL_RMN_ITM_31), 2280 MSG_INTL(MSG_REL_RMN_ITM_12), 2281 MSG_INTL(MSG_REL_RMN_ITM_2), 2282 MSG_INTL(MSG_REL_RMN_ITM_32)); 2283 2284 } 2285 2286 void 2287 ld_reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl) 2288 { 2289 static Boolean reloc_title = TRUE; 2290 2291 /* 2292 * -ztextoff 2293 */ 2294 if (ofl->ofl_flags1 & FLG_OF1_TEXTOFF) 2295 return; 2296 2297 /* 2298 * Only give relocation errors against loadable read-only segments. 2299 */ 2300 if ((orsp->rel_rtype == M_R_REGISTER) || (!osp) || 2301 (osp->os_sgdesc->sg_phdr.p_type != PT_LOAD) || 2302 (osp->os_sgdesc->sg_phdr.p_flags & PF_W)) 2303 return; 2304 2305 /* 2306 * If we are in -ztextwarn mode, it's a silent error if a relocation is 2307 * due to a 'WEAK REFERENCE'. This is because if the symbol is not 2308 * provided at run-time we will not perform a text-relocation. 2309 */ 2310 if (((ofl->ofl_flags & FLG_OF_PURETXT) == 0) && 2311 (ELF_ST_BIND(orsp->rel_sym->sd_sym->st_info) == STB_WEAK) && 2312 (orsp->rel_sym->sd_sym->st_shndx == SHN_UNDEF)) 2313 return; 2314 2315 if (reloc_title) { 2316 /* 2317 * If building with '-ztext' then emit a fatal error. If 2318 * building a executable then only emit a 'warning'. 2319 */ 2320 if (ofl->ofl_flags & FLG_OF_PURETXT) 2321 reloc_remain_title(ofl, 0); 2322 else 2323 reloc_remain_title(ofl, 1); 2324 reloc_title = FALSE; 2325 } 2326 2327 eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_2), 2328 demangle(orsp->rel_sname), EC_OFF(orsp->rel_roffset), 2329 orsp->rel_isdesc->is_file->ifl_name); 2330 } 2331 2332 /* 2333 * Generic encapsulation for generating a TLS got index. 2334 */ 2335 uintptr_t 2336 ld_assign_got_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl, Sym_desc *sdp, 2337 Gotndx *gnp, Gotref gref, Word rflag, Word ortype, Word rtype1, Word rtype2) 2338 { 2339 Word rflags; 2340 2341 if (ld_assign_got_ndx(&(sdp->sd_GOTndxs), gnp, gref, ofl, 2342 rsp, sdp) == S_ERROR) 2343 return (S_ERROR); 2344 2345 rflags = FLG_REL_GOT | rflag; 2346 if (local) 2347 rflags |= FLG_REL_SCNNDX; 2348 rsp->rel_rtype = rtype1; 2349 2350 if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR) 2351 return (S_ERROR); 2352 2353 if (local && (gref == GOT_REF_TLSIE)) { 2354 /* 2355 * If this is a local LE TLS symbol, then the symbol won't be 2356 * available at runtime. The value of the local symbol will 2357 * be placed in the associated got entry, and the got 2358 * relocation is reassigned to a section symbol. 2359 */ 2360 if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR) 2361 return (S_ERROR); 2362 } 2363 2364 if (rtype2) { 2365 rflags = FLG_REL_GOT | rflag; 2366 rsp->rel_rtype = rtype2; 2367 2368 if (local) { 2369 if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR) 2370 return (S_ERROR); 2371 } else { 2372 if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR) 2373 return (S_ERROR); 2374 } 2375 } 2376 2377 rsp->rel_rtype = ortype; 2378 2379 return (1); 2380 } 2381 2382 /* 2383 * Move Section related function 2384 */ 2385 static uintptr_t 2386 newroffset_for_move(Sym_desc *symd, 2387 Move *mventry, Xword offset1, Xword *offset2) 2388 { 2389 Psym_info *psym = symd->sd_psyminfo; 2390 Mv_itm *itm; 2391 Listnode *lnp1; 2392 int found = 0; 2393 2394 /* 2395 * Search for matching move entry 2396 */ 2397 found = 0; 2398 for (LIST_TRAVERSE(&psym->psym_mvs, lnp1, itm)) { 2399 if (itm->mv_ientry == mventry) { 2400 found = 1; 2401 break; 2402 } 2403 } 2404 if (found == 0) { 2405 /* 2406 * This should never happen. 2407 */ 2408 return (S_ERROR); 2409 } 2410 2411 /* 2412 * Update r_offset 2413 */ 2414 *offset2 = (Xword)((itm->mv_oidx - 1)*sizeof (Move) + 2415 offset1 % sizeof (Move)); 2416 return (1); 2417 } 2418 2419 void 2420 ld_adj_movereloc(Ofl_desc *ofl, Rel_desc *arsp) 2421 { 2422 Move *move = arsp->rel_move->mvd_move; 2423 Sym_desc *psdp = arsp->rel_move->mvd_sym; 2424 Xword newoffset; 2425 2426 if (arsp->rel_flags & FLG_REL_MOVETAB) { 2427 /* 2428 * We are relocating the move table itself. 2429 */ 2430 (void) newroffset_for_move(psdp, move, arsp->rel_roffset, 2431 &newoffset); 2432 DBG_CALL(Dbg_move_adjmovereloc(ofl->ofl_lml, arsp->rel_roffset, 2433 newoffset, psdp->sd_name)); 2434 arsp->rel_roffset = newoffset; 2435 } else { 2436 /* 2437 * We are expanding the partial symbol. So we are generating 2438 * the relocation entry relocating the expanded partial symbol. 2439 */ 2440 arsp->rel_roffset += psdp->sd_sym->st_value - 2441 ofl->ofl_issunwdata1->is_osdesc->os_shdr->sh_addr; 2442 DBG_CALL(Dbg_move_adjexpandreloc(ofl->ofl_lml, 2443 arsp->rel_roffset, psdp->sd_name)); 2444 } 2445 } 2446 2447 /* 2448 * Partially Initialized Symbol Handling routines 2449 * For sparc architecture, the second argument is reld->rel_raddend. 2450 * For i386 acrchitecure, the second argument is the value stored 2451 * at the relocation target address. 2452 */ 2453 Sym_desc * 2454 ld_am_I_partial(Rel_desc *reld, Xword val) 2455 { 2456 Ifl_desc * ifile = reld->rel_sym->sd_isc->is_file; 2457 int nlocs = ifile->ifl_locscnt, i; 2458 2459 for (i = 1; i < nlocs; i++) { 2460 Sym * osym; 2461 Sym_desc * symd = ifile->ifl_oldndx[i]; 2462 2463 if ((osym = symd->sd_osym) == 0) 2464 continue; 2465 if ((symd->sd_flags & FLG_SY_PAREXPN) == 0) 2466 continue; 2467 if ((osym->st_value <= val) && 2468 (osym->st_value + osym->st_size > val)) 2469 return (symd); 2470 } 2471 return ((Sym_desc *) 0); 2472 } 2473 2474 /* 2475 * Because of the combinations of 32-bit lib providing 64-bit support, and 2476 * visa-versa, the use of krtld's dorelocs can result in differing message 2477 * requirements that make msg.c/msg.h creation and chkmsg "interesting". 2478 * Thus the actual message files contain a couple of entries to satisfy 2479 * each architectures build. Here we add dummy calls to quieten chkmsg. 2480 * 2481 * chkmsg: MSG_INTL(MSG_REL_NOFIT) 2482 * chkmsg: MSG_INTL(MSG_REL_NONALIGN) 2483 */ 2484