summaryrefslogtreecommitdiff
path: root/csu
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
parent0e1d99119e7851c112aefce64574506f8183e648 (diff)
Support static IFUNC calls irrespective of USE_MULTIARCH.
Diffstat (limited to 'csu')
-rw-r--r--csu/elf-init.c45
-rw-r--r--csu/libc-start.c38
2 files changed, 37 insertions, 46 deletions
diff --git a/csu/elf-init.c b/csu/elf-init.c
index 91ba74ce55..8b4431ba0c 100644
--- a/csu/elf-init.c
+++ b/csu/elf-init.c
@@ -1,6 +1,5 @@
/* Startup support for ELF initializers/finalizers in the main executable.
- Copyright (C) 2002,2003,2004,2005,2009,2011
- Free Software Foundation, Inc.
+ Copyright (C) 2002-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
@@ -36,20 +35,6 @@
#include <stddef.h>
-#if defined USE_MULTIARCH && !defined LIBC_NONSHARED
-# include <link.h>
-# include <dl-irel.h>
-
-# ifdef ELF_MACHINE_IRELA
-extern const ElfW(Rela) __rela_iplt_start [];
-extern const ElfW(Rela) __rela_iplt_end [];
-# endif
-
-# ifdef ELF_MACHINE_IREL
-extern const ElfW(Rel) __rel_iplt_start [];
-extern const ElfW(Rel) __rel_iplt_end [];
-# endif
-#endif /* LIBC_NONSHARED */
/* These magic symbols are provided by the linker. */
extern void (*__preinit_array_start []) (int, char **, char **)
@@ -72,33 +57,7 @@ extern void _fini (void);
/* These functions are passed to __libc_start_main by the startup code.
These get statically linked into each program. For dynamically linked
programs, this module will come from libc_nonshared.a and differs from
- the libc.a module in that it doesn't call the preinit array and performs
- explicit IREL{,A} relocations. */
-
-
-#ifndef LIBC_NONSHARED
-void
-__libc_csu_irel (void)
-{
-# ifdef USE_MULTIARCH
-# ifdef ELF_MACHINE_IRELA
- {
- const size_t size = __rela_iplt_end - __rela_iplt_start;
- for (size_t i = 0; i < size; i++)
- elf_irela (&__rela_iplt_start [i]);
- }
-# endif
-
-# ifdef ELF_MACHINE_IREL
- {
- const size_t size = __rel_iplt_end - __rel_iplt_start;
- for (size_t i = 0; i < size; i++)
- elf_irel (&__rel_iplt_start [i]);
- }
-# endif
-# endif
-}
-#endif
+ the libc.a module in that it doesn't call the preinit array. */
void
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