powerpc TLS in PIEs
[deliverable/binutils-gdb.git] / bfd / elf32-arc.c
index b00207ed8db9db55fc7d0beadc1017bdc87561c9..cdecdb145289706caddc1b6f4e57b5dad0cd577d 100644 (file)
@@ -55,17 +55,20 @@ name_for_global_symbol (struct elf_link_hash_entry *h)
     Elf_Internal_Rela _rel;                                            \
     bfd_byte * _loc;                                                   \
                                                                        \
-    BFD_ASSERT (_htab->srel##SECTION &&_htab->srel##SECTION->contents); \
-    _loc = _htab->srel##SECTION->contents                              \
-      + ((_htab->srel##SECTION->reloc_count)                           \
-        * sizeof (Elf32_External_Rela));                               \
-    _htab->srel##SECTION->reloc_count++;                               \
-    _rel.r_addend = ADDEND;                                            \
-    _rel.r_offset = (_htab->s##SECTION)->output_section->vma           \
-      + (_htab->s##SECTION)->output_offset + OFFSET;                   \
-    BFD_ASSERT ((long) SYM_IDX != -1);                                 \
-    _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE);                                \
-    bfd_elf32_swap_reloca_out (BFD, &_rel, _loc);                      \
+    if (_htab->dynamic_sections_created == TRUE)                               \
+      {                                                                        \
+       BFD_ASSERT (_htab->srel##SECTION &&_htab->srel##SECTION->contents); \
+       _loc = _htab->srel##SECTION->contents                           \
+         + ((_htab->srel##SECTION->reloc_count)                        \
+            * sizeof (Elf32_External_Rela));                           \
+       _htab->srel##SECTION->reloc_count++;                            \
+       _rel.r_addend = ADDEND;                                         \
+       _rel.r_offset = (_htab->s##SECTION)->output_section->vma        \
+         + (_htab->s##SECTION)->output_offset + OFFSET;                \
+       BFD_ASSERT ((long) SYM_IDX != -1);                              \
+       _rel.r_info = ELF32_R_INFO (SYM_IDX, TYPE);                     \
+       bfd_elf32_swap_reloca_out (BFD, &_rel, _loc);                   \
+      }                                                                        \
   }
 
 
@@ -728,9 +731,11 @@ arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
 
        case Tag_ARC_ABI_pic:
          tagname = "PIC";
+         /* fall through */
        case Tag_ARC_ABI_sda:
          if (!tagname)
            tagname = "SDA";
+         /* fall through */
        case Tag_ARC_ABI_tls:
          {
            const char *tagval[] = { "Absent", "MWDT", "GNU" };
@@ -756,9 +761,11 @@ arc_elf_merge_attributes (bfd *ibfd, struct bfd_link_info *info)
 
        case Tag_ARC_ABI_double_size:
          tagname = "Double size";
+         /* fall through */
        case Tag_ARC_ABI_enumsize:
          if (!tagname)
            tagname = "Enum size";
+         /* fall through */
        case Tag_ARC_ABI_exceptions:
          if (!tagname)
            tagname = "ABI exceptions";
@@ -881,9 +888,9 @@ arc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
          /* Warn if different flags.  */
          _bfd_error_handler
            /* xgettext:c-format */
-           (_("%B: uses different e_flags (0x%lx) fields than "
-              "previous modules (0x%lx)"),
-            ibfd, (long) in_flags, (long) out_flags);
+           (_("%B: uses different e_flags (%#x) fields than "
+              "previous modules (%#x)"),
+            ibfd, in_flags, out_flags);
          if (in_flags && out_flags)
            return FALSE;
          /* MWDT doesnt set the eflags hence make sure we choose the
@@ -1109,26 +1116,26 @@ arc_special_overflow_checks (const struct arc_relocation_data reloc_data,
          if (reloc_data.reloc_addend == 0)
            _bfd_error_handler
              /* xgettext:c-format */
-             (_("%B(%A+0x%lx): CMEM relocation to `%s' is invalid, "
-                "16 MSB should be 0x%04x (value is 0x%lx)"),
+             (_("%B(%A+%#Lx): CMEM relocation to `%s' is invalid, "
+                "16 MSB should be %#x (value is %#Lx)"),
               reloc_data.input_section->owner,
               reloc_data.input_section,
               reloc_data.reloc_offset,
               reloc_data.symbol_name,
               NPS_CMEM_HIGH_VALUE,
-              (relocation));
+              relocation);
          else
            _bfd_error_handler
              /* xgettext:c-format */
-             (_("%B(%A+0x%lx): CMEM relocation to `%s+0x%lx' is invalid, "
-                "16 MSB should be 0x%04x (value is 0x%lx)"),
+             (_("%B(%A+%#Lx): CMEM relocation to `%s+%#Lx' is invalid, "
+                "16 MSB should be %#x (value is %#Lx)"),
               reloc_data.input_section->owner,
               reloc_data.input_section,
               reloc_data.reloc_offset,
               reloc_data.symbol_name,
               reloc_data.reloc_addend,
               NPS_CMEM_HIGH_VALUE,
-              (relocation));
+              relocation);
          return bfd_reloc_overflow;
        }
       break;
@@ -1175,12 +1182,11 @@ arc_special_overflow_checks (const struct arc_relocation_data reloc_data,
             + (reloc_data.reloc_offset))))
 #define SECTSTART (bfd_signed_vma) (reloc_data.sym_section->output_section->vma \
                                    + reloc_data.sym_section->output_offset)
-
+#define JLI (bfd_signed_vma) (reloc_data.sym_section->output_section->vma)
 #define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
 #define TLS_REL (bfd_signed_vma) \
   ((elf_hash_table (info))->tls_sec->output_section->vma)
 #define TLS_TBSS (8)
-#define TCB_SIZE (8)
 
 #define none (0)
 
@@ -1259,7 +1265,7 @@ arc_do_relocation (bfd_byte * contents,
   struct elf_link_hash_table *htab ATTRIBUTE_UNUSED = elf_hash_table (info);
   bfd_reloc_status_type flag;
 
-  if (reloc_data.should_relocate == FALSE)
+  if (!reloc_data.should_relocate)
     return bfd_reloc_ok;
 
   switch (reloc_data.howto->size)
@@ -1353,6 +1359,7 @@ arc_do_relocation (bfd_byte * contents,
 #undef P
 #undef SECTSTAR
 #undef SECTSTART
+#undef JLI
 #undef _SDA_BASE_
 #undef none
 
@@ -1405,6 +1412,7 @@ elf_arc_relocate_section (bfd *                     output_bfd,
       asection *                   sec;
       struct elf_link_hash_entry *  h2;
       const char *                  msg;
+      bfd_boolean                  unresolved_reloc = FALSE;
 
       struct arc_relocation_data reloc_data =
       {
@@ -1464,9 +1472,9 @@ elf_arc_relocate_section (bfd *                     output_bfd,
       h2 = elf_link_hash_lookup (elf_hash_table (info), "__SDATA_BEGIN__",
                                 FALSE, FALSE, TRUE);
 
-      if (reloc_data.sdata_begin_symbol_vma_set == FALSE
-           && h2 != NULL && h2->root.type != bfd_link_hash_undefined
-           && h2->root.u.def.section->output_section != NULL)
+      if (!reloc_data.sdata_begin_symbol_vma_set
+         && h2 != NULL && h2->root.type != bfd_link_hash_undefined
+         && h2->root.u.def.section->output_section != NULL)
        /* TODO: Verify this condition.  */
        {
          reloc_data.sdata_begin_symbol_vma =
@@ -1492,6 +1500,14 @@ elf_arc_relocate_section (bfd *                    output_bfd,
        }
       else
        {
+         bfd_boolean warned, ignored;
+         bfd_vma relocation ATTRIBUTE_UNUSED;
+
+         RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+                                  r_symndx, symtab_hdr, sym_hashes,
+                                  h, sec, relocation,
+                                  unresolved_reloc, warned, ignored);
+
          /* TODO: This code is repeated from below.  We should
             clean it and remove duplications.
             Sec is used check for discarded sections.
@@ -1581,7 +1597,12 @@ elf_arc_relocate_section (bfd *                    output_bfd,
 
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
+         {
+           struct elf_link_hash_entry *h_old = h;
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
+           if (h->got.glist == 0 && h_old->got.glist != h->got.glist)
+             h->got.glist = h_old->got.glist;
+         }
 
          /* TODO: Need to validate what was the intention.  */
          /* BFD_ASSERT ((h->dynindx == -1) || (h->forced_local != 0)); */
@@ -1701,16 +1722,22 @@ elf_arc_relocate_section (bfd *                   output_bfd,
            }
        }
 
+
+#define IS_ARC_PCREL_TYPE(TYPE) \
+  (   (TYPE == R_ARC_PC32)      \
+   || (TYPE == R_ARC_32_PCREL))
+
       switch (r_type)
        {
          case R_ARC_32:
          case R_ARC_32_ME:
          case R_ARC_PC32:
          case R_ARC_32_PCREL:
-           if ((bfd_link_pic (info))
-               && ((r_type != R_ARC_PC32 && r_type != R_ARC_32_PCREL)
+           if (bfd_link_pic (info)
+               && (!IS_ARC_PCREL_TYPE (r_type)
                    || (h != NULL
                        && h->dynindx != -1
+                       && !h->def_regular
                        && (!info->symbolic || !h->def_regular))))
              {
                Elf_Internal_Rela outrel;
@@ -1727,6 +1754,7 @@ elf_arc_relocate_section (bfd *                     output_bfd,
                                                           info,
                                                           input_section,
                                                           rel->r_offset);
+
                if (outrel.r_offset == (bfd_vma) -1)
                  skip = TRUE;
 
@@ -1734,10 +1762,6 @@ elf_arc_relocate_section (bfd *                    output_bfd,
                outrel.r_offset += (input_section->output_section->vma
                                    + input_section->output_offset);
 
-#define IS_ARC_PCREL_TYPE(TYPE) \
-  (   (TYPE == R_ARC_PC32)      \
-   || (TYPE == R_ARC_32_PCREL))
-
                if (skip)
                  {
                    memset (&outrel, 0, sizeof outrel);
@@ -1745,10 +1769,10 @@ elf_arc_relocate_section (bfd *                   output_bfd,
                  }
                else if (h != NULL
                         && h->dynindx != -1
-                        && ((IS_ARC_PCREL_TYPE (r_type))
-                        || !(bfd_link_executable (info)
-                             || SYMBOLIC_BIND (info, h))
-                        || ! h->def_regular))
+                        && (IS_ARC_PCREL_TYPE (r_type)
+                            || !(bfd_link_executable (info)
+                                 || SYMBOLIC_BIND (info, h))
+                            || ! h->def_regular))
                  {
                    BFD_ASSERT (h != NULL);
                    if ((input_section->flags & SEC_ALLOC) != 0)
@@ -1784,7 +1808,7 @@ elf_arc_relocate_section (bfd *                     output_bfd,
 
                bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
 
-               if (relocate == FALSE)
+               if (!relocate)
                  continue;
              }
            break;
@@ -1793,7 +1817,7 @@ elf_arc_relocate_section (bfd *                     output_bfd,
        }
 
       if (is_reloc_SDA_relative (howto)
-         && (reloc_data.sdata_begin_symbol_vma_set == FALSE))
+         && !reloc_data.sdata_begin_symbol_vma_set)
        {
          _bfd_error_handler
            ("Error: Linker symbol __SDATA_BEGIN__ not found");
@@ -1881,10 +1905,14 @@ elf_arc_check_relocs (bfd *                      abfd,
   const Elf_Internal_Rela *    rel_end;
   bfd *                                dynobj;
   asection *                   sreloc = NULL;
+  struct elf_link_hash_table * htab = elf_hash_table (info);
 
   if (bfd_link_relocatable (info))
     return TRUE;
 
+  if (htab->dynobj == NULL)
+    htab->dynobj = abfd;
+
   dynobj = (elf_hash_table (info))->dynobj;
   symtab_hdr = &((elf_tdata (abfd))->symtab_hdr);
   sym_hashes = elf_sym_hashes (abfd);
@@ -1906,15 +1934,6 @@ elf_arc_check_relocs (bfd *                       abfd,
        }
       howto = arc_elf_howto (r_type);
 
-      if (dynobj == NULL
-         && (is_reloc_for_GOT (howto) == TRUE
-             || is_reloc_for_TLS (howto) == TRUE))
-       {
-         dynobj = elf_hash_table (info)->dynobj = abfd;
-         if (! _bfd_elf_create_got_section (abfd, info))
-           return FALSE;
-       }
-
       /* Load symbol information.  */
       r_symndx = ELF32_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info) /* Is a local symbol.  */
@@ -1931,7 +1950,8 @@ elf_arc_check_relocs (bfd *                        abfd,
               and the dynamic linker can not resolve these.  However
               the error should not occur for e.g. debugging or
               non-readonly sections.  */
-           if ((bfd_link_dll (info) && !bfd_link_pie (info))
+           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
@@ -1970,6 +1990,10 @@ elf_arc_check_relocs (bfd *                       abfd,
              {
                if (sreloc == NULL)
                  {
+                   if (info->dynamic
+                       && ! htab->dynamic_sections_created
+                       && ! _bfd_elf_link_create_dynamic_sections (abfd, info))
+                     return FALSE;
                    sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
                                                                  2, abfd,
                                                                  /*rela*/
@@ -1985,7 +2009,7 @@ elf_arc_check_relocs (bfd *                        abfd,
            break;
        }
 
-      if (is_reloc_for_PLT (howto) == TRUE)
+      if (is_reloc_for_PLT (howto))
        {
          if (h == NULL)
            continue;
@@ -1994,9 +2018,12 @@ elf_arc_check_relocs (bfd *                       abfd,
        }
 
       /* Add info to the symbol got_entry_list.  */
-      if (is_reloc_for_GOT (howto) == TRUE
-         || is_reloc_for_TLS (howto) == TRUE)
+      if (is_reloc_for_GOT (howto)
+         || is_reloc_for_TLS (howto))
        {
+         if (! _bfd_elf_create_got_section (dynobj, info))
+           return FALSE;
+
          arc_fill_got_info_for_reloc (
                  arc_got_entry_type_for_reloc (howto),
                  get_got_entry_list_for_symbol (abfd, r_symndx, h),
@@ -2623,7 +2650,8 @@ elf_arc_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                  const char *name = s->name + 5;
                  bfd *ibfd;
                  for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
-                   if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour)
+                   if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
+                       && ibfd->flags & DYNAMIC)
                      {
                        asection *target = bfd_get_section_by_name (ibfd, name);
                        if (target != NULL
This page took 0.027819 seconds and 4 git commands to generate.