Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/Support/LEB128.h
Line
Count
Source
1
//===- llvm/Support/LEB128.h - [SU]LEB128 utility functions -----*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file declares some utility functions for encoding SLEB128 and
11
// ULEB128 values.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_SUPPORT_LEB128_H
16
#define LLVM_SUPPORT_LEB128_H
17
18
#include "llvm/Support/raw_ostream.h"
19
20
namespace llvm {
21
22
/// Utility function to encode a SLEB128 value to an output stream.
23
inline void encodeSLEB128(int64_t Value, raw_ostream &OS,
24
117k
                          unsigned PadTo = 0) {
25
117k
  bool More;
26
117k
  unsigned Count = 0;
27
190k
  do {
28
190k
    uint8_t Byte = Value & 0x7f;
29
190k
    // NOTE: this assumes that this signed shift is an arithmetic right shift.
30
190k
    Value >>= 7;
31
67.4k
    More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
32
134k
              
((Value == -1) && 134k
((Byte & 0x40) != 0)74.2k
)));
33
190k
    Count++;
34
190k
    if (
More || 190k
Count < PadTo117k
)
35
72.5k
      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
36
190k
    OS << char(Byte);
37
190k
  } while (More);
38
117k
39
117k
  // Pad with 0x80 and emit a terminating byte at the end.
40
117k
  if (
Count < PadTo117k
) {
41
10
    uint8_t PadValue = Value < 0 ? 
0x7f4
:
0x006
;
42
15
    for (; 
Count < PadTo - 115
;
++Count5
)
43
5
      OS << char(PadValue | 0x80);
44
10
    OS << char(PadValue);
45
10
  }
46
117k
}
47
48
/// Utility function to encode a SLEB128 value to a buffer. Returns
49
/// the length in bytes of the encoded value.
50
inline unsigned encodeSLEB128(int64_t Value, uint8_t *p, unsigned PadTo = 0) {
51
  uint8_t *orig_p = p;
52
  unsigned Count = 0;
53
  bool More;
54
  do {
55
    uint8_t Byte = Value & 0x7f;
56
    // NOTE: this assumes that this signed shift is an arithmetic right shift.
57
    Value >>= 7;
58
    More = !((((Value == 0 ) && ((Byte & 0x40) == 0)) ||
59
              ((Value == -1) && ((Byte & 0x40) != 0))));
60
    Count++;
61
    if (More || Count < PadTo)
62
      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
63
    *p++ = Byte;
64
  } while (More);
65
66
  // Pad with 0x80 and emit a terminating byte at the end.
67
  if (Count < PadTo) {
68
    uint8_t PadValue = Value < 0 ? 0x7f : 0x00;
69
    for (; Count < PadTo - 1; ++Count)
70
      *p++ = (PadValue | 0x80);
71
    *p++ = PadValue;
72
  }
73
  return (unsigned)(p - orig_p);
74
}
75
76
/// Utility function to encode a ULEB128 value to an output stream.
77
inline void encodeULEB128(uint64_t Value, raw_ostream &OS,
78
10.6M
                          unsigned PadTo = 0) {
79
10.6M
  unsigned Count = 0;
80
17.2M
  do {
81
17.2M
    uint8_t Byte = Value & 0x7f;
82
17.2M
    Value >>= 7;
83
17.2M
    Count++;
84
17.2M
    if (
Value != 0 || 17.2M
Count < PadTo10.6M
)
85
6.60M
      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
86
17.2M
    OS << char(Byte);
87
17.2M
  } while (Value != 0);
88
10.6M
89
10.6M
  // Pad with 0x80 and emit a null byte at the end.
90
10.6M
  if (
Count < PadTo10.6M
) {
91
3.13k
    for (; 
Count < PadTo - 13.13k
;
++Count1.15k
)
92
1.15k
      OS << '\x80';
93
1.98k
    OS << '\x00';
94
1.98k
    Count++;
95
1.98k
  }
96
10.6M
}
97
98
/// Utility function to encode a ULEB128 value to a buffer. Returns
99
/// the length in bytes of the encoded value.
100
inline unsigned encodeULEB128(uint64_t Value, uint8_t *p,
101
51.8k
                              unsigned PadTo = 0) {
102
51.8k
  uint8_t *orig_p = p;
103
51.8k
  unsigned Count = 0;
104
73.0k
  do {
105
73.0k
    uint8_t Byte = Value & 0x7f;
106
73.0k
    Value >>= 7;
107
73.0k
    Count++;
108
73.0k
    if (
Value != 0 || 73.0k
Count < PadTo51.8k
)
109
21.1k
      Byte |= 0x80; // Mark this byte to show that more bytes will follow.
110
73.0k
    *p++ = Byte;
111
73.0k
  } while (Value != 0);
112
51.8k
113
51.8k
  // Pad with 0x80 and emit a null byte at the end.
114
51.8k
  if (
Count < PadTo51.8k
) {
115
9
    for (; 
Count < PadTo - 19
;
++Count3
)
116
3
      *p++ = '\x80';
117
6
    *p++ = '\x00';
118
6
  }
119
51.8k
120
51.8k
  return (unsigned)(p - orig_p);
121
51.8k
}
122
123
/// Utility function to decode a ULEB128 value.
124
inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr,
125
                              const uint8_t *end = nullptr,
