2011-05-09 Paul Brook <paul@codesourcery.com>
[binutils-gdb.git] / bfd / elf32-m68k.c
index ff37a3c06e06281ee48ed787b30951e44f8d44a6..b4f7bc2c94c9346a2b7a3e4fd522fe1e4c41bccf 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, 2010 Free Software Foundation, Inc.
+   2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -469,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.  */
 
@@ -1293,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);
@@ -3712,15 +3716,8 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
        }
 
       if (sec != NULL && elf_discarded_section (sec))
-       {
-         /* For relocs against symbols from removed linkonce sections,
-            or sections discarded by a linker script, we just want the
-            section contents zeroed.  Avoid any special processing.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
-         continue;
-       }
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
 
       if (info->relocatable)
        continue;
@@ -4030,7 +4027,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
        case R_68K_PC16:
        case R_68K_PC32:
          if (info->shared
-             && r_symndx != 0
+             && r_symndx != STN_UNDEF
              && (input_section->flags & SEC_ALLOC) != 0
              && (h == NULL
                  || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
@@ -4165,7 +4162,7 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
          return FALSE;
        }
 
-      if (r_symndx != 0
+      if (r_symndx != STN_UNDEF
          && r_type != R_68K_NONE
          && (h == NULL
              || h->root.type == bfd_link_hash_defined
@@ -4393,6 +4390,11 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
                  break;
 
                case R_68K_TLS_GD32:
+                 /* The value for this relocation is actually put in
+                    the second GOT slot.  */
+                 relocation = bfd_get_signed_32 (output_bfd,
+                                                 (sgot->contents
+                                                  + got_entry_offset + 4));
                  relocation += dtpoff_base (info);
                  break;
 
@@ -4742,34 +4744,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;
     }
 }