Re: [PATCH v2] libdl: Add support to import base image TLS symbols

2023-08-20 Thread Gedare Bloom
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

2023-08-16 Thread chrisj
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