diff options
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf32-crx.c | 21 |
2 files changed, 13 insertions, 14 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5d004cd..7388c4d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,11 @@ 2020-08-31 Alan Modra <amodra@gmail.com> + PR 26442 + * elf32-crx.c (crx_elf_final_link_relocate): Calculate reloc_bits + without undefined behaviour. Tidy excess casts. + +2020-08-31 Alan Modra <amodra@gmail.com> + * elf-m10300.c (mn10300_elf_relax_delete_bytes): Calculate alignment from reloc addend after reloc type R_MN10300_ALIGN is found. diff --git a/bfd/elf32-crx.c b/bfd/elf32-crx.c index 82f1a3e..32db5b7 100644 --- a/bfd/elf32-crx.c +++ b/bfd/elf32-crx.c @@ -506,25 +506,18 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd, as signed or unsigned. */ check = Rvalue >> howto->rightshift; - /* Assumes two's complement. This expression avoids - overflow if howto->bitsize is the number of bits in - bfd_vma. */ - reloc_bits = (((1 << (howto->bitsize - 1)) - 1) << 1) | 1; - - if (((bfd_vma) check & ~reloc_bits) != 0 - && (((bfd_vma) check & ~reloc_bits) - != (-(bfd_vma) 1 & ~reloc_bits))) + reloc_bits = ((bfd_vma) 1 << (howto->bitsize - 1) << 1) - 1; + + if ((check & ~reloc_bits) != 0 + && (check & ~reloc_bits) != ((bfd_vma) -1 & ~reloc_bits)) { /* The above right shift is incorrect for a signed value. See if turning on the upper bits fixes the overflow. */ if (howto->rightshift && (bfd_signed_vma) Rvalue < 0) { - check |= ((bfd_vma) - 1 - & ~((bfd_vma) - 1 - >> howto->rightshift)); - if (((bfd_vma) check & ~reloc_bits) - != (-(bfd_vma) 1 & ~reloc_bits)) + check |= (bfd_vma) -1 & ~((bfd_vma) -1 >> howto->rightshift); + if ((check & ~reloc_bits) != ((bfd_vma) -1 & ~reloc_bits)) return bfd_reloc_overflow; } else @@ -532,7 +525,7 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd, } /* Drop unwanted bits from the value we are relocating to. */ - Rvalue >>= (bfd_vma) howto->rightshift; + Rvalue >>= howto->rightshift; /* Apply dst_mask to select only relocatable part of the insn. */ Rvalue &= howto->dst_mask; |