2 * Copyright 1996, 1997, 1998, 1999 John D. Polstra.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * Dynamic linker for ELF.
31 * John Polstra <jdp@polstra.com>.
34 #include <sys/param.h>
36 #include <machine/ia64_cpu.h>
51 extern Elf_Dyn _DYNAMIC;
54 * Macros for loading/storing unaligned 64-bit values. These are
55 * needed because relocations can point to unaligned data. This
56 * occurs in the DWARF2 exception frame tables generated by the
57 * compiler, for instance.
59 * We don't use these when relocating jump slots and GOT entries,
60 * since they are guaranteed to be aligned.
62 * XXX dfr stub for now.
64 #define load64(p) (*(u_int64_t *) (p))
65 #define store64(p, v) (*(u_int64_t *) (p) = (v))
67 /* Allocate an @fptr. */
69 #define FPTR_CHUNK_SIZE 64
72 struct fptr fptrs[FPTR_CHUNK_SIZE];
75 static struct fptr_chunk first_chunk;
76 static struct fptr_chunk *current_chunk = &first_chunk;
77 static struct fptr *next_fptr = &first_chunk.fptrs[0];
78 static struct fptr *last_fptr = &first_chunk.fptrs[FPTR_CHUNK_SIZE];
81 * We use static storage initially so that we don't have to call
82 * malloc during init_rtld().
85 alloc_fptr(Elf_Addr target, Elf_Addr gp)
89 if (next_fptr == last_fptr) {
90 current_chunk = xmalloc(sizeof(struct fptr_chunk));
91 next_fptr = ¤t_chunk->fptrs[0];
92 last_fptr = ¤t_chunk->fptrs[FPTR_CHUNK_SIZE];
96 fptr->target = target;
101 static struct fptr **
102 alloc_fptrs(Obj_Entry *obj, bool mapped)
107 fbytes = obj->dynsymcount * sizeof(struct fptr *);
110 * Avoid malloc, if requested. Happens when relocating
111 * rtld itself on startup.
114 fptrs = mmap(NULL, fbytes, PROT_READ|PROT_WRITE,
116 if (fptrs == MAP_FAILED)
119 fptrs = xcalloc(1, fbytes);
123 * This assertion is necessary to guarantee function pointer
126 assert(fptrs != NULL);
128 return (obj->priv = fptrs);
132 free_fptrs(Obj_Entry *obj, bool mapped)
141 fbytes = obj->dynsymcount * sizeof(struct fptr *);
143 munmap(fptrs, fbytes);
149 /* Relocate a non-PLT object with addend. */
151 reloc_non_plt_obj(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
152 SymCache *cache, int flags, RtldLockState *lockstate)
155 Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rela->r_offset);
157 switch (ELF_R_TYPE(rela->r_info)) {
158 case R_IA_64_REL64LSB:
160 * We handle rtld's relocations in rtld_start.S
164 load64(where) + (Elf_Addr) obj->relocbase);
167 case R_IA_64_DIR64LSB: {
169 const Obj_Entry *defobj;
172 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
173 flags, cache, lockstate);
177 target = (def->st_shndx != SHN_UNDEF)
178 ? (Elf_Addr)(defobj->relocbase + def->st_value) : 0;
179 store64(where, target + rela->r_addend);
183 case R_IA_64_FPTR64LSB: {
185 * We have to make sure that all @fptr references to
186 * the same function are identical so that code can
187 * compare function pointers.
190 const Obj_Entry *defobj;
191 struct fptr *fptr = 0;
195 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
196 SYMLOOK_IN_PLT | flags, cache, lockstate);
199 * XXX r_debug_state is problematic and find_symdef()
200 * returns NULL for it. This probably has something to
201 * do with symbol versioning (r_debug_state is in the
202 * symbol map). If we return -1 in that case we abort
203 * relocating rtld, which typically is fatal. So, for
204 * now just skip the symbol when we're relocating
205 * rtld. We don't care about r_debug_state unless we
206 * are being debugged.
213 if (def->st_shndx != SHN_UNDEF) {
214 target = (Elf_Addr)(defobj->relocbase + def->st_value);
215 gp = (Elf_Addr)defobj->pltgot;
217 /* rtld is allowed to reference itself only */
218 assert(!obj->rtld || obj == defobj);
219 fptrs = defobj->priv;
221 fptrs = alloc_fptrs((Obj_Entry *) defobj,
224 sym_index = def - defobj->symtab;
227 * Find the @fptr, using fptrs as a helper.
230 fptr = fptrs[sym_index];
232 fptr = alloc_fptr(target, gp);
234 fptrs[sym_index] = fptr;
239 store64(where, (Elf_Addr)fptr);
243 case R_IA_64_IPLTLSB: {
245 * Relocation typically used to populate C++ virtual function
246 * tables. It creates a 128-bit function descriptor at the
247 * specified memory address.
250 const Obj_Entry *defobj;
254 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
255 flags, cache, lockstate);
259 if (def->st_shndx != SHN_UNDEF) {
260 target = (Elf_Addr)(defobj->relocbase + def->st_value);
261 gp = (Elf_Addr)defobj->pltgot;
268 store64(&fptr->target, target);
269 store64(&fptr->gp, gp);
273 case R_IA_64_DTPMOD64LSB: {
275 const Obj_Entry *defobj;
277 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
278 flags, cache, lockstate);
282 store64(where, defobj->tlsindex);
286 case R_IA_64_DTPREL64LSB: {
288 const Obj_Entry *defobj;
290 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
291 flags, cache, lockstate);
295 store64(where, def->st_value + rela->r_addend);
299 case R_IA_64_TPREL64LSB: {
301 const Obj_Entry *defobj;
303 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
304 flags, cache, lockstate);
309 * We lazily allocate offsets for static TLS as we
310 * see the first relocation that references the
311 * TLS block. This allows us to support (small
312 * amounts of) static TLS in dynamically loaded
313 * modules. If we run out of space, we generate an
316 if (!defobj->tls_done) {
317 if (!allocate_tls_offset((Obj_Entry*) defobj)) {
318 _rtld_error("%s: No space available for static "
319 "Thread Local Storage", obj->path);
324 store64(where, defobj->tlsoffset + def->st_value + rela->r_addend);
332 _rtld_error("%s: Unsupported relocation type %u"
333 " in non-PLT relocations\n", obj->path,
334 (unsigned int)ELF_R_TYPE(rela->r_info));
341 /* Process the non-PLT relocations. */
343 reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
344 RtldLockState *lockstate)
346 const Elf_Rel *rellim;
348 const Elf_Rela *relalim;
349 const Elf_Rela *rela;
351 int bytes = obj->dynsymcount * sizeof(SymCache);
354 if ((flags & SYMLOOK_IFUNC) != 0)
355 /* XXX not implemented */
359 * The dynamic loader may be called from a thread, we have
360 * limited amounts of stack available so we cannot use alloca().
362 cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
363 if (cache == MAP_FAILED)
366 /* Perform relocations without addend if there are any: */
367 rellim = (const Elf_Rel *) ((caddr_t) obj->rel + obj->relsize);
368 for (rel = obj->rel; obj->rel != NULL && rel < rellim; rel++) {
371 locrela.r_info = rel->r_info;
372 locrela.r_offset = rel->r_offset;
373 locrela.r_addend = 0;
374 if (reloc_non_plt_obj(obj_rtld, obj, &locrela, cache, flags,
379 /* Perform relocations with addend if there are any: */
380 relalim = (const Elf_Rela *) ((caddr_t) obj->rela + obj->relasize);
381 for (rela = obj->rela; obj->rela != NULL && rela < relalim; rela++) {
382 if (reloc_non_plt_obj(obj_rtld, obj, rela, cache, flags,
390 munmap(cache, bytes);
393 * Release temporarily mapped fptrs if relocating
394 * rtld object itself. A new table will be created
395 * in make_function_pointer using malloc when needed.
397 if (obj->rtld && obj->priv)
398 free_fptrs(obj, true);
403 /* Process the PLT relocations. */
405 reloc_plt(Obj_Entry *obj)
407 /* All PLT relocations are the same kind: Elf_Rel or Elf_Rela. */
408 if (obj->pltrelsize != 0) {
409 const Elf_Rel *rellim;
412 rellim = (const Elf_Rel *)
413 ((char *)obj->pltrel + obj->pltrelsize);
414 for (rel = obj->pltrel; rel < rellim; rel++) {
417 assert(ELF_R_TYPE(rel->r_info) == R_IA_64_IPLTLSB);
419 /* Relocate the @fptr pointing into the PLT. */
420 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
421 *where += (Elf_Addr)obj->relocbase;
424 const Elf_Rela *relalim;
425 const Elf_Rela *rela;
427 relalim = (const Elf_Rela *)
428 ((char *)obj->pltrela + obj->pltrelasize);
429 for (rela = obj->pltrela; rela < relalim; rela++) {
432 assert(ELF_R_TYPE(rela->r_info) == R_IA_64_IPLTLSB);
434 /* Relocate the @fptr pointing into the PLT. */
435 where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
436 *where += (Elf_Addr)obj->relocbase;
443 reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
446 /* XXX not implemented */
451 reloc_gnu_ifunc(Obj_Entry *obj, int flags,
452 struct Struct_RtldLockState *lockstate)
455 /* XXX not implemented */
459 /* Relocate the jump slots in an object. */
461 reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
463 if (obj->jmpslots_done)
465 /* All PLT relocations are the same kind: Elf_Rel or Elf_Rela. */
466 if (obj->pltrelsize != 0) {
467 const Elf_Rel *rellim;
470 rellim = (const Elf_Rel *)
471 ((char *)obj->pltrel + obj->pltrelsize);
472 for (rel = obj->pltrel; rel < rellim; rel++) {
475 const Obj_Entry *defobj;
477 assert(ELF_R_TYPE(rel->r_info) == R_IA_64_IPLTLSB);
478 where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
479 def = find_symdef(ELF_R_SYM(rel->r_info), obj,
480 &defobj, SYMLOOK_IN_PLT | flags, NULL, lockstate);
484 (Elf_Addr)(defobj->relocbase
489 const Elf_Rela *relalim;
490 const Elf_Rela *rela;
492 relalim = (const Elf_Rela *)
493 ((char *)obj->pltrela + obj->pltrelasize);
494 for (rela = obj->pltrela; rela < relalim; rela++) {
497 const Obj_Entry *defobj;
499 where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
500 def = find_symdef(ELF_R_SYM(rela->r_info), obj,
501 &defobj, SYMLOOK_IN_PLT | flags, NULL, lockstate);
505 (Elf_Addr)(defobj->relocbase
507 defobj, obj, (Elf_Rel *)rela);
510 obj->jmpslots_done = true;
514 /* Fixup the jump slot at "where" to transfer control to "target". */
516 reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *obj,
517 const Obj_Entry *refobj, const Elf_Rel *rel)
521 dbg(" reloc_jmpslot: where=%p, target=%p, gp=%p",
522 (void *)where, (void *)target, (void *)obj->pltgot);
524 if (stubaddr != target) {
527 * Point this @fptr directly at the target. Update the
528 * gp value first so that we don't break another cpu
529 * which is currently executing the PLT entry.
531 where[1] = (Elf_Addr) obj->pltgot;
538 * The caller needs an @fptr for the adjusted entry. The PLT
539 * entry serves this purpose nicely.
541 return (Elf_Addr) where;
545 * XXX ia64 doesn't seem to have copy relocations.
547 * Returns 0 on success, -1 on failure.
550 do_copy_relocations(Obj_Entry *dstobj)
557 * Return the @fptr representing a given function symbol.
560 make_function_pointer(const Elf_Sym *sym, const Obj_Entry *obj)
562 struct fptr **fptrs = obj->priv;
563 int index = sym - obj->symtab;
567 * This should only happen for something like
568 * dlsym("dlopen"). Actually, I'm not sure it can ever
571 fptrs = alloc_fptrs((Obj_Entry *) obj, false);
575 target = (Elf_Addr) (obj->relocbase + sym->st_value);
576 gp = (Elf_Addr) obj->pltgot;
577 fptrs[index] = alloc_fptr(target, gp);
583 call_initfini_pointer(const Obj_Entry *obj, Elf_Addr target)
587 fptr.gp = (Elf_Addr) obj->pltgot;
588 fptr.target = target;
589 dbg(" initfini: target=%p, gp=%p",
590 (void *) fptr.target, (void *) fptr.gp);
591 ((InitFunc) &fptr)();
595 call_init_pointer(const Obj_Entry *obj, Elf_Addr target)
599 fptr.gp = (Elf_Addr) obj->pltgot;
600 fptr.target = target;
601 dbg(" initfini: target=%p, gp=%p",
602 (void *) fptr.target, (void *) fptr.gp);
603 ((InitArrFunc) &fptr)(main_argc, main_argv, environ);
607 ifunc_init(Elf_Auxinfo aux_info[__min_size(AT_COUNT)] __unused)
618 /* Initialize the special PLT entries. */
620 init_pltgot(Obj_Entry *obj)
623 Elf_Addr *pltres = 0;
626 * When there are no PLT relocations, the DT_IA_64_PLT_RESERVE entry
627 * is bogus. Do not setup the BOR pointers in that case. An example
628 * of where this happens is /usr/lib/libxpg4.so.3.
630 if (obj->pltrelasize == 0 && obj->pltrelsize == 0)
634 * Find the PLT RESERVE section.
636 for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; dynp++) {
637 if (dynp->d_tag == DT_IA_64_PLT_RESERVE)
638 pltres = (u_int64_t *)
639 (obj->relocbase + dynp->d_un.d_ptr);
642 errx(1, "Can't find DT_IA_64_PLT_RESERVE entry");
645 * The PLT RESERVE section is used to get values to pass to
646 * _rtld_bind when lazy binding.
648 pltres[0] = (Elf_Addr) obj;
649 pltres[1] = FPTR_TARGET(_rtld_bind_start);
650 pltres[2] = FPTR_GP(_rtld_bind_start);
654 allocate_initial_tls(Obj_Entry *list)
659 * Fix the size of the static TLS block by using the maximum
660 * offset allocated so far and adding a bit for dynamic modules to
663 tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA;
665 tpval = allocate_tls(list, NULL, TLS_TCB_SIZE, 16);
666 __asm __volatile("mov r13 = %0" :: "r"(tpval));
669 void *__tls_get_addr(unsigned long module, unsigned long offset)
671 register Elf_Addr** tp __asm__("r13");
673 return tls_get_addr_common(tp, module, offset);