1*78a685aaSJim Ingham //===-- ValueObjectMemory.cpp ---------------------------------*- C++ -*-===//
2*78a685aaSJim Ingham //
3*78a685aaSJim Ingham //                     The LLVM Compiler Infrastructure
4*78a685aaSJim Ingham //
5*78a685aaSJim Ingham // This file is distributed under the University of Illinois Open Source
6*78a685aaSJim Ingham // License. See LICENSE.TXT for details.
7*78a685aaSJim Ingham //
8*78a685aaSJim Ingham //===----------------------------------------------------------------------===//
9*78a685aaSJim Ingham 
10*78a685aaSJim Ingham 
11*78a685aaSJim Ingham #include "lldb/Core/ValueObjectMemory.h"
12*78a685aaSJim Ingham 
13*78a685aaSJim Ingham // C Includes
14*78a685aaSJim Ingham // C++ Includes
15*78a685aaSJim Ingham // Other libraries and framework includes
16*78a685aaSJim Ingham // Project includes
17*78a685aaSJim Ingham #include "lldb/Core/Module.h"
18*78a685aaSJim Ingham #include "lldb/Core/ValueObjectList.h"
19*78a685aaSJim Ingham #include "lldb/Core/Value.h"
20*78a685aaSJim Ingham #include "lldb/Core/ValueObject.h"
21*78a685aaSJim Ingham 
22*78a685aaSJim Ingham #include "lldb/Symbol/ObjectFile.h"
23*78a685aaSJim Ingham #include "lldb/Symbol/SymbolContext.h"
24*78a685aaSJim Ingham #include "lldb/Symbol/Type.h"
25*78a685aaSJim Ingham #include "lldb/Symbol/Variable.h"
26*78a685aaSJim Ingham 
27*78a685aaSJim Ingham #include "lldb/Target/ExecutionContext.h"
28*78a685aaSJim Ingham #include "lldb/Target/Process.h"
29*78a685aaSJim Ingham #include "lldb/Target/RegisterContext.h"
30*78a685aaSJim Ingham #include "lldb/Target/Target.h"
31*78a685aaSJim Ingham #include "lldb/Target/Thread.h"
32*78a685aaSJim Ingham 
33*78a685aaSJim Ingham 
34*78a685aaSJim Ingham using namespace lldb_private;
35*78a685aaSJim Ingham 
36*78a685aaSJim Ingham ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
37*78a685aaSJim Ingham                                       const char *name,
38*78a685aaSJim Ingham                                       const Address &address,
39*78a685aaSJim Ingham                                       lldb::TypeSP &type_sp) :
40*78a685aaSJim Ingham     ValueObject(exe_scope),
41*78a685aaSJim Ingham     m_address (address),
42*78a685aaSJim Ingham     m_type_sp(type_sp)
43*78a685aaSJim Ingham {
44*78a685aaSJim Ingham     // Do not attempt to construct one of these objects with no variable!
45*78a685aaSJim Ingham     assert (m_type_sp.get() != NULL);
46*78a685aaSJim Ingham     SetName (name);
47*78a685aaSJim Ingham     m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
48*78a685aaSJim Ingham     lldb::addr_t load_address = m_address.GetLoadAddress(m_update_point.GetTarget());
49*78a685aaSJim Ingham     if (load_address != LLDB_INVALID_ADDRESS)
50*78a685aaSJim Ingham     {
51*78a685aaSJim Ingham         m_value.SetValueType(Value::eValueTypeLoadAddress);
52*78a685aaSJim Ingham         m_value.GetScalar() = load_address;
53*78a685aaSJim Ingham     }
54*78a685aaSJim Ingham     else
55*78a685aaSJim Ingham     {
56*78a685aaSJim Ingham         lldb::addr_t file_address = m_address.GetFileAddress();
57*78a685aaSJim Ingham         if (file_address != LLDB_INVALID_ADDRESS)
58*78a685aaSJim Ingham         {
59*78a685aaSJim Ingham             m_value.SetValueType(Value::eValueTypeFileAddress);
60*78a685aaSJim Ingham             m_value.GetScalar() = file_address;
61*78a685aaSJim Ingham         }
62*78a685aaSJim Ingham         else
63*78a685aaSJim Ingham         {
64*78a685aaSJim Ingham             m_value.GetScalar() = m_address.GetOffset();
65*78a685aaSJim Ingham             m_value.SetValueType (Value::eValueTypeScalar);
66*78a685aaSJim Ingham         }
67*78a685aaSJim Ingham     }
68*78a685aaSJim Ingham }
69*78a685aaSJim Ingham 
70*78a685aaSJim Ingham ValueObjectMemory::~ValueObjectMemory()
71*78a685aaSJim Ingham {
72*78a685aaSJim Ingham }
73*78a685aaSJim Ingham 
74*78a685aaSJim Ingham lldb::clang_type_t
75*78a685aaSJim Ingham ValueObjectMemory::GetClangType ()
76*78a685aaSJim Ingham {
77*78a685aaSJim Ingham     return m_type_sp->GetClangForwardType();
78*78a685aaSJim Ingham }
79*78a685aaSJim Ingham 
80*78a685aaSJim Ingham ConstString
81*78a685aaSJim Ingham ValueObjectMemory::GetTypeName()
82*78a685aaSJim Ingham {
83*78a685aaSJim Ingham     return m_type_sp->GetName();
84*78a685aaSJim Ingham }
85*78a685aaSJim Ingham 
86*78a685aaSJim Ingham uint32_t
87*78a685aaSJim Ingham ValueObjectMemory::CalculateNumChildren()
88*78a685aaSJim Ingham {
89*78a685aaSJim Ingham     return m_type_sp->GetNumChildren(true);
90*78a685aaSJim Ingham }
91*78a685aaSJim Ingham 
92*78a685aaSJim Ingham clang::ASTContext *
93*78a685aaSJim Ingham ValueObjectMemory::GetClangAST ()
94*78a685aaSJim Ingham {
95*78a685aaSJim Ingham     return m_type_sp->GetClangAST();
96*78a685aaSJim Ingham }
97*78a685aaSJim Ingham 
98*78a685aaSJim Ingham size_t
99*78a685aaSJim Ingham ValueObjectMemory::GetByteSize()
100*78a685aaSJim Ingham {
101*78a685aaSJim Ingham     return m_type_sp->GetByteSize();
102*78a685aaSJim Ingham }
103*78a685aaSJim Ingham 
104*78a685aaSJim Ingham lldb::ValueType
105*78a685aaSJim Ingham ValueObjectMemory::GetValueType() const
106*78a685aaSJim Ingham {
107*78a685aaSJim Ingham     // RETHINK: Should this be inherited from somewhere?
108*78a685aaSJim Ingham     return lldb::eValueTypeVariableGlobal;
109*78a685aaSJim Ingham }
110*78a685aaSJim Ingham 
111*78a685aaSJim Ingham bool
112*78a685aaSJim Ingham ValueObjectMemory::UpdateValue ()
113*78a685aaSJim Ingham {
114*78a685aaSJim Ingham     SetValueIsValid (false);
115*78a685aaSJim Ingham     m_error.Clear();
116*78a685aaSJim Ingham 
117*78a685aaSJim Ingham     ExecutionContext exe_ctx (GetExecutionContextScope());
118*78a685aaSJim Ingham 
119*78a685aaSJim Ingham     if (exe_ctx.target)
120*78a685aaSJim Ingham     {
121*78a685aaSJim Ingham         m_data.SetByteOrder(exe_ctx.target->GetArchitecture().GetByteOrder());
122*78a685aaSJim Ingham         m_data.SetAddressByteSize(exe_ctx.target->GetArchitecture().GetAddressByteSize());
123*78a685aaSJim Ingham     }
124*78a685aaSJim Ingham 
125*78a685aaSJim Ingham     Value old_value(m_value);
126*78a685aaSJim Ingham     if (m_address.IsValid())
127*78a685aaSJim Ingham     {
128*78a685aaSJim Ingham         Value::ValueType value_type = m_value.GetValueType();
129*78a685aaSJim Ingham 
130*78a685aaSJim Ingham         switch (value_type)
131*78a685aaSJim Ingham         {
132*78a685aaSJim Ingham         default:
133*78a685aaSJim Ingham             assert(!"Unhandled expression result value kind...");
134*78a685aaSJim Ingham             break;
135*78a685aaSJim Ingham 
136*78a685aaSJim Ingham         case Value::eValueTypeScalar:
137*78a685aaSJim Ingham             // The variable value is in the Scalar value inside the m_value.
138*78a685aaSJim Ingham             // We can point our m_data right to it.
139*78a685aaSJim Ingham             m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0);
140*78a685aaSJim Ingham             break;
141*78a685aaSJim Ingham 
142*78a685aaSJim Ingham         case Value::eValueTypeFileAddress:
143*78a685aaSJim Ingham         case Value::eValueTypeLoadAddress:
144*78a685aaSJim Ingham         case Value::eValueTypeHostAddress:
145*78a685aaSJim Ingham             // The DWARF expression result was an address in the inferior
146*78a685aaSJim Ingham             // process. If this variable is an aggregate type, we just need
147*78a685aaSJim Ingham             // the address as the main value as all child variable objects
148*78a685aaSJim Ingham             // will rely upon this location and add an offset and then read
149*78a685aaSJim Ingham             // their own values as needed. If this variable is a simple
150*78a685aaSJim Ingham             // type, we read all data for it into m_data.
151*78a685aaSJim Ingham             // Make sure this type has a value before we try and read it
152*78a685aaSJim Ingham 
153*78a685aaSJim Ingham             // If we have a file address, convert it to a load address if we can.
154*78a685aaSJim Ingham             if (value_type == Value::eValueTypeFileAddress && exe_ctx.process)
155*78a685aaSJim Ingham             {
156*78a685aaSJim Ingham                 lldb::addr_t load_addr = m_address.GetLoadAddress(exe_ctx.target);
157*78a685aaSJim Ingham                 if (load_addr != LLDB_INVALID_ADDRESS)
158*78a685aaSJim Ingham                 {
159*78a685aaSJim Ingham                     m_value.SetValueType(Value::eValueTypeLoadAddress);
160*78a685aaSJim Ingham                     m_value.GetScalar() = load_addr;
161*78a685aaSJim Ingham                 }
162*78a685aaSJim Ingham             }
163*78a685aaSJim Ingham 
164*78a685aaSJim Ingham             if (ClangASTContext::IsAggregateType (GetClangType()))
165*78a685aaSJim Ingham             {
166*78a685aaSJim Ingham                 // this value object represents an aggregate type whose
167*78a685aaSJim Ingham                 // children have values, but this object does not. So we
168*78a685aaSJim Ingham                 // say we are changed if our location has changed.
169*78a685aaSJim Ingham                 SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
170*78a685aaSJim Ingham             }
171*78a685aaSJim Ingham             else
172*78a685aaSJim Ingham             {
173*78a685aaSJim Ingham                 // Copy the Value and set the context to use our Variable
174*78a685aaSJim Ingham                 // so it can extract read its value into m_data appropriately
175*78a685aaSJim Ingham                 Value value(m_value);
176*78a685aaSJim Ingham                 value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
177*78a685aaSJim Ingham                 m_error = value.GetValueAsData(&exe_ctx, GetClangAST(), m_data, 0);
178*78a685aaSJim Ingham             }
179*78a685aaSJim Ingham             break;
180*78a685aaSJim Ingham         }
181*78a685aaSJim Ingham 
182*78a685aaSJim Ingham         SetValueIsValid (m_error.Success());
183*78a685aaSJim Ingham     }
184*78a685aaSJim Ingham     return m_error.Success();
185*78a685aaSJim Ingham }
186*78a685aaSJim Ingham 
187*78a685aaSJim Ingham 
188*78a685aaSJim Ingham 
189*78a685aaSJim Ingham bool
190*78a685aaSJim Ingham ValueObjectMemory::IsInScope ()
191*78a685aaSJim Ingham {
192*78a685aaSJim Ingham     // FIXME: Maybe try to read the memory address, and if that works, then
193*78a685aaSJim Ingham     // we are in scope?
194*78a685aaSJim Ingham     return true;
195*78a685aaSJim Ingham }
196*78a685aaSJim Ingham 
197