summary refs log tree commit diff
path: root/include
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
parent2ce0481d26066b7d4e2c950da555a7ca20e313fb (diff)
downloadglibc-ae49f218daca0b7cab27764da4081e6509bc7345.tar.gz
glibc-ae49f218daca0b7cab27764da4081e6509bc7345.tar.xz
glibc-ae49f218daca0b7cab27764da4081e6509bc7345.zip
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')
-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 a60b5ae19f..1a2f6ad56b 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 */