PR20744, Incorrect PowerPC VLE relocs
authorAlan Modra <amodra@gmail.com>
Tue, 22 Nov 2016 08:15:29 +0000 (18:45 +1030)
committerAlan Modra <amodra@gmail.com>
Tue, 22 Nov 2016 09:49:29 +0000 (20:19 +1030)
VLE 16A and 16D relocs were functionally swapped.

PR 20744
include/
* opcode/ppc.h: Define VLE insns using 16A and 16D relocs.
bfd/
* elf32-ppc.h (struct ppc_elf_params): Add vle_reloc_fixup field.
* elf32-ppc.c: Include opcode/ppc.h.
(ppc_elf_howto_raw): Correct dst_mask for R_PPC_VLE_LO16A,
R_PPC_VLE_LO16D, R_PPC_VLE_HI16A, R_PPC_VLE_HI16D, R_PPC_VLE_HA16A,
R_PPC_VLE_HA16D, R_PPC_VLE_SDAREL_LO16A, R_PPC_VLE_SDAREL_LO16D,
R_PPC_VLE_SDAREL_HI16A, R_PPC_VLE_SDAREL_HI16D,
R_PPC_VLE_SDAREL_HA16A, and R_PPC_VLE_SDAREL_HA16D relocs.
(ppc_elf_link_hash_table_create): Update default_params init.
(ppc_elf_vle_split16): Correct shift and mask.  Add params.
Report or fix insn/reloc mismatches.
(ppc_elf_relocate_section): Pass input_section, offset and fixup
to ppc_elf_vle_split16.
binutils/
* NEWS: Mention PowerPC VLE relocation error.
gas/
* config/tc-ppc.c: Delete VLE insn defines.
(md_assemble): Swap use_a_reloc and use_d_reloc.
* testsuite/gas/ppc/vle-reloc.d: Update.
ld/
* emultempl/ppc32elf.em (params): Update initializer.  Handle
--vle-reloc-fixup command line arg.

12 files changed:
bfd/ChangeLog
bfd/elf32-ppc.c
bfd/elf32-ppc.h
binutils/ChangeLog
binutils/NEWS
gas/ChangeLog
gas/config/tc-ppc.c
gas/testsuite/gas/ppc/vle-reloc.d
include/ChangeLog
include/opcode/ppc.h
ld/ChangeLog
ld/emultempl/ppc32elf.em

index c3283ea7ebc9f55016e693b7db57789a25c1de36..ebf827948023af1f913638d8fec856b3d0916745 100644 (file)
@@ -1,3 +1,19 @@
+2016-11-22  Alan Modra  <amodra@gmail.com>
+
+       PR 20744
+       * elf32-ppc.h (struct ppc_elf_params): Add vle_reloc_fixup field.
+       * elf32-ppc.c: Include opcode/ppc.h.
+       (ppc_elf_howto_raw): Correct dst_mask for R_PPC_VLE_LO16A,
+       R_PPC_VLE_LO16D, R_PPC_VLE_HI16A, R_PPC_VLE_HI16D, R_PPC_VLE_HA16A,
+       R_PPC_VLE_HA16D, R_PPC_VLE_SDAREL_LO16A, R_PPC_VLE_SDAREL_LO16D,
+       R_PPC_VLE_SDAREL_HI16A, R_PPC_VLE_SDAREL_HI16D,
+       R_PPC_VLE_SDAREL_HA16A, and R_PPC_VLE_SDAREL_HA16D relocs.
+       (ppc_elf_link_hash_table_create): Update default_params init.
+       (ppc_elf_vle_split16): Correct shift and mask.  Add params.
+       Report or fix insn/reloc mismatches.
+       (ppc_elf_relocate_section): Pass input_section, offset and fixup
+       to ppc_elf_vle_split16.
+
 2016-11-22  Alan Modra  <amodra@gmail.com>
 
        * elf32-ppc.c (ppc64_elf_relocate_section): Calculate d_offset for
index 75b0478d2b82ba89b623e50f17bde14d30a3a859..efe7f69b83ca828b5cbe59a97ebe553511b1472f 100644 (file)
@@ -35,6 +35,7 @@
 #include "elf32-ppc.h"
 #include "elf-vxworks.h"
 #include "dwarf2.h"
