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