[PATCH] [ARC] More fixes for TLS.

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] [ARC] More fixes for TLS.

cupertinomiranda
From: Cupertino Miranda <[hidden email]>

Good morning,

Just another patch for review.

Cheers,
Cupertino Miranda

Added warning for static TLS reloc.

Fixed issue related to TLS and partial static linking of libraries:
  This issue was detected when throwing exceptions in C++ while linking with
  -static-libstdc++.
  TLS relocation from the libstdc++ wasn't being patched as local now that it was
  static linked with the executable.

Fix for TLS with static and pie. Problem introduced by earlier patch:
  Fixes the following glibc tests:
   - elf/tst-tls1-static

bfd/
    xxxx-xx-xx  Cupertino Miranda  <[hidden email]>

            * arc-got.h (arc_got_entry_type_for_reloc): Changed to
              correct static TLS relocs.
            * elf32-arc.c (elf_arc_check_relocs): Introduced warning to
              TLS relocs which require -fPIC.
              (arc_create_forced_local_got_entries_for_tls): Created.
              Traverses list of GOT entries to be resolved statically
              when needed.
              (elf_arc_finish_dynamic_sections): Changed. Calls
              arc_create_forced_local_got_entries_for_tls for each known
              possibly GOT symbol.
---
 bfd/arc-got.h   |  33 +++++++++-------
 bfd/elf32-arc.c | 116 +++++++++++++++++++++++++++++++++++++++++---------------
 2 files changed, 105 insertions(+), 44 deletions(-)

diff --git a/bfd/arc-got.h b/bfd/arc-got.h
index 69e9aa3..253578b 100644
--- a/bfd/arc-got.h
+++ b/bfd/arc-got.h
@@ -208,7 +208,7 @@ arc_got_entry_type_for_reloc (reloc_howto_type *howto)
      __LINE__, name_for_global_symbol (H)); \
       } \
     if (H) \
-      if (h->dynindx == -1 && !h->forced_local) \
+      if (H->dynindx == -1 && !H->forced_local) \
  if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
   return FALSE; \
      htab->s##SECNAME->size += 4; \
