diff --git a/vxworks-6.9/target/h/openssl/crypto.h b/vxworks-6.9/target/h/openssl/crypto.h index f02d2096..4c79c9ca 100644 --- a/vxworks-6.9/target/h/openssl/crypto.h +++ b/vxworks-6.9/target/h/openssl/crypto.h @@ -55,10 +55,13 @@ # if defined(OPENSSL_SYS_VXWORKS) && defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) #include /* threads.h cannot be included from C++ files, so define these types */ - typedef int once_flag; - typedef unsigned int tss_t; -# ifndef __cplusplus -# endif +#define MAX_STR_LEN 64 + typedef unsigned int tss_t; + typedef struct { + BOOL done; + SEM_ID sem; + char run_once_arg[MAX_STR_LEN]; + } once_flag; # endif #ifdef __cplusplus @@ -523,13 +526,7 @@ typedef once_flag CRYPTO_ONCE; typedef tss_t CRYPTO_THREAD_LOCAL; typedef TASK_ID CRYPTO_THREAD_ID; -typedef struct - { - int initialized; - SEM_ID sem; - }CRYPTO_ONCE_STATIC_INIT; - -# define ONCE_FLAG_INIT {0, NULL} +#define ONCE_FLAG_INIT { 0, NULL, { '\0' } } # define CRYPTO_ONCE_STATIC_INIT ONCE_FLAG_INIT # else diff --git a/vxworks-6.9/target/h/vxtss_symlist.h b/vxworks-6.9/target/h/vxtss_symlist.h new file mode 100644 index 00000000..ba9ee43a --- /dev/null +++ b/vxworks-6.9/target/h/vxtss_symlist.h @@ -0,0 +1,60 @@ +/* vxtss_symlist.h - VxWorks TSS symbol tracking interface */ + +#ifndef __VX_TSS_SYMLIST_H__ +#define __VX_TSS_SYMLIST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* Basic tss sym state types */ + +typedef enum { + TSS_SYMLIST_STATE_INVALID = 0, + TSS_SYMLIST_STATE_NEW, + TSS_SYMLIST_STATE_ADDED, + TSS_SYMLIST_STATE_FAILED, +} tss_sym_state; + +typedef struct { + void *var; /* task-specific variable */ + void (*dtor)(void *); /* optional destructor */ +} tss_entry_t; + +/* Initialize - deinitialize TSS sym */ +int tss_sym_init(void); +int tss_sym_deinit(void); + +/* + * Add new symbol entry + */ +int tss_symlist_add_new(TASK_ID taskid, + char *run_once_arg_str, + char *tss_key_name, + tss_t *tss_key, + tss_sym_state state); + +/* Get the first task ID with matching run_once_arg_string */ +TASK_ID +tss_symlist_get_first_tid(char *run_once_arg_string); + +/* + * Check and populate keys for current task based on run_once_arg_str + */ +void +tss_symlist_clone_entries_for_new_task(TASK_ID tid, char *run_once_arg_string); + +/* Display the tss symbol table */ +int +tss_symlist_show(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __VX_TSS_SYMLIST_H__ */ diff --git a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/async/async.c b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/async/async.c index 46c87d6a..ba5b14ed 100644 --- a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/async/async.c +++ b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/async/async.c @@ -21,6 +21,7 @@ #include #include "crypto/cryptlib.h" #include +#include #define ASYNC_JOB_RUNNING 0 #define ASYNC_JOB_PAUSING 1 @@ -330,11 +331,17 @@ int async_init(void) if (!CRYPTO_THREAD_init_local(&ctxkey, NULL)) return 0; + tss_symlist_add_new(taskIdSelf(), "ossl_init_async", "ctxkey", + &ctxkey, TSS_SYMLIST_STATE_ADDED); + if (!CRYPTO_THREAD_init_local(&poolkey, NULL)) { CRYPTO_THREAD_cleanup_local(&ctxkey); return 0; } + tss_symlist_add_new(taskIdSelf(), "ossl_init_async", "poolkey", + &poolkey, TSS_SYMLIST_STATE_ADDED); + return async_local_init(); } diff --git a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/context.c b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/context.c index f15bc3d7..30dcf215 100644 --- a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/context.c +++ b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/context.c @@ -18,6 +18,8 @@ #include "internal/provider.h" #include "crypto/decoder.h" #include "crypto/context.h" +#include +#include struct ossl_lib_ctx_st { CRYPTO_RWLOCK *lock; @@ -95,6 +97,9 @@ static int context_init(OSSL_LIB_CTX *ctx) if (!CRYPTO_THREAD_init_local(&ctx->rcu_local_key, NULL)) return 0; + tss_symlist_add_new(taskIdSelf(), "default_context_do_init", "ctx->rcu_local_key", + &ctx->rcu_local_key, TSS_SYMLIST_STATE_ADDED); + ctx->lock = CRYPTO_THREAD_lock_new(); if (ctx->lock == NULL) goto err; @@ -396,6 +401,8 @@ DEFINE_RUN_ONCE_STATIC(default_context_do_init) if (!CRYPTO_THREAD_init_local(&default_context_thread_local, NULL)) goto err; + tss_symlist_add_new(taskIdSelf(), "default_context_do_init", "default_context_thread_local", + &default_context_thread_local, TSS_SYMLIST_STATE_ADDED); if (!context_init(&default_context_int)) goto deinit_thread; diff --git a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/err/err.c b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/err/err.c index b95182d7..0e08eff1 100644 --- a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/err/err.c +++ b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/err/err.c @@ -25,6 +25,7 @@ #include "internal/constant_time.h" #include "internal/e_os.h" #include "err_local.h" +#include /* Forward declaration in case it's not published because of configuration */ ERR_STATE *ERR_get_state(void); @@ -666,7 +667,10 @@ void ERR_remove_state(unsigned long pid) DEFINE_RUN_ONCE_STATIC(err_do_init) { set_err_thread_local = 1; - return CRYPTO_THREAD_init_local(&err_thread_local, NULL); + int rc = CRYPTO_THREAD_init_local(&err_thread_local, NULL); + tss_symlist_add_new(taskIdSelf(), "err_do_init", "err_thread_local", + &err_thread_local, TSS_SYMLIST_STATE_ADDED); + return rc; } ERR_STATE *ossl_err_get_state_int(void) diff --git a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/init.c b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/init.c index 036dd700..8f6129fa 100644 --- a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/init.c +++ b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/init.c @@ -40,6 +40,8 @@ #include #include #include "ipcrypto_config.h" +#include +#include #endif static int stopped = 0; @@ -81,6 +83,9 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_base) if (!CRYPTO_THREAD_init_local(&in_init_config_local, NULL)) goto err; + tss_symlist_add_new(taskIdSelf(), "ossl_init_base", "in_init_config_local", + &in_init_config_local, TSS_SYMLIST_STATE_ADDED); + base_inited = 1; return 1; diff --git a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/initthread.c b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/initthread.c index fbd3a480..0fc5ee99 100644 --- a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/initthread.c +++ b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/initthread.c @@ -13,6 +13,7 @@ #include "prov/providercommon.h" #include "internal/thread_once.h" #include "crypto/context.h" +#include #ifdef FIPS_MODULE #include "prov/provider_ctx.h" @@ -207,6 +208,9 @@ int ossl_init_thread(void) init_thread_destructor)) return 0; + tss_symlist_add_new(taskIdSelf(), "ossl_init_base", "destructor_key.value", + &destructor_key.value, TSS_SYMLIST_STATE_ADDED); + return 1; } @@ -270,6 +274,8 @@ void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *libctx) if (!CRYPTO_THREAD_init_local(tlocal, NULL)) goto deinit; + tss_symlist_add_new(taskIdSelf(),"default_context_do_init", "tlocal", + tlocal, TSS_SYMLIST_STATE_ADDED); hands = OPENSSL_zalloc(sizeof(*hands)); if (hands == NULL) diff --git a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/rand/rand_lib.c b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/rand/rand_lib.c index baebedf8..c9c66ffa 100644 --- a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/rand/rand_lib.c +++ b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/crypto/rand/rand_lib.c @@ -22,6 +22,8 @@ #include "rand_local.h" #include "crypto/context.h" #include "internal/provider.h" +#include +#include #ifndef OPENSSL_DEFAULT_SEED_SRC # define OPENSSL_DEFAULT_SEED_SRC SEED-SRC @@ -112,6 +114,8 @@ static RAND_GLOBAL *rand_get_global(OSSL_LIB_CTX *libctx) # include "prov/seeding.h" # include "internal/e_os.h" # include "internal/property.h" +#include +#include /* * The default name for the random provider. @@ -546,9 +550,15 @@ void *ossl_rand_ctx_new(OSSL_LIB_CTX *libctx) if (!CRYPTO_THREAD_init_local(&dgbl->private, NULL)) goto err1; + tss_symlist_add_new(taskIdSelf(), "default_context_do_init", "dgbl->private", + &dgbl->private, TSS_SYMLIST_STATE_ADDED); + if (!CRYPTO_THREAD_init_local(&dgbl->public, NULL)) goto err2; + tss_symlist_add_new(taskIdSelf(), "default_context_do_init", "dgbl->public", + &dgbl->public, TSS_SYMLIST_STATE_ADDED); + return dgbl; err2: diff --git a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/include/internal/thread_once.h b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/include/internal/thread_once.h index d6cb2eee..79f208be 100644 --- a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/include/internal/thread_once.h +++ b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/include/internal/thread_once.h @@ -127,7 +127,8 @@ * (*) by convention, since the init function must return 1 on success. */ # define RUN_ONCE(once, init) \ - (CRYPTO_THREAD_run_once(once, init##_ossl_) ? init##_ossl_ret_ : 0) + (snprintf((once)->run_once_arg, sizeof((once)->run_once_arg), "%s", #init), \ + CRYPTO_THREAD_run_once(once, init##_ossl_) ? init##_ossl_ret_ : 0) /* * RUN_ONCE_ALT - use CRYPTO_THREAD_run_once, to run an alternative initialiser diff --git a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/include/openssl/crypto.h.in b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/include/openssl/crypto.h.in index ce585cc0..4bc4f891 100644 --- a/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/include/openssl/crypto.h.in +++ b/vxworks-6.9/target/src/openssl/OPENSSL/openssl-3.5.0/include/openssl/crypto.h.in @@ -56,13 +56,13 @@ use OpenSSL::stackhash qw(generate_stack_macros); # if defined(OPENSSL_SYS_VXWORKS) && defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) #include /* threads.h cannot be included from C++ files, so define these types */ +#define MAX_STR_LEN 64 + typedef unsigned int tss_t; typedef struct { - BOOL done; - SEM_ID sem; - } once_flag; - typedef unsigned int tss_t; -# ifndef __cplusplus -# endif + BOOL done; + SEM_ID sem; + char run_once_arg[MAX_STR_LEN]; + } once_flag; # endif #ifdef __cplusplus @@ -520,13 +520,8 @@ typedef LONG CRYPTO_ONCE; typedef once_flag CRYPTO_ONCE; typedef tss_t CRYPTO_THREAD_LOCAL; typedef TASK_ID CRYPTO_THREAD_ID; -typedef struct - { - int initialized; - SEM_ID sem; - }CRYPTO_ONCE_STATIC_INIT; -# define ONCE_FLAG_INIT {0, NULL} +#define ONCE_FLAG_INIT { 0, NULL, { '\0' } } # define CRYPTO_ONCE_STATIC_INIT ONCE_FLAG_INIT # else # if defined(__TANDEM) && defined(_SPT_MODEL_) diff --git a/vxworks-6.9/target/src/os/Makefile b/vxworks-6.9/target/src/os/Makefile index 8ab9824d..e8606600 100644 --- a/vxworks-6.9/target/src/os/Makefile +++ b/vxworks-6.9/target/src/os/Makefile @@ -179,7 +179,7 @@ OBJS_COMMON= classLib.o clockLib.o coprocLib.o coprocFuncBind.o copyright.o \ objFuncBind.o objLib.o objSymLib.o pmLib.o \ rebootLib.o rebootHookLib.o kernelBaseLib.o sigFuncBind.o \ taskHookShow.o timerLib.o timerShow.o trcLib.o vxAtomicLib.o \ - vxMemProbeLib.o vxCpuLib.o vxIpiLib.o vxtss.o + vxMemProbeLib.o vxCpuLib.o vxIpiLib.o vxtss_symlist.o vxtss.o # Handle modules & subdirs that are incompatible # with MEM_ALLOT because they use malloc/free. diff --git a/vxworks-6.9/target/src/os/vxtss.c b/vxworks-6.9/target/src/os/vxtss.c index 79e3ad61..90bef024 100644 --- a/vxworks-6.9/target/src/os/vxtss.c +++ b/vxworks-6.9/target/src/os/vxtss.c @@ -1,4 +1,4 @@ -/* vxtssLib.c - vxworks threads-specific storage */ +/* vxtss.c - vxworks threads-specific storage */ /* * Copyright (c) 2025 Wind River Systems, Inc. @@ -19,34 +19,19 @@ DESCRIPTION */ #include -#include #include #include #include #include -#include - -/* Macro for static initialization */ -#define CRYPTO_ONCE_INIT { FALSE, NULL } - -#define tss_t int -#define TSS_TASK_PRIORITY 50 +#include +#include +#include typedef void (*tss_dtor_t)(void*); -/* Equivalent to CRYPTO_ONCE */ -typedef struct { - BOOL done; - SEM_ID sem; -} CRYPTO_ONCE; - -typedef struct { - void *var; /* pointer to the task-specific variable */ - tss_dtor_t dtor; /* optional destructor */ -} tss_entry_t; - /* Internal pthread_once-like routine */ -static STATUS crypto_once(CRYPTO_ONCE *once_control, void (*init_routine)(void)) +static STATUS +crypto_once(CRYPTO_ONCE *once_control, void (*init_routine)(void)) { /* Lazy init of semaphore */ if (once_control->sem == NULL) { @@ -63,81 +48,100 @@ static STATUS crypto_once(CRYPTO_ONCE *once_control, void (*init_routine)(void)) once_control->done = TRUE; } + /* Per Task initialization */ + TASK_ID tid = tss_symlist_get_first_tid(once_control->run_once_arg); + + if (tid != ERROR) { + tss_symlist_clone_entries_for_new_task(tid, once_control->run_once_arg); + } + semGive(once_control->sem); return OK; } -void call_once(CRYPTO_ONCE *once_control, void (*init_routine)(void)) +void +call_once(CRYPTO_ONCE *once_control, void (*init_routine)(void)) { crypto_once(once_control, init_routine); } int -tss_create(tss_t *key, tss_dtor_t destructor) { - if (!key) return ERROR; - - /* Allocate a slot for the variable */ - tss_entry_t *entry = (tss_entry_t*) malloc(sizeof(tss_entry_t)); - if (!entry) return ERROR; - - entry->var = malloc(sizeof(void*)); /* storage for per-task value */ - if (!entry->var) { - free(entry); +tss_create(tss_t *key, tss_dtor_t destructor) +{ + if (!key) { return ERROR; } + /* Allocate a slot for the variable */ + tss_entry_t *entry = (tss_entry_t*) calloc(1, sizeof(tss_entry_t)); + if (!entry) { + return ERROR; + } entry->dtor = destructor; /* Register this variable with the current task */ - if (__taskVarAdd(taskIdSelf(), (int*)entry->var) == ERROR) { - free(entry->var); + if (taskVarAdd(taskIdSelf(), (int*)&entry->var) == ERROR) { free(entry); return ERROR; } - /* Return a "key" (could be just the pointer cast to int) */ *key = (tss_t) entry; - return OK; } void -tss_delete(tss_t key) { - if (!key) return; +tss_delete(tss_t key) +{ + if (!key) + return; tss_entry_t *entry = (tss_entry_t*) key; - /* Remove the task variable association */ - __taskVarDelete(taskIdSelf(), (int*)entry->var); + if (!entry) + return; + + /* Remove the task variable association */ + taskVarDelete(taskIdSelf(), (int*)&entry->var); - /* Free allocated storage */ - free(entry->var); free(entry); } void * tss_get(tss_t key) { - long var=0; + long taskVar = 0; + tss_entry_t *entry = (tss_entry_t*) key; - if (__taskVarGet (key, &var) == ERROR) + if (!entry) + return NULL; + + taskVar = taskVarGet (taskIdSelf(), (int*)&entry->var); + if (taskVar == ERROR) { return NULL; - else - return (void*)var; + } + return (void*)taskVar; } int tss_set(tss_t key, void *val) { - long var=0; + tss_entry_t *entry = (tss_entry_t*) key; - if (__taskVarGet (key, &var) == ERROR) - return OK; - else - { - if (__taskVarSet (key, &var, (long)val) == ERROR) + if (!entry) + return ERROR; + + long taskVar = 0; + + errnoSet(0); /* reset errno to 0 */ + taskVar = taskVarGet (taskIdSelf(), (int*)&entry->var); + if (taskVar == ERROR) { + if (errno == S_taskLib_TASK_VAR_NOT_FOUND) { return ERROR; - else - return OK; + } } + if (taskVarSet (taskIdSelf(), (int*)&entry->var, (long)val) == ERROR) { + return ERROR; + } + return OK; } + diff --git a/vxworks-6.9/target/src/os/vxtss_symlist.c b/vxworks-6.9/target/src/os/vxtss_symlist.c new file mode 100644 index 00000000..94202893 --- /dev/null +++ b/vxworks-6.9/target/src/os/vxtss_symlist.c @@ -0,0 +1,380 @@ +/* vxtss_symlist.c - VxWorks TSS symbol tracking interface */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_TSS_SYM_ENTRY 256 + +/* Sym table entry */ +typedef struct { + long taskid; + char run_once_arg_str[MAX_STR_LEN]; + char tss_key_name[MAX_STR_LEN]; + tss_t *tss_key; + tss_sym_state state; +} tss_sym_entry; + +/* Globals */ +static CRYPTO_RWLOCK *tss_sym_table_lock = NULL; +static tss_sym_entry tss_sym_table[MAX_TSS_SYM_ENTRY]; +static int g_tss_sym_initialized = 0; +static TASK_ID g_first_tid = -1; + + +/* Helper functions */ +static const char* +tss_symlist_get_entry_state_str(tss_sym_state state) +{ + switch(state) { + case TSS_SYMLIST_STATE_INVALID: return "INVALID"; + case TSS_SYMLIST_STATE_NEW: return "NEW"; + case TSS_SYMLIST_STATE_ADDED: return "ADDED"; + case TSS_SYMLIST_STATE_FAILED: return "FAILED"; + default: return "UNKNOWN"; + } +} + +/* Display the symbol table */ +int +tss_symlist_show(void) +{ + int i; + + if (!g_tss_sym_initialized) { + return ERROR; + } + + printf("\n=== TSS Symbol Table ===\n"); + printf("%-20s %-32s %-32s %-16s %-8s\n", + "TNAME", "ONCE_ARGSTR", "TSSKEYNAME", "TSSKEYVAL", "STATE"); + printf("------------------------------------------------------------------------------------------------------------\n"); + + /* Acquire lock for reading */ + CRYPTO_THREAD_read_lock(tss_sym_table_lock); + + for (i = 0; i < MAX_TSS_SYM_ENTRY; i++) { + if (tss_sym_table[i].state == TSS_SYMLIST_STATE_INVALID) { + continue; /* Skip invalid entries */ + } + + const char *tname = taskName((int)tss_sym_table[i].taskid); + if (!tname) tname = "(null)"; + /* Print entry in the specified format */ + printf("%-20s %-32s %-32s %-16p %-8s\n", + tname, + tss_sym_table[i].run_once_arg_str ?: "(null)", + tss_sym_table[i].tss_key_name ?: "(null)", + (void *)tss_sym_table[i].tss_key, + tss_symlist_get_entry_state_str(tss_sym_table[i].state)); + } + + CRYPTO_THREAD_unlock(tss_sym_table_lock); + + printf("=== End of Table ===\n\n"); + + return OK; +} + +static int +tss_symlist_find_free_slot(void) +{ + int i; + for (i = 0; i < MAX_TSS_SYM_ENTRY; i++) { + if (tss_sym_table[i].state == TSS_SYMLIST_STATE_INVALID) { + return i; + } + } + return ERROR; +} + +/* Helper function to check if entry exists for a task */ +static int +tss_symlist_find_entry_by_tid_and_arg(TASK_ID tid, char *run_once_arg_string) +{ + int i; + + for (i = 0; i < MAX_TSS_SYM_ENTRY; i++) { + if (tss_sym_table[i].state != TSS_SYMLIST_STATE_INVALID && + tss_sym_table[i].taskid == (long)tid && + strncmp(tss_sym_table[i].run_once_arg_str, run_once_arg_string, MAX_STR_LEN) == 0) { + return i; /* Return index of matching entry */ + } + } + + return ERROR; /* No matching entry found */ +} + +/* Internal add function - assumes lock is already held */ +static int +tss_symlist_add_new_internal(TASK_ID taskId, char *run_once_arg_str, char *tss_key_name, tss_t *key, tss_sym_state state) +{ + int idx; + + /* Find free slot */ + idx = tss_symlist_find_free_slot(); + + if (idx == ERROR) { + return ERROR; + } + + /* Add new entry */ + tss_sym_table[idx].taskid = (long)taskId; + strncpy(tss_sym_table[idx].run_once_arg_str, run_once_arg_str, MAX_STR_LEN - 1); + tss_sym_table[idx].run_once_arg_str[MAX_STR_LEN - 1] = '\0'; + strncpy(tss_sym_table[idx].tss_key_name, tss_key_name, MAX_STR_LEN - 1); + tss_sym_table[idx].tss_key_name[MAX_STR_LEN - 1] = '\0'; + tss_sym_table[idx].tss_key = (tss_t*)key; + tss_sym_table[idx].state = state; + + return OK; +} + +/* taskHook cleanup */ +void +tss_symlist_task_cleanup_hook(int taskId) +{ + if (!CRYPTO_THREAD_write_lock(tss_sym_table_lock)) + return; + + int i; + for (i = 0; i < MAX_TSS_SYM_ENTRY; i++) { + if (tss_sym_table[i].state == TSS_SYMLIST_STATE_INVALID || + tss_sym_table[i].taskid != taskId) + continue; + + tss_t *thread_local_ptr = tss_sym_table[i].tss_key; + tss_entry_t *entry = (tss_entry_t *)(*thread_local_ptr); + + if (entry) { + taskVarDelete(taskId, (void *)&entry->var); + + if (entry->dtor) + entry->dtor(entry->var); + + if (taskId != g_first_tid) { + free(entry); + *thread_local_ptr = (tss_t)0; + tss_sym_table[i].tss_key = NULL; + tss_sym_table[i].state = TSS_SYMLIST_STATE_INVALID; + } else { + /* First task: keep metadata */ + *thread_local_ptr = (tss_t)0; /* clear slot for this task */ + } + } + } + + CRYPTO_THREAD_unlock(tss_sym_table_lock); +} + +/* Initialize the TSS symbol table */ +int +tss_sym_init(void) +{ + int i; + + if (g_tss_sym_initialized) + return OK; + + /* Initialize all entries to INVALID */ + for (i = 0; i < MAX_TSS_SYM_ENTRY; i++) { + memset(&tss_sym_table[i], 0, sizeof(tss_sym_entry)); + tss_sym_table[i].state = TSS_SYMLIST_STATE_INVALID; + } + + /* Create new lock */ + tss_sym_table_lock = (CRYPTO_RWLOCK *)CRYPTO_THREAD_lock_new(); + + /* Attach cleanup routine to task delete hook chain */ + taskDeleteHookAdd((FUNCPTR)tss_symlist_task_cleanup_hook); + + g_tss_sym_initialized = 1; + + return OK; +} + +/* Add new entry to the symbol table */ +int +tss_symlist_add_new(TASK_ID taskId, char *run_once_arg_str, char *tss_key_name, tss_t *key, tss_sym_state state) +{ + int result; + + if (!g_tss_sym_initialized) { + tss_sym_init(); + } + + /* Acquire lock */ + CRYPTO_THREAD_write_lock(tss_sym_table_lock); + + result = tss_symlist_add_new_internal(taskId, run_once_arg_str, tss_key_name, key, state); + + /* Store this as the first tid if not already set */ + if (g_first_tid == -1 && result == OK) { + g_first_tid = taskId; + } + + /* Release lock */ + CRYPTO_THREAD_unlock(tss_sym_table_lock); + + return result; +} + +/* Get the first task ID with matching run_once_arg_string */ +TASK_ID +tss_symlist_get_first_tid(char *run_once_arg_string) +{ + int i; + int found = 0; + + if (!g_tss_sym_initialized) { + tss_sym_init(); + } + + /* Acquire lock for reading */ + CRYPTO_THREAD_read_lock(tss_sym_table_lock); + + /* Find the first entry with run_once_arg_str */ + for (i = 0; i < MAX_TSS_SYM_ENTRY; i++) { + if (tss_sym_table[i].state != TSS_SYMLIST_STATE_INVALID && + strncmp(tss_sym_table[i].run_once_arg_str, run_once_arg_string, MAX_STR_LEN) == 0) { + found = 1; + break; + } + } + + if (!found) { + CRYPTO_THREAD_unlock(tss_sym_table_lock); + return (TASK_ID)ERROR; + } + + CRYPTO_THREAD_unlock(tss_sym_table_lock); + return (TASK_ID)tss_sym_table[i].taskid; +} + +/* Create entry and update the global key (thread_local) for the current task */ +int +tss_create_and_update_table(tss_t *key, char *tss_key_name, char *run_once_arg_str) +{ + tss_entry_t *entry; + TASK_ID selfTaskId; + + entry = (tss_entry_t *)malloc(sizeof(tss_entry_t)); + if (entry == NULL) { + return ERROR; + } + + memset(entry, 0, sizeof(tss_entry_t)); + + selfTaskId = taskIdSelf(); + + if (taskVarAdd(0, (int *)&entry->var) != OK) { + free(entry); + return ERROR; + } + + /* Update the global key (thread_local) to point to this entry */ + *key = (tss_t)entry; + + /* Add to symbol table for tracking */ + tss_symlist_add_new_internal(selfTaskId, run_once_arg_str, tss_key_name, key, TSS_SYMLIST_STATE_ADDED); + + return OK; +} + +/* Clone entries for a new task - correctly passes the global key address */ +void +tss_symlist_clone_entries_for_new_task(TASK_ID tid, char *run_once_arg_string) +{ + int i = 0; + + if (!g_tss_sym_initialized) { + tss_sym_init(); + } + + TASK_ID current_tid = taskIdSelf(); + + CRYPTO_THREAD_read_lock(tss_sym_table_lock); + + /* Check if entry already added for current task */ + int existing_idx = tss_symlist_find_entry_by_tid_and_arg(current_tid, run_once_arg_string); + + if (existing_idx != ERROR) { + /* Entry already exists for this task, no need to clone */ + CRYPTO_THREAD_unlock(tss_sym_table_lock); + return; + } + + CRYPTO_THREAD_unlock(tss_sym_table_lock); + CRYPTO_THREAD_write_lock(tss_sym_table_lock); + + /* Find entries with matching run_once_arg_str */ + while (i < MAX_TSS_SYM_ENTRY) { + if (tss_sym_table[i].state != TSS_SYMLIST_STATE_INVALID && + tss_sym_table[i].taskid == tid && + strncmp(tss_sym_table[i].run_once_arg_str, run_once_arg_string, MAX_STR_LEN) == 0) { + tss_create_and_update_table(tss_sym_table[i].tss_key, + tss_sym_table[i].tss_key_name, + run_once_arg_string); + } + i++; + } + + CRYPTO_THREAD_unlock(tss_sym_table_lock); + +} + +/* De-initialize the TSS symbol table */ +int +tss_sym_deinit(void) +{ + int i; + + if (!g_tss_sym_initialized) + return OK; + + /* Acquire write lock before tearing down */ + if (!CRYPTO_THREAD_write_lock(tss_sym_table_lock)) + return ERROR; + + /* Free any remaining entries */ + for (i = 0; i < MAX_TSS_SYM_ENTRY; i++) { + tss_entry_t *entry = NULL; + + if (tss_sym_table[i].state == TSS_SYMLIST_STATE_INVALID) + continue; + + /* If tss_key points to a slot, clear it */ + if (tss_sym_table[i].tss_key) { + entry = (tss_entry_t *)(*tss_sym_table[i].tss_key); + if (entry) { + if (entry->dtor) + entry->dtor(entry->var); + free(entry); + *tss_sym_table[i].tss_key = (tss_t)0; /* clear slot */ + } + tss_sym_table[i].tss_key = NULL; + } + + memset(&tss_sym_table[i], 0, sizeof(tss_sym_entry)); + tss_sym_table[i].state = TSS_SYMLIST_STATE_INVALID; + } + + CRYPTO_THREAD_unlock(tss_sym_table_lock); + + /* Free the lock */ + CRYPTO_THREAD_lock_free(tss_sym_table_lock); + tss_sym_table_lock = NULL; + + /* Remove cleanup hook from task delete chain */ + taskDeleteHookDelete((FUNCPTR)tss_symlist_task_cleanup_hook); + + g_tss_sym_initialized = 0; + + return OK; +} +