From 83eef883581525d04df3a8e53a82c01d0d12b56a Mon Sep 17 00:00:00 2001 From: Alexander Fedotov-B55613 Date: Tue, 5 Sep 2017 08:22:17 +0930 Subject: [PATCH] Missing relocation R_PPC_VLE_ADDR20 and add VLE flag to details in readelf include/ * elf/ppc.h (R_PPC_VLE_ADDR20): New relocation. bfd/ * elf32-ppc.c (ppc_elf_howto_raw): Add R_PPC_VLE_ADDR20. (ppc_elf_check_relocs): Handle it. (ppc_elf_vle_split20): New function. (ppc_elf_relocate_section): Handle R_PPC_VLE_ADDR20. binutils/ * readelf.c (get_elf_section_flags): Add VLE. (process_section_headers): Add VLE key to details. gas/ * config/tc-ppc.c (md_parse_option): Handle "mno-vle" flag. (ppc_elf_section_letter): New function. * config/tc-ppc.h (md_elf_section_letter): New. * testsuite/gas/elf/section10.d: Adjust for VLE. --- bfd/ChangeLog | 8 +++++++ bfd/elf32-ppc.c | 37 +++++++++++++++++++++++++++++++ binutils/ChangeLog | 6 +++++ binutils/readelf.c | 11 +++++++++ gas/ChangeLog | 8 +++++++ gas/config/tc-ppc.c | 20 +++++++++++++++++ gas/config/tc-ppc.h | 3 +++ gas/testsuite/gas/elf/section10.d | 4 ++-- include/ChangeLog | 5 +++++ include/elf/ppc.h | 1 + 10 files changed, 101 insertions(+), 2 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3b3a53cf134..1957ca9e5f0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2017-09-05 Alexander Fedotov + Edmar Wienskoski PR ld/22071 diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 2bdba9ff5ae..da4adea8aec 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -1656,6 +1656,21 @@ static reloc_howto_type ppc_elf_howto_raw[] = { 0x3e007ff, /* dst_mask */ FALSE), /* pcrel_offset */ + /* e_li split20 format. */ + HOWTO (R_PPC_VLE_ADDR20, /* type */ + 16, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 20, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_PPC_VLE_ADDR20", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + 0x1f07ff, /* dst_mask */ + FALSE), /* pcrel_offset */ + HOWTO (R_PPC_IRELATIVE, /* type */ 0, /* rightshift */ 2, /* size (0 = byte, 1 = short, 2 = long) */ @@ -4268,6 +4283,7 @@ ppc_elf_check_relocs (bfd *abfd, case R_PPC_VLE_HI16D: case R_PPC_VLE_HA16A: case R_PPC_VLE_HA16D: + case R_PPC_VLE_ADDR20: break; case R_PPC_EMB_SDA2REL: @@ -4986,6 +5002,23 @@ ppc_elf_vle_split16 (bfd *input_bfd, insn |= value & 0x7ff; bfd_put_32 (input_bfd, insn, loc); } + +static void +ppc_elf_vle_split20 (bfd *output_bfd, bfd_byte *loc, bfd_vma value) +{ + unsigned int insn; + + insn = bfd_get_32 (output_bfd, loc); + /* We have an li20 field, bits 17..20, 11..15, 21..31. */ + /* Top 4 bits of value to 17..20. */ + insn |= (value & 0xf0000) >> 5; + /* Next 5 bits of the value to 11..15. */ + insn |= (value & 0xf800) << 5; + /* And the final 11 bits of the value to bits 21 to 31. */ + insn |= value & 0x7ff; + bfd_put_32 (output_bfd, insn, loc); +} + /* Choose which PLT scheme to use, and set .plt flags appropriately. Returns -1 on error, 0 for old PLT, 1 for new PLT. */ @@ -9512,6 +9545,10 @@ ppc_elf_relocate_section (bfd *output_bfd, } goto copy_reloc; + case R_PPC_VLE_ADDR20: + ppc_elf_vle_split20 (output_bfd, contents + rel->r_offset, relocation); + continue; + /* Relocate against the beginning of the section. */ case R_PPC_SECTOFF: case R_PPC_SECTOFF_LO: diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 6d6aeee61b6..92d8602546b 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2017-09-05 Alexander Fedotov + Edmar Wienskoski PR 21994 diff --git a/binutils/readelf.c b/binutils/readelf.c index db3fc037d67..571da2cf7c8 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -5587,6 +5587,8 @@ get_elf_section_flags (bfd_vma sh_flags) /* 23 */ { STRING_COMMA_LEN ("COMDEF") }, /* GNU specific. */ /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") }, + /* VLE specific. */ + /* 25 */ { STRING_COMMA_LEN ("VLE") }, }; if (do_section_details) @@ -5667,6 +5669,10 @@ get_elf_section_flags (bfd_vma sh_flags) default: break; } break; + case EM_PPC: + if (flag == SHF_PPC_VLE) + sindex = 25; + break; default: break; @@ -5724,6 +5730,9 @@ get_elf_section_flags (bfd_vma sh_flags) else if (elf_header.e_machine == EM_ARM && flag == SHF_ARM_PURECODE) *p = 'y'; + else if (elf_header.e_machine == EM_PPC + && flag == SHF_PPC_VLE) + *p = 'v'; else if (flag & SHF_MASKOS) { *p = 'o'; @@ -6460,6 +6469,8 @@ process_section_headers (FILE * file) printf (_("l (large), ")); else if (elf_header.e_machine == EM_ARM) printf (_("y (purecode), ")); + else if (elf_header.e_machine == EM_PPC) + printf (_("v (VLE), ")); printf ("p (processor specific)\n"); } diff --git a/gas/ChangeLog b/gas/ChangeLog index 318472df5f4..b52259f8d1e 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2017-09-05 Alexander Fedotov + Edmar Wienskoski * config/tc-aarch64.c (aarch64_cpus): Enable DOTPROD for diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index d20fac6d207..7118b719242 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -1206,6 +1206,16 @@ md_parse_option (int c, const char *arg) } } + else if (strcmp (arg, "no-vle") == 0) + { + sticky &= ~PPC_OPCODE_VLE; + + new_cpu = ppc_parse_cpu (ppc_cpu, &sticky, "booke"); + new_cpu &= ~PPC_OPCODE_VLE; + + ppc_cpu = new_cpu; + } + else if (strcmp (arg, "regnames") == 0) reg_names_p = TRUE; @@ -3683,6 +3693,16 @@ ppc_section_flags (flagword flags, bfd_vma attr ATTRIBUTE_UNUSED, int type) return flags; } + +bfd_vma +ppc_elf_section_letter (int letter, const char **ptrmsg) +{ + if (letter == 'v') + return SHF_PPC_VLE; + + *ptrmsg = _("bad .section directive: want a,e,v,w,x,M,S,G,T in string"); + return -1; +} #endif /* OBJ_ELF */ diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h index 514c2231f70..f71f2ea90f4 100644 --- a/gas/config/tc-ppc.h +++ b/gas/config/tc-ppc.h @@ -226,6 +226,9 @@ extern int ppc_section_flags (flagword, bfd_vma, int); #define tc_comment_chars ppc_comment_chars extern const char *ppc_comment_chars; +#define md_elf_section_letter ppc_elf_section_letter +extern bfd_vma ppc_elf_section_letter (int, const char **); + /* Keep relocations relative to the GOT, or non-PC relative. */ #define tc_fix_adjustable(FIX) ppc_fix_adjustable (FIX) extern int ppc_fix_adjustable (struct fix *); diff --git a/gas/testsuite/gas/elf/section10.d b/gas/testsuite/gas/elf/section10.d index e187263d8ff..554a791f1db 100644 --- a/gas/testsuite/gas/elf/section10.d +++ b/gas/testsuite/gas/elf/section10.d @@ -18,7 +18,7 @@ #... [ ]*\[.*\][ ]+sec3 [ ]*PROGBITS.* -[ ]*\[.*fefff030\]: MERGE, STRINGS,.* EXCLUDE, OS \(.*ef00000\), PROC \(.*[347]0000000\), UNKNOWN \(0+0ff000\) +[ ]*\[.*fefff030\]: MERGE, STRINGS,.* EXCLUDE, OS \(.*ef00000\), PROC \(.*[3467]0000000\), UNKNOWN \(0+0ff000\) #... [ ]*\[.*\][ ]+sec4 [ ]*LOOS\+0x11[ ].* @@ -26,7 +26,7 @@ #... [ ]*\[.*\][ ]+sec5 [ ]*LOUSER\+0x9[ ].* -[ ]*\[.*feff0000\]:.* EXCLUDE, OS \(.*ef00000\), PROC \(.*[347]0000000\), UNKNOWN \(.*f0000\) +[ ]*\[.*feff0000\]:.* EXCLUDE, OS \(.*ef00000\), PROC \(.*[3467]0000000\), UNKNOWN \(.*f0000\) [ ]*\[.*\][ ]+.data.foo [ ]*LOUSER\+0x7f000000[ ].* [ ]*\[0+003\]: WRITE, ALLOC diff --git a/include/ChangeLog b/include/ChangeLog index d914f712e03..2845f8574cf 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2017-09-05 Alexander Fedotov + Edmar Wienskoski Edmar Wienskoski diff --git a/include/elf/ppc.h b/include/elf/ppc.h index 6790cd76ef1..a7d2f3e14f8 100644 --- a/include/elf/ppc.h +++ b/include/elf/ppc.h @@ -152,6 +152,7 @@ START_RELOC_NUMBERS (elf_ppc_reloc_type) RELOC_NUMBER (R_PPC_VLE_SDAREL_HI16D, 230) RELOC_NUMBER (R_PPC_VLE_SDAREL_HA16A, 231) RELOC_NUMBER (R_PPC_VLE_SDAREL_HA16D, 232) + RELOC_NUMBER (R_PPC_VLE_ADDR20, 233) /* Power9 split rel16 for addpcis. */ RELOC_NUMBER (R_PPC_REL16DX_HA, 246) -- 2.30.2