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()); 676f3533fbSEnrico Granata lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTargetSP().get()); 6878a685aaSJim Ingham if (load_address != LLDB_INVALID_ADDRESS) 6978a685aaSJim Ingham { 7078a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeLoadAddress); 7178a685aaSJim Ingham m_value.GetScalar() = load_address; 7278a685aaSJim Ingham } 7378a685aaSJim Ingham else 7478a685aaSJim Ingham { 7578a685aaSJim Ingham lldb::addr_t file_address = m_address.GetFileAddress(); 7678a685aaSJim Ingham if (file_address != LLDB_INVALID_ADDRESS) 7778a685aaSJim Ingham { 7878a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeFileAddress); 7978a685aaSJim Ingham m_value.GetScalar() = file_address; 8078a685aaSJim Ingham } 8178a685aaSJim Ingham else 8278a685aaSJim Ingham { 8378a685aaSJim Ingham m_value.GetScalar() = m_address.GetOffset(); 8478a685aaSJim Ingham m_value.SetValueType (Value::eValueTypeScalar); 8578a685aaSJim Ingham } 8678a685aaSJim Ingham } 8778a685aaSJim Ingham } 8878a685aaSJim Ingham 8984c39663SGreg Clayton ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, 9084c39663SGreg Clayton const char *name, 9184c39663SGreg Clayton const Address &address, 9284c39663SGreg Clayton const ClangASTType &ast_type) : 9384c39663SGreg Clayton ValueObject(exe_scope), 9484c39663SGreg Clayton m_address (address), 9584c39663SGreg Clayton m_type_sp(), 9684c39663SGreg Clayton m_clang_type(ast_type) 9784c39663SGreg Clayton { 9884c39663SGreg Clayton // Do not attempt to construct one of these objects with no variable! 9984c39663SGreg Clayton assert (m_clang_type.GetASTContext()); 10084c39663SGreg Clayton assert (m_clang_type.GetOpaqueQualType()); 10184c39663SGreg Clayton 1026f3533fbSEnrico Granata SetName (ConstString(name)); 10384c39663SGreg Clayton m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 1046f3533fbSEnrico Granata lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTargetSP().get()); 10584c39663SGreg Clayton if (load_address != LLDB_INVALID_ADDRESS) 10684c39663SGreg Clayton { 10784c39663SGreg Clayton m_value.SetValueType(Value::eValueTypeLoadAddress); 10884c39663SGreg Clayton m_value.GetScalar() = load_address; 10984c39663SGreg Clayton } 11084c39663SGreg Clayton else 11184c39663SGreg Clayton { 11284c39663SGreg Clayton lldb::addr_t file_address = m_address.GetFileAddress(); 11384c39663SGreg Clayton if (file_address != LLDB_INVALID_ADDRESS) 11484c39663SGreg Clayton { 11584c39663SGreg Clayton m_value.SetValueType(Value::eValueTypeFileAddress); 11684c39663SGreg Clayton m_value.GetScalar() = file_address; 11784c39663SGreg Clayton } 11884c39663SGreg Clayton else 11984c39663SGreg Clayton { 12084c39663SGreg Clayton m_value.GetScalar() = m_address.GetOffset(); 12184c39663SGreg Clayton m_value.SetValueType (Value::eValueTypeScalar); 12284c39663SGreg Clayton } 12384c39663SGreg Clayton } 12484c39663SGreg Clayton } 12584c39663SGreg Clayton 12678a685aaSJim Ingham ValueObjectMemory::~ValueObjectMemory() 12778a685aaSJim Ingham { 12878a685aaSJim Ingham } 12978a685aaSJim Ingham 13078a685aaSJim Ingham lldb::clang_type_t 13178a685aaSJim Ingham ValueObjectMemory::GetClangType () 13278a685aaSJim Ingham { 13384c39663SGreg Clayton if (m_type_sp) 13478a685aaSJim Ingham return m_type_sp->GetClangForwardType(); 13584c39663SGreg Clayton return m_clang_type.GetOpaqueQualType(); 13678a685aaSJim Ingham } 13778a685aaSJim Ingham 13878a685aaSJim Ingham ConstString 13978a685aaSJim Ingham ValueObjectMemory::GetTypeName() 14078a685aaSJim Ingham { 14184c39663SGreg Clayton if (m_type_sp) 14278a685aaSJim Ingham return m_type_sp->GetName(); 143e3055942SGreg Clayton return ClangASTType::GetConstTypeName (m_clang_type.GetOpaqueQualType()); 14478a685aaSJim Ingham } 14578a685aaSJim Ingham 14678a685aaSJim Ingham uint32_t 14778a685aaSJim Ingham ValueObjectMemory::CalculateNumChildren() 14878a685aaSJim Ingham { 14984c39663SGreg Clayton if (m_type_sp) 15078a685aaSJim Ingham return m_type_sp->GetNumChildren(true); 15184c39663SGreg Clayton const bool omit_empty_base_classes = true; 15284c39663SGreg Clayton return ClangASTContext::GetNumChildren (m_clang_type.GetASTContext(), 15384c39663SGreg Clayton m_clang_type.GetOpaqueQualType(), 15484c39663SGreg Clayton omit_empty_base_classes); 15578a685aaSJim Ingham } 15678a685aaSJim Ingham 15778a685aaSJim Ingham clang::ASTContext * 15878a685aaSJim Ingham ValueObjectMemory::GetClangAST () 15978a685aaSJim Ingham { 16084c39663SGreg Clayton if (m_type_sp) 16178a685aaSJim Ingham return m_type_sp->GetClangAST(); 16284c39663SGreg Clayton return m_clang_type.GetASTContext(); 16378a685aaSJim Ingham } 16478a685aaSJim Ingham 16578a685aaSJim Ingham size_t 16678a685aaSJim Ingham ValueObjectMemory::GetByteSize() 16778a685aaSJim Ingham { 16884c39663SGreg Clayton if (m_type_sp) 16978a685aaSJim Ingham return m_type_sp->GetByteSize(); 17084c39663SGreg Clayton return (m_clang_type.GetClangTypeBitWidth () + 7) / 8; 17178a685aaSJim Ingham } 17278a685aaSJim Ingham 17378a685aaSJim Ingham lldb::ValueType 17478a685aaSJim Ingham ValueObjectMemory::GetValueType() const 17578a685aaSJim Ingham { 17678a685aaSJim Ingham // RETHINK: Should this be inherited from somewhere? 17778a685aaSJim Ingham return lldb::eValueTypeVariableGlobal; 17878a685aaSJim Ingham } 17978a685aaSJim Ingham 18078a685aaSJim Ingham bool 18178a685aaSJim Ingham ValueObjectMemory::UpdateValue () 18278a685aaSJim Ingham { 18378a685aaSJim Ingham SetValueIsValid (false); 18478a685aaSJim Ingham m_error.Clear(); 18578a685aaSJim Ingham 18678a685aaSJim Ingham ExecutionContext exe_ctx (GetExecutionContextScope()); 18778a685aaSJim Ingham 188c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 189c14ee32dSGreg Clayton if (target) 19078a685aaSJim Ingham { 191c14ee32dSGreg Clayton m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 192c14ee32dSGreg Clayton m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 19378a685aaSJim Ingham } 19478a685aaSJim Ingham 19578a685aaSJim Ingham Value old_value(m_value); 19678a685aaSJim Ingham if (m_address.IsValid()) 19778a685aaSJim Ingham { 19878a685aaSJim Ingham Value::ValueType value_type = m_value.GetValueType(); 19978a685aaSJim Ingham 20078a685aaSJim Ingham switch (value_type) 20178a685aaSJim Ingham { 20278a685aaSJim Ingham default: 20378a685aaSJim Ingham assert(!"Unhandled expression result value kind..."); 20478a685aaSJim Ingham break; 20578a685aaSJim Ingham 20678a685aaSJim Ingham case Value::eValueTypeScalar: 20778a685aaSJim Ingham // The variable value is in the Scalar value inside the m_value. 20878a685aaSJim Ingham // We can point our m_data right to it. 209644247c1SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule()); 21078a685aaSJim Ingham break; 21178a685aaSJim Ingham 21278a685aaSJim Ingham case Value::eValueTypeFileAddress: 21378a685aaSJim Ingham case Value::eValueTypeLoadAddress: 21478a685aaSJim Ingham case Value::eValueTypeHostAddress: 21578a685aaSJim Ingham // The DWARF expression result was an address in the inferior 21678a685aaSJim Ingham // process. If this variable is an aggregate type, we just need 21778a685aaSJim Ingham // the address as the main value as all child variable objects 21878a685aaSJim Ingham // will rely upon this location and add an offset and then read 21978a685aaSJim Ingham // their own values as needed. If this variable is a simple 22078a685aaSJim Ingham // type, we read all data for it into m_data. 22178a685aaSJim Ingham // Make sure this type has a value before we try and read it 22278a685aaSJim Ingham 22378a685aaSJim Ingham // If we have a file address, convert it to a load address if we can. 224c14ee32dSGreg Clayton if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr()) 22578a685aaSJim Ingham { 226c14ee32dSGreg Clayton lldb::addr_t load_addr = m_address.GetLoadAddress(target); 22778a685aaSJim Ingham if (load_addr != LLDB_INVALID_ADDRESS) 22878a685aaSJim Ingham { 22978a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeLoadAddress); 23078a685aaSJim Ingham m_value.GetScalar() = load_addr; 23178a685aaSJim Ingham } 23278a685aaSJim Ingham } 23378a685aaSJim Ingham 23478a685aaSJim Ingham if (ClangASTContext::IsAggregateType (GetClangType())) 23578a685aaSJim Ingham { 23678a685aaSJim Ingham // this value object represents an aggregate type whose 23778a685aaSJim Ingham // children have values, but this object does not. So we 23878a685aaSJim Ingham // say we are changed if our location has changed. 23978a685aaSJim Ingham SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 24078a685aaSJim Ingham } 24178a685aaSJim Ingham else 24278a685aaSJim Ingham { 24378a685aaSJim Ingham // Copy the Value and set the context to use our Variable 24478a685aaSJim Ingham // so it can extract read its value into m_data appropriately 24578a685aaSJim Ingham Value value(m_value); 24684c39663SGreg Clayton if (m_type_sp) 24778a685aaSJim Ingham value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); 24884c39663SGreg Clayton else 24984c39663SGreg Clayton value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 25084c39663SGreg Clayton 251644247c1SGreg Clayton m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0, GetModule()); 25278a685aaSJim Ingham } 25378a685aaSJim Ingham break; 25478a685aaSJim Ingham } 25578a685aaSJim Ingham 25678a685aaSJim Ingham SetValueIsValid (m_error.Success()); 25778a685aaSJim Ingham } 25878a685aaSJim Ingham return m_error.Success(); 25978a685aaSJim Ingham } 26078a685aaSJim Ingham 26178a685aaSJim Ingham 26278a685aaSJim Ingham 26378a685aaSJim Ingham bool 26478a685aaSJim Ingham ValueObjectMemory::IsInScope () 26578a685aaSJim Ingham { 26678a685aaSJim Ingham // FIXME: Maybe try to read the memory address, and if that works, then 26778a685aaSJim Ingham // we are in scope? 26878a685aaSJim Ingham return true; 26978a685aaSJim Ingham } 27078a685aaSJim Ingham 271644247c1SGreg Clayton 272644247c1SGreg Clayton Module * 273644247c1SGreg Clayton ValueObjectMemory::GetModule() 274644247c1SGreg Clayton { 275*e1cd1be6SGreg Clayton return m_address.GetModulePtr(); 276644247c1SGreg Clayton } 277644247c1SGreg Clayton 278644247c1SGreg Clayton 279