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 ®_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 ®_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 ®_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 ®_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 ®_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 ®_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 } 364