+#include "opcode/ppc.h"
 
 typedef enum split16_format_type
 {
@@ -1455,7 +1456,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_LO16A",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f007ff,             /* dst_mask */
+        0x1f07ff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* The 16 LSBS in split16d format.  */
@@ -1470,7 +1471,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_LO16D",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
+        0x1f007ff,             /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* Bits 16-31 split16a format.  */
@@ -1485,7 +1486,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_HI16A",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f007ff,             /* dst_mask */
+        0x1f07ff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* Bits 16-31 split16d format.  */
@@ -1500,7 +1501,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_HI16D",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
+        0x1f007ff,             /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* Bits 16-31 (High Adjusted) in split16a format.  */
@@ -1515,7 +1516,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_HA16A",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f007ff,             /* dst_mask */
+        0x1f07ff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* Bits 16-31 (High Adjusted) in split16d format.  */
@@ -1530,7 +1531,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_HA16D",     /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
+        0x1f007ff,             /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* This reloc is like R_PPC_EMB_SDA21 but only applies to e_add16i
@@ -1577,7 +1578,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_SDAREL_LO16A", /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f007ff,             /* dst_mask */
+        0x1f07ff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* The 16 LSBS relative to _SDA_BASE_ in split16d format.  */
@@ -1592,7 +1593,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_SDAREL_LO16D", /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
+        0x1f007ff,             /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* Bits 16-31 relative to _SDA_BASE_ in split16a format.  */
@@ -1607,7 +1608,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_SDAREL_HI16A", /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f007ff,             /* dst_mask */
+        0x1f07ff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* Bits 16-31 relative to _SDA_BASE_ in split16d format.  */
@@ -1622,7 +1623,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_SDAREL_HI16D", /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
+        0x1f007ff,             /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* Bits 16-31 (HA) relative to _SDA_BASE split16a format.  */
@@ -1637,7 +1638,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_SDAREL_HA16A", /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f007ff,             /* dst_mask */
+        0x1f07ff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   /* Bits 16-31 (HA) relative to _SDA_BASE split16d format.  */
@@ -1652,7 +1653,7 @@ static reloc_howto_type ppc_elf_howto_raw[] = {
         "R_PPC_VLE_SDAREL_HA16D", /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
-        0x1f07ff,              /* dst_mask */
+        0x1f007ff,             /* dst_mask */
         FALSE),                /* pcrel_offset */
 
   HOWTO (R_PPC_IRELATIVE,      /* type */
@@ -3384,7 +3385,7 @@ ppc_elf_link_hash_table_create (bfd *abfd)
 {
   struct ppc_elf_link_hash_table *ret;
   static struct ppc_elf_params default_params
-    = { PLT_OLD, 0, 1, 0, 0, 12, 0, 0 };
+    = { PLT_OLD, 0, 1, 0, 0, 12, 0, 0, 0 };
 
   ret = bfd_zmalloc (sizeof (struct ppc_elf_link_hash_table));
   if (ret == NULL)
@@ -4925,16 +4926,56 @@ ppc_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 
 static void
 ppc_elf_vle_split16 (bfd *input_bfd,
+                    asection *input_section,
+                    unsigned long offset,
                     bfd_byte *loc,
                     bfd_vma value,
-                    split16_format_type split16_format)
+                    split16_format_type split16_format,
+                    bfd_boolean fixup)
 {
-  unsigned int insn, top5;
+  unsigned int insn, opcode, top5;
 
   insn = bfd_get_32 (input_bfd, loc);
+  opcode = insn & 0xf300f800;
+  if (opcode == E_OR2I_INSN
+      || opcode == E_AND2I_DOT_INSN
+      || opcode == E_OR2IS_INSN
+      || opcode == E_LIS_INSN
+      || opcode == E_AND2IS_DOT_INSN)
+    {
+      if (split16_format != split16a_type)
+       {
+         if (fixup)
+           split16_format = split16a_type;
+         else
+           _bfd_error_handler
+             /* xgettext:c-format */
+             (_("%B(%A+0x%lx): expected 16A style relocation on 0x%08x insn"),
+              input_bfd, input_section, offset, opcode);
+       }
+    }
+  else if (opcode == E_ADD2I_DOT_INSN
+          || opcode == E_ADD2IS_INSN
+          || opcode == E_CMP16I_INSN
+          || opcode == E_MULL2I_INSN
+          || opcode == E_CMPL16I_INSN
+          || opcode == E_CMPH16I_INSN
+          || opcode == E_CMPHL16I_INSN)
+    {
+      if (split16_format != split16d_type)
+       {
+         if (fixup)
+           split16_format = split16d_type;
+         else
+           _bfd_error_handler
+             /* xgettext:c-format */
+             (_("%B(%A+0x%lx): expected 16D style relocation on 0x%08x insn"),
+              input_bfd, input_section, offset, opcode);
+       }
+    }
   top5 = value & 0xf800;
-  top5 = top5 << (split16_format == split16a_type ? 9 : 5);
-  insn &= (split16_format == split16a_type ? ~0x1f007ff : ~0x1f07ff);
+  top5 = top5 << (split16_format == split16a_type ? 5 : 9);
+  insn &= (split16_format == split16a_type ? ~0x1f07ff : ~0x1f007ff);
   insn |= top5;
   insn |= value & 0x7ff;
   bfd_put_32 (input_bfd, insn, loc);
@@ -9220,38 +9261,44 @@ ppc_elf_relocate_section (bfd *output_bfd,
 
        case R_PPC_VLE_LO16A:
          relocation = relocation + addend;
-         ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                              relocation, split16a_type);
+         ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                              contents + rel->r_offset, relocation,
+                              split16a_type, htab->params->vle_reloc_fixup);
          goto copy_reloc;
 
        case R_PPC_VLE_LO16D:
          relocation = relocation + addend;
-         ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                              relocation, split16d_type);
+         ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                              contents + rel->r_offset, relocation,
+                              split16d_type, htab->params->vle_reloc_fixup);
          goto copy_reloc;
 
        case R_PPC_VLE_HI16A:
          relocation = (relocation + addend) >> 16;
