[PowerPC] VLE update

Message ID CAN8C2CrG3n5QP17Om=_0SwmLVOKi+Z9NV-oTKXsgnhhGd=N7cQ@mail.gmail.com
State New
Headers show
Series
  • [PowerPC] VLE update
Related show

Commit Message

Alexander Fedotov Aug. 26, 2017, 5:37 p.m.
This patch adds support PLT for VLE ISA. Also adds new relocations and
section headers handling.

Comments

Alan Modra Aug. 27, 2017, 10:34 p.m. | #1
On Sat, Aug 26, 2017 at 08:37:22PM +0300, Alexander Fedotov wrote:
> This patch adds support PLT for VLE ISA. Also adds new relocations and

> section headers handling.


Looks to me like you've been give the job of sweeping out the
stables..

> +  /* PowerPC VLE code.  */

> +#define SEC_PPC_VLE 0x100000000


How can this possibly work?  The field is an unsigned int.

> @@ -7371,10 +7474,21 @@ ppc_elf_relax_section (bfd *abfd,

>  	    case R_PPC_REL24:

>  	    case R_PPC_LOCAL24PC:

>  	    case R_PPC_PLTREL24:

> -	      t0 = bfd_get_32 (abfd, hit_addr);

> -	      t0 &= ~0x3fffffc;

> -	      t0 |= val & 0x3fffffc;

> -	      bfd_put_32 (abfd, t0, hit_addr);

> +	      if (r_type == R_PPC_PLTREL24

> +		  && (elf_section_flags (isec) & SHF_PPC_VLE) != 0)

> +		{

> +		  t0 = bfd_get_32 (abfd, hit_addr);

> +		  t0 &= ~0x01fffffe;

> +		  t0 |= val & 0x01fffffe;

> +		  bfd_put_32 (abfd, t0, hit_addr);

> +		}

> +	      else

> +		{

> +		  t0 = bfd_get_32 (abfd, hit_addr);

> +		  t0 &= ~0x3fffffc;

> +		  t0 |= val & 0x3fffffc;

> +		  bfd_put_32 (abfd, t0, hit_addr);

> +		}


What is going on here?  

> +	(R_PPC_VLE_PLTREL24): New relocation.

> +	(R_PPC_VLE_ADDR20): Likewise.


How are these generated?  I see code that processes them, but nothing
to create them.

> @@ -253,12 +253,13 @@ get_powerpc_dialect (struct disassemble_info *info)

>    dialect = POWERPC_DIALECT (info);

>  

>    /* Disassemble according to the section headers flags for VLE-mode.  */

> -  if (dialect & PPC_OPCODE_VLE

> -      && info->section != NULL && info->section->owner != NULL

> +  if (dialect & PPC_OPCODE_VLE)

> +    return dialect;

> +  else if (info->section != NULL && info->section->owner != NULL

>        && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour

>        && elf_object_id (info->section->owner) == PPC32_ELF_DATA

>        && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)

> -    return dialect;

> +    return PPC_OPCODE_VLE;

>    else

>      return dialect & ~ PPC_OPCODE_VLE;


Can you explain why this change is necessary?

-- 
Alan Modra
Australia Development Lab, IBM
Alexander Fedotov Aug. 28, 2017, 10:11 a.m. | #2
>>Looks to me like you've been give the job of sweeping out the

>>stables..


Well I have the same feelings, but that's is always part of our job :)
And thats why I appreciate your feedback on all this stuff.

>> +  /* PowerPC VLE code.  */

>> +#define SEC_PPC_VLE 0x100000000

>

> How can this possibly work?  The field is an unsigned int.


You are right. In original patch it was just reuse:
+#define SEC_PPC_VLE SEC_TIC54X_BLOCK

Well what the best way to deal with this ? Extend flagword to long ?
Or keep reuse ?


>> +     (R_PPC_VLE_PLTREL24): New relocation.

>> +     (R_PPC_VLE_ADDR20): Likewise.

>

>How are these generated?  I see code that processes them, but nothing

> to create them.


Regarding to R_PPC_VLE_PLTREL24 I forgot to apply patch:

@@ -9686,8 +9845,17 @@ ppc_elf_relocate_section (bfd *output_bfd,
            }
        }
       else
-       r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
+       {
+         if ((elf_section_flags (input_section) & SHF_PPC_VLE) != 0)
+           {
+             if (howto == ppc_elf_howto_table[R_PPC_PLTREL24])
+               howto = ppc_elf_howto_table[R_PPC_VLE_PLTREL24];
+             else if (howto == ppc_elf_howto_table[R_PPC_LOCAL24PC])
+               howto = ppc_elf_howto_table[R_PPC_VLE_REL24];
+           }
+         r = _bfd_final_link_relocate (howto, input_bfd,
input_section, contents,
                                      rel->r_offset, relocation, addend);
+       }


Yes, R_PPC_VLE_ADDR20 is not used yet. But it is defined by Power
Architecture 32-bit Application Binary Interface Supplement 1.0 -
Linux & Embedded. So it looks like just missing.


>> @@ -253,12 +253,13 @@ get_powerpc_dialect (struct disassemble_info *info)

>>    dialect = POWERPC_DIALECT (info);

>>

>>    /* Disassemble according to the section headers flags for VLE-mode.  */

>> -  if (dialect & PPC_OPCODE_VLE

>> -      && info->section != NULL && info->section->owner != NULL

>> +  if (dialect & PPC_OPCODE_VLE)

>> +    return dialect;

>> +  else if (info->section != NULL && info->section->owner != NULL

>>        && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour

>>        && elf_object_id (info->section->owner) == PPC32_ELF_DATA

>>        && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)

>> -    return dialect;

>> +    return PPC_OPCODE_VLE;

>>    else

>>      return dialect & ~ PPC_OPCODE_VLE;

>

>Can you explain why this change is necessary?


As I can see it resolves problem with LSP disassembling on lsp.s test.
Unfortunately I have no more history for this one. Drop it from the
patch ?

Best regards,
Alex


On Mon, Aug 28, 2017 at 1:34 AM, Alan Modra <amodra@gmail.com> wrote:
> On Sat, Aug 26, 2017 at 08:37:22PM +0300, Alexander Fedotov wrote:

>> This patch adds support PLT for VLE ISA. Also adds new relocations and

>> section headers handling.

>

> Looks to me like you've been give the job of sweeping out the

> stables..

>

>> +  /* PowerPC VLE code.  */

>> +#define SEC_PPC_VLE 0x100000000

>

> How can this possibly work?  The field is an unsigned int.

>

>> @@ -7371,10 +7474,21 @@ ppc_elf_relax_section (bfd *abfd,

>>           case R_PPC_REL24:

>>           case R_PPC_LOCAL24PC:

>>           case R_PPC_PLTREL24:

>> -           t0 = bfd_get_32 (abfd, hit_addr);

>> -           t0 &= ~0x3fffffc;

>> -           t0 |= val & 0x3fffffc;

>> -           bfd_put_32 (abfd, t0, hit_addr);

>> +           if (r_type == R_PPC_PLTREL24

>> +               && (elf_section_flags (isec) & SHF_PPC_VLE) != 0)

>> +             {

>> +               t0 = bfd_get_32 (abfd, hit_addr);

>> +               t0 &= ~0x01fffffe;

>> +               t0 |= val & 0x01fffffe;

>> +               bfd_put_32 (abfd, t0, hit_addr);

>> +             }

>> +           else

>> +             {

>> +               t0 = bfd_get_32 (abfd, hit_addr);

>> +               t0 &= ~0x3fffffc;

>> +               t0 |= val & 0x3fffffc;

>> +               bfd_put_32 (abfd, t0, hit_addr);

>> +             }

>

> What is going on here?

>

>> +     (R_PPC_VLE_PLTREL24): New relocation.

>> +     (R_PPC_VLE_ADDR20): Likewise.

>

> How are these generated?  I see code that processes them, but nothing

> to create them.

>

>> @@ -253,12 +253,13 @@ get_powerpc_dialect (struct disassemble_info *info)

>>    dialect = POWERPC_DIALECT (info);

>>

>>    /* Disassemble according to the section headers flags for VLE-mode.  */

>> -  if (dialect & PPC_OPCODE_VLE

>> -      && info->section != NULL && info->section->owner != NULL

>> +  if (dialect & PPC_OPCODE_VLE)

>> +    return dialect;

>> +  else if (info->section != NULL && info->section->owner != NULL

>>        && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour

>>        && elf_object_id (info->section->owner) == PPC32_ELF_DATA

>>        && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)

>> -    return dialect;

>> +    return PPC_OPCODE_VLE;

>>    else

>>      return dialect & ~ PPC_OPCODE_VLE;

>

> Can you explain why this change is necessary?

>

> --

> Alan Modra

> Australia Development Lab, IBM




-- 
Best regards,
AF
Alan Modra Aug. 28, 2017, 1:14 p.m. | #3
On Mon, Aug 28, 2017 at 01:11:28PM +0300, Alexander Fedotov wrote:
> >> +  /* PowerPC VLE code.  */

> >> +#define SEC_PPC_VLE 0x100000000

> >

> > How can this possibly work?  The field is an unsigned int.

> 

> You are right. In original patch it was just reuse:

> +#define SEC_PPC_VLE SEC_TIC54X_BLOCK

> 

> Well what the best way to deal with this ? Extend flagword to long ?

> Or keep reuse ?


You could reuse the SEC_MEP_VLIW bit, I guess.   The section flags
weren't really supposed to be used for target-specific purposes, but
it seems pointless trying to be a purist now.

> 

> 

> >> +     (R_PPC_VLE_PLTREL24): New relocation.

> >> +     (R_PPC_VLE_ADDR20): Likewise.

> >

> >How are these generated?  I see code that processes them, but nothing

> > to create them.

> 

> Regarding to R_PPC_VLE_PLTREL24 I forgot to apply patch:

> 

> @@ -9686,8 +9845,17 @@ ppc_elf_relocate_section (bfd *output_bfd,

>             }

>         }

>        else

> -       r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,

> +       {

> +         if ((elf_section_flags (input_section) & SHF_PPC_VLE) != 0)

> +           {

> +             if (howto == ppc_elf_howto_table[R_PPC_PLTREL24])

> +               howto = ppc_elf_howto_table[R_PPC_VLE_PLTREL24];

> +             else if (howto == ppc_elf_howto_table[R_PPC_LOCAL24PC])

> +               howto = ppc_elf_howto_table[R_PPC_VLE_REL24];

> +           }

> +         r = _bfd_final_link_relocate (howto, input_bfd,

> input_section, contents,

>                                       rel->r_offset, relocation, addend);

> +       }


That doesn't look elegant at all.  So you are using R_PPC_PLTREL24 and
R_PPC_LOCAL24PC relocations in VLE code but giving them a new meaning.
Is that documented in the ABI?

I think it would be better to define new R_PPC_VLE_PLTREL24 and
R_PPC_VLE_LOCAL24 relocs, and make the assembler generate them when
assembling VLE code.

> Yes, R_PPC_VLE_ADDR20 is not used yet. But it is defined by Power

> Architecture 32-bit Application Binary Interface Supplement 1.0 -

> Linux & Embedded. So it looks like just missing.


OK.

> >> @@ -253,12 +253,13 @@ get_powerpc_dialect (struct disassemble_info *info)

> >>    dialect = POWERPC_DIALECT (info);

> >>

> >>    /* Disassemble according to the section headers flags for VLE-mode.  */

> >> -  if (dialect & PPC_OPCODE_VLE

> >> -      && info->section != NULL && info->section->owner != NULL

> >> +  if (dialect & PPC_OPCODE_VLE)

> >> +    return dialect;

> >> +  else if (info->section != NULL && info->section->owner != NULL

> >>        && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour

> >>        && elf_object_id (info->section->owner) == PPC32_ELF_DATA

> >>        && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)

> >> -    return dialect;

> >> +    return PPC_OPCODE_VLE;

> >>    else

> >>      return dialect & ~ PPC_OPCODE_VLE;

> >

> >Can you explain why this change is necessary?

> 

> As I can see it resolves problem with LSP disassembling on lsp.s test.

> Unfortunately I have no more history for this one. Drop it from the

> patch ?


As I understand it, SHF_PPC_VLE and PF_PPC_VLE are set on sections or
segments containing instructions that can only be executed by a
processor in VLE mode.  PPC_OPCODE_VLE is set for such opcodes too.
So, do the LSP instructions only execute in VLE mode?  I suspect not,
from their encoding.

Do you have the LSP instructions in the correct opcode table?

-- 
Alan Modra
Australia Development Lab, IBM
Alexander Fedotov Aug. 28, 2017, 2:20 p.m. | #4
> You could reuse the SEC_MEP_VLIW bit, I guess.   The section flags

> weren't really supposed to be used for target-specific purposes, but

> it seems pointless trying to be a purist now.


Okay, so I will set
+#define SEC_PPC_VLE SEC_MEP_VLIW


> That doesn't look elegant at all.  So you are using R_PPC_PLTREL24 and

> R_PPC_LOCAL24PC relocations in VLE code but giving them a new meaning.

> Is that documented in the ABI?

>

> I think it would be better to define new R_PPC_VLE_PLTREL24 and

> R_PPC_VLE_LOCAL24 relocs, and make the assembler generate them when

> assembling VLE code.


Nope, they are not defined by ABI at all. I agree it would be better
to rework. I will remove it from current patch set.

> As I understand it, SHF_PPC_VLE and PF_PPC_VLE are set on sections or

> segments containing instructions that can only be executed by a

> processor in VLE mode.  PPC_OPCODE_VLE is set for such opcodes too.

> So, do the LSP instructions only execute in VLE mode?  I suspect not,

> from their encoding.

>

> Do you have the LSP instructions in the correct opcode table?


I see that LSP instructions are available only on the cores with VLE ISA only.


Alex

On Mon, Aug 28, 2017 at 4:14 PM, Alan Modra <amodra@gmail.com> wrote:
> On Mon, Aug 28, 2017 at 01:11:28PM +0300, Alexander Fedotov wrote:

>> >> +  /* PowerPC VLE code.  */

>> >> +#define SEC_PPC_VLE 0x100000000

>> >

>> > How can this possibly work?  The field is an unsigned int.

>>

>> You are right. In original patch it was just reuse:

>> +#define SEC_PPC_VLE SEC_TIC54X_BLOCK

>>

>> Well what the best way to deal with this ? Extend flagword to long ?

>> Or keep reuse ?

>

> You could reuse the SEC_MEP_VLIW bit, I guess.   The section flags

> weren't really supposed to be used for target-specific purposes, but

> it seems pointless trying to be a purist now.

>

>>

>>

>> >> +     (R_PPC_VLE_PLTREL24): New relocation.

>> >> +     (R_PPC_VLE_ADDR20): Likewise.

>> >

>> >How are these generated?  I see code that processes them, but nothing

>> > to create them.

>>

>> Regarding to R_PPC_VLE_PLTREL24 I forgot to apply patch:

>>

>> @@ -9686,8 +9845,17 @@ ppc_elf_relocate_section (bfd *output_bfd,

>>             }

>>         }

>>        else

>> -       r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents,

>> +       {

>> +         if ((elf_section_flags (input_section) & SHF_PPC_VLE) != 0)

>> +           {

>> +             if (howto == ppc_elf_howto_table[R_PPC_PLTREL24])

>> +               howto = ppc_elf_howto_table[R_PPC_VLE_PLTREL24];

>> +             else if (howto == ppc_elf_howto_table[R_PPC_LOCAL24PC])

>> +               howto = ppc_elf_howto_table[R_PPC_VLE_REL24];

>> +           }

>> +         r = _bfd_final_link_relocate (howto, input_bfd,

>> input_section, contents,

>>                                       rel->r_offset, relocation, addend);

>> +       }

>

> That doesn't look elegant at all.  So you are using R_PPC_PLTREL24 and

> R_PPC_LOCAL24PC relocations in VLE code but giving them a new meaning.

> Is that documented in the ABI?

>

> I think it would be better to define new R_PPC_VLE_PLTREL24 and

> R_PPC_VLE_LOCAL24 relocs, and make the assembler generate them when

> assembling VLE code.

>

>> Yes, R_PPC_VLE_ADDR20 is not used yet. But it is defined by Power

>> Architecture 32-bit Application Binary Interface Supplement 1.0 -

>> Linux & Embedded. So it looks like just missing.

>

> OK.

>

>> >> @@ -253,12 +253,13 @@ get_powerpc_dialect (struct disassemble_info *info)

>> >>    dialect = POWERPC_DIALECT (info);

>> >>

>> >>    /* Disassemble according to the section headers flags for VLE-mode.  */

>> >> -  if (dialect & PPC_OPCODE_VLE

>> >> -      && info->section != NULL && info->section->owner != NULL

>> >> +  if (dialect & PPC_OPCODE_VLE)

>> >> +    return dialect;

>> >> +  else if (info->section != NULL && info->section->owner != NULL

>> >>        && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour

>> >>        && elf_object_id (info->section->owner) == PPC32_ELF_DATA

>> >>        && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)

>> >> -    return dialect;

>> >> +    return PPC_OPCODE_VLE;

>> >>    else

>> >>      return dialect & ~ PPC_OPCODE_VLE;

>> >

>> >Can you explain why this change is necessary?

>>

>> As I can see it resolves problem with LSP disassembling on lsp.s test.

>> Unfortunately I have no more history for this one. Drop it from the

>> patch ?

>

> As I understand it, SHF_PPC_VLE and PF_PPC_VLE are set on sections or

> segments containing instructions that can only be executed by a

> processor in VLE mode.  PPC_OPCODE_VLE is set for such opcodes too.

> So, do the LSP instructions only execute in VLE mode?  I suspect not,

> from their encoding.

>

> Do you have the LSP instructions in the correct opcode table?

>

> --

> Alan Modra

> Australia Development Lab, IBM




-- 
Best regards,
AF
Joseph Myers Aug. 28, 2017, 3:35 p.m. | #5
On Mon, 28 Aug 2017, Alexander Fedotov wrote:

> > I think it would be better to define new R_PPC_VLE_PLTREL24 and

> > R_PPC_VLE_LOCAL24 relocs, and make the assembler generate them when

> > assembling VLE code.

> 

> Nope, they are not defined by ABI at all. I agree it would be better

> to rework. I will remove it from current patch set.


Note that the current (as far as I know) 32-bit ABI sources are at 
<https://github.com/ryanarn/powerabi> - but the ABI mailing list is long 
dead (as is power.org) and as far as I know Ryan is no longer working on 
Power, so there may not be anyone to process pull requests or consider ABI 
additions.

-- 
Joseph S. Myers
joseph@codesourcery.com
Bill Schmidt Aug. 28, 2017, 3:59 p.m. | #6
On Aug 28, 2017, at 10:35 AM, Joseph Myers <joseph@codesourcery.com> wrote:
> 

> On Mon, 28 Aug 2017, Alexander Fedotov wrote:

> 

>>> I think it would be better to define new R_PPC_VLE_PLTREL24 and

>>> R_PPC_VLE_LOCAL24 relocs, and make the assembler generate them when

>>> assembling VLE code.

>> 

>> Nope, they are not defined by ABI at all. I agree it would be better

>> to rework. I will remove it from current patch set.

> 

> Note that the current (as far as I know) 32-bit ABI sources are at 

> <https://urldefense.proofpoint.com/v2/url?u=https-3A__github.com_ryanarn_powerabi&d=DwIBAg&c=jf_iaSHvJObTbx-siA1ZOg&r=POnVfwz_vzz6S-DRogtSLYEPvZWOh-UL1JJQ_X52MeA&m=uv2q3qkfsy4N66OHGiw_2_KjuGd7Ps206LhFETN3Ch8&s=0-mici25PX0z6YTryj-40V_ApN0m-Lx9IplU777xVmI&e= > - but the ABI mailing list is long 

> dead (as is power.org) and as far as I know Ryan is no longer working on 

> Power, so there may not be anyone to process pull requests or consider ABI 

> additions.


Hi Joseph,

I took ownership of this github project after Ryan left the company, though there
hasn't been any activity on it since then.  I can be involved as needed here.

Thanks,
Bill

> 

> -- 

> Joseph S. Myers

> joseph@codesourcery.com

>
Alexander Fedotov Aug. 28, 2017, 4:01 p.m. | #7
Thanks for the link !
I know that VLE is no longer supported. But anyway it still useful
because of existing MCUs for automotive.
So can we fork this ABI description and define new relocs? We have
free placeholders for that.

Alex

On Mon, Aug 28, 2017 at 6:35 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Mon, 28 Aug 2017, Alexander Fedotov wrote:

>

>> > I think it would be better to define new R_PPC_VLE_PLTREL24 and

>> > R_PPC_VLE_LOCAL24 relocs, and make the assembler generate them when

>> > assembling VLE code.

>>

>> Nope, they are not defined by ABI at all. I agree it would be better

>> to rework. I will remove it from current patch set.

>

> Note that the current (as far as I know) 32-bit ABI sources are at

> <https://github.com/ryanarn/powerabi> - but the ABI mailing list is long

> dead (as is power.org) and as far as I know Ryan is no longer working on

> Power, so there may not be anyone to process pull requests or consider ABI

> additions.

>

> --

> Joseph S. Myers

> joseph@codesourcery.com




-- 
Best regards,
AF
Alan Modra Aug. 29, 2017, 6:17 a.m. | #8
On Mon, Aug 28, 2017 at 05:20:45PM +0300, Alexander Fedotov wrote:
> > You could reuse the SEC_MEP_VLIW bit, I guess.   The section flags

> > weren't really supposed to be used for target-specific purposes, but

> > it seems pointless trying to be a purist now.

> 

> Okay, so I will set

> +#define SEC_PPC_VLE SEC_MEP_VLIW


If you split off the part dealing with SEC_PPC_VLE that can be
committed separately.

> > That doesn't look elegant at all.  So you are using R_PPC_PLTREL24 and

> > R_PPC_LOCAL24PC relocations in VLE code but giving them a new meaning.

> > Is that documented in the ABI?

> >

> > I think it would be better to define new R_PPC_VLE_PLTREL24 and

> > R_PPC_VLE_LOCAL24 relocs, and make the assembler generate them when

> > assembling VLE code.

> 

> Nope, they are not defined by ABI at all. I agree it would be better

> to rework. I will remove it from current patch set.


I should note that I'm not greatly concerned about adding relocations
that aren't described in an ABI document.  It's not ideal, but the
document can always be modified later.  I was more concerned that
someone may have already described R_PPC_PLTREL24 as behaving
differently for VLE, and the problem that causes for compatibility if
the GNU toolchain then goes off and implements something else.

> > As I understand it, SHF_PPC_VLE and PF_PPC_VLE are set on sections or

> > segments containing instructions that can only be executed by a

> > processor in VLE mode.  PPC_OPCODE_VLE is set for such opcodes too.

> > So, do the LSP instructions only execute in VLE mode?  I suspect not,

> > from their encoding.

> >

> > Do you have the LSP instructions in the correct opcode table?

> 

> I see that LSP instructions are available only on the cores with VLE ISA only.


OK, but if there was a processor that could operate in both VLE and
non-VLE mode (controlled by MAS2 bit VLE), would these instructions be
available in both modes?  If only VLE, then SHF_PPC_VLE ought to be
set for any section containing them.  See tc-ppc.c:3513.

However, from the fact that the "Lightweight Signal Processing APU
(LSP APU) Reference Manual" does not mention VLE, and the encoding of
these instructions, my guess is that these instruction are not VLE and
thus should not be in vle_opcodes.

-- 
Alan Modra
Australia Development Lab, IBM
Alexander Fedotov Aug. 30, 2017, 4:03 p.m. | #9
>> If you split off the part dealing with SEC_PPC_VLE that can be

>> committed separately.


Done. New patch attached.


>> OK, but if there was a processor that could operate in both VLE and

>> non-VLE mode (controlled by MAS2 bit VLE), would these instructions be

>> available in both modes?  If only VLE, then SHF_PPC_VLE ought to be

>> set for any section containing them.  See tc-ppc.c:3513.

>>

>> However, from the fact that the "Lightweight Signal Processing APU

>> (LSP APU) Reference Manual" does not mention VLE, and the encoding of

>> these instructions, my guess is that these instruction are not VLE and

>> thus should not be in vle_opcodes.


Yes, there could be e.g e200z759n core. But it has SPE, not LSP.

On Tue, Aug 29, 2017 at 9:17 AM, Alan Modra <amodra@gmail.com> wrote:
> On Mon, Aug 28, 2017 at 05:20:45PM +0300, Alexander Fedotov wrote:

>> > You could reuse the SEC_MEP_VLIW bit, I guess.   The section flags

>> > weren't really supposed to be used for target-specific purposes, but

>> > it seems pointless trying to be a purist now.

>>

>> Okay, so I will set

>> +#define SEC_PPC_VLE SEC_MEP_VLIW

>

> If you split off the part dealing with SEC_PPC_VLE that can be

> committed separately.

>

>> > That doesn't look elegant at all.  So you are using R_PPC_PLTREL24 and

>> > R_PPC_LOCAL24PC relocations in VLE code but giving them a new meaning.

>> > Is that documented in the ABI?

>> >

>> > I think it would be better to define new R_PPC_VLE_PLTREL24 and

>> > R_PPC_VLE_LOCAL24 relocs, and make the assembler generate them when

>> > assembling VLE code.

>>

>> Nope, they are not defined by ABI at all. I agree it would be better

>> to rework. I will remove it from current patch set.

>

> I should note that I'm not greatly concerned about adding relocations

> that aren't described in an ABI document.  It's not ideal, but the

> document can always be modified later.  I was more concerned that

> someone may have already described R_PPC_PLTREL24 as behaving

> differently for VLE, and the problem that causes for compatibility if

> the GNU toolchain then goes off and implements something else.

>

>> > As I understand it, SHF_PPC_VLE and PF_PPC_VLE are set on sections or

>> > segments containing instructions that can only be executed by a

>> > processor in VLE mode.  PPC_OPCODE_VLE is set for such opcodes too.

>> > So, do the LSP instructions only execute in VLE mode?  I suspect not,

>> > from their encoding.

>> >

>> > Do you have the LSP instructions in the correct opcode table?

>>

>> I see that LSP instructions are available only on the cores with VLE ISA only.

>

> OK, but if there was a processor that could operate in both VLE and

> non-VLE mode (controlled by MAS2 bit VLE), would these instructions be

> available in both modes?  If only VLE, then SHF_PPC_VLE ought to be

> set for any section containing them.  See tc-ppc.c:3513.

>

> However, from the fact that the "Lightweight Signal Processing APU

> (LSP APU) Reference Manual" does not mention VLE, and the encoding of

> these instructions, my guess is that these instruction are not VLE and

> thus should not be in vle_opcodes.

>

> --

> Alan Modra

> Australia Development Lab, IBM




-- 
Best regards,
AF
From 7e445bda4bae1899527fe0d562dfd7f9654189a6 Mon Sep 17 00:00:00 2001
From: Alexander Fedotov-B55613 <b55613@freescale.com>
Date: Wed, 30 Aug 2017 17:57:14 +0300
Subject: [PATCH] Missing relocation R_PPC_VLE_ADDR20. Add VLE flag to details
 in readelf.

---
 bfd/ChangeLog       |  7 +++++++
 bfd/elf32-ppc.c     | 37 +++++++++++++++++++++++++++++++++++++
 binutils/ChangeLog  |  6 ++++++
 binutils/readelf.c  | 11 +++++++++++
 gas/ChangeLog       |  7 +++++++
 gas/config/tc-ppc.c | 20 ++++++++++++++++++++
 gas/config/tc-ppc.h |  3 +++
 include/ChangeLog   |  5 +++++
 include/elf/ppc.h   |  1 +
 9 files changed, 97 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 4882260..eeb6382 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2017-08-30  Alexander Fedotov <alexander.fedotov@nxp.com>
+	    Edmar Wienskoski <edmar.wienskoski@nxp.com
+
+	* elf32-ppc.c (R_PPC_VLE_ADDR20): New relocation.
+	(ppc_elf_vle_split20): New function.
+	(ppc_elf_relocate_section): Handle R_PPC_VLE_ADDR20.
+
 2017-08-30  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR binutils/22032
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 2bdba9f..da4adea 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 6d6aeee..d8a3de7 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2017-08-30  Alexander Fedotov <alexander.fedotov@nxp.com>
+	    Edmar Wienskoski <edmar.wienskoski@nxp.com
+
+	* readelf.c (get_elf_section_flags): Add VLE.
+	(process_section_headers): Add VLE key to details.
+
 2017-08-25  Alan Modra  <amodra@gmail.com>
 
 	PR 21994
diff --git a/binutils/readelf.c b/binutils/readelf.c
index db3fc03..571da2c 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 2e60e29..51cdf0d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,11 @@
+2017-08-30  Alexander Fedotov <alexander.fedotov@nxp.com>
+	    Edmar Wienskoski <edmar.wienskoski@nxp.com
+
+	* 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: XFAIL for VLE
+
 2017-08-30  Maciej W. Rozycki  <macro@imgtec.com>
 
 	* testsuite/gas/mips/branch-local-n32-2.d: Use `branch-local-2.l'
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index d20fac6..7118b71 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 514c223..f71f2ea 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 e187263..dc7446f 100644
--- a/gas/testsuite/gas/elf/section10.d
+++ b/gas/testsuite/gas/elf/section10.d
@@ -1,7 +1,7 @@
 #readelf: -N --wide
 #name: numeric section flags and types
 # The RX port annoyingly reorders the sections so that they do not match the sequence expected below.
-#skip: rx-*-*
+#skip: rx-*-* powerpc*-*-*vle
 
 #...
 [ 	]*\[.*\][ 	]+.text
diff --git a/include/ChangeLog b/include/ChangeLog
index d914f71..8f50361 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2017-08-30  Alexander Fedotov <alexander.fedotov@nxp.com>
+	    Edmar Wienskoski <edmar.wienskoski@nxp.com
+
+	* elf/ppc.h (R_PPC_VLE_ADDR20): New relocation.
+
 2017-08-23  Alexander Fedotov <alexander.fedotov@nxp.com>
 	    Edmar Wienskoski <edmar.wienskoski@nxp.com>
 
diff --git a/include/elf/ppc.h b/include/elf/ppc.h
index 6790cd7..a7d2f3e 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)
Alexander Fedotov Sept. 4, 2017, 7:41 a.m. | #10
Ping on a patch :)

On Wed, Aug 30, 2017 at 7:03 PM, Alexander Fedotov <alfedotov@gmail.com> wrote:
>>> If you split off the part dealing with SEC_PPC_VLE that can be

>>> committed separately.

>

> Done. New patch attached.

>

>

>>> OK, but if there was a processor that could operate in both VLE and

>>> non-VLE mode (controlled by MAS2 bit VLE), would these instructions be

>>> available in both modes?  If only VLE, then SHF_PPC_VLE ought to be

>>> set for any section containing them.  See tc-ppc.c:3513.

>>>

>>> However, from the fact that the "Lightweight Signal Processing APU

>>> (LSP APU) Reference Manual" does not mention VLE, and the encoding of

>>> these instructions, my guess is that these instruction are not VLE and

>>> thus should not be in vle_opcodes.

>

> Yes, there could be e.g e200z759n core. But it has SPE, not LSP.

>

> On Tue, Aug 29, 2017 at 9:17 AM, Alan Modra <amodra@gmail.com> wrote:

>> On Mon, Aug 28, 2017 at 05:20:45PM +0300, Alexander Fedotov wrote:

>>> > You could reuse the SEC_MEP_VLIW bit, I guess.   The section flags

>>> > weren't really supposed to be used for target-specific purposes, but

>>> > it seems pointless trying to be a purist now.

>>>

>>> Okay, so I will set

>>> +#define SEC_PPC_VLE SEC_MEP_VLIW

>>

>> If you split off the part dealing with SEC_PPC_VLE that can be

>> committed separately.

>>

>>> > That doesn't look elegant at all.  So you are using R_PPC_PLTREL24 and

>>> > R_PPC_LOCAL24PC relocations in VLE code but giving them a new meaning.

>>> > Is that documented in the ABI?

>>> >

>>> > I think it would be better to define new R_PPC_VLE_PLTREL24 and

>>> > R_PPC_VLE_LOCAL24 relocs, and make the assembler generate them when

>>> > assembling VLE code.

>>>

>>> Nope, they are not defined by ABI at all. I agree it would be better

>>> to rework. I will remove it from current patch set.

>>

>> I should note that I'm not greatly concerned about adding relocations

>> that aren't described in an ABI document.  It's not ideal, but the

>> document can always be modified later.  I was more concerned that

>> someone may have already described R_PPC_PLTREL24 as behaving

>> differently for VLE, and the problem that causes for compatibility if

>> the GNU toolchain then goes off and implements something else.

>>

>>> > As I understand it, SHF_PPC_VLE and PF_PPC_VLE are set on sections or

>>> > segments containing instructions that can only be executed by a

>>> > processor in VLE mode.  PPC_OPCODE_VLE is set for such opcodes too.

>>> > So, do the LSP instructions only execute in VLE mode?  I suspect not,

>>> > from their encoding.

>>> >

>>> > Do you have the LSP instructions in the correct opcode table?

>>>

>>> I see that LSP instructions are available only on the cores with VLE ISA only.

>>

>> OK, but if there was a processor that could operate in both VLE and

>> non-VLE mode (controlled by MAS2 bit VLE), would these instructions be

>> available in both modes?  If only VLE, then SHF_PPC_VLE ought to be

>> set for any section containing them.  See tc-ppc.c:3513.

>>

>> However, from the fact that the "Lightweight Signal Processing APU

>> (LSP APU) Reference Manual" does not mention VLE, and the encoding of

>> these instructions, my guess is that these instruction are not VLE and

>> thus should not be in vle_opcodes.

>>

>> --

>> Alan Modra

>> Australia Development Lab, IBM

>

>

>

> --

> Best regards,

> AF




-- 
Best regards,
AF
Alan Modra Sept. 4, 2017, 11:15 p.m. | #11
On Mon, Sep 04, 2017 at 10:41:14AM +0300, Alexander Fedotov wrote:
> Ping on a patch :)


Thanks for your patience.  It's now committed with a small change:
I modified the section10.d gas test to pass for VLE rather than
disabling it.

-- 
Alan Modra
Australia Development Lab, IBM

Patch

From daa4f8fad1f39691b6e3338b1acb24b388c8450d Mon Sep 17 00:00:00 2001
From: Alexander Fedotov-B55613 <b55613@freescale.com>
Date: Sat, 26 Aug 2017 20:29:23 +0300
Subject: [PATCH] Update VLE to handle PLT, new relocations and flags.

---
 bfd/ChangeLog                     |  21 +++++
 bfd/bfd-in2.h                     |   3 +
 bfd/elf32-ppc.c                   | 189 +++++++++++++++++++++++++++++++++++---
 bfd/section.c                     |   3 +
 binutils/ChangeLog                |   8 ++
 binutils/objdump.c                |   5 +
 binutils/readelf.c                |  11 +++
 gas/ChangeLog                     |  12 +++
 gas/config/obj-elf.c              |   5 +
 gas/config/tc-ppc.c               |  25 ++++-
 gas/config/tc-ppc.h               |   3 +
 gas/testsuite/gas/elf/section10.d |   2 +-
 gas/testsuite/gas/ppc/ppc.exp     |   2 -
 include/ChangeLog                 |   8 ++
 include/elf/ppc.h                 |   5 +-
 opcodes/ChangeLog                 |   5 +
 opcodes/ppc-dis.c                 |   7 +-
 17 files changed, 295 insertions(+), 19 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e785d0e..c6f6415 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,24 @@ 
+2017-08-26  Alexander Fedotov <alexander.fedotov@nxp.com>
+	    Edmar Wienskoski <edmar.wienskoski@nxp.com
+
+	* bfd-in2.h (SEC_PPC_VLE): New macro.
+	* elf32-ppc.c (E_B): New macro.
+	(R_PPC_VLE_PLTREL24): New relocation.
+	(R_PPC_VLE_ADDR20): Likewise.
+	(ppc_elf_section_flags): New function.
+	(ppc_elf_fake_sections): Add SHF_PPC_VLE.
+	(ppc_elf_check_relocs): Hnadle R_PPC_VLE_ADDR20, R_PPC_VLE_PLTREL24
+	and R_PPC_VLE_ADDR20 relocations.
+	(ppc_elf_vle_split20): New function.
+	(ppc_target_stub_entry_type): New.
+	(stub_entry_vle): New stub.
+	(ppc_elf_relax_section): Handle stub_entry_vle
+	and new relocations.
+	(ppc_elf_relocate_section): Handle stub_entry_vle
+	and new relocations. Use E_B instruiction when VLE for trampolines.
+	(elf_backend_section_flags): New macro.
+	* section.c (SEC_PPC_VLE): New macro.
+
 2017-08-26  Alan Modra  <amodra@gmail.com>
 
 	* elf32-ppc.c (must_be_dyn_reloc): Use bfd_link_dll.  Comment.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index d126aed..17fafa0 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1467,6 +1467,9 @@  typedef struct bfd_section
   /* Indicate that section has the purecode flag set.  */
 #define SEC_ELF_PURECODE 0x80000000
 
+  /* PowerPC VLE code.  */
+#define SEC_PPC_VLE 0x100000000
+
   /*  End of section flags.  */
 
   /* Some internal packed boolean fields.  */
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index a5d8193..e3c9b8b 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -171,6 +171,9 @@  static const bfd_vma ppc_elf_vxworks_pic_plt0_entry
 #define NOP		0x60000000
 #define SUB_11_11_12	0x7d6c5850
 
+/* VLE some instructions */
+#define E_B		0x78000000
+
 /* Offset of tp and dtp pointers from start of TLS block.  */
 #define TP_OFFSET	0x7000
 #define DTP_OFFSET	0x8000
@@ -1444,6 +1447,21 @@  static reloc_howto_type ppc_elf_howto_raw[] = {
 	 0x1fffffe,		/* dst_mask */
 	 TRUE),			/* pcrel_offset */
 
+  /* A relative 24 bit branch.  */
+  HOWTO (R_PPC_VLE_PLTREL24,	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 24,			/* bitsize */
+	 TRUE,			/* pc_relative */
+	 1,			/* bitpos */
+	 complain_overflow_signed, /* complain_on_overflow */
+	 ppc_elf_unhandled_reloc, /* special_function */
+	 "R_PPC_VLE_PLTREL24",	/* name */
+	 FALSE,			/* partial_inplace */
+	 0,			/* src_mask */
+	 0x1fffffe,		/* dst_mask */
+	 TRUE),			/* pcrel_offset */
+
   /* The 16 LSBS in split16a format.  */
   HOWTO (R_PPC_VLE_LO16A,	/* type */
 	 0,			/* rightshift */
@@ -1656,6 +1674,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) */
@@ -2463,6 +2496,14 @@  ppc_elf_lookup_section_flags (char *flag_name)
   return 0;
 }
 
+static bfd_boolean
+ppc_elf_section_flags (flagword *flags, const Elf_Internal_Shdr * hdr)
+{
+  if (hdr->sh_flags & SHF_PPC_VLE)
+    *flags |= SEC_PPC_VLE;
+  return TRUE;
+}
+
 /* Return address for Ith PLT stub in section PLT, for relocation REL
    or (bfd_vma) -1 if it should not be included.  */
 
@@ -2512,6 +2553,9 @@  ppc_elf_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
   if ((asect->flags & SEC_SORT_ENTRIES) != 0)
     shdr->sh_type = SHT_ORDERED;
 
+  if ((asect->flags & SEC_PPC_VLE) != 0)
+    shdr->sh_flags |= SHF_PPC_VLE;
+
   return TRUE;
 }
 
@@ -4265,6 +4309,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:
@@ -4312,6 +4357,7 @@  ppc_elf_check_relocs (bfd *abfd,
 	  break;
 
 	case R_PPC_PLTREL24:
+	case R_PPC_VLE_PLTREL24:
 	  if (h == NULL)
 	    break;
 	  /* Fall through */
@@ -4383,6 +4429,7 @@  ppc_elf_check_relocs (bfd *abfd,
 	case R_PPC_NONE:
 	case R_PPC_max:
 	case R_PPC_RELAX:
+	case R_PPC_VLE_RELAX:
 	case R_PPC_RELAX_PLT:
 	case R_PPC_RELAX_PLTREL24:
 	case R_PPC_16DX_HA:
@@ -4983,6 +5030,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.  */
@@ -6893,6 +6957,13 @@  static const int shared_stub_entry[] =
     0x4e800420, /* bctr */
   };
 
+typedef enum ppc_target_stub_entry_type
+  {
+    stub_entry_type_ppc = 0,
+    stub_entry_type_vle
+  }
+ppc_target_stub_entry_type;
+
 static const int stub_entry[] =
   {
     0x3d800000, /* lis 12,xxx@ha */
@@ -6901,6 +6972,15 @@  static const int stub_entry[] =
     0x4e800420, /* bctr */
   };
 
+/* Keep the same size as stub_entry */
+static const int stub_entry_vle[] =
+  {
+    0x7180e000, /* e_lis 12,xxx@ha */
+    0x1d8c0000, /* e_add16i 12,12,xxx@l */
+    0x7d8903a6, /* mtctr 12 */
+    0x00064400, /* se_bctr, se_nop (size padding) */
+  };
+
 struct ppc_elf_relax_info
 {
   unsigned int workaround_size;
@@ -6941,6 +7021,7 @@  ppc_elf_relax_section (bfd *abfd,
   bfd_size_type trampbase, trampoff, newsize, picfixup_size;
   asection *got2;
   bfd_boolean maybe_pasted;
+  ppc_target_stub_entry_type target_stub_type = stub_entry_type_ppc;
 
   *again = FALSE;
 
@@ -7027,15 +7108,32 @@  ppc_elf_relax_section (bfd *abfd,
 	    case R_PPC_REL24:
 	    case R_PPC_LOCAL24PC:
 	    case R_PPC_PLTREL24:
+	      target_stub_type = stub_entry_type_ppc;
 	      max_branch_offset = 1 << 25;
 	      break;
 
 	    case R_PPC_REL14:
 	    case R_PPC_REL14_BRTAKEN:
 	    case R_PPC_REL14_BRNTAKEN:
+	      target_stub_type = stub_entry_type_ppc;
 	      max_branch_offset = 1 << 15;
 	      break;
 
+	    case R_PPC_VLE_REL24:
+	      target_stub_type = stub_entry_type_vle;
+	      max_branch_offset = 1 << 25;
+	      break;
+
+	    case R_PPC_VLE_REL15:
+	      target_stub_type = stub_entry_type_vle;
+	      max_branch_offset = 1 << 16;
+	      break;
+
+	    case R_PPC_VLE_REL8:
+	      target_stub_type = stub_entry_type_vle;
+	      max_branch_offset = 1 << 9;
+	      break;
+
 	    case R_PPC_ADDR16_HA:
 	      if (htab->params->pic_fixup > 0)
 		break;
@@ -7314,7 +7412,12 @@  ppc_elf_relax_section (bfd *abfd,
 		  size = 4 * ARRAY_SIZE (stub_entry);
 		  insn_offset = 0;
 		}
-	      stub_rtype = R_PPC_RELAX;
+
+	      if (target_stub_type == stub_entry_type_ppc)
+		stub_rtype = R_PPC_RELAX;
+	      else
+		stub_rtype = R_PPC_VLE_RELAX;
+
 	      if (tsec == htab->elf.splt
 		  || tsec == htab->glink)
 		{
@@ -7371,10 +7474,21 @@  ppc_elf_relax_section (bfd *abfd,
 	    case R_PPC_REL24:
 	    case R_PPC_LOCAL24PC:
 	    case R_PPC_PLTREL24:
-	      t0 = bfd_get_32 (abfd, hit_addr);
-	      t0 &= ~0x3fffffc;
-	      t0 |= val & 0x3fffffc;
-	      bfd_put_32 (abfd, t0, hit_addr);
+	      if (r_type == R_PPC_PLTREL24
+		  && (elf_section_flags (isec) & SHF_PPC_VLE) != 0)
+		{
+		  t0 = bfd_get_32 (abfd, hit_addr);
+		  t0 &= ~0x01fffffe;
+		  t0 |= val & 0x01fffffe;
+		  bfd_put_32 (abfd, t0, hit_addr);
+		}
+	      else
+		{
+		  t0 = bfd_get_32 (abfd, hit_addr);
+		  t0 &= ~0x3fffffc;
+		  t0 |= val & 0x3fffffc;
+		  bfd_put_32 (abfd, t0, hit_addr);
+		}
 	      break;
 
 	    case R_PPC_REL14:
@@ -7385,6 +7499,27 @@  ppc_elf_relax_section (bfd *abfd,
 	      t0 |= val & 0xfffc;
 	      bfd_put_32 (abfd, t0, hit_addr);
 	      break;
+
+	    case R_PPC_VLE_REL24:
+	      t0 = bfd_get_32 (abfd, hit_addr);
+	      t0 &= ~0x01fffffe;
+	      t0 |= val & 0x01fffffe;
+	      bfd_put_32 (abfd, t0, hit_addr);
+	      break;
+
+	    case R_PPC_VLE_REL15:
+	      t0 = bfd_get_32 (abfd, hit_addr);
+	      t0 &= ~0xfffe;
+	      t0 |= val & 0xfffe;
+	      bfd_put_32 (abfd, t0, hit_addr);
+	      break;
+
+	    case R_PPC_VLE_REL8:
+	      t0 = bfd_get_32 (abfd, hit_addr);
+	      t0 &= ~0xff;
+	      t0 |= val & 0xff;
+	      bfd_put_32 (abfd, t0, hit_addr);
+	      break;
 	    }
 	}
 
@@ -9035,6 +9170,7 @@  ppc_elf_relocate_section (bfd *output_bfd,
 	  /* Fall through.  */
 
 	case R_PPC_RELAX:
+	case R_PPC_VLE_RELAX:
 	  {
 	    const int *stub;
 	    size_t size;
@@ -9055,7 +9191,13 @@  ppc_elf_relocate_section (bfd *output_bfd,
 	      }
 	    else
 	      {
-		stub = stub_entry;
+		if (r_type == R_PPC_VLE_RELAX)
+		  stub = stub_entry_vle;
+		else
+		  stub = stub_entry;
+
+		BFD_ASSERT(ARRAY_SIZE (stub_entry_vle) == ARRAY_SIZE (stub_entry));
+
 		size = ARRAY_SIZE (stub_entry);
 	      }
 
@@ -9064,10 +9206,23 @@  ppc_elf_relocate_section (bfd *output_bfd,
 	      relocation = 0;
 
 	    /* First insn is HA, second is LO.  */
-	    insn = *stub++;
-	    insn |= ((relocation + 0x8000) >> 16) & 0xffff;
-	    bfd_put_32 (input_bfd, insn, contents + insn_offset);
-	    insn_offset += 4;
+	    if (r_type == R_PPC_VLE_RELAX)
+	      {
+		/* Write e_lis insn is @ha type relocation */
+		unsigned ha_val;
+		insn = *stub++;
+		ha_val = ((relocation + 0x8000) >> 16) & 0xffff;
+		insn |= (((ha_val & 0xf800) << 5) | (ha_val&0x7ff));
+		bfd_put_32 (input_bfd, insn, contents + insn_offset);
+		insn_offset += 4;
+	      }
+	    else
+	      {
+		insn = *stub++;
+		insn |= ((relocation + 0x8000) >> 16) & 0xffff;
+		bfd_put_32 (input_bfd, insn, contents + insn_offset);
+		insn_offset += 4;
+	      }
 
 	    insn = *stub++;
 	    insn |= relocation & 0xffff;
@@ -9474,6 +9629,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:
@@ -9751,8 +9910,15 @@  ppc_elf_relocate_section (bfd *output_bfd,
       && (strcmp (input_section->output_section->name, ".init") == 0
 	  || strcmp (input_section->output_section->name, ".fini") == 0))
     {
+      unsigned int insn;
+
+      if ((elf_section_flags (input_section) & SHF_PPC_VLE) == 0)
+	insn = B;
+      else
+	insn = E_B;
+
       /* Branch around the trampolines.  */
-      unsigned int insn = B + input_section->size - input_section->rawsize;
+      insn += input_section->size - input_section->rawsize;
       bfd_put_32 (input_bfd, insn, contents + input_section->rawsize);
     }
 
@@ -10959,6 +11125,7 @@  ppc_elf_finish_dynamic_sections (bfd *output_bfd,
 #define elf_backend_action_discarded		ppc_elf_action_discarded
 #define elf_backend_init_index_section		_bfd_elf_init_1_index_section
 #define elf_backend_lookup_section_flags_hook	ppc_elf_lookup_section_flags
+#define elf_backend_section_flags	       ppc_elf_section_flags
 
 #include "elf32-target.h"
 
diff --git a/bfd/section.c b/bfd/section.c
index 811d42a..54698f4 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -364,6 +364,9 @@  CODE_FRAGMENT
 .  {* Indicate that section has the purecode flag set.  *}
 .#define SEC_ELF_PURECODE 0x80000000
 .
+.  {* PowerPC VLE code.  *}
+.#define SEC_PPC_VLE 0x100000000
+.
 .  {*  End of section flags.  *}
 .
 .  {* Some internal packed boolean fields.  *}
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 6d6aeee..57185c9 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,11 @@ 
+2017-08-26  Alexander Fedotov <alexander.fedotov@nxp.com>
+	    Edmar Wienskoski <edmar.wienskoski@nxp.com
+
+	* objdump.c (dump_section_header): Add SEC_PPC_VLE.
+	* readelf.c (get_elf_section_flags): Add VLE.
+	Handle SEC_PPC_VLE flag.
+	(process_section_headers): Add VLE key to details.
+
 2017-08-25  Alan Modra  <amodra@gmail.com>
 
 	PR 21994
diff --git a/binutils/objdump.c b/binutils/objdump.c
index 3c5defa..8782648 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -485,6 +485,11 @@  dump_section_header (bfd *abfd, asection *section, void *data)
   PF (SEC_NEVER_LOAD, "NEVER_LOAD");
   PF (SEC_EXCLUDE, "EXCLUDE");
   PF (SEC_SORT_ENTRIES, "SORT_ENTRIES");
+  if (bfd_get_arch(abfd) == bfd_arch_powerpc
+      || bfd_get_arch (abfd) == bfd_mach_ppc_vle)
+    {
+      PF (SEC_PPC_VLE, "VLE");
+    }
   if (bfd_get_arch (abfd) == bfd_arch_tic54x)
     {
       PF (SEC_TIC54X_BLOCK, "BLOCK");
diff --git a/binutils/readelf.c b/binutils/readelf.c
index db3fc03..571da2c 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 8bea1df..19abfb9 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,15 @@ 
+2017-08-26  Alexander Fedotov <alexander.fedotov@nxp.com>
+	    Edmar Wienskoski <edmar.wienskoski@nxp.com
+
+	* config/obj-elf.c (obj_elf_change_section): Override if
+	section have SHF_PPC_VLE.
+	* config/tc-ppc.c (md_parse_option): Handle "mno-vle" flag.
+	(ppc_section_flags): Handle SHF_PPC_VLE attribute.
+	(ppc_elf_section_letter): New function.
+	* config/tc-ppc.h (md_elf_section_letter): New.
+	* testsuite/gas/elf/section10.d: XFAIL for VLE
+	* testsuite/gas/ppc/ppc.exp: Mark LSP test as pass.
+
 2017-08-23  Alexander Fedotov <alexander.fedotov@nxp.com>
 	    Edmar Wienskoski <edmar.wienskoski@nxp.com
 
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 49d99a4..e79103b 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -696,6 +696,11 @@  obj_elf_change_section (const char *name,
 	    /* RX init/fini arrays can and should have the "awx" attributes set.  */
 	    ;
 #endif
+#ifdef TC_PPC
+	  /* A section on powerpc-vle may have SHF_PPC_VLE.  */
+	  else if ((attr & ~ssect->attr) == SHF_PPC_VLE)
+	    override = TRUE;
+#endif
 	  else
 	    {
 	      if (group_name == NULL)
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index d20fac6..6b9f6c4 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;
 
@@ -3676,13 +3686,26 @@  ppc_section_type (char *str, size_t len)
 }
 
 int
-ppc_section_flags (flagword flags, bfd_vma attr ATTRIBUTE_UNUSED, int type)
+ppc_section_flags (flagword flags, bfd_vma attr, int type)
 {
   if (type == SHT_ORDERED)
     flags |= SEC_ALLOC | SEC_LOAD | SEC_SORT_ENTRIES;
 
+  if (attr == SHF_PPC_VLE)
+    flags |= SEC_PPC_VLE;
+
   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 514c223..f71f2ea 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 e187263..dc7446f 100644
--- a/gas/testsuite/gas/elf/section10.d
+++ b/gas/testsuite/gas/elf/section10.d
@@ -1,7 +1,7 @@ 
 #readelf: -N --wide
 #name: numeric section flags and types
 # The RX port annoyingly reorders the sections so that they do not match the sequence expected below.
-#skip: rx-*-*
+#skip: rx-*-* powerpc*-*-*vle
 
 #...
 [ 	]*\[.*\][ 	]+.text
diff --git a/gas/testsuite/gas/ppc/ppc.exp b/gas/testsuite/gas/ppc/ppc.exp
index cdcd8a1..593c703 100644
--- a/gas/testsuite/gas/ppc/ppc.exp
+++ b/gas/testsuite/gas/ppc/ppc.exp
@@ -61,8 +61,6 @@  if { [istarget powerpc*-*-*] } then {
 	    run_dump_test "vle-simple-5"
 	    run_dump_test "vle-simple-6"
 
-	    #fail expected until get_powerpc_dialect() patch not applied
-	    setup_xfail "*-*-*"
 	    run_dump_test "lsp"
 	    run_dump_test "lsp-checks"
 	    run_dump_test "efs"
diff --git a/include/ChangeLog b/include/ChangeLog
index d914f71..32e2faa 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,11 @@ 
+2017-08-26  Alexander Fedotov <alexander.fedotov@nxp.com>
+	    Edmar Wienskoski <edmar.wienskoski@nxp.com
+
+	* elf/ppc.h (R_PPC_VLE_RELAX): New relocation.
+	(R_PPC_16DX_HA): Modify number.
+	(R_PPC_VLE_PLTREL24): New relocation.
+	(R_PPC_VLE_ADDR20): Likewise.
+
 2017-08-23  Alexander Fedotov <alexander.fedotov@nxp.com>
 	    Edmar Wienskoski <edmar.wienskoski@nxp.com>
 
diff --git a/include/elf/ppc.h b/include/elf/ppc.h
index 6790cd7..d3a77f9 100644
--- a/include/elf/ppc.h
+++ b/include/elf/ppc.h
@@ -79,8 +79,10 @@  START_RELOC_NUMBERS (elf_ppc_reloc_type)
   RELOC_NUMBER (R_PPC_RELAX,		 48)
   RELOC_NUMBER (R_PPC_RELAX_PLT,	 49)
   RELOC_NUMBER (R_PPC_RELAX_PLTREL24,	 50)
+  RELOC_NUMBER (R_PPC_VLE_RELAX,	 51)
 /* Reloc only used internally by gas.  As above, value is unimportant.  */
-  RELOC_NUMBER (R_PPC_16DX_HA,		 51)
+  RELOC_NUMBER (R_PPC_16DX_HA,		 52)
+  RELOC_NUMBER (R_PPC_VLE_PLTREL24,	 53)
 #endif
 
   /* Relocs added to support TLS.  */
@@ -152,6 +154,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)
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index e252089..63e8068 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,8 @@ 
+2017-08-26  Alexander Fedotov <alexander.fedotov@nxp.com>
+	    Edmar Wienskoski <edmar.wienskoski@nxp.com
+
+	* ppc-dis.c (get_powerpc_dialect): Modify for VLE.
+
 2017-08-23  Alexander Fedotov <alexander.fedotov@nxp.com>
 	    Edmar Wienskoski <edmar.wienskoski@nxp.com>
 
diff --git a/opcodes/ppc-dis.c b/opcodes/ppc-dis.c
index 0e2e185..7b95f0a 100644
--- a/opcodes/ppc-dis.c
+++ b/opcodes/ppc-dis.c
@@ -253,12 +253,13 @@  get_powerpc_dialect (struct disassemble_info *info)
   dialect = POWERPC_DIALECT (info);
 
   /* Disassemble according to the section headers flags for VLE-mode.  */
-  if (dialect & PPC_OPCODE_VLE
-      && info->section != NULL && info->section->owner != NULL
+  if (dialect & PPC_OPCODE_VLE)
+    return dialect;
+  else if (info->section != NULL && info->section->owner != NULL
       && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
       && elf_object_id (info->section->owner) == PPC32_ELF_DATA
       && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
-    return dialect;
+    return PPC_OPCODE_VLE;
   else
     return dialect & ~ PPC_OPCODE_VLE;
 }
-- 
2.7.4