diff mbox series

[uclibc-ng-devel,10/32,ARM,FDPIC] Allow to generate PIE 'static' binary

Message ID 20180704155605.1892-11-christophe.lyon@st.com
State Accepted
Headers show
Series FDPIC ABI for ARM | expand

Commit Message

Christophe Lyon July 4, 2018, 3:55 p.m. UTC
* libc/misc/internals/__uClibc_main.c (funcdesc_value): New.
	(fdpic_init_array_jump): New.
	(__uClibc_fini): Support __FDPIC__.
	(__uClibc_main): Likewise.

Signed-off-by: Mickaël Guêné <mickael.guene@st.com>
Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
diff mbox series

Patch

diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index d80565e..d8286f2 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -48,6 +48,39 @@ 
 int _pe_secure = 0;
 libc_hidden_data_def(_pe_secure)
 
+#if !defined(SHARED) && defined(__FDPIC__)
+struct funcdesc_value
+{
+	void *entry_point;
+	void *got_value;
+} __attribute__((__aligned__(8)));
+
+
+/* Prevent compiler optimization that removes GOT assignment.
+
+  Due to optimization passes (block split and move), in the rare case
+  where use r9 is the single instruction in a block we can have the
+  following behaviour:
+  - this block is marked as a forward block since use is not
+  considered as an active instruction after reload pass.
+
+  - In this case a jump in this block can be moved to the start of the
+  next one and so remove use in this flow of instructions which can
+  lead to a removal of r9 restoration after a call. */
+#define _dl_stabilize_funcdesc(val)			\
+	({ __asm__ ("" : "+m" (*(val))); (val); })
+
+static void fdpic_init_array_jump(void *addr)
+{
+	struct funcdesc_value *fm = (struct funcdesc_value *) fdpic_init_array_jump;
+	struct funcdesc_value fd = {addr, fm->got_value};
+
+	void (*pf)(void) = (void*) _dl_stabilize_funcdesc(&fd);
+
+	(*pf)();
+}
+#endif
+
 #ifndef SHARED
 void *__libc_stack_end = NULL;
 
@@ -307,7 +340,11 @@  void __uClibc_fini(void)
 # elif !defined (__UCLIBC_FORMAT_SHARED_FLAT__)
     size_t i = __fini_array_end - __fini_array_start;
     while (i-- > 0)
+#if !defined(SHARED) && defined(__FDPIC__)
+	fdpic_init_array_jump(__fini_array_start[i]);
+#else
 	(*__fini_array_start [i]) ();
+#endif
 # endif
     if (__app_fini != NULL)
 	(__app_fini)();
@@ -436,7 +473,11 @@  void __uClibc_main(int (*main)(int, char **, char **), int argc,
 	const size_t size = __preinit_array_end - __preinit_array_start;
 	size_t i;
 	for (i = 0; i < size; i++)
+#if !defined(SHARED) && defined(__FDPIC__)
+	    fdpic_init_array_jump(__preinit_array_start[i]);
+#else
 	    (*__preinit_array_start [i]) ();
+#endif
     }
 # endif
     /* Run all the application's ctors now.  */
@@ -452,7 +493,11 @@  void __uClibc_main(int (*main)(int, char **, char **), int argc,
 	const size_t size = __init_array_end - __init_array_start;
 	size_t i;
 	for (i = 0; i < size; i++)
+#if !defined(SHARED) && defined(__FDPIC__)
+	    fdpic_init_array_jump(__init_array_start[i]);
+#else
 	    (*__init_array_start [i]) ();
+#endif
     }
 # endif
 #endif