-         ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                              relocation, split16a_type);
+         ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                              contents + rel->r_offset, relocation,
+                              split16a_type, htab->params->vle_reloc_fixup);
          goto copy_reloc;
 
        case R_PPC_VLE_HI16D:
          relocation = (relocation + addend) >> 16;
-         ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                              relocation, split16d_type);
+         ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                              contents + rel->r_offset, relocation,
+                              split16d_type, htab->params->vle_reloc_fixup);
          goto copy_reloc;
 
        case R_PPC_VLE_HA16A:
          relocation = (relocation + addend + 0x8000) >> 16;
-         ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                              relocation, split16a_type);
+         ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                              contents + rel->r_offset, relocation,
+                              split16a_type, htab->params->vle_reloc_fixup);
          goto copy_reloc;
 
        case R_PPC_VLE_HA16D:
          relocation = (relocation + addend + 0x8000) >> 16;
-         ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                              relocation, split16d_type);
+         ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                              contents + rel->r_offset, relocation,
+                              split16d_type, htab->params->vle_reloc_fixup);
          goto copy_reloc;
 
          /* Relocate against either _SDA_BASE_, _SDA2_BASE_, or 0.  */
@@ -9414,34 +9461,46 @@ ppc_elf_relocate_section (bfd *output_bfd,
                     + addend);
 
            if (r_type == R_PPC_VLE_SDAREL_LO16A)
-             ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                                  value, split16a_type);
+             ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                                  contents + rel->r_offset, value,
+                                  split16a_type,
+                                  htab->params->vle_reloc_fixup);
            else if (r_type == R_PPC_VLE_SDAREL_LO16D)
-             ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                                  value, split16d_type);
+             ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                                  contents + rel->r_offset, value,
+                                  split16d_type,
+                                  htab->params->vle_reloc_fixup);
            else if (r_type == R_PPC_VLE_SDAREL_HI16A)
              {
                value = value >> 16;
-               ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                                    value, split16a_type);
+               ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                                    contents + rel->r_offset, value,
+                                    split16a_type,
+                                    htab->params->vle_reloc_fixup);
              }
            else if (r_type == R_PPC_VLE_SDAREL_HI16D)
              {
                value = value >> 16;
-               ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                                    value, split16d_type);
+               ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                                    contents + rel->r_offset, value,
+                                    split16d_type,
+                                    htab->params->vle_reloc_fixup);
              }
            else if (r_type == R_PPC_VLE_SDAREL_HA16A)
              {
                value = (value + 0x8000) >> 16;
-               ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                                    value, split16a_type);
+               ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                                    contents + rel->r_offset, value,
+                                    split16a_type,
+                                    htab->params->vle_reloc_fixup);
              }
            else if (r_type == R_PPC_VLE_SDAREL_HA16D)
              {
                value = (value + 0x8000) >> 16;
-               ppc_elf_vle_split16 (input_bfd, contents + rel->r_offset,
-                                    value, split16d_type);
+               ppc_elf_vle_split16 (input_bfd, input_section, rel->r_offset,
+                                    contents + rel->r_offset, value,
+                                    split16d_type,
+                                    htab->params->vle_reloc_fixup);
              }
          }
          goto copy_reloc;
index 5f3a88b3d430f897969aa10febfae23422c5edcf..0351a2b3a489bcc5c4cbc9a5f11a3a9743407628 100644 (file)
@@ -49,6 +49,9 @@ struct ppc_elf_params
      defined in a shared library.  */
   int pic_fixup;
 
+  /* Relocate 16A relocs as 16D and vice versa.  */
+  int vle_reloc_fixup;
+
   bfd_vma pagesize;
 };
 
