Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Support/BinaryStreamReader.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- BinaryStreamReader.cpp - Reads objects from a binary stream --------===//
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
#include "llvm/Support/BinaryStreamReader.h"
10
11
#include "llvm/Support/BinaryStreamError.h"
12
#include "llvm/Support/BinaryStreamRef.h"
13
#include "llvm/Support/LEB128.h"
14
15
using namespace llvm;
16
using endianness = llvm::support::endianness;
17
18
33.3k
BinaryStreamReader::BinaryStreamReader(BinaryStreamRef Ref) : Stream(Ref) {}
19
20
33.5k
BinaryStreamReader::BinaryStreamReader(BinaryStream &Stream) : Stream(Stream) {}
21
22
BinaryStreamReader::BinaryStreamReader(ArrayRef<uint8_t> Data,
23
                                       endianness Endian)
24
1.38k
    : Stream(Data, Endian) {}
25
26
BinaryStreamReader::BinaryStreamReader(StringRef Data, endianness Endian)
27
836
    : Stream(Data, Endian) {}
28
29
Error BinaryStreamReader::readLongestContiguousChunk(
30
63.0k
    ArrayRef<uint8_t> &Buffer) {
31
63.0k
  if (auto EC = Stream.readLongestContiguousChunk(Offset, Buffer))
32
341
    return EC;
33
62.7k
  Offset += Buffer.size();
34
62.7k
  return Error::success();
35
62.7k
}
36
37
372k
Error BinaryStreamReader::readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size) {
38
372k
  if (auto EC = Stream.readBytes(Offset, Size, Buffer))
39
119
    return EC;
40
372k
  Offset += Size;
41
372k
  return Error::success();
42
372k
}
43
44
47
Error BinaryStreamReader::readULEB128(uint64_t &Dest) {
45
47
  SmallVector<uint8_t, 10> EncodedBytes;
46
47
  ArrayRef<uint8_t> NextByte;
47
47
48
47
  // Copy the encoded ULEB into the buffer.
49
197
  do {
50
197
    if (auto Err = readBytes(NextByte, 1))
51
0
      return Err;
52
197
    EncodedBytes.push_back(NextByte[0]);
53
197
  } while (NextByte[0] & 0x80);
54
47
55
47
  Dest = decodeULEB128(EncodedBytes.begin(), nullptr, EncodedBytes.end());
56
47
  return Error::success();
57
47
}
58
59
62
Error BinaryStreamReader::readSLEB128(int64_t &Dest) {
60
62
  SmallVector<uint8_t, 10> EncodedBytes;
61
62
  ArrayRef<uint8_t> NextByte;
62
62
63
62
  // Copy the encoded ULEB into the buffer.
64
248
  do {
65
248
    if (auto Err = readBytes(NextByte, 1))
66
0
      return Err;
67
248
    EncodedBytes.push_back(NextByte[0]);
68
248
  } while (NextByte[0] & 0x80);
69
62
70
62
  Dest = decodeSLEB128(EncodedBytes.begin(), nullptr, EncodedBytes.end());
71
62
  return Error::success();
72
62
}
73
74
59.0k
Error BinaryStreamReader::readCString(StringRef &Dest) {
75
59.0k
  uint32_t OriginalOffset = getOffset();
76
59.0k
  uint32_t FoundOffset = 0;
77
59.0k
  while (true) {
78
59.0k
    uint32_t ThisOffset = getOffset();
79
59.0k
    ArrayRef<uint8_t> Buffer;
80
59.0k
    if (auto EC = readLongestContiguousChunk(Buffer))
81
0
      return EC;
82
59.0k
    StringRef S(reinterpret_cast<const char *>(Buffer.begin()), Buffer.size());
83
59.0k
    size_t Pos = S.find_first_of('\0');
84
59.0k
    if (LLVM_LIKELY(Pos != StringRef::npos)) {
85
59.0k
      FoundOffset = Pos + ThisOffset;
86
59.0k
      break;
87
59.0k
    }
88
59.0k
  }
89
59.0k
  assert(FoundOffset >= OriginalOffset);
90
59.0k
91
59.0k
  setOffset(OriginalOffset);
92
59.0k
  size_t Length = FoundOffset - OriginalOffset;
93
59.0k
94
59.0k
  if (auto EC = readFixedString(Dest, Length))
95
0
    return EC;
96
59.0k
97
59.0k
  // Now set the offset back to after the null terminator.
98
59.0k
  setOffset(FoundOffset + 1);
99
59.0k
  return Error::success();
100
59.0k
}
101
102
154
Error BinaryStreamReader::readWideString(ArrayRef<UTF16> &Dest) {
103
154
  uint32_t Length = 0;
104
154
  uint32_t OriginalOffset = getOffset();
105
154
  const UTF16 *C;
106
1.45k
  while (true) {
107
1.45k
    if (auto EC = readObject(C))
108
0
      return EC;
109
1.45k
    if (*C == 0x0000)
110
154
      break;
111
1.29k
    ++Length;
112
1.29k
  }
113
154
  uint32_t NewOffset = getOffset();
114
154
  setOffset(OriginalOffset);
115
154
116
154
  if (auto EC = readArray(Dest, Length))
117
0
    return EC;
118
154
  setOffset(NewOffset);
119
154
  return Error::success();
120
154
}
121
122
60.2k
Error BinaryStreamReader::readFixedString(StringRef &Dest, uint32_t Length) {
123
60.2k
  ArrayRef<uint8_t> Bytes;
124
60.2k
  if (auto EC = readBytes(Bytes, Length))
125
15
    return EC;
126
60.2k
  Dest = StringRef(reinterpret_cast<const char *>(Bytes.begin()), Bytes.size());
127
60.2k
  return Error::success();
128
60.2k
}
129
130
361
Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref) {
131
361
  return readStreamRef(Ref, bytesRemaining());
132
361
}
133
134
10.6k
Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref, uint32_t Length) {
135
10.6k
  if (bytesRemaining() < Length)
136
0
    return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
137
10.6k
  Ref = Stream.slice(Offset, Length);
138
10.6k
  Offset += Length;
139
10.6k
  return Error::success();
140
10.6k
}
141
142
Error BinaryStreamReader::readSubstream(BinarySubstreamRef &Stream,
143
2.58k
                                        uint32_t Size) {
144
2.58k
  Stream.Offset = getOffset();
145
2.58k
  return readStreamRef(Stream.StreamData, Size);
146
2.58k
}
147
148
14.7k
Error BinaryStreamReader::skip(uint32_t Amount) {
149
14.7k
  if (Amount > bytesRemaining())
150
0
    return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
151
14.7k
  Offset += Amount;
152
14.7k
  return Error::success();
153
14.7k
}
154
155
4.79k
Error BinaryStreamReader::padToAlignment(uint32_t Align) {
156
4.79k
  uint32_t NewOffset = alignTo(Offset, Align);
157
4.79k
  return skip(NewOffset - Offset);
158
4.79k
}
159
160
34.5k
uint8_t BinaryStreamReader::peek() const {
161
34.5k
  ArrayRef<uint8_t> Buffer;
162
34.5k
  auto EC = Stream.readBytes(Offset, 1, Buffer);
163
34.5k
  assert(!EC && "Cannot peek an empty buffer!");
164
34.5k
  llvm::consumeError(std::move(EC));
165
34.5k
  return Buffer[0];
166
34.5k
}
167
168
std::pair<BinaryStreamReader, BinaryStreamReader>
169
624
BinaryStreamReader::split(uint32_t Off) const {
170
624
  assert(getLength() >= Off);
171
624
172
624
  BinaryStreamRef First = Stream.drop_front(Offset);
173
624
174
624
  BinaryStreamRef Second = First.drop_front(Off);
175
624
  First = First.keep_front(Off);
176
624
  BinaryStreamReader W1{First};
177
624
  BinaryStreamReader W2{Second};
178
624
  return std::make_pair(W1, W2);
179
624
}