[PATCH] [lsan] [mips] adding support of lsan for mips64/mips64el arch

Sergey Matveev earthdok at google.com
Thu Jan 15 10:08:26 PST 2015


The point of confusion here is whether the TCB is considered a part of TLS or not. From LSan's point of view, we have to include the TCB in the rootset. One reason is because thread-specific storage (i.e. pointers stored using pthread_setspecific()) is only reachable through a static array which is a part of the TCB structure. So LSan includes the TCB into the TLS.

In http://reviews.llvm.org/D5616#109055, @sagar wrote:

> X86_64 uses tls variant 2 and `TLS_TCB_AT_TP` is set to 1 in tls.h. So the size we get from `__dl_tls_get_static_info ()` includes the thread descriptor size along with size of static TLS area as per the following code in elf/dl-tls.c:
>   223  GL(dl_tls_static_used) = offset;
>   224  GL(dl_tls_static_size) = (roundup (offset + TLS_STATIC_SURPLUS, max_align)
>   225			    + TLS_TCB_SIZE);
> Therefore we need the Thread Descriptor Size, so that we can exclude it from the size we get from  `__dl_tls_get_static_info ()`.

This is not strictly true. The size we get is correct; it's the offset that is shifted by ThreadDescriptorSize. Take a look at the code in sanitizer_linux_libcdep.cc:

264 # if defined(__x86_64__) || defined(__i386__)                                                                                                                                                            
265   *addr = ThreadSelf();                                                                                                                                                                                  
266   *size = GetTlsSize();                                                                                                                                                                                  
267   *addr -= *size;                                                                                                                                                                                        
268   *addr += ThreadDescriptorSize();

The size we get is the TLS size, including the TCB. We do not adjust it. But ThreadSelf() points at the beginning of the TCB, which is located at the very end of the TLS.

This is of course not relevant to MIPS, just making sure you have a clear picture.

> But MIPS uses TLS variant 1 and `TLS_DTV_AT_TP` is set to 1 in tls.h. So the size we get from `__dl_tls_get_static_info ()` is only the size of static TLS area and does not include the thread descriptor size as per the following code in elf/dl-tls.c:


>   267  GL(dl_tls_static_used) = offset;

>   268  GL(dl_tls_static_size) = roundup (offset + TLS_STATIC_SURPLUS,

>   269				    TLS_TCB_ALIGN);



> Also when we read from hardware register $29 and subtract 0x7000 from it we reach to the start of static TLS (which is also end of TCB for TLS variant 1).

>  Therefore we already have the start address and size of static TLS area so we don't require TlsPreTcbSize () and ThreadDescriptorSize () at all for MIPS.

As discussed above, we still need to adjust the address to point to the beginning of the TCB.




More information about the llvm-commits mailing list