* peXXigen.c: Whitespace.
[deliverable/binutils-gdb.git] / bfd / elf32-m68k.c
index ced19a137ab9554c2f46c9a3ed1517d84912b29a..732361217613c2e294f72cd3e175d9d89faf0734 100644 (file)
@@ -1,6 +1,6 @@
 /* Motorola 68k series support for 32-bit ELF
    Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
-   2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -374,13 +374,17 @@ static reloc_howto_type howto_table[] = {
 };
 
 static void
-rtype_to_howto (abfd, cache_ptr, dst)
-     bfd *abfd ATTRIBUTE_UNUSED;
-     arelent *cache_ptr;
-     Elf_Internal_Rela *dst;
+rtype_to_howto (bfd *abfd, arelent *cache_ptr, Elf_Internal_Rela *dst)
 {
-  BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_68K_max);
-  cache_ptr->howto = &howto_table[ELF32_R_TYPE(dst->r_info)];
+  unsigned int indx = ELF32_R_TYPE (dst->r_info);
+
+  if (indx >= (unsigned int) R_68K_max)
+    {
+      (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
+                            abfd, (int) indx);
+      indx = R_68K_NONE;
+    }
+  cache_ptr->howto = &howto_table[indx];
 }
 
 #define elf_info_to_howto rtype_to_howto
@@ -465,6 +469,7 @@ reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
 #define bfd_elf32_bfd_reloc_type_lookup reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup reloc_name_lookup
 #define ELF_ARCH bfd_arch_m68k
+#define ELF_TARGET_ID M68K_ELF_DATA
 \f
 /* Functions for the m68k ELF linker.  */
 
@@ -933,7 +938,8 @@ struct elf_m68k_link_hash_table
 /* Get the m68k ELF linker hash table from a link_info structure.  */
 
 #define elf_m68k_hash_table(p) \
-  ((struct elf_m68k_link_hash_table *) (p)->hash)
+  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+  == M68K_ELF_DATA ? ((struct elf_m68k_link_hash_table *) ((p)->hash)) : NULL)
 
 /* Shortcut to multi-GOT data.  */
 #define elf_m68k_multi_got(INFO) (&elf_m68k_hash_table (INFO)->multi_got_)
@@ -941,10 +947,9 @@ struct elf_m68k_link_hash_table
 /* Create an entry in an m68k ELF linker hash table.  */
 
 static struct bfd_hash_entry *
-elf_m68k_link_hash_newfunc (entry, table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *table;
-     const char *string;
+elf_m68k_link_hash_newfunc (struct bfd_hash_entry *entry,
+                           struct bfd_hash_table *table,
+                           const char *string)
 {
   struct bfd_hash_entry *ret = entry;
 
@@ -971,8 +976,7 @@ elf_m68k_link_hash_newfunc (entry, table, string)
 /* Create an m68k ELF linker hash table.  */
 
 static struct bfd_link_hash_table *
-elf_m68k_link_hash_table_create (abfd)
-     bfd *abfd;
+elf_m68k_link_hash_table_create (bfd *abfd)
 {
   struct elf_m68k_link_hash_table *ret;
   bfd_size_type amt = sizeof (struct elf_m68k_link_hash_table);
@@ -983,7 +987,8 @@ elf_m68k_link_hash_table_create (abfd)
 
   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
                                      elf_m68k_link_hash_newfunc,
-                                     sizeof (struct elf_m68k_link_hash_entry)))
+                                     sizeof (struct elf_m68k_link_hash_entry),
+                                     M68K_ELF_DATA))
     {
       free (ret);
       return NULL;
@@ -1076,7 +1081,68 @@ elf32_m68k_object_p (bfd *abfd)
   return TRUE;
 }
 
