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 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 ClangASTType 46 ValueObjectRegisterContext::GetClangTypeImpl () 47 { 48 return ClangASTType(); 49 } 50 51 ConstString 52 ValueObjectRegisterContext::GetTypeName() 53 { 54 return ConstString(); 55 } 56 57 ConstString 58 ValueObjectRegisterContext::GetQualifiedTypeName() 59 { 60 return ConstString(); 61 } 62 63 size_t 64 ValueObjectRegisterContext::CalculateNumChildren() 65 { 66 return m_reg_ctx_sp->GetRegisterSetCount(); 67 } 68 69 uint64_t 70 ValueObjectRegisterContext::GetByteSize() 71 { 72 return 0; 73 } 74 75 bool 76 ValueObjectRegisterContext::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 97 ValueObject * 98 ValueObjectRegisterContext::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 116 ValueObjectSP 117 ValueObjectRegisterSet::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 123 ValueObjectRegisterSet::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 137 ValueObjectRegisterSet::~ValueObjectRegisterSet() 138 { 139 } 140 141 ClangASTType 142 ValueObjectRegisterSet::GetClangTypeImpl () 143 { 144 return ClangASTType(); 145 } 146 147 ConstString 148 ValueObjectRegisterSet::GetTypeName() 149 { 150 return ConstString(); 151 } 152 153 ConstString 154 ValueObjectRegisterSet::GetQualifiedTypeName() 155 { 156 return ConstString(); 157 } 158 159 size_t 160 ValueObjectRegisterSet::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 168 uint64_t 169 ValueObjectRegisterSet::GetByteSize() 170 { 171 return 0; 172 } 173 174 bool 175 ValueObjectRegisterSet::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 212 ValueObject * 213 ValueObjectRegisterSet::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 225 lldb::ValueObjectSP 226 ValueObjectRegisterSet::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 241 size_t 242 ValueObjectRegisterSet::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 256 void 257 ValueObjectRegister::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 270 ValueObjectRegister::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 282 ValueObjectSP 283 ValueObjectRegister::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 288 ValueObjectRegister::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 300 ValueObjectRegister::~ValueObjectRegister() 301 { 302 } 303 304 ClangASTType 305 ValueObjectRegister::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 324 ConstString 325 ValueObjectRegister::GetTypeName() 326 { 327 if (m_type_name.IsEmpty()) 328 m_type_name = GetClangType().GetConstTypeName (); 329 return m_type_name; 330 } 331 332 size_t 333 ValueObjectRegister::CalculateNumChildren() 334 { 335 return GetClangType().GetNumChildren(true); 336 } 337 338 uint64_t 339 ValueObjectRegister::GetByteSize() 340 { 341 return m_reg_info.byte_size; 342 } 343 344 bool 345 ValueObjectRegister::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 380 bool 381 ValueObjectRegister::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 399 bool 400 ValueObjectRegister::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 417 bool 418 ValueObjectRegister::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 425 void 426 ValueObjectRegister::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat) 427 { 428 s.Printf("$%s", m_reg_info.name); 429 } 430 431 432