From fc5e0925d4bff79c8c036cf00803112a1ec04188 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 15 May 2021 14:36:26 +0930 Subject: [PATCH] _mul_overflow and get_encoded_value A sufficiently mad compiler optimiser can take undefined behaviour according to the C standard as an opportunity to remove code. Since "data + size" might be seen to be past the end of an array, calculating such an expression is UB. _mul_overflow is infrastructure for later patches. * bucomm.h (_mul_overflow): Define. * dwarf.c (get_encoded_value): Avoid pointer UB. --- binutils/ChangeLog | 5 +++++ binutils/bucomm.h | 8 ++++++++ binutils/dwarf.c | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 85d21ebfa6..74efc3376e 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2021-05-15 Alan Modra + + * bucomm.h (_mul_overflow): Define. + * dwarf.c (get_encoded_value): Avoid pointer UB. + 2021-05-13 Alan Modra PR 27861 diff --git a/binutils/bucomm.h b/binutils/bucomm.h index 78f61762ca..2769c27867 100644 --- a/binutils/bucomm.h +++ b/binutils/bucomm.h @@ -80,4 +80,12 @@ void *xmalloc (size_t); void *xrealloc (void *, size_t); +#if __GNUC__ >= 7 +#define _mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res) +#else +/* Assumes unsigned values. Careful! Args evaluated multiple times. */ +#define _mul_overflow(a, b, res) \ + ((*res) = (a), (*res) *= (b), (b) != 0 && (*res) / (b) != (a)) +#endif + #endif /* _BUCOMM_H */ diff --git a/binutils/dwarf.c b/binutils/dwarf.c index 2794a15a1d..020b7e071e 100644 --- a/binutils/dwarf.c +++ b/binutils/dwarf.c @@ -178,7 +178,7 @@ get_encoded_value (unsigned char **pdata, unsigned int size = size_of_encoded_value (encoding); dwarf_vma val; - if (data + size >= end) + if (data >= end || size > (size_t) (end - data)) { warn (_("Encoded value extends past end of section\n")); * pdata = end; -- 2.34.1