+/* Somewhat reverse of elf32_m68k_object_p, this sets the e_flag
+   field based on the machine number.  */
+
+static void
+elf_m68k_final_write_processing (bfd *abfd,
+                                bfd_boolean linker ATTRIBUTE_UNUSED)
+{
+  int mach = bfd_get_mach (abfd);
+  unsigned long e_flags = elf_elfheader (abfd)->e_flags;
+
+  if (!e_flags)
+    {
+      unsigned int arch_mask;
+
+      arch_mask = bfd_m68k_mach_to_features (mach);
+
+      if (arch_mask & m68000)
+       e_flags = EF_M68K_M68000;
+      else if (arch_mask & cpu32)
+       e_flags = EF_M68K_CPU32;
+      else if (arch_mask & fido_a)
+       e_flags = EF_M68K_FIDO;
+      else
+       {
+         switch (arch_mask
+                 & (mcfisa_a | mcfisa_aa | mcfisa_b | mcfisa_c | mcfhwdiv | mcfusp))
+           {
+           case mcfisa_a:
+             e_flags |= EF_M68K_CF_ISA_A_NODIV;
+             break;
+           case mcfisa_a | mcfhwdiv:
+             e_flags |= EF_M68K_CF_ISA_A;
+             break;
+           case mcfisa_a | mcfisa_aa | mcfhwdiv | mcfusp:
+             e_flags |= EF_M68K_CF_ISA_A_PLUS;
+             break;
+           case mcfisa_a | mcfisa_b | mcfhwdiv:
+             e_flags |= EF_M68K_CF_ISA_B_NOUSP;
+             break;
+           case mcfisa_a | mcfisa_b | mcfhwdiv | mcfusp:
+             e_flags |= EF_M68K_CF_ISA_B;
+             break;
+           case mcfisa_a | mcfisa_c | mcfhwdiv | mcfusp:
+             e_flags |= EF_M68K_CF_ISA_C;
+             break;
+           case mcfisa_a | mcfisa_c | mcfusp:
+             e_flags |= EF_M68K_CF_ISA_C_NODIV;
+             break;
+           }
+         if (arch_mask & mcfmac)
+           e_flags |= EF_M68K_CF_MAC;
+         else if (arch_mask & mcfemac)
+           e_flags |= EF_M68K_CF_EMAC;
+         if (arch_mask & cfloat)
+           e_flags |= EF_M68K_CF_FLOAT | EF_M68K_CFV4E;
+       }
+      elf_elfheader (abfd)->e_flags = e_flags;
+    }
+}
+
 /* Keep m68k-specific flags in the ELF header.  */
+
 static bfd_boolean
 elf32_m68k_set_private_flags (abfd, flags)
      bfd *abfd;
@@ -1228,6 +1294,9 @@ elf32_m68k_print_private_bfd_data (bfd *abfd, void * ptr)
            case EF_M68K_CF_EMAC:
              mac = "emac";
              break;
+           case EF_M68K_CF_EMAC_B:
+             mac = "emac_b";
+             break;
            }
          if (mac)
            fprintf (file, " [%s]", mac);
@@ -1531,7 +1600,7 @@ elf_m68k_get_got_entry (struct elf_m68k_got *got,
 static enum elf_m68k_reloc_type
 elf_m68k_update_got_entry_type (struct elf_m68k_got *got,
                                enum elf_m68k_reloc_type was,
-                               enum elf_m68k_reloc_type new)
+                               enum elf_m68k_reloc_type new_reloc)
 {
   enum elf_m68k_got_offset_size was_size;
   enum elf_m68k_got_offset_size new_size;
@@ -1543,20 +1612,20 @@ elf_m68k_update_got_entry_type (struct elf_m68k_got *got,
       /* Update all got->n_slots counters, including n_slots[R_32].  */
       was_size = R_LAST;
 
-      was = new;
+      was = new_reloc;
     }
   else
     {
       /* !!! We, probably, should emit an error rather then fail on assert
         in such a case.  */
       BFD_ASSERT (elf_m68k_reloc_got_type (was)
-                 == elf_m68k_reloc_got_type (new));
+                 == elf_m68k_reloc_got_type (new_reloc));
 
       was_size = elf_m68k_reloc_got_offset_size (was);
     }
 
-  new_size = elf_m68k_reloc_got_offset_size (new);
-  n_slots = elf_m68k_reloc_got_n_slots (new);
+  new_size = elf_m68k_reloc_got_offset_size (new_reloc);
+  n_slots = elf_m68k_reloc_got_n_slots (new_reloc);
 
   while (was_size > new_size)
     {
@@ -1564,10 +1633,10 @@ elf_m68k_update_got_entry_type (struct elf_m68k_got *got,
       got->n_slots[was_size] += n_slots;
     }
 
-  if (new > was)
+  if (new_reloc > was)
     /* Relocations are ordered from bigger got offset size to lesser,
        so choose the relocation type with lesser offset size.  */
-    was = new;
+    was = new_reloc;
 
   return was;
 }
