diff options
author | Alan Modra <amodra@gmail.com> | 2014-06-07 12:09:04 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2014-06-07 14:55:11 +0930 |
commit | a47622ac1badbd906c7533ef6011b6bb021271ee (patch) | |
tree | 3e6ad4e4cb4ed80e652cf756cbbacf4a7a6ae3d1 /bfd | |
parent | d634c69f87e9b88a5ff5cd8af7a1f60e738ea0bd (diff) | |
download | binutils-a47622ac1badbd906c7533ef6011b6bb021271ee.zip binutils-a47622ac1badbd906c7533ef6011b6bb021271ee.tar.gz binutils-a47622ac1badbd906c7533ef6011b6bb021271ee.tar.bz2 |
Allow both signed and unsigned fields in PowerPC cmpli insn
There are legitimate reasons to allow a signed value in a cmpli insn
field, for example to test for a "stw r1,lock@sdarel(r13)" instruction
in user code, a kernel might use
subis r3,r3,STW_R1_0R13@ha # subtract off high part
cmplwi r3,lock@sdarel # is low part accessing lock?
Since the lock@sdarel may take a range of -32768 to 32767,
the allowed range of cmpli immediate must be at least [-32768,65535].
bfd/
* elf32-ppc.c (ppc_elf_relocate_section): Treat field of cmpli
insn as a bitfield; Use complain_overflow_bitfield.
* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
opcodes/
* ppc-opc.c (UISIGNOPT): Define and use with cmpli.
gas/
* config/tc-ppc.c (ppc_insert_operand): Handle PPC_OPERAND_SIGNOPT
on unsigned fields. Comment on PPC_OPERAND_SIGNOPT signed fields
in 64-bit mode.
gold/
* powerpc.cc (relocate): Treat field of cmpli insn as a bitfield.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 9 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 17 |
3 files changed, 20 insertions, 12 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1ff9fca..c14719f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2014-06-07 Alan Modra <amodra@gmail.com> + + * elf32-ppc.c (ppc_elf_relocate_section): Treat field of cmpli + insn as a bitfield; Use complain_overflow_bitfield. + * elf64-ppc.c (ppc64_elf_relocate_section): Likewise. + 2014-06-05 Joel Brobecker <brobecker@adacore.com> * development.sh: New file. diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 1bea6f8..344845d 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -9147,10 +9147,11 @@ ppc_elf_relocate_section (bfd *output_bfd, unsigned int insn; insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3)); - if ((insn & (0x3f << 26)) == 28u << 26 /* andi */ - || (insn & (0x3f << 26)) == 24u << 26 /* ori */ - || (insn & (0x3f << 26)) == 26u << 26 /* xori */ - || (insn & (0x3f << 26)) == 10u << 26 /* cmpli */) + if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */) + complain = complain_overflow_bitfield; + else if ((insn & (0x3f << 26)) == 28u << 26 /* andi */ + || (insn & (0x3f << 26)) == 24u << 26 /* ori */ + || (insn & (0x3f << 26)) == 26u << 26 /* xori */) complain = complain_overflow_unsigned; } if (howto->complain_on_overflow != complain) diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index e7e2e39..b8d7465 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -14648,14 +14648,15 @@ ppc64_elf_relocate_section (bfd *output_bfd, enum complain_overflow complain = complain_overflow_signed; insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3)); - if (howto->rightshift == 0 - ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */ - || (insn & (0x3f << 26)) == 24u << 26 /* ori */ - || (insn & (0x3f << 26)) == 26u << 26 /* xori */ - || (insn & (0x3f << 26)) == 10u << 26 /* cmpli */) - : ((insn & (0x3f << 26)) == 29u << 26 /* andis */ - || (insn & (0x3f << 26)) == 25u << 26 /* oris */ - || (insn & (0x3f << 26)) == 27u << 26 /* xoris */)) + if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */) + complain = complain_overflow_bitfield; + else if (howto->rightshift == 0 + ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */ + || (insn & (0x3f << 26)) == 24u << 26 /* ori */ + || (insn & (0x3f << 26)) == 26u << 26 /* xori */) + : ((insn & (0x3f << 26)) == 29u << 26 /* andis */ + || (insn & (0x3f << 26)) == 25u << 26 /* oris */ + || (insn & (0x3f << 26)) == 27u << 26 /* xoris */)) complain = complain_overflow_unsigned; if (howto->complain_on_overflow != complain) { |