[libunwind] fd802cc - [libunwind] Fix getSLEB128 on large values

Ryan Prichard via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 15 19:14:00 PDT 2020


Author: Ryan Prichard
Date: 2020-07-15T19:12:56-07:00
New Revision: fd802cc4dea4ed1a233ff725f98c686dc2836bf3

URL: https://github.com/llvm/llvm-project/commit/fd802cc4dea4ed1a233ff725f98c686dc2836bf3
DIFF: https://github.com/llvm/llvm-project/commit/fd802cc4dea4ed1a233ff725f98c686dc2836bf3.diff

LOG: [libunwind] Fix getSLEB128 on large values

Previously, for large-enough values, getSLEB128 would attempt to shift
a signed int in the range [0..0x7f] by 28, 35, 42... bits, which is
undefined behavior and likely to fail.

Avoid shifting (-1ULL) by 70 for large values. e.g. For INT64_MAX, the
last two bytes will be:
 - 0x7f [bit==56]
 - 0x00 [bit==63]

Differential Revision: https://reviews.llvm.org/D83742

Added: 
    

Modified: 
    libunwind/src/AddressSpace.hpp

Removed: 
    


################################################################################
diff  --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp
index a4564cb67328..764aaa3489f2 100644
--- a/libunwind/src/AddressSpace.hpp
+++ b/libunwind/src/AddressSpace.hpp
@@ -290,11 +290,11 @@ inline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) {
     if (p == pend)
       _LIBUNWIND_ABORT("truncated sleb128 expression");
     byte = *p++;
-    result |= ((byte & 0x7f) << bit);
+    result |= (uint64_t)(byte & 0x7f) << bit;
     bit += 7;
   } while (byte & 0x80);
   // sign extend negative numbers
-  if ((byte & 0x40) != 0)
+  if ((byte & 0x40) != 0 && bit < 64)
     result |= (-1ULL) << bit;
   addr = (pint_t) p;
   return result;


        


More information about the cfe-commits mailing list