126
25.9M
                              const char **error = nullptr) {
127
25.9M
  const uint8_t *orig_p = p;
128
25.9M
  uint64_t Value = 0;
129
25.9M
  unsigned Shift = 0;
130
25.9M
  if (error)
131
496
    *error = nullptr;
132
33.5M
  do {
133
33.5M
    if (
end && 33.5M
p == end709
) {
134
3
      if (error)
135
3
        *error = "malformed uleb128, extends past end";
136
3
      if (n)
137
3
        *n = (unsigned)(p - orig_p);
138
3
      return 0;
139
3
    }
140
33.5M
    uint64_t Slice = *p & 0x7f;
141
33.5M
    if (
Shift >= 64 || 33.5M
Slice << Shift >> Shift != Slice33.5M
) {
142
2
      if (error)
143
2
        *error = "uleb128 too big for uint64";
144
2
      if (n)
145
2
        *n = (unsigned)(p - orig_p);
146
2
      return 0;
147
2
    }
148
33.5M
    Value += uint64_t(*p & 0x7f) << Shift;
149
33.5M
    Shift += 7;
150
33.5M
  } while (*p++ >= 128);
151
25.9M
  
if (25.9M
n25.9M
)
152
25.9M
    *n = (unsigned)(p - orig_p);
153
25.9M
  return Value;
154
25.9M
}
155
156
/// Utility function to decode a SLEB128 value.
157
inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr,
158
                             const uint8_t *end = nullptr,
159
                             const char **error = nullptr) {
160
  const uint8_t *orig_p = p;
161
  int64_t Value = 0;
162
  unsigned Shift = 0;
163
  uint8_t Byte;
164
  do {
165
    if (end && p == end) {
166
      if (error)
167
        *error = "malformed sleb128, extends past end";
168
      if (n)
169
        *n = (unsigned)(p - orig_p);
170
      return 0;
171
    }
172
    Byte = *p++;
173
    Value |= (int64_t(Byte & 0x7f) << Shift);
174
    Shift += 7;
175
  } while (Byte >= 128);
176
  // Sign extend negative numbers.
177
  if (Byte & 0x40)
178
    Value |= (-1ULL) << Shift;
179
  if (n)
180
    *n = (unsigned)(p - orig_p);
181
  return Value;
182
}
183
184
/// Utility function to get the size of the ULEB128-encoded value.
185
extern unsigned getULEB128Size(uint64_t Value);
186
187
/// Utility function to get the size of the SLEB128-encoded value.
188
extern unsigned getSLEB128Size(int64_t Value);
189
190
} // namespace llvm
191
192
#endif // LLVM_SYSTEM_LEB128_H