[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