about summary refs log tree commit diff
path: root/csu/libc-start.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@hack.frob.com>2012-08-21 15:01:27 -0700
committerRoland McGrath <roland@hack.frob.com>2012-08-21 15:01:27 -0700
commit21ad055803de5dd03606588753c46fbf8a5863b2 (patch)
treecb9f135af9ffea2cb34ffd07f5d77daba060e141 /csu/libc-start.c
parent0e1d99119e7851c112aefce64574506f8183e648 (diff)
downloadglibc-21ad055803de5dd03606588753c46fbf8a5863b2.tar.gz
glibc-21ad055803de5dd03606588753c46fbf8a5863b2.tar.xz
glibc-21ad055803de5dd03606588753c46fbf8a5863b2.zip
Support static IFUNC calls irrespective of USE_MULTIARCH.
Diffstat (limited to 'csu/libc-start.c')
-rw-r--r--csu/libc-start.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 0f9bfd7fc5..7e541d4f79 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998-2006, 2007, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 1998-2012 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
@@ -46,6 +46,38 @@ uintptr_t __stack_chk_guard attribute_relro;
 #endif
 
 
+#ifndef SHARED
+# include <link.h>
+# include <dl-irel.h>
+
+# ifdef ELF_MACHINE_IRELA
+#  define IREL_T	ElfW(Rela)
+#  define IPLT_START	__rela_iplt_start
+#  define IPLT_END	__rela_iplt_end
+#  define IREL		elf_irela
+# elif defined ELF_MACHINE_IREL
+#  define IREL_T	ElfW(Rel)
+#  define IPLT_START	__rel_iplt_start
+#  define IPLT_END	__rel_iplt_end
+#  define IREL		elf_irel
+# endif
+
+/* We use weak references for these so that we'll still work with a linker
+   that doesn't define them.  Such a linker doesn't support IFUNC at all
+   and so uses won't work, but a statically-linked program that doesn't
+   use any IFUNC symbols won't have a problem.  */
+extern const IREL_T IPLT_START[] __attribute__ ((weak));
+extern const IREL_T IPLT_END[] __attribute__ ((weak));
+
+static void
+apply_irel (void)
+{
+  for (const IREL_T *ipltent = IPLT_START; ipltent < IPLT_END; ++ipltent)
+    IREL (ipltent);
+}
+#endif
+
+
 #ifdef LIBC_START_MAIN
 # ifdef LIBC_START_DISABLE_INLINE
 #  define STATIC static
@@ -136,8 +168,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
     }
 # endif
 
-  /* Performe IREL{,A} relocations.  */
-  __libc_csu_irel ();
+  /* Perform IREL{,A} relocations.  */
+  apply_irel ();
 
   /* Initialize the thread library at least a bit since the libgcc
      functions are using thread functions if these are available and