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