[binutils-gdb] _mul_overflow and get_encoded_value
Alan Modra
amodra@sourceware.org
Sat May 15 08:12:12 GMT 2021
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=fc5e0925d4bff79c8c036cf00803112a1ec04188
commit fc5e0925d4bff79c8c036cf00803112a1ec04188
Author: Alan Modra <amodra@gmail.com>
Date: Sat May 15 14:36:26 2021 +0930
_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.
Diff:
---
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 85d21ebfa6b..74efc3376eb 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2021-05-15 Alan Modra <amodra@gmail.com>
+
+ * bucomm.h (_mul_overflow): Define.
+ * dwarf.c (get_encoded_value): Avoid pointer UB.
+
2021-05-13 Alan Modra <amodra@gmail.com>
PR 27861
diff --git a/binutils/bucomm.h b/binutils/bucomm.h
index 78f61762cac..2769c278671 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 2794a15a1d3..020b7e071ec 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;
More information about the Binutils-cvs
mailing list