@@ -2903,8 +2972,6 @@ elf_m68k_gc_sweep_hook (bfd *abfd,
   struct elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel, *relend;
   bfd *dynobj;
-  asection *sgot;
-  asection *srelgot;
   struct elf_m68k_got *got;
 
   if (info->relocatable)
@@ -2916,9 +2983,6 @@ elf_m68k_gc_sweep_hook (bfd *abfd,
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
-
-  sgot = bfd_get_section_by_name (dynobj, ".got");
-  srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
   got = NULL;
 
   relend = relocs + sec->reloc_count;
@@ -3446,9 +3510,11 @@ elf_m68k_install_rela (bfd *output_bfd,
   bfd_elf32_swap_reloca_out (output_bfd, rela, loc);
 }
 
-/* Return the base VMA address which should be subtracted from real addresses
-   when resolving @dtpoff relocation.
-   This is PT_TLS segment p_vaddr.  */
+/* Find the base offsets for thread-local storage in this object,
+   for GD/LD and IE/LE respectively.  */
+
+#define DTP_OFFSET 0x8000
+#define TP_OFFSET  0x7000
 
 static bfd_vma
 dtpoff_base (struct bfd_link_info *info)
@@ -3456,23 +3522,116 @@ dtpoff_base (struct bfd_link_info *info)
   /* If tls_sec is NULL, we should have signalled an error already.  */
   if (elf_hash_table (info)->tls_sec == NULL)
     return 0;
-  return elf_hash_table (info)->tls_sec->vma;
+  return elf_hash_table (info)->tls_sec->vma + DTP_OFFSET;
 }
 
-/* Return the relocation value for @tpoff relocation
-   if STT_TLS virtual address is ADDRESS.  */
-
 static bfd_vma
-tpoff (struct bfd_link_info *info, bfd_vma address)
+tpoff_base (struct bfd_link_info *info)
 {
-  struct elf_link_hash_table *htab = elf_hash_table (info);
-  bfd_vma base;
-
   /* If tls_sec is NULL, we should have signalled an error already.  */
-  if (htab->tls_sec == NULL)
+  if (elf_hash_table (info)->tls_sec == NULL)
     return 0;
-  base = align_power ((bfd_vma) 8, htab->tls_sec->alignment_power);
-  return address - htab->tls_sec->vma + base;
+  return elf_hash_table (info)->tls_sec->vma + TP_OFFSET;
+}
+
+/* Output necessary relocation to handle a symbol during static link.
+   This function is called from elf_m68k_relocate_section.  */
+
+static void
+elf_m68k_init_got_entry_static (struct bfd_link_info *info,
+                               bfd *output_bfd,
+                               enum elf_m68k_reloc_type r_type,
+                               asection *sgot,
+                               bfd_vma got_entry_offset,
+                               bfd_vma relocation)
+{
+  switch (elf_m68k_reloc_got_type (r_type))
+    {
+    case R_68K_GOT32O:
+      bfd_put_32 (output_bfd, relocation, sgot->contents + got_entry_offset);
+      break;
+
+    case R_68K_TLS_GD32:
+      /* We know the offset within the module,
+        put it into the second GOT slot.  */
+      bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
+                 sgot->contents + got_entry_offset + 4);
+      /* FALLTHRU */
+
+    case R_68K_TLS_LDM32:
+      /* Mark it as belonging to module 1, the executable.  */
+      bfd_put_32 (output_bfd, 1, sgot->contents + got_entry_offset);
+      break;
+
+    case R_68K_TLS_IE32:
+      bfd_put_32 (output_bfd, relocation - tpoff_base (info),
+                 sgot->contents + got_entry_offset);
+      break;
+
+    default:
+      BFD_ASSERT (FALSE);
+    }
+}
+
+/* Output necessary relocation to handle a local symbol
+   during dynamic link.
+   This function is called either from elf_m68k_relocate_section
+   or from elf_m68k_finish_dynamic_symbol.  */
+
+static void
+elf_m68k_init_got_entry_local_shared (struct bfd_link_info *info,
+                                     bfd *output_bfd,
+                                     enum elf_m68k_reloc_type r_type,
+                                     asection *sgot,
+                                     bfd_vma got_entry_offset,
+                                     bfd_vma relocation,
+                                     asection *srela)
+{
+  Elf_Internal_Rela outrel;
+
+  switch (elf_m68k_reloc_got_type (r_type))
+    {
+    case R_68K_GOT32O:
+      /* Emit RELATIVE relocation to initialize GOT slot
+        at run-time.  */
+      outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
+      outrel.r_addend = relocation;
+      break;
+
+    case R_68K_TLS_GD32:
+      /* We know the offset within the module,
+        put it into the second GOT slot.  */
+      bfd_put_32 (output_bfd, relocation - dtpoff_base (info),
+                 sgot->contents + got_entry_offset + 4);
+      /* FALLTHRU */
+
+    case R_68K_TLS_LDM32:
+      /* We don't know the module number,
+        create a relocation for it.  */
+      outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_DTPMOD32);
+      outrel.r_addend = 0;
+      break;
+
+    case R_68K_TLS_IE32:
+      /* Emit TPREL relocation to initialize GOT slot
+        at run-time.  */
+      outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_TPREL32);
+      outrel.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
+      break;
+
+    default:
+      BFD_ASSERT (FALSE);
+    }
+
+  /* Offset of the GOT entry.  */
+  outrel.r_offset = (sgot->output_section->vma
+                    + sgot->output_offset
+                    + got_entry_offset);
+
+  /* Install one of the above relocations.  */
+  elf_m68k_install_rela (output_bfd, srela, &outrel);
+
+  bfd_put_32 (output_bfd, outrel.r_addend, sgot->contents + got_entry_offset);
 }
 
 /* Relocate an M68K ELF section.  */
