On 11.09.2020 07:13, Rin Okuyama wrote:
> Hi again,
>
> On 2020/09/10 21:53, Kamil Rytarowski wrote:
>> Module Name: src
>> Committed By: kamil
>> Date: Thu Sep 10 12:53:06 UTC 2020
>>
>> Modified Files:
>> src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common:
>> sanitizer_linux_libcdep.cc
>> src/external/gpl3/gcc/lib: Makefile.sanitizer
>>
>> Log Message:
>> Avoid using internal RTLD/libpthread/libc symbol in sanitizers
>>
> ...
>> Index:
>> src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc
>>
>> diff -u
>> src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc:1.15
>> src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc:1.16
>>
>> ---
>> src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc:1.15
>>
>> Mon Sep 7 07:10:43 2020
>> +++
>> src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc
>>
>> Thu Sep 10 12:53:05 2020
>> @@ -47,6 +47,7 @@
>> #if SANITIZER_NETBSD
>> #include
>> #include
>> +#include
>> #endif
>> #if SANITIZER_SOLARIS
>> @@ -417,13 +418,7 @@ uptr ThreadSelf() {
>> #if SANITIZER_NETBSD
>> static struct tls_tcb * ThreadSelfTlsTcb() {
>> - struct tls_tcb * tcb = NULL;
>> -# ifdef __HAVE___LWP_GETTCB_FAST
>> - tcb = (struct tls_tcb *)__lwp_gettcb_fast();
>> -# elif defined(__HAVE___LWP_GETPRIVATE_FAST)
>> - tcb = (struct tls_tcb *)__lwp_getprivate_fast();
>> -# endif
>> - return tcb;
>> + return (struct tls_tcb *)_lwp_getprivate();
>> }
>> uptr ThreadSelf() {
>>
>
> This change breaks at least mips and powerpc, in which the return value of
> __lwp_getprivate(2), i.e., curlwp->l_private is not tcb address itself, but
> biased one. On the other hand, the return value of __lwp_gettcb_fast() is
> unbiased address; see sys/arch/{mips,powerpc}/include/mcontext.h.
>
> For powerpc, I recently attempted to change l_private to store tcb address
> itself:
>
> http://www.nerv.org/netbsd/?q=id:20200621T004000Z.95c1a18070b53713ce2c763df7f40743bf74172c
>
>
> But I reverted it soon as requested by joerg:
>
> http://www.nerv.org/netbsd/?q=id:20200622T053457Z.05db3be87b5ad499f5d1adba755bc573fd241c87
>
>
> His reasoning was that kernel must not know the ABI details in userland.
> I fully agree with this. See above links for more details.
>
> Thanks,
> rin
Thank you for noting it!
This is strange as I assumed that _lwp_getprivate() returns always the
correct private pointer and it is abstraction over fast ABI specific
calls . Also the usage of _lwp_getprivate() was suggested by Joerg back
then in sanitizers.
So we want exported to userland functionality to get the tls_tcb
pointer, something without using the internal RTLS/LIBPTHREAD/LIBC
namespaces.
The current code is confusing, as it attempts to use unimplemented
_PTHREAD_GETTCB_EXT() and in one place uses _lwp_getprivate_fast() in
other _lwp_getprivate(). This caused my confusion... as I assumed that
_lwp_getprivate_fast() is internal and _lwp_getprivate() for public
consumption.
https://nxr.netbsd.org/xref/src/lib/libpthread/pthread_int.h#266
263 static inline pthread_t __constfunc
264 pthread__self(void)
265 {
266 #if defined(_PTHREAD_GETTCB_EXT)
267 struct tls_tcb * const tcb = _PTHREAD_GETTCB_EXT();
268 #elif defined(__HAVE___LWP_GETTCB_FAST)
269 struct tls_tcb * const tcb = __lwp_gettcb_fast();
270 #else
271 struct tls_tcb * const tcb = __lwp_getprivate_fast();
272 #endif
273 return (pthread_t)tcb->tcb_pthread;
274 }
https://nxr.netbsd.org/xref/src/lib/libpthread/pthread.c#1268
1268 #if defined(_PTHREAD_GETTCB_EXT)
1269 pthread__main->pt_tls = _PTHREAD_GETTCB_EXT();
1270 #elif defined(__HAVE___LWP_GETTCB_FAST)
1271 pthread__main->pt_tls = __lwp_gettcb_fast();
1272 #else
1273 pthread__main->pt_tls = _lwp_getprivate();
1274 #endif
1275 pthread__main->pt_tls->tcb_pthread = pthread__main;
https://nxr.netbsd.org/xref/src/libexec/ld.elf_so/tls.c#294
293 #ifdef __HAVE___LWP_GETTCB_FAST
294 struct tls_tcb * const tcb = __lwp_gettcb_fast();
295 #else
296 struct tls_tcb * const tcb = __lwp_getprivate_fast();
297 #endif
1. Could we please synchronize above three code chunks, avoiding the
situation of having each of them implemented differently?
2. Could we please export _rtld_tls_self() or something similar and
register in ?
Does this patch look good?
https://www.netbsd.org/~kamil/patch-00278-_rtld_tls_self.txt
In the worst case I will need to reexpose internal APIs in sanitizers
and pick one of the above tls_tcb retrieval implementations and use in
LLVM/GCC sanitizers.
PS. There is an ongoing GCC and Linux kernel discussion on a related
topic in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96200 "Implement
__builtin_thread_pointer() and __builtin_