Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Support/LEB128.h
Line
Count
Source
1
//===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- 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
// This file declares some utility functions for encoding SLEB128 and
10
// ULEB128 values.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_SUPPORT_LEB128_H
15
#define LLVM_SUPPORT_LEB128_H
16
17
#include "llvm/Support/raw_ostream.h"
18
19
namespace llvm {
20
21
/// Utility function to encode a SLEB128 value to an output stream. Returns
22
/// the length in bytes of the encoded value.
23
inline unsigned encodeSLEB128(int64_t Value, raw_ostream &OS,
24
1.52M
                              unsigned PadTo = 0) {
25
1.52M
  bool More;
26
1.52M
  unsigned Count = 0;
27
2.66M
  do {
28
2.66M
    uint8_t Byte = Value & 0x7f;
29
2.66M
    // NOTE: this assumes that this signed shift is an arithmetic right shift.
30
2.66M
    Value >>= 7;
31
2.66M
    More = !((((Value == 0 ) && 
((Byte & 0x40) == 0)881k
) ||
32
2.66M
              
(1.89M
(Value == -1)1.89M
&&
((Byte & 0x40) != 0)849k
)));
33
2.66M
    Count++;
34
2.66M
    if (More || 
Count < PadTo1.52M
)
35
1.14M
      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
36
2.66M
    OS << char(Byte);
37
2.66M
  } while (More);
38
1.52M
39
1.52M
  // Pad with 0x80 and emit a terminating byte at the end.
40
1.52M
  if (Count < PadTo) {
41
10
    uint8_t PadValue = Value < 0 ? 
0x7f4
:
0x006
;
42
15
    for (; Count < PadTo - 1; 
++Count5
)
43
5
      OS << char(PadValue | 0x80);
44
10
    OS << char(PadValue);
45
10
    Count++;
46
10
  }
47
1.52M
  return Count;
48
1.52M
}
49
50
/// Utility function to encode a SLEB128 value to a buffer. Returns
51
/// the length in bytes of the encoded value.
52
228
inline unsigned encodeSLEB128(int64_t Value, uint8_t *p, unsigned PadTo = 0) {
53
228
  uint8_t *orig_p = p;
54
228
  unsigned Count = 0;
55
228
  bool More;
56
443
  do {
57
443
    uint8_t Byte = Value & 0x7f;
58
443
    // NOTE: this assumes that this signed shift is an arithmetic right shift.
59
443
    Value >>= 7;
60
443
    More = !((((Value == 0 ) && 
((Byte & 0x40) == 0)211
) ||
61
443
              
(241
(Value == -1)241
&&
((Byte & 0x40) != 0)35
)));
62
443
    Count++;
63
443
    if (More || 
Count < PadTo228
)
64
375
      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
65
443
    *p++ = Byte;
66
443
  } while (More);
67
228
68
228
  // Pad with 0x80 and emit a terminating byte at the end.
69
228
  if (Count < PadTo) {
70
160
    uint8_t PadValue = Value < 0 ? 
0x7f4
:
0x00156
;
71
594
    for (; Count < PadTo - 1; 
++Count434
)
72
434
      *p++ = (PadValue | 0x80);
73
160
    *p++ = PadValue;
74
160
  }
75
228
  return (unsigned)(p - orig_p);
76
228
}
77
78
/// Utility function to encode a ULEB128 value to an output stream. Returns
79
/// the length in bytes of the encoded value.
80
inline unsigned encodeULEB128(uint64_t Value, raw_ostream &OS,
81
7.47M
                              unsigned PadTo = 0) {
82
7.47M
  unsigned Count = 0;
83
11.0M
  do {
84
11.0M
    uint8_t Byte = Value & 0x7f;
85
11.0M
    Value >>= 7;
86
11.0M
    Count++;
87
11.0M
    if (Value != 0 || 
Count < PadTo7.47M
)
88
3.57M
      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
89
11.0M
    OS << char(Byte);
90
11.0M
  } while (Value != 0);
91
7.47M
92
7.47M
  // Pad with 0x80 and emit a null byte at the end.
93
7.47M
  if (Count < PadTo) {
94
7.96k
    for (; Count < PadTo - 1; 
++Count5.96k
)
95
5.96k
      OS << '\x80';
96
2.00k
    OS << '\x00';
97
2.00k
    Count++;
98
2.00k
  }
99
7.47M
  return Count;
100
7.47M
}
101
102
/// Utility function to encode a ULEB128 value to a buffer. Returns
103
/// the length in bytes of the encoded value.
104
inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
105
78.0k
                              unsigned PadTo = 0) {
106
78.0k
  uint8_t *orig_p = p;
107
78.0k
  unsigned Count = 0;
108
108k
  do {
109
108k
    uint8_t Byte = Value & 0x7f;
110
108k
    Value >>= 7;
111
108k
    Count++;
112
108k
    if (Value != 0 || 
Count < PadTo78.0k
)
113
33.2k
      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
114
108k
    *p++ = Byte;
115
108k
  } while (Value != 0);
116
78.0k
117
78.0k
  // Pad with 0x80 and emit a null byte at the end.
118
78.0k
  if (Count < PadTo) {
119
8.94k
    for (; Count < PadTo - 1; 
++Count6.68k
)
120
6.68k
      *p++ = '\x80';
121
2.25k
    *p++ = '\x00';
122
2.25k
  }
123
78.0k
124
78.0k
  return (unsigned)(p - orig_p);
125
78.0k
}
126
127
/// Utility function to decode a ULEB128 value.
128
inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr,
129
                              const uint8_t *end = nullptr,
