sanitizer_leb128.h 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. #ifndef SANITIZER_LEB128_H
  9. #define SANITIZER_LEB128_H
  10. #include "sanitizer_common.h"
  11. #include "sanitizer_internal_defs.h"
  12. namespace __sanitizer {
  13. template <typename T, typename It>
  14. It EncodeSLEB128(T value, It begin, It end) {
  15. bool more;
  16. do {
  17. u8 byte = value & 0x7f;
  18. // NOTE: this assumes that this signed shift is an arithmetic right shift.
  19. value >>= 7;
  20. more = !((((value == 0) && ((byte & 0x40) == 0)) ||
  21. ((value == -1) && ((byte & 0x40) != 0))));
  22. if (more)
  23. byte |= 0x80;
  24. if (UNLIKELY(begin == end))
  25. break;
  26. *(begin++) = byte;
  27. } while (more);
  28. return begin;
  29. }
  30. template <typename T, typename It>
  31. It DecodeSLEB128(It begin, It end, T* v) {
  32. T value = 0;
  33. unsigned shift = 0;
  34. u8 byte;
  35. do {
  36. if (UNLIKELY(begin == end))
  37. return begin;
  38. byte = *(begin++);
  39. T slice = byte & 0x7f;
  40. value |= slice << shift;
  41. shift += 7;
  42. } while (byte >= 128);
  43. if (shift < 64 && (byte & 0x40))
  44. value |= (-1ULL) << shift;
  45. *v = value;
  46. return begin;
  47. }
  48. template <typename T, typename It>
  49. It EncodeULEB128(T value, It begin, It end) {
  50. do {
  51. u8 byte = value & 0x7f;
  52. value >>= 7;
  53. if (value)
  54. byte |= 0x80;
  55. if (UNLIKELY(begin == end))
  56. break;
  57. *(begin++) = byte;
  58. } while (value);
  59. return begin;
  60. }
  61. template <typename T, typename It>
  62. It DecodeULEB128(It begin, It end, T* v) {
  63. T value = 0;
  64. unsigned shift = 0;
  65. u8 byte;
  66. do {
  67. if (UNLIKELY(begin == end))
  68. return begin;
  69. byte = *(begin++);
  70. T slice = byte & 0x7f;
  71. value += slice << shift;
  72. shift += 7;
  73. } while (byte >= 128);
  74. *v = value;
  75. return begin;
  76. }
  77. } // namespace __sanitizer
  78. #endif // SANITIZER_LEB128_H