* elf32-mips.c (mips_elf_create_dynamic_relocation): Change
[deliverable/binutils-gdb.git] / bfd / elf32-m68k.c
index 2d0aba210fb4f1a1510ad5dd6f29dc81dd3e4510..709057b15315e138d7dd18c5f544d6b907a53eaa 100644 (file)
@@ -43,8 +43,6 @@ static boolean elf_m68k_gc_sweep_hook
           const Elf_Internal_Rela *));
 static boolean elf_m68k_adjust_dynamic_symbol
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
-static boolean elf_m68k_adjust_dynindx
-  PARAMS ((struct elf_link_hash_entry *, PTR));
 static boolean elf_m68k_size_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 static boolean elf_m68k_relocate_section
@@ -56,6 +54,15 @@ static boolean elf_m68k_finish_dynamic_symbol
 static boolean elf_m68k_finish_dynamic_sections
   PARAMS ((bfd *, struct bfd_link_info *));
 
+static boolean elf32_m68k_set_private_flags
+  PARAMS ((bfd *, flagword));
+static boolean elf32_m68k_copy_private_bfd_data
+  PARAMS ((bfd *, bfd *));
+static boolean elf32_m68k_merge_private_bfd_data
+  PARAMS ((bfd *, bfd *));
+static boolean elf32_m68k_print_private_bfd_data
+  PARAMS ((bfd *, PTR));
+
 static reloc_howto_type howto_table[] = {
   HOWTO(R_68K_NONE,       0, 0, 0, false,0, complain_overflow_dont,     bfd_elf_generic_reloc, "R_68K_NONE",      false, 0, 0x00000000,false),
   HOWTO(R_68K_32,         0, 2,32, false,0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_68K_32",        false, 0, 0xffffffff,false),
@@ -112,7 +119,7 @@ static reloc_howto_type howto_table[] = {
 
 static void
 rtype_to_howto (abfd, cache_ptr, dst)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      arelent *cache_ptr;
      Elf_Internal_Rela *dst;
 {
@@ -157,7 +164,7 @@ static const struct
 
 static reloc_howto_type *
 reloc_type_lookup (abfd, code)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      bfd_reloc_code_real_type code;
 {
   unsigned int i;
@@ -211,6 +218,33 @@ static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
   0, 0, 0, 0             /* replaced with offset to start of .plt.  */
 };
 
+#define CPU32_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_CPU32)
+
+#define PLT_CPU32_ENTRY_SIZE 24
+/* Procedure linkage table entries for the cpu32 */
+static const bfd_byte elf_cpu32_plt0_entry[PLT_CPU32_ENTRY_SIZE] =
+{
+  0x20, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a0 */
+  0, 0, 0, 0,             /* replaced with offset to .got + 4.  */
+  0x4e, 0xd0,             /* jmp %a0@ */
+  0, 0, 0, 0,             /* replace with offset to .got +8. */
+  0, 0, 0, 0,             /* pad out to 24 bytes.  */
+  0, 0, 0, 0,             /* pad out to 24 bytes.  */
+  0, 0
+};
+
+static const bfd_byte elf_cpu32_plt_entry[PLT_CPU32_ENTRY_SIZE] =
+{
+  0x20, 0x7b, 0x01, 0x70,  /* moveal %pc@(0xc), %a0 */
+  0, 0, 0, 0,              /* replaced with offset to symbol's .got entry.  */
+  0x4e, 0xd0,              /* jmp %a0@ */
+  0x2f, 0x3c,              /* move.l #offset,-(%sp) */
+  0, 0, 0, 0,              /* replaced with offset into relocation table.  */
+  0x60, 0xff,              /* bra.l .plt */
+  0, 0, 0, 0,              /* replaced with offset to start of .plt.  */
+  0, 0
+};
+
 /* The m68k linker needs to keep track of the number of relocs that it
    decides to copy in check_relocs for each symbol.  This is so that it
    can discard PC relative relocs if it doesn't need them when linking
@@ -320,6 +354,88 @@ elf_m68k_link_hash_table_create (abfd)
   return &ret->root.root;
 }
 
+/* Keep m68k-specific flags in the ELF header */
+static boolean
+elf32_m68k_set_private_flags (abfd, flags)
+     bfd *abfd;
+     flagword flags;
+{
+  elf_elfheader (abfd)->e_flags = flags;
+  elf_flags_init (abfd) = true;
+  return true;
+}
+
+/* Copy m68k-specific data from one module to another */
+static boolean
+elf32_m68k_copy_private_bfd_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  flagword in_flags;
+
+  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+  in_flags = elf_elfheader (ibfd)->e_flags;
+  elf_elfheader (obfd)->e_flags = in_flags;
+  elf_flags_init (obfd) = true;
+  return true;
+}
+
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+static boolean
+elf32_m68k_merge_private_bfd_data (ibfd, obfd)
+     bfd *ibfd;
+     bfd *obfd;
+{
+  flagword out_flags;
+  flagword in_flags;
+
+  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
+    return true;
+
+  in_flags  = elf_elfheader (ibfd)->e_flags;
+  out_flags = elf_elfheader (obfd)->e_flags;
+
+  if (!elf_flags_init (obfd))
+    {
+      elf_flags_init (obfd) = true;
+      elf_elfheader (obfd)->e_flags = in_flags;
+    }
+
+  return true;
+}
+
+/* Display the flags field */
+static boolean
+elf32_m68k_print_private_bfd_data (abfd, ptr)
+     bfd *abfd;
+     PTR ptr;
+{
+  FILE *file = (FILE *) ptr;
+
+  BFD_ASSERT (abfd != NULL && ptr != NULL);
+
+  /* Print normal ELF private data.  */
+  _bfd_elf_print_private_bfd_data (abfd, ptr);
+
+  /* Ignore init flag - it may not be set, despite the flags field containing valid data.  */
+
+  /* xgettext:c-format */
+  fprintf (file, _ ("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
+
+  if (elf_elfheader (abfd)->e_flags & EF_CPU32)
+    fprintf (file, _ (" [cpu32]"));
+
+  fputc ('\n', file);
+
+  return true;
+}
 /* Look through the relocs for a section during the first phase, and
    allocate space in the global offset table or procedure linkage
    table.  */
@@ -673,7 +789,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
 static asection *
 elf_m68k_gc_mark_hook (abfd, info, rel, h, sym)
      bfd *abfd;
-     struct bfd_link_info *info;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
      Elf_Internal_Rela *rel;
      struct elf_link_hash_entry *h;
      Elf_Internal_Sym *sym;
@@ -890,7 +1006,12 @@ elf_m68k_adjust_dynamic_symbol (info, h)
       /* If this is the first .plt entry, make room for the special
         first entry.  */
       if (s->_raw_size == 0)
-       s->_raw_size += PLT_ENTRY_SIZE;
+       {
+         if (CPU32_FLAG (dynobj))
+           s->_raw_size += PLT_CPU32_ENTRY_SIZE;
+         else
+           s->_raw_size += PLT_ENTRY_SIZE;
+       }
 
       /* If this symbol is not defined in a regular file, and we are
         not generating a shared library, then set the symbol to this
@@ -907,7 +1028,10 @@ elf_m68k_adjust_dynamic_symbol (info, h)
       h->plt.offset = s->_raw_size;
 
       /* Make room for this entry.  */
-      s->_raw_size += PLT_ENTRY_SIZE;
+      if (CPU32_FLAG (dynobj))
+        s->_raw_size += PLT_CPU32_ENTRY_SIZE;
+      else
+        s->_raw_size += PLT_ENTRY_SIZE;
 
       /* We also need to make an entry in the .got.plt section, which
         will be placed in the .got section by the linker script.  */
@@ -1186,51 +1310,6 @@ elf_m68k_size_dynamic_sections (output_bfd, info)
        }
     }
 
-  /* If we are generating a shared library, we generate a section
-     symbol for each output section for which we might need to copy
-     relocs.  These are local symbols, which means that they must come
-     first in the dynamic symbol table.  That means we must increment
-     the dynamic symbol index of every other dynamic symbol.  */
-  if (info->shared)
-    {
-      int c;
-
-      c = 0;
-      for (s = output_bfd->sections; s != NULL; s = s->next)
-       {
-         if ((s->flags & SEC_LINKER_CREATED) != 0
-             || (s->flags & SEC_ALLOC) == 0)
-           continue;
-
-         elf_section_data (s)->dynindx = c + 1;
-
-         /* These symbols will have no names, so we don't need to
-             fiddle with dynstr_index.  */
-
-         ++c;
-       }
-
-      elf_link_hash_traverse (elf_hash_table (info),
-                             elf_m68k_adjust_dynindx,
-                             (PTR) &c);
-      elf_hash_table (info)->dynsymcount += c;
-    }
-
-  return true;
-}
-
-/* Increment the index of a dynamic symbol by a given amount.  Called
-   via elf_link_hash_traverse.  */
-
-static boolean
-elf_m68k_adjust_dynindx (h, cparg)
-     struct elf_link_hash_entry *h;
-     PTR cparg;
-{
-  int *cp = (int *) cparg;
-
-  if (h->dynindx != -1)
-    h->dynindx += *cp;
   return true;
 }
 
@@ -1244,7 +1323,7 @@ elf_m68k_adjust_dynindx (h, cparg)
 static boolean
 elf_m68k_discard_copies (h, ignore)
      struct elf_m68k_link_hash_entry *h;
-     PTR ignore;
+     PTR ignore ATTRIBUTE_UNUSED;
 {
   struct elf_m68k_pcrel_relocs_copied *s;
 
@@ -1776,6 +1855,7 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
      Elf_Internal_Sym *sym;
 {
   bfd *dynobj;
+  int plt_off1, plt_off2, plt_off3;
 
   dynobj = elf_hash_table (info)->dynobj;
 
@@ -1802,16 +1882,35 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
         corresponds to this symbol.  This is the index of this symbol
         in all the symbols for which we are making plt entries.  The
         first entry in the procedure linkage table is reserved.  */
-      plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
+      if ( CPU32_FLAG (output_bfd))
+        plt_index = h->plt.offset / PLT_CPU32_ENTRY_SIZE - 1;
+      else
+        plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
 
       /* Get the offset into the .got table of the entry that
         corresponds to this function.  Each .got entry is 4 bytes.
         The first three are reserved.  */
       got_offset = (plt_index + 3) * 4;
 
-      /* Fill in the entry in the procedure linkage table.  */
-      memcpy (splt->contents + h->plt.offset, elf_m68k_plt_entry,
-             PLT_ENTRY_SIZE);
+      if ( CPU32_FLAG (output_bfd))
+        {
+          /* Fill in the entry in the procedure linkage table.  */
+          memcpy (splt->contents + h->plt.offset, elf_cpu32_plt_entry,
+                 PLT_CPU32_ENTRY_SIZE);
+          plt_off1 = 4;
+          plt_off2 = 12;
+          plt_off3 = 18;
+        }
+      else
+        {
+          /* Fill in the entry in the procedure linkage table.  */
+          memcpy (splt->contents + h->plt.offset, elf_m68k_plt_entry,
+                 PLT_ENTRY_SIZE);
+          plt_off1 = 4;
+          plt_off2 = 10;
+          plt_off3 = 16;
+        }
+
       /* The offset is relative to the first extension word.  */
       bfd_put_32 (output_bfd,
                  (sgot->output_section->vma
@@ -1819,12 +1918,12 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
                   + got_offset
                   - (splt->output_section->vma
                      + h->plt.offset + 2)),
-                 splt->contents + h->plt.offset + 4);
+                 splt->contents + h->plt.offset + plt_off1);
 
       bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
-                 splt->contents + h->plt.offset + 10);
-      bfd_put_32 (output_bfd, - (h->plt.offset + 16),
-                 splt->contents + h->plt.offset + 16);
+                 splt->contents + h->plt.offset + plt_off2);
+      bfd_put_32 (output_bfd, - (h->plt.offset + plt_off3),
+                 splt->contents + h->plt.offset + plt_off3);
 
       /* Fill in the entry in the global offset table.  */
       bfd_put_32 (output_bfd,
@@ -2017,21 +2116,39 @@ elf_m68k_finish_dynamic_sections (output_bfd, info)
       /* Fill in the first entry in the procedure linkage table.  */
       if (splt->_raw_size > 0)
        {
-         memcpy (splt->contents, elf_m68k_plt0_entry, PLT_ENTRY_SIZE);
-         bfd_put_32 (output_bfd,
-                     (sgot->output_section->vma
-                      + sgot->output_offset + 4
-                      - (splt->output_section->vma + 2)),
-                     splt->contents + 4);
-         bfd_put_32 (output_bfd,
-                     (sgot->output_section->vma
-                      + sgot->output_offset + 8
-                      - (splt->output_section->vma + 10)),
-                     splt->contents + 12);
+          if (!CPU32_FLAG (output_bfd))
+            {
+             memcpy (splt->contents, elf_m68k_plt0_entry, PLT_ENTRY_SIZE);
+             bfd_put_32 (output_bfd,
+                         (sgot->output_section->vma
+                          + sgot->output_offset + 4
+                          - (splt->output_section->vma + 2)),
+                         splt->contents + 4);
+             bfd_put_32 (output_bfd,
+                         (sgot->output_section->vma
+                          + sgot->output_offset + 8
+                          - (splt->output_section->vma + 10)),
+                         splt->contents + 12);
+              elf_section_data (splt->output_section)->this_hdr.sh_entsize 
+               = PLT_ENTRY_SIZE;
+            }
+          else /* cpu32 */
+            {
+              memcpy (splt->contents, elf_cpu32_plt0_entry, PLT_CPU32_ENTRY_SIZE);
+             bfd_put_32 (output_bfd,
+                         (sgot->output_section->vma
+                          + sgot->output_offset + 4
+                          - (splt->output_section->vma + 2)),
+                         splt->contents + 4);
+             bfd_put_32 (output_bfd,
+                         (sgot->output_section->vma
+                          + sgot->output_offset + 8
+                          - (splt->output_section->vma + 10)),
+                         splt->contents + 10);
+              elf_section_data (splt->output_section)->this_hdr.sh_entsize 
+               = PLT_CPU32_ENTRY_SIZE;
+            }
        }
-
-      elf_section_data (splt->output_section)->this_hdr.sh_entsize
-       = PLT_ENTRY_SIZE;
     }
 
   /* Fill in the first three entries in the global offset table.  */
@@ -2049,50 +2166,6 @@ elf_m68k_finish_dynamic_sections (output_bfd, info)
 
   elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
 
-  if (info->shared)
-    {
-      asection *sdynsym;
-      asection *s;
-      Elf_Internal_Sym sym;
-      int c;
-
-      /* Set up the section symbols for the output sections.  */
-
-      sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
-      BFD_ASSERT (sdynsym != NULL);
-
-      sym.st_size = 0;
-      sym.st_name = 0;
-      sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
-      sym.st_other = 0;
-
-      c = 0;
-      for (s = output_bfd->sections; s != NULL; s = s->next)
-       {
-         int indx;
-
-         if (elf_section_data (s)->dynindx == 0)
-           continue;
-
-         sym.st_value = s->vma;
-
-         indx = elf_section_data (s)->this_idx;
-         BFD_ASSERT (indx > 0);
-         sym.st_shndx = indx;
-
-         bfd_elf32_swap_symbol_out (output_bfd, &sym,
-                                    (PTR) (((Elf32_External_Sym *)
-                                            sdynsym->contents)
-                                           + elf_section_data (s)->dynindx));
-
-         ++c;
-       }
-
-      /* Set the sh_info field of the output .dynsym section to the
-         index of the first global symbol.  */
-      elf_section_data (sdynsym->output_section)->this_hdr.sh_info = c + 1;
-    }
-
   return true;
 }
 
@@ -2118,11 +2191,19 @@ elf_m68k_finish_dynamic_sections (output_bfd, info)
                                        elf_m68k_finish_dynamic_sections
 #define elf_backend_gc_mark_hook       elf_m68k_gc_mark_hook
 #define elf_backend_gc_sweep_hook      elf_m68k_gc_sweep_hook
+#define bfd_elf32_bfd_copy_private_bfd_data \
+                                        elf32_m68k_copy_private_bfd_data
+#define bfd_elf32_bfd_merge_private_bfd_data \
+                                        elf32_m68k_merge_private_bfd_data
+#define bfd_elf32_bfd_set_private_flags \
+                                        elf32_m68k_set_private_flags
+#define bfd_elf32_bfd_print_private_bfd_data \
+                                        elf32_m68k_print_private_bfd_data
+
 #define elf_backend_can_gc_sections 1
 #define elf_backend_want_got_plt 1
 #define elf_backend_plt_readonly 1
 #define elf_backend_want_plt_sym 0
 #define elf_backend_got_header_size    12
-#define elf_backend_plt_header_size    PLT_ENTRY_SIZE
 
 #include "elf32-target.h"
This page took 0.026909 seconds and 4 git commands to generate.