LLDB mainline
RegisterValue.h
Go to the documentation of this file.
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"
14#include "lldb/Utility/Scalar.h"
15#include "lldb/Utility/Status.h"
17#include "lldb/lldb-types.h"
18#include "llvm/ADT/APInt.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/StringRef.h"
21#include <cstdint>
22#include <cstring>
23#include <utility>
24
25namespace lldb_private {
26class DataExtractor;
27class Stream;
28
30public:
31 enum {
32 // What we can reasonably put on the stack, big enough to support up to 256
33 // byte AArch64 SVE.
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 {
49 eTypeUIntN, /// < This value is used when the (integer) register is larger
50 /// than 64-bits.
55 };
56
57 RegisterValue() : m_scalar(static_cast<unsigned long>(0)) {}
58
59 explicit RegisterValue(uint8_t inst) : m_type(eTypeUInt8) { m_scalar = inst; }
60
61 explicit RegisterValue(uint16_t inst) : m_type(eTypeUInt16) {
62 m_scalar = inst;
63 }
64
65 explicit RegisterValue(uint32_t inst) : m_type(eTypeUInt32) {
66 m_scalar = inst;
67 }
68
69 explicit RegisterValue(uint64_t inst) : m_type(eTypeUInt64) {
70 m_scalar = inst;
71 }
72
73 explicit RegisterValue(llvm::APInt inst) : m_type(eTypeUIntN) {
74 m_scalar = llvm::APInt(std::move(inst));
75 }
76
77 explicit RegisterValue(float value) : m_type(eTypeFloat) { m_scalar = value; }
78
79 explicit RegisterValue(double value) : m_type(eTypeDouble) {
80 m_scalar = value;
81 }
82
83 explicit RegisterValue(long double value) : m_type(eTypeLongDouble) {
84 m_scalar = value;
85 }
86
87 explicit RegisterValue(llvm::ArrayRef<uint8_t> bytes,
88 lldb::ByteOrder byte_order) {
89 SetBytes(bytes.data(), bytes.size(), byte_order);
90 }
91
93
94 bool CopyValue(const RegisterValue &rhs);
95
96 void SetType(RegisterValue::Type type) { m_type = type; }
97
99
100 bool GetData(DataExtractor &data) const;
101
102 /// Copy \p byte_size bytes from this value into \p data using \p byte_order.
103 bool GetData(DataExtractor &data, uint32_t byte_size,
104 lldb::ByteOrder byte_order) const;
105
106 // Copy the register value from this object into a buffer in "dst" and obey
107 // the "dst_byte_order" when copying the data. Also watch out in case
108 // "dst_len" is longer or shorter than the register value described by
109 // "reg_info" and only copy the least significant bytes of the register
110 // value, or pad the destination with zeroes if the register byte size is
111 // shorter that "dst_len" (all while correctly abiding the "dst_byte_order").
112 // Returns the number of bytes copied into "dst".
113 uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst,
114 uint32_t dst_len, lldb::ByteOrder dst_byte_order,
115 Status &error) const;
116
117 uint32_t SetFromMemoryData(const RegisterInfo &reg_info, const void *src,
118 uint32_t src_len, lldb::ByteOrder src_byte_order,
119 Status &error);
120
121 bool GetScalarValue(Scalar &scalar) const;
122
123 uint8_t GetAsUInt8(uint8_t fail_value = UINT8_MAX,
124 bool *success_ptr = nullptr) const {
125 if (m_type == eTypeUInt8) {
126 if (success_ptr)
127 *success_ptr = true;
128 return m_scalar.UChar(fail_value);
129 }
130 if (success_ptr)
131 *success_ptr = true;
132 return fail_value;
133 }
134
135 uint16_t GetAsUInt16(uint16_t fail_value = UINT16_MAX,
136 bool *success_ptr = nullptr) const;
137
138 uint32_t GetAsUInt32(uint32_t fail_value = UINT32_MAX,
139 bool *success_ptr = nullptr) const;
140
141 uint64_t GetAsUInt64(uint64_t fail_value = UINT64_MAX,
142 bool *success_ptr = nullptr) const;
143
144 llvm::APInt GetAsUInt128(const llvm::APInt &fail_value,
145 bool *success_ptr = nullptr) const;
146
147 float GetAsFloat(float fail_value = 0.0f, bool *success_ptr = nullptr) const;
148
149 double GetAsDouble(double fail_value = 0.0,
150 bool *success_ptr = nullptr) const;
151
152 long double GetAsLongDouble(long double fail_value = 0.0,
153 bool *success_ptr = nullptr) const;
154
156
157 bool ClearBit(uint32_t bit);
158
159 bool SetBit(uint32_t bit);
160
161 bool operator==(const RegisterValue &rhs) const;
162
163 bool operator!=(const RegisterValue &rhs) const;
164
165 void operator=(uint8_t uint) {
167 m_scalar = uint;
168 }
169
170 void operator=(uint16_t uint) {
172 m_scalar = uint;
173 }
174
175 void operator=(uint32_t uint) {
177 m_scalar = uint;
178 }
179
180 void operator=(uint64_t uint) {
182 m_scalar = uint;
183 }
184
185 void operator=(llvm::APInt uint) {
187 m_scalar = llvm::APInt(std::move(uint));
188 }
189
190 void operator=(float f) {
192 m_scalar = f;
193 }
194
195 void operator=(double f) {
197 m_scalar = f;
198 }
199
200 void operator=(long double f) {
202 m_scalar = f;
203 }
204
205 void SetUInt8(uint8_t uint) {
207 m_scalar = uint;
208 }
209
210 void SetUInt16(uint16_t uint) {
212 m_scalar = uint;
213 }
214
215 void SetUInt32(uint32_t uint, Type t = eTypeUInt32) {
216 m_type = t;
217 m_scalar = uint;
218 }
219
220 void SetUInt64(uint64_t uint, Type t = eTypeUInt64) {
221 m_type = t;
222 m_scalar = uint;
223 }
224
225 void SetUIntN(llvm::APInt uint) {
227 m_scalar = std::move(uint);
228 }
229
230 bool SetUInt(uint64_t uint, uint32_t byte_size);
231
232 void SetFloat(float f) {
234 m_scalar = f;
235 }
236
237 void SetDouble(double f) {
239 m_scalar = f;
240 }
241
242 void SetLongDouble(long double f) {
244 m_scalar = f;
245 }
246
247 void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order);
248
249 bool SignExtend(uint32_t sign_bitpos);
250
251 Status SetValueFromString(const RegisterInfo *reg_info,
252 llvm::StringRef value_str);
254 const char *value_str) = delete;
255
256 Status SetValueFromData(const RegisterInfo &reg_info, DataExtractor &data,
257 lldb::offset_t offset, bool partial_data_ok);
258
259 const void *GetBytes() const;
260
262 if (m_type == eTypeBytes)
263 return buffer.byte_order;
265 }
266
267 uint32_t GetByteSize() const;
268
269 void Clear();
270
271protected:
274
276 // Start at max stack storage size. Move to the heap for anything larger.
278
282};
283
284} // namespace lldb_private
285
286#endif // LLDB_UTILITY_REGISTERVALUE_H
static llvm::raw_ostream & error(Stream &strm)
An data extractor class.
void operator=(llvm::APInt uint)
bool operator==(const RegisterValue &rhs) const
RegisterValue::Type m_type
uint16_t GetAsUInt16(uint16_t fail_value=UINT16_MAX, bool *success_ptr=nullptr) const
bool SignExtend(uint32_t sign_bitpos)
uint32_t SetFromMemoryData(const RegisterInfo &reg_info, const void *src, uint32_t src_len, lldb::ByteOrder src_byte_order, Status &error)
long double GetAsLongDouble(long double fail_value=0.0, bool *success_ptr=nullptr) const
bool GetData(DataExtractor &data) const
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
uint8_t GetAsUInt8(uint8_t fail_value=UINT8_MAX, bool *success_ptr=nullptr) const
void SetUInt16(uint16_t uint)
double GetAsDouble(double fail_value=0.0, bool *success_ptr=nullptr) const
void SetUIntN(llvm::APInt uint)
bool SetUInt(uint64_t uint, uint32_t byte_size)
Status SetValueFromString(const RegisterInfo *reg_info, llvm::StringRef value_str)
uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
float GetAsFloat(float fail_value=0.0f, bool *success_ptr=nullptr) const
void SetUInt8(uint8_t uint)
void operator=(long double f)
llvm::APInt GetAsUInt128(const llvm::APInt &fail_value, bool *success_ptr=nullptr) const
struct lldb_private::RegisterValue::RegisterValueBuffer buffer
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
void operator=(uint8_t uint)
bool GetScalarValue(Scalar &scalar) const
const void * GetBytes() const
RegisterValue::Type GetType() const
void SetLongDouble(long double f)
bool operator!=(const RegisterValue &rhs) const
Status SetValueFromData(const RegisterInfo &reg_info, DataExtractor &data, lldb::offset_t offset, bool partial_data_ok)
void SetType(RegisterValue::Type type)
RegisterValue(llvm::APInt inst)
void operator=(uint64_t uint)
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
void operator=(uint32_t uint)
bool CopyValue(const RegisterValue &rhs)
RegisterValue(long double value)
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
lldb::ByteOrder GetByteOrder() const
@ eTypeFloat
< This value is used when the (integer) register is larger than 64-bits.
RegisterValue(llvm::ArrayRef< uint8_t > bytes, lldb::ByteOrder byte_order)
void operator=(uint16_t uint)
Status SetValueFromString(const RegisterInfo *reg_info, const char *value_str)=delete
llvm::SmallVector< uint8_t, kTypicalRegisterByteSize > BytesContainer
An error handling class.
Definition Status.h:118
A stream class that can stream formatted output to a file.
Definition Stream.h:28
#define UINT64_MAX
#define UINT32_MAX
lldb::ByteOrder InlHostByteOrder()
Definition Endian.h:25
A class that represents a running process on the host machine.
static uint32_t bit(const uint32_t val, const uint32_t msbit)
Definition ARMUtils.h:270
uint64_t offset_t
Definition lldb-types.h:86
ByteOrder
Byte ordering definitions.
Every register is described in detail including its name, alternate name (optional),...