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