]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Core/ValueObjectRegister.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Core / ValueObjectRegister.cpp
1 //===-- ValueObjectRegister.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/ValueObjectRegister.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/Symbol/ClangASTContext.h"
18 #include "lldb/Symbol/CompilerType.h"
19 #include "lldb/Symbol/TypeList.h"
20 #include "lldb/Target/ExecutionContext.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25
26 using namespace lldb;
27 using namespace lldb_private;
28
29 #pragma mark ValueObjectRegisterContext
30
31 ValueObjectRegisterContext::ValueObjectRegisterContext(
32     ValueObject &parent, RegisterContextSP &reg_ctx)
33     : ValueObject(parent), m_reg_ctx_sp(reg_ctx) {
34   assert(reg_ctx);
35   m_name.SetCString("Registers");
36   SetValueIsValid(true);
37 }
38
39 ValueObjectRegisterContext::~ValueObjectRegisterContext() {}
40
41 CompilerType ValueObjectRegisterContext::GetCompilerTypeImpl() {
42   return CompilerType();
43 }
44
45 ConstString ValueObjectRegisterContext::GetTypeName() { return ConstString(); }
46
47 ConstString ValueObjectRegisterContext::GetDisplayTypeName() {
48   return ConstString();
49 }
50
51 ConstString ValueObjectRegisterContext::GetQualifiedTypeName() {
52   return ConstString();
53 }
54
55 size_t ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) {
56   auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount();
57   return reg_set_count <= max ? reg_set_count : max;
58 }
59
60 uint64_t ValueObjectRegisterContext::GetByteSize() { return 0; }
61
62 bool ValueObjectRegisterContext::UpdateValue() {
63   m_error.Clear();
64   ExecutionContext exe_ctx(GetExecutionContextRef());
65   StackFrame *frame = exe_ctx.GetFramePtr();
66   if (frame)
67     m_reg_ctx_sp = frame->GetRegisterContext();
68   else
69     m_reg_ctx_sp.reset();
70
71   if (m_reg_ctx_sp.get() == NULL) {
72     SetValueIsValid(false);
73     m_error.SetErrorToGenericError();
74   } else
75     SetValueIsValid(true);
76
77   return m_error.Success();
78 }
79
80 ValueObject *ValueObjectRegisterContext::CreateChildAtIndex(
81     size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
82   ValueObject *new_valobj = NULL;
83
84   const size_t num_children = GetNumChildren();
85   if (idx < num_children) {
86     ExecutionContext exe_ctx(GetExecutionContextRef());
87     new_valobj = new ValueObjectRegisterSet(
88         exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
89   }
90
91   return new_valobj;
92 }
93
94 #pragma mark -
95 #pragma mark ValueObjectRegisterSet
96
97 ValueObjectSP
98 ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
99                                lldb::RegisterContextSP &reg_ctx_sp,
100                                uint32_t set_idx) {
101   return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP();
102 }
103
104 ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
105                                                lldb::RegisterContextSP &reg_ctx,
106                                                uint32_t reg_set_idx)
107     : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(NULL),
108       m_reg_set_idx(reg_set_idx) {
109   assert(reg_ctx);
110   m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
111   if (m_reg_set) {
112     m_name.SetCString(m_reg_set->name);
113   }
114 }
115
116 ValueObjectRegisterSet::~ValueObjectRegisterSet() {}
117
118 CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() {
119   return CompilerType();
120 }
121
122 ConstString ValueObjectRegisterSet::GetTypeName() { return ConstString(); }
123
124 ConstString ValueObjectRegisterSet::GetQualifiedTypeName() {
125   return ConstString();
126 }
127
128 size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
129   const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
130   if (reg_set) {
131     auto reg_count = reg_set->num_registers;
132     return reg_count <= max ? reg_count : max;
133   }
134   return 0;
135 }
136
137 uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
138
139 bool ValueObjectRegisterSet::UpdateValue() {
140   m_error.Clear();
141   SetValueDidChange(false);
142   ExecutionContext exe_ctx(GetExecutionContextRef());
143   StackFrame *frame = exe_ctx.GetFramePtr();
144   if (frame == NULL)
145     m_reg_ctx_sp.reset();
146   else {
147     m_reg_ctx_sp = frame->GetRegisterContext();
148     if (m_reg_ctx_sp) {
149       const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
150       if (reg_set == NULL)
151         m_reg_ctx_sp.reset();
152       else if (m_reg_set != reg_set) {
153         SetValueDidChange(true);
154         m_name.SetCString(reg_set->name);
155       }
156     }
157   }
158   if (m_reg_ctx_sp) {
159     SetValueIsValid(true);
160   } else {
161     SetValueIsValid(false);
162     m_error.SetErrorToGenericError();
163     m_children.Clear();
164   }
165   return m_error.Success();
166 }
167
168 ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
169     size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
170   ValueObject *valobj = NULL;
171   if (m_reg_ctx_sp && m_reg_set) {
172     const size_t num_children = GetNumChildren();
173     if (idx < num_children)
174       valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
175                                        m_reg_set->registers[idx]);
176   }
177   return valobj;
178 }
179
180 lldb::ValueObjectSP
181 ValueObjectRegisterSet::GetChildMemberWithName(const ConstString &name,
182                                                bool can_create) {
183   ValueObject *valobj = NULL;
184   if (m_reg_ctx_sp && m_reg_set) {
185     const RegisterInfo *reg_info =
186         m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
187     if (reg_info != NULL)
188       valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
189                                        reg_info->kinds[eRegisterKindLLDB]);
190   }
191   if (valobj)
192     return valobj->GetSP();
193   else
194     return ValueObjectSP();
195 }
196
197 size_t
198 ValueObjectRegisterSet::GetIndexOfChildWithName(const ConstString &name) {
199   if (m_reg_ctx_sp && m_reg_set) {
200     const RegisterInfo *reg_info =
201         m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
202     if (reg_info != NULL)
203       return reg_info->kinds[eRegisterKindLLDB];
204   }
205   return UINT32_MAX;
206 }
207
208 #pragma mark -
209 #pragma mark ValueObjectRegister
210
211 void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
212   const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
213   if (reg_info) {
214     m_reg_info = *reg_info;
215     if (reg_info->name)
216       m_name.SetCString(reg_info->name);
217     else if (reg_info->alt_name)
218       m_name.SetCString(reg_info->alt_name);
219   }
220 }
221
222 ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
223                                          lldb::RegisterContextSP &reg_ctx_sp,
224                                          uint32_t reg_num)
225     : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
226       m_reg_value(), m_type_name(), m_compiler_type() {
227   assert(reg_ctx_sp.get());
228   ConstructObject(reg_num);
229 }
230
231 ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
232                                           lldb::RegisterContextSP &reg_ctx_sp,
233                                           uint32_t reg_num) {
234   return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP();
235 }
236
237 ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
238                                          lldb::RegisterContextSP &reg_ctx,
239                                          uint32_t reg_num)
240     : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(),
241       m_reg_value(), m_type_name(), m_compiler_type() {
242   assert(reg_ctx);
243   ConstructObject(reg_num);
244 }
245
246 ValueObjectRegister::~ValueObjectRegister() {}
247
248 CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
249   if (!m_compiler_type.IsValid()) {
250     ExecutionContext exe_ctx(GetExecutionContextRef());
251     Target *target = exe_ctx.GetTargetPtr();
252     if (target) {
253       Module *exe_module = target->GetExecutableModulePointer();
254       if (exe_module) {
255         TypeSystem *type_system =
256             exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
257         if (type_system)
258           m_compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(
259               m_reg_info.encoding, m_reg_info.byte_size * 8);
260       }
261     }
262   }
263   return m_compiler_type;
264 }
265
266 ConstString ValueObjectRegister::GetTypeName() {
267   if (m_type_name.IsEmpty())
268     m_type_name = GetCompilerType().GetConstTypeName();
269   return m_type_name;
270 }
271
272 size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
273   auto children_count = GetCompilerType().GetNumChildren(true);
274   return children_count <= max ? children_count : max;
275 }
276
277 uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
278
279 bool ValueObjectRegister::UpdateValue() {
280   m_error.Clear();
281   ExecutionContext exe_ctx(GetExecutionContextRef());
282   StackFrame *frame = exe_ctx.GetFramePtr();
283   if (frame == NULL) {
284     m_reg_ctx_sp.reset();
285     m_reg_value.Clear();
286   }
287
288   if (m_reg_ctx_sp) {
289     RegisterValue m_old_reg_value(m_reg_value);
290     if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
291       if (m_reg_value.GetData(m_data)) {
292         Process *process = exe_ctx.GetProcessPtr();
293         if (process)
294           m_data.SetAddressByteSize(process->GetAddressByteSize());
295         m_value.SetContext(Value::eContextTypeRegisterInfo,
296                            (void *)&m_reg_info);
297         m_value.SetValueType(Value::eValueTypeHostAddress);
298         m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
299         SetValueIsValid(true);
300         SetValueDidChange(!(m_old_reg_value == m_reg_value));
301         return true;
302       }
303     }
304   }
305
306   SetValueIsValid(false);
307   m_error.SetErrorToGenericError();
308   return false;
309 }
310
311 bool ValueObjectRegister::SetValueFromCString(const char *value_str,
312                                               Error &error) {
313   // The new value will be in the m_data.  Copy that into our register value.
314   error =
315       m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
316   if (error.Success()) {
317     if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
318       SetNeedsUpdate();
319       return true;
320     } else
321       return false;
322   } else
323     return false;
324 }
325
326 bool ValueObjectRegister::SetData(DataExtractor &data, Error &error) {
327   error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
328   if (error.Success()) {
329     if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
330       SetNeedsUpdate();
331       return true;
332     } else
333       return false;
334   } else
335     return false;
336 }
337
338 bool ValueObjectRegister::ResolveValue(Scalar &scalar) {
339   if (UpdateValueIfNeeded(
340           false)) // make sure that you are up to date before returning anything
341     return m_reg_value.GetScalarValue(scalar);
342   return false;
343 }
344
345 void ValueObjectRegister::GetExpressionPath(Stream &s,
346                                             bool qualify_cxx_base_classes,
347                                             GetExpressionPathFormat epformat) {
348   s.Printf("$%s", m_reg_info.name);
349 }