@@ -284,6 +284,7 @@ relocate_fix_got_relocs_for_got_info (struct got_entry **   list_p,
   BFD_ASSERT (entry);
 
   if (h == NULL
+      || h->forced_local == TRUE
       || (! elf_hash_table (info)->dynamic_sections_created
   || (bfd_link_pic (info)
       && SYMBOL_REFERENCES_LOCAL (info, h))))
@@ -331,27 +332,31 @@ relocate_fix_got_relocs_for_got_info (struct got_entry **   list_p,
  BFD_ASSERT (tls_sec && tls_sec->output_section);
  bfd_vma sec_vma = tls_sec->output_section->vma;
 
- bfd_put_32 (output_bfd,
+ if (h == NULL || h->forced_local
+   || !elf_hash_table (info)->dynamic_sections_created)
+  {
+    bfd_put_32 (output_bfd,
     sym_value - sec_vma
     + (elf_hash_table (info)->dynamic_sections_created
        ? 0
-       : (align_power (TCB_SIZE,
+       : (align_power (0,
        tls_sec->alignment_power))),
     htab->sgot->contents + entry->offset
     + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
        ? 4 : 0));
 
- ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
-   "@ %lx, for symbol %s\n",
-   (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
-    "GOT_TLS_IE"),
-   (long) (sym_value - sec_vma),
-   (long) (htab->sgot->output_section->vma
-      + htab->sgot->output_offset
-      + entry->offset
-      + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
- ? 4 : 0)),
-   symbol_name);
+    ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
+  "@ %lx, for symbol %s\n",
+  (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
+   "GOT_TLS_IE"),
+  (long) (sym_value - sec_vma),
+  (long) (htab->sgot->output_section->vma
+     + htab->sgot->output_offset
+     + entry->offset
+     + (entry->existing_entries == TLS_GOT_MOD_AND_OFF
+ ? 4 : 0)),
+  symbol_name);
+  }
       }
       break;
 
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
index 668642c..0a98b9f 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -1989,36 +1989,35 @@ elf_arc_check_relocs (bfd * abfd,
 
       switch (r_type)
  {
-  case R_ARC_32:
-  case R_ARC_32_ME:
-    /* During shared library creation, these relocs should not
-       appear in a shared library (as memory will be read only
-       and the dynamic linker can not resolve these.  However
-       the error should not occur for e.g. debugging or
-       non-readonly sections.  */
-    if (h != NULL
- && (bfd_link_dll (info) && !bfd_link_pie (info))
- && (sec->flags & SEC_ALLOC) != 0
- && (sec->flags & SEC_READONLY) != 0
- && ((sec->flags & SEC_CODE) != 0
-    || (sec->flags & SEC_DEBUGGING) != 0))
-      {
- const char *name;
- if (h)
-  name = h->root.root.string;
- else
-  /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
-  name = "UNKNOWN";
- _bfd_error_handler
-  /* xgettext:c-format */
-  (_("%pB: relocation %s against `%s' can not be used"
-     " when making a shared object; recompile with -fPIC"),
-   abfd,
-   arc_elf_howto (r_type)->name,
-   name);
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
-      }
+ case R_ARC_32:
+ case R_ARC_32_ME:
+  /* During shared library creation, these relocs should not
+     appear in a shared library (as memory will be read only
+     and the dynamic linker can not resolve these.  However
+     the error should not occur for e.g. debugging or
+     non-readonly sections.  */
+  if (h != NULL
+      && (bfd_link_dll (info) && !bfd_link_pie (info))
+      && (sec->flags & SEC_ALLOC) != 0
+      && (sec->flags & SEC_READONLY) != 0
+      && ((sec->flags & SEC_CODE) != 0
+  || (sec->flags & SEC_DEBUGGING) != 0))
+    {
+      const char *name;
+      if (h)
+ name = h->root.root.string;
+      else
+ name = "UNKNOWN";
+      _bfd_error_handler
+      /* xgettext:c-format */
+      (_("%pB: relocation %s against `%s' can not be used"
+ " when making a shared object; recompile with -fPIC"),
+ abfd,
+ arc_elf_howto (r_type)->name,
+ name);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
 
     /* In some cases we are not setting the 'non_got_ref'
        flag, even though the relocations don't require a GOT
@@ -2068,6 +2067,25 @@ elf_arc_check_relocs (bfd * abfd,
       if (is_reloc_for_GOT (howto)
   || is_reloc_for_TLS (howto))
  {
+  if (bfd_link_dll (info) && !bfd_link_pie (info)
+      && (r_type == R_ARC_TLS_LE_32 || r_type == R_ARC_TLS_LE_S9))
+    {
+      const char *name;
+      if (h)
+        name = h->root.root.string;
+      else
+        /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
+        name = "UNKNOWN";
+      _bfd_error_handler
+        /* xgettext:c-format */
+        (_("%pB: relocation %s against `%s' can not be used"
+           " when making a shared object; recompile with -fPIC"),
+         abfd,
+         arc_elf_howto (r_type)->name,
+         name);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
   if (! _bfd_elf_create_got_section (dynobj, info))
     return FALSE;
 
@@ -2490,6 +2508,38 @@ elf_arc_finish_dynamic_symbol (bfd * output_bfd,
     s = bfd_get_linker_section (dynobj, SECTION); \
   break;
 
+
+struct obfd_info_group {
+  bfd *output_bfd;
+  struct bfd_link_info *info;
+};
+
+static bfd_boolean
+arc_create_forced_local_got_entries_for_tls (struct bfd_hash_entry *bh,
+     void *data)
+{
+  struct elf_arc_link_hash_entry * h =
+    (struct elf_arc_link_hash_entry *) bh;
+  struct obfd_info_group *tmp = (struct obfd_info_group *) data;
+
+  if (h->got_ents != NULL)
+    {
+      BFD_ASSERT (h);
+
+      struct got_entry *list = h->got_ents;
+
+      while (list != NULL)
+ {
+  create_got_dynrelocs_for_single_entry (list, tmp->output_bfd,
+ tmp->info, h);
+  list = list->next;
+ }
+    }
+
+  return TRUE;
+}
+
+
 /* Function :  elf_arc_finish_dynamic_sections
    Brief    :  Finish up the dynamic sections handling.
    Args     :  output_bfd :
@@ -2623,6 +2673,12 @@ elf_arc_finish_dynamic_sections (bfd * output_bfd,
  }
     }
 
+  struct obfd_info_group group;
+  group.output_bfd = output_bfd;
+  group.info = info;
+  bfd_hash_traverse (&info->hash->table,
+     arc_create_forced_local_got_entries_for_tls, &group);
+
   return TRUE;
 }
 
--
2.9.0

Reply | Threaded
Open this post in threaded view
|

RE: [PATCH] [ARC] More fixes for TLS.

Claudiu Zissulescu
This is ok. Please fix the GNU styling issues and commit.

Cheers,
Claudiu

> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]]
> Sent: Friday, November 09, 2018 1:25 PM
> To: [hidden email]
> Cc: [hidden email]; [hidden email];
> [hidden email]; Cupertino Miranda
> <[hidden email]>
> Subject: [PATCH] [ARC] More fixes for TLS.
>
> From: Cupertino Miranda <[hidden email]>
>
> Good morning,
>
> Just another patch for review.
>
> Cheers,
> Cupertino Miranda
>
> Added warning for static TLS reloc.
>
> Fixed issue related to TLS and partial static linking of libraries:
>   This issue was detected when throwing exceptions in C++ while linking with
>   -static-libstdc++.
>   TLS relocation from the libstdc++ wasn't being patched as local now that it
> was
>   static linked with the executable.
>
> Fix for TLS with static and pie. Problem introduced by earlier patch:
>   Fixes the following glibc tests:
>    - elf/tst-tls1-static
>
> bfd/
>     xxxx-xx-xx  Cupertino Miranda  <[hidden email]>
>
>    * arc-got.h (arc_got_entry_type_for_reloc): Changed to
>      correct static TLS relocs.
>             * elf32-arc.c (elf_arc_check_relocs): Introduced warning to
>      TLS relocs which require -fPIC.
>      (arc_create_forced_local_got_entries_for_tls): Created.
>      Traverses list of GOT entries to be resolved statically
>      when needed.
>      (elf_arc_finish_dynamic_sections): Changed. Calls
>      arc_create_forced_local_got_entries_for_tls for each known
>      possibly GOT symbol.
> ---
>  bfd/arc-got.h   |  33 +++++++++-------
>  bfd/elf32-arc.c | 116 +++++++++++++++++++++++++++++++++++++++++--
> -------------
>  2 files changed, 105 insertions(+), 44 deletions(-)
>
> diff --git a/bfd/arc-got.h b/bfd/arc-got.h
> index 69e9aa3..253578b 100644
> --- a/bfd/arc-got.h
> +++ b/bfd/arc-got.h
> @@ -208,7 +208,7 @@ arc_got_entry_type_for_reloc (reloc_howto_type
> *howto)
>       __LINE__, name_for_global_symbol (H)); \
>        } \
>      if (H) \
> -      if (h->dynindx == -1 && !h->forced_local) \
> +      if (H->dynindx == -1 && !H->forced_local) \
>   if (! bfd_elf_link_record_dynamic_symbol (info, H)) \
>    return FALSE; \
>       htab->s##SECNAME->size += 4; \
> @@ -284,6 +284,7 @@ relocate_fix_got_relocs_for_got_info (struct
> got_entry **   list_p,
>    BFD_ASSERT (entry);
>
>    if (h == NULL
> +      || h->forced_local == TRUE
>        || (! elf_hash_table (info)->dynamic_sections_created
>    || (bfd_link_pic (info)
>        && SYMBOL_REFERENCES_LOCAL (info, h))))
> @@ -331,27 +332,31 @@ relocate_fix_got_relocs_for_got_info (struct
> got_entry **   list_p,
>   BFD_ASSERT (tls_sec && tls_sec->output_section);
>   bfd_vma sec_vma = tls_sec->output_section->vma;
>
> - bfd_put_32 (output_bfd,
> + if (h == NULL || h->forced_local
> +   || !elf_hash_table (info)->dynamic_sections_created)
> +  {
> +    bfd_put_32 (output_bfd,
>      sym_value - sec_vma
>      + (elf_hash_table (info)-
> >dynamic_sections_created
>         ? 0
> -       : (align_power (TCB_SIZE,
> +       : (align_power (0,
>         tls_sec->alignment_power))),
>      htab->sgot->contents + entry->offset
>      + (entry->existing_entries ==
> TLS_GOT_MOD_AND_OFF
>         ? 4 : 0));
>
> - ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
> -   "@ %lx, for symbol %s\n",
> -   (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
> -    "GOT_TLS_IE"),
> -   (long) (sym_value - sec_vma),
> -   (long) (htab->sgot->output_section->vma
> -      + htab->sgot->output_offset
> -      + entry->offset
> -      + (entry->existing_entries ==
> TLS_GOT_MOD_AND_OFF
> - ? 4 : 0)),
> -   symbol_name);
> +    ARC_DEBUG ("arc_info: FIXED -> %s value = %#lx "
> +  "@ %lx, for symbol %s\n",
> +  (entry->type == GOT_TLS_GD ? "GOT_TLS_GD" :
> +   "GOT_TLS_IE"),
> +  (long) (sym_value - sec_vma),
> +  (long) (htab->sgot->output_section->vma
> +     + htab->sgot->output_offset
> +     + entry->offset
> +     + (entry->existing_entries ==
> TLS_GOT_MOD_AND_OFF
> + ? 4 : 0)),
> +  symbol_name);
> +  }
>        }
>        break;
>
> diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
> index 668642c..0a98b9f 100644
> --- a/bfd/elf32-arc.c
> +++ b/bfd/elf32-arc.c
> @@ -1989,36 +1989,35 @@ elf_arc_check_relocs (bfd *
> abfd,
>
>        switch (r_type)
>   {
> -  case R_ARC_32:
> -  case R_ARC_32_ME:
> -    /* During shared library creation, these relocs should not
> -       appear in a shared library (as memory will be read only
> -       and the dynamic linker can not resolve these.  However
> -       the error should not occur for e.g. debugging or
> -       non-readonly sections.  */
> -    if (h != NULL
> - && (bfd_link_dll (info) && !bfd_link_pie (info))
> - && (sec->flags & SEC_ALLOC) != 0
> - && (sec->flags & SEC_READONLY) != 0
> - && ((sec->flags & SEC_CODE) != 0
> -    || (sec->flags & SEC_DEBUGGING) != 0))
> -      {
> - const char *name;
> - if (h)
> -  name = h->root.root.string;
> - else
> -  /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
> -  name = "UNKNOWN";
> - _bfd_error_handler
> -  /* xgettext:c-format */
> -  (_("%pB: relocation %s against `%s' can not be used"
> -     " when making a shared object; recompile with -fPIC"),
> -   abfd,
> -   arc_elf_howto (r_type)->name,
> -   name);
> - bfd_set_error (bfd_error_bad_value);
> - return FALSE;
> -      }
> + case R_ARC_32:
> + case R_ARC_32_ME:
> +  /* During shared library creation, these relocs should not
> +     appear in a shared library (as memory will be read only
> +     and the dynamic linker can not resolve these.  However
> +     the error should not occur for e.g. debugging or
> +     non-readonly sections.  */
> +  if (h != NULL
> +      && (bfd_link_dll (info) && !bfd_link_pie (info))
> +      && (sec->flags & SEC_ALLOC) != 0
> +      && (sec->flags & SEC_READONLY) != 0
> +      && ((sec->flags & SEC_CODE) != 0
> +  || (sec->flags & SEC_DEBUGGING) != 0))
> +    {
> +      const char *name;
> +      if (h)
> + name = h->root.root.string;
> +      else
> + name = "UNKNOWN";
> +      _bfd_error_handler
> +      /* xgettext:c-format */
> +      (_("%pB: relocation %s against `%s' can not be used"
> + " when making a shared object; recompile with -fPIC"),
> + abfd,
> + arc_elf_howto (r_type)->name,
> + name);
> +      bfd_set_error (bfd_error_bad_value);
> +      return FALSE;
> +    }
>
>      /* In some cases we are not setting the 'non_got_ref'
>         flag, even though the relocations don't require a GOT
> @@ -2068,6 +2067,25 @@ elf_arc_check_relocs (bfd * abfd,
>        if (is_reloc_for_GOT (howto)
>    || is_reloc_for_TLS (howto))
>   {
> +  if (bfd_link_dll (info) && !bfd_link_pie (info)
> +      && (r_type == R_ARC_TLS_LE_32 || r_type ==
> R_ARC_TLS_LE_S9))
> +    {
> +      const char *name;
> +      if (h)
> +        name = h->root.root.string;
> +      else
> +        /* bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);  */
> +        name = "UNKNOWN";
> +      _bfd_error_handler
> +        /* xgettext:c-format */
> +        (_("%pB: relocation %s against `%s' can not be used"
> +           " when making a shared object; recompile with -fPIC"),
> +         abfd,
> +         arc_elf_howto (r_type)->name,
> +         name);
> +      bfd_set_error (bfd_error_bad_value);
> +      return FALSE;
> +    }
>    if (! _bfd_elf_create_got_section (dynobj, info))
>      return FALSE;
>
> @@ -2490,6 +2508,38 @@ elf_arc_finish_dynamic_symbol (bfd *
> output_bfd,
>      s = bfd_get_linker_section (dynobj, SECTION); \
>    break;
>
> +
> +struct obfd_info_group {
> +  bfd *output_bfd;
> +  struct bfd_link_info *info;
> +};
> +
> +static bfd_boolean
> +arc_create_forced_local_got_entries_for_tls (struct bfd_hash_entry *bh,
> +     void *data)
> +{
> +  struct elf_arc_link_hash_entry * h =
> +    (struct elf_arc_link_hash_entry *) bh;
> +  struct obfd_info_group *tmp = (struct obfd_info_group *) data;
> +
> +  if (h->got_ents != NULL)
> +    {
> +      BFD_ASSERT (h);
> +
> +      struct got_entry *list = h->got_ents;
> +
> +      while (list != NULL)
> + {
> +  create_got_dynrelocs_for_single_entry (list, tmp->output_bfd,
> + tmp->info, h);
> +  list = list->next;
> + }
> +    }
> +
> +  return TRUE;
> +}
> +
> +
>  /* Function :  elf_arc_finish_dynamic_sections
>     Brief    :  Finish up the dynamic sections handling.
>     Args     :  output_bfd :
> @@ -2623,6 +2673,12 @@ elf_arc_finish_dynamic_sections (bfd *
> output_bfd,
>   }
>      }
>
> +  struct obfd_info_group group;
> +  group.output_bfd = output_bfd;
> +  group.info = info;
> +  bfd_hash_traverse (&info->hash->table,
> +     arc_create_forced_local_got_entries_for_tls, &group);
> +
>    return TRUE;
>  }
>
> --
> 2.9.0