aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-08-31 08:32:32 +0930
committerAlan Modra <amodra@gmail.com>2020-08-31 20:28:09 +0930
commitc1f138f9557a14678f6f988975cba441f56e6137 (patch)
tree1727af28cdcc72b85c08f140115b5563f92a1c16 /bfd
parent26e3de8e0a2d95e02b9dec46c67531755303fc4b (diff)
downloadbinutils-c1f138f9557a14678f6f988975cba441f56e6137.zip
binutils-c1f138f9557a14678f6f988975cba441f56e6137.tar.gz
binutils-c1f138f9557a14678f6f988975cba441f56e6137.tar.bz2
PR26442 UBSAN: elf32-crx.c:512 cannot be represented in int
PR 26442 * elf32-crx.c (crx_elf_final_link_relocate): Calculate reloc_bits without undefined behaviour. Tidy excess casts.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf32-crx.c21
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;