1 //===-- sanitizer_leb128.h --------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef SANITIZER_LEB128_H 10 #define SANITIZER_LEB128_H 11 12 #include "sanitizer_common.h" 13 #include "sanitizer_internal_defs.h" 14 15 namespace __sanitizer { 16 17 template <typename T, typename It> 18 It EncodeSLEB128(T value, It begin, It end) { 19 bool more; 20 do { 21 u8 byte = value & 0x7f; 22 // NOTE: this assumes that this signed shift is an arithmetic right shift. 23 value >>= 7; 24 more = !((((value == 0) && ((byte & 0x40) == 0)) || 25 ((value == -1) && ((byte & 0x40) != 0)))); 26 if (more) 27 byte |= 0x80; 28 if (UNLIKELY(begin == end)) 29 break; 30 *(begin++) = byte; 31 } while (more); 32 return begin; 33 } 34 35 template <typename T, typename It> 36 It DecodeSLEB128(It begin, It end, T* v) { 37 T value = 0; 38 unsigned shift = 0; 39 u8 byte; 40 do { 41 if (UNLIKELY(begin == end)) 42 return begin; 43 byte = *(begin++); 44 T slice = byte & 0x7f; 45 value |= slice << shift; 46 shift += 7; 47 } while (byte >= 128); 48 if (shift < 64 && (byte & 0x40)) 49 value |= (-1ULL) << shift; 50 *v = value; 51 return begin; 52 } 53 54 template <typename T, typename It> 55 It EncodeULEB128(T value, It begin, It end) { 56 do { 57 u8 byte = value & 0x7f; 58 value >>= 7; 59 if (value) 60 byte |= 0x80; 61 if (UNLIKELY(begin == end)) 62 break; 63 *(begin++) = byte; 64 } while (value); 65 return begin; 66 } 67 68 template <typename T, typename It> 69 It DecodeULEB128(It begin, It end, T* v) { 70 T value = 0; 71 unsigned shift = 0; 72 u8 byte; 73 do { 74 if (UNLIKELY(begin == end)) 75 return begin; 76 byte = *(begin++); 77 T slice = byte & 0x7f; 78 value += slice << shift; 79 shift += 7; 80 } while (byte >= 128); 81 *v = value; 82 return begin; 83 } 84 85 } // namespace __sanitizer 86 87 #endif // SANITIZER_LEB128_H 88