Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Support/DataExtractor.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- DataExtractor.cpp -------------------------------------------------===//
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/DataExtractor.h"
10
#include "llvm/Support/ErrorHandling.h"
11
#include "llvm/Support/Host.h"
12
#include "llvm/Support/SwapByteOrder.h"
13
#include "llvm/Support/LEB128.h"
14
using namespace llvm;
15
16
template <typename T>
17
static T getU(uint32_t *offset_ptr, const DataExtractor *de,
18
213k
              bool isLittleEndian, const char *Data) {
19
213k
  T val = 0;
20
213k
  uint32_t offset = *offset_ptr;
21
213k
  if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
22
213k
    std::memcpy(&val, &Data[offset], sizeof(val));
23
213k
    if (sys::IsLittleEndianHost != isLittleEndian)
24
2.53k
      sys::swapByteOrder(val);
25
213k
26
213k
    // Advance the offset
27
213k
    *offset_ptr += sizeof(val);
28
213k
  }
29
213k
  return val;
30
213k
}
DataExtractor.cpp:unsigned char getU<unsigned char>(unsigned int*, llvm::DataExtractor const*, bool, char const*)
Line
Count
Source
18
91.6k
              bool isLittleEndian, const char *Data) {
19
91.6k
  T val = 0;
20
91.6k
  uint32_t offset = *offset_ptr;
21
91.6k
  if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
22
91.5k
    std::memcpy(&val, &Data[offset], sizeof(val));
23
91.5k
    if (sys::IsLittleEndianHost != isLittleEndian)
24
1.60k
      sys::swapByteOrder(val);
25
91.5k
26
91.5k
    // Advance the offset
27
91.5k
    *offset_ptr += sizeof(val);
28
91.5k
  }
29
91.6k
  return val;
30
91.6k
}
DataExtractor.cpp:unsigned short getU<unsigned short>(unsigned int*, llvm::DataExtractor const*, bool, char const*)
Line
Count
Source
18
11.0k
              bool isLittleEndian, const char *Data) {
19
11.0k
  T val = 0;
20
11.0k
  uint32_t offset = *offset_ptr;
21
11.0k
  if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
22
10.8k
    std::memcpy(&val, &Data[offset], sizeof(val));
23
10.8k
    if (sys::IsLittleEndianHost != isLittleEndian)
24
109
      sys::swapByteOrder(val);
25
10.8k
26
10.8k
    // Advance the offset
27
10.8k
    *offset_ptr += sizeof(val);
28
10.8k
  }
29
11.0k
  return val;
30
11.0k
}
DataExtractor.cpp:llvm::Uint24 getU<llvm::Uint24>(unsigned int*, llvm::DataExtractor const*, bool, char const*)
Line
Count
Source
18
5
              bool isLittleEndian, const char *Data) {
19
5
  T val = 0;
20
5
  uint32_t offset = *offset_ptr;
21
5
  if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
22
5
    std::memcpy(&val, &Data[offset], sizeof(val));
23
5
    if (sys::IsLittleEndianHost != isLittleEndian)
24
0
      sys::swapByteOrder(val);
25
5
26
5
    // Advance the offset
27
5
    *offset_ptr += sizeof(val);
28
5
  }
29
5
  return val;
30
5
}
DataExtractor.cpp:unsigned int getU<unsigned int>(unsigned int*, llvm::DataExtractor const*, bool, char const*)
Line
Count
Source
18
96.6k
              bool isLittleEndian, const char *Data) {
19
96.6k
  T val = 0;
20
96.6k
  uint32_t offset = *offset_ptr;
21
96.6k
  if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
22
96.2k
    std::memcpy(&val, &Data[offset], sizeof(val));
23
96.2k
    if (sys::IsLittleEndianHost != isLittleEndian)
24
752
      sys::swapByteOrder(val);
25
96.2k
26
96.2k
    // Advance the offset
27
96.2k
    *offset_ptr += sizeof(val);
28
96.2k
  }
29
96.6k
  return val;
30
96.6k
}
DataExtractor.cpp:unsigned long long getU<unsigned long long>(unsigned int*, llvm::DataExtractor const*, bool, char const*)
Line
Count
Source
18
14.5k
              bool isLittleEndian, const char *Data) {
19
14.5k
  T val = 0;
20
14.5k
  uint32_t offset = *offset_ptr;
21
14.5k
  if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
22
14.4k
    std::memcpy(&val, &Data[offset], sizeof(val));
23
14.4k
    if (sys::IsLittleEndianHost != isLittleEndian)
24
70
      sys::swapByteOrder(val);
25
14.4k
26
14.4k
    // Advance the offset
27
14.4k
    *offset_ptr += sizeof(val);
28
14.4k
  }