130
79.6M
                              const char **error = nullptr) {
131
79.6M
  const uint8_t *orig_p = p;
132
79.6M
  uint64_t Value = 0;
133
79.6M
  unsigned Shift = 0;
134
79.6M
  if (error)
135
222k
    *error = nullptr;
136
102M
  do {
137
102M
    if (end && 
p == end245k
) {
138
63
      if (error)
139
63
        *error = "malformed uleb128, extends past end";
140
63
      if (n)
141
63
        *n = (unsigned)(p - orig_p);
142
63
      return 0;
143
63
    }
144
102M
    uint64_t Slice = *p & 0x7f;
145
102M
    if (Shift >= 64 || Slice << Shift >> Shift != Slice) {
146
2
      if (error)
147
2
        *error = "uleb128 too big for uint64";
148
2
      if (n)
149
2
        *n = (unsigned)(p - orig_p);
150
2
      return 0;
151
2
    }
152
102M
    Value += uint64_t(*p & 0x7f) << Shift;
153
102M
    Shift += 7;
154
102M
  } while (*p++ >= 128);
155
79.6M
  
if (79.6M
n79.6M
)
156
79.5M
    *n = (unsigned)(p - orig_p);
157
79.6M
  return Value;
158
79.6M
}
159
160
/// Utility function to decode a SLEB128 value.
161
inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr,
162
                             const uint8_t *end = nullptr,
163
5.91k
                             const char **error = nullptr) {
164
5.91k
  const uint8_t *orig_p = p;
165
5.91k
  int64_t Value = 0;
166
5.91k
  unsigned Shift = 0;
167
5.91k
  uint8_t Byte;
168
5.91k
  if (error)
169
5.81k
    *error = nullptr;
170
7.98k
  do {
171
7.98k
    if (end && 
p == end7.94k
) {
172
19
      if (error)
173
19
        *error = "malformed sleb128, extends past end";
174
19
      if (n)
175
19
        *n = (unsigned)(p - orig_p);
176
19
      return 0;
177
19
    }
178
7.96k
    Byte = *p++;
179
7.96k
    Value |= (uint64_t(Byte & 0x7f) << Shift);
180
7.96k
    Shift += 7;
181
7.96k
  } while (Byte >= 128);
182
5.91k
  // Sign extend negative numbers if needed.
183
5.91k
  
if (5.89k
Shift < 645.89k
&&
(Byte & 0x40)5.83k
)
184
1.56k
    Value |= (-1ULL) << Shift;
185
5.89k
  if (n)
186
5.81k
    *n = (unsigned)(p - orig_p);
187
5.89k
  return Value;
188
5.91k
}
189
190
/// Utility function to get the size of the ULEB128-encoded value.
191
extern unsigned getULEB128Size(uint64_t Value);
192
193
/// Utility function to get the size of the SLEB128-encoded value.
194
extern unsigned getSLEB128Size(int64_t Value);
195
196
} // namespace llvm
197
198
#endif // LLVM_SYSTEM_LEB128_H