Re: [PATCH v2] libdl: Add support to import base image TLS symbols
ok On Wed, Aug 16, 2023 at 9:00 PM wrote: > > From: Chris Johns > > This change requires an rtems-tools update for symbol generation. > > Working architectures: > - aarch64 > - arm > - powerpc > - sparc > > No newlib TLS support but checked: > - i386 > - m69k > > Updates #4920 > --- > cpukit/include/rtems/rtl/rtl-sym.h | 26 - > cpukit/include/rtems/rtl/rtl.h | 8 +- > 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 | 154 - > cpukit/libdl/rtl-sym.c | 40 ++-- > cpukit/libdl/rtl-tls.c | 114 + > cpukit/libdl/rtl-tls.h | 51 ++ > cpukit/libdl/rtl.c | 8 +- > spec/build/cpukit/objdl.yml| 1 + > testsuites/libtests/dl11/dl-load.c | 27 - > 13 files changed, 418 insertions(+), 58 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..3502b303b8 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_rtl_tls_offset_func)(void); > + > +/** > + * A TLS symbol offset entry. It is used with an exported symbol table > + * to find a TSL table offset for a variable at runtime. > + */ > +typedef struct rtems_rtl_tls_offset > +{ > + size_tindex; /** exported symbol table index */ > + rtems_rtl_tls_offset_func offset; /** TLS offset function */ > +} rtems_rtl_tls_offset; > + > /** > * Open a symbol table with the specified number of buckets. > * > @@ -101,10 +117,14 @@ 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. > */ > -bool rtems_rtl_symbol_global_add (rtems_rtl_obj* obj, > - const unsigned char* esyms, > - unsigned int size); > +bool rtems_rtl_symbol_global_add (rtems_rtl_obj*obj, > + const unsigned char* esyms, > + unsigned int size, > + rtems_rtl_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..bd3dce588a 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. > */ > -void rtems_rtl_base_sym_global_add (const unsigned char* esyms, > -unsigned int count); > +void rtems_rtl_base_sym_global_add (const unsigned char* esyms, > +unsigned int count, > +rtems_rtl_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
[PATCH v2] libdl: Add support to import base image TLS symbols
From: Chris Johns This change requires an rtems-tools update for symbol generation. Working architectures: - aarch64 - arm - powerpc - sparc No newlib TLS support but checked: - i386 - m69k Updates #4920 --- cpukit/include/rtems/rtl/rtl-sym.h | 26 - cpukit/include/rtems/rtl/rtl.h | 8 +- 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 | 154 - cpukit/libdl/rtl-sym.c | 40 ++-- cpukit/libdl/rtl-tls.c | 114 + cpukit/libdl/rtl-tls.h | 51 ++ cpukit/libdl/rtl.c | 8 +- spec/build/cpukit/objdl.yml| 1 + testsuites/libtests/dl11/dl-load.c | 27 - 13 files changed, 418 insertions(+), 58 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..3502b303b8 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_rtl_tls_offset_func)(void); + +/** + * A TLS symbol offset entry. It is used with an exported symbol table + * to find a TSL table offset for a variable at runtime. + */ +typedef struct rtems_rtl_tls_offset +{ + size_tindex; /** exported symbol table index */ + rtems_rtl_tls_offset_func offset; /** TLS offset function */ +} rtems_rtl_tls_offset; + /** * Open a symbol table with the specified number of buckets. * @@ -101,10 +117,14 @@ 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. */ -bool rtems_rtl_symbol_global_add (rtems_rtl_obj* obj, - const unsigned char* esyms, - unsigned int size); +bool rtems_rtl_symbol_global_add (rtems_rtl_obj*obj, + const unsigned char* esyms, + unsigned int size, + rtems_rtl_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..bd3dce588a 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. */ -void rtems_rtl_base_sym_global_add (const unsigned char* esyms, -unsigned int count); +void rtems_rtl_base_sym_global_add (const unsigned char* esyms, +unsigned int count, +rtems_rtl_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