Message ID | 20220621203225.714328-2-adhemerval.zanella@linaro.org |
---|---|
State | New |
Headers | show |
Series | Simplify internal single-threaded usage | expand |
On 2022-06-21, Adhemerval Zanella wrote: >By adding an internal alias to avoid the GOT indirection. >On some architecture, __libc_single_thread may be accessed through >copy relocations and thus it requires to update also the copies >default copy. > >This is done by adding a new internal macro, >libc_hidden_data_{proto,def}, which has an addition argument that >specifies the alias name (instead of default __GI_ one). > >Checked on x86_64-linux-gnu and i686-linux-gnu. >--- > elf/libc_early_init.c | 2 +- > include/libc-symbols.h | 22 ++++++++++++++++++++++ > include/sys/single_threaded.h | 11 +++++++++++ > misc/single_threaded.c | 2 ++ > nptl/pthread_create.c | 5 ++++- > posix/fork.c | 2 +- > sysdeps/nptl/setxid.h | 2 +- > 7 files changed, 42 insertions(+), 4 deletions(-) > >diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c >index 3c4a19cf6b..affc46fefc 100644 >--- a/elf/libc_early_init.c >+++ b/elf/libc_early_init.c >@@ -38,7 +38,7 @@ __libc_early_init (_Bool initial) > __libc_single_threaded = initial; > > #ifdef SHARED >- __libc_initial = initial; >+ __libc_single_threaded_internal = __libc_initial = initial; > #endif > > __pthread_early_init (); >diff --git a/include/libc-symbols.h b/include/libc-symbols.h >index 4bb3d8c7ba..4fde839471 100644 >--- a/include/libc-symbols.h >+++ b/include/libc-symbols.h >@@ -534,11 +534,15 @@ for linking") > __attribute__ ((visibility ("hidden"), ##attrs)) > # define hidden_proto(name, attrs...) \ > __hidden_proto (name, , __GI_##name, ##attrs) >+# define hidden_proto_alias(name, alias, attrs...) \ >+ __hidden_proto_alias (name, , alias, ##attrs) > # define hidden_tls_proto(name, attrs...) \ > __hidden_proto (name, __thread, __GI_##name, ##attrs) > # define __hidden_proto(name, thread, internal, attrs...) \ > extern thread __typeof (name) name __asm__ (__hidden_asmname (#internal)) \ > __hidden_proto_hiddenattr (attrs); >+# define __hidden_proto_alias(name, thread, internal, attrs...) \ >+ extern thread __typeof (name) internal __hidden_proto_hiddenattr (attrs); > # define __hidden_asmname(name) \ > __hidden_asmname1 (__USER_LABEL_PREFIX__, name) > # define __hidden_asmname1(prefix, name) __hidden_asmname2(prefix, name) >@@ -554,7 +558,10 @@ for linking") > # define hidden_ver(local, name) __hidden_ver1(local, __GI_##name, name); > # define hidden_data_ver(local, name) hidden_ver(local, name) > # define hidden_def(name) __hidden_ver1(__GI_##name, name, name); >+# define hidden_def_alias(name, internal) \ >+ strong_alias (name, internal) > # define hidden_data_def(name) hidden_def(name) >+# define hidden_data_def_alias(name, alias) hidden_def_alias(name, alias) > # define hidden_tls_def(name) \ > __hidden_ver2 (__thread, __GI_##name, name, name); > # define hidden_weak(name) \ >@@ -581,9 +588,11 @@ for linking") > hidden_proto doesn't make sense for assembly but the equivalent > is to call via the HIDDEN_JUMPTARGET macro instead of JUMPTARGET. */ > # define hidden_def(name) strong_alias (name, __GI_##name) >+# define hidden_def_alias(name, alias) strong_alias (name, alias) > # define hidden_weak(name) hidden_def (name) > # define hidden_ver(local, name) strong_alias (local, __GI_##name) > # define hidden_data_def(name) strong_data_alias (name, __GI_##name) >+# define hidden_data_def_alias(name, alias) strong_data_alias (name, alias) > # define hidden_tls_def(name) hidden_data_def (name) > # define hidden_data_weak(name) hidden_data_def (name) > # define hidden_data_ver(local, name) strong_data_alias (local, __GI_##name) >@@ -598,12 +607,17 @@ for linking") > __attribute__ ((visibility ("hidden"), ##attrs)) > # define hidden_proto(name, attrs...) \ > __hidden_proto (name, , name, ##attrs) >+# define hidden_proto_alias(name, alias, attrs...) \ >+ __hidden_proto_alias (name, , alias, ##attrs) > # define hidden_tls_proto(name, attrs...) \ > __hidden_proto (name, __thread, name, ##attrs) > # define __hidden_proto(name, thread, internal, attrs...) \ > extern thread __typeof (name) name __hidden_proto_hiddenattr (attrs); >+# define __hidden_proto_alias(name, thread, internal, attrs...) \ >+ extern thread __typeof (name) internal __hidden_proto_hiddenattr (attrs); > # else > # define hidden_proto(name, attrs...) >+# define hidden_proto_alias(name, alias, attrs...) > # define hidden_tls_proto(name, attrs...) > # endif > # else >@@ -611,9 +625,11 @@ for linking") > # endif /* Not __ASSEMBLER__ */ > # define hidden_weak(name) > # define hidden_def(name) >+# define hidden_def_alias(name, alias) > # define hidden_ver(local, name) > # define hidden_data_weak(name) > # define hidden_data_def(name) >+# define hidden_data_def_alias(name, alias) > # define hidden_tls_def(name) > # define hidden_data_ver(local, name) > # define hidden_nolink(name, lib, version) >@@ -621,22 +637,28 @@ for linking") > > #if IS_IN (libc) > # define libc_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) >+# define libc_hidden_proto_alias(name, alias, attrs...) \ >+ hidden_proto_alias (name, alias, ##attrs) > # define libc_hidden_tls_proto(name, attrs...) hidden_tls_proto (name, ##attrs) > # define libc_hidden_def(name) hidden_def (name) >+# define libc_hidden_def_alias(name, alias) hidden_def_alias (name, alias) > # define libc_hidden_weak(name) hidden_weak (name) > # define libc_hidden_nolink_sunrpc(name, version) hidden_nolink (name, libc, version) > # define libc_hidden_ver(local, name) hidden_ver (local, name) > # define libc_hidden_data_def(name) hidden_data_def (name) >+# define libc_hidden_data_def_alias(name, alias) hidden_data_def_alias (name, alias) > # define libc_hidden_tls_def(name) hidden_tls_def (name) > # define libc_hidden_data_weak(name) hidden_data_weak (name) > # define libc_hidden_data_ver(local, name) hidden_data_ver (local, name) > #else > # define libc_hidden_proto(name, attrs...) >+# define libc_hidden_proto_alias(name, alias, attrs...) > # define libc_hidden_tls_proto(name, attrs...) > # define libc_hidden_def(name) > # define libc_hidden_weak(name) > # define libc_hidden_ver(local, name) > # define libc_hidden_data_def(name) >+# define libc_hidden_data_def_alias(name, alias) > # define libc_hidden_tls_def(name) > # define libc_hidden_data_weak(name) > # define libc_hidden_data_ver(local, name) include/libc-symbols.h is very difficult to read. I can only use the preprocessed output to understand that this patch works as intended. I wish that we can simplify the file a bit :-) >diff --git a/include/sys/single_threaded.h b/include/sys/single_threaded.h >index 18f6972482..2015742be0 100644 >--- a/include/sys/single_threaded.h >+++ b/include/sys/single_threaded.h >@@ -1 +1,12 @@ > #include <misc/sys/single_threaded.h> >+ >+#ifndef _ISOMAC >+ >+libc_hidden_proto_alias (__libc_single_threaded, >+ __libc_single_threaded_internal); >+ >+#if !defined SHARED || !IS_IN(libc) >+# define __libc_single_threaded_internal __libc_single_threaded >+#endif >+ >+#endif Does this file need a header guard now? >diff --git a/misc/single_threaded.c b/misc/single_threaded.c >index 96ada9137b..9b0746a69c 100644 >--- a/misc/single_threaded.c >+++ b/misc/single_threaded.c >@@ -25,3 +25,5 @@ char __libc_single_threaded; > #else > char __libc_single_threaded = 1; > #endif >+libc_hidden_data_def_alias (__libc_single_threaded, >+ __libc_single_threaded_internal) >diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c >index e7a099acb7..5b98e053d6 100644 >--- a/nptl/pthread_create.c >+++ b/nptl/pthread_create.c >@@ -624,9 +624,12 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr, > > /* Avoid a data race in the multi-threaded case, and call the > deferred initialization only once. */ >- if (__libc_single_threaded) >+ if (__libc_single_threaded_internal) > { > late_init (); >+ __libc_single_threaded_internal = 0; >+ /* __libc_single_threaded can be accessed through copy relocations, so >+ it requires to update the external copy. */ > __libc_single_threaded = 0; > } LGTM. I verify that __libc_single_threaded has a GLOB_DAT. Reviewed-by: Fangrui Song <maskray@google.com> >diff --git a/posix/fork.c b/posix/fork.c >index e1be3422ea..987916a175 100644 >--- a/posix/fork.c >+++ b/posix/fork.c >@@ -45,7 +45,7 @@ __libc_fork (void) > requirement for fork (Austin Group tracker issue #62) this is > best effort to make is async-signal-safe at least for single-thread > case. */ >- bool multiple_threads = __libc_single_threaded == 0; >+ bool multiple_threads = __libc_single_threaded_internal == 0; > uint64_t lastrun; > > lastrun = __run_prefork_handlers (multiple_threads); >diff --git a/sysdeps/nptl/setxid.h b/sysdeps/nptl/setxid.h >index b821d6bc07..b87cad7b18 100644 >--- a/sysdeps/nptl/setxid.h >+++ b/sysdeps/nptl/setxid.h >@@ -29,7 +29,7 @@ > #define INLINE_SETXID_SYSCALL(name, nr, args...) \ > ({ \ > int __result; \ >- if (!__libc_single_threaded) \ >+ if (!__libc_single_threaded_internal) \ > { \ > struct xid_command __cmd; \ > __cmd.syscall_no = __NR_##name; \ >-- >2.34.1 >
> On 23 Jun 2022, at 01:15, Fangrui Song <maskray@google.com> wrote: > > On 2022-06-21, Adhemerval Zanella wrote: >> By adding an internal alias to avoid the GOT indirection. >> On some architecture, __libc_single_thread may be accessed through >> copy relocations and thus it requires to update also the copies >> default copy. >> >> This is done by adding a new internal macro, >> libc_hidden_data_{proto,def}, which has an addition argument that >> specifies the alias name (instead of default __GI_ one). >> >> Checked on x86_64-linux-gnu and i686-linux-gnu. >> --- >> elf/libc_early_init.c | 2 +- >> include/libc-symbols.h | 22 ++++++++++++++++++++++ >> include/sys/single_threaded.h | 11 +++++++++++ >> misc/single_threaded.c | 2 ++ >> nptl/pthread_create.c | 5 ++++- >> posix/fork.c | 2 +- >> sysdeps/nptl/setxid.h | 2 +- >> 7 files changed, 42 insertions(+), 4 deletions(-) >> >> diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c >> index 3c4a19cf6b..affc46fefc 100644 >> --- a/elf/libc_early_init.c >> +++ b/elf/libc_early_init.c >> @@ -38,7 +38,7 @@ __libc_early_init (_Bool initial) >> __libc_single_threaded = initial; >> >> #ifdef SHARED >> - __libc_initial = initial; >> + __libc_single_threaded_internal = __libc_initial = initial; >> #endif >> >> __pthread_early_init (); >> diff --git a/include/libc-symbols.h b/include/libc-symbols.h >> index 4bb3d8c7ba..4fde839471 100644 >> --- a/include/libc-symbols.h >> +++ b/include/libc-symbols.h >> @@ -534,11 +534,15 @@ for linking") >> __attribute__ ((visibility ("hidden"), ##attrs)) >> # define hidden_proto(name, attrs...) \ >> __hidden_proto (name, , __GI_##name, ##attrs) >> +# define hidden_proto_alias(name, alias, attrs...) \ >> + __hidden_proto_alias (name, , alias, ##attrs) >> # define hidden_tls_proto(name, attrs...) \ >> __hidden_proto (name, __thread, __GI_##name, ##attrs) >> # define __hidden_proto(name, thread, internal, attrs...) \ >> extern thread __typeof (name) name __asm__ (__hidden_asmname (#internal)) \ >> __hidden_proto_hiddenattr (attrs); >> +# define __hidden_proto_alias(name, thread, internal, attrs...) \ >> + extern thread __typeof (name) internal __hidden_proto_hiddenattr (attrs); >> # define __hidden_asmname(name) \ >> __hidden_asmname1 (__USER_LABEL_PREFIX__, name) >> # define __hidden_asmname1(prefix, name) __hidden_asmname2(prefix, name) >> @@ -554,7 +558,10 @@ for linking") >> # define hidden_ver(local, name) __hidden_ver1(local, __GI_##name, name); >> # define hidden_data_ver(local, name) hidden_ver(local, name) >> # define hidden_def(name) __hidden_ver1(__GI_##name, name, name); >> +# define hidden_def_alias(name, internal) \ >> + strong_alias (name, internal) >> # define hidden_data_def(name) hidden_def(name) >> +# define hidden_data_def_alias(name, alias) hidden_def_alias(name, alias) >> # define hidden_tls_def(name) \ >> __hidden_ver2 (__thread, __GI_##name, name, name); >> # define hidden_weak(name) \ >> @@ -581,9 +588,11 @@ for linking") >> hidden_proto doesn't make sense for assembly but the equivalent >> is to call via the HIDDEN_JUMPTARGET macro instead of JUMPTARGET. */ >> # define hidden_def(name) strong_alias (name, __GI_##name) >> +# define hidden_def_alias(name, alias) strong_alias (name, alias) >> # define hidden_weak(name) hidden_def (name) >> # define hidden_ver(local, name) strong_alias (local, __GI_##name) >> # define hidden_data_def(name) strong_data_alias (name, __GI_##name) >> +# define hidden_data_def_alias(name, alias) strong_data_alias (name, alias) >> # define hidden_tls_def(name) hidden_data_def (name) >> # define hidden_data_weak(name) hidden_data_def (name) >> # define hidden_data_ver(local, name) strong_data_alias (local, __GI_##name) >> @@ -598,12 +607,17 @@ for linking") >> __attribute__ ((visibility ("hidden"), ##attrs)) >> # define hidden_proto(name, attrs...) \ >> __hidden_proto (name, , name, ##attrs) >> +# define hidden_proto_alias(name, alias, attrs...) \ >> + __hidden_proto_alias (name, , alias, ##attrs) >> # define hidden_tls_proto(name, attrs...) \ >> __hidden_proto (name, __thread, name, ##attrs) >> # define __hidden_proto(name, thread, internal, attrs...) \ >> extern thread __typeof (name) name __hidden_proto_hiddenattr (attrs); >> +# define __hidden_proto_alias(name, thread, internal, attrs...) \ >> + extern thread __typeof (name) internal __hidden_proto_hiddenattr (attrs); >> # else >> # define hidden_proto(name, attrs...) >> +# define hidden_proto_alias(name, alias, attrs...) >> # define hidden_tls_proto(name, attrs...) >> # endif >> # else >> @@ -611,9 +625,11 @@ for linking") >> # endif /* Not __ASSEMBLER__ */ >> # define hidden_weak(name) >> # define hidden_def(name) >> +# define hidden_def_alias(name, alias) >> # define hidden_ver(local, name) >> # define hidden_data_weak(name) >> # define hidden_data_def(name) >> +# define hidden_data_def_alias(name, alias) >> # define hidden_tls_def(name) >> # define hidden_data_ver(local, name) >> # define hidden_nolink(name, lib, version) >> @@ -621,22 +637,28 @@ for linking") >> >> #if IS_IN (libc) >> # define libc_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) >> +# define libc_hidden_proto_alias(name, alias, attrs...) \ >> + hidden_proto_alias (name, alias, ##attrs) >> # define libc_hidden_tls_proto(name, attrs...) hidden_tls_proto (name, ##attrs) >> # define libc_hidden_def(name) hidden_def (name) >> +# define libc_hidden_def_alias(name, alias) hidden_def_alias (name, alias) >> # define libc_hidden_weak(name) hidden_weak (name) >> # define libc_hidden_nolink_sunrpc(name, version) hidden_nolink (name, libc, version) >> # define libc_hidden_ver(local, name) hidden_ver (local, name) >> # define libc_hidden_data_def(name) hidden_data_def (name) >> +# define libc_hidden_data_def_alias(name, alias) hidden_data_def_alias (name, alias) >> # define libc_hidden_tls_def(name) hidden_tls_def (name) >> # define libc_hidden_data_weak(name) hidden_data_weak (name) >> # define libc_hidden_data_ver(local, name) hidden_data_ver (local, name) >> #else >> # define libc_hidden_proto(name, attrs...) >> +# define libc_hidden_proto_alias(name, alias, attrs...) >> # define libc_hidden_tls_proto(name, attrs...) >> # define libc_hidden_def(name) >> # define libc_hidden_weak(name) >> # define libc_hidden_ver(local, name) >> # define libc_hidden_data_def(name) >> +# define libc_hidden_data_def_alias(name, alias) >> # define libc_hidden_tls_def(name) >> # define libc_hidden_data_weak(name) >> # define libc_hidden_data_ver(local, name) > > include/libc-symbols.h is very difficult to read. > I can only use the preprocessed output to understand that this patch > works as intended. > > I wish that we can simplify the file a bit :-) The libc-symbols.h requires to define different macros for C and ASM and it does have some cruft that we might clean up (like some unused macros and maybe old binutils support). > >> diff --git a/include/sys/single_threaded.h b/include/sys/single_threaded.h >> index 18f6972482..2015742be0 100644 >> --- a/include/sys/single_threaded.h >> +++ b/include/sys/single_threaded.h >> @@ -1 +1,12 @@ >> #include <misc/sys/single_threaded.h> >> + >> +#ifndef _ISOMAC >> + >> +libc_hidden_proto_alias (__libc_single_threaded, >> + __libc_single_threaded_internal); >> + >> +#if !defined SHARED || !IS_IN(libc) >> +# define __libc_single_threaded_internal __libc_single_threaded >> +#endif >> + >> +#endif > > Does this file need a header guard now? The _ISOMAC is required so we can use the header on tests. And the SHARED || !IS_IN(libc) is to avoid the optimization on Hurd (since it still has the pthread library outside libc). > >> diff --git a/misc/single_threaded.c b/misc/single_threaded.c >> index 96ada9137b..9b0746a69c 100644 >> --- a/misc/single_threaded.c >> +++ b/misc/single_threaded.c >> @@ -25,3 +25,5 @@ char __libc_single_threaded; >> #else >> char __libc_single_threaded = 1; >> #endif >> +libc_hidden_data_def_alias (__libc_single_threaded, >> + __libc_single_threaded_internal) >> diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c >> index e7a099acb7..5b98e053d6 100644 >> --- a/nptl/pthread_create.c >> +++ b/nptl/pthread_create.c >> @@ -624,9 +624,12 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr, >> >> /* Avoid a data race in the multi-threaded case, and call the >> deferred initialization only once. */ >> - if (__libc_single_threaded) >> + if (__libc_single_threaded_internal) >> { >> late_init (); >> + __libc_single_threaded_internal = 0; >> + /* __libc_single_threaded can be accessed through copy relocations, so >> + it requires to update the external copy. */ >> __libc_single_threaded = 0; >> } > > LGTM. I verify that __libc_single_threaded has a GLOB_DAT. > > Reviewed-by: Fangrui Song <maskray@google.com> Thanks. > >> diff --git a/posix/fork.c b/posix/fork.c >> index e1be3422ea..987916a175 100644 >> --- a/posix/fork.c >> +++ b/posix/fork.c >> @@ -45,7 +45,7 @@ __libc_fork (void) >> requirement for fork (Austin Group tracker issue #62) this is >> best effort to make is async-signal-safe at least for single-thread >> case. */ >> - bool multiple_threads = __libc_single_threaded == 0; >> + bool multiple_threads = __libc_single_threaded_internal == 0; >> uint64_t lastrun; >> >> lastrun = __run_prefork_handlers (multiple_threads); >> diff --git a/sysdeps/nptl/setxid.h b/sysdeps/nptl/setxid.h >> index b821d6bc07..b87cad7b18 100644 >> --- a/sysdeps/nptl/setxid.h >> +++ b/sysdeps/nptl/setxid.h >> @@ -29,7 +29,7 @@ >> #define INLINE_SETXID_SYSCALL(name, nr, args...) \ >> ({ \ >> int __result; \ >> - if (!__libc_single_threaded) \ >> + if (!__libc_single_threaded_internal) \ >> { \ >> struct xid_command __cmd; \ >> __cmd.syscall_no = __NR_##name; \ >> -- >> 2.34.1
diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c index 3c4a19cf6b..affc46fefc 100644 --- a/elf/libc_early_init.c +++ b/elf/libc_early_init.c @@ -38,7 +38,7 @@ __libc_early_init (_Bool initial) __libc_single_threaded = initial; #ifdef SHARED - __libc_initial = initial; + __libc_single_threaded_internal = __libc_initial = initial; #endif __pthread_early_init (); diff --git a/include/libc-symbols.h b/include/libc-symbols.h index 4bb3d8c7ba..4fde839471 100644 --- a/include/libc-symbols.h +++ b/include/libc-symbols.h @@ -534,11 +534,15 @@ for linking") __attribute__ ((visibility ("hidden"), ##attrs)) # define hidden_proto(name, attrs...) \ __hidden_proto (name, , __GI_##name, ##attrs) +# define hidden_proto_alias(name, alias, attrs...) \ + __hidden_proto_alias (name, , alias, ##attrs) # define hidden_tls_proto(name, attrs...) \ __hidden_proto (name, __thread, __GI_##name, ##attrs) # define __hidden_proto(name, thread, internal, attrs...) \ extern thread __typeof (name) name __asm__ (__hidden_asmname (#internal)) \ __hidden_proto_hiddenattr (attrs); +# define __hidden_proto_alias(name, thread, internal, attrs...) \ + extern thread __typeof (name) internal __hidden_proto_hiddenattr (attrs); # define __hidden_asmname(name) \ __hidden_asmname1 (__USER_LABEL_PREFIX__, name) # define __hidden_asmname1(prefix, name) __hidden_asmname2(prefix, name) @@ -554,7 +558,10 @@ for linking") # define hidden_ver(local, name) __hidden_ver1(local, __GI_##name, name); # define hidden_data_ver(local, name) hidden_ver(local, name) # define hidden_def(name) __hidden_ver1(__GI_##name, name, name); +# define hidden_def_alias(name, internal) \ + strong_alias (name, internal) # define hidden_data_def(name) hidden_def(name) +# define hidden_data_def_alias(name, alias) hidden_def_alias(name, alias) # define hidden_tls_def(name) \ __hidden_ver2 (__thread, __GI_##name, name, name); # define hidden_weak(name) \ @@ -581,9 +588,11 @@ for linking") hidden_proto doesn't make sense for assembly but the equivalent is to call via the HIDDEN_JUMPTARGET macro instead of JUMPTARGET. */ # define hidden_def(name) strong_alias (name, __GI_##name) +# define hidden_def_alias(name, alias) strong_alias (name, alias) # define hidden_weak(name) hidden_def (name) # define hidden_ver(local, name) strong_alias (local, __GI_##name) # define hidden_data_def(name) strong_data_alias (name, __GI_##name) +# define hidden_data_def_alias(name, alias) strong_data_alias (name, alias) # define hidden_tls_def(name) hidden_data_def (name) # define hidden_data_weak(name) hidden_data_def (name) # define hidden_data_ver(local, name) strong_data_alias (local, __GI_##name) @@ -598,12 +607,17 @@ for linking") __attribute__ ((visibility ("hidden"), ##attrs)) # define hidden_proto(name, attrs...) \ __hidden_proto (name, , name, ##attrs) +# define hidden_proto_alias(name, alias, attrs...) \ + __hidden_proto_alias (name, , alias, ##attrs) # define hidden_tls_proto(name, attrs...) \ __hidden_proto (name, __thread, name, ##attrs) # define __hidden_proto(name, thread, internal, attrs...) \ extern thread __typeof (name) name __hidden_proto_hiddenattr (attrs); +# define __hidden_proto_alias(name, thread, internal, attrs...) \ + extern thread __typeof (name) internal __hidden_proto_hiddenattr (attrs); # else # define hidden_proto(name, attrs...) +# define hidden_proto_alias(name, alias, attrs...) # define hidden_tls_proto(name, attrs...) # endif # else @@ -611,9 +625,11 @@ for linking") # endif /* Not __ASSEMBLER__ */ # define hidden_weak(name) # define hidden_def(name) +# define hidden_def_alias(name, alias) # define hidden_ver(local, name) # define hidden_data_weak(name) # define hidden_data_def(name) +# define hidden_data_def_alias(name, alias) # define hidden_tls_def(name) # define hidden_data_ver(local, name) # define hidden_nolink(name, lib, version) @@ -621,22 +637,28 @@ for linking") #if IS_IN (libc) # define libc_hidden_proto(name, attrs...) hidden_proto (name, ##attrs) +# define libc_hidden_proto_alias(name, alias, attrs...) \ + hidden_proto_alias (name, alias, ##attrs) # define libc_hidden_tls_proto(name, attrs...) hidden_tls_proto (name, ##attrs) # define libc_hidden_def(name) hidden_def (name) +# define libc_hidden_def_alias(name, alias) hidden_def_alias (name, alias) # define libc_hidden_weak(name) hidden_weak (name) # define libc_hidden_nolink_sunrpc(name, version) hidden_nolink (name, libc, version) # define libc_hidden_ver(local, name) hidden_ver (local, name) # define libc_hidden_data_def(name) hidden_data_def (name) +# define libc_hidden_data_def_alias(name, alias) hidden_data_def_alias (name, alias) # define libc_hidden_tls_def(name) hidden_tls_def (name) # define libc_hidden_data_weak(name) hidden_data_weak (name) # define libc_hidden_data_ver(local, name) hidden_data_ver (local, name) #else # define libc_hidden_proto(name, attrs...) +# define libc_hidden_proto_alias(name, alias, attrs...) # define libc_hidden_tls_proto(name, attrs...) # define libc_hidden_def(name) # define libc_hidden_weak(name) # define libc_hidden_ver(local, name) # define libc_hidden_data_def(name) +# define libc_hidden_data_def_alias(name, alias) # define libc_hidden_tls_def(name) # define libc_hidden_data_weak(name) # define libc_hidden_data_ver(local, name) diff --git a/include/sys/single_threaded.h b/include/sys/single_threaded.h index 18f6972482..2015742be0 100644 --- a/include/sys/single_threaded.h +++ b/include/sys/single_threaded.h @@ -1 +1,12 @@ #include <misc/sys/single_threaded.h> + +#ifndef _ISOMAC + +libc_hidden_proto_alias (__libc_single_threaded, + __libc_single_threaded_internal); + +#if !defined SHARED || !IS_IN(libc) +# define __libc_single_threaded_internal __libc_single_threaded +#endif + +#endif diff --git a/misc/single_threaded.c b/misc/single_threaded.c index 96ada9137b..9b0746a69c 100644 --- a/misc/single_threaded.c +++ b/misc/single_threaded.c @@ -25,3 +25,5 @@ char __libc_single_threaded; #else char __libc_single_threaded = 1; #endif +libc_hidden_data_def_alias (__libc_single_threaded, + __libc_single_threaded_internal) diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index e7a099acb7..5b98e053d6 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -624,9 +624,12 @@ __pthread_create_2_1 (pthread_t *newthread, const pthread_attr_t *attr, /* Avoid a data race in the multi-threaded case, and call the deferred initialization only once. */ - if (__libc_single_threaded) + if (__libc_single_threaded_internal) { late_init (); + __libc_single_threaded_internal = 0; + /* __libc_single_threaded can be accessed through copy relocations, so + it requires to update the external copy. */ __libc_single_threaded = 0; } diff --git a/posix/fork.c b/posix/fork.c index e1be3422ea..987916a175 100644 --- a/posix/fork.c +++ b/posix/fork.c @@ -45,7 +45,7 @@ __libc_fork (void) requirement for fork (Austin Group tracker issue #62) this is best effort to make is async-signal-safe at least for single-thread case. */ - bool multiple_threads = __libc_single_threaded == 0; + bool multiple_threads = __libc_single_threaded_internal == 0; uint64_t lastrun; lastrun = __run_prefork_handlers (multiple_threads); diff --git a/sysdeps/nptl/setxid.h b/sysdeps/nptl/setxid.h index b821d6bc07..b87cad7b18 100644 --- a/sysdeps/nptl/setxid.h +++ b/sysdeps/nptl/setxid.h @@ -29,7 +29,7 @@ #define INLINE_SETXID_SYSCALL(name, nr, args...) \ ({ \ int __result; \ - if (!__libc_single_threaded) \ + if (!__libc_single_threaded_internal) \ { \ struct xid_command __cmd; \ __cmd.syscall_no = __NR_##name; \