@@ -3495,6 +3654,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
   asection *sgot;
   asection *splt;
   asection *sreloc;
+  asection *srela;
   struct elf_m68k_got *got;
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
@@ -3506,6 +3666,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
   sgot = NULL;
   splt = NULL;
   sreloc = NULL;
+  srela = NULL;
 
   got = NULL;
 
@@ -3704,7 +3865,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
                        /* This is actually a static link, or it is a
                           -Bsymbolic link and the symbol is defined
                           locally, or the symbol was forced to be local
-                          because of a version file..  We must initialize
+                          because of a version file.  We must initialize
                           this entry in the global offset table.  Since
                           the offset must always be a multiple of 4, we
                           use the least significant bit to record whether
@@ -3714,26 +3875,12 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
                           relocation entry to initialize the value.  This
                           is done in the finish_dynamic_symbol routine.  */
 
-                       if (elf_m68k_reloc_got_type (r_type) == R_68K_GOT32O)
-                         bfd_put_32 (output_bfd, relocation,
-                                     sgot->contents + off);
-                       else if (elf_m68k_reloc_got_type (r_type)
-                                == R_68K_TLS_GD32)
-                         /* Mark it as belonging to module 1,
-                            the executable.  */
-                         {
-                           bfd_put_32 (output_bfd, 1,
-                                       sgot->contents + off);
-                           bfd_put_32 (output_bfd, (relocation
-                                                    - dtpoff_base (info)),
-                                       sgot->contents + off + 4);
-                         }
-                       else if (elf_m68k_reloc_got_type (r_type)
-                                == R_68K_TLS_IE32)
-                         bfd_put_32 (output_bfd, tpoff (info, relocation),
-                                     sgot->contents + off);
-                       else
-                         BFD_ASSERT (FALSE);
+                       elf_m68k_init_got_entry_static (info,
+                                                       output_bfd,
+                                                       r_type,
+                                                       sgot,
+                                                       off,
+                                                       relocation);
 
                        *off_ptr |= 1;
                      }
@@ -3741,103 +3888,32 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
                      unresolved_reloc = FALSE;
                  }
                else if (info->shared) /* && h == NULL */
+                 /* Process local symbol during dynamic link.  */
                  {
-                   asection *srela;
-                   Elf_Internal_Rela outrel;
-
-                   srela = bfd_get_section_by_name (dynobj, ".rela.got");
-                   BFD_ASSERT (srela != NULL);
-
-                   if (elf_m68k_reloc_got_type (r_type) == R_68K_GOT32O)
-                     {
-                       /* Emit RELATIVE relocation to initialize GOT slot
-                          at run-time.  */
-                       outrel.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
-                       outrel.r_addend = relocation;
-                       outrel.r_offset = (sgot->output_section->vma
-                                          + sgot->output_offset
-                                          + off);
-
-                       elf_m68k_install_rela (output_bfd, srela, &outrel);
-                     }
-                   else if (elf_m68k_reloc_got_type (r_type)
-                            == R_68K_TLS_LDM32)
-                     {
-                       /* If we don't know the module number, create
-                          a relocation for it.  */
-                       outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_DTPMOD32);
-                       outrel.r_addend = 0;
-                       outrel.r_offset = (sgot->output_section->vma
-                                          + sgot->output_offset
-                                          + off);
-
-                       elf_m68k_install_rela (output_bfd, srela, &outrel);
-                     }
-                   else if (elf_m68k_reloc_got_type (r_type)
-                            == R_68K_TLS_GD32)
+                   if (srela == NULL)
                      {
-                       /* If we don't know the module number, create
-                          a relocation for it.  */
-                       outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_DTPMOD32);
-                       outrel.r_addend = 0;
-                       outrel.r_offset = (sgot->output_section->vma
-                                          + sgot->output_offset
-                                          + off);
-
-                       elf_m68k_install_rela (output_bfd, srela, &outrel);
-
-                       bfd_put_32 (output_bfd, (relocation
-                                                - dtpoff_base (info)),
-                                   sgot->contents + off + 4);
+                       srela = bfd_get_section_by_name (dynobj, ".rela.got");
+                       BFD_ASSERT (srela != NULL);
                      }
