From 08dc996fedde9143cda25720961684087b133640 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 22 Nov 2016 18:45:29 +1030 Subject: [PATCH 1/1] 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. --- bfd/ChangeLog | 16 ++++ bfd/elf32-ppc.c | 141 ++++++++++++++++++++--------- bfd/elf32-ppc.h | 3 + binutils/ChangeLog | 5 + binutils/NEWS | 15 ++- gas/ChangeLog | 7 ++ gas/config/tc-ppc.c | 20 +--- gas/testsuite/gas/ppc/vle-reloc.d | 146 +++++++++++++++--------------- include/ChangeLog | 5 + include/opcode/ppc.h | 17 ++++ ld/ChangeLog | 6 ++ ld/emultempl/ppc32elf.em | 11 ++- 12 files changed, 257 insertions(+), 135 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c3283ea7eb..ebf8279480 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2016-11-22 Alan Modra + + 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 * elf32-ppc.c (ppc64_elf_relocate_section): Calculate d_offset for diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 75b0478d2b..efe7f69b83 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 5f3a88b3d4..0351a2b3a4 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 bbeec9c192..ef923cbba1 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2016-11-22 Alan Modra + + PR 20744 + * NEWS: Mention PowerPC VLE relocation error. + 2016-11-16 Mark Wielaard * cxxfilt.c (main): Recognize rust_demangling. diff --git a/binutils/NEWS b/binutils/NEWS index 5d0bc89bb5..4e1aacd815 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 134f24b511..71cc677dd7 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2016-11-22 Alan Modra + + 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 PR gas/20827 diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 5c7b09f02b..84d4ebc754 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 01eba4af9e..dad153f52c 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 18fe3ed531..3703f80c5c 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2016-11-22 Alan Modra + + PR 20744 + * opcode/ppc.h: Define VLE insns using 16A and 16D relocs. + 2016-11-03 David Tolnay Mark Wielaard diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h index 66d2ceb31d..a9dc50d2a6 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 7add280f82..00b7ca9b42 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2016-11-22 Alan Modra + + PR 20744 + * emultempl/ppc32elf.em (params): Update initializer. Handle + --vle-reloc-fixup command line arg. + 2016-11-15 Senthil Kumar Selvaraj PR ld/20789 diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em index 95df30d403..0e64ccfe07 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 -- 2.34.1