.
authorroland <roland>
Mon, 8 May 1995 09:10:24 +0000 (09:10 +0000)
committerroland <roland>
Mon, 8 May 1995 09:10:24 +0000 (09:10 +0000)
elf/dl-reloc.c
elf/do-rel.h [new file with mode: 0644]
elf/dynamic-link.h
elf/rtld.c

index 9315517..94ffb71 100644 (file)
@@ -76,7 +76,7 @@ _dl_relocate_object (struct link_map *l, int lazy)
     else
       scope = _dl_loaded;
 
-    elf_dynamic_relocate (l, lazy, resolve);
+    ELF_DYNAMIC_RELOCATE (l, lazy, resolve);
 
     /* Restore list frobnication done above for DT_SYMBOLIC.  */
     l->l_next = real_next;
diff --git a/elf/do-rel.h b/elf/do-rel.h
new file mode 100644 (file)
index 0000000..04643e8
--- /dev/null
@@ -0,0 +1,68 @@
+/* Do relocations for ELF dynamic linking.
+Copyright (C) 1995 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+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.  */
+
+/* This file may be included twice, to define both
+   `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.  */
+
+#ifdef DO_RELA
+#define elf_dynamic_do_rel     elf_dynamic_do_rela
+#define        Elf32_Rel               Elf32_Rela
+#define elf_machine_rel                elf_machine_rela
+#endif
+
+
+/* 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.  */
+
+static inline void
+elf_dynamic_do_rel (struct link_map *map,
+                   int reltag, int sztag, 
+                   Elf32_Addr (*resolve) (const Elf32_Sym **))
+{
+  const Elf32_Sym *const symtab
+    = (const Elf32_Sym *) map->l_info[DT_SYMTAB]->d_un.d_ptr;
+  const Elf32_Rel *r = (const Elf32_Rel *) map->l_info[reltag]->d_un.d_ptr;
+  const Elf32_Rel *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r];
+
+  for (; r < end; ++r)
+    {
+      const Elf32_Sym *definer = &symtab[ELF32_R_SYM (r->r_info)];
+      Elf32_Addr loadbase;
+
+      if (ELF32_R_SYM (r->r_info) == STN_UNDEF)
+       loadbase = 0;           /* This value will not be consulted.  */
+      else
+       {
+         if (resolve)
+           loadbase = (*resolve) (&definer);
+         else
+           {
+             assert (definer->st_shndx != SHN_UNDEF);
+             loadbase = map->l_addr;
+           }
+       }
+      elf_machine_rel (map, r, loadbase, definer);
+    }
+}
+
+#undef elf_dynamic_do_rel
+#undef Elf32_Rel
+#undef elf_machine_rel
index 5b4a502..fc5c585 100644 (file)
@@ -18,23 +18,10 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <elf.h>
-
-/* This machine-dependent file defines these inline functions.  */
-
-static void elf_machine_rel (struct link_map *map,
-                            const Elf32_Rel *reloc, 
-                            Elf32_Addr sym_loadaddr, const Elf32_Sym *sym);
-static void elf_machine_rela (struct link_map *map,
-                             const Elf32_Rela *reloc, 
-                             Elf32_Addr sym_loadaddr, const Elf32_Sym *sym);
-static Elf32_Addr *elf_machine_got (void);
-static Elf32_Addr elf_machine_load_address (void);
-
 #include <dl-machine.h>
-
-
 #include <assert.h>
 
+
 /* Read the dynamic section at DYN and fill in INFO with indices DT_*.  */
 
 static inline void
@@ -60,61 +47,36 @@ elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM])
            info[DT_PLTREL]->d_un.d_val == DT_RELA);
 }
 