-                   else if (elf_m68k_reloc_got_type (r_type)
-                            == R_68K_TLS_IE32)
-                     {
-                       outrel.r_info = ELF32_R_INFO (0, R_68K_TLS_TPREL32);
-                       outrel.r_addend = relocation - dtpoff_base (info);
-                       outrel.r_offset = (sgot->output_section->vma
-                                          + sgot->output_offset
-                                          + off);
-
-                       elf_m68k_install_rela (output_bfd, srela, &outrel);
-                     }
-                   else
-                     BFD_ASSERT (FALSE);
 
-                   bfd_put_32 (output_bfd, outrel.r_addend,
-                               sgot->contents + off);
+                   elf_m68k_init_got_entry_local_shared (info,
+                                                         output_bfd,
+                                                         r_type,
+                                                         sgot,
+                                                         off,
+                                                         relocation,
+                                                         srela);
 
                    *off_ptr |= 1;
                  }
                else /* h == NULL && !info->shared */
                  {
-                   if (elf_m68k_reloc_got_type (r_type) == R_68K_GOT32O)
-                     bfd_put_32 (output_bfd, relocation,
-                                 sgot->contents + off);
-                   else if (elf_m68k_reloc_got_type (r_type)
-                            == R_68K_TLS_LDM32)
-                     /* If this is a static link, put the number of the
-                        only module in the GOT slot.  */
-                     bfd_put_32 (output_bfd, 1, sgot->contents + off);
-                   else if (elf_m68k_reloc_got_type (r_type)
-                            == R_68K_TLS_GD32)
-                     {
-                       /* If we are not emitting relocations for a
-                          general dynamic reference, then we must be in a
-                          static link or an executable link with the
-                          symbol binding locally.  Mark it as belonging
-                          to module 1, the executable.  */
-                       bfd_put_32 (output_bfd, 1, sgot->contents + off);
-                       bfd_put_32 (output_bfd, (relocation
-                                                - dtpoff_base (info)),
-                                   sgot->contents + off + 4);
-                     }
-                   else if (elf_m68k_reloc_got_type (r_type)
-                            == R_68K_TLS_IE32)
-                     bfd_put_32 (output_bfd, tpoff (info, relocation),
-                                 sgot->contents + off);
-                   else
-                     BFD_ASSERT (FALSE);
+                   elf_m68k_init_got_entry_static (info,
+                                                   output_bfd,
+                                                   r_type,
+                                                   sgot,
+                                                   off,
+                                                   relocation);
 
                    *off_ptr |= 1;
                  }
@@ -3867,7 +3943,6 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
                  }
 
                /* This relocation does not use the addend.  */
-               BFD_ASSERT (rel->r_addend == 0);
                rel->r_addend = 0;
              }
            else
@@ -3895,7 +3970,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
              return FALSE;
            }
          else
-           relocation = tpoff (info, relocation);
+           relocation -= tpoff_base (info);
 
          break;
 