29
14.5k
  return val;
30
14.5k
}
31
32
template <typename T>
33
static T *getUs(uint32_t *offset_ptr, T *dst, uint32_t count,
34
75
                const DataExtractor *de, bool isLittleEndian, const char *Data){
35
75
  uint32_t offset = *offset_ptr;
36
75
37
75
  if (count > 0 && 
de->isValidOffsetForDataOfSize(offset, sizeof(*dst)*count)49
) {
38
417
    for (T *value_ptr = dst, *end = dst + count; value_ptr != end;
39
368
        ++value_ptr, offset += sizeof(*dst))
40
368
      *value_ptr = getU<T>(offset_ptr, de, isLittleEndian, Data);
41
49
    // Advance the offset
42
49
    *offset_ptr = offset;
43
49
    // Return a non-NULL pointer to the converted data as an indicator of
44
49
    // success
45
49
    return dst;
46
49
  }
47
26
  return nullptr;
48
26
}
DataExtractor.cpp:unsigned char* getUs<unsigned char>(unsigned int*, unsigned char*, unsigned int, llvm::DataExtractor const*, bool, char const*)
Line
Count
Source
34
73
                const DataExtractor *de, bool isLittleEndian, const char *Data){
35
73
  uint32_t offset = *offset_ptr;
36
73
37
73
  if (count > 0 && 
de->isValidOffsetForDataOfSize(offset, sizeof(*dst)*count)47
) {
38
411
    for (T *value_ptr = dst, *end = dst + count; value_ptr != end;
39
364
        ++value_ptr, offset += sizeof(*dst))
40
364
      *value_ptr = getU<T>(offset_ptr, de, isLittleEndian, Data);
41
47
    // Advance the offset
42
47
    *offset_ptr = offset;
43
47
    // Return a non-NULL pointer to the converted data as an indicator of
44
47
    // success
45
47
    return dst;
46
47
  }
47
26
  return nullptr;
48
26
}
Unexecuted instantiation: DataExtractor.cpp:unsigned short* getUs<unsigned short>(unsigned int*, unsigned short*, unsigned int, llvm::DataExtractor const*, bool, char const*)
DataExtractor.cpp:unsigned int* getUs<unsigned int>(unsigned int*, unsigned int*, unsigned int, llvm::DataExtractor const*, bool, char const*)
Line
Count
Source
34
2
                const DataExtractor *de, bool isLittleEndian, const char *Data){
35
2
  uint32_t offset = *offset_ptr;
36
2
37
2
  if (count > 0 && de->isValidOffsetForDataOfSize(offset, sizeof(*dst)*count)) {
38
6
    for (T *value_ptr = dst, *end = dst + count; value_ptr != end;
39
4
        ++value_ptr, offset += sizeof(*dst))
40
4
      *value_ptr = getU<T>(offset_ptr, de, isLittleEndian, Data);
41
2
    // Advance the offset
42
2
    *offset_ptr = offset;
43
2
    // Return a non-NULL pointer to the converted data as an indicator of
44
2
    // success
45
2
    return dst;
46
2
  }
47
0
  return nullptr;
48
0
}
Unexecuted instantiation: DataExtractor.cpp:unsigned long long* getUs<unsigned long long>(unsigned int*, unsigned long long*, unsigned int, llvm::DataExtractor const*, bool, char const*)
49
50
91.2k
uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const {
51
91.2k
  return getU<uint8_t>(offset_ptr, this, IsLittleEndian, Data.data());
52
91.2k
}
53
54
uint8_t *
55
73
DataExtractor::getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const {
56
73
  return getUs<uint8_t>(offset_ptr, dst, count, this, IsLittleEndian,
57
73
                       Data.data());
58
73
}
59
60
61
11.0k
uint16_t DataExtractor::getU16(uint32_t *offset_ptr) const {
62
11.0k
  return getU<uint16_t>(offset_ptr, this, IsLittleEndian, Data.data());
63
11.0k
}
64
65
uint16_t *DataExtractor::getU16(uint32_t *offset_ptr, uint16_t *dst,
66
0
                                uint32_t count) const {
67
0
  return getUs<uint16_t>(offset_ptr, dst, count, this, IsLittleEndian,
68
0
                        Data.data());
69
0
}
70
71
5
uint32_t DataExtractor::getU24(uint32_t *offset_ptr) const {
72
5
  uint24_t ExtractedVal =
73
5
      getU<uint24_t>(offset_ptr, this, IsLittleEndian, Data.data());
74
5
  // The 3 bytes are in the correct byte order for the host.
75
5
  return ExtractedVal.getAsUint32(sys::IsLittleEndianHost);
76
5
}
77
78
96.6k
uint32_t DataExtractor::getU32(uint32_t *offset_ptr) const {
79
96.6k
  return getU<uint32_t>(offset_ptr, this, IsLittleEndian, Data.data());
80
96.6k
}
81
82
uint32_t *DataExtractor::getU32(uint32_t *offset_ptr, uint32_t *dst,
83
2
                                uint32_t count) const {
84
2
  return getUs<uint32_t>(offset_ptr, dst, count, this, IsLittleEndian,
85
2
                        Data.data());
86
2
}
87
88
14.5k
uint64_t DataExtractor::getU64(uint32_t *offset_ptr) const {
89
14.5k
  return getU<uint64_t>(offset_ptr, this, IsLittleEndian, Data.data());
90
14.5k
}
91
92
uint64_t *DataExtractor::getU64(uint32_t *offset_ptr, uint64_t *dst,
93
0
                                uint32_t count) const {
94
0
  return getUs<uint64_t>(offset_ptr, dst, count, this, IsLittleEndian,
95
0
                        Data.data());
96
0
}
97
98
uint64_t
99
69.9k
DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const {
100
69.9k
  switch (byte_size) {
101
69.9k
  case 1:
102
3.08k
    return getU8(offset_ptr);
103
69.9k
  case 2:
104
7
    return getU16(offset_ptr);
105
69.9k
  case 4:
106
53.9k
    return getU32(offset_ptr);
107
69.9k
  case 8:
108
12.9k
    return getU64(offset_ptr);
109
0
  }
110
0
  llvm_unreachable("getUnsigned unhandled case!");
111
0
}
112
113
int64_t
114
352
DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const {
115
352
  switch (byte_size) {
116
352
  case 1:
117
1
    return (int8_t)getU8(offset_ptr);
118
352
  case 2:
119
3
    return (int16_t)getU16(offset_ptr);
120
352
  case 4:
121
343
    return (int32_t)getU32(offset_ptr);
122
352
  case 8:
123
5
    return (int64_t)getU64(offset_ptr);
124
0
  }
125
0
  llvm_unreachable("getSigned unhandled case!");
126
0
}
127
128
27.4k
const char *DataExtractor::getCStr(uint32_t *offset_ptr) const {
129
27.4k
  uint32_t offset = *offset_ptr;
130
27.4k
  StringRef::size_type pos = Data.find('\0', offset);
131
27.4k
  if (pos != StringRef::npos) {
132
27.0k
    *offset_ptr = pos + 1;
133
27.0k
    return Data.data() + offset;
134
27.0k
  }
135
316
  return nullptr;
136
316
}
137
138
5.29k
StringRef DataExtractor::getCStrRef(uint32_t *OffsetPtr) const {
139
5.29k
  uint32_t Start = *OffsetPtr;
140
5.29k
  StringRef::size_type Pos = Data.find('\0', Start);
141
5.29k
  if (
Pos != StringRef::npos5.29k
) {
142
5.29k
    *OffsetPtr = Pos + 1;
143
5.29k
    return StringRef(Data.data() + Start, Pos - Start);
144
5.29k
  }
145
18.4E
  return StringRef();
146
18.4E
}
147
148
177k
uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const {
149
177k
  assert(*offset_ptr <= Data.size());
150
177k
151
177k
  const char *error;
152
177k
  unsigned bytes_read;
153
177k
  uint64_t result = decodeULEB128(
154
177k
      reinterpret_cast<const uint8_t *>(Data.data() + *offset_ptr), &bytes_read,
155
177k
      reinterpret_cast<const uint8_t *>(Data.data() + Data.size()), &error);
156
177k
  if (error)
157
59
    return 0;
158
177k
  *offset_ptr += bytes_read;
159
177k
  return result;
160
177k
}
161
162
3.64k
int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const {
163
3.64k
  assert(*offset_ptr <= Data.size());
164
3.64k
165
3.64k
  const char *error;
166
3.64k
  unsigned bytes_read;
167
3.64k
  int64_t result = decodeSLEB128(
168
3.64k
      reinterpret_cast<const uint8_t *>(Data.data() + *offset_ptr), &bytes_read,
169
3.64k
      reinterpret_cast<const uint8_t *>(Data.data() + Data.size()), &error);
170
3.64k
  if (error)
171
15
    return 0;
172
3.62k
  *offset_ptr += bytes_read;
173
3.62k
  return result;
174
3.62k
}