]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectMemory.cpp
Checkpoint initial integration work
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Core / ValueObjectMemory.cpp
1 //===-- ValueObjectMemory.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10
11 #include "lldb/Core/ValueObjectMemory.h"
12
13 // C Includes
14 // C++ Includes
15 // Other libraries and framework includes
16 // Project includes
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/ValueObjectList.h"
19 #include "lldb/Core/Value.h"
20 #include "lldb/Core/ValueObject.h"
21
22 #include "lldb/Symbol/ObjectFile.h"
23 #include "lldb/Symbol/SymbolContext.h"
24 #include "lldb/Symbol/Type.h"
25 #include "lldb/Symbol/Variable.h"
26
27 #include "lldb/Target/ExecutionContext.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/RegisterContext.h"
30 #include "lldb/Target/Target.h"
31 #include "lldb/Target/Thread.h"
32
33 using namespace lldb;
34 using namespace lldb_private;
35
36 ValueObjectSP
37 ValueObjectMemory::Create (ExecutionContextScope *exe_scope, 
38                            const char *name,
39                            const Address &address, 
40                            lldb::TypeSP &type_sp)
41 {
42     return (new ValueObjectMemory (exe_scope, name, address, type_sp))->GetSP();
43 }
44
45 ValueObjectSP
46 ValueObjectMemory::Create (ExecutionContextScope *exe_scope, 
47                            const char *name,
48                            const Address &address, 
49                            const CompilerType &ast_type)
50 {
51     return (new ValueObjectMemory (exe_scope, name, address, ast_type))->GetSP();
52 }
53
54 ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
55                                       const char *name, 
56                                       const Address &address,
57                                       lldb::TypeSP &type_sp) :
58     ValueObject(exe_scope),
59     m_address (address),
60     m_type_sp(type_sp),
61     m_compiler_type()
62 {
63     // Do not attempt to construct one of these objects with no variable!
64     assert (m_type_sp.get() != NULL);
65     SetName (ConstString(name));
66     m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
67     TargetSP target_sp (GetTargetSP());
68     lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
69     if (load_address != LLDB_INVALID_ADDRESS)
70     {
71         m_value.SetValueType(Value::eValueTypeLoadAddress);
72         m_value.GetScalar() = load_address;
73     }
74     else
75     {
76         lldb::addr_t file_address = m_address.GetFileAddress();
77         if (file_address != LLDB_INVALID_ADDRESS)
78         {
79             m_value.SetValueType(Value::eValueTypeFileAddress);
80             m_value.GetScalar() = file_address;
81         }
82         else
83         {
84             m_value.GetScalar() = m_address.GetOffset();
85             m_value.SetValueType (Value::eValueTypeScalar);
86         }
87     }
88 }
89
90 ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
91                                       const char *name, 
92                                       const Address &address,
93                                       const CompilerType &ast_type) :
94     ValueObject(exe_scope),
95     m_address (address),
96     m_type_sp(),
97     m_compiler_type(ast_type)
98 {
99     // Do not attempt to construct one of these objects with no variable!
100     assert (m_compiler_type.GetTypeSystem());
101     assert (m_compiler_type.GetOpaqueQualType());
102     
103     TargetSP target_sp (GetTargetSP());
104
105     SetName (ConstString(name));
106 //    m_value.SetContext(Value::eContextTypeClangType, m_compiler_type.GetOpaqueQualType());
107     m_value.SetCompilerType(m_compiler_type);
108     lldb::addr_t load_address = m_address.GetLoadAddress (target_sp.get());
109     if (load_address != LLDB_INVALID_ADDRESS)
110     {
111         m_value.SetValueType(Value::eValueTypeLoadAddress);
112         m_value.GetScalar() = load_address;
113     }
114     else
115     {
116         lldb::addr_t file_address = m_address.GetFileAddress();
117         if (file_address != LLDB_INVALID_ADDRESS)
118         {
119             m_value.SetValueType(Value::eValueTypeFileAddress);
120             m_value.GetScalar() = file_address;
121         }
122         else
123         {
124             m_value.GetScalar() = m_address.GetOffset();
125             m_value.SetValueType (Value::eValueTypeScalar);
126         }
127     }
128 }
129
130 ValueObjectMemory::~ValueObjectMemory()
131 {
132 }
133
134 CompilerType
135 ValueObjectMemory::GetCompilerTypeImpl ()
136 {
137     if (m_type_sp)
138         return m_type_sp->GetForwardCompilerType ();
139     return m_compiler_type;
140 }
141
142 ConstString
143 ValueObjectMemory::GetTypeName()
144 {
145     if (m_type_sp)
146         return m_type_sp->GetName();
147     return m_compiler_type.GetConstTypeName();
148 }
149
150 ConstString
151 ValueObjectMemory::GetDisplayTypeName()
152 {
153     if (m_type_sp)
154         return m_type_sp->GetForwardCompilerType ().GetDisplayTypeName();
155     return m_compiler_type.GetDisplayTypeName();
156 }
157
158 size_t
159 ValueObjectMemory::CalculateNumChildren(uint32_t max)
160 {
161     if (m_type_sp)
162     {
163         auto child_count = m_type_sp->GetNumChildren(true);
164         return child_count <= max ? child_count : max;
165     }
166
167     const bool omit_empty_base_classes = true;
168     auto child_count = m_compiler_type.GetNumChildren (omit_empty_base_classes);
169     return child_count <= max ? child_count : max;
170 }
171
172 uint64_t
173 ValueObjectMemory::GetByteSize()
174 {
175     if (m_type_sp)
176         return m_type_sp->GetByteSize();
177     return m_compiler_type.GetByteSize (nullptr);
178 }
179
180 lldb::ValueType
181 ValueObjectMemory::GetValueType() const
182 {
183     // RETHINK: Should this be inherited from somewhere?
184     return lldb::eValueTypeVariableGlobal;
185 }
186
187 bool
188 ValueObjectMemory::UpdateValue ()
189 {
190     SetValueIsValid (false);
191     m_error.Clear();
192
193     ExecutionContext exe_ctx (GetExecutionContextRef());
194     
195     Target *target = exe_ctx.GetTargetPtr();
196     if (target)
197     {
198         m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
199         m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
200     }
201
202     Value old_value(m_value);
203     if (m_address.IsValid())
204     {
205         Value::ValueType value_type = m_value.GetValueType();
206
207         switch (value_type)
208         {
209         default:
210             assert(!"Unhandled expression result value kind...");
211             break;
212
213         case Value::eValueTypeScalar:
214             // The variable value is in the Scalar value inside the m_value.
215             // We can point our m_data right to it.
216             m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
217             break;
218
219         case Value::eValueTypeFileAddress:
220         case Value::eValueTypeLoadAddress:
221         case Value::eValueTypeHostAddress:
222             // The DWARF expression result was an address in the inferior
223             // process. If this variable is an aggregate type, we just need
224             // the address as the main value as all child variable objects
225             // will rely upon this location and add an offset and then read
226             // their own values as needed. If this variable is a simple
227             // type, we read all data for it into m_data.
228             // Make sure this type has a value before we try and read it
229
230             // If we have a file address, convert it to a load address if we can.
231             if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr())
232             {
233                 lldb::addr_t load_addr = m_address.GetLoadAddress(target);
234                 if (load_addr != LLDB_INVALID_ADDRESS)
235                 {
236                     m_value.SetValueType(Value::eValueTypeLoadAddress);
237                     m_value.GetScalar() = load_addr;
238                 }
239             }
240
241             if (!CanProvideValue())
242             {
243                 // this value object represents an aggregate type whose
244                 // children have values, but this object does not. So we
245                 // say we are changed if our location has changed.
246                 SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
247             }
248             else
249             {
250                 // Copy the Value and set the context to use our Variable
251                 // so it can extract read its value into m_data appropriately
252                 Value value(m_value);
253                 if (m_type_sp)
254                     value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
255                 else
256                 {
257                     //value.SetContext(Value::eContextTypeClangType, m_compiler_type.GetOpaqueQualType());
258                     value.SetCompilerType(m_compiler_type);
259                 }
260
261                 m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
262             }
263             break;
264         }
265
266         SetValueIsValid (m_error.Success());
267     }
268     return m_error.Success();
269 }
270
271
272
273 bool
274 ValueObjectMemory::IsInScope ()
275 {
276     // FIXME: Maybe try to read the memory address, and if that works, then
277     // we are in scope?
278     return true;
279 }
280
281
282 lldb::ModuleSP
283 ValueObjectMemory::GetModule()
284 {
285     return m_address.GetModule();
286 }
287
288