diff options
Diffstat (limited to 'newlib/libc/sys/linux/dl/dl-runtime.c')
-rw-r--r-- | newlib/libc/sys/linux/dl/dl-runtime.c | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/newlib/libc/sys/linux/dl/dl-runtime.c b/newlib/libc/sys/linux/dl/dl-runtime.c deleted file mode 100644 index 4fb81cfaf..000000000 --- a/newlib/libc/sys/linux/dl/dl-runtime.c +++ /dev/null @@ -1,233 +0,0 @@ -/* On-demand PLT fixup for shared objects. - Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include <alloca.h> -#include <stdlib.h> -#include <unistd.h> -#include <ldsodefs.h> -#include "dynamic-link.h" - -#ifndef __attribute_used__ -#define __attribute_used__ -#endif - -#if !defined ELF_MACHINE_NO_RELA || ELF_MACHINE_NO_REL -# define PLTREL ElfW(Rela) -#else -# define PLTREL ElfW(Rel) -#endif - -#ifndef VERSYMIDX -# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) -#endif - - -/* This function is called through a special trampoline from the PLT the - first time each PLT entry is called. We must perform the relocation - specified in the PLT of the given shared object, and return the resolved - function address to the trampoline, which will restart the original call - to that address. Future calls will bounce directly from the PLT to the - function. */ - -#ifndef ELF_MACHINE_NO_PLT -static ElfW(Addr) __attribute__ ((regparm (2), used)) -fixup ( -# ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS - ELF_MACHINE_RUNTIME_FIXUP_ARGS, -# endif - /* GKM FIXME: Fix trampoline to pass bounds so we can do - without the `__unbounded' qualifier. */ - struct link_map *__unbounded l, ElfW(Word) reloc_offset) -{ - const ElfW(Sym) *const symtab - = (const void *) D_PTR (l, l_info[DT_SYMTAB]); - const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); - - const PLTREL *const reloc - = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset); - const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; - void *const rel_addr = (void *)(l->l_addr + reloc->r_offset); - lookup_t result; - ElfW(Addr) value; - - /* The use of `alloca' here looks ridiculous but it helps. The goal is - to prevent the function from being inlined and thus optimized out. - There is no official way to do this so we use this trick. gcc never - inlines functions which use `alloca'. */ - alloca (sizeof (int)); - - /* Sanity check that we're really looking at a PLT relocation. */ - assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); - - /* Look up the target symbol. If the normal lookup rules are not - used don't look in the global scope. */ - if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) - { - switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) - { - default: - { - const ElfW(Half) *vernum = - (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]); - ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; - const struct r_found_version *version = &l->l_versions[ndx]; - - if (version->hash != 0) - { - result = _dl_lookup_versioned_symbol (strtab + sym->st_name, - l, &sym, l->l_scope, - version, - ELF_RTYPE_CLASS_PLT, 0); - break; - } - } - case 0: - result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, - l->l_scope, ELF_RTYPE_CLASS_PLT, 0); - } - - /* Currently result contains the base load address (or link map) - of the object that defines sym. Now add in the symbol - offset. */ - value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0); - } - else - { - /* We already found the symbol. The module (and therefore its load - address) is also known. */ - value = l->l_addr + sym->st_value; -#ifdef DL_LOOKUP_RETURNS_MAP - result = l; -#endif - } - - /* And now perhaps the relocation addend. */ - value = elf_machine_plt_value (l, reloc, value); - - /* Finally, fix up the plt itself. */ - if (__builtin_expect (_dl_bind_not, 0)) - return value; - - return elf_machine_fixup_plt (l, result, reloc, rel_addr, value); -} -#endif - -#if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__ - -static ElfW(Addr) __attribute__ ((regparm (3), used)) -profile_fixup ( -#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS - ELF_MACHINE_RUNTIME_FIXUP_ARGS, -#endif - struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr) -{ - void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount; - ElfW(Addr) *resultp; - lookup_t result; - ElfW(Addr) value; - - /* The use of `alloca' here looks ridiculous but it helps. The goal is - to prevent the function from being inlined, and thus optimized out. - There is no official way to do this so we use this trick. gcc never - inlines functions which use `alloca'. */ - alloca (sizeof (int)); - - /* This is the address in the array where we store the result of previous - relocations. */ - resultp = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)]; - - value = *resultp; - if (value == 0) - { - /* This is the first time we have to relocate this object. */ - const ElfW(Sym) *const symtab - = (const void *) D_PTR (l, l_info[DT_SYMTAB]); - const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); - - const PLTREL *const reloc - = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset); - const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; - - /* Sanity check that we're really looking at a PLT relocation. */ - assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); - - /* Look up the target symbol. If the symbol is marked STV_PROTECTED - don't look in the global scope. */ - if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) - { - switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) - { - default: - { - const ElfW(Half) *vernum = - (const void *) D_PTR (l,l_info[VERSYMIDX (DT_VERSYM)]); - ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; - const struct r_found_version *version = &l->l_versions[ndx]; - - if (version->hash != 0) - { - result = _dl_lookup_versioned_symbol(strtab + sym->st_name, - l, &sym, l->l_scope, - version, - ELF_RTYPE_CLASS_PLT, - 0); - break; - } - } - case 0: - result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, - l->l_scope, ELF_RTYPE_CLASS_PLT, 0); - } - - /* Currently result contains the base load address (or link map) - of the object that defines sym. Now add in the symbol - offset. */ - value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0); - } - else - { - /* We already found the symbol. The module (and therefore its load - address) is also known. */ - value = l->l_addr + sym->st_value; -#ifdef DL_LOOKUP_RETURNS_MAP - result = l; -#endif - } - /* And now perhaps the relocation addend. */ - value = elf_machine_plt_value (l, reloc, value); - - /* Store the result for later runs. */ - if (__builtin_expect (! _dl_bind_not, 1)) - *resultp = value; - } - - (*mcount_fct) (retaddr, value); - - return value; -} - -#endif /* PROF && ELF_MACHINE_NO_PLT */ - - -/* This macro is defined in dl-machine.h to define the entry point called - by the PLT. The `fixup' function above does the real work, but a little - more twiddling is needed to get the stack right and jump to the address - finally resolved. */ - -ELF_MACHINE_RUNTIME_TRAMPOLINE |