bfd/
authorRichard Sandiford <rdsandiford@googlemail.com>
Wed, 14 Jun 2006 08:27:41 +0000 (08:27 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Wed, 14 Jun 2006 08:27:41 +0000 (08:27 +0000)
* elf32-m68k.c (elf_m68k_plt_info): New structure.
(elf_m68k_plt0_entry): Add R_68K_PC32-style in-place addends.
(elf_m68k_plt_entry): Likewise.
(elf_m68k_plt_info): New table.
(CFV4E_PLT_ENTRY_SIZE): Rename to...
(ISAB_PLT_ENTRY_SIZE): ...this.
(CFV4E_FLAG): Delete.
(elf_cfv4e_plt0_entry): Rename to...
(elf_isab_plt0_entry): ...this.  Adjust comments.  Use (-6,%pc,%d0)
for the second instruction too.
(elf_cfv4e_plt_entry): Rename to...
(elf_isab_plt_entry): ...this.  Adjust comments and use (-6,%pc,%d0).
(elf_isab_plt_info): New table.
(CPU32_FLAG): Delete.
(PLT_CPU32_ENTRY_SIZE): Rename to...
(CPU32_PLT_ENTRY_SIZE): ...this.
(elf_cpu32_plt0_entry): Update bounds accordingly.  Add R_68K_PC32-
style in-place addends.
(elf_cpu32_plt_entry): Likewise.
(elf_cpu32_plt_info): New table.
(elf_m68k_link_hash_table): Add a plt_info field.
(elf_m68k_link_hash_table_create): Initialize it.
(elf_m68k_get_plt_info): New function.
(elf_m68k_always_size_sections): Likewise.
(elf_m68k_adjust_dynamic_symbol): Use the plt_info hash table field.
(elf_m68k_install_pc32): New function.
(elf_m68k_finish_dynamic_symbol): Factor code using plt_info and
elf_m68k_install_pc32.
(elf_m68k_finish_dynamic_sections): Likewise.
(elf_m68k_plt_sym_val): Use elf_m68k_get_plt_info.
(elf_backend_always_size_sections): Define.

ld/testsuite/
* ld-m68k/plt1.s, ld-m68k/plt1-empty.s, ld-m68k/plt1.ld: New files.
* ld-m68k/plt1-68020.d, ld-m68k/plt1-cpu32.d: Likewise.
* ld-m68k/plt1-isab.d: Likewise.
* ld-m68k/m68k.exp: Run new PLT tests.

bfd/ChangeLog
bfd/elf32-m68k.c
ld/testsuite/ChangeLog
ld/testsuite/ld-m68k/m68k.exp
ld/testsuite/ld-m68k/plt1-68020.d [new file with mode: 0644]
ld/testsuite/ld-m68k/plt1-cpu32.d [new file with mode: 0644]
ld/testsuite/ld-m68k/plt1-empty.s [new file with mode: 0644]
ld/testsuite/ld-m68k/plt1-isab.d [new file with mode: 0644]
ld/testsuite/ld-m68k/plt1.ld [new file with mode: 0644]
ld/testsuite/ld-m68k/plt1.s [new file with mode: 0644]

index 5090a01..aed0518 100644 (file)
@@ -1,3 +1,37 @@
+2006-06-14  Richard Sandiford  <richard@codesourcery.com>
+
+       * elf32-m68k.c (elf_m68k_plt_info): New structure.
+       (elf_m68k_plt0_entry): Add R_68K_PC32-style in-place addends.
+       (elf_m68k_plt_entry): Likewise.
+       (elf_m68k_plt_info): New table.
+       (CFV4E_PLT_ENTRY_SIZE): Rename to...
+       (ISAB_PLT_ENTRY_SIZE): ...this.
+       (CFV4E_FLAG): Delete.
+       (elf_cfv4e_plt0_entry): Rename to...
+       (elf_isab_plt0_entry): ...this.  Adjust comments.  Use (-6,%pc,%d0)
+       for the second instruction too.
+       (elf_cfv4e_plt_entry): Rename to...
+       (elf_isab_plt_entry): ...this.  Adjust comments and use (-6,%pc,%d0).
+       (elf_isab_plt_info): New table.
+       (CPU32_FLAG): Delete.
+       (PLT_CPU32_ENTRY_SIZE): Rename to...
+       (CPU32_PLT_ENTRY_SIZE): ...this.
+       (elf_cpu32_plt0_entry): Update bounds accordingly.  Add R_68K_PC32-
+       style in-place addends.
+       (elf_cpu32_plt_entry): Likewise.
+       (elf_cpu32_plt_info): New table.
+       (elf_m68k_link_hash_table): Add a plt_info field.
+       (elf_m68k_link_hash_table_create): Initialize it.
+       (elf_m68k_get_plt_info): New function.
+       (elf_m68k_always_size_sections): Likewise.
+       (elf_m68k_adjust_dynamic_symbol): Use the plt_info hash table field.
+       (elf_m68k_install_pc32): New function.
+       (elf_m68k_finish_dynamic_symbol): Factor code using plt_info and
+       elf_m68k_install_pc32.
+       (elf_m68k_finish_dynamic_sections): Likewise.
+       (elf_m68k_plt_sym_val): Use elf_m68k_get_plt_info.
+       (elf_backend_always_size_sections): Define.
+
 2006-06-14  Alan Modra  <amodra@bigpond.net.au>
 
        * elflink.c (elf_link_add_object_symbols): Save and restore
index df988a8..e8bb275 100644 (file)
@@ -190,6 +190,40 @@ reloc_type_lookup (abfd, code)
 
 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
 
+/* Describes one of the various PLT styles.  */
+
+struct elf_m68k_plt_info
+{
+  /* The size of each PLT entry.  */
+  bfd_vma size;
+
+  /* The template for the first PLT entry.  */
+  const bfd_byte *plt0_entry;
+
+  /* Offsets of fields in PLT0_ENTRY that require R_68K_PC32 relocations.
+     The comments by each member indicate the value that the relocation
+     is against.  */
+  struct {
+    unsigned int got4; /* .got + 4 */
+    unsigned int got8; /* .got + 8 */
+  } plt0_relocs;
+
+  /* The template for a symbol's PLT entry.  */
+  const bfd_byte *symbol_entry;
+
+  /* Offsets of fields in SYMBOL_ENTRY that require R_68K_PC32 relocations.
+     The comments by each member indicate the value that the relocation
+     is against.  */
+  struct {
+    unsigned int got; /* the symbol's .got.plt entry */
+    unsigned int plt; /* .plt */
+  } symbol_relocs;
+
+  /* The offset of the resolver stub from the start of SYMBOL_ENTRY.
+     The stub starts with "move.l #relocoffset,%d0".  */
+  bfd_vma symbol_resolve_entry;
+};
+
 /* The size in bytes of an entry in the procedure linkage table.  */
 
 #define PLT_ENTRY_SIZE 20
@@ -200,9 +234,9 @@ reloc_type_lookup (abfd, code)
 static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
 {
   0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
-  0, 0, 0, 0,            /* replaced with offset to .got + 4.  */
+  0, 0, 0, 2,            /* + (.got + 4) - . */
   0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,addr]) */