@@ -4294,15 +4369,12 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
 
       while (got_entry != NULL)
        {
-         Elf_Internal_Rela rela;
+         enum elf_m68k_reloc_type r_type;
          bfd_vma got_entry_offset;
 
+         r_type = got_entry->key_.type;
          got_entry_offset = got_entry->u.s2.offset &~ (bfd_vma) 1;
 
-         rela.r_offset = (sgot->output_section->vma
-                          + sgot->output_offset
-                          + got_entry_offset);
-
          /* If this is a -Bsymbolic link, and the symbol is defined
             locally, we just want to emit a RELATIVE reloc.  Likewise if
             the symbol was forced to be local because of a version file.
@@ -4311,33 +4383,43 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
          if (info->shared
              && SYMBOL_REFERENCES_LOCAL (info, h))
            {
-             rela.r_addend = bfd_get_signed_32 (output_bfd,
-                                                (sgot->contents
-                                                 + got_entry_offset));
+             bfd_vma relocation;
+
+             relocation = bfd_get_signed_32 (output_bfd,
+                                             (sgot->contents
+                                              + got_entry_offset));
 
-             switch (elf_m68k_reloc_got_type (got_entry->key_.type))
+             /* Undo TP bias.  */
+             switch (elf_m68k_reloc_got_type (r_type))
                {
                case R_68K_GOT32O:
-                 rela.r_info = ELF32_R_INFO (0, R_68K_RELATIVE);
+               case R_68K_TLS_LDM32:
                  break;
 
                case R_68K_TLS_GD32:
-                 rela.r_info = ELF32_R_INFO (0, R_68K_TLS_DTPMOD32);
+                 relocation += dtpoff_base (info);
                  break;
 
                case R_68K_TLS_IE32:
-                 rela.r_info = ELF32_R_INFO (0, R_68K_TLS_TPREL32);
+                 relocation += tpoff_base (info);
                  break;
 
                default:
                  BFD_ASSERT (FALSE);
-                 break;
                }
 
-               elf_m68k_install_rela (output_bfd, srela, &rela);
+             elf_m68k_init_got_entry_local_shared (info,
+                                                   output_bfd,
+                                                   r_type,
+                                                   sgot,
+                                                   got_entry_offset,
+                                                   relocation,
+                                                   srela);
            }
          else
            {
+             Elf_Internal_Rela rela;
+
              /* Put zeros to GOT slots that will be initialized
                 at run-time.  */
              {
@@ -4351,8 +4433,11 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
              }
 
              rela.r_addend = 0;
+             rela.r_offset = (sgot->output_section->vma
+                              + sgot->output_offset
+                              + got_entry_offset);
 
-             switch (elf_m68k_reloc_got_type (got_entry->key_.type))
+             switch (elf_m68k_reloc_got_type (r_type))
                {
                case R_68K_GOT32O:
                  rela.r_info = ELF32_R_INFO (h->dynindx, R_68K_GLOB_DAT);
@@ -4661,34 +4746,44 @@ void
 bfd_elf_m68k_set_target_options (struct bfd_link_info *info, int got_handling)
 {
   struct elf_m68k_link_hash_table *htab;
-
-  htab = elf_m68k_hash_table (info);
+  bfd_boolean use_neg_got_offsets_p;
+  bfd_boolean allow_multigot_p;
+  bfd_boolean local_gp_p;
 
   switch (got_handling)
     {
     case 0:
       /* --got=single.  */
-      htab->local_gp_p = FALSE;
-      htab->use_neg_got_offsets_p = FALSE;
-      htab->allow_multigot_p = FALSE;
+      local_gp_p = FALSE;
+      use_neg_got_offsets_p = FALSE;
+      allow_multigot_p = FALSE;
       break;
 
     case 1:
       /* --got=negative.  */
-      htab->local_gp_p = TRUE;
-      htab->use_neg_got_offsets_p = TRUE;
-      htab->allow_multigot_p = FALSE;
+      local_gp_p = TRUE;
+      use_neg_got_offsets_p = TRUE;
+      allow_multigot_p = FALSE;
       break;
 
     case 2:
       /* --got=multigot.  */
-      htab->local_gp_p = TRUE;
-      htab->use_neg_got_offsets_p = TRUE;
-      htab->allow_multigot_p = TRUE;
+      local_gp_p = TRUE;
+      use_neg_got_offsets_p = TRUE;
+      allow_multigot_p = TRUE;
       break;
 
     default:
       BFD_ASSERT (FALSE);
+      return;
+    }
+
+  htab = elf_m68k_hash_table (info);
+  if (htab != NULL)
+    {
+      htab->local_gp_p = local_gp_p;
+      htab->use_neg_got_offsets_p = use_neg_got_offsets_p;
+      htab->allow_multigot_p = allow_multigot_p;
     }
 }
 
@@ -4739,6 +4834,7 @@ elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
                                        elf_m68k_adjust_dynamic_symbol
 #define elf_backend_size_dynamic_sections \
                                        elf_m68k_size_dynamic_sections
+#define elf_backend_final_write_processing     elf_m68k_final_write_processing
 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
 #define elf_backend_relocate_section   elf_m68k_relocate_section
 #define elf_backend_finish_dynamic_symbol \
This page took 0.031908 seconds and 4 git commands to generate.