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 ®_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 ®_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 ®_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 ®_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 ®_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 ®_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 = m_reg_value.SetValueFromCString(&m_reg_info, value_str); 315 if (error.Success()) { 316 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) { 317 SetNeedsUpdate(); 318 return true; 319 } else 320 return false; 321 } else 322 return false; 323 } 324 325 bool ValueObjectRegister::SetData(DataExtractor &data, Error &error) { 326 error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false); 327 if (error.Success()) { 328 if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) { 329 SetNeedsUpdate(); 330 return true; 331 } else 332 return false; 333 } else 334 return false; 335 } 336 337 bool ValueObjectRegister::ResolveValue(Scalar &scalar) { 338 if (UpdateValueIfNeeded( 339 false)) // make sure that you are up to date before returning anything 340 return m_reg_value.GetScalarValue(scalar); 341 return false; 342 } 343 344 void ValueObjectRegister::GetExpressionPath(Stream &s, 345 bool qualify_cxx_base_classes, 346 GetExpressionPathFormat epformat) { 347 s.Printf("$%s", m_reg_info.name); 348 } 349