index bbeec9c192829130b03f34091a5056bb43fb621a..ef923cbba15bddf9305c4d0cc20e76776852cdb6 100644 (file)
@@ -1,3 +1,8 @@
+2016-11-22  Alan Modra  <amodra@gmail.com>
+
+       PR 20744
+       * NEWS: Mention PowerPC VLE relocation error.
+
 2016-11-16  Mark Wielaard  <mark@klomp.org>
 
        * cxxfilt.c (main): Recognize rust_demangling.
index 5d0bc89bb5dc57098414f09f6fc7de420cb5a764..4e1aacd815424d7bd306ec6aecfad69edb8537f4 100644 (file)
@@ -1,6 +1,19 @@
 -*- text -*-
 
-* The nm program has a new command lien option (--with-version-strings)
+* This version of binutils fixes a problem with PowerPC VLE 16A and 16D
+  relocations which were functionally swapped, for example,
+  R_PPC_VLE_HA16A performed like R_PPC_VLE_HA16D while R_PPC_VLE_HA16D
+  performed like R_PPC_VLE_HA16A.  This could have been fixed by
+  renumbering relocations, which would keep object files created by an
+  older version of gas compatible with a newer ld.  However, that would
+  require an ABI update, affecting other assemblers and linkers that
+  create and process the relocations correctly.  It is recommended that
+  all VLE object files be recompiled, but ld can modify the relocations
+  if --vle-reloc-fixup is passed to ld.  If the new ld command line
+  option is not used, ld will ld warn on finding relocations inconsistent
+  with the instructions being relocated.
+
+* The nm program has a new command line option (--with-version-strings)
   which will display a symbol's version information, if any, after the
   symbol's name.
 
index 134f24b5118f5aaf4ae8e4648d8561c2aeebb0bc..71cc677dd715a62edff377d0955278f81a4a7be5 100644 (file)
@@ -1,3 +1,10 @@
+2016-11-22  Alan Modra  <amodra@gmail.com>
+
+       PR 20744
+       * config/tc-ppc.c: Delete VLE insn defines.
+       (md_assemble): Swap use_a_reloc and use_d_reloc.
+       * testsuite/gas/ppc/vle-reloc.d: Update.
+
 2016-11-21  Renlin Li  <renlin.li@arm.com>
 
        PR gas/20827
index 5c7b09f02bced5b9ecba4bfa6b2e45bf98ee659a..84d4ebc754ce8be5a21c7bfe08680ea88c3f2a62 100644 (file)
@@ -2617,22 +2617,6 @@ struct ppc_fixup
 
 #define MAX_INSN_FIXUPS (5)
 
-/* Form I16L.  */
-#define E_OR2I_INSN            0x7000C000
-#define E_AND2I_DOT_INSN       0x7000C800
-#define E_OR2IS_INSN           0x7000D000
-#define E_LIS_INSN             0x7000E000
-#define        E_AND2IS_DOT_INSN       0x7000E800
-
-/* Form I16A.  */
-#define E_ADD2I_DOT_INSN       0x70008800
-#define E_ADD2IS_INSN          0x70009000
-#define E_CMP16I_INSN          0x70009800
-#define E_MULL2I_INSN          0x7000A000
-#define E_CMPL16I_INSN         0x7000A800
-#define E_CMPH16I_INSN         0x7000B000
-#define E_CMPHL16I_INSN                0x7000B800
-
 /* This routine is called for each instruction to be assembled.  */
 
 void
