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/sysarch.h>
53 * Process the special R_X86_64_COPY relocations in the main program. These
54 * copy data from a shared object into a region in the main program's BSS
57 * Returns 0 on success, -1 on failure.
60 do_copy_relocations(Obj_Entry *dstobj)
62 const Elf_Rela *relalim;
65 assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */
67 relalim = (const Elf_Rela *) ((caddr_t) dstobj->rela + dstobj->relasize);
68 for (rela = dstobj->rela; rela < relalim; rela++) {
69 if (ELF_R_TYPE(rela->r_info) == R_X86_64_COPY) {
71 const Elf_Sym *dstsym;
75 const Elf_Sym *srcsym;
76 const Obj_Entry *srcobj, *defobj;
80 dstaddr = (void *) (dstobj->relocbase + rela->r_offset);
81 dstsym = dstobj->symtab + ELF_R_SYM(rela->r_info);
82 name = dstobj->strtab + dstsym->st_name;
83 size = dstsym->st_size;
84 symlook_init(&req, name);
85 req.ventry = fetch_ventry(dstobj, ELF_R_SYM(rela->r_info));
86 req.flags = SYMLOOK_EARLY;
88 for (srcobj = globallist_next(dstobj); srcobj != NULL;
89 srcobj = globallist_next(srcobj)) {
90 res = symlook_obj(&req, srcobj);
93 defobj = req.defobj_out;
99 _rtld_error("Undefined symbol \"%s\" referenced from COPY"
100 " relocation in %s", name, dstobj->path);
104 srcaddr = (const void *) (defobj->relocbase + srcsym->st_value);
105 memcpy(dstaddr, srcaddr, size);
112 /* Initialize the special GOT entries. */
114 init_pltgot(Obj_Entry *obj)
116 if (obj->pltgot != NULL) {
117 obj->pltgot[1] = (Elf_Addr) obj;
118 obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
122 /* Process the non-PLT relocations. */
124 reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
125 RtldLockState *lockstate)
127 const Elf_Rela *relalim;
128 const Elf_Rela *rela;
131 const Obj_Entry *defobj;
132 Elf_Addr *where, symval;
138 * The dynamic loader may be called from a thread, we have
139 * limited amounts of stack available so we cannot use alloca().
141 if (obj != obj_rtld) {
142 cache = calloc(obj->dynsymcount, sizeof(SymCache));
143 /* No need to check for NULL here */
147 relalim = (const Elf_Rela *)((caddr_t)obj->rela + obj->relasize);
148 for (rela = obj->rela; rela < relalim; rela++) {
150 * First, resolve symbol for relocations which
153 switch (ELF_R_TYPE(rela->r_info)) {
156 case R_X86_64_GLOB_DAT:
157 case R_X86_64_TPOFF64:
158 case R_X86_64_TPOFF32:
159 case R_X86_64_DTPMOD64:
160 case R_X86_64_DTPOFF64:
161 case R_X86_64_DTPOFF32:
162 def = find_symdef(ELF_R_SYM(rela->r_info), obj,
163 &defobj, flags, cache, lockstate);
167 * If symbol is IFUNC, only perform relocation
168 * when caller allowed it by passing
169 * SYMLOOK_IFUNC flag. Skip the relocations
172 * Also error out in case IFUNC relocations
173 * are specified for TLS, which cannot be
174 * usefully interpreted.
176 if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
177 switch (ELF_R_TYPE(rela->r_info)) {
180 case R_X86_64_GLOB_DAT:
181 if ((flags & SYMLOOK_IFUNC) == 0) {
182 obj->non_plt_gnu_ifunc = true;
185 symval = (Elf_Addr)rtld_resolve_ifunc(
188 case R_X86_64_TPOFF64:
189 case R_X86_64_TPOFF32:
190 case R_X86_64_DTPMOD64:
191 case R_X86_64_DTPOFF64:
192 case R_X86_64_DTPOFF32:
193 _rtld_error("%s: IFUNC for TLS reloc",
198 if ((flags & SYMLOOK_IFUNC) != 0)
200 symval = (Elf_Addr)defobj->relocbase +
205 if ((flags & SYMLOOK_IFUNC) != 0)
209 where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
210 where32 = (Elf32_Addr *)where;
212 switch (ELF_R_TYPE(rela->r_info)) {
216 *where = symval + rela->r_addend;
220 * I don't think the dynamic linker should
221 * ever see this type of relocation. But the
222 * binutils-2.6 tools sometimes generate it.
224 *where32 = (Elf32_Addr)(unsigned long)(symval +
225 rela->r_addend - (Elf_Addr)where);
227 /* missing: R_X86_64_GOT32 R_X86_64_PLT32 */
230 * These are deferred until all other relocations have
231 * been done. All we do here is make sure that the COPY
232 * relocation is not in a shared library. They are allowed
233 * only in executable files.
235 if (!obj->mainprog) {
236 _rtld_error("%s: Unexpected R_X86_64_COPY "
237 "relocation in shared library", obj->path);
241 case R_X86_64_GLOB_DAT:
244 case R_X86_64_TPOFF64:
246 * We lazily allocate offsets for static TLS
247 * as we see the first relocation that
248 * references the TLS block. This allows us to
249 * support (small amounts of) static TLS in
250 * dynamically loaded modules. If we run out
251 * of space, we generate an error.
253 if (!defobj->tls_done) {
254 if (!allocate_tls_offset((Obj_Entry*) defobj)) {
255 _rtld_error("%s: No space available "
256 "for static Thread Local Storage",
261 *where = (Elf_Addr)(def->st_value - defobj->tlsoffset +
264 case R_X86_64_TPOFF32:
266 * We lazily allocate offsets for static TLS
267 * as we see the first relocation that
268 * references the TLS block. This allows us to
269 * support (small amounts of) static TLS in
270 * dynamically loaded modules. If we run out
271 * of space, we generate an error.
273 if (!defobj->tls_done) {
274 if (!allocate_tls_offset((Obj_Entry*) defobj)) {
275 _rtld_error("%s: No space available "
276 "for static Thread Local Storage",
281 *where32 = (Elf32_Addr)(def->st_value -
282 defobj->tlsoffset + rela->r_addend);
284 case R_X86_64_DTPMOD64:
285 *where += (Elf_Addr)defobj->tlsindex;
287 case R_X86_64_DTPOFF64:
288 *where += (Elf_Addr)(def->st_value + rela->r_addend);
290 case R_X86_64_DTPOFF32:
291 *where32 += (Elf32_Addr)(def->st_value +
294 case R_X86_64_RELATIVE:
295 *where = (Elf_Addr)(obj->relocbase + rela->r_addend);
299 * R_X86_64_GOTPCREL, R_X86_64_32, R_X86_64_32S, R_X86_64_16,
300 * R_X86_64_PC16, R_X86_64_8, R_X86_64_PC8
303 _rtld_error("%s: Unsupported relocation type %u"
304 " in non-PLT relocations\n", obj->path,
305 (unsigned int)ELF_R_TYPE(rela->r_info));
315 /* Process the PLT relocations. */
317 reloc_plt(Obj_Entry *obj)
319 const Elf_Rela *relalim;
320 const Elf_Rela *rela;
322 relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
323 for (rela = obj->pltrela; rela < relalim; rela++) {
326 switch(ELF_R_TYPE(rela->r_info)) {
327 case R_X86_64_JMP_SLOT:
328 /* Relocate the GOT slot pointing into the PLT. */
329 where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
330 *where += (Elf_Addr)obj->relocbase;
333 case R_X86_64_IRELATIVE:
334 obj->irelative = true;
338 _rtld_error("Unknown relocation type %x in PLT",
339 (unsigned int)ELF_R_TYPE(rela->r_info));
346 /* Relocate the jump slots in an object. */
348 reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
350 const Elf_Rela *relalim;
351 const Elf_Rela *rela;
353 if (obj->jmpslots_done)
355 relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
356 for (rela = obj->pltrela; rela < relalim; rela++) {
357 Elf_Addr *where, target;
359 const Obj_Entry *defobj;
361 switch (ELF_R_TYPE(rela->r_info)) {
362 case R_X86_64_JMP_SLOT:
363 where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
364 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
365 SYMLOOK_IN_PLT | flags, NULL, lockstate);
368 if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
369 obj->gnu_ifunc = true;
372 target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend);
373 reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
376 case R_X86_64_IRELATIVE:
380 _rtld_error("Unknown relocation type %x in PLT",
381 (unsigned int)ELF_R_TYPE(rela->r_info));
385 obj->jmpslots_done = true;
390 reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
392 const Elf_Rela *relalim;
393 const Elf_Rela *rela;
397 relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
398 for (rela = obj->pltrela; rela < relalim; rela++) {
399 Elf_Addr *where, target, *ptr;
401 switch (ELF_R_TYPE(rela->r_info)) {
402 case R_X86_64_JMP_SLOT:
405 case R_X86_64_IRELATIVE:
406 ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend);
407 where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
408 lock_release(rtld_bind_lock, lockstate);
409 target = ((Elf_Addr (*)(void))ptr)();
410 wlock_acquire(rtld_bind_lock, lockstate);
415 obj->irelative = false;
420 reloc_gnu_ifunc(Obj_Entry *obj, int flags, RtldLockState *lockstate)
422 const Elf_Rela *relalim;
423 const Elf_Rela *rela;
427 relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
428 for (rela = obj->pltrela; rela < relalim; rela++) {
429 Elf_Addr *where, target;
431 const Obj_Entry *defobj;
433 switch (ELF_R_TYPE(rela->r_info)) {
434 case R_X86_64_JMP_SLOT:
435 where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
436 def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
437 SYMLOOK_IN_PLT | flags, NULL, lockstate);
440 if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC)
442 lock_release(rtld_bind_lock, lockstate);
443 target = (Elf_Addr)rtld_resolve_ifunc(defobj, def);
444 wlock_acquire(rtld_bind_lock, lockstate);
445 reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
449 obj->gnu_ifunc = false;
454 allocate_initial_tls(Obj_Entry *objs)
457 * Fix the size of the static TLS block by using the maximum
458 * offset allocated so far and adding a bit for dynamic modules to
461 tls_static_space = tls_last_offset + RTLD_STATIC_TLS_EXTRA;
462 amd64_set_fsbase(allocate_tls(objs, 0,
463 3*sizeof(Elf_Addr), sizeof(Elf_Addr)));
466 void *__tls_get_addr(tls_index *ti)
470 __asm __volatile("movq %%fs:0, %0" : "=r" (segbase));
472 return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset);