diff options
| author | Christophe Lyon <christophe.lyon@st.com> | 2018-07-04 17:55:23 +0200 | 
|---|---|---|
| committer | Waldemar Brodkorb <wbrodkorb@conet.de> | 2018-08-10 16:02:23 +0200 | 
| commit | 99dfb1e26f784429e23f2e67eef5bbbc6e646b83 (patch) | |
| tree | 32a01b6e85cf0289648a7ad091dde8bc4a2e68a9 /libc | |
| parent | ae80d12e5f55ad491d1f1e6fe094bc291d908903 (diff) | |
Allow to generate PIE 'static' binary
	* 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>
Diffstat (limited to 'libc')
| -rw-r--r-- | libc/misc/internals/__uClibc_main.c | 45 | 
1 files changed, 45 insertions, 0 deletions
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index d80565e2c..d8286f20b 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  | 
