178a685aaSJim Ingham //===-- ValueObjectMemory.cpp ---------------------------------*- C++ -*-===// 278a685aaSJim Ingham // 378a685aaSJim Ingham // The LLVM Compiler Infrastructure 478a685aaSJim Ingham // 578a685aaSJim Ingham // This file is distributed under the University of Illinois Open Source 678a685aaSJim Ingham // License. See LICENSE.TXT for details. 778a685aaSJim Ingham // 878a685aaSJim Ingham //===----------------------------------------------------------------------===// 978a685aaSJim Ingham 1078a685aaSJim Ingham 1178a685aaSJim Ingham #include "lldb/Core/ValueObjectMemory.h" 1278a685aaSJim Ingham 1378a685aaSJim Ingham // C Includes 1478a685aaSJim Ingham // C++ Includes 1578a685aaSJim Ingham // Other libraries and framework includes 1678a685aaSJim Ingham // Project includes 1778a685aaSJim Ingham #include "lldb/Core/Module.h" 1878a685aaSJim Ingham #include "lldb/Core/ValueObjectList.h" 1978a685aaSJim Ingham #include "lldb/Core/Value.h" 2078a685aaSJim Ingham #include "lldb/Core/ValueObject.h" 2178a685aaSJim Ingham 2278a685aaSJim Ingham #include "lldb/Symbol/ObjectFile.h" 2378a685aaSJim Ingham #include "lldb/Symbol/SymbolContext.h" 2478a685aaSJim Ingham #include "lldb/Symbol/Type.h" 2578a685aaSJim Ingham #include "lldb/Symbol/Variable.h" 2678a685aaSJim Ingham 2778a685aaSJim Ingham #include "lldb/Target/ExecutionContext.h" 2878a685aaSJim Ingham #include "lldb/Target/Process.h" 2978a685aaSJim Ingham #include "lldb/Target/RegisterContext.h" 3078a685aaSJim Ingham #include "lldb/Target/Target.h" 3178a685aaSJim Ingham #include "lldb/Target/Thread.h" 3278a685aaSJim Ingham 3358b59f95SJim Ingham using namespace lldb; 3478a685aaSJim Ingham using namespace lldb_private; 3578a685aaSJim Ingham 3658b59f95SJim Ingham ValueObjectSP 3758b59f95SJim Ingham ValueObjectMemory::Create (ExecutionContextScope *exe_scope, 3858b59f95SJim Ingham const char *name, 3958b59f95SJim Ingham const Address &address, 4058b59f95SJim Ingham lldb::TypeSP &type_sp) 4158b59f95SJim Ingham { 4258b59f95SJim Ingham return (new ValueObjectMemory (exe_scope, name, address, type_sp))->GetSP(); 4358b59f95SJim Ingham } 4458b59f95SJim Ingham 4584c39663SGreg Clayton ValueObjectSP 4684c39663SGreg Clayton ValueObjectMemory::Create (ExecutionContextScope *exe_scope, 4784c39663SGreg Clayton const char *name, 4884c39663SGreg Clayton const Address &address, 4984c39663SGreg Clayton const ClangASTType &ast_type) 5084c39663SGreg Clayton { 5184c39663SGreg Clayton return (new ValueObjectMemory (exe_scope, name, address, ast_type))->GetSP(); 5284c39663SGreg Clayton } 5384c39663SGreg Clayton 5478a685aaSJim Ingham ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, 5578a685aaSJim Ingham const char *name, 5678a685aaSJim Ingham const Address &address, 5778a685aaSJim Ingham lldb::TypeSP &type_sp) : 5878a685aaSJim Ingham ValueObject(exe_scope), 5978a685aaSJim Ingham m_address (address), 6084c39663SGreg Clayton m_type_sp(type_sp), 6184c39663SGreg Clayton m_clang_type() 6278a685aaSJim Ingham { 6378a685aaSJim Ingham // Do not attempt to construct one of these objects with no variable! 6478a685aaSJim Ingham assert (m_type_sp.get() != NULL); 656f3533fbSEnrico Granata SetName (ConstString(name)); 6678a685aaSJim Ingham m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); 67cc4d0146SGreg Clayton TargetSP target_sp (GetTargetSP()); 68cc4d0146SGreg Clayton lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); 6978a685aaSJim Ingham if (load_address != LLDB_INVALID_ADDRESS) 7078a685aaSJim Ingham { 7178a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeLoadAddress); 7278a685aaSJim Ingham m_value.GetScalar() = load_address; 7378a685aaSJim Ingham } 7478a685aaSJim Ingham else 7578a685aaSJim Ingham { 7678a685aaSJim Ingham lldb::addr_t file_address = m_address.GetFileAddress(); 7778a685aaSJim Ingham if (file_address != LLDB_INVALID_ADDRESS) 7878a685aaSJim Ingham { 7978a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeFileAddress); 8078a685aaSJim Ingham m_value.GetScalar() = file_address; 8178a685aaSJim Ingham } 8278a685aaSJim Ingham else 8378a685aaSJim Ingham { 8478a685aaSJim Ingham m_value.GetScalar() = m_address.GetOffset(); 8578a685aaSJim Ingham m_value.SetValueType (Value::eValueTypeScalar); 8678a685aaSJim Ingham } 8778a685aaSJim Ingham } 8878a685aaSJim Ingham } 8978a685aaSJim Ingham 9084c39663SGreg Clayton ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, 9184c39663SGreg Clayton const char *name, 9284c39663SGreg Clayton const Address &address, 9384c39663SGreg Clayton const ClangASTType &ast_type) : 9484c39663SGreg Clayton ValueObject(exe_scope), 9584c39663SGreg Clayton m_address (address), 9684c39663SGreg Clayton m_type_sp(), 9784c39663SGreg Clayton m_clang_type(ast_type) 9884c39663SGreg Clayton { 9984c39663SGreg Clayton // Do not attempt to construct one of these objects with no variable! 10084c39663SGreg Clayton assert (m_clang_type.GetASTContext()); 10184c39663SGreg Clayton assert (m_clang_type.GetOpaqueQualType()); 10284c39663SGreg Clayton 103cc4d0146SGreg Clayton TargetSP target_sp (GetTargetSP()); 104cc4d0146SGreg Clayton 1056f3533fbSEnrico Granata SetName (ConstString(name)); 10684c39663SGreg Clayton m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 107cc4d0146SGreg Clayton lldb::addr_t load_address = m_address.GetLoadAddress (target_sp.get()); 10884c39663SGreg Clayton if (load_address != LLDB_INVALID_ADDRESS) 10984c39663SGreg Clayton { 11084c39663SGreg Clayton m_value.SetValueType(Value::eValueTypeLoadAddress); 11184c39663SGreg Clayton m_value.GetScalar() = load_address; 11284c39663SGreg Clayton } 11384c39663SGreg Clayton else 11484c39663SGreg Clayton { 11584c39663SGreg Clayton lldb::addr_t file_address = m_address.GetFileAddress(); 11684c39663SGreg Clayton if (file_address != LLDB_INVALID_ADDRESS) 11784c39663SGreg Clayton { 11884c39663SGreg Clayton m_value.SetValueType(Value::eValueTypeFileAddress); 11984c39663SGreg Clayton m_value.GetScalar() = file_address; 12084c39663SGreg Clayton } 12184c39663SGreg Clayton else 12284c39663SGreg Clayton { 12384c39663SGreg Clayton m_value.GetScalar() = m_address.GetOffset(); 12484c39663SGreg Clayton m_value.SetValueType (Value::eValueTypeScalar); 12584c39663SGreg Clayton } 12684c39663SGreg Clayton } 12784c39663SGreg Clayton } 12884c39663SGreg Clayton 12978a685aaSJim Ingham ValueObjectMemory::~ValueObjectMemory() 13078a685aaSJim Ingham { 13178a685aaSJim Ingham } 13278a685aaSJim Ingham 13378a685aaSJim Ingham lldb::clang_type_t 1347277284fSSean Callanan ValueObjectMemory::GetClangTypeImpl () 13578a685aaSJim Ingham { 13684c39663SGreg Clayton if (m_type_sp) 13778a685aaSJim Ingham return m_type_sp->GetClangForwardType(); 13884c39663SGreg Clayton return m_clang_type.GetOpaqueQualType(); 13978a685aaSJim Ingham } 14078a685aaSJim Ingham 14178a685aaSJim Ingham ConstString 14278a685aaSJim Ingham ValueObjectMemory::GetTypeName() 14378a685aaSJim Ingham { 14484c39663SGreg Clayton if (m_type_sp) 14578a685aaSJim Ingham return m_type_sp->GetName(); 146e3055942SGreg Clayton return ClangASTType::GetConstTypeName (m_clang_type.GetOpaqueQualType()); 14778a685aaSJim Ingham } 14878a685aaSJim Ingham 14978a685aaSJim Ingham uint32_t 15078a685aaSJim Ingham ValueObjectMemory::CalculateNumChildren() 15178a685aaSJim Ingham { 15284c39663SGreg Clayton if (m_type_sp) 15378a685aaSJim Ingham return m_type_sp->GetNumChildren(true); 15484c39663SGreg Clayton const bool omit_empty_base_classes = true; 15584c39663SGreg Clayton return ClangASTContext::GetNumChildren (m_clang_type.GetASTContext(), 15684c39663SGreg Clayton m_clang_type.GetOpaqueQualType(), 15784c39663SGreg Clayton omit_empty_base_classes); 15878a685aaSJim Ingham } 15978a685aaSJim Ingham 16078a685aaSJim Ingham clang::ASTContext * 1617277284fSSean Callanan ValueObjectMemory::GetClangASTImpl () 16278a685aaSJim Ingham { 16384c39663SGreg Clayton if (m_type_sp) 16478a685aaSJim Ingham return m_type_sp->GetClangAST(); 16584c39663SGreg Clayton return m_clang_type.GetASTContext(); 16678a685aaSJim Ingham } 16778a685aaSJim Ingham 16878a685aaSJim Ingham size_t 16978a685aaSJim Ingham ValueObjectMemory::GetByteSize() 17078a685aaSJim Ingham { 17184c39663SGreg Clayton if (m_type_sp) 17278a685aaSJim Ingham return m_type_sp->GetByteSize(); 17384c39663SGreg Clayton return (m_clang_type.GetClangTypeBitWidth () + 7) / 8; 17478a685aaSJim Ingham } 17578a685aaSJim Ingham 17678a685aaSJim Ingham lldb::ValueType 17778a685aaSJim Ingham ValueObjectMemory::GetValueType() const 17878a685aaSJim Ingham { 17978a685aaSJim Ingham // RETHINK: Should this be inherited from somewhere? 18078a685aaSJim Ingham return lldb::eValueTypeVariableGlobal; 18178a685aaSJim Ingham } 18278a685aaSJim Ingham 18378a685aaSJim Ingham bool 18478a685aaSJim Ingham ValueObjectMemory::UpdateValue () 18578a685aaSJim Ingham { 18678a685aaSJim Ingham SetValueIsValid (false); 18778a685aaSJim Ingham m_error.Clear(); 18878a685aaSJim Ingham 189cc4d0146SGreg Clayton ExecutionContext exe_ctx (GetExecutionContextRef()); 19078a685aaSJim Ingham 191c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 192c14ee32dSGreg Clayton if (target) 19378a685aaSJim Ingham { 194c14ee32dSGreg Clayton m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 195c14ee32dSGreg Clayton m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 19678a685aaSJim Ingham } 19778a685aaSJim Ingham 19878a685aaSJim Ingham Value old_value(m_value); 19978a685aaSJim Ingham if (m_address.IsValid()) 20078a685aaSJim Ingham { 20178a685aaSJim Ingham Value::ValueType value_type = m_value.GetValueType(); 20278a685aaSJim Ingham 20378a685aaSJim Ingham switch (value_type) 20478a685aaSJim Ingham { 20578a685aaSJim Ingham default: 20678a685aaSJim Ingham assert(!"Unhandled expression result value kind..."); 20778a685aaSJim Ingham break; 20878a685aaSJim Ingham 20978a685aaSJim Ingham case Value::eValueTypeScalar: 21078a685aaSJim Ingham // The variable value is in the Scalar value inside the m_value. 21178a685aaSJim Ingham // We can point our m_data right to it. 212*e72dfb32SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); 21378a685aaSJim Ingham break; 21478a685aaSJim Ingham 21578a685aaSJim Ingham case Value::eValueTypeFileAddress: 21678a685aaSJim Ingham case Value::eValueTypeLoadAddress: 21778a685aaSJim Ingham case Value::eValueTypeHostAddress: 21878a685aaSJim Ingham // The DWARF expression result was an address in the inferior 21978a685aaSJim Ingham // process. If this variable is an aggregate type, we just need 22078a685aaSJim Ingham // the address as the main value as all child variable objects 22178a685aaSJim Ingham // will rely upon this location and add an offset and then read 22278a685aaSJim Ingham // their own values as needed. If this variable is a simple 22378a685aaSJim Ingham // type, we read all data for it into m_data. 22478a685aaSJim Ingham // Make sure this type has a value before we try and read it 22578a685aaSJim Ingham 22678a685aaSJim Ingham // If we have a file address, convert it to a load address if we can. 227c14ee32dSGreg Clayton if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr()) 22878a685aaSJim Ingham { 229c14ee32dSGreg Clayton lldb::addr_t load_addr = m_address.GetLoadAddress(target); 23078a685aaSJim Ingham if (load_addr != LLDB_INVALID_ADDRESS) 23178a685aaSJim Ingham { 23278a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeLoadAddress); 23378a685aaSJim Ingham m_value.GetScalar() = load_addr; 23478a685aaSJim Ingham } 23578a685aaSJim Ingham } 23678a685aaSJim Ingham 23778a685aaSJim Ingham if (ClangASTContext::IsAggregateType (GetClangType())) 23878a685aaSJim Ingham { 23978a685aaSJim Ingham // this value object represents an aggregate type whose 24078a685aaSJim Ingham // children have values, but this object does not. So we 24178a685aaSJim Ingham // say we are changed if our location has changed. 24278a685aaSJim Ingham SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 24378a685aaSJim Ingham } 24478a685aaSJim Ingham else 24578a685aaSJim Ingham { 24678a685aaSJim Ingham // Copy the Value and set the context to use our Variable 24778a685aaSJim Ingham // so it can extract read its value into m_data appropriately 24878a685aaSJim Ingham Value value(m_value); 24984c39663SGreg Clayton if (m_type_sp) 25078a685aaSJim Ingham value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); 25184c39663SGreg Clayton else 25284c39663SGreg Clayton value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 25384c39663SGreg Clayton 254*e72dfb32SGreg Clayton m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule().get()); 25578a685aaSJim Ingham } 25678a685aaSJim Ingham break; 25778a685aaSJim Ingham } 25878a685aaSJim Ingham 25978a685aaSJim Ingham SetValueIsValid (m_error.Success()); 26078a685aaSJim Ingham } 26178a685aaSJim Ingham return m_error.Success(); 26278a685aaSJim Ingham } 26378a685aaSJim Ingham 26478a685aaSJim Ingham 26578a685aaSJim Ingham 26678a685aaSJim Ingham bool 26778a685aaSJim Ingham ValueObjectMemory::IsInScope () 26878a685aaSJim Ingham { 26978a685aaSJim Ingham // FIXME: Maybe try to read the memory address, and if that works, then 27078a685aaSJim Ingham // we are in scope? 27178a685aaSJim Ingham return true; 27278a685aaSJim Ingham } 27378a685aaSJim Ingham 274644247c1SGreg Clayton 275*e72dfb32SGreg Clayton lldb::ModuleSP 276644247c1SGreg Clayton ValueObjectMemory::GetModule() 277644247c1SGreg Clayton { 278*e72dfb32SGreg Clayton return m_address.GetModule(); 279644247c1SGreg Clayton } 280644247c1SGreg Clayton 281644247c1SGreg Clayton 282