1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright 1996, 1997, 1998, 1999 John D. Polstra. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* 29 * Dynamic linker for ELF. 30 * 31 * John Polstra <jdp@polstra.com>. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/mman.h> 36 37 #include <machine/segments.h> 38 #include <machine/sysarch.h> 39 40 #include <dlfcn.h> 41 #include <err.h> 42 #include <errno.h> 43 #include <fcntl.h> 44 #include <stdarg.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <unistd.h> 49 50 #include "debug.h" 51 #include "rtld.h" 52 #include "rtld_tls.h" 53 54 void 55 md_obj_entry_init(Obj_Entry *obj) 56 { 57 STAILQ_INIT(&obj->tlsdesc_dynargs); 58 } 59 60 void 61 md_obj_entry_fini(Obj_Entry *obj) 62 { 63 struct tlsdesc_dynarg *tda, *t; 64 65 STAILQ_FOREACH_SAFE(tda, &obj->tlsdesc_dynargs, link, t) { 66 free(tda); 67 } 68 } 69 70 /* 71 * Process the special R_386_COPY relocations in the main program. These 72 * copy data from a shared object into a region in the main program's BSS 73 * segment. 74 * 75 * Returns 0 on success, -1 on failure. 76 */ 77 int 78 do_copy_relocations(Obj_Entry *dstobj) 79 { 80 const Elf_Rel *rellim; 81 const Elf_Rel *rel; 82 83 assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */ 84 85 rellim = (const Elf_Rel *)((const char *)dstobj->rel + dstobj->relsize); 86 for (rel = dstobj->rel; rel < rellim; rel++) { 87 if (ELF_R_TYPE(rel->r_info) == R_386_COPY) { 88 void *dstaddr; 89 const Elf_Sym *dstsym; 90 const char *name; 91 size_t size; 92 const void *srcaddr; 93 const Elf_Sym *srcsym; 94 const Obj_Entry *srcobj, *defobj; 95 SymLook req; 96 int res; 97 98 dstaddr = (void *)(dstobj->relocbase + rel->r_offset); 99 dstsym = dstobj->symtab + ELF_R_SYM(rel->r_info); 100 name = dstobj->strtab + dstsym->st_name; 101 size = dstsym->st_size; 102 symlook_init(&req, name); 103 req.ventry = fetch_ventry(dstobj, 104 ELF_R_SYM(rel->r_info)); 105 req.flags = SYMLOOK_EARLY; 106 107 for (srcobj = globallist_next(dstobj); srcobj != NULL; 108 srcobj = globallist_next(srcobj)) { 109 res = symlook_obj(&req, srcobj); 110 if (res == 0) { 111 srcsym = req.sym_out; 112 defobj = req.defobj_out; 113 break; 114 } 115 } 116 117 if (srcobj == NULL) { 118 _rtld_error( 119 "Undefined symbol \"%s\" referenced from COPY" 120 " relocation in %s", 121 name, dstobj->path); 122 return (-1); 123 } 124 125 srcaddr = (const void *)(defobj->relocbase + 126 srcsym->st_value); 127 memcpy(dstaddr, srcaddr, size); 128 } 129 } 130 131 return (0); 132 } 133 134 /* Initialize the special GOT entries. */ 135 void 136 init_pltgot(Obj_Entry *obj) 137 { 138 if (obj->pltgot != NULL) { 139 obj->pltgot[1] = (Elf_Addr)obj; 140 obj->pltgot[2] = (Elf_Addr)&_rtld_bind_start; 141 } 142 } 143 144 static struct tlsdesc_dynarg * 145 reloc_tlsdesc_alloc(Obj_Entry *obj, Elf_Addr tlsoffs) 146 { 147 struct tlsdesc_dynarg *tda; 148 149 tda = xmalloc(sizeof(struct tlsdesc_dynarg)); 150 tda->tlsinfo.ti_module = obj->tlsindex; 151 tda->tlsinfo.ti_offset = tlsoffs; 152 STAILQ_INSERT_TAIL(&obj->tlsdesc_dynargs, tda, link); 153 return (tda); 154 } 155 156 static void 157 reloc_tlsdesc(const Obj_Entry *obj, const Elf_Rel *rel, 158 struct tlsdesc *where, int flags, RtldLockState *lockstate) 159 { 160 const Elf_Sym *def; 161 const Obj_Entry *defobj; 162 Elf_Addr offs; 163 164 dbg("reloc_tlsdesc obj %s rel %p where %p", obj->path, rel, where); 165 offs = 0; 166 if (ELF_R_SYM(rel->r_info) != 0) { 167 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, flags, 168 NULL, lockstate); 169 if (def == NULL) 170 rtld_die(); 171 if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) { 172 _rtld_error("%s: IFUNC for TLSDESC reloc", 173 obj->path); 174 rtld_die(); 175 } 176 offs = def->st_value; 177 obj = defobj; 178 if (def->st_shndx == SHN_UNDEF) { 179 /* Weak undefined thread variable */ 180 where->entry = rtld_tlsdesc_undef; 181 return; 182 } 183 } 184 offs += where->offset; 185 186 if (obj->tlsoffset != 0) { 187 /* Variable is in initialy allocated TLS segment */ 188 where->entry = rtld_tlsdesc_static; 189 where->offset = offs - obj->tlsoffset; 190 } else { 191 /* TLS offest is unknown at load time, use dynamic resolving */ 192 where->entry = rtld_tlsdesc_dynamic; 193 where->arg = reloc_tlsdesc_alloc(__DECONST(Obj_Entry *, obj), 194 offs); 195 } 196 } 197 198 /* Process the non-PLT relocations. */ 199 int 200 reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags, 201 RtldLockState *lockstate) 202 { 203 const Elf_Rel *rellim; 204 const Elf_Rel *rel; 205 SymCache *cache; 206 const Elf_Sym *def; 207 const Obj_Entry *defobj; 208 Elf_Addr *where, symval, add; 209 int r; 210 211 r = -1; 212 /* 213 * The dynamic loader may be called from a thread, we have 214 * limited amounts of stack available so we cannot use alloca(). 215 */ 216 if (obj != obj_rtld) { 217 cache = calloc(obj->dynsymcount, sizeof(SymCache)); 218 /* No need to check for NULL here */ 219 } else { 220 cache = NULL; 221 } 222 223 /* Appease some compilers. */ 224 symval = 0; 225 def = NULL; 226 227 rellim = (const Elf_Rel *)((const char *)obj->rel + obj->relsize); 228 for (rel = obj->rel; rel < rellim; rel++) { 229 switch (ELF_R_TYPE(rel->r_info)) { 230 case R_386_32: 231 case R_386_PC32: 232 case R_386_GLOB_DAT: 233 case R_386_TLS_TPOFF: 234 case R_386_TLS_TPOFF32: 235 case R_386_TLS_DTPMOD32: 236 case R_386_TLS_DTPOFF32: 237 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, 238 flags, cache, lockstate); 239 if (def == NULL) 240 goto done; 241 if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) { 242 switch (ELF_R_TYPE(rel->r_info)) { 243 case R_386_32: 244 case R_386_PC32: 245 case R_386_GLOB_DAT: 246 if ((flags & SYMLOOK_IFUNC) == 0) { 247 obj->non_plt_gnu_ifunc = true; 248 continue; 249 } 250 symval = (Elf_Addr) 251 rtld_resolve_ifunc(defobj, def); 252 break; 253 case R_386_TLS_TPOFF: 254 case R_386_TLS_TPOFF32: 255 case R_386_TLS_DTPMOD32: 256 case R_386_TLS_DTPOFF32: 257 _rtld_error("%s: IFUNC for TLS reloc", 258 obj->path); 259 goto done; 260 } 261 } else { 262 if ((flags & SYMLOOK_IFUNC) != 0) 263 continue; 264 symval = (Elf_Addr)defobj->relocbase + 265 def->st_value; 266 } 267 break; 268 default: 269 if ((flags & SYMLOOK_IFUNC) != 0) 270 continue; 271 break; 272 } 273 where = (Elf_Addr *)(obj->relocbase + rel->r_offset); 274 275 switch (ELF_R_TYPE(rel->r_info)) { 276 case R_386_NONE: 277 break; 278 case R_386_32: 279 *where += symval; 280 break; 281 case R_386_PC32: 282 /* 283 * I don't think the dynamic linker should ever 284 * see this type of relocation. But the 285 * binutils-2.6 tools sometimes generate it. 286 */ 287 *where += symval - (Elf_Addr)where; 288 break; 289 case R_386_COPY: 290 /* 291 * These are deferred until all other 292 * relocations have been done. All we do here 293 * is make sure that the COPY relocation is 294 * not in a shared library. They are allowed 295 * only in executable files. 296 */ 297 if (!obj->mainprog) { 298 _rtld_error( 299 "%s: Unexpected R_386_COPY relocation in shared library", 300 obj->path); 301 goto done; 302 } 303 break; 304 case R_386_GLOB_DAT: 305 *where = symval; 306 break; 307 case R_386_RELATIVE: 308 *where += (Elf_Addr)obj->relocbase; 309 break; 310 case R_386_TLS_TPOFF: 311 case R_386_TLS_TPOFF32: 312 /* 313 * We lazily allocate offsets for static TLS 314 * as we see the first relocation that 315 * references the TLS block. This allows us to 316 * support (small amounts of) static TLS in 317 * dynamically loaded modules. If we run out 318 * of space, we generate an error. 319 */ 320 if (!defobj->tls_static) { 321 if (!allocate_tls_offset( 322 __DECONST(Obj_Entry *, defobj))) { 323 _rtld_error( 324 "%s: No space available for static Thread Local Storage", 325 obj->path); 326 goto done; 327 } 328 } 329 add = (Elf_Addr)(def->st_value - defobj->tlsoffset); 330 if (ELF_R_TYPE(rel->r_info) == R_386_TLS_TPOFF) 331 *where += add; 332 else 333 *where -= add; 334 break; 335 case R_386_TLS_DTPMOD32: 336 *where += (Elf_Addr)defobj->tlsindex; 337 break; 338 case R_386_TLS_DTPOFF32: 339 *where += (Elf_Addr)def->st_value; 340 break; 341 case R_386_IRELATIVE: 342 obj->irelative_nonplt = true; 343 break; 344 case R_386_TLS_DESC: 345 reloc_tlsdesc(obj, rel, (struct tlsdesc *)where, 346 flags, lockstate); 347 break; 348 default: 349 _rtld_error( 350 "%s: Unsupported relocation type %d in non-PLT relocations", 351 obj->path, ELF_R_TYPE(rel->r_info)); 352 goto done; 353 } 354 } 355 r = 0; 356 done: 357 free(cache); 358 return (r); 359 } 360 361 /* Process the PLT relocations. */ 362 int 363 reloc_plt(Obj_Entry *obj, int flags, RtldLockState *lockstate) 364 { 365 const Elf_Rel *rellim; 366 const Elf_Rel *rel; 367 368 rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize); 369 for (rel = obj->pltrel; rel < rellim; rel++) { 370 Elf_Addr *where; 371 372 where = (Elf_Addr *)(obj->relocbase + rel->r_offset); 373 switch (ELF_R_TYPE(rel->r_info)) { 374 case R_386_JMP_SLOT: 375 /* Relocate the GOT slot pointing into the PLT. */ 376 *where += (Elf_Addr)obj->relocbase; 377 break; 378 379 case R_386_IRELATIVE: 380 obj->irelative = true; 381 break; 382 383 case R_386_TLS_DESC: 384 reloc_tlsdesc(obj, rel, (struct tlsdesc *)where, 385 SYMLOOK_IN_PLT | flags, lockstate); 386 break; 387 388 default: 389 _rtld_error("Unknown relocation type %x in PLT", 390 ELF_R_TYPE(rel->r_info)); 391 return (-1); 392 } 393 } 394 return (0); 395 } 396 397 /* Relocate the jump slots in an object. */ 398 int 399 reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate) 400 { 401 const Elf_Rel *rellim; 402 const Elf_Rel *rel; 403 404 if (obj->jmpslots_done) 405 return (0); 406 rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize); 407 for (rel = obj->pltrel; rel < rellim; rel++) { 408 Elf_Addr *where, target; 409 const Elf_Sym *def; 410 const Obj_Entry *defobj; 411 412 switch (ELF_R_TYPE(rel->r_info)) { 413 case R_386_JMP_SLOT: 414 where = (Elf_Addr *)(obj->relocbase + rel->r_offset); 415 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, 416 SYMLOOK_IN_PLT | flags, NULL, lockstate); 417 if (def == NULL) 418 return (-1); 419 if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) { 420 obj->gnu_ifunc = true; 421 continue; 422 } 423 target = (Elf_Addr)(defobj->relocbase + def->st_value); 424 reloc_jmpslot(where, target, defobj, obj, rel); 425 break; 426 427 case R_386_IRELATIVE: 428 break; 429 430 default: 431 _rtld_error("Unknown relocation type %x in PLT", 432 ELF_R_TYPE(rel->r_info)); 433 return (-1); 434 } 435 } 436 437 obj->jmpslots_done = true; 438 return (0); 439 } 440 441 /* Fixup the jump slot at "where" to transfer control to "target". */ 442 Elf_Addr 443 reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *obj __unused, 444 const Obj_Entry *refobj __unused, const Elf_Rel *rel __unused) 445 { 446 dbg("reloc_jmpslot: *%p = %p", where, (void *)target); 447 if (!ld_bind_not) 448 *where = target; 449 return (target); 450 } 451 452 static void 453 reloc_iresolve_one(Obj_Entry *obj, const Elf_Rel *rel, RtldLockState *lockstate) 454 { 455 Elf_Addr *where, target; 456 457 where = (Elf_Addr *)(obj->relocbase + rel->r_offset); 458 lock_release(rtld_bind_lock, lockstate); 459 target = call_ifunc_resolver(obj->relocbase + *where); 460 wlock_acquire(rtld_bind_lock, lockstate); 461 *where = target; 462 } 463 464 int 465 reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate) 466 { 467 const Elf_Rel *rellim; 468 const Elf_Rel *rel; 469 470 if (!obj->irelative) 471 return (0); 472 obj->irelative = false; 473 rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize); 474 for (rel = obj->pltrel; rel < rellim; rel++) { 475 if (ELF_R_TYPE(rel->r_info) == R_386_IRELATIVE) 476 reloc_iresolve_one(obj, rel, lockstate); 477 } 478 return (0); 479 } 480 481 int 482 reloc_iresolve_nonplt(Obj_Entry *obj, RtldLockState *lockstate) 483 { 484 const Elf_Rel *rellim; 485 const Elf_Rel *rel; 486 487 if (!obj->irelative_nonplt) 488 return (0); 489 obj->irelative_nonplt = false; 490 rellim = (const Elf_Rel *)((const char *)obj->rel + obj->relsize); 491 for (rel = obj->rel; rel < rellim; rel++) { 492 if (ELF_R_TYPE(rel->r_info) == R_386_IRELATIVE) 493 reloc_iresolve_one(obj, rel, lockstate); 494 } 495 return (0); 496 } 497 498 int 499 reloc_gnu_ifunc(Obj_Entry *obj, int flags, RtldLockState *lockstate) 500 { 501 const Elf_Rel *rellim; 502 const Elf_Rel *rel; 503 504 if (!obj->gnu_ifunc) 505 return (0); 506 rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize); 507 for (rel = obj->pltrel; rel < rellim; rel++) { 508 Elf_Addr *where, target; 509 const Elf_Sym *def; 510 const Obj_Entry *defobj; 511 512 switch (ELF_R_TYPE(rel->r_info)) { 513 case R_386_JMP_SLOT: 514 where = (Elf_Addr *)(obj->relocbase + rel->r_offset); 515 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, 516 SYMLOOK_IN_PLT | flags, NULL, lockstate); 517 if (def == NULL) 518 return (-1); 519 if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC) 520 continue; 521 lock_release(rtld_bind_lock, lockstate); 522 target = (Elf_Addr)rtld_resolve_ifunc(defobj, def); 523 wlock_acquire(rtld_bind_lock, lockstate); 524 reloc_jmpslot(where, target, defobj, obj, rel); 525 break; 526 } 527 } 528 529 obj->gnu_ifunc = false; 530 return (0); 531 } 532 533 uint32_t cpu_feature, cpu_feature2, cpu_stdext_feature, cpu_stdext_feature2; 534 535 static void 536 rtld_cpuid_count(int idx, int cnt, u_int *p) 537 { 538 __asm __volatile( 539 " pushl %%ebx\n" 540 " cpuid\n" 541 " movl %%ebx,%1\n" 542 " popl %%ebx\n" 543 : "=a"(p[0]), "=r"(p[1]), "=c"(p[2]), "=d"(p[3]) 544 : "0"(idx), "2"(cnt)); 545 } 546 547 void 548 ifunc_init(Elf_Auxinfo *aux_info[__min_size(AT_COUNT)] __unused) 549 { 550 u_int p[4], cpu_high; 551 int cpuid_supported; 552 553 __asm __volatile( 554 " pushfl\n" 555 " popl %%eax\n" 556 " movl %%eax,%%ecx\n" 557 " xorl $0x200000,%%eax\n" 558 " pushl %%eax\n" 559 " popfl\n" 560 " pushfl\n" 561 " popl %%eax\n" 562 " xorl %%eax,%%ecx\n" 563 " je 1f\n" 564 " movl $1,%0\n" 565 " jmp 2f\n" 566 "1: movl $0,%0\n" 567 "2:\n" 568 : "=r"(cpuid_supported) 569 : 570 : "eax", "ecx"); 571 if (!cpuid_supported) 572 return; 573 574 rtld_cpuid_count(1, 0, p); 575 cpu_feature = p[3]; 576 cpu_feature2 = p[2]; 577 rtld_cpuid_count(0, 0, p); 578 cpu_high = p[0]; 579 if (cpu_high >= 7) { 580 rtld_cpuid_count(7, 0, p); 581 cpu_stdext_feature = p[1]; 582 cpu_stdext_feature2 = p[2]; 583 } 584 } 585 586 void 587 allocate_initial_tls(Obj_Entry *objs) 588 { 589 void *tls; 590 591 /* 592 * Fix the size of the static TLS block by using the maximum 593 * offset allocated so far and adding a bit for dynamic modules to 594 * use. 595 */ 596 tls_static_space = tls_last_offset + ld_static_tls_extra; 597 tls = allocate_tls(objs, NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN); 598 _tcb_set(tls); 599 } 600 601 __GNU_ABI void * 602 ___tls_get_addr(tls_index *ti) 603 { 604 return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset)); 605 } 606 607 /* Sun ABI */ 608 void * 609 __tls_get_addr(tls_index *ti) 610 { 611 return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset)); 612 } 613 614 size_t 615 calculate_tls_offset(size_t prev_offset, size_t prev_size __unused, size_t size, 616 size_t align, size_t offset) 617 { 618 size_t res; 619 620 /* 621 * res is the smallest integer satisfying res - prev_offset >= size 622 * and (-res) % p_align = p_vaddr % p_align (= p_offset % p_align). 623 */ 624 res = prev_offset + size + align - 1; 625 res -= (res + offset) & (align - 1); 626 return (res); 627 } 628 629 size_t 630 calculate_first_tls_offset(size_t size, size_t align, size_t offset) 631 { 632 return (calculate_tls_offset(0, 0, size, align, offset)); 633 } 634 635 __GNU_ABI ptrdiff_t 636 rtld_tlsdesc_dynamic_impl(struct tlsdesc *tdp) 637 { 638 struct tlsdesc_dynarg *tda; 639 struct tcb *tcb; 640 tls_index *ti; 641 642 tda = tdp->arg; 643 ti = &tda->tlsinfo; 644 tcb = _tcb_get(); 645 return ((ptrdiff_t)tls_get_addr_common(tcb, ti->ti_module, 646 ti->ti_offset) - (ptrdiff_t)tcb); 647 } 648