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"
13#include "lldb/Utility/Scalar.h"
14#include "lldb/Utility/Status.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
24namespace lldb_private {
25class DataExtractor;
26class Stream;
27struct RegisterInfo;
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 the register value from this object into a buffer in "dst" and obey
103 // the "dst_byte_order" when copying the data. Also watch out in case
104 // "dst_len" is longer or shorter than the register value described by
105 // "reg_info" and only copy the least significant bytes of the register
106 // value, or pad the destination with zeroes if the register byte size is
107 // shorter that "dst_len" (all while correctly abiding the "dst_byte_order").
108 // Returns the number of bytes copied into "dst".
109 uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst,
110 uint32_t dst_len, lldb::ByteOrder dst_byte_order,
111 Status &error) const;
112
113 uint32_t SetFromMemoryData(const RegisterInfo &reg_info, const void *src,
114 uint32_t src_len, lldb::ByteOrder src_byte_order,
115 Status &error);
116
117 bool GetScalarValue(Scalar &scalar) const;
118
119 uint8_t GetAsUInt8(uint8_t fail_value = UINT8_MAX,
120 bool *success_ptr = nullptr) const {
121 if (m_type == eTypeUInt8) {
122 if (success_ptr)
123 *success_ptr = true;
124 return m_scalar.UChar(fail_value);
125 }
126 if (success_ptr)
127 *success_ptr = true;
128 return fail_value;
129 }
130
131 uint16_t GetAsUInt16(uint16_t fail_value = UINT16_MAX,
132 bool *success_ptr = nullptr) const;
133
134 uint32_t GetAsUInt32(uint32_t fail_value = UINT32_MAX,
135 bool *success_ptr = nullptr) const;
136
137 uint64_t GetAsUInt64(uint64_t fail_value = UINT64_MAX,
138 bool *success_ptr = nullptr) const;
139
140 llvm::APInt GetAsUInt128(const llvm::APInt &fail_value,
141 bool *success_ptr = nullptr) const;
142
143 float GetAsFloat(float fail_value = 0.0f, bool *success_ptr = nullptr) const;
144
145 double GetAsDouble(double fail_value = 0.0,
146 bool *success_ptr = nullptr) const;
147
148 long double GetAsLongDouble(long double fail_value = 0.0,
149 bool *success_ptr = nullptr) const;
150
152
153 bool ClearBit(uint32_t bit);
154
155 bool SetBit(uint32_t bit);
156
157 bool operator==(const RegisterValue &rhs) const;
158
159 bool operator!=(const RegisterValue &rhs) const;
160
161 void operator=(uint8_t uint) {
163 m_scalar = uint;
164 }
165
166 void operator=(uint16_t uint) {
168 m_scalar = uint;
169 }
170
171 void operator=(uint32_t uint) {
173 m_scalar = uint;
174 }
175
176 void operator=(uint64_t uint) {
178 m_scalar = uint;
179 }
180
181 void operator=(llvm::APInt uint) {
183 m_scalar = llvm::APInt(std::move(uint));
184 }
185
186 void operator=(float f) {
188 m_scalar = f;
189 }
190
191 void operator=(double f) {
193 m_scalar = f;
194 }
195
196 void operator=(long double f) {
198 m_scalar = f;
199 }
200
201 void SetUInt8(uint8_t uint) {
203 m_scalar = uint;
204 }
205
206 void SetUInt16(uint16_t uint) {
208 m_scalar = uint;
209 }
210
211 void SetUInt32(uint32_t uint, Type t = eTypeUInt32) {
212 m_type = t;
213 m_scalar = uint;
214 }
215
216 void SetUInt64(uint64_t uint, Type t = eTypeUInt64) {
217 m_type = t;
218 m_scalar = uint;
219 }
220
221 void SetUIntN(llvm::APInt uint) {
223 m_scalar = std::move(uint);
224 }
225
226 bool SetUInt(uint64_t uint, uint32_t byte_size);
227
228 void SetFloat(float f) {
230 m_scalar = f;
231 }
232
233 void SetDouble(double f) {
235 m_scalar = f;
236 }
237
238 void SetLongDouble(long double f) {
240 m_scalar = f;
241 }
242
243 void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order);
244
245 bool SignExtend(uint32_t sign_bitpos);
246
247 Status SetValueFromString(const RegisterInfo *reg_info,
248 llvm::StringRef value_str);
250 const char *value_str) = delete;
251
252 Status SetValueFromData(const RegisterInfo &reg_info, DataExtractor &data,
253 lldb::offset_t offset, bool partial_data_ok);
254
255 const void *GetBytes() const;
256
258 if (m_type == eTypeBytes)
259 return buffer.byte_order;
261 }
262
263 uint32_t GetByteSize() const;
264
265 void Clear();
266
267protected:
270
272 // Start at max stack storage size. Move to the heap for anything larger.
274
278};
279
280} // namespace lldb_private
281
282#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:85
ByteOrder
Byte ordering definitions.
Every register is described in detail including its name, alternate name (optional),...