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