-  0, 0, 0, 0,            /* replaced with offset to .got + 8.  */
+  0, 0, 0, 2,            /* + (.got + 8) - . */
   0, 0, 0, 0             /* pad out to 20 bytes.  */
 };
 
@@ -211,71 +245,84 @@ static const bfd_byte elf_m68k_plt0_entry[PLT_ENTRY_SIZE] =
 static const bfd_byte elf_m68k_plt_entry[PLT_ENTRY_SIZE] =
 {
   0x4e, 0xfb, 0x01, 0x71, /* jmp ([%pc,symbol@GOTPC]) */
-  0, 0, 0, 0,            /* replaced with offset to symbol's .got entry.  */
+  0, 0, 0, 2,            /* + (.got.plt entry) - . */
   0x2f, 0x3c,            /* move.l #offset,-(%sp) */
-  0, 0, 0, 0,            /* replaced with offset into relocation table.  */
+  0, 0, 0, 0,            /* + reloc index */
   0x60, 0xff,            /* bra.l .plt */
-  0, 0, 0, 0             /* replaced with offset to start of .plt.  */
+  0, 0, 0, 0             /* + .plt - . */
 };
 
+static const struct elf_m68k_plt_info elf_m68k_plt_info = {
+  PLT_ENTRY_SIZE,
+  elf_m68k_plt0_entry, { 4, 12 },
+  elf_m68k_plt_entry, { 4, 16 }, 8
+};
 
