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