diff options
author | Jakub Jelinek <jakub@redhat.com> | 2009-03-20 20:00:20 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2009-03-20 20:00:20 +0000 |
commit | ef860a878bf532436a469fc1f89fe3366862a949 (patch) | |
tree | c4a2666ac77cdaa00f41bd8f66a828b39e2642ff /elf/dl-runtime.c | |
parent | d4c583b4466962a9d9d4ca54ab6108dc7b42cdcc (diff) | |
download | glibc-ef860a878bf532436a469fc1f89fe3366862a949.tar.gz glibc-ef860a878bf532436a469fc1f89fe3366862a949.tar.xz glibc-ef860a878bf532436a469fc1f89fe3366862a949.zip |
Updated to fedora-glibc-20090320T1944 cvs/fedora-glibc-2_9_90-11
Diffstat (limited to 'elf/dl-runtime.c')
-rw-r--r-- | elf/dl-runtime.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c index 968e293409..93c8f29d39 100644 --- a/elf/dl-runtime.c +++ b/elf/dl-runtime.c @@ -1,5 +1,5 @@ /* On-demand PLT fixup for shared objects. - Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc. + Copyright (C) 1995-2006, 2007, 2008, 2009 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 @@ -46,6 +46,12 @@ # define ARCH_FIXUP_ATTRIBUTE #endif +#ifndef reloc_offset +# define reloc_offset reloc_arg +# define reloc_index reloc_arg / sizeof (PLTREL) +#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 @@ -63,7 +69,7 @@ _dl_fixup ( # 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) + struct link_map *__unbounded l, ElfW(Word) reloc_arg) { const ElfW(Sym) *const symtab = (const void *) D_PTR (l, l_info[DT_SYMTAB]); @@ -130,6 +136,9 @@ _dl_fixup ( /* And now perhaps the relocation addend. */ value = elf_machine_plt_value (l, reloc, value); + if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) + value = ((DL_FIXUP_VALUE_TYPE (*) (void)) value) (); + /* Finally, fix up the plt itself. */ if (__builtin_expect (GLRO(dl_bind_not), 0)) return value; @@ -139,22 +148,20 @@ _dl_fixup ( #endif #if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__ - DL_FIXUP_VALUE_TYPE __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE _dl_profile_fixup ( #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS ELF_MACHINE_RUNTIME_FIXUP_ARGS, #endif - struct link_map *l, ElfW(Word) reloc_offset, + struct link_map *l, ElfW(Word) reloc_arg, ElfW(Addr) retaddr, void *regs, long int *framesizep) { void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = INTUSE(_dl_mcount); /* This is the address in the array where we store the result of previous relocations. */ - struct reloc_result *reloc_result - = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)]; + struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index]; DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr; DL_FIXUP_VALUE_TYPE value = *resultp; @@ -215,12 +222,21 @@ _dl_profile_fixup ( defsym != NULL ? LOOKUP_VALUE_ADDRESS (result) + defsym->st_value : 0); + + if (__builtin_expect (ELFW(ST_TYPE) (defsym->st_info) + == STT_GNU_IFUNC, 0)) + value = ((DL_FIXUP_VALUE_TYPE (*) (void)) value) (); } else { /* We already found the symbol. The module (and therefore its load address) is also known. */ value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + refsym->st_value); + + if (__builtin_expect (ELFW(ST_TYPE) (refsym->st_info) + == STT_GNU_IFUNC, 0)) + value = ((DL_FIXUP_VALUE_TYPE (*) (void)) value) (); + result = l; } /* And now perhaps the relocation addend. */ @@ -403,7 +419,7 @@ _dl_profile_fixup ( #include <stdio.h> void ARCH_FIXUP_ATTRIBUTE -_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_offset, +_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg, const void *inregs, void *outregs) { #ifdef SHARED @@ -411,8 +427,7 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_offset, relocations. */ // XXX Maybe the bound information must be stored on the stack since // XXX with bind_not a new value could have been stored in the meantime. - struct reloc_result *reloc_result - = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)]; + struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index]; ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, l_info[DT_SYMTAB]) + reloc_result->boundndx); |