-#define CFV4E_PLT_ENTRY_SIZE 24 
-
-#define CFV4E_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_M68K_CFV4E)
+#define ISAB_PLT_ENTRY_SIZE 24 
 
-static const bfd_byte elf_cfv4e_plt0_entry[CFV4E_PLT_ENTRY_SIZE] =
+static const bfd_byte elf_isab_plt0_entry[ISAB_PLT_ENTRY_SIZE] =
 {
-  0x20, 0x3c,
-  0, 0, 0, 0,             /* Replaced with offset to .got + 4.  */
-  0x2f, 0x3b, 0x08, 0xfa, /* move.l (%pc,addr),-(%sp) */
-  0x20, 0x3c,
-  0, 0, 0, 0,             /* Replaced with offset to .got + 8.  */
-  0x20, 0x7b, 0x08, 0x00, /* move.l (%pc,%d0:l), %a0 */
+  0x20, 0x3c,             /* move.l #offset,%d0 */
+  0, 0, 0, 0,             /* + (.got + 4) - . */
+  0x2f, 0x3b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l),-(%sp) */
+  0x20, 0x3c,             /* move.l #offset,%d0 */
+  0, 0, 0, 0,             /* + (.got + 8) - . */
+  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
   0x4e, 0xd0,             /* jmp (%a0) */
   0x4e, 0x71             /* nop */
 };
 
 /* Subsequent entries in a procedure linkage table look like this.  */
 
-static const bfd_byte elf_cfv4e_plt_entry[CFV4E_PLT_ENTRY_SIZE] =
+static const bfd_byte elf_isab_plt_entry[ISAB_PLT_ENTRY_SIZE] =
 {
-  0x20, 0x3c,
-  0, 0, 0, 0,             /* Replaced with offset to symbol's .got entry.  */
-  0x20, 0x7b, 0x08, 0x00, /* move.l (%pc,%d0:l), %a0 */
+  0x20, 0x3c,             /* move.l #offset,%d0 */
+  0, 0, 0, 0,             /* + (.got.plt entry) - . */
+  0x20, 0x7b, 0x08, 0xfa, /* move.l (-6,%pc,%d0:l), %a0 */
   0x4e, 0xd0,             /* jmp (%a0) */
   0x2f, 0x3c,             /* move.l #offset,-(%sp) */
-  0, 0, 0, 0,             /* Replaced with offset into relocation table.  */
+  0, 0, 0, 0,             /* + reloc index */
   0x60, 0xff,             /* bra.l .plt */
-  0, 0, 0, 0              /* Replaced with offset to start of .plt.  */
+  0, 0, 0, 0              /* + .plt - . */
 };
 
-#define CPU32_FLAG(abfd)  (elf_elfheader (abfd)->e_flags & EF_M68K_CPU32)
+static const struct elf_m68k_plt_info elf_isab_plt_info = {
+  ISAB_PLT_ENTRY_SIZE,
+  elf_isab_plt0_entry, { 2, 12 },
+  elf_isab_plt_entry, { 2, 20 }, 12
+};
 
-#define PLT_CPU32_ENTRY_SIZE 24
+#define CPU32_PLT_ENTRY_SIZE 24
 /* Procedure linkage table entries for the cpu32 */
-static const bfd_byte elf_cpu32_plt0_entry[PLT_CPU32_ENTRY_SIZE] =
+static const bfd_byte elf_cpu32_plt0_entry[CPU32_PLT_ENTRY_SIZE] =
 {
   0x2f, 0x3b, 0x01, 0x70, /* move.l (%pc,addr),-(%sp) */
-  0, 0, 0, 0,             /* replaced with offset to .got + 4.  */
+  0, 0, 0, 2,             /* + (.got + 4) - . */
   0x22, 0x7b, 0x01, 0x70, /* moveal %pc@(0xc), %a1 */
-  0, 0, 0, 0,             /* replace with offset to .got +8.  */
+  0, 0, 0, 2,             /* + (.got + 8) - . */
   0x4e, 0xd1,             /* jmp %a1@ */
   0, 0, 0, 0,             /* pad out to 24 bytes.  */
   0, 0
 };
 