-/* Perform the relocations specified by MAP on the running program
-   image.  If LAZY is nonzero, don't relocate PLT entries.  *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.  */
-
-static inline void
-elf_dynamic_relocate (struct link_map *map,
-                     int lazy, Elf32_Addr (*resolve) (const Elf32_Sym **))
-{
-  const Elf32_Sym *const symtab
-    = (const Elf32_Sym *) map->l_info[DT_SYMTAB]->d_un.d_ptr;
-
-  inline Elf32_Addr symvalue (Elf32_Word info, const Elf32_Sym **definer)
-    {
-      if (ELF32_R_SYM (info) == STN_UNDEF)
-       return 0;               /* This value will not be consulted.  */
-      *definer = &symtab[ELF32_R_SYM (info)];
-      return (*resolve) (definer);
-    }
-
-  /* Perform Elf32_Rel relocations in the section found by RELTAG, SZTAG.  */
-  inline void do_rel (Elf32_Word reltag, Elf32_Word sztag)
-    {
-      const Elf32_Rel *r = (const Elf32_Rel *) map->l_info[reltag]->d_un.d_ptr;
-      const Elf32_Rel *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r];
-      while (r < end)
-       {
-         const Elf32_Sym *definer;
-         Elf32_Addr loadbase = symvalue (r->r_info, &definer);
-         elf_machine_rel (map, r, loadbase, definer);
-         ++r;
-       }
-    }
-  /* Perform Elf32_Rela relocations in the section found by RELTAG, SZTAG.  */
-  inline void do_rela (Elf32_Word reltag, Elf32_Word sztag)
-    {
-      const Elf32_Rela *r
-       = (const Elf32_Rela *) map->l_info[reltag]->d_un.d_ptr;
-      const Elf32_Rela *end = &r[map->l_info[sztag]->d_un.d_val / sizeof *r];
-      while (r < end)
-       {
-         const Elf32_Sym *definer;
-         Elf32_Addr loadbase = symvalue (r->r_info, &definer);
-         elf_machine_rela (map, r, loadbase, definer);
-         ++r;
-       }
-    }
-
-  if (map->l_info[DT_RELA])
-    do_rela (DT_RELA, DT_RELASZ);
-  if (map->l_info[DT_REL])
-    do_rel (DT_REL, DT_RELSZ);
-  if (map->l_info[DT_JMPREL] && ! lazy)
-    /* Relocate the PLT right now.  */
-    (map->l_info[DT_PLTREL]->d_un.d_val == DT_REL ? do_rel : do_rela)
-      (DT_JMPREL, DT_PLTRELSZ);
-}
+/* 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
+   because we must be able to completely inline.  */
+
+#if ! ELF_MACHINE_NO_REL
+#include "do-rel.h"
+#define ELF_DYNAMIC_DO_REL(map, lazy, resolve)                               \
+  if ((map)->l_info[DT_REL])                                                 \
+    elf_dynamic_do_rel ((map), DT_REL, DT_RELSZ, (resolve));                 \
+  if (!(lazy) && (map)->l_info[DT_PLTREL]->d_un.d_val == DT_REL)             \
+    elf_dynamic_do_rel ((map), DT_JMPREL, DT_PLTRELSZ, (resolve));
+#else
+#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* Nothing to do.  */
+#endif
+
+#if ! ELF_MACHINE_NO_RELA
+#define DO_RELA
+#include "do-rel.h"
+#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve)                                      \
+  if ((map)->l_info[DT_RELA])                                                \
+    elf_dynamic_do_rela ((map), DT_RELA, DT_RELASZ, (resolve));                      \
+  if (!(lazy) && (map)->l_info[DT_PLTREL]->d_un.d_val == DT_RELA)            \
+    elf_dynamic_do_rela ((map), DT_JMPREL, DT_PLTRELSZ, (resolve);
+#else
+#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* 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)
index 2b7d369..0605336 100644 (file)
@@ -54,8 +54,6 @@ _dl_start (void *arg)
 {
   struct link_map rtld_map;
 
-  rtld_map.l_name = (char *) "<dynamic linker>";
-
   /* Figure out the run-time load address of the dynamic linker itself.  */
   rtld_map.l_addr = elf_machine_load_address ();
 
@@ -71,14 +69,9 @@ _dl_start (void *arg)
 
   /* Relocate ourselves so we can do normal function calls and
      data access using the global offset table.  */
-  {
-    Elf32_Addr resolve (const Elf32_Sym **ref)
-      {
-       assert ((*ref)->st_shndx != SHN_UNDEF);
-       return rtld_map.l_addr;
-      }
-    elf_dynamic_relocate (&rtld_map, 0, resolve);
-  }
+
+  ELF_DYNAMIC_RELOCATE (&rtld_map, 0, NULL);
+
 
   /* Now life is sane; we can call functions and access global data.
      Set up to use the operating system facilities, and find out from