about summary refs log tree commit diff
path: root/elf/dynamic-link.h
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dynamic-link.h')
-rw-r--r--elf/dynamic-link.h105
1 files changed, 34 insertions, 71 deletions
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 1c3af29d6a..fc5c585356 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -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 (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
-			     const Elf32_Rel *reloc, 
-			     Elf32_Addr sym_loadaddr, const Elf32_Sym *sym);
-static void elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
-			      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,60 +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 DYNAMIC 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 (Elf32_Dyn *dynamic[DT_NUM], Elf32_Addr loadaddr,
-		      int lazy, Elf32_Addr (*resolve) (const Elf32_Sym **))
-{
-  const Elf32_Sym *const symtab
-    = (const Elf32_Sym *) dynamic[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 *) dynamic[reltag]->d_un.d_ptr;
-      const Elf32_Rel *end = &r[dynamic[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 (loadaddr, dynamic, 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 *) dynamic[reltag]->d_un.d_ptr;
-      const Elf32_Rela *end = &r[dynamic[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 (loadaddr, dynamic, r, loadbase, definer);
-	  ++r;
-	}
-    }
-
-  if (dynamic[DT_RELA])
-    do_rela (DT_RELA, DT_RELASZ);
-  if (dynamic[DT_REL])
-    do_rel (DT_REL, DT_RELSZ);
-  if (dynamic[DT_JMPREL] && ! lazy)
-    /* Relocate the PLT right now.  */
-    (dynamic[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)