-static const bfd_byte elf_cpu32_plt_entry[PLT_CPU32_ENTRY_SIZE] =
+static const bfd_byte elf_cpu32_plt_entry[CPU32_PLT_ENTRY_SIZE] =
 {
   0x22, 0x7b, 0x01, 0x70,  /* moveal %pc@(0xc), %a1 */
-  0, 0, 0, 0,              /* replaced with offset to symbol's .got entry.  */
+  0, 0, 0, 2,              /* + (.got.plt entry) - . */
   0x4e, 0xd1,              /* jmp %a1@ */
   0x2f, 0x3c,              /* move.l #offset,-(%sp) */
-  0, 0, 0, 0,              /* replaced with offset into relocation table.  */
+  0, 0, 0, 0,              /* + reloc index */
   0x60, 0xff,              /* bra.l .plt */
-  0, 0, 0, 0,              /* replaced with offset to start of .plt.  */
+  0, 0, 0, 0,              /* + .plt - . */
   0, 0
 };
 
+static const struct elf_m68k_plt_info elf_cpu32_plt_info = {
+  CPU32_PLT_ENTRY_SIZE,
+  elf_cpu32_plt0_entry, { 4, 12 },
+  elf_cpu32_plt_entry, { 4, 18 }, 10
+};
+
 /* 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
@@ -315,6 +362,10 @@ struct elf_m68k_link_hash_table
 
   /* Small local sym to section mapping cache.  */
   struct sym_sec_cache sym_sec;
+
+  /* The PLT format used by this link, or NULL if the format has not
+     yet been chosen.  */
+  const struct elf_m68k_plt_info *plt_info;
 };
 
 /* Get the m68k ELF linker hash table from a link_info structure.  */
@@ -370,6 +421,7 @@ elf_m68k_link_hash_table_create (abfd)
     }
 
   ret->sym_sec.abfd = NULL;
+  ret->plt_info = NULL;
 
   return &ret->root.root;
 }
@@ -1070,6 +1122,32 @@ elf_m68k_gc_sweep_hook (abfd, info, sec, relocs)
 
   return TRUE;
 }
+\f
+/* Return the type of PLT associated with OUTPUT_BFD.  */
+
+static const struct elf_m68k_plt_info *
+elf_m68k_get_plt_info (bfd *output_bfd)
+{
+  unsigned int features;
+
+  features = bfd_m68k_mach_to_features (bfd_get_mach (output_bfd));
+  if (features & cpu32)
+    return &elf_cpu32_plt_info;
+  if (features & mcfisa_b)
+    return &elf_isab_plt_info;
+  return &elf_m68k_plt_info;
+}
+
+/* This function is called after all the input files have been read,
+   and the input sections have been assigned to output sections.
+   It's a convenient place to determine the PLT style.  */
+
+static bfd_boolean
+elf_m68k_always_size_sections (bfd *output_bfd, struct bfd_link_info *info)
+{
+  elf_m68k_hash_table (info)->plt_info = elf_m68k_get_plt_info (output_bfd);
+  return TRUE;
+}
 
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
@@ -1082,10 +1160,12 @@ elf_m68k_adjust_dynamic_symbol (info, h)
      struct bfd_link_info *info;
      struct elf_link_hash_entry *h;
 {
+  struct elf_m68k_link_hash_table *htab;
   bfd *dynobj;
   asection *s;
   unsigned int power_of_two;
 
+  htab = elf_m68k_hash_table (info);
   dynobj = elf_hash_table (info)->dynobj;
 
   /* Make sure we know what is going on here.  */
@@ -1135,14 +1215,7 @@ elf_m68k_adjust_dynamic_symbol (info, h)
       /* If this is the first .plt entry, make room for the special
         first entry.  */
       if (s->size == 0)
-       {
-         if (CPU32_FLAG (dynobj))
-           s->size += PLT_CPU32_ENTRY_SIZE;
-         else if (CFV4E_FLAG (dynobj))
-           s->size += CFV4E_PLT_ENTRY_SIZE;
-         else
-           s->size += PLT_ENTRY_SIZE;
-       }
+       s->size = htab->plt_info->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
@@ -1159,12 +1232,7 @@ elf_m68k_adjust_dynamic_symbol (info, h)
       h->plt.offset = s->size;
 
       /* Make room for this entry.  */
-      if (CPU32_FLAG (dynobj))
-        s->size += PLT_CPU32_ENTRY_SIZE;
-      else if (CFV4E_FLAG (dynobj))
-       s->size += CFV4E_PLT_ENTRY_SIZE;
-      else
-        s->size += PLT_ENTRY_SIZE;
+      s->size += htab->plt_info->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.  */
@@ -1909,6 +1977,21 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
   return TRUE;
 }
 