@@ -3113,14 +3097,14 @@ md_assemble (char *str)
                {
                  int tmp_insn = insn & opcode->mask;
 
-                 int use_d_reloc = (tmp_insn == E_OR2I_INSN
+                 int use_a_reloc = (tmp_insn == E_OR2I_INSN
                                     || tmp_insn == E_AND2I_DOT_INSN
                                     || tmp_insn == E_OR2IS_INSN
                                     || tmp_insn == E_LIS_INSN
                                     || tmp_insn == E_AND2IS_DOT_INSN);
 
 
-                 int use_a_reloc = (tmp_insn == E_ADD2I_DOT_INSN
+                 int use_d_reloc = (tmp_insn == E_ADD2I_DOT_INSN
                                     || tmp_insn == E_ADD2IS_INSN
                                     || tmp_insn == E_CMP16I_INSN
                                     || tmp_insn == E_MULL2I_INSN
index 01eba4af9eb1c546fb713b96b144c673ba3ff1da..dad153f52caa1236dc5123be748a88a7f11cb4ea 100644 (file)
@@ -25,148 +25,148 @@ Disassembly of section \.text:
                        14: R_PPC_VLE_REL15     sub5
 
   18:  70 20 c0 00     e_or2i  r1,0
-                       18: R_PPC_VLE_LO16D     low
+                       18: R_PPC_VLE_LO16A     low
   1c:  70 40 c0 00     e_or2i  r2,0
-                       1c: R_PPC_VLE_HI16D     high
+                       1c: R_PPC_VLE_HI16A     high
   20:  70 60 c0 00     e_or2i  r3,0
-                       20: R_PPC_VLE_HA16D     high_adjust
+                       20: R_PPC_VLE_HA16A     high_adjust
   24:  70 80 c0 00     e_or2i  r4,0
-                       24: R_PPC_VLE_SDAREL_LO16D      low_sdarel
+                       24: R_PPC_VLE_SDAREL_LO16A      low_sdarel
   28:  70 a0 c0 00     e_or2i  r5,0
-                       28: R_PPC_VLE_SDAREL_HI16D      high_sdarel
+                       28: R_PPC_VLE_SDAREL_HI16A      high_sdarel
   2c:  70 40 c0 00     e_or2i  r2,0
-                       2c: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
+                       2c: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
   30:  70 20 c8 00     e_and2i. r1,0
-                       30: R_PPC_VLE_LO16D     low
+                       30: R_PPC_VLE_LO16A     low
   34:  70 40 c8 00     e_and2i. r2,0
-                       34: R_PPC_VLE_HI16D     high
+                       34: R_PPC_VLE_HI16A     high
   38:  70 60 c8 00     e_and2i. r3,0
-                       38: R_PPC_VLE_HA16D     high_adjust
+                       38: R_PPC_VLE_HA16A     high_adjust
   3c:  70 80 c8 00     e_and2i. r4,0
-                       3c: R_PPC_VLE_SDAREL_LO16D      low_sdarel
+                       3c: R_PPC_VLE_SDAREL_LO16A      low_sdarel
   40:  70 a0 c8 00     e_and2i. r5,0
-                       40: R_PPC_VLE_SDAREL_HI16D      high_sdarel
+                       40: R_PPC_VLE_SDAREL_HI16A      high_sdarel
   44:  70 40 c8 00     e_and2i. r2,0
-                       44: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
+                       44: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
   48:  70 40 c8 00     e_and2i. r2,0
-                       48: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
+                       48: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
   4c:  70 20 d0 00     e_or2is r1,0
-                       4c: R_PPC_VLE_LO16D     low
+                       4c: R_PPC_VLE_LO16A     low
   50:  70 40 d0 00     e_or2is r2,0
-                       50: R_PPC_VLE_HI16D     high
+                       50: R_PPC_VLE_HI16A     high
   54:  70 60 d0 00     e_or2is r3,0
-                       54: R_PPC_VLE_HA16D     high_adjust
+                       54: R_PPC_VLE_HA16A     high_adjust
   58:  70 80 d0 00     e_or2is r4,0
-                       58: R_PPC_VLE_SDAREL_LO16D      low_sdarel
+                       58: R_PPC_VLE_SDAREL_LO16A      low_sdarel
   5c:  70 a0 d0 00     e_or2is r5,0
-                       5c: R_PPC_VLE_SDAREL_HI16D      high_sdarel
+                       5c: R_PPC_VLE_SDAREL_HI16A      high_sdarel
   60:  70 40 d0 00     e_or2is r2,0
-                       60: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
+                       60: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
   64:  70 20 e0 00     e_lis   r1,0
-                       64: R_PPC_VLE_LO16D     low
+                       64: R_PPC_VLE_LO16A     low
   68:  70 40 e0 00     e_lis   r2,0
-                       68: R_PPC_VLE_HI16D     high
+                       68: R_PPC_VLE_HI16A     high
   6c:  70 60 e0 00     e_lis   r3,0
-                       6c: R_PPC_VLE_HA16D     high_adjust
+                       6c: R_PPC_VLE_HA16A     high_adjust
   70:  70 80 e0 00     e_lis   r4,0
-                       70: R_PPC_VLE_SDAREL_LO16D      low_sdarel
+                       70: R_PPC_VLE_SDAREL_LO16A      low_sdarel
   74:  70 a0 e0 00     e_lis   r5,0
-                       74: R_PPC_VLE_SDAREL_HI16D      high_sdarel
+                       74: R_PPC_VLE_SDAREL_HI16A      high_sdarel
   78:  70 40 e0 00     e_lis   r2,0
-                       78: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
+                       78: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
   7c:  70 20 e8 00     e_and2is. r1,0
-                       7c: R_PPC_VLE_LO16D     low
+                       7c: R_PPC_VLE_LO16A     low
   80:  70 40 e8 00     e_and2is. r2,0
-                       80: R_PPC_VLE_HI16D     high
+                       80: R_PPC_VLE_HI16A     high
   84:  70 60 e8 00     e_and2is. r3,0
-                       84: R_PPC_VLE_HA16D     high_adjust
+                       84: R_PPC_VLE_HA16A     high_adjust
   88:  70 80 e8 00     e_and2is. r4,0
-                       88: R_PPC_VLE_SDAREL_LO16D      low_sdarel
+                       88: R_PPC_VLE_SDAREL_LO16A      low_sdarel
   8c:  70 a0 e8 00     e_and2is. r5,0
-                       8c: R_PPC_VLE_SDAREL_HI16D      high_sdarel
+                       8c: R_PPC_VLE_SDAREL_HI16A      high_sdarel
   90:  70 40 e8 00     e_and2is. r2,0
-                       90: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
+                       90: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
   94:  70 01 98 00     e_cmp16i r1,0
-                       94: R_PPC_VLE_LO16A     low
+                       94: R_PPC_VLE_LO16D     low
   98:  70 02 98 00     e_cmp16i r2,0
-                       98: R_PPC_VLE_HI16A     high
+                       98: R_PPC_VLE_HI16D     high
   9c:  70 03 98 00     e_cmp16i r3,0
-                       9c: R_PPC_VLE_HA16A     high_adjust
+                       9c: R_PPC_VLE_HA16D     high_adjust
   a0:  70 04 98 00     e_cmp16i r4,0
-                       a0: R_PPC_VLE_SDAREL_LO16A      low_sdarel
+                       a0: R_PPC_VLE_SDAREL_LO16D      low_sdarel
   a4:  70 05 98 00     e_cmp16i r5,0
-                       a4: R_PPC_VLE_SDAREL_HI16A      high_sdarel
+                       a4: R_PPC_VLE_SDAREL_HI16D      high_sdarel
   a8:  70 02 98 00     e_cmp16i r2,0
-                       a8: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
+                       a8: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
   ac:  70 01 a8 00     e_cmpl16i r1,0
-                       ac: R_PPC_VLE_LO16A     low
+                       ac: R_PPC_VLE_LO16D     low
   b0:  70 02 a8 00     e_cmpl16i r2,0
-                       b0: R_PPC_VLE_HI16A     high
+                       b0: R_PPC_VLE_HI16D     high
   b4:  70 03 a8 00     e_cmpl16i r3,0
-                       b4: R_PPC_VLE_HA16A     high_adjust
+                       b4: R_PPC_VLE_HA16D     high_adjust
   b8:  70 04 a8 00     e_cmpl16i r4,0
-                       b8: R_PPC_VLE_SDAREL_LO16A      low_sdarel
+                       b8: R_PPC_VLE_SDAREL_LO16D      low_sdarel
   bc:  70 05 a8 00     e_cmpl16i r5,0
-                       bc: R_PPC_VLE_SDAREL_HI16A      high_sdarel
+                       bc: R_PPC_VLE_SDAREL_HI16D      high_sdarel
   c0:  70 02 a8 00     e_cmpl16i r2,0
-                       c0: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
+                       c0: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
   c4:  70 01 b0 00     e_cmph16i r1,0
-                       c4: R_PPC_VLE_LO16A     low
+                       c4: R_PPC_VLE_LO16D     low
   c8:  70 02 b0 00     e_cmph16i r2,0
-                       c8: R_PPC_VLE_HI16A     high
+                       c8: R_PPC_VLE_HI16D     high
   cc:  70 03 b0 00     e_cmph16i r3,0
-                       cc: R_PPC_VLE_HA16A     high_adjust
+                       cc: R_PPC_VLE_HA16D     high_adjust
   d0:  70 04 b0 00     e_cmph16i r4,0
-                       d0: R_PPC_VLE_SDAREL_LO16A      low_sdarel
+                       d0: R_PPC_VLE_SDAREL_LO16D      low_sdarel
   d4:  70 05 b0 00     e_cmph16i r5,0
-                       d4: R_PPC_VLE_SDAREL_HI16A      high_sdarel
+                       d4: R_PPC_VLE_SDAREL_HI16D      high_sdarel
   d8:  70 02 b0 00     e_cmph16i r2,0
-                       d8: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
+                       d8: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
   dc:  70 01 b8 00     e_cmphl16i r1,0
-                       dc: R_PPC_VLE_LO16A     low
+                       dc: R_PPC_VLE_LO16D     low
   e0:  70 02 b8 00     e_cmphl16i r2,0
-                       e0: R_PPC_VLE_HI16A     high
+                       e0: R_PPC_VLE_HI16D     high
   e4:  70 03 b8 00     e_cmphl16i r3,0
-                       e4: R_PPC_VLE_HA16A     high_adjust
+                       e4: R_PPC_VLE_HA16D     high_adjust
   e8:  70 04 b8 00     e_cmphl16i r4,0
-                       e8: R_PPC_VLE_SDAREL_LO16A      low_sdarel
+                       e8: R_PPC_VLE_SDAREL_LO16D      low_sdarel
   ec:  70 05 b8 00     e_cmphl16i r5,0
-                       ec: R_PPC_VLE_SDAREL_HI16A      high_sdarel
+                       ec: R_PPC_VLE_SDAREL_HI16D      high_sdarel
   f0:  70 02 b8 00     e_cmphl16i r2,0
-                       f0: R_PPC_VLE_SDAREL_HA16A      high_adjust_sdarel
+                       f0: R_PPC_VLE_SDAREL_HA16D      high_adjust_sdarel
   f4:  70 01 88 00     e_add2i. r1,0
-                       f4: R_PPC_VLE_LO16A     low
+                       f4: R_PPC_VLE_LO16D     low
   f8:  70 02 88 00     e_add2i. r2,0
-                       f8: R_PPC_VLE_HI16A     high
+                       f8: R_PPC_VLE_HI16D     high
   fc:  70 03 88 00     e_add2i. r3,0
-                       fc: R_PPC_VLE_HA16A     high_adjust
+                       fc: R_PPC_VLE_HA16D     high_adjust
  100:  70 04 88 00     e_add2i. r4,0
-                       100: R_PPC_VLE_SDAREL_LO16A     low_sdarel
+                       100: R_PPC_VLE_SDAREL_LO16D     low_sdarel
  104:  70 05 88 00     e_add2i. r5,0
-                       104: R_PPC_VLE_SDAREL_HI16A     high_sdarel
+                       104: R_PPC_VLE_SDAREL_HI16D     high_sdarel
  108:  70 02 88 00     e_add2i. r2,0
-                       108: R_PPC_VLE_SDAREL_HA16A     high_adjust_sdarel
+                       108: R_PPC_VLE_SDAREL_HA16D     high_adjust_sdarel
  10c:  70 01 90 00     e_add2is r1,0
-                       10c: R_PPC_VLE_LO16A    low
+                       10c: R_PPC_VLE_LO16D    low
  110:  70 02 90 00     e_add2is r2,0
-                       110: R_PPC_VLE_HI16A    high
+                       110: R_PPC_VLE_HI16D    high
  114:  70 03 90 00     e_add2is r3,0
-                       114: R_PPC_VLE_HA16A    high_adjust
+                       114: R_PPC_VLE_HA16D    high_adjust
  118:  70 04 90 00     e_add2is r4,0
-                       118: R_PPC_VLE_SDAREL_LO16A     low_sdarel
+                       118: R_PPC_VLE_SDAREL_LO16D     low_sdarel
  11c:  70 05 90 00     e_add2is r5,0
-                       11c: R_PPC_VLE_SDAREL_HI16A     high_sdarel
+                       11c: R_PPC_VLE_SDAREL_HI16D     high_sdarel
  120:  70 02 90 00     e_add2is r2,0
-                       120: R_PPC_VLE_SDAREL_HA16A     high_adjust_sdarel
+                       120: R_PPC_VLE_SDAREL_HA16D     high_adjust_sdarel
  124:  70 01 a0 00     e_mull2i r1,0
-                       124: R_PPC_VLE_LO16A    low
+                       124: R_PPC_VLE_LO16D    low
  128:  70 02 a0 00     e_mull2i r2,0
-                       128: R_PPC_VLE_HI16A    high
+                       128: R_PPC_VLE_HI16D    high
  12c:  70 03 a0 00     e_mull2i r3,0
-                       12c: R_PPC_VLE_HA16A    high_adjust
+                       12c: R_PPC_VLE_HA16D    high_adjust
  130:  70 04 a0 00     e_mull2i r4,0
-                       130: R_PPC_VLE_SDAREL_LO16A     low_sdarel
+                       130: R_PPC_VLE_SDAREL_LO16D     low_sdarel
  134:  70 05 a0 00     e_mull2i r5,0
-                       134: R_PPC_VLE_SDAREL_HI16A     high_sdarel
+                       134: R_PPC_VLE_SDAREL_HI16D     high_sdarel
  138:  70 02 a0 00     e_mull2i r2,0
-                       138: R_PPC_VLE_SDAREL_HA16A     high_adjust_sdarel
+                       138: R_PPC_VLE_SDAREL_HA16D     high_adjust_sdarel
index 18fe3ed531f8e4bfb67ebd656087f45277b33f94..3703f80c5cb9392f6cb8a068263cff93a71963a2 100644 (file)
@@ -1,3 +1,8 @@
+2016-11-22  Alan Modra  <amodra@gmail.com>
+
+       PR 20744
+       * opcode/ppc.h: Define VLE insns using 16A and 16D relocs.
+
 2016-11-03  David Tolnay <dtolnay@gmail.com>
            Mark Wielaard  <mark@klomp.org>
 
index 66d2ceb31db52a8ddb28da7588ffb66376607a60..a9dc50d2a698ad97384250f218bebb3f3d13c728 100644 (file)
@@ -448,6 +448,23 @@ ppc_optional_operand_value (const struct powerpc_operand *operand)
   return 0;
 }
 
+/* PowerPC VLE insns.  */
+/* Form I16L, uses 16A relocs.  */
+#define E_OR2I_INSN            0x7000C000
+#define E_AND2I_DOT_INSN       0x7000C800
+#define E_OR2IS_INSN           0x7000D000
+#define E_LIS_INSN             0x7000E000
+#define        E_AND2IS_DOT_INSN       0x7000E800
+
+/* Form I16A, uses 16D relocs.  */
+#define E_ADD2I_DOT_INSN       0x70008800
+#define E_ADD2IS_INSN          0x70009000
+#define E_CMP16I_INSN          0x70009800
+#define E_MULL2I_INSN          0x7000A000
+#define E_CMPL16I_INSN         0x7000A800
+#define E_CMPH16I_INSN         0x7000B000
+#define E_CMPHL16I_INSN                0x7000B800
+
 #ifdef __cplusplus
 }
 #endif
index 7add280f824c4d4a7e8490ef94e8e89e5511d94f..00b7ca9b427cf1190b71d1ccbdf76e46f6b6c4b7 100644 (file)
@@ -1,3 +1,9 @@
+2016-11-22  Alan Modra  <amodra@gmail.com>
+
+       PR 20744
+       * emultempl/ppc32elf.em (params): Update initializer.  Handle
+       --vle-reloc-fixup command line arg.
+
 2016-11-15  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
 
        PR ld/20789
index 95df30d4031aad2f46ee9949b37d5ef06ae6bbde..0e64ccfe07c397b9c14eaa04269b4d8e24d190f3 100644 (file)
@@ -38,7 +38,7 @@ static int notlsopt = 0;
 /* Choose the correct place for .got.  */
 static int old_got = 0;
 
-static struct ppc_elf_params params = { PLT_UNSET, -1, 0, 0, 0, 0, 0, 0 };
+static struct ppc_elf_params params = { PLT_UNSET, -1, 0, 0, 0, 0, 0, 0, 0 };
 
 static void
 ppc_after_open_output (void)
@@ -249,6 +249,7 @@ PARSE_AND_LIST_PROLOGUE=${PARSE_AND_LIST_PROLOGUE}'
 #define OPTION_PPC476_WORKAROUND       (OPTION_NO_STUBSYMS + 1)
 #define OPTION_NO_PPC476_WORKAROUND    (OPTION_PPC476_WORKAROUND + 1)
 #define OPTION_NO_PICFIXUP             (OPTION_NO_PPC476_WORKAROUND + 1)
+#define OPTION_VLE_RELOC_FIXUP         (OPTION_NO_PICFIXUP + 1)
 '
 
 PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
@@ -266,6 +267,7 @@ PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
   { "ppc476-workaround", optional_argument, NULL, OPTION_PPC476_WORKAROUND },
   { "no-ppc476-workaround", no_argument, NULL, OPTION_NO_PPC476_WORKAROUND },
   { "no-pic-fixup", no_argument, NULL, OPTION_NO_PICFIXUP },
+  { "vle-reloc-fixup", no_argument, NULL, OPTION_VLE_RELOC_FIXUP },
 '
 
 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
@@ -284,7 +286,8 @@ PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'\
   --ppc476-workaround [=pagesize]\n\
                               Avoid a cache bug on ppc476.\n\
   --no-ppc476-workaround      Disable workaround.\n\
-  --no-pic-fixup              Don'\''t edit non-pic to pic.\n"
+  --no-pic-fixup              Don'\''t edit non-pic to pic.\n\
+  --vle-reloc-fixup           Correct old object file 16A/16D relocation.\n"
                   ));
 '
 
@@ -342,6 +345,10 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
     case OPTION_NO_PICFIXUP:
       params.pic_fixup = -1;
       break;
+
+    case OPTION_VLE_RELOC_FIXUP:
+      params.vle_reloc_fixup = 1;
+      break;
 '
 
 # Put these extra ppc32elf routines in ld_${EMULATION_NAME}_emulation