From 0665a0f09e6597937766c32e606346baf055a495 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Tue, 30 Oct 2012 18:18:43 +0000 Subject: [PATCH] Path from Ashok Thirumurthi: The attached patch adds eValueTypeVector to lldb_private::Value. The nested struct Vector is patterned after RegisterValue::m_data.buffer. This change to Value allows ClangExpressionDeclMap::LookupDecl to return vector register data for consumption by InterpreterStackFrame::ResolveValue. Note that ResolveValue was tweaked slightly to allocate enough memory for vector registers. An immediate result of this patch is that "expr $xmm0" generates the same results on Linux as on the Mac, which is good enough for TestRegisters.py. In addition, the log of m_memory.PrintData(data_region.m_base, data_region.m_extent) shows that the register content has been resolved successfully. On the other hand, the output is glaringly empty: runCmd: expr $xmm0 output: (unsigned char __attribute__((ext_vector_type(16)))) $0 = {} Expecting sub string: vector_type Matched llvm-svn: 167033 --- lldb/include/lldb/Core/Value.h | 107 +++++++++++++++++++++- lldb/source/Core/ValueObject.cpp | 10 +- lldb/source/Core/ValueObjectVariable.cpp | 1 + lldb/source/Expression/ClangExpressionDeclMap.cpp | 9 +- lldb/source/Expression/IRInterpreter.cpp | 6 +- 5 files changed, 126 insertions(+), 7 deletions(-) diff --git a/lldb/include/lldb/Core/Value.h b/lldb/include/lldb/Core/Value.h index c01783b..c3fa1fa 100644 --- a/lldb/include/lldb/Core/Value.h +++ b/lldb/include/lldb/Core/Value.h @@ -12,6 +12,7 @@ // C Includes // C++ Includes +#include #include // Other libraries and framework includes // Project includes @@ -34,6 +35,7 @@ public: // m_value contains... // ============================ eValueTypeScalar, // raw scalar value + eValueTypeVector, // byte array of m_vector.length with endianness of m_vector.byte_order eValueTypeFileAddress, // file address value eValueTypeLoadAddress, // load address value eValueTypeHostAddress // host address value (for memory in the process that is using liblldb) @@ -45,13 +47,78 @@ public: // ==================== eContextTypeInvalid, // undefined eContextTypeClangType, // void * (an opaque clang::QualType * that can be fed to "static QualType QualType::getFromOpaquePtr(void *)") - eContextTypeRegisterInfo, // RegisterInfo * + eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector register) eContextTypeLLDBType, // lldb_private::Type * eContextTypeVariable // lldb_private::Variable * }; + enum + { + kMaxByteSize = 32u + }; + + struct Vector + { + // The byte array must be big enough to hold vector registers for any supported target. + uint8_t bytes[kMaxByteSize]; + size_t length; + lldb::ByteOrder byte_order; + + Vector() : + length(0), + byte_order(lldb::eByteOrderInvalid) + { + } + + Vector(const Vector& vector) + { *this = vector; + } + const Vector& + operator=(const Vector& vector) + { + SetBytes((uint8_t *)vector.bytes, vector.length, vector.byte_order); + return *this; + } + + bool + SetBytes(uint8_t *bytes, size_t length, lldb::ByteOrder byte_order) + { + this->length = length; + this->byte_order = byte_order; + if (length) + ::memcpy(this->bytes, bytes, length < kMaxByteSize ? length : kMaxByteSize); + return IsValid(); + } + + bool + IsValid() const + { + return (length > 0 && length < kMaxByteSize && byte_order != lldb::eByteOrderInvalid); + } + // Casts a vector, if valid, to an unsigned int of matching or largest supported size. + // Truncates to the beginning of the vector if required. + // Returns a default constructed Scalar if the Vector data is internally inconsistent. + Scalar + GetAsScalar() const + { + Scalar scalar; + if (IsValid()) + if (length == 1) scalar = *(uint8_t *)bytes; + if (length == 2) scalar = *(uint16_t *)bytes; + if (length == 4) scalar = *(uint32_t *)bytes; + if (length == 8) scalar = *(uint64_t *)bytes; +#if defined (ENABLE_128_BIT_SUPPORT) + if (length >= 16) scalar = *(__uint128_t *)bytes; +#else + if (length >= 16) scalar = *(__uint64_t *)bytes; +#endif + return scalar; + } + }; + Value(); Value(const Scalar& scalar); + Value(const Vector& vector); Value(const uint8_t *bytes, int len); Value(const Value &rhs); @@ -91,6 +158,13 @@ public: { m_context_type = context_type; m_context = p; + if (m_context_type == eContextTypeRegisterInfo) { + RegisterInfo *reg_info = GetRegisterInfo(); + if (reg_info->encoding == lldb::eEncodingVector) + SetValueType(eValueTypeVector); + else + SetValueType(eValueTypeScalar); + } } RegisterInfo * @@ -108,6 +182,36 @@ public: return m_value; } + Vector & + GetVector() + { + return m_vector; + } + + bool + SetVectorBytes(const Vector& vector) + { + m_vector = vector; + return m_vector.IsValid(); + } + + bool + SetVectorBytes(uint8_t *bytes, size_t length, lldb::ByteOrder byte_order) + { + return m_vector.SetBytes(bytes, length, byte_order); + } + + bool + SetScalarFromVector() + { + if (m_vector.IsValid()) + { + m_value = m_vector.GetAsScalar(); + return true; + } + return false; + } + void ResizeData(int len); @@ -144,6 +248,7 @@ public: protected: Scalar m_value; + Vector m_vector; ValueType m_value_type; void * m_context; ContextType m_context_type; diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index c3560f1..08f4308 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -422,6 +422,7 @@ ValueObject::GetLocationAsCString () break; case Value::eValueTypeScalar: + case Value::eValueTypeVector: if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) { RegisterInfo *reg_info = m_value.GetRegisterInfo(); @@ -431,10 +432,10 @@ ValueObject::GetLocationAsCString () m_location_str = reg_info->name; else if (reg_info->alt_name) m_location_str = reg_info->alt_name; - break; + + m_location_str = (reg_info->encoding == lldb::eEncodingVector) ? "vector" : "scalar"; } } - m_location_str = "scalar"; break; case Value::eValueTypeLoadAddress: @@ -1585,6 +1586,7 @@ ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_typ switch (m_value.GetValueType()) { case Value::eValueTypeScalar: + case Value::eValueTypeVector: if (scalar_is_load_address) { if(address_type) @@ -1621,6 +1623,7 @@ ValueObject::GetPointerValue (AddressType *address_type) switch (m_value.GetValueType()) { case Value::eValueTypeScalar: + case Value::eValueTypeVector: address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); break; @@ -1720,7 +1723,8 @@ ValueObject::SetValueFromCString (const char *value_str, Error& error) break; case Value::eValueTypeFileAddress: case Value::eValueTypeScalar: - break; + case Value::eValueTypeVector: + break; } } else diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp index 20a4af0..3ff37e9 100644 --- a/lldb/source/Core/ValueObjectVariable.cpp +++ b/lldb/source/Core/ValueObjectVariable.cpp @@ -176,6 +176,7 @@ ValueObjectVariable::UpdateValue () break; case Value::eValueTypeLoadAddress: case Value::eValueTypeScalar: + case Value::eValueTypeVector: SetAddressTypeOfChildren(eAddressTypeLoad); break; } diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index 940be04..f8304b9 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -1083,8 +1083,13 @@ ClangExpressionDeclMap::LookupDecl (clang::NamedDecl *decl, ClangExpressionVaria Value ret; ret.SetContext(Value::eContextTypeRegisterInfo, reg_info); - if (!reg_value.GetScalarValue(ret.GetScalar())) - return Value(); + if (reg_info->encoding == eEncodingVector) + { + if (ret.SetVectorBytes((uint8_t *)reg_value.GetBytes(), reg_value.GetByteSize(), reg_value.GetByteOrder())) + ret.SetScalarFromVector(); + } + else if (!reg_value.GetScalarValue(ret.GetScalar())) + return Value(); return ret; } diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp index 421b4f9..4211c87 100644 --- a/lldb/source/Expression/IRInterpreter.cpp +++ b/lldb/source/Expression/IRInterpreter.cpp @@ -676,7 +676,11 @@ public: if (bare_register) indirect_variable = false; - Memory::Region data_region = m_memory.Malloc(value->getType()); + lldb_private::RegisterInfo *reg_info = resolved_value.GetRegisterInfo(); + Memory::Region data_region = (reg_info->encoding == lldb::eEncodingVector) ? + m_memory.Malloc(reg_info->byte_size, m_target_data.getPrefTypeAlignment(value->getType())) : + m_memory.Malloc(value->getType()); + data_region.m_allocation->m_origin = resolved_value; Memory::Region ref_region = m_memory.Malloc(value->getType()); Memory::Region pointer_region; -- 2.7.4