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