1 /* On-demand PLT fixup for shared objects.
2 Copyright (C) 1995, 1996 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, USA. */
21 #include "dynamic-link.h"
23 /* Figure out the right type, Rel or Rela. */
24 #define elf_machine_rel 1
25 #define elf_machine_rela 2
26 #if elf_machine_relplt == elf_machine_rel
27 #define PLTREL Elf32_Rel
28 #elif elf_machine_relplt == elf_machine_rela
29 #define PLTREL Elf32_Rela
31 #error "dl-machine.h bug: elf_machine_relplt not rel or rela"
33 #undef elf_machine_rel
34 #undef elf_machine_rela
36 /* We need to define the function as a local symbol so that the reference
37 in the trampoline code will be a local PC-relative call. Tell the
38 compiler not to worry that the function appears not to be called. */
40 static Elf32_Addr fixup (
41 #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
42 ELF_MACHINE_RUNTIME_FIXUP_ARGS,
44 struct link_map *l, Elf32_Word reloc_offset)
45 __attribute__ ((unused));
47 /* This function is called through a special trampoline from the PLT the
48 first time each PLT entry is called. We must perform the relocation
49 specified in the PLT of the given shared object, and return the resolved
50 function address to the trampoline, which will restart the original call
51 to that address. Future calls will bounce directly from the PLT to the
56 #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
57 ELF_MACHINE_RUNTIME_FIXUP_ARGS,
59 struct link_map *l, Elf32_Word reloc_offset)
61 const Elf32_Sym *const symtab
62 = (const Elf32_Sym *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
64 (const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
66 const PLTREL *const reloc
67 = (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
70 Elf32_Addr resolve (const Elf32_Sym **ref,
71 Elf32_Addr reloc_addr, int noplt)
73 struct link_map *scope[2] = { _dl_loaded, NULL };
74 return _dl_lookup_symbol (strtab + (*ref)->st_name, ref,
75 scope, l->l_name, reloc_addr, noplt);
78 /* Perform the specified relocation. */
79 elf_machine_relplt (l, reloc, &symtab[ELF32_R_SYM (reloc->r_info)], resolve);
81 return *(Elf32_Addr *) (l->l_addr + reloc->r_offset);
85 /* This macro is defined in dl-machine.h to define the entry point called
86 by the PLT. The `fixup' function above does the real work, but a little
87 more twiddling is needed to get the stack right and jump to the address
90 ELF_MACHINE_RUNTIME_TRAMPOLINE