aboutsummaryrefslogtreecommitdiff
path: root/include/set-hooks.h
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2021-12-28 10:27:06 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2021-12-28 10:28:22 +0100
commitae49f218daca0b7cab27764da4081e6509bc7345 (patch)
treefef5fa1b87b9bc540c84690c3128c252651f6f34 /include/set-hooks.h
parent2ce0481d26066b7d4e2c950da555a7ca20e313fb (diff)
downloadglibc-ae49f218daca0b7cab27764da4081e6509bc7345.zip
glibc-ae49f218daca0b7cab27764da4081e6509bc7345.tar.gz
glibc-ae49f218daca0b7cab27764da4081e6509bc7345.tar.bz2
hurd: Fix static-PIE startup
hurd initialization stages use RUN_HOOK to run various initialization functions. That is however using absolute addresses which need to be relocated, which is done later by csu. We can however easily make the linker compute relative addresses which thus don't need a relocation. The new SET_RELHOOK and RUN_RELHOOK macros implement this.
Diffstat (limited to 'include/set-hooks.h')
-rw-r--r--include/set-hooks.h25
1 files changed, 25 insertions, 0 deletions
diff --git a/include/set-hooks.h b/include/set-hooks.h
index a60b5ae..1a2f6ad 100644
--- a/include/set-hooks.h
+++ b/include/set-hooks.h
@@ -24,6 +24,8 @@
#include <sys/cdefs.h>
#include <libc-symbols.h>
+#include "set-hooks-arch.h"
+
#ifdef symbol_set_define
/* Define a hook variable called NAME. Functions put on this hook take
arguments described by PROTO. Use `text_set_element (NAME, FUNCTION)'
@@ -55,6 +57,25 @@ do { \
DEFINE_HOOK (name, proto); \
extern void runner proto; void runner proto { RUN_HOOK (name, args); }
+# ifdef SET_RELHOOK
+/* This is similar to RUN_RELHOOK, but the hooks were registered with
+ * SET_RELHOOK so that a relative offset was computed by the linker
+ * rather than an absolute address by the dynamic linker. */
+# define RUN_RELHOOK(NAME, ARGS) \
+do { \
+ void *const *ptr; \
+ for (ptr = (void *const *) symbol_set_first_element (NAME); \
+ ! symbol_set_end_p (NAME, ptr); ++ptr) { \
+ __##NAME##_hook_function_t *f = \
+ (void*) ((uintptr_t) ptr + (ptrdiff_t) *ptr); \
+ (*f) ARGS; \
+ } \
+} while (0)
+# else
+# define SET_RELHOOK(NAME, HOOK) text_set_element (NAME, HOOK)
+# define RUN_RELHOOK(NAME, ARGS) RUN_HOOK(NAME, ARGS)
+# endif
+
#else
/* The system does not provide necessary support for this. */
@@ -66,6 +87,10 @@ extern void runner proto; void runner proto { RUN_HOOK (name, args); }
# define DEFINE_HOOK_RUNNER(name, runner, proto, args)
+# define SET_RELHOOK(NAME, HOOK)
+
+# define RUN_RELHOOK(NAME, ARGS)
+
#endif
#endif /* set-hooks.h */