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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Copyright (c) 1988 AT&T 29 * All Rights Reserved 30 */ 31 32 #pragma ident "%Z%%M% %I% %E% SMI" 33 34 /* 35 * SPARC machine dependent and ELF file class dependent functions. 36 * Contains routines for performing function binding and symbol relocations. 37 */ 38 39 #include <stdio.h> 40 #include <sys/elf.h> 41 #include <sys/elf_SPARC.h> 42 #include <sys/mman.h> 43 #include <dlfcn.h> 44 #include <synch.h> 45 #include <string.h> 46 #include <debug.h> 47 #include <reloc.h> 48 #include <conv.h> 49 #include "_rtld.h" 50 #include "_audit.h" 51 #include "_elf.h" 52 #include "msg.h" 53 54 55 extern void iflush_range(caddr_t, size_t); 56 extern void plt_full_range(uintptr_t, uintptr_t); 57 58 59 int 60 elf_mach_flags_check(Rej_desc *rej, Ehdr *ehdr) 61 { 62 /* 63 * Check machine type and flags. 64 */ 65 if (ehdr->e_machine != EM_SPARC) { 66 if (ehdr->e_machine != EM_SPARC32PLUS) { 67 rej->rej_type = SGS_REJ_MACH; 68 rej->rej_info = (uint_t)ehdr->e_machine; 69 return (0); 70 } 71 if ((ehdr->e_flags & EF_SPARC_32PLUS) == 0) { 72 rej->rej_type = SGS_REJ_MISFLAG; 73 rej->rej_info = (uint_t)ehdr->e_flags; 74 return (0); 75 } 76 if ((ehdr->e_flags & ~at_flags) & EF_SPARC_32PLUS_MASK) { 77 rej->rej_type = SGS_REJ_BADFLAG; 78 rej->rej_info = (uint_t)ehdr->e_flags; 79 return (0); 80 } 81 } else if ((ehdr->e_flags & ~EF_SPARCV9_MM) != 0) { 82 rej->rej_type = SGS_REJ_BADFLAG; 83 rej->rej_info = (uint_t)ehdr->e_flags; 84 return (0); 85 } 86 return (1); 87 } 88 89 void 90 ldso_plt_init(Rt_map * lmp) 91 { 92 /* 93 * There is no need to analyze ld.so because we don't map in any of 94 * its dependencies. However we may map these dependencies in later 95 * (as if ld.so had dlopened them), so initialize the plt and the 96 * permission information. 97 */ 98 if (PLTGOT(lmp)) 99 elf_plt_init((PLTGOT(lmp)), (caddr_t)lmp); 100 } 101 102 /* 103 * elf_plt_write() will test to see how far away our destination 104 * address lies. If it is close enough that a branch can 105 * be used instead of a jmpl - we will fill the plt in with 106 * single branch. The branches are much quicker then 107 * a jmpl instruction - see bug#4356879 for further 108 * details. 109 * 110 * NOTE: we pass in both a 'pltaddr' and a 'vpltaddr' since 111 * librtld/dldump update PLT's who's physical 112 * address is not the same as the 'virtual' runtime 113 * address. 114 */ 115 Pltbindtype 116 /* ARGSUSED4 */ 117 elf_plt_write(uintptr_t addr, uintptr_t vaddr, void *rptr, uintptr_t symval, 118 Xword pltndx) 119 { 120 Rela *rel = (Rela *)rptr; 121 uintptr_t vpltaddr, pltaddr; 122 long disp; 123 124 125 pltaddr = addr + rel->r_offset; 126 vpltaddr = vaddr + rel->r_offset; 127 disp = symval - vpltaddr - 4; 128 129 /* 130 * Test if the destination address is close enough to use 131 * a ba,a... instruction to reach it. 132 */ 133 if (S_INRANGE(disp, 23) && !(rtld_flags & RT_FL_NOBAPLT)) { 134 uint_t *pltent, bainstr; 135 Pltbindtype rc; 136 137 pltent = (uint_t *)pltaddr; 138 /* 139 * The 140 * 141 * ba,a,pt %icc, <dest> 142 * 143 * is the most efficient of the PLT's. If we 144 * are within +-20 bits *and* running on a 145 * v8plus architecture - use that branch. 146 */ 147 if ((at_flags & EF_SPARC_32PLUS) && 148 S_INRANGE(disp, 20)) { 149 bainstr = M_BA_A_PT; /* ba,a,pt %icc,<dest> */ 150 bainstr |= (S_MASK(19) & (disp >> 2)); 151 rc = PLT_T_21D; 152 DBG_CALL(pltcnt21d++); 153 } else { 154 /* 155 * Otherwise - we fall back to the good old 156 * 157 * ba,a <dest> 158 * 159 * Which still beats a jmpl instruction. 160 */ 161 bainstr = M_BA_A; /* ba,a <dest> */ 162 bainstr |= (S_MASK(22) & (disp >> 2)); 163 rc = PLT_T_24D; 164 DBG_CALL(pltcnt24d++); 165 } 166 167 pltent[2] = M_NOP; /* nop instr */ 168 pltent[1] = bainstr; 169 170 iflush_range((char *)(&pltent[1]), 4); 171 pltent[0] = M_NOP; /* nop instr */ 172 iflush_range((char *)(&pltent[0]), 4); 173 return (rc); 174 } 175 176 /* 177 * The PLT destination is not in reach of 178 * a branch instruction - so we fall back 179 * to a 'jmpl' sequence. 180 */ 181 plt_full_range(pltaddr, symval); 182 DBG_CALL(pltcntfull++); 183 return (PLT_T_FULL); 184 } 185 186 187 /* 188 * Local storage space created on the stack created for this glue 189 * code includes space for: 190 * 0x4 pointer to dyn_data 191 * 0x4 size prev stack frame 192 */ 193 static const uchar_t dyn_plt_template[] = { 194 /* 0x00 */ 0x80, 0x90, 0x00, 0x1e, /* tst %fp */ 195 /* 0x04 */ 0x02, 0x80, 0x00, 0x04, /* be 0x14 */ 196 /* 0x08 */ 0x82, 0x27, 0x80, 0x0e, /* sub %sp, %fp, %g1 */ 197 /* 0x0c */ 0x10, 0x80, 0x00, 0x03, /* ba 0x20 */ 198 /* 0x10 */ 0x01, 0x00, 0x00, 0x00, /* nop */ 199 /* 0x14 */ 0x82, 0x10, 0x20, 0x60, /* mov 0x60, %g1 */ 200 /* 0x18 */ 0x9d, 0xe3, 0xbf, 0x98, /* save %sp, -0x68, %sp */ 201 /* 0x1c */ 0xc2, 0x27, 0xbf, 0xf8, /* st %g1, [%fp + -0x8] */ 202 /* 0x20 */ 0x03, 0x00, 0x00, 0x00, /* sethi %hi(val), %g1 */ 203 /* 0x24 */ 0x82, 0x10, 0x60, 0x00, /* or %g1, %lo(val), %g1 */ 204 /* 0x28 */ 0x40, 0x00, 0x00, 0x00, /* call <rel_addr> */ 205 /* 0x2c */ 0xc2, 0x27, 0xbf, 0xfc /* st %g1, [%fp + -0x4] */ 206 }; 207 208 int dyn_plt_ent_size = sizeof (dyn_plt_template) + 209 sizeof (uintptr_t) + /* reflmp */ 210 sizeof (uintptr_t) + /* deflmp */ 211 sizeof (ulong_t) + /* symndx */ 212 sizeof (ulong_t) + /* sb_flags */ 213 sizeof (Sym); /* symdef */ 214 215 /* 216 * the dynamic plt entry is: 217 * 218 * tst %fp 219 * be 1f 220 * nop 221 * sub %sp, %fp, %g1 222 * ba 2f 223 * nop 224 * 1: 225 * mov SA(MINFRAME), %g1 ! if %fp is null this is the 226 * ! 'minimum stack'. %fp is null 227 * ! on the initial stack frame 228 * 2: 229 * save %sp, -(SA(MINFRAME) + 2 * CLONGSIZE), %sp 230 * st %g1, [%fp + -0x8] ! store prev_stack size in [%fp - 8] 231 * sethi %hi(dyn_data), %g1 232 * or %g1, %lo(dyn_data), %g1 233 * call elf_plt_trace 234 * st %g1, [%fp + -0x4] ! store dyn_data ptr in [%fp - 4] 235 * dyn data: 236 * uintptr_t reflmp 237 * uintptr_t deflmp 238 * ulong_t symndx 239 * ulong_t sb_flags 240 * Sym symdef 241 */ 242 static caddr_t 243 elf_plt_trace_write(caddr_t addr, Rela *rptr, Rt_map *rlmp, Rt_map *dlmp, 244 Sym *sym, ulong_t symndx, ulong_t pltndx, caddr_t to, ulong_t sb_flags, 245 int *fail) 246 { 247 extern ulong_t elf_plt_trace(); 248 uintptr_t dyn_plt, *dyndata; 249 250 /* 251 * If both pltenter & pltexit have been disabled there 252 * there is no reason to even create the glue code. 253 */ 254 if ((sb_flags & (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) == 255 (LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT)) { 256 (void) elf_plt_write((uintptr_t)addr, (uintptr_t)addr, 257 rptr, (uintptr_t)to, pltndx); 258 return (to); 259 } 260 261 /* 262 * We only need to add the glue code if there is an auditing 263 * library that is interested in this binding. 264 */ 265 dyn_plt = (uintptr_t)AUDINFO(rlmp)->ai_dynplts + 266 (pltndx * dyn_plt_ent_size); 267 268 /* 269 * Have we initialized this dynamic plt entry yet? If we haven't do it 270 * now. Otherwise this function has been called before, but from a 271 * different plt (ie. from another shared object). In that case 272 * we just set the plt to point to the new dyn_plt. 273 */ 274 if (*(uint_t *)dyn_plt == 0) { 275 Sym *symp; 276 Xword symvalue; 277 Lm_list *lml = LIST(rlmp); 278 279 (void) memcpy((void *)dyn_plt, dyn_plt_template, 280 sizeof (dyn_plt_template)); 281 dyndata = (uintptr_t *)(dyn_plt + sizeof (dyn_plt_template)); 282 283 /* 284 * relocating: 285 * sethi %hi(dyndata), %g1 286 */ 287 symvalue = (Xword)dyndata; 288 if (do_reloc_rtld(R_SPARC_HI22, (uchar_t *)(dyn_plt + 0x20), 289 &symvalue, MSG_ORIG(MSG_SYM_LADYNDATA), 290 MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { 291 *fail = 1; 292 return (0); 293 } 294 295 /* 296 * relocating: 297 * or %g1, %lo(dyndata), %g1 298 */ 299 symvalue = (Xword)dyndata; 300 if (do_reloc_rtld(R_SPARC_LO10, (uchar_t *)(dyn_plt + 0x24), 301 &symvalue, MSG_ORIG(MSG_SYM_LADYNDATA), 302 MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { 303 *fail = 1; 304 return (0); 305 } 306 307 /* 308 * relocating: 309 * call elf_plt_trace 310 */ 311 symvalue = (Xword)((uintptr_t)&elf_plt_trace - 312 (dyn_plt + 0x28)); 313 if (do_reloc_rtld(R_SPARC_WDISP30, (uchar_t *)(dyn_plt + 0x28), 314 &symvalue, MSG_ORIG(MSG_SYM_ELFPLTTRACE), 315 MSG_ORIG(MSG_SPECFIL_DYNPLT), lml) == 0) { 316 *fail = 1; 317 return (0); 318 } 319 320 *dyndata++ = (uintptr_t)rlmp; 321 *dyndata++ = (uintptr_t)dlmp; 322 *(ulong_t *)dyndata++ = symndx; 323 *(ulong_t *)dyndata++ = sb_flags; 324 symp = (Sym *)dyndata; 325 *symp = *sym; 326 symp->st_name += (Word)STRTAB(dlmp); 327 symp->st_value = (Addr)to; 328 329 iflush_range((void *)dyn_plt, sizeof (dyn_plt_template)); 330 } 331 332 (void) elf_plt_write((uintptr_t)addr, (uintptr_t)addr, 333 rptr, (uintptr_t)dyn_plt, 0); 334 return ((caddr_t)dyn_plt); 335 } 336 337 338 /* 339 * Function binding routine - invoked on the first call to a function through 340 * the procedure linkage table; 341 * passes first through an assembly language interface. 342 * 343 * Takes the address of the PLT entry where the call originated, 344 * the offset into the relocation table of the associated 345 * relocation entry and the address of the link map (rt_private_map struct) 346 * for the entry. 347 * 348 * Returns the address of the function referenced after re-writing the PLT 349 * entry to invoke the function directly. 350 * 351 * On error, causes process to terminate with a signal. 352 */ 353 ulong_t 354 elf_bndr(Rt_map *lmp, ulong_t pltoff, caddr_t from) 355 { 356 Rt_map *nlmp, *llmp; 357 ulong_t addr, vaddr, reloff, symval, rsymndx; 358 char *name; 359 Rela *rptr; 360 Sym *rsym, *nsym; 361 Xword pltndx; 362 uint_t binfo, sb_flags = 0; 363 Slookup sl; 364 Pltbindtype pbtype; 365 int entry, lmflags; 366 uint_t dbg_class; 367 Lm_list *lml = LIST(lmp); 368 369 /* 370 * For compatibility with libthread (TI_VERSION 1) we track the entry 371 * value. A zero value indicates we have recursed into ld.so.1 to 372 * further process a locking request. Under this recursion we disable 373 * tsort and cleanup activities. 374 */ 375 entry = enter(0); 376 377 if ((lmflags = lml->lm_flags) & LML_FLG_RTLDLM) { 378 dbg_class = dbg_desc->d_class; 379 dbg_desc->d_class = 0; 380 } 381 382 /* 383 * Must calculate true plt relocation address from reloc. 384 * Take offset, subtract number of reserved PLT entries, and divide 385 * by PLT entry size, which should give the index of the plt 386 * entry (and relocation entry since they have been defined to be 387 * in the same order). Then we must multiply by the size of 388 * a relocation entry, which will give us the offset of the 389 * plt relocation entry from the start of them given by JMPREL(lm). 390 */ 391 addr = pltoff - M_PLT_RESERVSZ; 392 pltndx = addr / M_PLT_ENTSIZE; 393 394 /* 395 * Perform some basic sanity checks. If we didn't get a load map 396 * or the plt offset is invalid then its possible someone has walked 397 * over the plt entries or jumped to plt0 out of the blue. 398 */ 399 if (!lmp || ((addr % M_PLT_ENTSIZE) != 0)) { 400 Conv_inv_buf_t inv_buf; 401 402 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_PLTREF), 403 conv_reloc_SPARC_type(R_SPARC_JMP_SLOT, 0, &inv_buf), 404 EC_NATPTR(lmp), EC_XWORD(pltoff), EC_NATPTR(from)); 405 rtldexit(lml, 1); 406 } 407 reloff = pltndx * sizeof (Rela); 408 409 /* 410 * Use relocation entry to get symbol table entry and symbol name. 411 */ 412 addr = (ulong_t)JMPREL(lmp); 413 rptr = (Rela *)(addr + reloff); 414 rsymndx = ELF_R_SYM(rptr->r_info); 415 rsym = (Sym *)((ulong_t)SYMTAB(lmp) + (rsymndx * SYMENT(lmp))); 416 name = (char *)(STRTAB(lmp) + rsym->st_name); 417 418 /* 419 * Determine the last link-map of this list, this'll be the starting 420 * point for any tsort() processing. 421 */ 422 llmp = lml->lm_tail; 423 424 /* 425 * Find definition for symbol. Initialize the symbol lookup data 426 * structure. 427 */ 428 SLOOKUP_INIT(sl, name, lmp, lml->lm_head, ld_entry_cnt, 0, 429 rsymndx, rsym, 0, LKUP_DEFT); 430 431 if ((nsym = lookup_sym(&sl, &nlmp, &binfo, NULL)) == 0) { 432 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYM), NAME(lmp), 433 demangle(name)); 434 rtldexit(lml, 1); 435 } 436 437 symval = nsym->st_value; 438 if (!(FLAGS(nlmp) & FLG_RT_FIXED) && 439 (nsym->st_shndx != SHN_ABS)) 440 symval += ADDR(nlmp); 441 if ((lmp != nlmp) && ((FLAGS1(nlmp) & FL1_RT_NOINIFIN) == 0)) { 442 /* 443 * Record that this new link map is now bound to the caller. 444 */ 445 if (bind_one(lmp, nlmp, BND_REFER) == 0) 446 rtldexit(lml, 1); 447 } 448 449 if ((lml->lm_tflags | FLAGS1(lmp)) & LML_TFLG_AUD_SYMBIND) { 450 ulong_t symndx = (((uintptr_t)nsym - 451 (uintptr_t)SYMTAB(nlmp)) / SYMENT(nlmp)); 452 453 symval = audit_symbind(lmp, nlmp, nsym, symndx, symval, 454 &sb_flags); 455 } 456 457 if (FLAGS(lmp) & FLG_RT_FIXED) 458 vaddr = 0; 459 else 460 vaddr = ADDR(lmp); 461 462 pbtype = PLT_T_NONE; 463 if (!(rtld_flags & RT_FL_NOBIND)) { 464 if (((lml->lm_tflags | FLAGS1(lmp)) & 465 (LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) && 466 AUDINFO(lmp)->ai_dynplts) { 467 int fail = 0; 468 ulong_t symndx = (((uintptr_t)nsym - 469 (uintptr_t)SYMTAB(nlmp)) / SYMENT(nlmp)); 470 471 symval = (ulong_t)elf_plt_trace_write((caddr_t)vaddr, 472 rptr, lmp, nlmp, nsym, symndx, pltndx, 473 (caddr_t)symval, sb_flags, &fail); 474 if (fail) 475 rtldexit(lml, 1); 476 } else { 477 /* 478 * Write standard PLT entry to jump directly 479 * to newly bound function. 480 */ 481 pbtype = elf_plt_write((uintptr_t)vaddr, 482 (uintptr_t)vaddr, rptr, symval, pltndx); 483 } 484 } 485 486 /* 487 * Print binding information and rebuild PLT entry. 488 */ 489 DBG_CALL(Dbg_bind_global(lmp, (Addr)from, (Off)(from - ADDR(lmp)), 490 pltndx, pbtype, nlmp, (Addr)symval, nsym->st_value, name, binfo)); 491 492 /* 493 * Complete any processing for newly loaded objects. Note we don't 494 * know exactly where any new objects are loaded (we know the object 495 * that supplied the symbol, but others may have been loaded lazily as 496 * we searched for the symbol), so sorting starts from the last 497 * link-map know on entry to this routine. 498 */ 499 if (entry) 500 load_completion(llmp); 501 502 /* 503 * Some operations like dldump() or dlopen()'ing a relocatable object 504 * result in objects being loaded on rtld's link-map, make sure these 505 * objects are initialized also. 506 */ 507 if ((LIST(nlmp)->lm_flags & LML_FLG_RTLDLM) && LIST(nlmp)->lm_init) 508 load_completion(nlmp); 509 510 /* 511 * If the object we've bound to is in the process of being initialized 512 * by another thread, determine whether we should block. 513 */ 514 is_dep_ready(nlmp, lmp, DBG_WAIT_SYMBOL); 515 516 /* 517 * Make sure the object to which we've bound has had it's .init fired. 518 * Cleanup before return to user code. 519 */ 520 if (entry) { 521 is_dep_init(nlmp, lmp); 522 leave(lml, 0); 523 } 524 525 if (lmflags & LML_FLG_RTLDLM) 526 dbg_desc->d_class = dbg_class; 527 528 return (symval); 529 } 530 531 532 /* 533 * Read and process the relocations for one link object, we assume all 534 * relocation sections for loadable segments are stored contiguously in 535 * the file. 536 */ 537 int 538 elf_reloc(Rt_map *lmp, uint_t plt, int *in_nfavl) 539 { 540 ulong_t relbgn, relend, relsiz, basebgn, pltbgn, pltend; 541 ulong_t roffset, rsymndx, psymndx = 0, etext = ETEXT(lmp); 542 ulong_t emap, dsymndx, pltndx; 543 uchar_t rtype; 544 long reladd, value, pvalue; 545 Sym *symref, *psymref, *symdef, *psymdef; 546 char *name, *pname; 547 Rt_map *_lmp, *plmp; 548 int textrel = 0, ret = 1, noplt = 0; 549 long relacount = RELACOUNT(lmp); 550 Rela *rel; 551 Pltbindtype pbtype; 552 uint_t binfo, pbinfo; 553 APlist *bound = NULL; 554 555 /* 556 * If an object has any DT_REGISTER entries associated with 557 * it, they are processed now. 558 */ 559 if ((plt == 0) && (FLAGS(lmp) & FLG_RT_REGSYMS)) { 560 if (elf_regsyms(lmp) == 0) 561 return (0); 562 } 563 564 /* 565 * Although only necessary for lazy binding, initialize the first 566 * procedure linkage table entry to go to elf_rtbndr(). dbx(1) seems 567 * to find this useful. 568 */ 569 if ((plt == 0) && PLTGOT(lmp)) { 570 if ((ulong_t)PLTGOT(lmp) < etext) { 571 if (elf_set_prot(lmp, PROT_WRITE) == 0) 572 return (0); 573 textrel = 1; 574 } 575 elf_plt_init(PLTGOT(lmp), (caddr_t)lmp); 576 } 577 578 /* 579 * Initialize the plt start and end addresses. 580 */ 581 if ((pltbgn = (ulong_t)JMPREL(lmp)) != 0) 582 pltend = pltbgn + (ulong_t)(PLTRELSZ(lmp)); 583 584 /* 585 * If we've been called upon to promote an RTLD_LAZY object to an 586 * RTLD_NOW then we're only interested in scaning the .plt table. 587 */ 588 if (plt) { 589 relbgn = pltbgn; 590 relend = pltend; 591 } else { 592 /* 593 * The relocation sections appear to the run-time linker as a 594 * single table. Determine the address of the beginning and end 595 * of this table. There are two different interpretations of 596 * the ABI at this point: 597 * 598 * o The REL table and its associated RELSZ indicate the 599 * concatenation of *all* relocation sections (this is the 600 * model our link-editor constructs). 601 * 602 * o The REL table and its associated RELSZ indicate the 603 * concatenation of all *but* the .plt relocations. These 604 * relocations are specified individually by the JMPREL and 605 * PLTRELSZ entries. 606 * 607 * Determine from our knowledege of the relocation range and 608 * .plt range, the range of the total relocation table. Note 609 * that one other ABI assumption seems to be that the .plt 610 * relocations always follow any other relocations, the 611 * following range checking drops that assumption. 612 */ 613 relbgn = (ulong_t)(REL(lmp)); 614 relend = relbgn + (ulong_t)(RELSZ(lmp)); 615 if (pltbgn) { 616 if (!relbgn || (relbgn > pltbgn)) 617 relbgn = pltbgn; 618 if (!relbgn || (relend < pltend)) 619 relend = pltend; 620 } 621 } 622 if (!relbgn || (relbgn == relend)) { 623 DBG_CALL(Dbg_reloc_run(lmp, 0, plt, DBG_REL_NONE)); 624 return (1); 625 } 626 627 relsiz = (ulong_t)(RELENT(lmp)); 628 basebgn = ADDR(lmp); 629 emap = ADDR(lmp) + MSIZE(lmp); 630 631 DBG_CALL(Dbg_reloc_run(lmp, M_REL_SHT_TYPE, plt, DBG_REL_START)); 632 633 /* 634 * If we're processing in lazy mode there is no need to scan the 635 * .rela.plt table. 636 */ 637 if (pltbgn && ((MODE(lmp) & RTLD_NOW) == 0)) 638 noplt = 1; 639 640 /* 641 * Loop through relocations. 642 */ 643 while (relbgn < relend) { 644 Addr vaddr; 645 uint_t sb_flags = 0; 646 647 rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH); 648 649 /* 650 * If this is a RELATIVE relocation in a shared object (the 651 * common case), and if we are not debugging, then jump into a 652 * tighter relocation loop (elf_reloc_relative). Only make the 653 * jump if we've been given a hint on the number of relocations. 654 */ 655 if ((rtype == R_SPARC_RELATIVE) && 656 ((FLAGS(lmp) & FLG_RT_FIXED) == 0) && (DBG_ENABLED == 0)) { 657 /* 658 * It's possible that the relative relocation block 659 * has relocations against the text segment as well 660 * as the data segment. Since our optimized relocation 661 * engine does not check which segment the relocation 662 * is against - just mprotect it now if it's been 663 * marked as containing TEXTREL's. 664 */ 665 if ((textrel == 0) && (FLAGS1(lmp) & FL1_RT_TEXTREL)) { 666 if (elf_set_prot(lmp, PROT_WRITE) == 0) { 667 ret = 0; 668 break; 669 } 670 textrel = 1; 671 } 672 if (relacount) { 673 relbgn = elf_reloc_relacount(relbgn, relacount, 674 relsiz, basebgn); 675 relacount = 0; 676 } else { 677 relbgn = elf_reloc_relative(relbgn, relend, 678 relsiz, basebgn, etext, emap); 679 } 680 if (relbgn >= relend) 681 break; 682 rtype = ELF_R_TYPE(((Rela *)relbgn)->r_info, M_MACH); 683 } 684 685 roffset = ((Rela *)relbgn)->r_offset; 686 687 reladd = (long)(((Rela *)relbgn)->r_addend); 688 rsymndx = ELF_R_SYM(((Rela *)relbgn)->r_info); 689 690 rel = (Rela *)relbgn; 691 relbgn += relsiz; 692 693 /* 694 * Optimizations. 695 */ 696 if (rtype == R_SPARC_NONE) 697 continue; 698 if (noplt && ((ulong_t)rel >= pltbgn) && 699 ((ulong_t)rel < pltend)) { 700 relbgn = pltend; 701 continue; 702 } 703 704 if (rtype != R_SPARC_REGISTER) { 705 /* 706 * If this is a shared object, add the base address 707 * to offset. 708 */ 709 if (!(FLAGS(lmp) & FLG_RT_FIXED)) 710 roffset += basebgn; 711 712 /* 713 * If this relocation is not against part of the image 714 * mapped into memory we skip it. 715 */ 716 if ((roffset < ADDR(lmp)) || (roffset > (ADDR(lmp) + 717 MSIZE(lmp)))) { 718 elf_reloc_bad(lmp, (void *)rel, rtype, roffset, 719 rsymndx); 720 continue; 721 } 722 } 723 724 /* 725 * If we're promoting .plts try and determine if this one has 726 * already been written. An uninitialized .plts' second 727 * instruction is a branch. Note, elf_plt_write() optimizes 728 * .plt relocations, and it's possible that a relocated entry 729 * is a branch. If this is the case, we can't tell the 730 * difference between an uninitialized .plt and a relocated, 731 * .plt that uses a branch. In this case, we'll simply redo 732 * the relocation calculation, which is a bit sad. 733 */ 734 if (plt) { 735 ulong_t *_roffset = (ulong_t *)roffset; 736 737 _roffset++; 738 if ((*_roffset & (~(S_MASK(22)))) != M_BA_A) 739 continue; 740 } 741 742 binfo = 0; 743 pltndx = (ulong_t)-1; 744 pbtype = PLT_T_NONE; 745 /* 746 * If a symbol index is specified then get the symbol table 747 * entry, locate the symbol definition, and determine its 748 * address. 749 */ 750 if (rsymndx) { 751 /* 752 * Get the local symbol table entry. 753 */ 754 symref = (Sym *)((ulong_t)SYMTAB(lmp) + 755 (rsymndx * SYMENT(lmp))); 756 757 /* 758 * If this is a local symbol, just use the base address. 759 * (we should have no local relocations in the 760 * executable). 761 */ 762 if (ELF_ST_BIND(symref->st_info) == STB_LOCAL) { 763 value = basebgn; 764 name = (char *)0; 765 766 /* 767 * Special case TLS relocations. 768 */ 769 if (rtype == R_SPARC_TLS_DTPMOD32) { 770 /* 771 * Use the TLS modid. 772 */ 773 value = TLSMODID(lmp); 774 775 } else if (rtype == R_SPARC_TLS_TPOFF32) { 776 if ((value = elf_static_tls(lmp, symref, 777 rel, rtype, 0, roffset, 0)) == 0) { 778 ret = 0; 779 break; 780 } 781 } 782 } else { 783 /* 784 * If the symbol index is equal to the previous 785 * symbol index relocation we processed then 786 * reuse the previous values. (Note that there 787 * have been cases where a relocation exists 788 * against a copy relocation symbol, our ld(1) 789 * should optimize this away, but make sure we 790 * don't use the same symbol information should 791 * this case exist). 792 */ 793 if ((rsymndx == psymndx) && 794 (rtype != R_SPARC_COPY)) { 795 /* LINTED */ 796 if (psymdef == 0) { 797 DBG_CALL(Dbg_bind_weak(lmp, 798 (Addr)roffset, (Addr) 799 (roffset - basebgn), name)); 800 continue; 801 } 802 /* LINTED */ 803 value = pvalue; 804 /* LINTED */ 805 name = pname; 806 symdef = psymdef; 807 /* LINTED */ 808 symref = psymref; 809 /* LINTED */ 810 _lmp = plmp; 811 /* LINTED */ 812 binfo = pbinfo; 813 814 if ((LIST(_lmp)->lm_tflags | 815 FLAGS1(_lmp)) & 816 LML_TFLG_AUD_SYMBIND) { 817 value = audit_symbind(lmp, _lmp, 818 /* LINTED */ 819 symdef, dsymndx, value, 820 &sb_flags); 821 } 822 } else { 823 Slookup sl; 824 825 /* 826 * Lookup the symbol definition. 827 * Initialize the symbol lookup data 828 * structure. 829 */ 830 name = (char *)(STRTAB(lmp) + 831 symref->st_name); 832 833 SLOOKUP_INIT(sl, name, lmp, 0, 834 ld_entry_cnt, 0, rsymndx, symref, 835 rtype, LKUP_STDRELOC); 836 837 symdef = lookup_sym(&sl, &_lmp, 838 &binfo, in_nfavl); 839 840 /* 841 * If the symbol is not found and the 842 * reference was not to a weak symbol, 843 * report an error. Weak references 844 * may be unresolved. 845 */ 846 /* BEGIN CSTYLED */ 847 if (symdef == 0) { 848 if (sl.sl_bind != STB_WEAK) { 849 if (elf_reloc_error(lmp, name, 850 rel, binfo)) 851 continue; 852 853 ret = 0; 854 break; 855 856 } else { 857 psymndx = rsymndx; 858 psymdef = 0; 859 860 DBG_CALL(Dbg_bind_weak(lmp, 861 (Addr)roffset, (Addr) 862 (roffset - basebgn), name)); 863 continue; 864 } 865 } 866 /* END CSTYLED */ 867 868 /* 869 * If symbol was found in an object 870 * other than the referencing object 871 * then record the binding. 872 */ 873 if ((lmp != _lmp) && ((FLAGS1(_lmp) & 874 FL1_RT_NOINIFIN) == 0)) { 875 if (aplist_test(&bound, _lmp, 876 AL_CNT_RELBIND) == 0) { 877 ret = 0; 878 break; 879 } 880 } 881 882 /* 883 * Calculate the location of definition; 884 * symbol value plus base address of 885 * containing shared object. 886 */ 887 if (IS_SIZE(rtype)) 888 value = symdef->st_size; 889 else 890 value = symdef->st_value; 891 892 if (!(FLAGS(_lmp) & FLG_RT_FIXED) && 893 !(IS_SIZE(rtype)) && 894 (symdef->st_shndx != SHN_ABS) && 895 (ELF_ST_TYPE(symdef->st_info) != 896 STT_TLS)) 897 value += ADDR(_lmp); 898 899 /* 900 * Retain this symbol index and the 901 * value in case it can be used for the 902 * subsequent relocations. 903 */ 904 if (rtype != R_SPARC_COPY) { 905 psymndx = rsymndx; 906 pvalue = value; 907 pname = name; 908 psymdef = symdef; 909 psymref = symref; 910 plmp = _lmp; 911 pbinfo = binfo; 912 } 913 if ((LIST(_lmp)->lm_tflags | 914 FLAGS1(_lmp)) & 915 LML_TFLG_AUD_SYMBIND) { 916 dsymndx = (((uintptr_t)symdef - 917 (uintptr_t)SYMTAB(_lmp)) / 918 SYMENT(_lmp)); 919 value = audit_symbind(lmp, _lmp, 920 symdef, dsymndx, value, 921 &sb_flags); 922 } 923 } 924 925 /* 926 * If relocation is PC-relative, subtract 927 * offset address. 928 */ 929 if (IS_PC_RELATIVE(rtype)) 930 value -= roffset; 931 932 /* 933 * Special case TLS relocations. 934 */ 935 if (rtype == R_SPARC_TLS_DTPMOD32) { 936 /* 937 * Relocation value is the TLS modid. 938 */ 939 value = TLSMODID(_lmp); 940 941 } else if (rtype == R_SPARC_TLS_TPOFF32) { 942 if ((value = elf_static_tls(_lmp, 943 symdef, rel, rtype, name, roffset, 944 value)) == 0) { 945 ret = 0; 946 break; 947 } 948 } 949 } 950 } else { 951 /* 952 * Special cases. 953 */ 954 if (rtype == R_SPARC_REGISTER) { 955 /* 956 * A register symbol associated with symbol 957 * index 0 is initialized (i.e. relocated) to 958 * a constant in the r_addend field rather than 959 * to a symbol value. 960 */ 961 value = 0; 962 963 } else if (rtype == R_SPARC_TLS_DTPMOD32) { 964 /* 965 * TLS relocation value is the TLS modid. 966 */ 967 value = TLSMODID(lmp); 968 } else 969 value = basebgn; 970 name = (char *)0; 971 } 972 973 DBG_CALL(Dbg_reloc_in(LIST(lmp), ELF_DBG_RTLD, M_MACH, 974 M_REL_SHT_TYPE, rel, NULL, name)); 975 976 /* 977 * If this object has relocations in the text segment, turn 978 * off the write protect. 979 */ 980 if ((rtype != R_SPARC_REGISTER) && (roffset < etext) && 981 (textrel == 0)) { 982 if (elf_set_prot(lmp, PROT_WRITE) == 0) { 983 ret = 0; 984 break; 985 } 986 textrel = 1; 987 } 988 989 /* 990 * Call relocation routine to perform required relocation. 991 */ 992 switch (rtype) { 993 case R_SPARC_REGISTER: 994 /* 995 * The v9 ABI 4.2.4 says that system objects may, 996 * but are not required to, use register symbols 997 * to inidcate how they use global registers. Thus 998 * at least %g6, %g7 must be allowed in addition 999 * to %g2 and %g3. 1000 */ 1001 value += reladd; 1002 if (roffset == STO_SPARC_REGISTER_G1) { 1003 set_sparc_g1(value); 1004 } else if (roffset == STO_SPARC_REGISTER_G2) { 1005 set_sparc_g2(value); 1006 } else if (roffset == STO_SPARC_REGISTER_G3) { 1007 set_sparc_g3(value); 1008 } else if (roffset == STO_SPARC_REGISTER_G4) { 1009 set_sparc_g4(value); 1010 } else if (roffset == STO_SPARC_REGISTER_G5) { 1011 set_sparc_g5(value); 1012 } else if (roffset == STO_SPARC_REGISTER_G6) { 1013 set_sparc_g6(value); 1014 } else if (roffset == STO_SPARC_REGISTER_G7) { 1015 set_sparc_g7(value); 1016 } else { 1017 eprintf(LIST(lmp), ERR_FATAL, 1018 MSG_INTL(MSG_REL_BADREG), NAME(lmp), 1019 EC_ADDR(roffset)); 1020 ret = 0; 1021 break; 1022 } 1023 1024 DBG_CALL(Dbg_reloc_apply_reg(LIST(lmp), ELF_DBG_RTLD, 1025 M_MACH, (Xword)roffset, (Xword)value)); 1026 break; 1027 case R_SPARC_COPY: 1028 if (elf_copy_reloc(name, symref, lmp, (void *)roffset, 1029 symdef, _lmp, (const void *)value) == 0) 1030 ret = 0; 1031 break; 1032 case R_SPARC_JMP_SLOT: 1033 pltndx = ((ulong_t)rel - 1034 (uintptr_t)JMPREL(lmp)) / relsiz; 1035 1036 if (FLAGS(lmp) & FLG_RT_FIXED) 1037 vaddr = 0; 1038 else 1039 vaddr = ADDR(lmp); 1040 1041 if (((LIST(lmp)->lm_tflags | FLAGS1(lmp)) & 1042 (LML_TFLG_AUD_PLTENTER | LML_TFLG_AUD_PLTEXIT)) && 1043 AUDINFO(lmp)->ai_dynplts) { 1044 int fail = 0; 1045 ulong_t symndx = (((uintptr_t)symdef - 1046 (uintptr_t)SYMTAB(_lmp)) / SYMENT(_lmp)); 1047 1048 (void) elf_plt_trace_write((caddr_t)vaddr, 1049 (Rela *)rel, lmp, _lmp, symdef, symndx, 1050 pltndx, (caddr_t)value, sb_flags, &fail); 1051 if (fail) 1052 ret = 0; 1053 } else { 1054 /* 1055 * Write standard PLT entry to jump directly 1056 * to newly bound function. 1057 */ 1058 DBG_CALL(Dbg_reloc_apply_val(LIST(lmp), 1059 ELF_DBG_RTLD, (Xword)roffset, 1060 (Xword)value)); 1061 pbtype = elf_plt_write((uintptr_t)vaddr, 1062 (uintptr_t)vaddr, (void *)rel, value, 1063 pltndx); 1064 } 1065 break; 1066 default: 1067 value += reladd; 1068 1069 /* 1070 * Write the relocation out. If this relocation is a 1071 * common basic write, skip the doreloc() engine. 1072 */ 1073 if ((rtype == R_SPARC_GLOB_DAT) || 1074 (rtype == R_SPARC_32)) { 1075 if (roffset & 0x3) { 1076 Conv_inv_buf_t inv_buf; 1077 1078 eprintf(LIST(lmp), ERR_FATAL, 1079 MSG_INTL(MSG_REL_NONALIGN), 1080 conv_reloc_SPARC_type(rtype, 1081 0, &inv_buf), 1082 NAME(lmp), demangle(name), 1083 EC_OFF(roffset)); 1084 ret = 0; 1085 } else 1086 *(uint_t *)roffset += value; 1087 } else { 1088 if (do_reloc_rtld(rtype, (uchar_t *)roffset, 1089 (Xword *)&value, name, 1090 NAME(lmp), LIST(lmp)) == 0) 1091 ret = 0; 1092 } 1093 1094 /* 1095 * The value now contains the 'bit-shifted' value that 1096 * was or'ed into memory (this was set by 1097 * do_reloc_rtld()). 1098 */ 1099 DBG_CALL(Dbg_reloc_apply_val(LIST(lmp), ELF_DBG_RTLD, 1100 (Xword)roffset, (Xword)value)); 1101 1102 /* 1103 * If this relocation is against a text segment, make 1104 * sure that the instruction cache is flushed. 1105 */ 1106 if (textrel) 1107 iflush_range((caddr_t)roffset, 0x4); 1108 } 1109 1110 if ((ret == 0) && 1111 ((LIST(lmp)->lm_flags & LML_FLG_TRC_WARN) == 0)) 1112 break; 1113 1114 if (binfo) { 1115 DBG_CALL(Dbg_bind_global(lmp, (Addr)roffset, 1116 (Off)(roffset - basebgn), pltndx, pbtype, 1117 _lmp, (Addr)value, symdef->st_value, name, binfo)); 1118 } 1119 } 1120 1121 return (relocate_finish(lmp, bound, textrel, ret)); 1122 } 1123 1124 /* 1125 * Provide a machine specific interface to the conversion routine. By calling 1126 * the machine specific version, rather than the generic version, we insure that 1127 * the data tables/strings for all known machine versions aren't dragged into 1128 * ld.so.1. 1129 */ 1130 const char * 1131 _conv_reloc_type(uint_t rel) 1132 { 1133 static Conv_inv_buf_t inv_buf; 1134 1135 return (conv_reloc_SPARC_type(rel, 0, &inv_buf)); 1136 } 1137