+/* Install an M_68K_PC32 relocation against VALUE at offset OFFSET
+   into section SEC.  */
+
+static void
+elf_m68k_install_pc32 (asection *sec, bfd_vma offset, bfd_vma value)
+{
+  /* Make VALUE PC-relative.  */
+  value -= sec->output_section->vma + offset;
+
+  /* Apply any in-place addend.  */
+  value += bfd_get_32 (sec->owner, sec->contents + offset);
+
+  bfd_put_32 (sec->owner, value, sec->contents + offset);
+}
+
 /* Finish up dynamic symbol handling.  We set the contents of various
    dynamic sections here.  */
 
@@ -1920,12 +2003,12 @@ 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;
 
   if (h->plt.offset != (bfd_vma) -1)
     {
+      const struct elf_m68k_plt_info *plt_info;
       asection *splt;
       asection *sgot;
       asection *srela;
@@ -1939,6 +2022,7 @@ elf_m68k_finish_dynamic_symbol (output_bfd, info, h, sym)
 
       BFD_ASSERT (h->dynindx != -1);
 
+      plt_info = elf_m68k_hash_table (info)->plt_info;
       splt = bfd_get_section_by_name (dynobj, ".plt");
       sgot = bfd_get_section_by_name (dynobj, ".got.plt");
       srela = bfd_get_section_by_name (dynobj, ".rela.plt");
@@ -1948,66 +2032,36 @@ 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.  */
-      if (CPU32_FLAG (output_bfd))
-        plt_index = (h->plt.offset / PLT_CPU32_ENTRY_SIZE) - 1;
-      else if (CFV4E_FLAG (output_bfd))
-       plt_index = (h->plt.offset / CFV4E_PLT_ENTRY_SIZE) - 1;
-      else
-        plt_index = (h->plt.offset / PLT_ENTRY_SIZE) - 1;
+      plt_index = (h->plt.offset / plt_info->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;
 
-      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 if (CFV4E_FLAG (output_bfd))
-        {
-          memcpy (splt->contents + h->plt.offset, elf_cfv4e_plt_entry,
-                 CFV4E_PLT_ENTRY_SIZE);
-          plt_off1 = 2;
-          plt_off2 = 14;
-          plt_off3 = 20;
-       }
-      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
-                 + sgot->output_offset
-                 + got_offset
-                 - (splt->output_section->vma
-                    + h->plt.offset
-                    + (CFV4E_FLAG (output_bfd) ? 8 : 2)),
-                 splt->contents + h->plt.offset + plt_off1);
+      memcpy (splt->contents + h->plt.offset,
+             plt_info->symbol_entry,
+             plt_info->size);
+
+      elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.got,
+                            (sgot->output_section->vma
+                             + sgot->output_offset
+                             + got_offset));
 
       bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
-                 splt->contents + h->plt.offset + plt_off2);
-      bfd_put_32 (output_bfd, - (h->plt.offset + plt_off3),
-                 splt->contents + h->plt.offset + plt_off3);
+                 splt->contents
+                 + h->plt.offset
+                 + plt_info->symbol_resolve_entry + 2);
+
+      elf_m68k_install_pc32 (splt, h->plt.offset + plt_info->symbol_relocs.plt,
+                            splt->output_section->vma);
 
       /* Fill in the entry in the global offset table.  */
       bfd_put_32 (output_bfd,
                  (splt->output_section->vma
                   + splt->output_offset
                   + h->plt.offset
-                  + (CFV4E_FLAG (output_bfd) ? 12 : 8)),
+                  + plt_info->symbol_resolve_entry),
                  sgot->contents + got_offset);
 
       /* Fill in the entry in the .rela.plt section.  */
