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