File indexing completed on 2026-05-10 08:42:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_UTILITY_REGISTERVALUE_H
0010 #define LLDB_UTILITY_REGISTERVALUE_H
0011
0012 #include "lldb/Utility/Endian.h"
0013 #include "lldb/Utility/Scalar.h"
0014 #include "lldb/Utility/Status.h"
0015 #include "lldb/lldb-enumerations.h"
0016 #include "lldb/lldb-types.h"
0017 #include "llvm/ADT/APInt.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include <cstdint>
0021 #include <cstring>
0022 #include <utility>
0023
0024 namespace lldb_private {
0025 class DataExtractor;
0026 class Stream;
0027 struct RegisterInfo;
0028
0029 class RegisterValue {
0030 public:
0031 enum {
0032
0033
0034 kTypicalRegisterByteSize = 256u,
0035
0036
0037
0038 kMaxRegisterByteSize = 256u * 256u,
0039 };
0040
0041 typedef llvm::SmallVector<uint8_t, kTypicalRegisterByteSize> BytesContainer;
0042
0043 enum Type {
0044 eTypeInvalid,
0045 eTypeUInt8,
0046 eTypeUInt16,
0047 eTypeUInt32,
0048 eTypeUInt64,
0049 eTypeUInt128,
0050 eTypeFloat,
0051 eTypeDouble,
0052 eTypeLongDouble,
0053 eTypeBytes
0054 };
0055
0056 RegisterValue() : m_scalar(static_cast<unsigned long>(0)) {}
0057
0058 explicit RegisterValue(uint8_t inst) : m_type(eTypeUInt8) { m_scalar = inst; }
0059
0060 explicit RegisterValue(uint16_t inst) : m_type(eTypeUInt16) {
0061 m_scalar = inst;
0062 }
0063
0064 explicit RegisterValue(uint32_t inst) : m_type(eTypeUInt32) {
0065 m_scalar = inst;
0066 }
0067
0068 explicit RegisterValue(uint64_t inst) : m_type(eTypeUInt64) {
0069 m_scalar = inst;
0070 }
0071
0072 explicit RegisterValue(llvm::APInt inst) : m_type(eTypeUInt128) {
0073 m_scalar = llvm::APInt(std::move(inst));
0074 }
0075
0076 explicit RegisterValue(float value) : m_type(eTypeFloat) { m_scalar = value; }
0077
0078 explicit RegisterValue(double value) : m_type(eTypeDouble) {
0079 m_scalar = value;
0080 }
0081
0082 explicit RegisterValue(long double value) : m_type(eTypeLongDouble) {
0083 m_scalar = value;
0084 }
0085
0086 explicit RegisterValue(llvm::ArrayRef<uint8_t> bytes,
0087 lldb::ByteOrder byte_order) {
0088 SetBytes(bytes.data(), bytes.size(), byte_order);
0089 }
0090
0091 RegisterValue::Type GetType() const { return m_type; }
0092
0093 bool CopyValue(const RegisterValue &rhs);
0094
0095 void SetType(RegisterValue::Type type) { m_type = type; }
0096
0097 RegisterValue::Type SetType(const RegisterInfo ®_info);
0098
0099 bool GetData(DataExtractor &data) const;
0100
0101
0102
0103
0104
0105
0106
0107
0108 uint32_t GetAsMemoryData(const RegisterInfo ®_info, void *dst,
0109 uint32_t dst_len, lldb::ByteOrder dst_byte_order,
0110 Status &error) const;
0111
0112 uint32_t SetFromMemoryData(const RegisterInfo ®_info, const void *src,
0113 uint32_t src_len, lldb::ByteOrder src_byte_order,
0114 Status &error);
0115
0116 bool GetScalarValue(Scalar &scalar) const;
0117
0118 uint8_t GetAsUInt8(uint8_t fail_value = UINT8_MAX,
0119 bool *success_ptr = nullptr) const {
0120 if (m_type == eTypeUInt8) {
0121 if (success_ptr)
0122 *success_ptr = true;
0123 return m_scalar.UChar(fail_value);
0124 }
0125 if (success_ptr)
0126 *success_ptr = true;
0127 return fail_value;
0128 }
0129
0130 uint16_t GetAsUInt16(uint16_t fail_value = UINT16_MAX,
0131 bool *success_ptr = nullptr) const;
0132
0133 uint32_t GetAsUInt32(uint32_t fail_value = UINT32_MAX,
0134 bool *success_ptr = nullptr) const;
0135
0136 uint64_t GetAsUInt64(uint64_t fail_value = UINT64_MAX,
0137 bool *success_ptr = nullptr) const;
0138
0139 llvm::APInt GetAsUInt128(const llvm::APInt &fail_value,
0140 bool *success_ptr = nullptr) const;
0141
0142 float GetAsFloat(float fail_value = 0.0f, bool *success_ptr = nullptr) const;
0143
0144 double GetAsDouble(double fail_value = 0.0,
0145 bool *success_ptr = nullptr) const;
0146
0147 long double GetAsLongDouble(long double fail_value = 0.0,
0148 bool *success_ptr = nullptr) const;
0149
0150 void SetValueToInvalid() { m_type = eTypeInvalid; }
0151
0152 bool ClearBit(uint32_t bit);
0153
0154 bool SetBit(uint32_t bit);
0155
0156 bool operator==(const RegisterValue &rhs) const;
0157
0158 bool operator!=(const RegisterValue &rhs) const;
0159
0160 void operator=(uint8_t uint) {
0161 m_type = eTypeUInt8;
0162 m_scalar = uint;
0163 }
0164
0165 void operator=(uint16_t uint) {
0166 m_type = eTypeUInt16;
0167 m_scalar = uint;
0168 }
0169
0170 void operator=(uint32_t uint) {
0171 m_type = eTypeUInt32;
0172 m_scalar = uint;
0173 }
0174
0175 void operator=(uint64_t uint) {
0176 m_type = eTypeUInt64;
0177 m_scalar = uint;
0178 }
0179
0180 void operator=(llvm::APInt uint) {
0181 m_type = eTypeUInt128;
0182 m_scalar = llvm::APInt(std::move(uint));
0183 }
0184
0185 void operator=(float f) {
0186 m_type = eTypeFloat;
0187 m_scalar = f;
0188 }
0189
0190 void operator=(double f) {
0191 m_type = eTypeDouble;
0192 m_scalar = f;
0193 }
0194
0195 void operator=(long double f) {
0196 m_type = eTypeLongDouble;
0197 m_scalar = f;
0198 }
0199
0200 void SetUInt8(uint8_t uint) {
0201 m_type = eTypeUInt8;
0202 m_scalar = uint;
0203 }
0204
0205 void SetUInt16(uint16_t uint) {
0206 m_type = eTypeUInt16;
0207 m_scalar = uint;
0208 }
0209
0210 void SetUInt32(uint32_t uint, Type t = eTypeUInt32) {
0211 m_type = t;
0212 m_scalar = uint;
0213 }
0214
0215 void SetUInt64(uint64_t uint, Type t = eTypeUInt64) {
0216 m_type = t;
0217 m_scalar = uint;
0218 }
0219
0220 void SetUInt128(llvm::APInt uint) {
0221 m_type = eTypeUInt128;
0222 m_scalar = std::move(uint);
0223 }
0224
0225 bool SetUInt(uint64_t uint, uint32_t byte_size);
0226
0227 void SetFloat(float f) {
0228 m_type = eTypeFloat;
0229 m_scalar = f;
0230 }
0231
0232 void SetDouble(double f) {
0233 m_type = eTypeDouble;
0234 m_scalar = f;
0235 }
0236
0237 void SetLongDouble(long double f) {
0238 m_type = eTypeLongDouble;
0239 m_scalar = f;
0240 }
0241
0242 void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order);
0243
0244 bool SignExtend(uint32_t sign_bitpos);
0245
0246 Status SetValueFromString(const RegisterInfo *reg_info,
0247 llvm::StringRef value_str);
0248 Status SetValueFromString(const RegisterInfo *reg_info,
0249 const char *value_str) = delete;
0250
0251 Status SetValueFromData(const RegisterInfo ®_info, DataExtractor &data,
0252 lldb::offset_t offset, bool partial_data_ok);
0253
0254 const void *GetBytes() const;
0255
0256 lldb::ByteOrder GetByteOrder() const {
0257 if (m_type == eTypeBytes)
0258 return buffer.byte_order;
0259 return endian::InlHostByteOrder();
0260 }
0261
0262 uint32_t GetByteSize() const;
0263
0264 void Clear();
0265
0266 protected:
0267 RegisterValue::Type m_type = eTypeInvalid;
0268 Scalar m_scalar;
0269
0270 struct RegisterValueBuffer {
0271
0272 RegisterValueBuffer() : bytes(kTypicalRegisterByteSize) {}
0273
0274 mutable BytesContainer bytes;
0275 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
0276 } buffer;
0277 };
0278
0279 }
0280
0281 #endif