@@ -2185,54 +2239,23 @@ elf_m68k_finish_dynamic_sections (output_bfd, info)
       /* Fill in the first entry in the procedure linkage table.  */
       if (splt->size > 0)
        {
-         if (CFV4E_FLAG (output_bfd))
-           {
-            memcpy (splt->contents, elf_cfv4e_plt0_entry, CFV4E_PLT_ENTRY_SIZE);
-             bfd_put_32 (output_bfd,
-                         (sgot->output_section->vma
-                          + sgot->output_offset + 4
-                          - (splt->output_section->vma + 2)),
-                         splt->contents + 2);
-             bfd_put_32 (output_bfd,
-                         (sgot->output_section->vma
-                          + sgot->output_offset + 8
-                          - (splt->output_section->vma + 10) - 8),
-                         splt->contents + 12);
-             elf_section_data (splt->output_section)->this_hdr.sh_entsize
-              = CFV4E_PLT_ENTRY_SIZE;
-           }
-         else if (CPU32_FLAG (output_bfd))
-            {
-              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 + 12);
-              elf_section_data (splt->output_section)->this_hdr.sh_entsize
-               = PLT_CPU32_ENTRY_SIZE;
-            }
-          else
-            {
-             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;
-            }
+         const struct elf_m68k_plt_info *plt_info;
+
+         plt_info = elf_m68k_hash_table (info)->plt_info;
+         memcpy (splt->contents, plt_info->plt0_entry, plt_info->size);
+
+         elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got4,
+                                (sgot->output_section->vma
+                                 + sgot->output_offset
+                                 + 4));
+
+         elf_m68k_install_pc32 (splt, plt_info->plt0_relocs.got8,
+                                (sgot->output_section->vma
+                                 + sgot->output_offset
+                                 + 8));
+
+         elf_section_data (splt->output_section)->this_hdr.sh_entsize
+           = plt_info->size;
        }
     }
 
@@ -2401,9 +2424,7 @@ static bfd_vma
 elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
                      const arelent *rel ATTRIBUTE_UNUSED)
 {
-  if (CPU32_FLAG (plt->owner))
-    return plt->vma + (i + 1) * PLT_CPU32_ENTRY_SIZE;
-  return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+  return plt->vma + (i + 1) * elf_m68k_get_plt_info (plt->owner)->size;
 }
 
 #define TARGET_BIG_SYM                 bfd_elf32_m68k_vec
