summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--elf/dl-reloc.c16
-rw-r--r--elf/dl-runtime.c21
-rw-r--r--elf/do-rel.h12
-rw-r--r--elf/dynamic-link.h26
-rw-r--r--elf/rtld.c4
-rw-r--r--sysdeps/i386/dl-machine.h196
7 files changed, 154 insertions, 137 deletions
diff --git a/ChangeLog b/ChangeLog
index 256151e35e..0a3946203c 100644
--- a/ChangeLog
+++ b/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
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index e6778e7de3..5adf0f6dac 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -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
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index cdacd756ef..2785592c44 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -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;
diff --git a/elf/do-rel.h b/elf/do-rel.h
index ebf2e84a64..25da59252f 100644
--- a/elf/do-rel.h
+++ b/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
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index b69cb3fd43..45b6b2dcde 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -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
diff --git a/elf/rtld.c b/elf/rtld.c
index 2e23d9cb38..1058d87150 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -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.
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 */