1 //===-- RegisterValue.h ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef lldb_RegisterValue_h 11 #define lldb_RegisterValue_h 12 13 // C Includes 14 #include <string.h> 15 16 // C++ Includes 17 // Other libraries and framework includes 18 // Project includes 19 #include "lldb/lldb-public.h" 20 #include "lldb/lldb-private.h" 21 #include "lldb/Host/Endian.h" 22 23 //#define ENABLE_128_BIT_SUPPORT 1 24 namespace lldb_private { 25 26 class RegisterValue 27 { 28 public: 29 enum 30 { 31 kMaxRegisterByteSize = 32u 32 }; 33 enum Type 34 { 35 eTypeInvalid, 36 eTypeUInt8, 37 eTypeUInt16, 38 eTypeUInt32, 39 eTypeUInt64, 40 #if defined (ENABLE_128_BIT_SUPPORT) 41 eTypeUInt128, 42 #endif 43 eTypeFloat, 44 eTypeDouble, 45 eTypeLongDouble, 46 eTypeBytes 47 }; 48 RegisterValue()49 RegisterValue () : 50 m_type (eTypeInvalid) 51 { 52 } 53 54 explicit RegisterValue(uint8_t inst)55 RegisterValue (uint8_t inst) : 56 m_type (eTypeUInt8) 57 { 58 m_data.uint8 = inst; 59 } 60 61 explicit RegisterValue(uint16_t inst)62 RegisterValue (uint16_t inst) : 63 m_type (eTypeUInt16) 64 { 65 m_data.uint16 = inst; 66 } 67 68 explicit RegisterValue(uint32_t inst)69 RegisterValue (uint32_t inst) : 70 m_type (eTypeUInt32) 71 { 72 m_data.uint32 = inst; 73 } 74 75 explicit RegisterValue(uint64_t inst)76 RegisterValue (uint64_t inst) : 77 m_type (eTypeUInt64) 78 { 79 m_data.uint64 = inst; 80 } 81 82 #if defined (ENABLE_128_BIT_SUPPORT) 83 explicit RegisterValue(__uint128_t inst)84 RegisterValue (__uint128_t inst) : 85 m_type (eTypeUInt128) 86 { 87 m_data.uint128 = inst; 88 } 89 #endif 90 explicit RegisterValue(float value)91 RegisterValue (float value) : 92 m_type (eTypeFloat) 93 { 94 m_data.ieee_float = value; 95 } 96 97 explicit RegisterValue(double value)98 RegisterValue (double value) : 99 m_type (eTypeDouble) 100 { 101 m_data.ieee_double = value; 102 } 103 104 explicit RegisterValue(long double value)105 RegisterValue (long double value) : 106 m_type (eTypeLongDouble) 107 { 108 m_data.ieee_long_double = value; 109 } 110 111 explicit RegisterValue(uint8_t * bytes,size_t length,lldb::ByteOrder byte_order)112 RegisterValue (uint8_t *bytes, size_t length, lldb::ByteOrder byte_order) 113 { 114 SetBytes (bytes, length, byte_order); 115 } 116 117 RegisterValue::Type GetType()118 GetType () const 119 { 120 return m_type; 121 } 122 123 bool 124 CopyValue (const RegisterValue &rhs); 125 126 void SetType(RegisterValue::Type type)127 SetType (RegisterValue::Type type) 128 { 129 m_type = type; 130 } 131 132 RegisterValue::Type 133 SetType (const RegisterInfo *reg_info); 134 135 bool 136 GetData (DataExtractor &data) const; 137 138 // Copy the register value from this object into a buffer in "dst" 139 // and obey the "dst_byte_order" when copying the data. Also watch out 140 // in case "dst_len" is longer or shorter than the register value 141 // described by "reg_info" and only copy the least significant bytes 142 // of the register value, or pad the destination with zeroes if the 143 // register byte size is shorter that "dst_len" (all while correctly 144 // abiding the "dst_byte_order"). Returns the number of bytes copied 145 // into "dst". 146 uint32_t 147 GetAsMemoryData (const RegisterInfo *reg_info, 148 void *dst, 149 uint32_t dst_len, 150 lldb::ByteOrder dst_byte_order, 151 Error &error) const; 152 153 uint32_t 154 SetFromMemoryData (const RegisterInfo *reg_info, 155 const void *src, 156 uint32_t src_len, 157 lldb::ByteOrder src_byte_order, 158 Error &error); 159 160 bool 161 GetScalarValue (Scalar &scalar) const; 162 163 uint8_t 164 GetAsUInt8 (uint8_t fail_value = UINT8_MAX, bool *success_ptr = NULL) const 165 { 166 if (m_type == eTypeUInt8) 167 { 168 if (success_ptr) 169 *success_ptr = true; 170 return m_data.uint8; 171 } 172 if (success_ptr) 173 *success_ptr = true; 174 return fail_value; 175 } 176 177 uint16_t 178 GetAsUInt16 (uint16_t fail_value = UINT16_MAX, bool *success_ptr = NULL) const; 179 180 uint32_t 181 GetAsUInt32 (uint32_t fail_value = UINT32_MAX, bool *success_ptr = NULL) const; 182 183 uint64_t 184 GetAsUInt64 (uint64_t fail_value = UINT64_MAX, bool *success_ptr = NULL) const; 185 186 #if defined (ENABLE_128_BIT_SUPPORT) 187 __uint128_t 188 GetAsUInt128 (__uint128_t fail_value = ~((__uint128_t)0), bool *success_ptr = NULL) const; 189 #endif 190 191 float 192 GetAsFloat (float fail_value = 0.0f, bool *success_ptr = NULL) const; 193 194 double 195 GetAsDouble (double fail_value = 0.0, bool *success_ptr = NULL) const; 196 197 long double 198 GetAsLongDouble (long double fail_value = 0.0, bool *success_ptr = NULL) const; 199 200 void SetValueToInvalid()201 SetValueToInvalid () 202 { 203 m_type = eTypeInvalid; 204 } 205 206 bool 207 ClearBit (uint32_t bit); 208 209 bool 210 SetBit (uint32_t bit); 211 212 bool 213 operator == (const RegisterValue &rhs) const; 214 215 bool 216 operator != (const RegisterValue &rhs) const; 217 218 void 219 operator = (uint8_t uint) 220 { 221 m_type = eTypeUInt8; 222 m_data.uint8 = uint; 223 } 224 225 void 226 operator = (uint16_t uint) 227 { 228 m_type = eTypeUInt16; 229 m_data.uint16 = uint; 230 } 231 232 void 233 operator = (uint32_t uint) 234 { 235 m_type = eTypeUInt32; 236 m_data.uint32 = uint; 237 } 238 239 void 240 operator = (uint64_t uint) 241 { 242 m_type = eTypeUInt64; 243 m_data.uint64 = uint; 244 } 245 246 #if defined (ENABLE_128_BIT_SUPPORT) 247 void 248 operator = (__uint128_t uint) 249 { 250 m_type = eTypeUInt128; 251 m_data.uint128 = uint; 252 } 253 #endif 254 void 255 operator = (float f) 256 { 257 m_type = eTypeFloat; 258 m_data.ieee_float = f; 259 } 260 261 void 262 operator = (double f) 263 { 264 m_type = eTypeDouble; 265 m_data.ieee_double = f; 266 } 267 268 void 269 operator = (long double f) 270 { 271 m_type = eTypeLongDouble; 272 m_data.ieee_long_double = f; 273 } 274 275 void SetUInt8(uint8_t uint)276 SetUInt8 (uint8_t uint) 277 { 278 m_type = eTypeUInt8; 279 m_data.uint8 = uint; 280 } 281 282 void SetUInt16(uint16_t uint)283 SetUInt16 (uint16_t uint) 284 { 285 m_type = eTypeUInt16; 286 m_data.uint16 = uint; 287 } 288 289 void 290 SetUInt32 (uint32_t uint, Type t = eTypeUInt32) 291 { 292 m_type = t; 293 m_data.uint32 = uint; 294 } 295 296 void 297 SetUInt64 (uint64_t uint, Type t = eTypeUInt64) 298 { 299 m_type = t; 300 m_data.uint64 = uint; 301 } 302 303 #if defined (ENABLE_128_BIT_SUPPORT) 304 void SetUInt128(__uint128_t uint)305 SetUInt128 (__uint128_t uint) 306 { 307 m_type = eTypeUInt128; 308 m_data.uint128 = uint; 309 } 310 #endif 311 bool 312 SetUInt (uint64_t uint, uint32_t byte_size); 313 314 void SetFloat(float f)315 SetFloat (float f) 316 { 317 m_type = eTypeFloat; 318 m_data.ieee_float = f; 319 } 320 321 void SetDouble(double f)322 SetDouble (double f) 323 { 324 m_type = eTypeDouble; 325 m_data.ieee_double = f; 326 } 327 328 void SetLongDouble(long double f)329 SetLongDouble (long double f) 330 { 331 m_type = eTypeLongDouble; 332 m_data.ieee_long_double = f; 333 } 334 335 void 336 SetBytes (const void *bytes, size_t length, lldb::ByteOrder byte_order); 337 338 bool 339 SignExtend (uint32_t sign_bitpos); 340 341 Error 342 SetValueFromCString (const RegisterInfo *reg_info, 343 const char *value_str); 344 345 Error 346 SetValueFromData (const RegisterInfo *reg_info, 347 DataExtractor &data, 348 lldb::offset_t offset, 349 bool partial_data_ok); 350 351 // The default value of 0 for reg_name_right_align_at means no alignment at all. 352 bool 353 Dump (Stream *s, 354 const RegisterInfo *reg_info, 355 bool prefix_with_name, 356 bool prefix_with_alt_name, 357 lldb::Format format, 358 uint32_t reg_name_right_align_at = 0) const; 359 360 void * 361 GetBytes (); 362 363 const void * 364 GetBytes () const; 365 366 lldb::ByteOrder GetByteOrder()367 GetByteOrder () const 368 { 369 if (m_type == eTypeBytes) 370 return m_data.buffer.byte_order; 371 return lldb::endian::InlHostByteOrder(); 372 } 373 374 uint32_t 375 GetByteSize () const; 376 377 void 378 Clear(); 379 380 protected: 381 382 RegisterValue::Type m_type; 383 union 384 { 385 uint8_t uint8; 386 uint16_t uint16; 387 uint32_t uint32; 388 uint64_t uint64; 389 #if defined (ENABLE_128_BIT_SUPPORT) 390 __uint128_t uint128; 391 #endif 392 float ieee_float; 393 double ieee_double; 394 long double ieee_long_double; 395 struct 396 { 397 uint8_t bytes[kMaxRegisterByteSize]; // This must be big enough to hold any register for any supported target. 398 uint8_t length; 399 lldb::ByteOrder byte_order; 400 } buffer; 401 } m_data; 402 }; 403 404 } // namespace lldb_private 405 406 #endif // lldb_RegisterValue_h 407