Back to index

glibc  2.9
dl-machine.h
Go to the documentation of this file.
00001 /* Machine-dependent ELF dynamic relocation inline functions.  Stub version.
00002    Copyright (C) 1995, 1996, 1997, 1999, 2000, 2001, 2005
00003    Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #define ELF_MACHINE_NAME "stub"
00022 
00023 #include <string.h>
00024 #include <link.h>
00025 
00026 
00027 /* Return nonzero iff ELF header is compatible with the running host.  */
00028 static inline int
00029 elf_machine_matches_host (const Elf32_Ehdr *ehdr)
00030 {
00031   switch (ehdr->e_machine)
00032     {
00033     default:
00034       return 0;
00035     }
00036 }
00037 
00038 
00039 /* Return the link-time address of _DYNAMIC.  */
00040 static inline Elf32_Addr
00041 elf_machine_dynamic (void)
00042 {
00043 #error "Damn, no _DYNAMIC"
00044 }
00045 
00046 
00047 /* Return the run-time load address of the shared object.  */
00048 static inline Elf32_Addr
00049 elf_machine_load_address (void)
00050 {
00051 #error "Where am I?"
00052 }
00053 
00054 /* Fixup a PLT entry to bounce directly to the function at VALUE.  */
00055 
00056 static inline Elf32_Addr
00057 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
00058                      const Elf32_Rel *reloc,
00059                      Elf32_Addr *reloc_addr, Elf32_Addr value)
00060 {
00061   return *reloc_addr = value;
00062 }
00063 
00064 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
00065    LOADADDR is the load address of the object; INFO is an array indexed
00066    by DT_* of the .dynamic section info.  */
00067 
00068 auto inline void
00069 __attribute__ ((always_inline))
00070 elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
00071                const Elf32_Rel *reloc, const Elf32_Sym *sym,
00072                Elf32_Addr (*resolve) (const Elf32_Sym **ref,
00073                                    Elf32_Addr reloc_addr,
00074                                    int noplt))
00075 {
00076   Elf32_Addr *const reloc_addr = (Elf32_Addr *) reloc->r_offset;
00077   Elf32_Addr loadbase;
00078 
00079   switch (ELF32_R_TYPE (reloc->r_info))
00080     {
00081     case R_MACHINE_COPY:
00082       loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
00083       memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size);
00084       break;
00085     default:
00086       _dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 0);
00087       break;
00088     }
00089 }
00090 
00091 
00092 auto inline Elf32_Addr
00093 __attribute__ ((always_inline))
00094 elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
00095                 const Elf32_Rel *reloc, const Elf32_Sym *sym,
00096                 Elf32_Addr (*resolve) (const Elf32_Sym **ref,
00097                                     Elf32_Addr reloc_addr,
00098                                     int noplt))
00099 {
00100   _dl_signal_error (0, "Elf32_Rela relocation requested -- unused on "
00101                   NULL, ELF_MACHINE_NAME);
00102 }
00103 
00104 
00105 /* Set up the loaded object described by L so its unrelocated PLT
00106    entries will jump to the on-demand fixup code in dl-runtime.c.  */
00107 
00108 static inline int
00109 elf_machine_runtime_setup (struct link_map *l, int lazy)
00110 {
00111   extern void _dl_runtime_resolve (Elf32_Word);
00112 
00113   if (lazy)
00114     {
00115       /* The GOT entries for functions in the PLT have not yet been filled
00116          in.  Their initial contents will arrange when called to push an
00117          offset into the .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1],
00118          and then jump to _GLOBAL_OFFSET_TABLE[2].  */
00119       Elf32_Addr *got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
00120       got[1] = (Elf32_Addr) l;     /* Identify this shared object.  */
00121 
00122       /* This function will get called to fix up the GOT entry indicated by
00123          the offset on the stack, and then jump to the resolved address.  */
00124       got[2] = (Elf32_Addr) &_dl_runtime_resolve;
00125     }
00126 
00127   return lazy;
00128 }
00129 
00130 
00131 /* Initial entry point code for the dynamic linker.
00132    The C function `_dl_start' is the real entry point;
00133    its return value is the user program's entry point.  */
00134 
00135 #define RTLD_START #error need some startup code