Coverage Report

Created: 2022-01-25 06:29

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Utility/RegisterValue.h
Line
Count
Source (jump to first uncovered line)
1
//===-- RegisterValue.h -----------------------------------------*- 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
#ifndef LLDB_UTILITY_REGISTERVALUE_H
10
#define LLDB_UTILITY_REGISTERVALUE_H
11
12
#include "lldb/Utility/Endian.h"
13
#include "lldb/Utility/Scalar.h"
14
#include "lldb/Utility/Status.h"
15
#include "lldb/lldb-enumerations.h"
16
#include "lldb/lldb-types.h"
17
#include "llvm/ADT/APInt.h"
18
#include "llvm/ADT/StringRef.h"
19
#include <cstdint>
20
#include <cstring>
21
#include <utility>
22
23
namespace lldb_private {
24
class DataExtractor;
25
class Stream;
26
struct RegisterInfo;
27
28
class RegisterValue {
29
public:
30
  // big enough to support up to 256 byte AArch64 SVE
31
  enum { kMaxRegisterByteSize = 256u };
32
33
  enum Type {
34
    eTypeInvalid,
35
    eTypeUInt8,
36
    eTypeUInt16,
37
    eTypeUInt32,
38
    eTypeUInt64,
39
    eTypeUInt128,
40
    eTypeFloat,
41
    eTypeDouble,
42
    eTypeLongDouble,
43
    eTypeBytes
44
  };
45
46
587k
  RegisterValue() : m_scalar(static_cast<unsigned long>(0)) {}
47
48
  explicit RegisterValue(uint8_t inst) : m_type(eTypeUInt8) { m_scalar = inst; }
49
50
  explicit RegisterValue(uint16_t inst) : m_type(eTypeUInt16) {
51
    m_scalar = inst;
52
  }
53
54
  explicit RegisterValue(uint32_t inst) : m_type(eTypeUInt32) {
55
    m_scalar = inst;
56
  }
57
58
  explicit RegisterValue(uint64_t inst) : m_type(eTypeUInt64) {
59
    m_scalar = inst;
60
  }
61
62
  explicit RegisterValue(llvm::APInt inst) : m_type(eTypeUInt128) {
63
    m_scalar = llvm::APInt(std::move(inst));
64
  }
65
66
  explicit RegisterValue(float value) : m_type(eTypeFloat) { m_scalar = value; }
67
68
  explicit RegisterValue(double value) : m_type(eTypeDouble) {
69
    m_scalar = value;
70
  }
71
72
  explicit RegisterValue(long double value) : m_type(eTypeLongDouble) {
73
    m_scalar = value;
74
  }
75
76
  explicit RegisterValue(llvm::ArrayRef<uint8_t> bytes,
77
4
                         lldb::ByteOrder byte_order) {
78
4
    SetBytes(bytes.data(), bytes.size(), byte_order);
79
4
  }
80
81
4.51k
  RegisterValue::Type GetType() const { return m_type; }
82
83
  bool CopyValue(const RegisterValue &rhs);
84
85
0
  void SetType(RegisterValue::Type type) { m_type = type; }
86
87
  RegisterValue::Type SetType(const RegisterInfo *reg_info);
88
89
  bool GetData(DataExtractor &data) const;
90
91
  // Copy the register value from this object into a buffer in "dst" and obey
92
  // the "dst_byte_order" when copying the data. Also watch out in case
93
  // "dst_len" is longer or shorter than the register value described by
94
  // "reg_info" and only copy the least significant bytes of the register
95
  // value, or pad the destination with zeroes if the register byte size is
96
  // shorter that "dst_len" (all while correctly abiding the "dst_byte_order").
97
  // Returns the number of bytes copied into "dst".
98
  uint32_t GetAsMemoryData(const RegisterInfo *reg_info, void *dst,
99
                           uint32_t dst_len, lldb::ByteOrder dst_byte_order,
100
                           Status &error) const;
101
102
  uint32_t SetFromMemoryData(const RegisterInfo *reg_info, const void *src,
103
                             uint32_t src_len, lldb::ByteOrder src_byte_order,
104
                             Status &error);
105
106
  bool GetScalarValue(Scalar &scalar) const;
107
108
  uint8_t GetAsUInt8(uint8_t fail_value = UINT8_MAX,
109
2
                     bool *success_ptr = nullptr) const {
110
2
    if (m_type == eTypeUInt8) {
111
2
      if (success_ptr)
112
0
        *success_ptr = true;
113
2
      return m_scalar.UChar(fail_value);
114
2
    }
115
0
    if (success_ptr)
116
0
      *success_ptr = true;
117
0
    return fail_value;
118
2
  }
119
120
  uint16_t GetAsUInt16(uint16_t fail_value = UINT16_MAX,
121
                       bool *success_ptr = nullptr) const;
122
123
  uint32_t GetAsUInt32(uint32_t fail_value = UINT32_MAX,
124
                       bool *success_ptr = nullptr) const;
125
126
  uint64_t GetAsUInt64(uint64_t fail_value = UINT64_MAX,
127
                       bool *success_ptr = nullptr) const;
128
129
  llvm::APInt GetAsUInt128(const llvm::APInt &fail_value,
130
                           bool *success_ptr = nullptr) const;
131
132
  float GetAsFloat(float fail_value = 0.0f, bool *success_ptr = nullptr) const;
133
134
  double GetAsDouble(double fail_value = 0.0,
135
                     bool *success_ptr = nullptr) const;
136
137
  long double GetAsLongDouble(long double fail_value = 0.0,
138
                              bool *success_ptr = nullptr) const;
139
140
0
  void SetValueToInvalid() { m_type = eTypeInvalid; }
141
142
  bool ClearBit(uint32_t bit);
143
144
  bool SetBit(uint32_t bit);
145
146
  bool operator==(const RegisterValue &rhs) const;
147
148
  bool operator!=(const RegisterValue &rhs) const;
149
150
1
  void operator=(uint8_t uint) {
151
1
    m_type = eTypeUInt8;
152
1
    m_scalar = uint;
153
1
  }
154
155
0
  void operator=(uint16_t uint) {
156
0
    m_type = eTypeUInt16;
157
0
    m_scalar = uint;
158
0
  }
159
160
0
  void operator=(uint32_t uint) {
161
0
    m_type = eTypeUInt32;
162
0
    m_scalar = uint;
163
0
  }
164
165
5.08k
  void operator=(uint64_t uint) {
166
5.08k
    m_type = eTypeUInt64;
167
5.08k
    m_scalar = uint;
168
5.08k
  }
169
170
0
  void operator=(llvm::APInt uint) {
171
0
    m_type = eTypeUInt128;
172
0
    m_scalar = llvm::APInt(std::move(uint));
173
0
  }
174
175
0
  void operator=(float f) {
176
0
    m_type = eTypeFloat;
177
0
    m_scalar = f;
178
0
  }
179
180
0
  void operator=(double f) {
181
0
    m_type = eTypeDouble;
182
0
    m_scalar = f;
183
0
  }
184
185
0
  void operator=(long double f) {
186
0
    m_type = eTypeLongDouble;
187
0
    m_scalar = f;
188
0
  }
189
190
909
  void SetUInt8(uint8_t uint) {
191
909
    m_type = eTypeUInt8;
192
909
    m_scalar = uint;
193
909
  }
194
195
1.03k
  void SetUInt16(uint16_t uint) {
196
1.03k
    m_type = eTypeUInt16;
197
1.03k
    m_scalar = uint;
198
1.03k
  }
199
200
2.86k
  void SetUInt32(uint32_t uint, Type t = eTypeUInt32) {
201
2.86k
    m_type = t;
202
2.86k
    m_scalar = uint;
203
2.86k
  }
204
205
394k
  void SetUInt64(uint64_t uint, Type t = eTypeUInt64) {
206
394k
    m_type = t;
207
394k
    m_scalar = uint;
208
394k
  }
209
210
0
  void SetUInt128(llvm::APInt uint) {
211
0
    m_type = eTypeUInt128;
212
0
    m_scalar = std::move(uint);
213
0
  }
214
215
  bool SetUInt(uint64_t uint, uint32_t byte_size);
216
217
311
  void SetFloat(float f) {
218
311
    m_type = eTypeFloat;
219
311
    m_scalar = f;
220
311
  }
221
222
259
  void SetDouble(double f) {
223
259
    m_type = eTypeDouble;
224
259
    m_scalar = f;
225
259
  }
226
227
0
  void SetLongDouble(long double f) {
228
0
    m_type = eTypeLongDouble;
229
0
    m_scalar = f;
230
0
  }
231
232
  void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order);
233
234
  bool SignExtend(uint32_t sign_bitpos);
235
236
  Status SetValueFromString(const RegisterInfo *reg_info,
237
                            llvm::StringRef value_str);
238
  Status SetValueFromString(const RegisterInfo *reg_info,
239
                            const char *value_str) = delete;
240
241
  Status SetValueFromData(const RegisterInfo *reg_info, DataExtractor &data,
242
                          lldb::offset_t offset, bool partial_data_ok);
243
244
  const void *GetBytes() const;
245
246
22.8k
  lldb::ByteOrder GetByteOrder() const {
247
22.8k
    if (m_type == eTypeBytes)
248
2.46k
      return buffer.byte_order;
249
20.3k
    return endian::InlHostByteOrder();
250
22.8k
  }
251
252
  uint32_t GetByteSize() const;
253
254
0
  static uint32_t GetMaxByteSize() { return kMaxRegisterByteSize; }
255
256
  void Clear();
257
258
protected:
259
  RegisterValue::Type m_type = eTypeInvalid;
260
  Scalar m_scalar;
261
262
  struct {
263
    mutable uint8_t
264
        bytes[kMaxRegisterByteSize]; // This must be big enough to hold any
265
                                     // register for any supported target.
266
    uint16_t length;
267
    lldb::ByteOrder byte_order;
268
  } buffer;
269
};
270
271
} // namespace lldb_private
272
273
#endif // LLDB_UTILITY_REGISTERVALUE_H