Clean up the TLS code

This commit is contained in:
Justine Tunney 2022-09-10 11:49:13 -07:00
parent cfcf5918bc
commit 333768440c
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
8 changed files with 81 additions and 21 deletions

View file

@ -21,6 +21,8 @@
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/asancodes.h"
#include "libc/intrin/bits.h"
#include "libc/intrin/weaken.h"
#include "libc/log/libfatal.internal.h"
@ -57,7 +59,7 @@ __msabi extern typeof(TlsAlloc) *const __imp_TlsAlloc;
extern unsigned char __tls_mov_nt_rax[];
extern unsigned char __tls_add_nt_rax[];
_Alignas(long) static char __static_tls[5008];
_Alignas(TLS_ALIGNMENT) static char __static_tls[5008];
/**
* Enables thread local storage for main process.
@ -103,7 +105,6 @@ privileged void __enable_tls(void) {
// if tls requirement is small then use the static tls block
// which helps avoid a system call for appes with little tls
// this is crucial to keeping life.com 16 kilobytes in size!
_Static_assert(alignof(__static_tls) >= alignof(struct CosmoTib));
mem = __static_tls;
} else {
// if this binary needs a hefty tls block then we'll bank on
@ -115,6 +116,12 @@ privileged void __enable_tls(void) {
mem = weaken(_mapanon)(siz);
assert(mem);
}
if (IsAsan()) {
// poison the space between .tdata and .tbss
__asan_poison(mem + (intptr_t)_tdata_size,
(intptr_t)_tbss_offset - (intptr_t)_tdata_size,
kAsanProtected);
}
tib = (struct CosmoTib *)(mem + siz - _TIBZ);
tls = mem + siz - _TIBZ - _TLSZ;
tib->tib_self = tib;

View file

@ -23,6 +23,8 @@ extern unsigned char _tdata_end[];
extern unsigned char _tdata_size[];
extern unsigned char _tbss_start[];
extern unsigned char _tbss_end[];
extern unsigned char _tbss_size[];
extern unsigned char _tbss_offset[];
extern unsigned char _tls_size[];
extern unsigned char _tls_content[];

View file

@ -50,6 +50,8 @@
_tdata_size = 0
_tbss_start = 0
_tbss_end = 0
_tbss_offset = 0
_tbss_size = 0
_tls_size = 0
_tls_content = 0
@ -73,6 +75,8 @@
.globl _tdata_size
.globl _tbss_start
.globl _tbss_end
.globl _tbss_size
.globl _tbss_offset
.globl _tls_size
.globl _tls_content
.globl __data_start
@ -100,8 +104,10 @@
.weak _tdata_size
.weak _tbss_start
.weak _tbss_end
.weak _tbss_size
.weak _tls_size
.weak _tls_content
.weak _tbss_offset
.weak __data_start
.weak __data_end
.weak __bss_start

View file

@ -16,6 +16,9 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/asancodes.h"
#include "libc/macros.internal.h"
#include "libc/mem/mem.h"
#include "libc/runtime/internal.h"
@ -24,10 +27,9 @@
#include "libc/thread/spawn.h"
#include "libc/thread/tls.h"
#define _TLSZ ((intptr_t)_tls_size)
#define _TLDZ ((intptr_t)_tdata_size)
#define _TIBZ sizeof(struct CosmoTib)
#define _MEMZ ROUNDUP(_TLSZ + _TIBZ, _Alignof(struct CosmoTib))
#define I(x) ((intptr_t)x)
void Bzero(void *, size_t) asm("bzero"); // gcc bug
/**
* Allocates thread-local storage memory for new thread.
@ -37,17 +39,25 @@ char *_mktls(char **out_tib) {
char *tls;
struct CosmoTib *tib;
// Allocate enough TLS memory for all the GNU Linuker (_tls_size)
// organized _Thread_local data, as well as Cosmpolitan Libc (64)
if (!(tls = calloc(1, _MEMZ))) return 0;
// allocate memory for tdata, tbss, and tib
tls = memalign(TLS_ALIGNMENT, I(_tls_size) + sizeof(struct CosmoTib));
if (!tls) return 0;
// poison memory between tdata and tbss
if (IsAsan()) {
__asan_poison(tls + I(_tdata_size), I(_tbss_offset) - I(_tdata_size),
kAsanProtected);
}
// initialize tdata and clear tbss
memmove(tls, _tdata_start, I(_tdata_size));
Bzero(tls + I(_tbss_offset), I(_tbss_size) + sizeof(struct CosmoTib));
// set up thread information block
tib = (struct CosmoTib *)(tls + _MEMZ - _TIBZ);
tib = (struct CosmoTib *)(tls + I(_tls_size));
tib->tib_self = tib;
tib->tib_self2 = tib;
tib->tib_errno = 0;
tib->tib_tid = -1;
memmove(tls, _tdata_start, _TLDZ);
if (out_tib) {
*out_tib = (char *)tib;

View file

@ -1,5 +1,8 @@
#ifndef COSMOPOLITAN_LIBC_THREAD_TLS_H_
#define COSMOPOLITAN_LIBC_THREAD_TLS_H_
#define TLS_ALIGNMENT 64
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_