Coverage Report

Created: 2023-09-30 09:22

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