aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Core/RegisterValue.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/lldb/Core/RegisterValue.h')
-rw-r--r--include/lldb/Core/RegisterValue.h406
1 files changed, 406 insertions, 0 deletions
diff --git a/include/lldb/Core/RegisterValue.h b/include/lldb/Core/RegisterValue.h
new file mode 100644
index 000000000000..cf29cea46d36
--- /dev/null
+++ b/include/lldb/Core/RegisterValue.h
@@ -0,0 +1,406 @@
+//===-- RegisterValue.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef lldb_RegisterValue_h
+#define lldb_RegisterValue_h
+
+// C Includes
+#include <string.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-private.h"
+#include "lldb/Host/Endian.h"
+
+//#define ENABLE_128_BIT_SUPPORT 1
+namespace lldb_private {
+
+ class RegisterValue
+ {
+ public:
+ enum
+ {
+ kMaxRegisterByteSize = 32u
+ };
+ enum Type
+ {
+ eTypeInvalid,
+ eTypeUInt8,
+ eTypeUInt16,
+ eTypeUInt32,
+ eTypeUInt64,
+#if defined (ENABLE_128_BIT_SUPPORT)
+ eTypeUInt128,
+#endif
+ eTypeFloat,
+ eTypeDouble,
+ eTypeLongDouble,
+ eTypeBytes
+ };
+
+ RegisterValue () :
+ m_type (eTypeInvalid)
+ {
+ }
+
+ explicit
+ RegisterValue (uint8_t inst) :
+ m_type (eTypeUInt8)
+ {
+ m_data.uint8 = inst;
+ }
+
+ explicit
+ RegisterValue (uint16_t inst) :
+ m_type (eTypeUInt16)
+ {
+ m_data.uint16 = inst;
+ }
+
+ explicit
+ RegisterValue (uint32_t inst) :
+ m_type (eTypeUInt32)
+ {
+ m_data.uint32 = inst;
+ }
+
+ explicit
+ RegisterValue (uint64_t inst) :
+ m_type (eTypeUInt64)
+ {
+ m_data.uint64 = inst;
+ }
+
+#if defined (ENABLE_128_BIT_SUPPORT)
+ explicit
+ RegisterValue (__uint128_t inst) :
+ m_type (eTypeUInt128)
+ {
+ m_data.uint128 = inst;
+ }
+#endif
+ explicit
+ RegisterValue (float value) :
+ m_type (eTypeFloat)
+ {
+ m_data.ieee_float = value;
+ }
+
+ explicit
+ RegisterValue (double value) :
+ m_type (eTypeDouble)
+ {
+ m_data.ieee_double = value;
+ }
+
+ explicit
+ RegisterValue (long double value) :
+ m_type (eTypeLongDouble)
+ {
+ m_data.ieee_long_double = value;
+ }
+
+ explicit
+ RegisterValue (uint8_t *bytes, size_t length, lldb::ByteOrder byte_order)
+ {
+ SetBytes (bytes, length, byte_order);
+ }
+
+ RegisterValue::Type
+ GetType () const
+ {
+ return m_type;
+ }
+
+ bool
+ CopyValue (const RegisterValue &rhs);
+
+ void
+ SetType (RegisterValue::Type type)
+ {
+ m_type = type;
+ }
+
+ RegisterValue::Type
+ SetType (const RegisterInfo *reg_info);
+
+ bool
+ GetData (DataExtractor &data) const;
+
+ // Copy the register value from this object into a buffer in "dst"
+ // and obey the "dst_byte_order" when copying the data. Also watch out
+ // in case "dst_len" is longer or shorter than the register value
+ // described by "reg_info" and only copy the least significant bytes
+ // of the register value, or pad the destination with zeroes if the
+ // register byte size is shorter that "dst_len" (all while correctly
+ // abiding the "dst_byte_order"). Returns the number of bytes copied
+ // into "dst".
+ uint32_t
+ GetAsMemoryData (const RegisterInfo *reg_info,
+ void *dst,
+ uint32_t dst_len,
+ lldb::ByteOrder dst_byte_order,
+ Error &error) const;
+
+ uint32_t
+ SetFromMemoryData (const RegisterInfo *reg_info,
+ const void *src,
+ uint32_t src_len,
+ lldb::ByteOrder src_byte_order,
+ Error &error);
+
+ bool
+ GetScalarValue (Scalar &scalar) const;
+
+ uint8_t
+ GetAsUInt8 (uint8_t fail_value = UINT8_MAX, bool *success_ptr = NULL) const
+ {
+ if (m_type == eTypeUInt8)
+ {
+ if (success_ptr)
+ *success_ptr = true;
+ return m_data.uint8;
+ }
+ if (success_ptr)
+ *success_ptr = true;
+ return fail_value;
+ }
+
+ uint16_t
+ GetAsUInt16 (uint16_t fail_value = UINT16_MAX, bool *success_ptr = NULL) const;
+
+ uint32_t
+ GetAsUInt32 (uint32_t fail_value = UINT32_MAX, bool *success_ptr = NULL) const;
+
+ uint64_t
+ GetAsUInt64 (uint64_t fail_value = UINT64_MAX, bool *success_ptr = NULL) const;
+
+#if defined (ENABLE_128_BIT_SUPPORT)
+ __uint128_t
+ GetAsUInt128 (__uint128_t fail_value = ~((__uint128_t)0), bool *success_ptr = NULL) const;
+#endif
+
+ float
+ GetAsFloat (float fail_value = 0.0f, bool *success_ptr = NULL) const;
+
+ double
+ GetAsDouble (double fail_value = 0.0, bool *success_ptr = NULL) const;
+
+ long double
+ GetAsLongDouble (long double fail_value = 0.0, bool *success_ptr = NULL) const;
+
+ void
+ SetValueToInvalid ()
+ {
+ m_type = eTypeInvalid;
+ }
+
+ bool
+ ClearBit (uint32_t bit);
+
+ bool
+ SetBit (uint32_t bit);
+
+ bool
+ operator == (const RegisterValue &rhs) const;
+
+ bool
+ operator != (const RegisterValue &rhs) const;
+
+ void
+ operator = (uint8_t uint)
+ {
+ m_type = eTypeUInt8;
+ m_data.uint8 = uint;
+ }
+
+ void
+ operator = (uint16_t uint)
+ {
+ m_type = eTypeUInt16;
+ m_data.uint16 = uint;
+ }
+
+ void
+ operator = (uint32_t uint)
+ {
+ m_type = eTypeUInt32;
+ m_data.uint32 = uint;
+ }
+
+ void
+ operator = (uint64_t uint)
+ {
+ m_type = eTypeUInt64;
+ m_data.uint64 = uint;
+ }
+
+#if defined (ENABLE_128_BIT_SUPPORT)
+ void
+ operator = (__uint128_t uint)
+ {
+ m_type = eTypeUInt128;
+ m_data.uint128 = uint;
+ }
+#endif
+ void
+ operator = (float f)
+ {
+ m_type = eTypeFloat;
+ m_data.ieee_float = f;
+ }
+
+ void
+ operator = (double f)
+ {
+ m_type = eTypeDouble;
+ m_data.ieee_double = f;
+ }
+
+ void
+ operator = (long double f)
+ {
+ m_type = eTypeLongDouble;
+ m_data.ieee_long_double = f;
+ }
+
+ void
+ SetUInt8 (uint8_t uint)
+ {
+ m_type = eTypeUInt8;
+ m_data.uint8 = uint;
+ }
+
+ void
+ SetUInt16 (uint16_t uint)
+ {
+ m_type = eTypeUInt16;
+ m_data.uint16 = uint;
+ }
+
+ void
+ SetUInt32 (uint32_t uint, Type t = eTypeUInt32)
+ {
+ m_type = t;
+ m_data.uint32 = uint;
+ }
+
+ void
+ SetUInt64 (uint64_t uint, Type t = eTypeUInt64)
+ {
+ m_type = t;
+ m_data.uint64 = uint;
+ }
+
+#if defined (ENABLE_128_BIT_SUPPORT)
+ void
+ SetUInt128 (__uint128_t uint)
+ {
+ m_type = eTypeUInt128;
+ m_data.uint128 = uint;
+ }
+#endif
+ bool
+ SetUInt (uint64_t uint, uint32_t byte_size);
+
+ void
+ SetFloat (float f)
+ {
+ m_type = eTypeFloat;
+ m_data.ieee_float = f;
+ }
+
+ void
+ SetDouble (double f)
+ {
+ m_type = eTypeDouble;
+ m_data.ieee_double = f;
+ }
+
+ void
+ SetLongDouble (long double f)
+ {
+ m_type = eTypeLongDouble;
+ m_data.ieee_long_double = f;
+ }
+
+ void
+ SetBytes (const void *bytes, size_t length, lldb::ByteOrder byte_order);
+
+ bool
+ SignExtend (uint32_t sign_bitpos);
+
+ Error
+ SetValueFromCString (const RegisterInfo *reg_info,
+ const char *value_str);
+
+ Error
+ SetValueFromData (const RegisterInfo *reg_info,
+ DataExtractor &data,
+ lldb::offset_t offset,
+ bool partial_data_ok);
+
+ // The default value of 0 for reg_name_right_align_at means no alignment at all.
+ bool
+ Dump (Stream *s,
+ const RegisterInfo *reg_info,
+ bool prefix_with_name,
+ bool prefix_with_alt_name,
+ lldb::Format format,
+ uint32_t reg_name_right_align_at = 0) const;
+
+ void *
+ GetBytes ();
+
+ const void *
+ GetBytes () const;
+
+ lldb::ByteOrder
+ GetByteOrder () const
+ {
+ if (m_type == eTypeBytes)
+ return m_data.buffer.byte_order;
+ return lldb::endian::InlHostByteOrder();
+ }
+
+ uint32_t
+ GetByteSize () const;
+
+ void
+ Clear();
+
+ protected:
+
+ RegisterValue::Type m_type;
+ union
+ {
+ uint8_t uint8;
+ uint16_t uint16;
+ uint32_t uint32;
+ uint64_t uint64;
+#if defined (ENABLE_128_BIT_SUPPORT)
+ __uint128_t uint128;
+#endif
+ float ieee_float;
+ double ieee_double;
+ long double ieee_long_double;
+ struct
+ {
+ uint8_t bytes[kMaxRegisterByteSize]; // This must be big enough to hold any register for any supported target.
+ uint8_t length;
+ lldb::ByteOrder byte_order;
+ } buffer;
+ } m_data;
+ };
+
+} // namespace lldb_private
+
+#endif // lldb_RegisterValue_h