]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Core/ValueObjectMemory.cpp
Update ELF Tool Chain to upstream rev 3400
[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 ClangASTType &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_clang_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 ClangASTType &ast_type) :
94     ValueObject(exe_scope),
95     m_address (address),
96     m_type_sp(),
97     m_clang_type(ast_type)
98 {
99     // Do not attempt to construct one of these objects with no variable!
100     assert (m_clang_type.GetASTContext());
101     assert (m_clang_type.GetOpaqueQualType());
102     
103     TargetSP target_sp (GetTargetSP());
104
105     SetName (ConstString(name));
106 //    m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
107     m_value.SetClangType(m_clang_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 ClangASTType
135 ValueObjectMemory::GetClangTypeImpl ()
136 {
137     if (m_type_sp)
138         return m_type_sp->GetClangForwardType();
139     return m_clang_type;
140 }
141
142 ConstString
143 ValueObjectMemory::GetTypeName()
144 {
145     if (m_type_sp)
146         return m_type_sp->GetName();
147     return m_clang_type.GetConstTypeName();
148 }
149
150 ConstString
151 ValueObjectMemory::GetDisplayTypeName()
152 {
153     if (m_type_sp)
154         return m_type_sp->GetClangForwardType().GetDisplayTypeName();
155     return m_clang_type.GetDisplayTypeName();
156 }
157
158 size_t
159 ValueObjectMemory::CalculateNumChildren()
160 {
161     if (m_type_sp)
162         return m_type_sp->GetNumChildren(true);
163     const bool omit_empty_base_classes = true;
164     return m_clang_type.GetNumChildren (omit_empty_base_classes);
165 }
166
167 uint64_t
168 ValueObjectMemory::GetByteSize()
169 {
170     if (m_type_sp)
171         return m_type_sp->GetByteSize();
172     return m_clang_type.GetByteSize (nullptr);
173 }
174
175 lldb::ValueType
176 ValueObjectMemory::GetValueType() const
177 {
178     // RETHINK: Should this be inherited from somewhere?
179     return lldb::eValueTypeVariableGlobal;
180 }
181
182 bool
183 ValueObjectMemory::UpdateValue ()
184 {
185     SetValueIsValid (false);
186     m_error.Clear();
187
188     ExecutionContext exe_ctx (GetExecutionContextRef());
189     
190     Target *target = exe_ctx.GetTargetPtr();
191     if (target)
192     {
193         m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
194         m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
195     }
196
197     Value old_value(m_value);
198     if (m_address.IsValid())
199     {
200         Value::ValueType value_type = m_value.GetValueType();
201
202         switch (value_type)
203         {
204         default:
205             assert(!"Unhandled expression result value kind...");
206             break;
207
208         case Value::eValueTypeScalar:
209             // The variable value is in the Scalar value inside the m_value.
210             // We can point our m_data right to it.
211             m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
212             break;
213
214         case Value::eValueTypeFileAddress:
215         case Value::eValueTypeLoadAddress:
216         case Value::eValueTypeHostAddress:
217             // The DWARF expression result was an address in the inferior
218             // process. If this variable is an aggregate type, we just need
219             // the address as the main value as all child variable objects
220             // will rely upon this location and add an offset and then read
221             // their own values as needed. If this variable is a simple
222             // type, we read all data for it into m_data.
223             // Make sure this type has a value before we try and read it
224
225             // If we have a file address, convert it to a load address if we can.
226             if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr())
227             {
228                 lldb::addr_t load_addr = m_address.GetLoadAddress(target);
229                 if (load_addr != LLDB_INVALID_ADDRESS)
230                 {
231                     m_value.SetValueType(Value::eValueTypeLoadAddress);
232                     m_value.GetScalar() = load_addr;
233                 }
234             }
235
236             if (!CanProvideValue())
237             {
238                 // this value object represents an aggregate type whose
239                 // children have values, but this object does not. So we
240                 // say we are changed if our location has changed.
241                 SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
242             }
243             else
244             {
245                 // Copy the Value and set the context to use our Variable
246                 // so it can extract read its value into m_data appropriately
247                 Value value(m_value);
248                 if (m_type_sp)
249                     value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
250                 else
251                 {
252                     //value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType());
253                     value.SetClangType(m_clang_type);
254                 }
255
256                 m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
257             }
258             break;
259         }
260
261         SetValueIsValid (m_error.Success());
262     }
263     return m_error.Success();
264 }
265
266
267
268 bool
269 ValueObjectMemory::IsInScope ()
270 {
271     // FIXME: Maybe try to read the memory address, and if that works, then
272     // we are in scope?
273     return true;
274 }
275
276
277 lldb::ModuleSP
278 ValueObjectMemory::GetModule()
279 {
280     return m_address.GetModule();
281 }
282
283