@@ -2417,6 +2438,8 @@ elf_m68k_plt_sym_val (bfd_vma i, const asection *plt,
 #define bfd_elf32_bfd_final_link       bfd_elf_gc_common_final_link
 
 #define elf_backend_check_relocs       elf_m68k_check_relocs
+#define elf_backend_always_size_sections \
+                                       elf_m68k_always_size_sections
 #define elf_backend_adjust_dynamic_symbol \
                                        elf_m68k_adjust_dynamic_symbol
 #define elf_backend_size_dynamic_sections \
index 66a5dac..fb9b87d 100644 (file)
@@ -1,3 +1,10 @@
+2006-06-14  Richard Sandiford  <richard@codesourcery.com>
+
+       * ld-m68k/plt1.s, ld-m68k/plt1-empty.s, ld-m68k/plt1.ld: New files.
+       * ld-m68k/plt1-68020.d, ld-m68k/plt1-cpu32.d: Likewise.
+       * ld-m68k/plt1-isab.d: Likewise.
+       * ld-m68k/m68k.exp: Run new PLT tests.
+
 2006-06-12  Thiemo Seufer  <ths@mips.com>
 
        * ld-mips-elf/multi-got-no-shared.d: Adjust for recent change of
index a1096a8..042f1b9 100644 (file)
@@ -53,3 +53,12 @@ run_dump_test "merge-error-1d"
 run_dump_test "merge-error-1e"
 run_dump_test "merge-ok-1a"
 run_dump_test "merge-ok-1b"
+
+foreach { id sources } { a { plt1.s } b { plt1-empty.s plt1.s } } {
+    foreach arch { 68020 cpu32 isab } {
+       run_ld_link_tests [list \
+           [list "PLT 1$id ($arch)" "-shared -T plt1.ld" "-m$arch" \
+                $sources [list [list objdump -dr plt1-$arch.d]] \
+                plt1-${id}-${arch}.so]]
+    }
+}
diff --git a/ld/testsuite/ld-m68k/plt1-68020.d b/ld/testsuite/ld-m68k/plt1-68020.d
new file mode 100644 (file)
index 0000000..964acb6
--- /dev/null
@@ -0,0 +1,35 @@
+
+.*:     file format elf32-m68k
+
+Disassembly of section \.plt:
+
+00020800 <f.@plt-0x14>:
+   20800:      2f3b 0170 0000  movel %pc@\(30404 <_GLOBAL_OFFSET_TABLE_\+0x4>\),%sp@-
+   20806:      fc02 
+   20808:      4efb 0171 0000  jmp %pc@\(30408 <_GLOBAL_OFFSET_TABLE_\+0x8>\)@\(00000000\)
+   2080e:      fbfe 
+   20810:      0000 0000       orib #0,%d0
+
+00020814 <f.@plt>:
+   20814:      4efb 0171 0000  jmp %pc@\(3040c <_GLOBAL_OFFSET_TABLE_\+0xc>\)@\(00000000\)
+   2081a:      fbf6 
+   2081c:      2f3c 0000 0000  movel #0,%sp@-
+   20822:      60ff ffff ffdc  bral 20800 <f.@plt-0x14>
+
+00020828 <f.@plt>:
+   20828:      4efb 0171 0000  jmp %pc@\(30410 <_GLOBAL_OFFSET_TABLE_\+0x10>\)@\(00000000\)
+   2082e:      fbe6 
+   20830:      2f3c 0000 000c  movel #12,%sp@-
+   20836:      60ff ffff ffc8  bral 20800 <f.@plt-0x14>
+
+0002083c <f.@plt>:
+   2083c:      4efb 0171 0000  jmp %pc@\(30414 <_GLOBAL_OFFSET_TABLE_\+0x14>\)@\(00000000\)
+   20842:      fbd6 
+   20844:      2f3c 0000 0018  movel #24,%sp@-
+   2084a:      60ff ffff ffb4  bral 20800 <f.@plt-0x14>
+Disassembly of section \.text:
+
+00020c00 <.*>:
+   20c00:      61ff ffff fc..  bsrl 208.. <f1@plt>
+   20c06:      61ff ffff fc..  bsrl 208.. <f2@plt>
+   20c0c:      61ff ffff fc..  bsrl 208.. <f3@plt>
diff --git a/ld/testsuite/ld-m68k/plt1-cpu32.d b/ld/testsuite/ld-m68k/plt1-cpu32.d
new file mode 100644 (file)
index 0000000..a497740
--- /dev/null
@@ -0,0 +1,43 @@
+
+.*:     file format elf32-m68k
+
+Disassembly of section \.plt:
+
+00020800 <f.@plt-0x18>:
+   20800:      2f3b 0170 0000  movel %pc@\(30404 <_GLOBAL_OFFSET_TABLE_\+0x4>\),%sp@-
+   20806:      fc02 
+   20808:      227b 0170 0000  moveal %pc@\(30408 <_GLOBAL_OFFSET_TABLE_\+0x8>\),%a1
+   2080e:      fbfe 
+   20810:      4ed1            jmp %a1@
+   20812:      0000 0000       orib #0,%d0
+       \.\.\.
+
+00020818 <f.@plt>:
+   20818:      227b 0170 0000  moveal %pc@\(3040c <_GLOBAL_OFFSET_TABLE_\+0xc>\),%a1
+   2081e:      fbf2 
+   20820:      4ed1            jmp %a1@
+   20822:      2f3c 0000 0000  movel #0,%sp@-
+   20828:      60ff ffff ffd6  bral 20800 <f.@plt-0x18>
+       \.\.\.
+
+00020830 <f.@plt>:
+   20830:      227b 0170 0000  moveal %pc@\(30410 <_GLOBAL_OFFSET_TABLE_\+0x10>\),%a1
+   20836:      fbde 
+   20838:      4ed1            jmp %a1@
+   2083a:      2f3c 0000 000c  movel #12,%sp@-
+   20840:      60ff ffff ffbe  bral 20800 <f.@plt-0x18>
+       \.\.\.
+
+00020848 <f.@plt>:
+   20848:      227b 0170 0000  moveal %pc@\(30414 <_GLOBAL_OFFSET_TABLE_\+0x14>\),%a1
+   2084e:      fbca 
+   20850:      4ed1            jmp %a1@
+   20852:      2f3c 0000 0018  movel #24,%sp@-
+   20858:      60ff ffff ffa6  bral 20800 <f.@plt-0x18>
+       \.\.\.
+Disassembly of section \.text:
+
+00020c00 <.*>:
+   20c00:      61ff ffff fc..  bsrl 208.. <f1@plt>
+   20c06:      61ff ffff fc..  bsrl 208.. <f2@plt>
+   20c0c:      61ff ffff fc..  bsrl 208.. <f3@plt>
diff --git a/ld/testsuite/ld-m68k/plt1-empty.s b/ld/testsuite/ld-m68k/plt1-empty.s
new file mode 100644 (file)
index 0000000..a59477d
--- /dev/null
@@ -0,0 +1,3 @@
+       .text
+       .globl  foo
+foo:
diff --git a/ld/testsuite/ld-m68k/plt1-isab.d b/ld/testsuite/ld-m68k/plt1-isab.d
new file mode 100644 (file)
index 0000000..a9aeacb
--- /dev/null
@@ -0,0 +1,44 @@
+
+.*:     file format elf32-m68k
+
+Disassembly of section \.plt:
+
+00020800 <f.@plt-0x18>:
+# _GLOBAL_OFFSET_TABLE_ + 4 == 0x30404 == 0x20802 + 0xfc02
+   20800:      203c 0000 fc02  movel #64514,%d0
+   20806:      2f3b 08fa       movel %pc@\(20802 <f.@plt-0x16>,%d0:l\),%sp@-
+# _GLOBAL_OFFSET_TABLE_ + 8 == 0x30408 == 0x2080c + 0xfbfc
+   2080a:      203c 0000 fbfc  movel #64508,%d0
+   20810:      207b 08fa       moveal %pc@\(2080c <f.@plt-0xc>,%d0:l\),%a0
+   20814:      4ed0            jmp %a0@
+   20816:      4e71            nop
+
+00020818 <f.@plt>:
+# _GLOBAL_OFFSET_TABLE_ + 12 == 0x3040c == 0x2081a + 0xfbf2
+   20818:      203c 0000 fbf2  movel #64498,%d0
+   2081e:      207b 08fa       moveal %pc@\(2081a <f.@plt\+0x2>,%d0:l\),%a0
+   20822:      4ed0            jmp %a0@
+   20824:      2f3c 0000 0000  movel #0,%sp@-
+   2082a:      60ff ffff ffd4  bral 20800 <f.@plt-0x18>
+
+00020830 <f.@plt>:
+# _GLOBAL_OFFSET_TABLE_ + 16 == 0x30410 == 0x20832 + 0xfbde
+   20830:      203c 0000 fbde  movel #64478,%d0
+   20836:      207b 08fa       moveal %pc@\(20832 <f.@plt\+0x2>,%d0:l\),%a0
+   2083a:      4ed0            jmp %a0@
+   2083c:      2f3c 0000 000c  movel #12,%sp@-
+   20842:      60ff ffff ffbc  bral 20800 <f.@plt-0x18>
+
+00020848 <f.@plt>:
+# _GLOBAL_OFFSET_TABLE_ + 20 == 0x30414 == 0x2084a + 0xfbca
+   20848:      203c 0000 fbca  movel #64458,%d0
+   2084e:      207b 08fa       moveal %pc@\(2084a <f.@plt\+0x2>,%d0:l\),%a0
+   20852:      4ed0            jmp %a0@
+   20854:      2f3c 0000 0018  movel #24,%sp@-
+   2085a:      60ff ffff ffa4  bral 20800 <f.@plt-0x18>
+Disassembly of section \.text:
+
+00020c00 <.*>:
+   20c00:      61ff ffff fc..  bsrl 208.. <f1@plt>
+   20c06:      61ff ffff fc..  bsrl 208.. <f2@plt>
+   20c0c:      61ff ffff fc..  bsrl 208.. <f3@plt>
diff --git a/ld/testsuite/ld-m68k/plt1.ld b/ld/testsuite/ld-m68k/plt1.ld
new file mode 100644 (file)
index 0000000..718e2ad
--- /dev/null
@@ -0,0 +1,23 @@
+SECTIONS
+{
+  . = 0x20000;
+  .interp : { *(.interp) }
+  .hash : { *(.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+
+  . = ALIGN (0x400);
+  .rela.plt : { *(.rela.plt) }
+
+  . = ALIGN (0x400);
+  .plt : { *(.plt) }
+
+  . = ALIGN (0x400);
+  .text : { *(.text) }
+
+  . = ALIGN (0x10000);
+  .dynamic : { *(.dynamic) }
+
+  . = ALIGN (0x400);
+  .got : { *(.got.plt) *(.got) }
+}
diff --git a/ld/testsuite/ld-m68k/plt1.s b/ld/testsuite/ld-m68k/plt1.s
new file mode 100644 (file)
index 0000000..855fb19
--- /dev/null
@@ -0,0 +1,3 @@
+       bsr.l   f1@PLTPC
+       bsr.l   f2@PLTPC
+       bsr.l   f3@PLTPC