Thanks for the detailed review. It is so nice to have this happen. I will post v2 soon.
On 17/8/2023 6:55 am, Gedare Bloom wrote: > 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? I will change the function call to rtems_rtl_tls_. Yes an score way to provide the base would be welcome but that is out of scope for this change. I am sorry but I have no time to invest in adding something new the score like this. >> +/** >> + * 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 I have fixed this as well. >> +{ >> + 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" Fixed > >> + > extra blank line Fixed > >> */ >> 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 Fixed > >> */ >> 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 Yes, it is present in the netbsd code but not used here yet. It is not showing up in the reloc I can see. I only see 2 types of TLS relocs in the tools libraries: $ /opt/work/rtems/6/bin/sparc-rtems6-readelf -r `find /opt/work/rtems/6/sparc-rtems6 -name \*.a` | grep TLS | sed -e 's/.*R_SPARC/R_SPARC/' -e 's/ .*//' | sort | uniq R_SPARC_TLS_LE_HI R_SPARC_TLS_LE_LO $ /opt/work/rtems/6/bin/sparc-rtems6-readelf -r `find /opt/work/rtems/6/lib/gcc/sparc-rtems6 -name \*.a` | grep TLS | sed -e 's/.*R_SPARC/R_SPARC/' -e 's/ .*//' | sort | uniq R_SPARC_TLS_LE_HI R_SPARC_TLS_LE_LO There are only 2 being used. I will place the code in an #if ... block. > >> + >> + 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 Moved to an #if block. > >> + 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 ? Thanks, this has slipped through a previous change. Fixed > >> + >> /* >> * 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 Thanks and I found another one >> + 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 Fixed > >> + 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 Fixed > > >> + */ >> + >> +/* >> + * 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 Yes I think as an OS we should provide this and if a new arch is added who ever is doing that work would be required to provide the support. >> + >> +/* >> + * Pasted in from: > Maybe, put this in its own include file that you add here? I also wondered this and then I decided we should have score support so when than happens this can go away. >> + * >> + * >> 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 Fixed Chris > >> + */ >> + >> +/* >> + * 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