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