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