aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2016-11-22 18:45:29 +1030
committerAlan Modra <amodra@gmail.com>2016-11-22 20:19:29 +1030
commit08dc996fedde9143cda25720961684087b133640 (patch)
tree9bb48db13193c8e0839bc213eb2fc9ca8a73adb8
parent95f0d0d2338f8eba18d2b3c8cbe15b1d584b885c (diff)
downloadfsf-binutils-gdb-08dc996fedde9143cda25720961684087b133640.zip
fsf-binutils-gdb-08dc996fedde9143cda25720961684087b133640.tar.gz
fsf-binutils-gdb-08dc996fedde9143cda25720961684087b133640.tar.bz2
PR20744, Incorrect PowerPC VLE relocs
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.
-rw-r--r--bfd/ChangeLog16
-rw-r--r--bfd/elf32-ppc.c141
-rw-r--r--bfd/elf32-ppc.h3
-rw-r--r--binutils/ChangeLog5
-rw-r--r--binutils/NEWS15
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-ppc.c20
-rw-r--r--gas/testsuite/gas/ppc/vle-reloc.d146
-rw-r--r--include/ChangeLog5
-rw-r--r--include/opcode/ppc.h17
-rw-r--r--ld/ChangeLog6
-rw-r--r--ld/emultempl/ppc32elf.em11
12 files changed, 257 insertions, 135 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c3283ea..ebf8279 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,21 @@
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
input_bfd. Replace occurrences of output_bfd as bfd_get_32 and
bfd_put_32 param with input_bfd.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 75b0478..efe7f69 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -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;
diff --git a/bfd/elf32-ppc.h b/bfd/elf32-ppc.h
index 5f3a88b..0351a2b 100644
--- a/bfd/elf32-ppc.h
+++ b/bfd/elf32-ppc.h
@@ -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;
};
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index bbeec9c..ef923cb 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -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.
diff --git a/binutils/NEWS b/binutils/NEWS
index 5d0bc89..4e1aacd 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -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.
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 134f24b..71cc677 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index 5c7b09f..84d4ebc 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -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
diff --git a/gas/testsuite/gas/ppc/vle-reloc.d b/gas/testsuite/gas/ppc/vle-reloc.d
index 01eba4a..dad153f 100644
--- a/gas/testsuite/gas/ppc/vle-reloc.d
+++ b/gas/testsuite/gas/ppc/vle-reloc.d
@@ -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
diff --git a/include/ChangeLog b/include/ChangeLog
index 18fe3ed..3703f80 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -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>
diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h
index 66d2ceb..a9dc50d 100644
--- a/include/opcode/ppc.h
+++ b/include/opcode/ppc.h
@@ -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
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 7add280..00b7ca9 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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
diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em
index 95df30d..0e64ccf 100644
--- a/ld/emultempl/ppc32elf.em
+++ b/ld/emultempl/ppc32elf.em
@@ -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