_mul_overflow and get_encoded_value
authorAlan Modra <amodra@gmail.com>
Sat, 15 May 2021 05:06:26 +0000 (14:36 +0930)
committerAlan Modra <amodra@gmail.com>
Sat, 15 May 2021 05:06:54 +0000 (14:36 +0930)
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
binutils/bucomm.h
binutils/dwarf.c

index 85d21ebfa6b2e5fb90100ac7475b021eedbb815d..74efc3376ebcbcad79b1266c72c2b5487f858c04 100644 (file)
@@ -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
index 78f61762cac9f50188dd72ca98e7f29f7c8cee1f..2769c2786717c233c4ccf553aa445d587f188225 100644 (file)
@@ -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 */
index 2794a15a1d3948ed151a3a18137777f4fb6b3dfd..020b7e071ec22f36906a1ad4535c79d343065a40 100644 (file)
@@ -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;