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