Skip to content

Commit

Permalink
ld.elf_so: add support for __cxa_thread_atexit_impl
Browse files Browse the repository at this point in the history
JIRA: RTOS-664
  • Loading branch information
badochov committed Sep 2, 2024
1 parent fdaab8d commit 94c36aa
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 1 deletion.
2 changes: 1 addition & 1 deletion stdlib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
# Copyright 2018, 2019, 2020 Phoenix Systems
#

OBJS += $(addprefix $(PREFIX_O)stdlib/, abort.o bsearch.o div.o exit.o mktemp.o qsort.o random.o strtoul.o atexit.o env.o malloc_dl.o pty.o rand.o strtod.o strtoull.o)
OBJS += $(addprefix $(PREFIX_O)stdlib/, abort.o bsearch.o div.o exit.o mktemp.o qsort.o random.o strtoul.o atexit.o env.o malloc_dl.o pty.o rand.o strtod.o strtoull.o cxa_thread_atexit.o)
5 changes: 5 additions & 0 deletions stdlib/atexit.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,17 @@ static struct {
} atexit_common = { .head = &((struct atexit_node) {}) };


extern void __cxa_thread_atexit_init(void);


/* Initialise atexit_common structure before main */
void _atexit_init(void)
{
mutexCreate(&atexit_common.lock);
memset(atexit_common.head, 0, sizeof(struct atexit_node));
atexit_common.idx = 0;

__cxa_thread_atexit_init();
}


Expand Down
130 changes: 130 additions & 0 deletions stdlib/cxa_thread_atexit.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Phoenix-RTOS
*
* libphoenix
*
* atexit.c
*
* Copyright 2019 2022 Phoenix Systems
* Author: Kamil Amanowicz, Dawid Szpejna
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/


#include <stdlib.h>
#include <arch.h>


void __cxa_thread_atexit_init(void);
void __cxa_thread_atexit_run(void);
int __cxa_thread_atexit_impl(void (*)(void *), void *, void *);


#ifdef __LIBPHOENIX_ARCH_TLS_SUPPORTED


void __libc__dl_cxa_refcount(void *addr, ssize_t delta)
{
/* Do nothing in static lib */
(void)addr;
(void)delta;
}


extern void __dl_cxa_refcount(void *, ssize_t) __attribute__((weak, alias("__libc__dl_cxa_refcount")));


struct __cxa_atexit_node {
struct __cxa_atexit_node *prev;
void (*dtor)(void *);
void *obj;
void *handle;
};


static __thread struct __cxa_atexit_node *__cxa_thread_atexit_head;


extern int can_use_tls;


void __cxa_thread_atexit_init(void)
{
/* Special case for dynamic linker exit */
if (can_use_tls != 0) {
atexit(__cxa_thread_atexit_run);
}
}


void __cxa_thread_atexit_run(void)
{
while (__cxa_thread_atexit_head != NULL) {
struct __cxa_atexit_node *last = __cxa_thread_atexit_head;

__cxa_thread_atexit_head->dtor(__cxa_thread_atexit_head->obj);
__cxa_thread_atexit_head = __cxa_thread_atexit_head->prev;

if (last->handle != NULL) {
__dl_cxa_refcount(last->handle, -1);
}

free(last);
}
}


/* C++ thread-local destructor handler */
int __cxa_thread_atexit_impl(void (*dtor)(void *), void *obj, void *handle)
{
struct __cxa_atexit_node *node = malloc(sizeof(struct __cxa_atexit_node));

if (node == NULL) {
return -1;
}

node->dtor = dtor;
node->obj = obj;
node->handle = handle;
node->prev = __cxa_thread_atexit_head;

if (node->handle != NULL) {
__dl_cxa_refcount(node->handle, 1);
}

__cxa_thread_atexit_head = node;

return 0;
}


#else


void __cxa_thread_atexit_init(void)
{
/* Nothing to do */
}


void __cxa_thread_atexit_run(void)
{
/* Nothing to do */
}


/* NOTE: no support for __cxa_thread_atexit_impl on platforms not supporting TLS. */
int __cxa_thread_atexit_impl(void (*dtor)(void *), void *obj, void *handle)
{
(void)dtor;
(void)obj;
(void)handle;

abort();
}


#endif
4 changes: 4 additions & 0 deletions sys/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,12 @@ int beginthreadex(void (*start)(void *), unsigned int priority, void *stack, uns
}


void __cxa_thread_atexit_run(void);


__attribute__((noreturn)) void endthread(void)
{
__cxa_thread_atexit_run();
_rtld_tls_free_curr();
endthreadsvc();
}
Expand Down

0 comments on commit 94c36aa

Please sign in to comment.