Add TLS (thread local storage) support
This commit is contained in:
parent
33d05f0fd0
commit
3f9513e62c
@ -40,11 +40,11 @@ INCLUDES := include
|
||||
#---------------------------------------------------------------------------------
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard
|
||||
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
|
||||
|
||||
CFLAGS := -g -Wall -Werror -O2 -mword-relocations \
|
||||
-ffunction-sections -fno-strict-aliasing \
|
||||
-fomit-frame-pointer -ffast-math \
|
||||
-fomit-frame-pointer \
|
||||
$(ARCH)
|
||||
|
||||
CFLAGS += $(INCLUDE) -DARM11 -D_3DS
|
||||
|
@ -610,7 +610,6 @@ static void newRow() {
|
||||
}
|
||||
|
||||
consoleClearLine('2');
|
||||
gfxFlushBuffers();
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
|
@ -20,6 +20,9 @@ typedef struct
|
||||
// Pointer to this thread's newlib state
|
||||
struct _reent* reent;
|
||||
|
||||
// Pointer to this thread's thread-local segment
|
||||
void* tls_tp; // !! Keep offset in sync inside __aeabi_read_tp !!
|
||||
|
||||
// FS session override
|
||||
u32 fs_magic;
|
||||
Handle fs_session;
|
||||
|
9
libctru/source/system/readtp.s
Normal file
9
libctru/source/system/readtp.s
Normal file
@ -0,0 +1,9 @@
|
||||
.arm
|
||||
.section .text.__aeabi_read_tp, "ax", %progbits
|
||||
.global __aeabi_read_tp
|
||||
.type __aeabi_read_tp, %function
|
||||
.align 2
|
||||
__aeabi_read_tp:
|
||||
mrc p15, 0, r0, c13, c0, 3
|
||||
ldr r0, [r0, #0xC] @ Read ThreadVars.tls_tp
|
||||
bx lr
|
@ -13,6 +13,10 @@
|
||||
void __ctru_exit(int rc);
|
||||
int __libctru_gtod(struct _reent *ptr, struct timeval *tp, struct timezone *tz);
|
||||
|
||||
extern const u8 __tdata_lma[];
|
||||
extern const u8 __tdata_lma_end[];
|
||||
extern u8 __tls_start[];
|
||||
|
||||
static struct _reent* __ctru_get_reent()
|
||||
{
|
||||
ThreadVars* tv = getThreadVars();
|
||||
@ -46,4 +50,9 @@ void __system_initSyscalls(void)
|
||||
tv->magic = THREADVARS_MAGIC;
|
||||
tv->reent = _impure_ptr;
|
||||
tv->thread_ptr = NULL;
|
||||
tv->tls_tp = __tls_start-8; // ARM ELF TLS ABI mandates an 8-byte header
|
||||
|
||||
u32 tls_size = __tdata_lma_end - __tdata_lma;
|
||||
if (tls_size)
|
||||
memcpy(__tls_start, __tdata_lma, tls_size);
|
||||
}
|
||||
|
@ -2,6 +2,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
extern const u8 __tdata_lma[];
|
||||
extern const u8 __tdata_lma_end[];
|
||||
extern u8 __tls_start[];
|
||||
extern u8 __tls_end[];
|
||||
|
||||
struct Thread_tag
|
||||
{
|
||||
Handle handle;
|
||||
@ -26,6 +31,7 @@ static void _thread_begin(void* arg)
|
||||
tv->magic = THREADVARS_MAGIC;
|
||||
tv->reent = &t->reent;
|
||||
tv->thread_ptr = t;
|
||||
tv->tls_tp = (u8*)t->stacktop-8; // ARM ELF TLS ABI mandates an 8-byte header
|
||||
t->ep(t->arg);
|
||||
threadExit(0);
|
||||
}
|
||||
@ -34,9 +40,16 @@ Thread threadCreate(ThreadFunc entrypoint, void* arg, size_t stack_size, int pri
|
||||
{
|
||||
size_t stackoffset = (sizeof(struct Thread_tag)+7)&~7;
|
||||
size_t allocsize = stackoffset + ((stack_size+7)&~7);
|
||||
if (allocsize < stackoffset) return NULL; // guard against overflow
|
||||
if ((allocsize-stackoffset) < stack_size) return NULL; // guard against overflow
|
||||
Thread t = (Thread)malloc(allocsize);
|
||||
size_t tlssize = __tls_end-__tls_start;
|
||||
size_t tlsloadsize = __tdata_lma_end-__tdata_lma;
|
||||
size_t tbsssize = tlssize-tlsloadsize;
|
||||
|
||||
// Guard against overflow
|
||||
if (allocsize < stackoffset) return NULL;
|
||||
if ((allocsize-stackoffset) < stack_size) return NULL;
|
||||
if ((allocsize+tlssize) < allocsize) return NULL;
|
||||
|
||||
Thread t = (Thread)malloc(allocsize+tlssize);
|
||||
if (!t) return NULL;
|
||||
|
||||
t->ep = entrypoint;
|
||||
@ -45,6 +58,11 @@ Thread threadCreate(ThreadFunc entrypoint, void* arg, size_t stack_size, int pri
|
||||
t->finished = false;
|
||||
t->stacktop = (u8*)t + allocsize;
|
||||
|
||||
if (tlsloadsize)
|
||||
memcpy(t->stacktop, __tdata_lma, tlsloadsize);
|
||||
if (tbsssize)
|
||||
memset((u8*)t->stacktop+tlsloadsize, 0, tbsssize);
|
||||
|
||||
// Set up child thread's reent struct, inheriting standard file handles
|
||||
_REENT_INIT_PTR(&t->reent);
|
||||
struct _reent* cur = getThreadVars()->reent;
|
||||
|
Loading…
Reference in New Issue
Block a user