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.
