Merged to master at 433b282f05aa..23833dc15246 (from, to]

You can see the entire diff with 'git diff' or at
https://github.com/brho/akaros/compare/433b282f05aa...23833dc15246



On 2017-08-30 at 13:32 Barret Rhoden <[email protected]> wrote:
> Part 3 of trying to fix shared objects, following up on commit c77d5ade84b7
> ("parlib: Fix fake parlib detection for dlopen() (XCC)").
> 
> If we use -rdynamic, all symbols from the binary (e.g. hello.c) will
> override functions in the .so.  For instance, __in_fake_parlib() and
> vcore_lib_init() will be from the binary, not the .so, even when we're
> running the library's ctors.
> 
> The fix is relatively simple: __in_fake_parlib() is a static inline, which
> won't give the opportunity for the .so to link against a global version,
> since there is no global version.
> 
> For the ctors, we actually could leave vcore_lib_init() as a global ctor,
> since it can safely be called multiple times.  But that's a little sloppy
> and confusing - I wondered for a little while why vcore_lib_init() ran from
> hello, while uthread_lib_init() was run from within the .so.  static vs
> global.  We still need the guts vcore_lib_init() to be in a header for
> uthread.c, so the sanest thing was to just split it up.
> 
> Signed-off-by: Barret Rhoden <[email protected]>
> ---
>  user/parlib/alarm.c                |  2 +-
>  user/parlib/include/parlib/vcore.h | 20 ++++++++++++++++++-
>  user/parlib/panic.c                |  2 +-
>  user/parlib/uthread.c              |  4 ++--
>  user/parlib/vcore.c                | 39 
> ++++++++++++++------------------------
>  user/parlib/vcore_tick.c           |  2 +-
>  6 files changed, 38 insertions(+), 31 deletions(-)
> 
> diff --git a/user/parlib/alarm.c b/user/parlib/alarm.c
> index 54eaad4c819d..b11accdb0de6 100644
> --- a/user/parlib/alarm.c
> +++ b/user/parlib/alarm.c
> @@ -147,7 +147,7 @@ static void devalarm_forked(void)
>       global_tchain.timerfd = -42;
>  }
>  
> -static void __attribute__((constructor)) init_alarm_service(void)
> +static void __attribute__((constructor)) alarm_service_ctor(void)
>  {
>       int ctlfd, timerfd, alarmid;
>       struct event_queue *ev_q;
> diff --git a/user/parlib/include/parlib/vcore.h 
> b/user/parlib/include/parlib/vcore.h
> index 6e8f2efe53c0..242902e8c76c 100644
> --- a/user/parlib/include/parlib/vcore.h
> +++ b/user/parlib/include/parlib/vcore.h
> @@ -40,8 +40,9 @@ static inline void set_vcpd_tls_desc(uint32_t vcoreid, void 
> *tls_desc);
>  static inline uint64_t vcore_account_resume_nsec(uint32_t vcoreid);
>  static inline uint64_t vcore_account_total_nsec(uint32_t vcoreid);
>  static inline void cpu_relax_any(void);
> +static inline bool __in_fake_parlib(void);
> +
>  void vcore_lib_init(void);
> -bool __in_fake_parlib(void);
>  void vcore_change_to_m(void);
>  void vcore_request_more(long nr_new_vcores);
>  void vcore_request_total(long nr_vcores_wanted);
> @@ -193,6 +194,23 @@ static inline void cpu_relax_any(void)
>       return cpu_relax_vc(vcore_id());
>  }
>  
> +/* Shared libraries also contain parlib.  That'll be true until we start 
> making
> + * parlib a .so, which has some TLS implications (and maybe others).  The 
> real
> + * parlib is the one in the program binary, not the shared libraries.  This
> + * detection works because all shared libs, both the -l and the dlopens, are
> + * mapped above the BRK.
> + *
> + * Previously, we tried using weak symbols, specifically _start or _end, but 
> be
> + * careful.  If you pass e.g. _start or _end to a function or inline asm, the
> + * program binary will do something slightly different, which may make the
> + * shared library load different values. */
> +static inline bool __in_fake_parlib(void)
> +{
> +     static char dummy;
> +
> +     return (uintptr_t)&dummy > BRK_START;
> +}
> +
>  #ifndef __PIC__
>  
>  #define begin_safe_access_tls_vars()
> diff --git a/user/parlib/panic.c b/user/parlib/panic.c
> index dc796f5edeac..44e992e5b17d 100644
> --- a/user/parlib/panic.c
> +++ b/user/parlib/panic.c
> @@ -5,7 +5,7 @@
>  #include <stdarg.h>
>  #include <stdlib.h>
>  
> -static void __attribute__((constructor)) parlib_stdio_init(void)
> +static void __attribute__((constructor)) parlib_stdio_ctor(void)
>  {
>       if (__in_fake_parlib())
>               return;
> diff --git a/user/parlib/uthread.c b/user/parlib/uthread.c
> index 5f5ec9e9647e..85f7ea01221e 100644
> --- a/user/parlib/uthread.c
> +++ b/user/parlib/uthread.c
> @@ -159,13 +159,13 @@ static char *__ros_errstr_loc(void)
>               return current_uthread->err_str;
>  }
>  
> -static void __attribute__((constructor)) uthread_lib_init(void)
> +static void __attribute__((constructor)) uthread_lib_ctor(void)
>  {
>       /* Surprise!  Parlib's ctors also run in shared objects.  We can't have
>        * multiple versions of parlib (with multiple data structures). */
>       if (__in_fake_parlib())
>               return;
> -     /* Need to make sure the vcore_lib_init() ctor runs first */
> +     /* Need to make sure vcore_lib_init() runs first */
>       vcore_lib_init();
>       /* Instead of relying on ctors for the specific 2LS, we make sure they 
> are
>        * called next.  They will call uthread_2ls_init().
> diff --git a/user/parlib/vcore.c b/user/parlib/vcore.c
> index 3a29c65869c0..32c89e3ecff2 100644
> --- a/user/parlib/vcore.c
> +++ b/user/parlib/vcore.c
> @@ -37,28 +37,6 @@ void __attribute__((noreturn)) __vcore_entry(void)
>  }
>  void vcore_entry(void) __attribute__((weak, alias ("__vcore_entry")));
>  
> -static void __fake_start(void)
> -{
> -}
> -void _start(void) __attribute__((weak, alias ("__fake_start")));
> -
> -/* Shared libraries also contain parlib.  That'll be true until we start 
> making
> - * parlib a .so, which has some TLS implications (and maybe others).  The 
> real
> - * parlib is the one in the program binary, not the shared libraries.  This
> - * detection works because all shared libs, both the -l and the dlopens, are
> - * mapped above the BRK.
> - *
> - * Previously, we tried using weak symbols, specifically _start or _end, but 
> be
> - * careful.  If you pass e.g. _start or _end to a function or inline asm, the
> - * program binary will do something slightly different, which may make the
> - * shared library load different values. */
> -bool __in_fake_parlib(void)
> -{
> -     static char dummy;
> -
> -     return (uintptr_t)&dummy > BRK_START;
> -}
> -
>  /* TODO: probably don't want to dealloc.  Considering caching */
>  static void free_transition_tls(int id)
>  {
> @@ -192,10 +170,14 @@ static void vcore_libc_init(void)
>        * program. */
>  }
>  
> -void __attribute__((constructor)) vcore_lib_init(void)
> +/* We need to separate the guts of vcore_lib_ctor() into a separate function,
> + * since the uthread ctor depends on this ctor running first.
> + *
> + * Also note that if you make a global ctor (not static, like this used to 
> be),
> + * any shared objects that you load when the binary is built with -rdynamic 
> will
> + * run the global ctor from the binary, not the one from the .so. */
> +void vcore_lib_init(void)
>  {
> -     if (__in_fake_parlib())
> -             return;
>       /* Note this is racy, but okay.  The first time through, we are _S.
>        * Also, this is the "lowest" level constructor for now, so we don't 
> need
>        * to call any other init functions after our run_once() call. This may
> @@ -209,6 +191,13 @@ void __attribute__((constructor)) vcore_lib_init(void)
>       vcore_libc_init();
>  }
>  
> +static void __attribute__((constructor)) vcore_lib_ctor(void)
> +{
> +     if (__in_fake_parlib())
> +             return;
> +     vcore_lib_init();
> +}
> +
>  /* Helper functions used to reenter at the top of a vcore's stack for an
>   * arbitrary function */
>  static void __attribute__((noinline, noreturn)) 
> diff --git a/user/parlib/vcore_tick.c b/user/parlib/vcore_tick.c
> index fcd9e1d3e029..7df2e5f911eb 100644
> --- a/user/parlib/vcore_tick.c
> +++ b/user/parlib/vcore_tick.c
> @@ -33,7 +33,7 @@ struct vcore_tick {
>  
>  static struct vcore_tick *__vc_ticks;
>  
> -static void __attribute__((constructor)) vcore_tick_lib_init(void)
> +static void __attribute__((constructor)) vcore_tick_lib_ctor(void)
>  {
>       if (__in_fake_parlib())
>               return;

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to