diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/i386/dl-machine.h | 196 |
1 files changed, 97 insertions, 99 deletions
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 7a61aaad4c..dc88b043ea 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -17,12 +17,12 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef dl_machine_h +#define dl_machine_h + #define ELF_MACHINE_NAME "i386" #include <assert.h> -#include <string.h> -#include <link.h> - /* Return nonzero iff E_MACHINE is compatible with the running host. */ static inline int @@ -68,102 +68,6 @@ elf_machine_load_address (void) ++(const Elf32_Rel *) (dynamic_info)[DT_REL]->d_un.d_ptr; \ (dynamic_info)[DT_RELSZ]->d_un.d_val -= sizeof (Elf32_Rel); -/* Perform the relocation specified by RELOC and SYM (which is fully resolved). - MAP is the object containing the reloc. */ - -static inline void -elf_machine_rel (struct link_map *map, - const Elf32_Rel *reloc, const Elf32_Sym *sym, - Elf32_Addr (*resolve) (const Elf32_Sym **ref, - Elf32_Addr reloc_addr, - int noplt)) -{ - Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset); - Elf32_Addr loadbase; - -#ifdef RTLD_BOOTSTRAP -#define RESOLVE(noplt) map->l_addr -#else -#define RESOLVE(noplt) (*resolve) (&sym, (Elf32_Addr) reloc_addr, noplt) -#endif - - switch (ELF32_R_TYPE (reloc->r_info)) - { - case R_386_COPY: - loadbase = RESOLVE (0); - memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size); - break; - case R_386_GLOB_DAT: - loadbase = RESOLVE (0); - *reloc_addr = sym ? (loadbase + sym->st_value) : 0; - break; - case R_386_JMP_SLOT: - loadbase = RESOLVE (1); - *reloc_addr = sym ? (loadbase + sym->st_value) : 0; - break; - case R_386_32: - { - Elf32_Addr undo = 0; -#ifndef RTLD_BOOTSTRAP - /* This is defined in rtld.c, but nowhere in the static libc.a; - make the reference weak so static programs can still link. This - declaration cannot be done when compiling rtld.c (i.e. #ifdef - RTLD_BOOTSTRAP) because rtld.c contains the common defn for - _dl_rtld_map, which is incompatible with a weak decl in the same - file. */ - weak_extern (_dl_rtld_map); - if (map == &_dl_rtld_map) - /* Undo the relocation done here during bootstrapping. Now we will - relocate it anew, possibly using a binding found in the user - program or a loaded library rather than the dynamic linker's - built-in definitions used while loading those libraries. */ - undo = map->l_addr + sym->st_value; -#endif - loadbase = RESOLVE (0); - *reloc_addr += (sym ? (loadbase + sym->st_value) : 0) - undo; - break; - } - case R_386_RELATIVE: - if (!resolve || map != &_dl_rtld_map) /* Already done in rtld itself. */ - *reloc_addr += map->l_addr; - break; - case R_386_PC32: - loadbase = RESOLVE (0); - *reloc_addr += ((sym ? (loadbase + sym->st_value) : 0) - - (Elf32_Addr) reloc_addr); - break; - case R_386_NONE: /* Alright, Wilbur. */ - break; - default: - assert (! "unexpected dynamic reloc type"); - break; - } - -#undef RESOLVE -} - -static inline void -elf_machine_lazy_rel (struct link_map *map, const Elf32_Rel *reloc) -{ - Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset); - switch (ELF32_R_TYPE (reloc->r_info)) - { - case R_386_JMP_SLOT: - *reloc_addr += map->l_addr; - break; - default: - assert (! "unexpected PLT reloc type"); - break; - } -} - -/* Nonzero iff TYPE describes relocation of a PLT entry, so - PLT entries should not be allowed to define the value. */ -#define elf_machine_pltrel_p(type) ((type) == R_386_JMP_SLOT) - -/* The i386 never uses Elf32_Rela relocations. */ -#define ELF_MACHINE_NO_RELA 1 - /* Set up the loaded object described by L so its unrelocated PLT entries will jump to the on-demand fixup code in dl-runtime.c. */ @@ -264,3 +168,97 @@ _dl_start_user:\n\ # Jump to the user's entry point.\n\ jmp *%edi\n\ "); + +/* Nonzero iff TYPE describes relocation of a PLT entry, so + PLT entries should not be allowed to define the value. */ +#define elf_machine_pltrel_p(type) ((type) == R_386_JMP_SLOT) + +/* The i386 never uses Elf32_Rela relocations. */ +#define ELF_MACHINE_NO_RELA 1 + +#endif /* !dl_machine_h */ + +#ifdef RESOLVE + +/* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +static inline void +elf_machine_rel (struct link_map *map, + const Elf32_Rel *reloc, const Elf32_Sym *sym) +{ + Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset); + Elf32_Addr loadbase; + + switch (ELF32_R_TYPE (reloc->r_info)) + { + case R_386_COPY: + loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size); + break; + case R_386_GLOB_DAT: + loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + *reloc_addr = sym ? (loadbase + sym->st_value) : 0; + break; + case R_386_JMP_SLOT: + loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 1); + *reloc_addr = sym ? (loadbase + sym->st_value) : 0; + break; + case R_386_32: + { + Elf32_Addr undo = 0; +#ifndef RTLD_BOOTSTRAP + /* This is defined in rtld.c, but nowhere in the static libc.a; + make the reference weak so static programs can still link. This + declaration cannot be done when compiling rtld.c (i.e. #ifdef + RTLD_BOOTSTRAP) because rtld.c contains the common defn for + _dl_rtld_map, which is incompatible with a weak decl in the same + file. */ + weak_extern (_dl_rtld_map); + if (map == &_dl_rtld_map) + /* Undo the relocation done here during bootstrapping. Now we will + relocate it anew, possibly using a binding found in the user + program or a loaded library rather than the dynamic linker's + built-in definitions used while loading those libraries. */ + undo = map->l_addr + sym->st_value; +#endif + loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + *reloc_addr += (sym ? (loadbase + sym->st_value) : 0) - undo; + break; + } + case R_386_RELATIVE: +#ifndef RTLD_BOOTSTRAP + if (map != &_dl_rtld_map) /* Already done in rtld itself. */ +#endif + *reloc_addr += map->l_addr; + break; + case R_386_PC32: + loadbase = RESOLVE (&sym, (Elf32_Addr) reloc_addr, 0); + *reloc_addr += ((sym ? (loadbase + sym->st_value) : 0) - + (Elf32_Addr) reloc_addr); + break; + case R_386_NONE: /* Alright, Wilbur. */ + break; + default: + assert (! "unexpected dynamic reloc type"); + break; + } + +} + +static inline void +elf_machine_lazy_rel (struct link_map *map, const Elf32_Rel *reloc) +{ + Elf32_Addr *const reloc_addr = (void *) (map->l_addr + reloc->r_offset); + switch (ELF32_R_TYPE (reloc->r_info)) + { + case R_386_JMP_SLOT: + *reloc_addr += map->l_addr; + break; + default: + assert (! "unexpected PLT reloc type"); + break; + } +} + +#endif /* RESOLVE */ |