1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright (c) 1988 AT&T 25 * All Rights Reserved 26 * 27 * Copyright 2006 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 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 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(ERR_WARNING, msg, conv_reloc_type_str(ifl->ifl_ehdr->e_machine, 311 rsp->rel_rtype), ifl->ifl_name, rsp->rel_sname, str, 312 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_shndx == SHN_UNDEF) || 370 (sdp->sd_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 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 disp_errmsg(MSG_INTL(MSG_REL_DISPREL3), arsp, ofl); 496 } 497 498 DBG_CALL(Dbg_reloc_ars_entry(M_MACH, arsp)); 499 return (1); 500 } 501 502 uintptr_t 503 reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl) 504 { 505 Sym_desc *sdp; 506 Word flags = ofl->ofl_flags; 507 Gotndx *gnp; 508 509 sdp = rsp->rel_sym; 510 511 /* 512 * If this is the first time we've seen this symbol in a GOT 513 * relocation we need to assign it a GOT token. Once we've got 514 * all of the GOT's assigned we can assign the actual indexes. 515 */ 516 if ((gnp = find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_GENERIC, 517 ofl, rsp)) == 0) { 518 Word rtype = rsp->rel_rtype; 519 520 if (assign_gotndx(&(sdp->sd_GOTndxs), 0, GOT_REF_GENERIC, 521 ofl, rsp, sdp) == S_ERROR) 522 return (S_ERROR); 523 524 /* 525 * Now we initialize the GOT table entry. 526 * 527 * Pseudo code to describe the the decisions below: 528 * 529 * If (local) 530 * then 531 * enter symbol value in GOT table entry 532 * if (Shared Object) 533 * then 534 * create Relative relocation against symbol 535 * fi 536 * else 537 * clear GOT table entry 538 * create a GLOB_DAT relocation against symbol 539 * fi 540 */ 541 if (local == TRUE) { 542 if (flags & FLG_OF_SHAROBJ) { 543 if (add_actrel((FLG_REL_GOT | FLG_REL_GOTCL), 544 rsp, ofl) == S_ERROR) 545 return (S_ERROR); 546 547 /* 548 * Add a RELATIVE relocation if this is 549 * anything but a ABS symbol. 550 */ 551 if ((((sdp->sd_flags & FLG_SY_SPECSEC) == 0) || 552 (sdp->sd_shndx != SHN_ABS)) || 553 (sdp->sd_aux && sdp->sd_aux->sa_symspec)) { 554 rsp->rel_rtype = M_R_RELATIVE; 555 if (add_outrel((FLG_REL_GOT | 556 FLG_REL_ADVAL), rsp, 557 ofl) == S_ERROR) 558 return (S_ERROR); 559 rsp->rel_rtype = rtype; 560 } 561 } else { 562 if (add_actrel(FLG_REL_GOT, rsp, 563 ofl) == S_ERROR) 564 return (S_ERROR); 565 } 566 } else { 567 rsp->rel_rtype = M_R_GLOB_DAT; 568 if (add_outrel(FLG_REL_GOT, rsp, ofl) == S_ERROR) 569 return (S_ERROR); 570 rsp->rel_rtype = rtype; 571 } 572 } else { 573 if (assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_GENERIC, 574 ofl, rsp, sdp) == S_ERROR) 575 return (S_ERROR); 576 } 577 578 /* 579 * Perform relocation to GOT table entry. 580 */ 581 return (add_actrel(NULL, rsp, ofl)); 582 } 583 584 585 /* 586 * Perform relocations for PLT's 587 */ 588 uintptr_t 589 reloc_plt(Rel_desc *rsp, Ofl_desc *ofl) 590 { 591 Sym_desc *sdp = rsp->rel_sym; 592 593 #if defined(__i386) || defined(__amd64) 594 #if defined(_ELF64) 595 /* 596 * AMD64 TLS code sequences do not use a unique 597 * TLS relocation to reference the __tls_get_addr() 598 * 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 (add_actrel(FLG_REL_TLSFIX, rsp, ofl)); 603 } 604 #else 605 /* 606 * GNUC IA32 TLS code sequences do not use a unique 607 * TLS relocation to reference the ___tls_get_addr() 608 * function call. 609 */ 610 if ((ofl->ofl_flags & FLG_OF_EXEC) && 611 (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_UU)) == 0)) { 612 return (add_actrel(FLG_REL_TLSFIX, rsp, ofl)); 613 } 614 #endif 615 #endif /* __i386 && __amd64 */ 616 617 /* 618 * if (not PLT yet assigned) 619 * then 620 * assign PLT index to symbol 621 * build output JMP_SLOT relocation 622 * fi 623 */ 624 if (sdp->sd_aux->sa_PLTndx == 0) { 625 Word ortype = rsp->rel_rtype; 626 627 assign_plt_ndx(sdp, ofl); 628 629 /* 630 * If this symbol is binding to a LAZYLOADED object then 631 * set the LAZYLD symbol flag. 632 */ 633 if ((sdp->sd_aux->sa_bindto && 634 (sdp->sd_aux->sa_bindto->ifl_flags & FLG_IF_LAZYLD)) || 635 (sdp->sd_file && 636 (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD))) 637 sdp->sd_flags |= FLG_SY_LAZYLD; 638 639 rsp->rel_rtype = M_R_JMP_SLOT; 640 if (add_outrel(FLG_REL_PLT, rsp, ofl) == S_ERROR) 641 return (S_ERROR); 642 rsp->rel_rtype = ortype; 643 } 644 645 /* 646 * Perform relocation to PLT table entry. 647 */ 648 if ((ofl->ofl_flags & FLG_OF_SHAROBJ) && 649 IS_ADD_RELATIVE(rsp->rel_rtype)) { 650 Word ortype = rsp->rel_rtype; 651 652 rsp->rel_rtype = M_R_RELATIVE; 653 if (add_outrel(FLG_REL_ADVAL, rsp, ofl) == S_ERROR) 654 return (S_ERROR); 655 rsp->rel_rtype = ortype; 656 return (1); 657 } else 658 return (add_actrel(NULL, rsp, ofl)); 659 } 660 661 /* 662 * process GLOBAL undefined and ref_dyn_need symbols. 663 */ 664 uintptr_t 665 reloc_exec(Rel_desc *rsp, Ofl_desc *ofl) 666 { 667 Sym_desc *_sdp, *sdp = rsp->rel_sym; 668 Sym_aux *sap = sdp->sd_aux; 669 Sym *sym = sdp->sd_sym; 670 Addr stval; 671 672 /* 673 * Reference is to a function so simply create a plt entry for it. 674 */ 675 if (ELF_ST_TYPE(sym->st_info) == STT_FUNC) 676 return (reloc_plt(rsp, ofl)); 677 678 /* 679 * Catch absolutes - these may cause a text relocation. 680 */ 681 if ((sdp->sd_flags & FLG_SY_SPECSEC) && (sdp->sd_shndx == SHN_ABS)) { 682 if ((ofl->ofl_flags1 & FLG_OF1_ABSEXEC) == 0) 683 return (add_outrel(NULL, rsp, ofl)); 684 /* 685 * If -zabsexec is set then promote the ABSOLUTE 686 * symbol to current the current object and 687 * perform the relocation now. 688 */ 689 sdp->sd_ref = REF_REL_NEED; 690 return (add_actrel(NULL, rsp, ofl)); 691 } 692 693 /* 694 * If the relocation is against a writable section simply compute the 695 * necessary output relocation. As an optimization, if the symbol has 696 * already been transformed into a copy relocation then we can perform 697 * the relocation directly (copy relocations should only be generated 698 * for references from the text segment and these relocations are 699 * normally carried out before we get to the data segment relocations). 700 */ 701 if ((ELF_ST_TYPE(sym->st_info) == STT_OBJECT) && 702 (rsp->rel_osdesc->os_shdr->sh_flags & SHF_WRITE)) { 703 if (sdp->sd_flags & FLG_SY_MVTOCOMM) 704 return (add_actrel(NULL, rsp, ofl)); 705 else 706 return (add_outrel(NULL, rsp, ofl)); 707 } 708 709 /* 710 * If the reference isn't to an object (normally because some idiot 711 * hasn't defined a .type directive in some assembler source), then 712 * simply apply a generic relocation (this has a tendency to result in 713 * text relocations). 714 */ 715 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) { 716 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_UNEXPSYM), 717 conv_info_type_str(ofl->ofl_e_machine, 718 ELF_ST_TYPE(sym->st_info)), 719 rsp->rel_isdesc->is_file->ifl_name, 720 demangle(rsp->rel_sname), sdp->sd_file->ifl_name); 721 return (add_outrel(NULL, rsp, ofl)); 722 } 723 724 /* 725 * Prepare for generating a copy relocation. 726 * 727 * If this symbol is one of an alias pair, we need to insure both 728 * symbols become part of the output (the strong symbol will be used to 729 * maintain the symbols state). And, if we did raise the precedence of 730 * a symbol we need to check and see if this is a weak symbol. If it is 731 * we want to use it's strong counter part. 732 * 733 * The results of this logic should be: 734 * rel_usym: assigned to strong 735 * rel_sym: assigned to symbol to perform 736 * copy_reloc against (weak or strong). 737 */ 738 if (sap->sa_linkndx) { 739 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx]; 740 741 if (_sdp->sd_ref < sdp->sd_ref) { 742 _sdp->sd_ref = sdp->sd_ref; 743 _sdp->sd_flags |= FLG_SY_REFRSD; 744 745 /* 746 * As we're going to replicate a symbol from a shared 747 * object, retain its correct binding status. 748 */ 749 if (ELF_ST_BIND(_sdp->sd_sym->st_info) == STB_GLOBAL) 750 _sdp->sd_flags |= FLG_SY_GLOBREF; 751 752 } else if (_sdp->sd_ref > sdp->sd_ref) { 753 sdp->sd_ref = _sdp->sd_ref; 754 sdp->sd_flags |= FLG_SY_REFRSD; 755 756 /* 757 * As we're going to replicate a symbol from a shared 758 * object, retain its correct binding status. 759 */ 760 if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL) 761 sdp->sd_flags |= FLG_SY_GLOBREF; 762 } 763 764 /* 765 * If this is a weak symbol then we want to move the strong 766 * symbol into local .bss. If there is a copy_reloc to be 767 * performed, that should still occur against the WEAK symbol. 768 */ 769 if ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) || 770 (sdp->sd_flags & FLG_SY_WEAKDEF)) 771 rsp->rel_usym = _sdp; 772 } else 773 _sdp = 0; 774 775 /* 776 * If the reference is to an object then allocate space for the object 777 * within the executables .bss. Relocations will now be performed from 778 * this new location. If the original shared objects data is 779 * initialized, then generate a copy relocation that will copy the data 780 * to the executables .bss at runtime. 781 */ 782 if (!(rsp->rel_usym->sd_flags & FLG_SY_MVTOCOMM)) { 783 Word rtype = rsp->rel_rtype; 784 Copy_rel *cpy_rel; 785 786 /* 787 * Indicate that the symbol(s) against which we're relocating 788 * have been moved to the executables common. Also, insure that 789 * the symbol(s) remain marked as global, as the shared object 790 * from which they are copied must be able to relocate to the 791 * new common location within the executable. 792 * 793 * Note that even though a new symbol has been generated in the 794 * output files' .bss, the symbol must remain REF_DYN_NEED and 795 * not be promoted to REF_REL_NEED. sym_validate() still needs 796 * to carry out a number of checks against the symbols binding 797 * that are triggered by the REF_DYN_NEED state. 798 */ 799 sdp->sd_flags |= FLG_SY_MVTOCOMM; 800 sdp->sd_flags1 |= FLG_SY1_GLOB; 801 sdp->sd_flags1 &= ~FLG_SY1_LOCL; 802 sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY; 803 if (_sdp) { 804 _sdp->sd_flags |= FLG_SY_MVTOCOMM; 805 _sdp->sd_flags1 |= FLG_SY1_GLOB; 806 _sdp->sd_flags1 &= ~FLG_SY1_LOCL; 807 _sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY; 808 809 /* 810 * Make sure the symbol has a reference in case of any 811 * error diagnostics against it (perhaps this belongs 812 * to a version that isn't allowable for this build). 813 * The resulting diagnostic (see sym_undef_entry()) 814 * might seem a little bogus, as the symbol hasn't 815 * really been referenced by this file, but has been 816 * promoted as a consequence of its alias reference. 817 */ 818 if (!(_sdp->sd_aux->sa_rfile)) 819 _sdp->sd_aux->sa_rfile = sdp->sd_aux->sa_rfile; 820 } 821 822 /* 823 * Assign the symbol to the bss and insure sufficient alignment 824 * (we don't know the real alignment so we have to make the 825 * worst case guess). 826 */ 827 _sdp = rsp->rel_usym; 828 stval = _sdp->sd_sym->st_value; 829 if (sym_copy(_sdp) == S_ERROR) 830 return (S_ERROR); 831 _sdp->sd_shndx = _sdp->sd_sym->st_shndx = SHN_COMMON; 832 _sdp->sd_flags |= FLG_SY_SPECSEC; 833 _sdp->sd_sym->st_value = 834 (_sdp->sd_sym->st_size < (M_WORD_ALIGN * 2)) ? 835 M_WORD_ALIGN : M_WORD_ALIGN * 2; 836 837 /* 838 * Whether or not the symbol references initialized 839 * data we generate a copy relocation - this differs 840 * from the past where we would not create the COPY_RELOC 841 * if we were binding against .bss. This is done 842 * for *two* reasons. 843 * 844 * o If the symbol in the shared object changes to 845 * a initialized data - we need the COPY to pick it 846 * up. 847 * o without the COPY RELOC we can't tell that the 848 * symbol from the COPY'd object has been moved 849 * and all bindings to it should bind here. 850 */ 851 852 /* 853 * Keep this symbol in the copy relocation list 854 * to check the validity later. 855 */ 856 if ((cpy_rel = libld_malloc(sizeof (Copy_rel))) == 0) 857 return (S_ERROR); 858 cpy_rel->copyrel_symd = _sdp; 859 cpy_rel->copyrel_stval = stval; 860 if (list_appendc(&ofl->ofl_copyrels, cpy_rel) == 0) 861 return (S_ERROR); 862 863 rsp->rel_rtype = M_R_COPY; 864 if (add_outrel(FLG_REL_BSS, rsp, ofl) == S_ERROR) 865 return (S_ERROR); 866 rsp->rel_rtype = rtype; 867 868 /* 869 * If this symbol is a protected symbol, warn it. 870 */ 871 if (_sdp->sd_flags & FLG_SY_PROT) 872 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_COPY), 873 conv_reloc_type_str(_sdp->sd_file->ifl_ehdr->e_machine, 874 M_R_COPY), _sdp->sd_file->ifl_name, _sdp->sd_name); 875 DBG_CALL(Dbg_syms_reloc(sdp->sd_file->ifl_ehdr, sdp)); 876 } 877 return (add_actrel(NULL, rsp, ofl)); 878 } 879 880 /* 881 * All relocations should have been handled by the other routines. This 882 * routine is hear 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 uintptr_t 886 reloc_generic(Rel_desc *rsp, Ofl_desc *ofl) 887 { 888 Word flags = ofl->ofl_flags; 889 890 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_UNEXPREL), 891 conv_reloc_type_str(ofl->ofl_e_machine, rsp->rel_rtype), 892 rsp->rel_isdesc->is_file->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 (flags & FLG_OF_SHAROBJ) 899 return (add_outrel(NULL, rsp, ofl)); 900 901 /* 902 * Otherwise process relocation now. 903 */ 904 return (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 (add_actrel(NULL, rsp, ofl)); 931 932 /* 933 * If -zredlocsym is in effect, translate all local symbol relocations 934 * to be against section symbols, since section symbols are the only 935 * 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(ERR_FATAL, MSG_INTL(MSG_REL_PICREDLOC), 948 demangle(rsp->rel_sname), ifl->ifl_name, 949 conv_reloc_type_str(ifl->ifl_ehdr->e_machine, 950 rsp->rel_rtype)); 951 return (S_ERROR); 952 } 953 954 /* 955 * Indicate that this relocation should be processed the same 956 * as a section symbol. For SPARC and AMD (Rela), indicate 957 * that the addend also needs to be applied to this relocation. 958 */ 959 #if (defined(__i386) || defined(__amd64)) && !defined(_ELF64) 960 oflags = FLG_REL_SCNNDX; 961 #else 962 oflags = FLG_REL_SCNNDX | FLG_REL_ADVAL; 963 #endif 964 } 965 966 #if (defined(__i386) || defined(__amd64)) && !defined(_ELF64) 967 /* 968 * Intel (Rel) relocations do not contain an addend. Any addend is 969 * contained within the file at the location identified by the 970 * relocation offset. Therefore, if we're processing a section symbol, 971 * or a -zredlocsym relocation (that basically transforms a local symbol 972 * reference into a section reference), perform an active relocation to 973 * propagate any addend. 974 */ 975 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) || 976 (oflags == FLG_REL_SCNNDX)) 977 if (add_actrel(NULL, rsp, ofl) == S_ERROR) 978 return (S_ERROR); 979 #endif 980 return (add_outrel(oflags, rsp, ofl)); 981 } 982 983 uintptr_t 984 process_sym_reloc(Ofl_desc * ofl, Rel_desc * reld, Rel * reloc, 985 Is_desc * isp, const char *isname) 986 { 987 Word rtype = reld->rel_rtype; 988 Word flags = ofl->ofl_flags; 989 Sym_desc *sdp = reld->rel_sym; 990 Sym_aux *sap; 991 Boolean local; 992 993 DBG_CALL(Dbg_reloc_in(M_MACH, M_REL_SHT_TYPE, (void *)reloc, 994 reld->rel_sname, isname)); 995 996 /* 997 * Indicate this symbol is being used for relocation and therefore must 998 * have its output address updated accordingly (refer to update_osym()). 999 */ 1000 sdp->sd_flags |= FLG_SY_UPREQD; 1001 1002 /* 1003 * Indicate the section this symbol is defined in has been referenced, 1004 * therefor it *is not* a candidate for elimination. 1005 */ 1006 if (sdp->sd_isc) { 1007 sdp->sd_isc->is_flags |= FLG_IS_SECTREF; 1008 sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF; 1009 } 1010 1011 reld->rel_usym = sdp; 1012 1013 /* 1014 * Determine if this symbol is actually an alias to another symbol. If 1015 * so, and the alias is not REF_DYN_SEEN, set rel_usym to point to the 1016 * weak symbols strong counter-part. The one exception is if the 1017 * FLG_SY_MVTOCOMM flag is set on the weak symbol. If this is the case, 1018 * the strong is only here because of its promotion, and the weak symbol 1019 * should still be used for the relocation reference (see reloc_exec()). 1020 */ 1021 sap = sdp->sd_aux; 1022 if (sap && sap->sa_linkndx && 1023 ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) || 1024 (sdp->sd_flags & FLG_SY_WEAKDEF)) && 1025 (!(sdp->sd_flags & FLG_SY_MVTOCOMM))) { 1026 Sym_desc * _sdp; 1027 1028 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx]; 1029 if (_sdp->sd_ref != REF_DYN_SEEN) 1030 reld->rel_usym = _sdp; 1031 } 1032 1033 /* 1034 * Determine whether this symbol should be bound locally or not. 1035 * Symbols will be bound locally if one of the following is true: 1036 * 1037 * o the symbol is of type STB_LOCAL 1038 * 1039 * o the output image is not a relocatable object and the 1040 * relocation is relative to the .got 1041 * 1042 * o the section being relocated is of type SHT_SUNW_dof; 1043 * these sections are bound to the functions in the 1044 * containing object and don't care about interpositioning 1045 * 1046 * o the symbol has been reduced (scoped to a local or 1047 * symbolic) and reductions are being processed 1048 * 1049 * o the -Bsymbolic flag is in use when building a shared 1050 * object or an executable (fixed address) is being created 1051 * 1052 * o Building an executable and the symbol is defined 1053 * in the executable. 1054 * 1055 * o the relocation is against a segment which will not 1056 * be loaded into memory. If that is the case we need 1057 * to resolve the relocation now because ld.so.1 won't 1058 * be able to. 1059 */ 1060 local = FALSE; 1061 if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) { 1062 local = TRUE; 1063 } else if (!(reld->rel_flags & FLG_REL_LOAD)) { 1064 local = TRUE; 1065 } else if (sdp->sd_shndx != SHN_UNDEF) { 1066 if (reld->rel_isdesc && 1067 reld->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof) { 1068 local = TRUE; 1069 } else if (!(flags & FLG_OF_RELOBJ) && 1070 (IS_LOCALBND(rtype) || IS_SEG_RELATIVE(rtype))) { 1071 local = TRUE; 1072 } else if (sdp->sd_ref == REF_REL_NEED) { 1073 if ((sdp->sd_flags1 & (FLG_SY1_LOCL | FLG_SY1_PROT))) 1074 local = TRUE; 1075 else if (flags & (FLG_OF_SYMBOLIC | FLG_OF_EXEC)) 1076 local = TRUE; 1077 } 1078 } 1079 1080 /* 1081 * If this is a PC_RELATIVE relocation, the relocation could be 1082 * compromised if the relocated address is later used as a copy 1083 * relocated symbol (PSARC 1999/636, bugid 4187211). Scan the input 1084 * files symbol table to cross reference this relocation offset. 1085 */ 1086 if ((ofl->ofl_flags & FLG_OF_SHAROBJ) && IS_PC_RELATIVE(rtype) && 1087 (IS_GOT_PC(rtype) == 0) && (IS_PLT(rtype) == 0)) { 1088 if (disp_inspect(ofl, reld, local) == S_ERROR) 1089 return (S_ERROR); 1090 } 1091 1092 /* 1093 * GOT based relocations must bind to the object being built - since 1094 * they are relevant to the current GOT. If not building a relocatable 1095 * object - give a appropriate error message. 1096 */ 1097 if (!local && !(flags & FLG_OF_RELOBJ) && IS_GOT_BASED(rtype)) { 1098 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED), 1099 conv_reloc_type_str(ofl->ofl_e_machine, rtype), 1100 reld->rel_isdesc->is_file->ifl_name, 1101 demangle(sdp->sd_name)); 1102 return (S_ERROR); 1103 } 1104 1105 /* 1106 * TLS symbols can only have TLS relocations. 1107 */ 1108 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_TLS) && !IS_TLS(rtype)) { 1109 /* 1110 * The above test is relaxed if the target section is 1111 * non-allocable. 1112 */ 1113 if (reld->rel_osdesc->os_shdr->sh_flags & SHF_ALLOC) { 1114 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_BADTLS), 1115 conv_reloc_type_str(ofl->ofl_e_machine, rtype), 1116 reld->rel_isdesc->is_file->ifl_name, 1117 demangle(sdp->sd_name)); 1118 return (S_ERROR); 1119 } 1120 } 1121 1122 /* 1123 * Select the relocation to perform. 1124 */ 1125 if (IS_REGISTER(rtype)) 1126 return (reloc_register(reld, isp, ofl)); 1127 1128 if (flags & FLG_OF_RELOBJ) 1129 return (reloc_relobj(local, reld, ofl)); 1130 1131 if (IS_TLS_INS(rtype)) 1132 return (reloc_TLS(local, reld, ofl)); 1133 1134 if (IS_GOT_INS(rtype)) 1135 return (reloc_GOTOP(local, reld, ofl)); 1136 1137 if (IS_GOT_RELATIVE(rtype)) 1138 return (reloc_GOT_relative(local, reld, ofl)); 1139 1140 if (local) 1141 return (reloc_local(reld, ofl)); 1142 1143 if ((IS_PLT(rtype)) && ((flags & FLG_OF_BFLAG) == 0)) 1144 return (reloc_plt(reld, ofl)); 1145 1146 if ((sdp->sd_ref == REF_REL_NEED) || 1147 (flags & FLG_OF_BFLAG) || (flags & FLG_OF_SHAROBJ) || 1148 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_NOTYPE)) 1149 return (add_outrel(NULL, reld, ofl)); 1150 1151 if (sdp->sd_ref == REF_DYN_NEED) 1152 return (reloc_exec(reld, ofl)); 1153 1154 /* 1155 * IS_NOT_REL(rtype) 1156 */ 1157 return (reloc_generic(reld, ofl)); 1158 } 1159 1160 /* 1161 * Generate relocation descriptor and dispatch 1162 */ 1163 static uintptr_t 1164 process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx, 1165 Rel *reloc) 1166 { 1167 Ifl_desc *ifl = isp->is_file; 1168 Word rtype = reld->rel_rtype; 1169 Sym_desc *sdp; 1170 1171 /* 1172 * Make sure the relocation is in the valid range. 1173 */ 1174 if (rtype >= M_R_NUM) { 1175 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT), ifl->ifl_name, 1176 isp->is_name, rtype); 1177 return (S_ERROR); 1178 } 1179 1180 ofl->ofl_entrelscnt++; 1181 1182 /* 1183 * Special case: a register symbol associated with symbol index 0 is 1184 * initialized (i.e., relocated) to a constant from the r_addend field 1185 * rather than from a symbol value. 1186 */ 1187 if (IS_REGISTER(rtype) && (rsndx == 0)) { 1188 reld->rel_sym = 0; 1189 reld->rel_sname = MSG_ORIG(MSG_STR_EMPTY); 1190 1191 DBG_CALL(Dbg_reloc_in(M_MACH, isp->is_shdr->sh_type, 1192 (void *)reloc, reld->rel_sname, isp->is_name)); 1193 return (reloc_register(reld, isp, ofl)); 1194 } 1195 1196 /* 1197 * Determine whether we're dealing with a named symbol. Note, bogus 1198 * relocations can result in a null symbol descriptor (sdp), the error 1199 * condition should be caught below after determining whether a valid 1200 * symbol name exists. 1201 */ 1202 sdp = ifl->ifl_oldndx[rsndx]; 1203 if (sdp != NULL && sdp->sd_name && *sdp->sd_name) 1204 reld->rel_sname = sdp->sd_name; 1205 else { 1206 static char *strunknown; 1207 1208 if (strunknown == 0) 1209 strunknown = (char *)MSG_INTL(MSG_STR_UNKNOWN); 1210 reld->rel_sname = strunknown; 1211 } 1212 1213 /* 1214 * If for some reason we have a null relocation record issue a 1215 * warning and continue (the compiler folks can get into this 1216 * state some time). Normal users should never see this error. 1217 */ 1218 if (rtype == M_R_NONE) { 1219 DBG_CALL(Dbg_reloc_in(M_MACH, M_REL_SHT_TYPE, (void *)reloc, 1220 reld->rel_sname, isp->is_name)); 1221 eprintf(ERR_WARNING, MSG_INTL(MSG_REL_NULL), ifl->ifl_name, 1222 isp->is_name); 1223 return (1); 1224 } 1225 1226 if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && IS_NOTSUP(rtype)) { 1227 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP), 1228 conv_reloc_type_str(ifl->ifl_ehdr->e_machine, rtype), 1229 ifl->ifl_name, isp->is_name); 1230 return (S_ERROR); 1231 } 1232 1233 /* 1234 * If we are here, we know that the relocation requires reference 1235 * symbol. If no symbol is assigned, this is a fatal error. 1236 */ 1237 if (sdp == NULL) { 1238 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL), 1239 conv_reloc_type_str(ifl->ifl_ehdr->e_machine, rtype), 1240 isp->is_name, ifl->ifl_name, EC_XWORD(reloc->r_offset)); 1241 return (S_ERROR); 1242 } 1243 1244 if (sdp->sd_flags1 & FLG_SY1_IGNORE) 1245 return (1); 1246 1247 /* 1248 * If this symbol is part of a DISCARDED section attempt to find another 1249 * definition. 1250 */ 1251 if (sdp->sd_flags & FLG_SY_ISDISC) { 1252 Sym_desc * nsdp; 1253 1254 if ((reld->rel_sname != sdp->sd_name) || 1255 (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) || 1256 ((nsdp = sym_find(sdp->sd_name, SYM_NOHASH, 0, 1257 ofl)) == 0)) { 1258 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_SYMDISC), 1259 ifl->ifl_name, isp->is_name, demangle(sdp->sd_name), 1260 sdp->sd_isc->is_name); 1261 return (S_ERROR); 1262 } 1263 ifl->ifl_oldndx[rsndx] = sdp = nsdp; 1264 } 1265 1266 /* 1267 * If this is a global symbol, determine whether its visibility needs 1268 * adjusting. 1269 */ 1270 if (sdp->sd_aux && ((sdp->sd_flags & FLG_SY_VISIBLE) == 0)) 1271 sym_adjust_vis(sdp, ofl); 1272 1273 /* 1274 * Ignore any relocation against a section that will not be in the 1275 * output file (has been stripped). 1276 */ 1277 if ((sdp->sd_isc == 0) && 1278 (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) 1279 return (1); 1280 1281 /* 1282 * If the symbol for this relocation is invalid (which should have 1283 * generated a message during symbol processing), or the relocation 1284 * record's symbol reference is in any other way invalid, then it's 1285 * about time we gave up. 1286 */ 1287 if ((sdp->sd_flags & FLG_SY_INVALID) || (rsndx == 0) || 1288 (rsndx >= ifl->ifl_symscnt)) { 1289 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM), 1290 M_REL_CONTYPSTR(rtype), ifl->ifl_name, isp->is_name, 1291 demangle(reld->rel_sname), EC_XWORD(reloc->r_offset), 1292 EC_WORD(rsndx)); 1293 return (S_ERROR); 1294 } 1295 1296 reld->rel_sym = sdp; 1297 return (process_sym_reloc(ofl, reld, reloc, isp, isp->is_name)); 1298 } 1299 1300 static uintptr_t 1301 reloc_section(Ofl_desc *ofl, Is_desc *isect, Is_desc *rsect, Os_desc *osect) 1302 { 1303 Rel *rend; /* end of relocation section data */ 1304 Rel *reloc; /* current relocation entry */ 1305 Xword rsize; /* size of relocation section data */ 1306 Xword entsize; /* size of relocation entry */ 1307 Rel_desc reld; /* relocation descriptor */ 1308 Shdr * shdr; 1309 Word flags = 0; 1310 1311 shdr = rsect->is_shdr; 1312 rsize = shdr->sh_size; 1313 reloc = (Rel *)rsect->is_indata->d_buf; 1314 1315 /* 1316 * Decide entry size. 1317 */ 1318 if (((entsize = shdr->sh_entsize) == 0) || (entsize > rsize)) { 1319 if (shdr->sh_type == SHT_RELA) 1320 entsize = sizeof (Rela); 1321 else 1322 entsize = sizeof (Rel); 1323 } 1324 1325 /* 1326 * Build up the basic information in for the Rel_desc structure. 1327 */ 1328 reld.rel_osdesc = osect; 1329 reld.rel_isdesc = isect; 1330 reld.rel_move = 0; 1331 1332 if ((ofl->ofl_flags & FLG_OF_RELOBJ) || 1333 (osect && (osect->os_sgdesc->sg_phdr.p_type == PT_LOAD))) 1334 flags |= FLG_REL_LOAD; 1335 1336 if (shdr->sh_info == 0) 1337 flags |= FLG_REL_NOINFO; 1338 1339 DBG_CALL(Dbg_reloc_proc(osect, isect, rsect)); 1340 1341 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize); 1342 reloc < rend; 1343 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) { 1344 Word rsndx; 1345 1346 /* 1347 * Initialize the relocation record information and process 1348 * the individual relocation. Reinitialize the flags to 1349 * insure we don't carry any state over from the previous 1350 * relocation records processing. 1351 */ 1352 reld.rel_flags = flags; 1353 rsndx = init_rel(&reld, (void *)reloc); 1354 1355 if (process_reld(ofl, rsect, &reld, rsndx, reloc) == S_ERROR) 1356 return (S_ERROR); 1357 } 1358 return (1); 1359 } 1360 1361 1362 uintptr_t 1363 reloc_segments(int wr_flag, Ofl_desc *ofl) 1364 { 1365 Listnode *lnp1; 1366 Sg_desc *sgp; 1367 Is_desc *isp; 1368 1369 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { 1370 Os_desc *osp; 1371 Listnode *lnp2; 1372 1373 if ((sgp->sg_phdr.p_flags & PF_W) != wr_flag) 1374 continue; 1375 1376 for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp2, osp)) { 1377 Is_desc *risp; 1378 Listnode *lnp3; 1379 1380 osp->os_szoutrels = 0; 1381 for (LIST_TRAVERSE(&(osp->os_relisdescs), lnp3, risp)) { 1382 Word indx; 1383 1384 /* 1385 * Determine the input section that this 1386 * relocation information refers to. 1387 */ 1388 indx = risp->is_shdr->sh_info; 1389 isp = risp->is_file->ifl_isdesc[indx]; 1390 1391 /* 1392 * Do not process relocations against sections 1393 * which are being discarded (COMDAT) 1394 */ 1395 if (isp->is_flags & FLG_IS_DISCARD) 1396 continue; 1397 1398 if (reloc_section(ofl, isp, risp, osp) == 1399 S_ERROR) 1400 return (S_ERROR); 1401 } 1402 1403 /* 1404 * Check for relocations against non-writable 1405 * allocatable sections. 1406 */ 1407 if ((osp->os_szoutrels) && 1408 (sgp->sg_phdr.p_type == PT_LOAD) && 1409 ((sgp->sg_phdr.p_flags & PF_W) == 0)) { 1410 ofl->ofl_flags |= FLG_OF_TEXTREL; 1411 ofl->ofl_dtflags |= DF_TEXTREL; 1412 } 1413 } 1414 } 1415 1416 return (1); 1417 } 1418 1419 /* 1420 * Move Section related function 1421 * Get move entry 1422 */ 1423 static Move * 1424 get_move_entry(Is_desc *rsect, Xword roffset) 1425 { 1426 Ifl_desc *ifile = rsect->is_file; 1427 Shdr *rshdr = rsect->is_shdr; 1428 Is_desc *misp; 1429 Shdr *mshdr; 1430 Xword midx; 1431 Move *ret; 1432 1433 /* 1434 * Set info for the target move section 1435 */ 1436 misp = ifile->ifl_isdesc[rshdr->sh_info]; 1437 mshdr = (ifile->ifl_isdesc[rshdr->sh_info])->is_shdr; 1438 1439 if (mshdr->sh_entsize == 0) 1440 return ((Move *)0); 1441 midx = roffset / mshdr->sh_entsize; 1442 1443 ret = (Move *)misp->is_indata->d_buf; 1444 ret += midx; 1445 1446 /* 1447 * If this is an illgal entry, retun NULL. 1448 */ 1449 if ((midx * mshdr->sh_entsize) >= mshdr->sh_size) 1450 return ((Move *)0); 1451 return (ret); 1452 } 1453 1454 /* 1455 * Relocation against Move Table. 1456 */ 1457 static uintptr_t 1458 process_movereloc(Ofl_desc *ofl, Is_desc *rsect) 1459 { 1460 Ifl_desc *file = rsect->is_file; 1461 Rel *rend, *reloc; 1462 Xword rsize, entsize; 1463 static Rel_desc reld_zero; 1464 Rel_desc reld; 1465 1466 rsize = rsect->is_shdr->sh_size; 1467 reloc = (Rel *)rsect->is_indata->d_buf; 1468 1469 reld = reld_zero; 1470 1471 /* 1472 * Decide entry size 1473 */ 1474 entsize = rsect->is_shdr->sh_entsize; 1475 if ((entsize == 0) || 1476 (entsize > rsect->is_shdr->sh_size)) { 1477 if (rsect->is_shdr->sh_type == SHT_RELA) 1478 entsize = sizeof (Rela); 1479 else 1480 entsize = sizeof (Rel); 1481 } 1482 1483 /* 1484 * Go through the relocation entries. 1485 */ 1486 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize); 1487 reloc < rend; 1488 reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) { 1489 Sym_desc * psdp; 1490 Move * mp; 1491 Word rsndx; 1492 1493 /* 1494 * Initialize the relocation record information. 1495 */ 1496 reld.rel_flags = FLG_REL_LOAD; 1497 rsndx = init_rel(&reld, (void *)reloc); 1498 1499 if (((mp = get_move_entry(rsect, reloc->r_offset)) == 0) || 1500 ((reld.rel_move = libld_malloc(sizeof (Mv_desc))) == 0)) 1501 return (S_ERROR); 1502 1503 psdp = file->ifl_oldndx[ELF_M_SYM(mp->m_info)]; 1504 reld.rel_move->mvd_move = mp; 1505 reld.rel_move->mvd_sym = psdp; 1506 1507 if (psdp->sd_flags & FLG_SY_PAREXPN) { 1508 int _num, num; 1509 1510 reld.rel_osdesc = ofl->ofl_issunwdata1->is_osdesc; 1511 reld.rel_isdesc = ofl->ofl_issunwdata1; 1512 reld.rel_roffset = mp->m_poffset; 1513 1514 for (num = mp->m_repeat, _num = 0; _num < num; _num++) { 1515 reld.rel_roffset += 1516 /* LINTED */ 1517 (_num * ELF_M_SIZE(mp->m_info)); 1518 /* 1519 * Generate Reld 1520 */ 1521 if (process_reld(ofl, 1522 rsect, &reld, rsndx, reloc) == S_ERROR) 1523 return (S_ERROR); 1524 } 1525 } else { 1526 /* 1527 * Generate Reld 1528 */ 1529 reld.rel_flags |= FLG_REL_MOVETAB; 1530 reld.rel_osdesc = ofl->ofl_osmove; 1531 reld.rel_isdesc = 1532 ofl->ofl_osmove->os_isdescs.head->data; 1533 if (process_reld(ofl, 1534 rsect, &reld, rsndx, reloc) == S_ERROR) 1535 return (S_ERROR); 1536 } 1537 } 1538 return (1); 1539 } 1540 1541 /* 1542 * This function is similar to reloc_init(). 1543 * 1544 * This function is called when the SHT_SUNW_move table is expanded 1545 * and there were relocation against the SHT_SUNW_move section. 1546 */ 1547 static uintptr_t 1548 reloc_movesections(Ofl_desc *ofl) 1549 { 1550 Listnode *lnp1; 1551 Is_desc *risp; 1552 1553 /* 1554 * Generate/Expand relocation entries 1555 */ 1556 for (LIST_TRAVERSE(&ofl->ofl_mvrelisdescs, lnp1, risp)) { 1557 if (process_movereloc(ofl, risp) == S_ERROR) 1558 return (S_ERROR); 1559 } 1560 1561 return (1); 1562 } 1563 1564 /* 1565 * Count the number of output relocation entries, global offset table entries, 1566 * and procedure linkage table entries. This function searches the segment and 1567 * outsect lists and passes each input reloc section to process_reloc(). 1568 * It allocates space for any output relocations needed. And builds up 1569 * the relocation structures for later processing. 1570 */ 1571 uintptr_t 1572 reloc_init(Ofl_desc *ofl) 1573 { 1574 Listnode *lnp; 1575 Is_desc *isp; 1576 1577 /* 1578 * At this point we have finished processing all input symbols. Make 1579 * sure we add any absolute (internal) symbols before continuing with 1580 * any relocation processing. 1581 */ 1582 if (sym_spec(ofl) == S_ERROR) 1583 return (S_ERROR); 1584 1585 ofl->ofl_gotcnt = M_GOT_XNumber; 1586 1587 /* 1588 * First process all of the relocations against NON-writable 1589 * segments followed by relocations against the writeable segments. 1590 * 1591 * This separation is so that when the writable segments are processed 1592 * we know whether or not a COPYRELOC will be produced for any symbols. 1593 * If relocations aren't processed in this order, a COPYRELOC and a 1594 * regular relocation can be produced against the same symbol. The 1595 * regular relocation would be redundant. 1596 */ 1597 if (reloc_segments(0, ofl) == S_ERROR) 1598 return (S_ERROR); 1599 1600 if (reloc_segments(PF_W, ofl) == S_ERROR) 1601 return (S_ERROR); 1602 1603 /* 1604 * Process any extra relocations. These are relocation sections that 1605 * have a NULL sh_info. 1606 */ 1607 for (LIST_TRAVERSE(&ofl->ofl_extrarels, lnp, isp)) { 1608 if (reloc_section(ofl, NULL, isp, NULL) == S_ERROR) 1609 return (S_ERROR); 1610 } 1611 1612 /* 1613 * If there were relocation against move table, 1614 * process the relocation sections. 1615 */ 1616 if (reloc_movesections(ofl) == S_ERROR) 1617 return (S_ERROR); 1618 1619 /* 1620 * Now all the relocations are pre-processed, 1621 * check the validity of copy relocations. 1622 */ 1623 if (ofl->ofl_copyrels.head != 0) { 1624 Copy_rel * cpyrel; 1625 1626 for (LIST_TRAVERSE(&ofl->ofl_copyrels, lnp, cpyrel)) { 1627 Sym_desc * sdp; 1628 1629 sdp = cpyrel->copyrel_symd; 1630 /* 1631 * If there were no displacement relocation 1632 * in this file, don't worry about it. 1633 */ 1634 if (sdp->sd_file->ifl_flags & 1635 (FLG_IF_DISPPEND | FLG_IF_DISPDONE)) 1636 is_disp_copied(ofl, cpyrel); 1637 } 1638 } 1639 1640 /* 1641 * GOT sections are created for dynamic executables and shared objects 1642 * if the FLG_OF_BLDGOT is set, or explicit reference has been made to 1643 * a GOT symbol. 1644 */ 1645 if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && 1646 ((ofl->ofl_flags & FLG_OF_BLDGOT) || 1647 (sym_find(MSG_ORIG(MSG_SYM_GOFTBL), SYM_NOHASH, 0, ofl) != 0) || 1648 (sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U), SYM_NOHASH, 0, ofl) != 0))) { 1649 if (make_got(ofl) == S_ERROR) 1650 return (S_ERROR); 1651 1652 #if defined(sparc) || defined(__sparcv9) 1653 if (allocate_got(ofl) == S_ERROR) 1654 return (S_ERROR); 1655 #elif defined(i386) || defined(__amd64) 1656 /* nothing to do */ 1657 #else 1658 #error Unknown architecture! 1659 #endif 1660 } 1661 1662 return (1); 1663 } 1664 1665 /* 1666 * Simple comparison routine to be used by qsort() for 1667 * the sorting of the output relocation list. 1668 * 1669 * The reloc_compare() routine results in a relocation 1670 * table which is located on: 1671 * 1672 * file referenced (NEEDED NDX) 1673 * referenced symbol 1674 * relocation offset 1675 * 1676 * This provides the most efficient traversal of the relocation 1677 * table at run-time. 1678 */ 1679 int 1680 reloc_compare(Reloc_list *i, Reloc_list *j) 1681 { 1682 1683 /* 1684 * first - sort on neededndx 1685 */ 1686 if (i->rl_key1 > j->rl_key1) 1687 return (1); 1688 if (i->rl_key1 < j->rl_key1) 1689 return (-1); 1690 1691 /* 1692 * Then sort on symbol 1693 */ 1694 if ((uintptr_t)i->rl_key2 > (uintptr_t)j->rl_key2) 1695 return (1); 1696 if ((uintptr_t)i->rl_key2 < (uintptr_t)j->rl_key2) 1697 return (-1); 1698 1699 /* 1700 * i->key2 == j->key2 1701 * 1702 * At this point we fall back to key2 (offsets) to 1703 * sort the output relocations. Ideally this will 1704 * make for the most efficient processing of these 1705 * relocations at run-time. 1706 */ 1707 if (i->rl_key3 > j->rl_key3) 1708 return (1); 1709 if (i->rl_key3 < j->rl_key3) 1710 return (-1); 1711 return (0); 1712 } 1713 1714 1715 uintptr_t 1716 do_sorted_outrelocs(Ofl_desc *ofl) 1717 { 1718 Rel_desc *orsp; 1719 Rel_cache *rcp; 1720 Listnode *lnp; 1721 Reloc_list *sorted_list; 1722 Word index = 0; 1723 int debug = 0; 1724 uintptr_t error = 1; 1725 1726 if ((sorted_list = libld_malloc((size_t)(sizeof (Reloc_list) * 1727 ofl->ofl_reloccnt))) == NULL) 1728 return (S_ERROR); 1729 1730 /* 1731 * All but the PLT output relocations are sorted in the output file 1732 * based upon their sym_desc. By doing this multiple relocations 1733 * against the same symbol are grouped together, thus when the object 1734 * is later relocated by ld.so.1 it will take advantage of the symbol 1735 * cache that ld.so.1 has. This can significantly reduce the runtime 1736 * relocation cost of a dynamic object. 1737 * 1738 * PLT relocations are not sorted because the order of the PLT 1739 * relocations is used by ld.so.1 to determine what symbol a PLT 1740 * relocation is against. 1741 */ 1742 for (LIST_TRAVERSE(&ofl->ofl_outrels, lnp, rcp)) { 1743 /*LINTED*/ 1744 for (orsp = (Rel_desc *)(rcp + 1); 1745 orsp < rcp->rc_free; orsp++) { 1746 if (debug == 0) { 1747 DBG_CALL(Dbg_reloc_dooutrel(M_REL_SHT_TYPE)); 1748 debug = 1; 1749 } 1750 1751 /* 1752 * If it's a PLT relocation we output it now in the 1753 * order that it was originally processed. 1754 */ 1755 if (orsp->rel_flags & FLG_REL_PLT) { 1756 if (perform_outreloc(orsp, ofl) == S_ERROR) 1757 error = S_ERROR; 1758 continue; 1759 } 1760 1761 if ((orsp->rel_rtype == M_R_RELATIVE) || 1762 (orsp->rel_rtype == M_R_REGISTER)) { 1763 sorted_list[index].rl_key1 = 0; 1764 sorted_list[index].rl_key2 = 1765 /* LINTED */ 1766 (Sym_desc *)(uintptr_t)orsp->rel_rtype; 1767 } else { 1768 sorted_list[index].rl_key1 = 1769 orsp->rel_sym->sd_file->ifl_neededndx; 1770 sorted_list[index].rl_key2 = 1771 orsp->rel_sym; 1772 } 1773 1774 if (orsp->rel_flags & FLG_REL_GOT) 1775 sorted_list[index].rl_key3 = 1776 calc_got_offset(orsp, ofl); 1777 else { 1778 if (orsp->rel_rtype == M_R_REGISTER) 1779 sorted_list[index].rl_key3 = 0; 1780 else { 1781 sorted_list[index].rl_key3 = 1782 orsp->rel_roffset + 1783 (Xword)_elf_getxoff(orsp-> 1784 rel_isdesc-> 1785 is_indata) + 1786 orsp->rel_isdesc->is_osdesc-> 1787 os_shdr->sh_addr; 1788 } 1789 } 1790 1791 sorted_list[index++].rl_rsp = orsp; 1792 } 1793 } 1794 1795 qsort(sorted_list, (size_t)ofl->ofl_reloccnt, sizeof (Reloc_list), 1796 (int (*)(const void *, const void *))reloc_compare); 1797 1798 /* 1799 * All output relocations have now been sorted, go through 1800 * and process each relocation. 1801 */ 1802 for (index = 0; index < ofl->ofl_reloccnt; index++) { 1803 if (perform_outreloc(sorted_list[index].rl_rsp, ofl) == 1804 S_ERROR) 1805 error = S_ERROR; 1806 } 1807 1808 return (error); 1809 } 1810 1811 /* 1812 * Process relocations. Finds every input relocation section for each output 1813 * section and invokes reloc_sec() to relocate that section. 1814 */ 1815 uintptr_t 1816 reloc_process(Ofl_desc *ofl) 1817 { 1818 Listnode *lnp1; 1819 Sg_desc *sgp; 1820 Word ndx = 0, flags = ofl->ofl_flags; 1821 Shdr *shdr; 1822 1823 /* 1824 * Determine the index of the symbol table that will be referenced by 1825 * the relocation entries. 1826 */ 1827 if ((flags & (FLG_OF_DYNAMIC|FLG_OF_RELOBJ)) == FLG_OF_DYNAMIC) 1828 /* LINTED */ 1829 ndx = (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn); 1830 else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ)) 1831 /* LINTED */ 1832 ndx = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn); 1833 1834 /* 1835 * Re-initialize counters. These are used to provide relocation 1836 * offsets within the output buffers. 1837 */ 1838 ofl->ofl_relocpltsz = 0; 1839 ofl->ofl_relocgotsz = 0; 1840 ofl->ofl_relocbsssz = 0; 1841 1842 /* 1843 * Now that the output file is created and symbol update has occurred, 1844 * process the relocations collected in process_reloc(). 1845 */ 1846 if (do_sorted_outrelocs(ofl) == S_ERROR) 1847 return (S_ERROR); 1848 1849 if (do_activerelocs(ofl) == S_ERROR) 1850 return (S_ERROR); 1851 1852 if ((ofl->ofl_flags1 & FLG_OF1_RELCNT) == 0) { 1853 /* 1854 * Process the relocation sections: 1855 * 1856 * o for each relocation section generated for the output 1857 * image update its shdr information to reflect the 1858 * symbol table it needs (sh_link) and the section to 1859 * which the relocation must be applied (sh_info). 1860 */ 1861 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) { 1862 Listnode * lnp2; 1863 Os_desc * osp; 1864 1865 for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp2, osp)) { 1866 if (osp->os_relosdesc == 0) 1867 continue; 1868 1869 shdr = osp->os_relosdesc->os_shdr; 1870 shdr->sh_link = ndx; 1871 /* LINTED */ 1872 shdr->sh_info = (Word)elf_ndxscn(osp->os_scn); 1873 } 1874 } 1875 1876 /* 1877 * Since the .rel[a] section is not tied to any specific 1878 * section, we'd of not found it above. 1879 */ 1880 if (ofl->ofl_osrel) { 1881 shdr = ofl->ofl_osrel->os_shdr; 1882 shdr->sh_link = ndx; 1883 shdr->sh_info = 0; 1884 } 1885 } else { 1886 /* 1887 * We only have two relocation sections here, (PLT's, 1888 * coalesced) so just hit them directly instead of stepping 1889 * over the output sections. 1890 */ 1891 if (ofl->ofl_osrelhead) { 1892 shdr = ofl->ofl_osrelhead->os_shdr; 1893 shdr->sh_link = ndx; 1894 shdr->sh_info = 0; 1895 } 1896 if (ofl->ofl_osplt && ofl->ofl_osplt->os_relosdesc) { 1897 shdr = ofl->ofl_osplt->os_relosdesc->os_shdr; 1898 shdr->sh_link = ndx; 1899 /* LINTED */ 1900 shdr->sh_info = 1901 (Word)elf_ndxscn(ofl->ofl_osplt->os_scn); 1902 } 1903 } 1904 1905 /* 1906 * If the -z text option was given, and we have output relocations 1907 * against a non-writable, allocatable section, issue a diagnostic and 1908 * return (the actual entries that caused this error would have been 1909 * output during the relocating section phase). 1910 */ 1911 if ((flags & (FLG_OF_PURETXT | FLG_OF_TEXTREL)) == 1912 (FLG_OF_PURETXT | FLG_OF_TEXTREL)) { 1913 eprintf(ERR_FATAL, MSG_INTL(MSG_REL_REMAIN_3)); 1914 return (S_ERROR); 1915 } 1916 1917 /* 1918 * Finally, initialize the first got entry with the address of the 1919 * .dynamic section (_DYNAMIC). 1920 */ 1921 if (flags & FLG_OF_DYNAMIC) { 1922 if (fillin_gotplt1(ofl) == S_ERROR) 1923 return (S_ERROR); 1924 } 1925 1926 return (1); 1927 } 1928 1929 /* 1930 * If the -z text option was given, and we have output relocations against a 1931 * non-writable, allocatable section, issue a diagnostic. Print offending 1932 * symbols in tabular form similar to the way undefined symbols are presented. 1933 * Called from reloc_count(). The actual fatal error condition is triggered on 1934 * in reloc_process() above. 1935 * 1936 * Note. For historic reasons -ztext is not a default option (however all OS 1937 * shared object builds use this option). It can be argued that this option 1938 * should also be default when generating an a.out (see 1163979). However, if 1939 * an a.out contains text relocations it is either because the user is creating 1940 * something pretty weird (they've used the -b or -znodefs options), or because 1941 * the library against which they're building wasn't constructed correctly (ie. 1942 * a function has a NOTYPE type, in which case the a.out won't generate an 1943 * associated plt). In the latter case the builder of the a.out can't do 1944 * anything to fix the error - thus we've chosen not to give the user an error, 1945 * or warning, for this case. 1946 */ 1947 1948 void 1949 reloc_remain_title(int warning) 1950 { 1951 const char *str1; 1952 1953 if (warning) 1954 str1 = MSG_INTL(MSG_REL_RMN_ITM_13); 1955 else 1956 str1 = MSG_INTL(MSG_REL_RMN_ITM_11); 1957 1958 eprintf(ERR_NONE, MSG_INTL(MSG_REL_REMAIN_FMT_1), 1959 str1, 1960 MSG_INTL(MSG_REL_RMN_ITM_31), 1961 MSG_INTL(MSG_REL_RMN_ITM_12), 1962 MSG_INTL(MSG_REL_RMN_ITM_2), 1963 MSG_INTL(MSG_REL_RMN_ITM_32)); 1964 1965 } 1966 1967 void 1968 reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl) 1969 { 1970 static Boolean reloc_title = TRUE; 1971 1972 /* 1973 * -ztextoff 1974 */ 1975 if (ofl->ofl_flags1 & FLG_OF1_TEXTOFF) 1976 return; 1977 1978 /* 1979 * Only give relocation errors against loadable read-only segments. 1980 */ 1981 if ((orsp->rel_rtype == M_R_REGISTER) || (!osp) || 1982 (osp->os_sgdesc->sg_phdr.p_type != PT_LOAD) || 1983 (osp->os_sgdesc->sg_phdr.p_flags & PF_W)) 1984 return; 1985 1986 /* 1987 * If we are in -ztextwarn mode, it's a silent error if a relocation is 1988 * due to a 'WEAK REFERENCE'. This is because if the symbol is not 1989 * provided at run-time we will not perform a text-relocation. 1990 */ 1991 if (((ofl->ofl_flags & FLG_OF_PURETXT) == 0) && 1992 (ELF_ST_BIND(orsp->rel_sym->sd_sym->st_info) == STB_WEAK) && 1993 (orsp->rel_sym->sd_shndx == SHN_UNDEF)) 1994 return; 1995 1996 if (reloc_title) { 1997 /* 1998 * If building with '-ztext' then emit a fatal error. If 1999 * building a executable then only emit a 'warning'. 2000 */ 2001 if (ofl->ofl_flags & FLG_OF_PURETXT) 2002 reloc_remain_title(0); 2003 else 2004 reloc_remain_title(1); 2005 reloc_title = FALSE; 2006 } 2007 2008 eprintf(ERR_NONE, MSG_INTL(MSG_REL_REMAIN_2), demangle(orsp->rel_sname), 2009 EC_OFF(orsp->rel_roffset), orsp->rel_isdesc->is_file->ifl_name); 2010 } 2011 2012 /* 2013 * The following functions are called from 2014 * machine functions defined in {sparc,i386,sparcv9}/machrel.c 2015 */ 2016 2017 /* 2018 * Move Section related function 2019 */ 2020 static uintptr_t 2021 newroffset_for_move(Sym_desc *symd, 2022 Move *mventry, Xword offset1, Xword *offset2) 2023 { 2024 Psym_info *psym = symd->sd_psyminfo; 2025 Mv_itm *itm; 2026 Listnode *lnp1; 2027 int found = 0; 2028 2029 /* 2030 * Search for matching move entry 2031 */ 2032 found = 0; 2033 for (LIST_TRAVERSE(&psym->psym_mvs, lnp1, itm)) { 2034 if (itm->mv_ientry == mventry) { 2035 found = 1; 2036 break; 2037 } 2038 } 2039 if (found == 0) { 2040 /* 2041 * This should never happen. 2042 */ 2043 return (S_ERROR); 2044 } 2045 2046 /* 2047 * Update r_offset 2048 */ 2049 *offset2 = (Xword)((itm->mv_oidx - 1)*sizeof (Move) + 2050 offset1 % sizeof (Move)); 2051 return (1); 2052 } 2053 2054 void 2055 adj_movereloc(Ofl_desc *ofl, Rel_desc *arsp) 2056 { 2057 Move *move = arsp->rel_move->mvd_move; 2058 Sym_desc *psdp = arsp->rel_move->mvd_sym; 2059 Xword newoffset; 2060 2061 if (arsp->rel_flags & FLG_REL_MOVETAB) { 2062 /* 2063 * We are relocating the move table itself. 2064 */ 2065 (void) newroffset_for_move(psdp, move, arsp->rel_roffset, 2066 &newoffset); 2067 DBG_CALL(Dbg_move_adjmovereloc(arsp->rel_roffset, newoffset, 2068 psdp->sd_name)); 2069 arsp->rel_roffset = newoffset; 2070 } else { 2071 /* 2072 * We are expanding the partial symbol. So we are generating 2073 * the relocation entry relocating the expanded partial symbol. 2074 */ 2075 arsp->rel_roffset += 2076 psdp->sd_sym->st_value - 2077 ofl->ofl_issunwdata1->is_osdesc->os_shdr->sh_addr; 2078 DBG_CALL(Dbg_move_adjexpandreloc(arsp->rel_roffset, 2079 psdp->sd_name)); 2080 } 2081 } 2082 2083 /* 2084 * Partially Initialized Symbol Handling routines 2085 * For sparc architecture, the second argument is reld->rel_raddend. 2086 * For i386 acrchitecure, the second argument is the value stored 2087 * at the relocation target address. 2088 */ 2089 Sym_desc * 2090 am_I_partial(Rel_desc *reld, Xword val) 2091 { 2092 Ifl_desc * ifile = reld->rel_sym->sd_isc->is_file; 2093 int nlocs = ifile->ifl_locscnt, i; 2094 2095 for (i = 1; i < nlocs; i++) { 2096 Sym * osym; 2097 Sym_desc * symd = ifile->ifl_oldndx[i]; 2098 2099 if ((osym = symd->sd_osym) == 0) 2100 continue; 2101 if ((symd->sd_flags & FLG_SY_PAREXPN) == 0) 2102 continue; 2103 if ((osym->st_value <= val) && 2104 (osym->st_value + osym->st_size > val)) 2105 return (symd); 2106 } 2107 return ((Sym_desc *) 0); 2108 } 2109 2110 /* 2111 * Because of the combinations of 32-bit lib providing 64-bit support, and 2112 * visa-versa, the use of krtld's dorelocs can result in differing message 2113 * requirements that make msg.c/msg.h creation and chkmsg "interesting". 2114 * Thus the actual message files contain a couple of entries to satisfy 2115 * each architectures build. Here we add dummy calls to quieten chkmsg. 2116 * 2117 * chkmsg: MSG_INTL(MSG_REL_NOFIT) 2118 * chkmsg: MSG_INTL(MSG_REL_NONALIGN) 2119 */ 2120