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)); 106*57ee3067SGreg Clayton // m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 107*57ee3067SGreg Clayton m_value.SetClangType(m_clang_type); 108cc4d0146SGreg Clayton lldb::addr_t load_address = m_address.GetLoadAddress (target_sp.get()); 10984c39663SGreg Clayton if (load_address != LLDB_INVALID_ADDRESS) 11084c39663SGreg Clayton { 11184c39663SGreg Clayton m_value.SetValueType(Value::eValueTypeLoadAddress); 11284c39663SGreg Clayton m_value.GetScalar() = load_address; 11384c39663SGreg Clayton } 11484c39663SGreg Clayton else 11584c39663SGreg Clayton { 11684c39663SGreg Clayton lldb::addr_t file_address = m_address.GetFileAddress(); 11784c39663SGreg Clayton if (file_address != LLDB_INVALID_ADDRESS) 11884c39663SGreg Clayton { 11984c39663SGreg Clayton m_value.SetValueType(Value::eValueTypeFileAddress); 12084c39663SGreg Clayton m_value.GetScalar() = file_address; 12184c39663SGreg Clayton } 12284c39663SGreg Clayton else 12384c39663SGreg Clayton { 12484c39663SGreg Clayton m_value.GetScalar() = m_address.GetOffset(); 12584c39663SGreg Clayton m_value.SetValueType (Value::eValueTypeScalar); 12684c39663SGreg Clayton } 12784c39663SGreg Clayton } 12884c39663SGreg Clayton } 12984c39663SGreg Clayton 13078a685aaSJim Ingham ValueObjectMemory::~ValueObjectMemory() 13178a685aaSJim Ingham { 13278a685aaSJim Ingham } 13378a685aaSJim Ingham 134*57ee3067SGreg Clayton ClangASTType 1357277284fSSean Callanan ValueObjectMemory::GetClangTypeImpl () 13678a685aaSJim Ingham { 13784c39663SGreg Clayton if (m_type_sp) 13878a685aaSJim Ingham return m_type_sp->GetClangForwardType(); 139*57ee3067SGreg Clayton return m_clang_type; 14078a685aaSJim Ingham } 14178a685aaSJim Ingham 14278a685aaSJim Ingham ConstString 14378a685aaSJim Ingham ValueObjectMemory::GetTypeName() 14478a685aaSJim Ingham { 14584c39663SGreg Clayton if (m_type_sp) 14678a685aaSJim Ingham return m_type_sp->GetName(); 147*57ee3067SGreg Clayton return m_clang_type.GetConstTypeName(); 14878a685aaSJim Ingham } 14978a685aaSJim Ingham 150c7bece56SGreg Clayton size_t 15178a685aaSJim Ingham ValueObjectMemory::CalculateNumChildren() 15278a685aaSJim Ingham { 15384c39663SGreg Clayton if (m_type_sp) 15478a685aaSJim Ingham return m_type_sp->GetNumChildren(true); 15584c39663SGreg Clayton const bool omit_empty_base_classes = true; 156*57ee3067SGreg Clayton return m_clang_type.GetNumChildren (omit_empty_base_classes); 15778a685aaSJim Ingham } 15878a685aaSJim Ingham 159faac1118SGreg Clayton uint64_t 16078a685aaSJim Ingham ValueObjectMemory::GetByteSize() 16178a685aaSJim Ingham { 16284c39663SGreg Clayton if (m_type_sp) 16378a685aaSJim Ingham return m_type_sp->GetByteSize(); 164*57ee3067SGreg Clayton return m_clang_type.GetByteSize (); 16578a685aaSJim Ingham } 16678a685aaSJim Ingham 16778a685aaSJim Ingham lldb::ValueType 16878a685aaSJim Ingham ValueObjectMemory::GetValueType() const 16978a685aaSJim Ingham { 17078a685aaSJim Ingham // RETHINK: Should this be inherited from somewhere? 17178a685aaSJim Ingham return lldb::eValueTypeVariableGlobal; 17278a685aaSJim Ingham } 17378a685aaSJim Ingham 17478a685aaSJim Ingham bool 17578a685aaSJim Ingham ValueObjectMemory::UpdateValue () 17678a685aaSJim Ingham { 17778a685aaSJim Ingham SetValueIsValid (false); 17878a685aaSJim Ingham m_error.Clear(); 17978a685aaSJim Ingham 180cc4d0146SGreg Clayton ExecutionContext exe_ctx (GetExecutionContextRef()); 18178a685aaSJim Ingham 182c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 183c14ee32dSGreg Clayton if (target) 18478a685aaSJim Ingham { 185c14ee32dSGreg Clayton m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 186c14ee32dSGreg Clayton m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 18778a685aaSJim Ingham } 18878a685aaSJim Ingham 18978a685aaSJim Ingham Value old_value(m_value); 19078a685aaSJim Ingham if (m_address.IsValid()) 19178a685aaSJim Ingham { 19278a685aaSJim Ingham Value::ValueType value_type = m_value.GetValueType(); 19378a685aaSJim Ingham 19478a685aaSJim Ingham switch (value_type) 19578a685aaSJim Ingham { 19678a685aaSJim Ingham default: 19778a685aaSJim Ingham assert(!"Unhandled expression result value kind..."); 19878a685aaSJim Ingham break; 19978a685aaSJim Ingham 20078a685aaSJim Ingham case Value::eValueTypeScalar: 20178a685aaSJim Ingham // The variable value is in the Scalar value inside the m_value. 20278a685aaSJim Ingham // We can point our m_data right to it. 203*57ee3067SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 20478a685aaSJim Ingham break; 20578a685aaSJim Ingham 20678a685aaSJim Ingham case Value::eValueTypeFileAddress: 20778a685aaSJim Ingham case Value::eValueTypeLoadAddress: 20878a685aaSJim Ingham case Value::eValueTypeHostAddress: 20978a685aaSJim Ingham // The DWARF expression result was an address in the inferior 21078a685aaSJim Ingham // process. If this variable is an aggregate type, we just need 21178a685aaSJim Ingham // the address as the main value as all child variable objects 21278a685aaSJim Ingham // will rely upon this location and add an offset and then read 21378a685aaSJim Ingham // their own values as needed. If this variable is a simple 21478a685aaSJim Ingham // type, we read all data for it into m_data. 21578a685aaSJim Ingham // Make sure this type has a value before we try and read it 21678a685aaSJim Ingham 21778a685aaSJim Ingham // If we have a file address, convert it to a load address if we can. 218c14ee32dSGreg Clayton if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr()) 21978a685aaSJim Ingham { 220c14ee32dSGreg Clayton lldb::addr_t load_addr = m_address.GetLoadAddress(target); 22178a685aaSJim Ingham if (load_addr != LLDB_INVALID_ADDRESS) 22278a685aaSJim Ingham { 22378a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeLoadAddress); 22478a685aaSJim Ingham m_value.GetScalar() = load_addr; 22578a685aaSJim Ingham } 22678a685aaSJim Ingham } 22778a685aaSJim Ingham 228*57ee3067SGreg Clayton if (GetClangType().IsAggregateType()) 22978a685aaSJim Ingham { 23078a685aaSJim Ingham // this value object represents an aggregate type whose 23178a685aaSJim Ingham // children have values, but this object does not. So we 23278a685aaSJim Ingham // say we are changed if our location has changed. 23378a685aaSJim Ingham SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 23478a685aaSJim Ingham } 23578a685aaSJim Ingham else 23678a685aaSJim Ingham { 23778a685aaSJim Ingham // Copy the Value and set the context to use our Variable 23878a685aaSJim Ingham // so it can extract read its value into m_data appropriately 23978a685aaSJim Ingham Value value(m_value); 24084c39663SGreg Clayton if (m_type_sp) 24178a685aaSJim Ingham value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); 24284c39663SGreg Clayton else 243*57ee3067SGreg Clayton { 244*57ee3067SGreg Clayton //value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 245*57ee3067SGreg Clayton value.SetClangType(m_clang_type); 246*57ee3067SGreg Clayton } 24784c39663SGreg Clayton 248*57ee3067SGreg Clayton m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); 24978a685aaSJim Ingham } 25078a685aaSJim Ingham break; 25178a685aaSJim Ingham } 25278a685aaSJim Ingham 25378a685aaSJim Ingham SetValueIsValid (m_error.Success()); 25478a685aaSJim Ingham } 25578a685aaSJim Ingham return m_error.Success(); 25678a685aaSJim Ingham } 25778a685aaSJim Ingham 25878a685aaSJim Ingham 25978a685aaSJim Ingham 26078a685aaSJim Ingham bool 26178a685aaSJim Ingham ValueObjectMemory::IsInScope () 26278a685aaSJim Ingham { 26378a685aaSJim Ingham // FIXME: Maybe try to read the memory address, and if that works, then 26478a685aaSJim Ingham // we are in scope? 26578a685aaSJim Ingham return true; 26678a685aaSJim Ingham } 26778a685aaSJim Ingham 268644247c1SGreg Clayton 269e72dfb32SGreg Clayton lldb::ModuleSP 270644247c1SGreg Clayton ValueObjectMemory::GetModule() 271644247c1SGreg Clayton { 272e72dfb32SGreg Clayton return m_address.GetModule(); 273644247c1SGreg Clayton } 274644247c1SGreg Clayton 275644247c1SGreg Clayton 276