mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-25 14:30:06 +00:00
* elf/dl-reloc.c: Include "dynamic-link.h" at file scope.
* elf/rtld.c: Include <string.h>. * elf/dynamic-link.h (ELF_DYNAMIC_DO_REL, ELF_DYNAMIC_DO_RELA, ELF_DYNAMIC_RELOCATE): No longer take RESOLVE argument. Conditionalize defns on [RESOLVE]. * elf/do-rel.h (elf_dynamic_do_rel): Likewise. * sysdeps/i386/dl-machine.h (elf_machine_rel): Likewise. Instead use RESOLVE macro with same args. (elf_machine_rel): Conditionalize defn on [RESOLVE]. * elf/dl-reloc.c (RESOLVE): New macro, define before including "dynamic-link.h". It replaces `resolve' local function. * elf/dl-runtime.c: Likewise. * elf/rtld.c: Likewise.
This commit is contained in:
parent
c928de7902
commit
f51d1dfd35
16
ChangeLog
16
ChangeLog
@ -1,5 +1,21 @@
|
||||
Sun Jul 14 01:51:39 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
|
||||
|
||||
* elf/dl-reloc.c: Include "dynamic-link.h" at file scope.
|
||||
|
||||
* elf/rtld.c: Include <string.h>.
|
||||
|
||||
* elf/dynamic-link.h (ELF_DYNAMIC_DO_REL, ELF_DYNAMIC_DO_RELA,
|
||||
ELF_DYNAMIC_RELOCATE): No longer take RESOLVE argument.
|
||||
Conditionalize defns on [RESOLVE].
|
||||
* elf/do-rel.h (elf_dynamic_do_rel): Likewise.
|
||||
* sysdeps/i386/dl-machine.h (elf_machine_rel): Likewise.
|
||||
Instead use RESOLVE macro with same args.
|
||||
(elf_machine_rel): Conditionalize defn on [RESOLVE].
|
||||
* elf/dl-reloc.c (RESOLVE): New macro, define before including
|
||||
"dynamic-link.h". It replaces `resolve' local function.
|
||||
* elf/dl-runtime.c: Likewise.
|
||||
* elf/rtld.c: Likewise.
|
||||
|
||||
* elf/dl-deps.c (_dl_map_object_deps): Start TAILP at last preload.
|
||||
|
||||
* elf/dl-open.c (_dl_open): Force an indirect call for
|
||||
|
@ -24,7 +24,6 @@ Cambridge, MA 02139, USA. */
|
||||
#include <errno.h>
|
||||
#include "dynamic-link.h"
|
||||
|
||||
|
||||
void
|
||||
_dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy)
|
||||
{
|
||||
@ -56,15 +55,14 @@ _dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy)
|
||||
|
||||
const char *strtab /* String table object symbols. */
|
||||
= ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
|
||||
ElfW(Addr) resolve (const ElfW(Sym) **ref,
|
||||
ElfW(Addr) reloc_addr, int noplt)
|
||||
{
|
||||
/* Look up the referenced symbol in the specified scope. */
|
||||
return _dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope,
|
||||
l->l_name, reloc_addr, noplt);
|
||||
}
|
||||
|
||||
ELF_DYNAMIC_RELOCATE (l, lazy, resolve);
|
||||
/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */
|
||||
#define RESOLVE(ref, reloc_addr, noplt) \
|
||||
(_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \
|
||||
l->l_name, reloc_addr, noplt))
|
||||
|
||||
#include "dynamic-link.h"
|
||||
ELF_DYNAMIC_RELOCATE (l, lazy);
|
||||
}
|
||||
|
||||
/* Set up the PLT so its unrelocated entries will jump to
|
||||
|
@ -18,7 +18,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <link.h>
|
||||
#include "dynamic-link.h"
|
||||
|
||||
|
||||
/* The global scope we will use for symbol lookups.
|
||||
@ -68,6 +67,8 @@ _dl_object_relocation_scope (struct link_map *l)
|
||||
}
|
||||
}
|
||||
|
||||
#include "dynamic-link.h"
|
||||
|
||||
/* Figure out the right type, Rel or Rela. */
|
||||
#define elf_machine_rel 1
|
||||
#define elf_machine_rela 2
|
||||
@ -118,14 +119,16 @@ fixup (
|
||||
/* Set up the scope to find symbols referenced by this object. */
|
||||
struct link_map **scope = _dl_object_relocation_scope (l);
|
||||
|
||||
/* Perform the specified relocation. */
|
||||
ElfW(Addr) resolve (const ElfW(Sym) **ref,
|
||||
ElfW(Addr) reloc_addr, int noplt)
|
||||
{
|
||||
return _dl_lookup_symbol (strtab + (*ref)->st_name, ref,
|
||||
scope, l->l_name, reloc_addr, noplt);
|
||||
}
|
||||
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)], resolve);
|
||||
{
|
||||
/* This macro is used as a callback from the elf_machine_relplt code. */
|
||||
#define RESOLVE(ref, reloc_addr, noplt) \
|
||||
(_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \
|
||||
l->l_name, reloc_addr, noplt))
|
||||
#include "dynamic-link.h"
|
||||
|
||||
/* Perform the specified relocation. */
|
||||
elf_machine_relplt (l, reloc, &symtab[ELFW(R_SYM) (reloc->r_info)]);
|
||||
}
|
||||
|
||||
*_dl_global_scope_end = NULL;
|
||||
|
||||
|
12
elf/do-rel.h
12
elf/do-rel.h
@ -28,17 +28,13 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
/* Perform the relocations in MAP on the running program image as specified
|
||||
by RELTAG, SZTAG. *RESOLVE is called to resolve symbol values; it
|
||||
modifies its argument pointer to point to the defining symbol, and
|
||||
returns the base load address of the defining object. If LAZY is
|
||||
nonzero, this is the first pass on PLT relocations; they should be set
|
||||
up to call _dl_runtime_resolve, rather than fully resolved now. */
|
||||
by RELTAG, SZTAG. If LAZY is nonzero, this is the first pass on PLT
|
||||
relocations; they should be set up to call _dl_runtime_resolve, rather
|
||||
than fully resolved now. */
|
||||
|
||||
static inline void
|
||||
elf_dynamic_do_rel (struct link_map *map,
|
||||
int reltag, int sztag,
|
||||
ElfW(Addr) (*resolve) (const ElfW(Sym) **symbol,
|
||||
ElfW(Addr) reloc_addr, int noplt),
|
||||
int lazy)
|
||||
{
|
||||
const ElfW(Sym) *const symtab
|
||||
@ -53,7 +49,7 @@ elf_dynamic_do_rel (struct link_map *map,
|
||||
elf_machine_lazy_rel (map, r);
|
||||
else
|
||||
for (; r < end; ++r)
|
||||
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], resolve);
|
||||
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)]);
|
||||
}
|
||||
|
||||
#undef elf_dynamic_do_rel
|
||||
|
@ -56,6 +56,8 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Dyn) *info[DT_NUM + DT_PROCNUM])
|
||||
info[DT_PLTREL]->d_un.d_val == DT_RELA);
|
||||
}
|
||||
|
||||
#ifdef RESOLVE
|
||||
|
||||
/* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.
|
||||
These functions are almost identical, so we use cpp magic to avoid
|
||||
duplicating their code. It cannot be done in a more general function
|
||||
@ -63,31 +65,33 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn, ElfW(Dyn) *info[DT_NUM + DT_PROCNUM])
|
||||
|
||||
#if ! ELF_MACHINE_NO_REL
|
||||
#include "do-rel.h"
|
||||
#define ELF_DYNAMIC_DO_REL(map, lazy, resolve) \
|
||||
#define ELF_DYNAMIC_DO_REL(map, lazy) \
|
||||
if ((map)->l_info[DT_REL]) \
|
||||
elf_dynamic_do_rel ((map), DT_REL, DT_RELSZ, (resolve), 0); \
|
||||
elf_dynamic_do_rel ((map), DT_REL, DT_RELSZ, 0); \
|
||||
if ((map)->l_info[DT_PLTREL] && \
|
||||
(map)->l_info[DT_PLTREL]->d_un.d_val == DT_REL) \
|
||||
elf_dynamic_do_rel ((map), DT_JMPREL, DT_PLTRELSZ, (resolve), (lazy));
|
||||
elf_dynamic_do_rel ((map), DT_JMPREL, DT_PLTRELSZ, (lazy));
|
||||
#else
|
||||
#define ELF_DYNAMIC_DO_REL(map, lazy, resolve) /* Nothing to do. */
|
||||
#define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do. */
|
||||
#endif
|
||||
|
||||
#if ! ELF_MACHINE_NO_RELA
|
||||
#define DO_RELA
|
||||
#include "do-rel.h"
|
||||
#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) \
|
||||
#define ELF_DYNAMIC_DO_RELA(map, lazy) \
|
||||
if ((map)->l_info[DT_RELA]) \
|
||||
elf_dynamic_do_rela ((map), DT_RELA, DT_RELASZ, (resolve), 0); \
|
||||
elf_dynamic_do_rela ((map), DT_RELA, DT_RELASZ, 0); \
|
||||
if ((map)->l_info[DT_PLTREL] && \
|
||||
(map)->l_info[DT_PLTREL]->d_un.d_val == DT_RELA) \
|
||||
elf_dynamic_do_rela ((map), DT_JMPREL, DT_PLTRELSZ, (resolve), (lazy));
|
||||
elf_dynamic_do_rela ((map), DT_JMPREL, DT_PLTRELSZ, (lazy));
|
||||
#else
|
||||
#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* Nothing to do. */
|
||||
#define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do. */
|
||||
#endif
|
||||
|
||||
/* This can't just be an inline function because GCC is too dumb
|
||||
to inline functions containing inlines themselves. */
|
||||
#define ELF_DYNAMIC_RELOCATE(map, lazy, resolve) \
|
||||
do { ELF_DYNAMIC_DO_REL ((map), (lazy), (resolve)); \
|
||||
ELF_DYNAMIC_DO_RELA ((map), (lazy), (resolve)); } while (0)
|
||||
#define ELF_DYNAMIC_RELOCATE(map, lazy) \
|
||||
do { ELF_DYNAMIC_DO_REL ((map), (lazy)); \
|
||||
ELF_DYNAMIC_DO_RELA ((map), (lazy)); } while (0)
|
||||
|
||||
#endif
|
||||
|
@ -20,6 +20,7 @@ Cambridge, MA 02139, USA. */
|
||||
#include <link.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h> /* Check if MAP_ANON is defined. */
|
||||
#include "../stdio-common/_itoa.h"
|
||||
@ -28,6 +29,7 @@ Cambridge, MA 02139, USA. */
|
||||
/* This #define produces dynamic linking inline functions for
|
||||
bootstrap relocation instead of general-purpose relocation. */
|
||||
#define RTLD_BOOTSTRAP
|
||||
#define RESOLVE(sym, reloc_addr, noplt) 0
|
||||
#include "dynamic-link.h"
|
||||
|
||||
|
||||
@ -79,7 +81,7 @@ _dl_start (void *arg)
|
||||
/* Relocate ourselves so we can do normal function calls and
|
||||
data access using the global offset table. */
|
||||
|
||||
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, NULL);
|
||||
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0);
|
||||
|
||||
|
||||
/* Now life is sane; we can call functions and access global data.
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user