On Mon, Aug 14, 2023 at 10:05 PM <chr...@rtems.org> wrote: > > From: Chris Johns <chr...@rtems.org> > > This change requires an rtems-tools update for symbol generation. > > Working architectures: > - aarch64 > - arm > - powerpc > - sparc > > Updates #4920 > --- > cpukit/include/rtems/rtl/rtl-sym.h | 23 ++++- > cpukit/include/rtems/rtl/rtl.h | 6 +- > cpukit/libdl/rtl-elf.c | 20 +++- > cpukit/libdl/rtl-mdreloc-aarch64.c | 6 +- > cpukit/libdl/rtl-mdreloc-arm.c | 3 +- > cpukit/libdl/rtl-mdreloc-powerpc.c | 18 +++- > cpukit/libdl/rtl-mdreloc-sparc.c | 152 ++++++++++++++++++++++++----- > cpukit/libdl/rtl-sym.c | 36 ++++++- > cpukit/libdl/rtl-tls.c | 111 +++++++++++++++++++++ > cpukit/libdl/rtl-tls.h | 51 ++++++++++ > cpukit/libdl/rtl.c | 6 +- > spec/build/cpukit/objdl.yml | 1 + > testsuites/libtests/dl11/dl-load.c | 27 ++++- > 13 files changed, 408 insertions(+), 52 deletions(-) > create mode 100644 cpukit/libdl/rtl-tls.c > create mode 100644 cpukit/libdl/rtl-tls.h > > diff --git a/cpukit/include/rtems/rtl/rtl-sym.h > b/cpukit/include/rtems/rtl/rtl-sym.h > index 0d29a6ae40..9eef9a1b7b 100644 > --- a/cpukit/include/rtems/rtl/rtl-sym.h > +++ b/cpukit/include/rtems/rtl/rtl-sym.h > @@ -62,6 +62,22 @@ typedef struct rtems_rtl_symbols > size_t nbuckets; > } rtems_rtl_symbols; > > +/** > + * A TLS variable offset call. There is one per base image TLS > + * variable. > + */ > +typedef size_t (*rtems_tls_offset_func)(void); > + rtems_tls_xxx is a new naming prefix. Is this stuff only specific to rtl? should be rtems_rtl_tls_...?
or, do we need to add a new tls header file and interface for this stuff, in case it would be needed outside of the rtl? > +/** > + * A TLS symbol offset entry. It is used with an exported symbol table > + * to find a TSL table offset for a variable at runtime. s/TSL/TLS > + */ > +typedef struct rtems_tls_offset > +{ > + size_t index; /** exported symbol table index */ > + rtems_tls_offset_func offset; /** TLS offset function */ > +} rtems_tls_offset; > + > /** > * Open a symbol table with the specified number of buckets. > * > @@ -101,10 +117,15 @@ void rtems_rtl_symbol_table_close (rtems_rtl_symbols* > symbols); > * @param obj The object table the symbols are for. > * @param esyms The exported symbol table. > * @param size The size of the table in bytes. > + * @param tls_offsets The TLS offsets table. If NULL none provided. > + * @param tls_size The number TLS offset entries in the table.. two periods, "number of" > + extra blank line > */ > bool rtems_rtl_symbol_global_add (rtems_rtl_obj* obj, > const unsigned char* esyms, > - unsigned int size); > + unsigned int size, > + rtems_tls_offset* tls_offsets, > + unsigned int tls_size); > > /** > * Find a symbol given the symbol label in the global symbol table. > diff --git a/cpukit/include/rtems/rtl/rtl.h b/cpukit/include/rtems/rtl/rtl.h > index 0fd4e74cdf..aaaeb7b592 100644 > --- a/cpukit/include/rtems/rtl/rtl.h > +++ b/cpukit/include/rtems/rtl/rtl.h > @@ -393,9 +393,13 @@ bool rtems_rtl_path_prepend (const char* path); > * > * @param esyms The exported symbol table. > * @param count The size of the exported symbol table. > + * @param tls_offsets The TLS offsets table. If NULL none provided. > + * @param tls_size The number TLS offset entries in the table.. two periods > */ > void rtems_rtl_base_sym_global_add (const unsigned char* esyms, > - unsigned int count); > + unsigned int count, > + rtems_tls_offset* tls_offsets, > + unsigned int tls_size); > > /** > * Return the object file descriptor for the base image. The object file > diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c > index 5754070518..b46d2ac3a0 100644 > --- a/cpukit/libdl/rtl-elf.c > +++ b/cpukit/libdl/rtl-elf.c > @@ -178,12 +178,19 @@ rtems_rtl_elf_find_symbol (rtems_rtl_obj* obj, > > /* > * If the symbol type is STT_NOTYPE the symbol references a global > - * symbol. The gobal symbol table is searched to find it and that value > + * symbol. The global symbol table is searched to find it and that value > * returned. If the symbol is local to the object module the section for > the > * symbol is located and it's base added to the symbol's value giving an > * absolute location. > + * > + * If the symbols type of TLS return the symbols value. It is the > + * offset from the thread's TLS area base. The offset is set by the > + * linker for the base image and by the TLS allocator for loaded > + * modules. There is no section and no absolute base. > */ > - if (ELF_ST_TYPE(sym->st_info) == STT_NOTYPE || sym->st_shndx == SHN_COMMON) > + if (ELF_ST_TYPE (sym->st_info) == STT_NOTYPE || > + sym->st_shndx == SHN_COMMON || > + ELF_ST_TYPE (sym->st_info) == STT_TLS) > { > /* > * Search the object file then the global table for the symbol. > @@ -246,6 +253,13 @@ rtems_rtl_elf_reloc_parser (rtems_rtl_obj* obj, > rtems_rtl_word rel_words[3]; > rtems_rtl_elf_rel_status rs; > > + /* > + * TLS are not parsed. > + */ > + if (ELF_ST_TYPE (sym->st_info) == STT_TLS) { > + return true; > + } > + > /* > * Check the reloc record to see if a trampoline is needed. > */ > @@ -302,7 +316,7 @@ rtems_rtl_elf_reloc_parser (rtems_rtl_obj* obj, > * Find the symbol's object file. It cannot be NULL so ignore that result > * if returned, it means something is corrupted. We are in an iterator. > */ > - rtems_rtl_obj* sobj = rtems_rtl_find_obj_with_symbol (symbol); > + rtems_rtl_obj* sobj = rtems_rtl_find_obj_with_symbol (symbol); > if (sobj != NULL) > { > /* > diff --git a/cpukit/libdl/rtl-mdreloc-aarch64.c > b/cpukit/libdl/rtl-mdreloc-aarch64.c > index 15396c3de9..3b808f6667 100644 > --- a/cpukit/libdl/rtl-mdreloc-aarch64.c > +++ b/cpukit/libdl/rtl-mdreloc-aarch64.c > @@ -309,11 +309,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, > } > > if (!parsing) { > - target = (Elf_Addr)symvalue + rela->r_addend; > - /* Calculate offset accounting for the DTV */ > - target -= (uintptr_t)_TLS_Data_begin; > - target += sizeof(TLS_Dynamic_thread_vector); > - > + target = (Elf_Addr)symvalue; > target >>= shift; > target &= WIDTHMASK(12); > if (of_check && target >= of_check) { > diff --git a/cpukit/libdl/rtl-mdreloc-arm.c b/cpukit/libdl/rtl-mdreloc-arm.c > index fbfd42dc58..b45708dd46 100644 > --- a/cpukit/libdl/rtl-mdreloc-arm.c > +++ b/cpukit/libdl/rtl-mdreloc-arm.c > @@ -526,7 +526,6 @@ rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj, > break; > > case R_TYPE(TLS_LE32): > -#if ALLOW_UNTESTED_RELOCS > if (!parsing) { > addend = *where; > *where = symvalue + addend; > @@ -535,7 +534,7 @@ rtems_rtl_elf_reloc_rel (rtems_rtl_obj* obj, > (void *)*where, where, rtems_rtl_obj_oname (obj)); > } > break; > -#endif > + > case R_TYPE(TLS_GD32): > case R_TYPE(TLS_LDM32): > case R_TYPE(TLS_LDO32): > diff --git a/cpukit/libdl/rtl-mdreloc-powerpc.c > b/cpukit/libdl/rtl-mdreloc-powerpc.c > index c6062c872a..49ed9e848c 100644 > --- a/cpukit/libdl/rtl-mdreloc-powerpc.c > +++ b/cpukit/libdl/rtl-mdreloc-powerpc.c > @@ -348,37 +348,47 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, > break; > > case R_TYPE(16_HA): > + case R_TYPE(TPREL16_HA): > /* > * value:6; Field:half16; Expression: #ha(S+A) > + * value:72; Field:half16; Expression: #ha(S+A) > */ > if (!parsing) { > tmp = symvalue + rela->r_addend; > *(uint16_t *)where = (((tmp >> 16) + ((tmp & 0x8000) ? 1: 0)) & > 0xffff); > if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) > - printf ("rtl: 16_HA %p @ %p in %s\n", > + printf ("rtl: %s16_HA %p @ %p in %s\n", > + ELF_R_TYPE(rela->r_info) == R_TYPE(TPREL16_HA) ? "TPREL" : > "", > (void *)*(where), where, rtems_rtl_obj_oname (obj)); > } > break; > > case R_TYPE(16_HI): > + case R_TYPE(TPREL16_HI): > /* > * value:5; Field:half16; Expression: #hi(S+A) > + * value:71; Field:half16; Expression: #hi(S+A) > */ > if (!parsing) { > *(uint16_t *)where = ((symvalue + rela->r_addend) >> 16) & 0xffff; > if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) > - printf ("rtl: 16_HI %p @ %p in %s\n", > + printf ("rtl: %s16_HI %p @ %p in %s\n", > + ELF_R_TYPE(rela->r_info) == R_TYPE(TPREL16_HI) ? "TPREL" : > "", > (void *)*where, where, rtems_rtl_obj_oname (obj)); > } > break; > + > case R_TYPE(16_LO): > + case R_TYPE(TPREL16_LO): > /* > * value:4; Field:half16; Expression: #lo(S+A) > + * value:71; Field:half16; Expression: #lo(S+A) > */ > if (!parsing) { > *(uint16_t *)where = (symvalue + (rela->r_addend)) & 0xffff; > if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) > - printf ("rtl: 16_LO %p @ %p in %s\n", > + printf ("rtl: %s16_LO %p @ %p in %s\n", > + ELF_R_TYPE(rela->r_info) == R_TYPE(TPREL16_LO) ? "TPREL" : > "", > (void *)*where, where, rtems_rtl_obj_oname (obj)); > } > break; > @@ -484,7 +494,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj* obj, > (void *)rela->r_offset, (void *)*where); > rtems_rtl_set_error (EINVAL, > "%s: Unsupported relocation type %" PRId32 > - "in non-PLT relocations", > + " in non-PLT relocations", > sect->name, (uint32_t) ELF_R_TYPE(rela->r_info)); > return rtems_rtl_elf_rel_failure; > } > diff --git a/cpukit/libdl/rtl-mdreloc-sparc.c > b/cpukit/libdl/rtl-mdreloc-sparc.c > index f8a4312a8a..00fb346a72 100644 > --- a/cpukit/libdl/rtl-mdreloc-sparc.c > +++ b/cpukit/libdl/rtl-mdreloc-sparc.c > @@ -87,46 +87,66 @@ static const uint32_t reloc_target_flags[] = { > _RF_G| _RF_SZ(32) | _RF_RS(10), /* GOT22 */ > _RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(0), /* PC10 */ > _RF_S|_RF_A|_RF_P| _RF_SZ(32) | _RF_RS(10), /* PC22 */ > - _RF_A|_RF_P| _RF_SZ(32) | _RF_RS(2), /* WPLT30 */ > - _RF_SZ(32) | _RF_RS(0), /* COPY */ > + _RF_A|_RF_P| _RF_SZ(32) | _RF_RS(2), /* WPLT30 */ > + _RF_SZ(32) | _RF_RS(0), /* COPY */ > _RF_S|_RF_A| _RF_SZ(32) | _RF_RS(0), /* GLOB_DAT */ > - _RF_SZ(32) | _RF_RS(0), /* JMP_SLOT */ > - _RF_A| _RF_B|_RF_SZ(32) | _RF_RS(0), /* RELATIVE */ > - _RF_S|_RF_A| _RF_U|_RF_SZ(32) | _RF_RS(0), /* UA_32 */ > + _RF_SZ(32) | _RF_RS(0), /* JMP_SLOT */ > + _RF_A| _RF_B| _RF_SZ(32) | _RF_RS(0), /* RELATIVE */ > + _RF_S|_RF_A|_RF_U| _RF_SZ(32) | _RF_RS(0), /* UA_32 */ > + > + /* TLS and 64 bit relocs not listed here... */ > }; > +#define RELOC_TARGET_FLAGS_SIZE \ > + (sizeof(reloc_target_flags) / sizeof(reloc_target_flags[0])) > > -#define NOT_CURRENTLY_USED_BUT_MAYBE_USEFUL > -#ifdef NOT_CURRENTLY_USED_BUT_MAYBE_USEFUL > +#define RTLD_DEBUG_RELOC > +#ifdef RTLD_DEBUG_RELOC > static const char *reloc_names[] = { > "NONE", "RELOC_8", "RELOC_16", "RELOC_32", "DISP_8", > "DISP_16", "DISP_32", "WDISP_30", "WDISP_22", "HI22", > "22", "13", "LO10", "GOT10", "GOT13", > "GOT22", "PC10", "PC22", "WPLT30", "COPY", > - "GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32" > + "GLOB_DAT", "JMP_SLOT", "RELATIVE", "UA_32", > + > + /* not used with 32bit userland, besides a few of the TLS ones */ > + "PLT32", > + "HIPLT22", "LOPLT10", "LOPLT10", "PCPLT22", "PCPLT32", > + "10", "11", "64", "OLO10", "HH22", > + "HM10", "LM22", "PC_HH22", "PC_HM10", "PC_LM22", > + "WDISP16", "WDISP19", "GLOB_JMP", "7", "5", "6", > + "DISP64", "PLT64", "HIX22", "LOX10", "H44", "M44", > + "L44", "REGISTER", "UA64", "UA16", > + "TLS_GD_HI22", "TLS_GD_LO10", "TLS_GD_ADD", "TLS_GD_CALL", > + "TLS_LDM_HI22", "TLS_LDM_LO10", "TLS_LDM_ADD", "TLS_LDM_CALL", > + "TLS_LDO_HIX22", "TLS_LDO_LOX10", "TLS_LDO_ADD", "TLS_IE_HI22", > + "TLS_IE_LO10", "TLS_IE_LD", "TLS_IE_LDX", "TLS_IE_ADD", "TLS_LE_HIX22", > + "TLS_LE_LOX10", "TLS_DTPMOD32", "TLS_DTPMOD64", "TLS_DTPOFF32", > + "TLS_DTPOFF64", "TLS_TPOFF32", "TLS_TPOFF64", > }; > #endif > > -#define RELOC_RESOLVE_SYMBOL(t) ((reloc_target_flags[t] & _RF_S) != 0) > -#define RELOC_PC_RELATIVE(t) ((reloc_target_flags[t] & _RF_P) != 0) > -#define RELOC_BASE_RELATIVE(t) ((reloc_target_flags[t] & _RF_B) != 0) > -#define RELOC_UNALIGNED(t) ((reloc_target_flags[t] & _RF_U) != 0) > -#define RELOC_USE_ADDEND(t) ((reloc_target_flags[t] & _RF_A) != 0) > -#define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff) > -#define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff) > +#define RELOC_RESOLVE_SYMBOL(t) ((reloc_target_flags[t] & _RF_S) != > 0) > +#define RELOC_PC_RELATIVE(t) ((reloc_target_flags[t] & _RF_P) != > 0) > +#define RELOC_BASE_RELATIVE(t) ((reloc_target_flags[t] & _RF_B) != > 0) > +#define RELOC_UNALIGNED(t) ((reloc_target_flags[t] & _RF_U) != > 0) > +#define RELOC_USE_ADDEND(t) ((reloc_target_flags[t] & _RF_A) != > 0) > +#define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff) > +#define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff) > +#define RELOC_TLS(t) (t >= R_TYPE(TLS_GD_HI22)) > > static const int reloc_target_bitmask[] = { > #define _BM(x) (~(-(1ULL << (x)))) > - 0, /* NONE */ > - _BM(8), _BM(16), _BM(32), /* RELOC_8, _16, _32 */ > - _BM(8), _BM(16), _BM(32), /* DISP8, DISP16, DISP32 */ > - _BM(30), _BM(22), /* WDISP30, WDISP22 */ > - _BM(22), _BM(22), /* HI22, _22 */ > - _BM(13), _BM(10), /* RELOC_13, _LO10 */ > - _BM(10), _BM(13), _BM(22), /* GOT10, GOT13, GOT22 */ > - _BM(10), _BM(22), /* _PC10, _PC22 */ > - _BM(30), 0, /* _WPLT30, _COPY */ > - -1, -1, -1, /* _GLOB_DAT, JMP_SLOT, _RELATIVE */ > - _BM(32) /* _UA32 */ > + 0, /* NONE */ > + _BM(8), _BM(16), _BM(32), /* RELOC_8, _16, _32 */ > + _BM(8), _BM(16), _BM(32), /* DISP8, DISP16, DISP32 */ > + _BM(30), _BM(22), /* WDISP30, WDISP22 */ > + _BM(22), _BM(22), /* HI22, _22 */ > + _BM(13), _BM(10), /* RELOC_13, _LO10 */ > + _BM(10), _BM(13), _BM(22), /* GOT10, GOT13, GOT22 */ > + _BM(10), _BM(22), /* _PC10, _PC22 */ > + _BM(30), 0, /* _WPLT30, _COPY */ > + -1, -1, -1, /* _GLOB_DAT, JMP_SLOT, _RELATIVE */ > + _BM(32) /* _UA32 */ > #undef _BM > }; > #define RELOC_VALUE_BITMASK(t) (reloc_target_bitmask[t]) > @@ -173,7 +193,20 @@ rtems_rtl_elf_arch_section_free (const rtems_rtl_obj* > obj, > bool > rtems_rtl_elf_rel_resolve_sym (Elf_Word type) > { > - return RELOC_RESOLVE_SYMBOL (type) ? true : false; > + bool r = false; > + if (type < RELOC_TARGET_FLAGS_SIZE) { > + r = RELOC_RESOLVE_SYMBOL (type) ? true : false; > + } > + switch (type) { > + case R_TYPE(TLS_DTPOFF32): > + case R_TYPE(TLS_LE_HIX22): > + case R_TYPE(TLS_LE_LOX10): > + r = true; > + break; > + default: > + break; > + } > + return r; > } > > size_t > @@ -240,6 +273,71 @@ rtems_rtl_elf_relocate_rela (rtems_rtl_obj* > obj, > > value = rela->r_addend; > > + /* > + * Handle TLS relocations here, they are different. > + */ > + if (RELOC_TLS(type)) { > + switch (type) { > + case R_TYPE(TLS_DTPMOD32): > + /* *where = (Elf_Addr)defobj->tlsindex; */ commented code > + > + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) > + printf("rtl: reloc: TLS_DTPMOD32 %s in %s --> %p\n", > + symname, rtems_rtl_obj_oname (obj), (void *)*where); > + break; > + > + case R_TYPE(TLS_DTPOFF32): > + *where = (Elf_Addr)(symvalue + rela->r_addend); > + > + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) > + printf("rtl: reloc: TLS_DTPOFF32 %s in %s --> %p\n", > + symname, rtems_rtl_obj_oname (obj), (void *)*where); > + break; > + > + case R_TYPE(TLS_TPOFF32): > + /* > + if (!defobj->tls_static && > + _rtld_tls_offset_allocate(__UNCONST(defobj))) > + return ; > + > + *where = (Elf_Addr)(def->st_value - > + defobj->tlsoffset + rela->r_addend); > + */ ditto > + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) > + printf("rtl: reloc: TLS_TPOFF32 %s in %s --> %p\n", > + symname, rtems_rtl_obj_oname (obj), (void *)*where); > + return rtems_rtl_elf_rel_failure; > + > + case R_TYPE(TLS_LE_HIX22): > + *where |= ((symvalue + rela->r_addend) ^ 0xffffffff) >> 10; > + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) > + printf("rtl: reloc: R_SPARC_TLS_LE_HIX22 %s in %s --> %p\n", > + symname, rtems_rtl_obj_oname (obj), (void *)*where); > + break; > + > + case R_TYPE(TLS_LE_LOX10): > + *where |= ((symvalue + rela->r_addend) & 0x3ff) | 0x1c00; > + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) > + printf("rtl: reloc: R_SPARC_TLS_LE_LOX10 %s in %s --> %p\n", > + symname, rtems_rtl_obj_oname (obj), (void *)*where); > + break; > + > + default: > + if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) > + printf("rtl: reloc: unknown TLS relo: %d for %s in %s --> %p\n", > + type, symname, rtems_rtl_obj_oname (obj), (void *)*where); > + return rtems_rtl_elf_rel_failure; > + } > + return rtems_rtl_elf_rel_no_error; > + } > + > + /* > + * If it is no TLS relocation (handled above), we can not > + * deal with it if it is beyond R_SPARC_6. > + */ > + if (type > R_TYPE(6)) > + return (-1); casting an enum type failure from an int probably use rtems_rtl_elf_rel_failure ? > + > /* > * Handle relative relocs here, as an optimization. > */ > diff --git a/cpukit/libdl/rtl-sym.c b/cpukit/libdl/rtl-sym.c > index 5c9c3981df..32b6224612 100644 > --- a/cpukit/libdl/rtl-sym.c > +++ b/cpukit/libdl/rtl-sym.c > @@ -77,6 +77,22 @@ rtems_rtl_symbol_global_insert (rtems_rtl_symbols* symbols, > &symbol->node); > } > > +static rtems_tls_offset* > +rtems_rtl_symbol_find_tsl_offset (size_t index, s/tsl/tls > + rtems_tls_offset* tls_offsets, > + size_t tls_size) > +{ > + size_t entry; > + for (entry = 0; entry < tls_size; ++entry) > + { > + if (tls_offsets[entry].index == index) > + { > + return &tls_offsets[entry]; > + } > + } > + return NULL; > +} > + > bool > rtems_rtl_symbol_table_open (rtems_rtl_symbols* symbols, > size_t buckets) > @@ -105,7 +121,9 @@ rtems_rtl_symbol_table_close (rtems_rtl_symbols* symbols) > bool > rtems_rtl_symbol_global_add (rtems_rtl_obj* obj, > const unsigned char* esyms, > - unsigned int size) > + unsigned int size, > + rtems_tls_offset* tls_offsets, > + unsigned int tls_size) > { > rtems_rtl_symbols* symbols; > rtems_rtl_obj_sym* sym; > @@ -159,6 +177,9 @@ rtems_rtl_symbol_global_add (rtems_rtl_obj* obj, > > symbols = rtems_rtl_global_symbols (); > > + obj->global_syms = count; > + > + count = 0; > s = 0; > sym = obj->global_table; > > @@ -171,24 +192,29 @@ rtems_rtl_symbol_global_add (rtems_rtl_obj* obj, > */ > union { > uint8_t data[sizeof (void*)]; > - void* value; > + void* voidp; > } copy_voidp; > + rtems_tls_offset* tls_off; > int b; > > sym->name = (const char*) &esyms[s]; > s += strlen (sym->name) + 1; > for (b = 0; b < sizeof (void*); ++b, ++s) > copy_voidp.data[b] = esyms[s]; > - sym->value = copy_voidp.value; > + tls_off = rtems_rtl_symbol_find_tsl_offset (count, tls_offsets, > tls_size); ditto > + if (tls_off == NULL) { > + sym->value = copy_voidp.voidp; > + } else { > + sym->value = (void*) tls_off->offset(); > + } > if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM)) > printf ("rtl: esyms: %s -> %8p\n", sym->name, sym->value); > if (rtems_rtl_symbol_global_find (sym->name) == NULL) > rtems_rtl_symbol_global_insert (symbols, sym); > + ++count; > ++sym; > } > > - obj->global_syms = count; > - > return true; > } > > diff --git a/cpukit/libdl/rtl-tls.c b/cpukit/libdl/rtl-tls.c > new file mode 100644 > index 0000000000..570190617e > --- /dev/null > +++ b/cpukit/libdl/rtl-tls.c > @@ -0,0 +1,111 @@ > +/* SPDX-License-Identifier: BSD-2-Clause */ > + > +/** > + * @file > + * > + * @ingroup rtems_rtld > + * > + * @brief RTEMS Run-Time Link Editor Thread Local Storage > + * > + * TSL support the RTL. TLS support for > + */ > + > +/* > + * COPYRIGHT (c) 2023 Chris Johns <chr...@rtems.org> > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifdef HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include "rtl-tls.h" > + > +/* > + * The cpukit/score should provide a call for any arch that > + * supports TLS. This code is here until that happens if it > + * happens. > + */ this definitely implies that we should have a TLS set of interfaces > + > +/* > + * Pasted in from: Maybe, put this in its own include file that you add here? > + * > + * > https://android.googlesource.com/platform/bionic/+/refs/heads/main/libc/platform/bionic/tls.h > + * > + * Note, "#pragma once" has been removed > + */ > +/* > + * Copyright (C) 2008 The Android Open Source Project > + * All rights reserved. > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * * Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * * Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in > + * the documentation and/or other materials provided with the > + * distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS > + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT > + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS > + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE > + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, > + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, > + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS > + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED > + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, > + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT > + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF > + * SUCH DAMAGE. > + */ > +#if defined(__aarch64__) > +# define __get_tls() ({ void** __val; __asm__("mrs %0, tpidr_el0" : > "=r"(__val)); __val; }) > +#elif defined(__arm__) > +# define __get_tls() ({ void** __val; __asm__("mrc p15, 0, %0, c13, c0, 3" : > "=r"(__val)); __val; }) > +#elif defined(__i386__) > +# define __get_tls() ({ void** __val; __asm__("movl %%gs:0, %0" : > "=r"(__val)); __val; }) > +#elif defined(__riscv) > +# define __get_tls() ({ void** __val; __asm__("mv %0, tp" : "=r"(__val)); > __val; }) > +#elif defined(__x86_64__) > +# define __get_tls() ({ void** __val; __asm__("mov %%fs:0, %0" : > "=r"(__val)); __val; }) > +#elif defined(__sparc__) > +#include <stdint.h> > +# define __get_tls() ({ void** __val; register uintptr_t g7 __asm__( "g7" ); > __val = (void**) g7; __val; }) > +#elif defined(__powerpc__) > +#include <stdint.h> > +# define __get_tls() ({ void** __val; register uintptr_t tp __asm__( "2" ); > __val = (void**) tp; __val; }) > +#else > +#error unsupported architecture > +#endif > + > +#if defined(__get_tls) > + > +void* rtems_rtl_tls_get_base (void) > +{ > + return (void*) __get_tls(); > +} > + > +#endif > diff --git a/cpukit/libdl/rtl-tls.h b/cpukit/libdl/rtl-tls.h > new file mode 100644 > index 0000000000..a56764ac46 > --- /dev/null > +++ b/cpukit/libdl/rtl-tls.h > @@ -0,0 +1,51 @@ > +/* SPDX-License-Identifier: BSD-2-Clause */ > + > +/** > + * @file > + * > + * @ingroup rtems_rtld > + * > + * @brief RTEMS Run-Time Link Editor Thread Local Storage > + * > + * TSL support the RTL. TLS support for > + */ > + > +/* > + * COPYRIGHT (c) 2023 Chris Johns <chr...@rtems.org> > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#if !defined (_RTEMS_RTL_TLS_H_) > +#define _RTEMS_RTL_TLS_H_ > + > +#ifdef __cplusplus > +extern "C" { > +#endif /* __cplusplus */ > + > +void* rtems_rtl_tls_get_base (void); > + > +#ifdef __cplusplus > +} > +#endif /* __cplusplus */ > + > +#endif > diff --git a/cpukit/libdl/rtl.c b/cpukit/libdl/rtl.c > index 21ddb00aac..14de511771 100644 > --- a/cpukit/libdl/rtl.c > +++ b/cpukit/libdl/rtl.c > @@ -858,7 +858,9 @@ rtems_rtl_path_prepend (const char* path) > > void > rtems_rtl_base_sym_global_add (const unsigned char* esyms, > - unsigned int size) > + unsigned int size, > + rtems_tls_offset* tls_offsets, > + unsigned int tls_size) > { > if (rtems_rtl_trace (RTEMS_RTL_TRACE_GLOBAL_SYM)) > printf ("rtl: adding global symbols, table size %u\n", size); > @@ -869,7 +871,7 @@ rtems_rtl_base_sym_global_add (const unsigned char* esyms, > return; > } > > - rtems_rtl_symbol_global_add (rtl->base, esyms, size); > + rtems_rtl_symbol_global_add (rtl->base, esyms, size, tls_offsets, > tls_size); > > rtems_rtl_unlock (); > } > diff --git a/spec/build/cpukit/objdl.yml b/spec/build/cpukit/objdl.yml > index 133485a93d..f6dc9478a6 100644 > --- a/spec/build/cpukit/objdl.yml > +++ b/spec/build/cpukit/objdl.yml > @@ -66,6 +66,7 @@ source: > - cpukit/libdl/rtl-shell.c > - cpukit/libdl/rtl-string.c > - cpukit/libdl/rtl-sym.c > +- cpukit/libdl/rtl-tls.c > - cpukit/libdl/rtl-trace.c > - cpukit/libdl/rtl-unresolved.c > - cpukit/libdl/rtl-unwind-dw2.c > diff --git a/testsuites/libtests/dl11/dl-load.c > b/testsuites/libtests/dl11/dl-load.c > index aee1517269..70d7bf1c65 100644 > --- a/testsuites/libtests/dl11/dl-load.c > +++ b/testsuites/libtests/dl11/dl-load.c > @@ -37,10 +37,17 @@ > > #define TEST_TRACE 0 > #if TEST_TRACE > + #define SHOW_GLOBAL_SYMS 1 > + #if SHOW_GLOBAL_SYMS > + #define TRACE_GLOBAL_SYMBOL RTEMS_RTL_TRACE_GLOBAL_SYM > + #else > + #define TRACE_GLOBAL_SYMBOL 0 > + #endif > #define DEBUG_TRACE (RTEMS_RTL_TRACE_DETAIL | \ > RTEMS_RTL_TRACE_WARNING | \ > RTEMS_RTL_TRACE_LOAD | \ > RTEMS_RTL_TRACE_UNLOAD | \ > + TRACE_GLOBAL_SYMBOL | \ > RTEMS_RTL_TRACE_SYMBOL | \ > RTEMS_RTL_TRACE_RELOC | \ > RTEMS_RTL_TRACE_ALLOCATOR | \ > @@ -69,6 +76,9 @@ static void dl_load_dump (void) > typedef int (*int_call_t)(void); > typedef int* (*ptr_call_t)(void); > > +void* get_errno_ptr(void); > +int get_errno(void); > + > int dl_load_test(void) > { > void* handle; > @@ -116,7 +126,7 @@ int dl_load_test(void) > } > > ptr_call_ret = ptr_call (); > - if (ptr_call_ret != &errno) > + if (ptr_call_ret != get_errno_ptr()) > { > printf("dlsym ptr_call failed: ret value bad\n"); > return 1; > @@ -124,7 +134,7 @@ int dl_load_test(void) > > errno = 12345; > int_call_ret = int_call (); > - if (int_call_ret != 12345) > + if (int_call_ret != get_errno()) > { > printf("dlsym int_call failed: ret value bad\n"); > return 1; > @@ -140,3 +150,16 @@ int dl_load_test(void) > > return 0; > } > + > +/* > + * Disasseble these to see how the platform accesses TLS > + */ > +void* get_errno_ptr(void) > +{ > + return &errno; > +} > + > +int get_errno(void) > +{ > + return errno; > +} > -- > 2.37.1 > > _______________________________________________ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel