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