88 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef SANITIZER_LEB128_H10#define SANITIZER_LEB128_H11 12#include "sanitizer_common.h"13#include "sanitizer_internal_defs.h"14 15namespace __sanitizer {16 17template <typename T, typename It>18It 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 35template <typename T, typename It>36It 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 54template <typename T, typename It>55It 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 68template <typename T, typename It>69It 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 __sanitizer86 87#endif // SANITIZER_LEB128_H88