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)); 10657ee3067SGreg Clayton // m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 10757ee3067SGreg 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 13457ee3067SGreg Clayton ClangASTType 1357277284fSSean Callanan ValueObjectMemory::GetClangTypeImpl () 13678a685aaSJim Ingham { 13784c39663SGreg Clayton if (m_type_sp) 13878a685aaSJim Ingham return m_type_sp->GetClangForwardType(); 13957ee3067SGreg 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(); 14757ee3067SGreg Clayton return m_clang_type.GetConstTypeName(); 14878a685aaSJim Ingham } 14978a685aaSJim Ingham 150e8daa2f8SEnrico Granata ConstString 151e8daa2f8SEnrico Granata ValueObjectMemory::GetDisplayTypeName() 152e8daa2f8SEnrico Granata { 153e8daa2f8SEnrico Granata if (m_type_sp) 154e8daa2f8SEnrico Granata return m_type_sp->GetClangForwardType().GetDisplayTypeName(); 155e8daa2f8SEnrico Granata return m_clang_type.GetDisplayTypeName(); 156e8daa2f8SEnrico Granata } 157e8daa2f8SEnrico Granata 158c7bece56SGreg Clayton size_t 15978a685aaSJim Ingham ValueObjectMemory::CalculateNumChildren() 16078a685aaSJim Ingham { 16184c39663SGreg Clayton if (m_type_sp) 16278a685aaSJim Ingham return m_type_sp->GetNumChildren(true); 16384c39663SGreg Clayton const bool omit_empty_base_classes = true; 16457ee3067SGreg Clayton return m_clang_type.GetNumChildren (omit_empty_base_classes); 16578a685aaSJim Ingham } 16678a685aaSJim Ingham 167faac1118SGreg Clayton uint64_t 16878a685aaSJim Ingham ValueObjectMemory::GetByteSize() 16978a685aaSJim Ingham { 17084c39663SGreg Clayton if (m_type_sp) 17178a685aaSJim Ingham return m_type_sp->GetByteSize(); 17257ee3067SGreg Clayton return m_clang_type.GetByteSize (); 17378a685aaSJim Ingham } 17478a685aaSJim Ingham 17578a685aaSJim Ingham lldb::ValueType 17678a685aaSJim Ingham ValueObjectMemory::GetValueType() const 17778a685aaSJim Ingham { 17878a685aaSJim Ingham // RETHINK: Should this be inherited from somewhere? 17978a685aaSJim Ingham return lldb::eValueTypeVariableGlobal; 18078a685aaSJim Ingham } 18178a685aaSJim Ingham 18278a685aaSJim Ingham bool 18378a685aaSJim Ingham ValueObjectMemory::UpdateValue () 18478a685aaSJim Ingham { 18578a685aaSJim Ingham SetValueIsValid (false); 18678a685aaSJim Ingham m_error.Clear(); 18778a685aaSJim Ingham 188cc4d0146SGreg Clayton ExecutionContext exe_ctx (GetExecutionContextRef()); 18978a685aaSJim Ingham 190c14ee32dSGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 191c14ee32dSGreg Clayton if (target) 19278a685aaSJim Ingham { 193c14ee32dSGreg Clayton m_data.SetByteOrder(target->GetArchitecture().GetByteOrder()); 194c14ee32dSGreg Clayton m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize()); 19578a685aaSJim Ingham } 19678a685aaSJim Ingham 19778a685aaSJim Ingham Value old_value(m_value); 19878a685aaSJim Ingham if (m_address.IsValid()) 19978a685aaSJim Ingham { 20078a685aaSJim Ingham Value::ValueType value_type = m_value.GetValueType(); 20178a685aaSJim Ingham 20278a685aaSJim Ingham switch (value_type) 20378a685aaSJim Ingham { 20478a685aaSJim Ingham default: 20578a685aaSJim Ingham assert(!"Unhandled expression result value kind..."); 20678a685aaSJim Ingham break; 20778a685aaSJim Ingham 20878a685aaSJim Ingham case Value::eValueTypeScalar: 20978a685aaSJim Ingham // The variable value is in the Scalar value inside the m_value. 21078a685aaSJim Ingham // We can point our m_data right to it. 21157ee3067SGreg Clayton m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); 21278a685aaSJim Ingham break; 21378a685aaSJim Ingham 21478a685aaSJim Ingham case Value::eValueTypeFileAddress: 21578a685aaSJim Ingham case Value::eValueTypeLoadAddress: 21678a685aaSJim Ingham case Value::eValueTypeHostAddress: 21778a685aaSJim Ingham // The DWARF expression result was an address in the inferior 21878a685aaSJim Ingham // process. If this variable is an aggregate type, we just need 21978a685aaSJim Ingham // the address as the main value as all child variable objects 22078a685aaSJim Ingham // will rely upon this location and add an offset and then read 22178a685aaSJim Ingham // their own values as needed. If this variable is a simple 22278a685aaSJim Ingham // type, we read all data for it into m_data. 22378a685aaSJim Ingham // Make sure this type has a value before we try and read it 22478a685aaSJim Ingham 22578a685aaSJim Ingham // If we have a file address, convert it to a load address if we can. 226c14ee32dSGreg Clayton if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr()) 22778a685aaSJim Ingham { 228c14ee32dSGreg Clayton lldb::addr_t load_addr = m_address.GetLoadAddress(target); 22978a685aaSJim Ingham if (load_addr != LLDB_INVALID_ADDRESS) 23078a685aaSJim Ingham { 23178a685aaSJim Ingham m_value.SetValueType(Value::eValueTypeLoadAddress); 23278a685aaSJim Ingham m_value.GetScalar() = load_addr; 23378a685aaSJim Ingham } 23478a685aaSJim Ingham } 23578a685aaSJim Ingham 236*d07cfd3aSEnrico Granata if (!CanProvideValue()) 23778a685aaSJim Ingham { 23878a685aaSJim Ingham // this value object represents an aggregate type whose 23978a685aaSJim Ingham // children have values, but this object does not. So we 24078a685aaSJim Ingham // say we are changed if our location has changed. 24178a685aaSJim Ingham SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar()); 24278a685aaSJim Ingham } 24378a685aaSJim Ingham else 24478a685aaSJim Ingham { 24578a685aaSJim Ingham // Copy the Value and set the context to use our Variable 24678a685aaSJim Ingham // so it can extract read its value into m_data appropriately 24778a685aaSJim Ingham Value value(m_value); 24884c39663SGreg Clayton if (m_type_sp) 24978a685aaSJim Ingham value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); 25084c39663SGreg Clayton else 25157ee3067SGreg Clayton { 25257ee3067SGreg Clayton //value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); 25357ee3067SGreg Clayton value.SetClangType(m_clang_type); 25457ee3067SGreg Clayton } 25584c39663SGreg Clayton 25657ee3067SGreg Clayton m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); 25778a685aaSJim Ingham } 25878a685aaSJim Ingham break; 25978a685aaSJim Ingham } 26078a685aaSJim Ingham 26178a685aaSJim Ingham SetValueIsValid (m_error.Success()); 26278a685aaSJim Ingham } 26378a685aaSJim Ingham return m_error.Success(); 26478a685aaSJim Ingham } 26578a685aaSJim Ingham 26678a685aaSJim Ingham 26778a685aaSJim Ingham 26878a685aaSJim Ingham bool 26978a685aaSJim Ingham ValueObjectMemory::IsInScope () 27078a685aaSJim Ingham { 27178a685aaSJim Ingham // FIXME: Maybe try to read the memory address, and if that works, then 27278a685aaSJim Ingham // we are in scope? 27378a685aaSJim Ingham return true; 27478a685aaSJim Ingham } 27578a685aaSJim Ingham 276644247c1SGreg Clayton 277e72dfb32SGreg Clayton lldb::ModuleSP 278644247c1SGreg Clayton ValueObjectMemory::GetModule() 279644247c1SGreg Clayton { 280e72dfb32SGreg Clayton return m_address.GetModule(); 281644247c1SGreg Clayton } 282644247c1SGreg Clayton 283644247c1SGreg Clayton 284