ClangExpressionDeclMap.cpp revision 06dc17f8eb821d7256fd42e56f85c2779a29f689
1//===-- ClangExpressionDeclMap.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#include "lldb/Expression/ClangExpressionDeclMap.h" 11 12// C Includes 13// C++ Includes 14// Other libraries and framework includes 15// Project includes 16#include "clang/AST/ASTContext.h" 17#include "clang/AST/DeclarationName.h" 18#include "clang/AST/Decl.h" 19#include "lldb/lldb-private.h" 20#include "lldb/Core/Address.h" 21#include "lldb/Core/Error.h" 22#include "lldb/Core/Log.h" 23#include "lldb/Core/Module.h" 24#include "lldb/Core/RegisterValue.h" 25#include "lldb/Core/ValueObjectConstResult.h" 26#include "lldb/Core/ValueObjectVariable.h" 27#include "lldb/Expression/ASTDumper.h" 28#include "lldb/Expression/ClangASTSource.h" 29#include "lldb/Expression/ClangPersistentVariables.h" 30#include "lldb/Host/Endian.h" 31#include "lldb/Symbol/ClangASTContext.h" 32#include "lldb/Symbol/ClangNamespaceDecl.h" 33#include "lldb/Symbol/CompileUnit.h" 34#include "lldb/Symbol/Function.h" 35#include "lldb/Symbol/ObjectFile.h" 36#include "lldb/Symbol/SymbolContext.h" 37#include "lldb/Symbol/SymbolVendor.h" 38#include "lldb/Symbol/Type.h" 39#include "lldb/Symbol/TypeList.h" 40#include "lldb/Symbol/Variable.h" 41#include "lldb/Symbol/VariableList.h" 42#include "lldb/Target/ExecutionContext.h" 43#include "lldb/Target/Process.h" 44#include "lldb/Target/RegisterContext.h" 45#include "lldb/Target/StackFrame.h" 46#include "lldb/Target/Target.h" 47#include "lldb/Target/Thread.h" 48 49using namespace lldb; 50using namespace lldb_private; 51using namespace clang; 52 53ClangExpressionDeclMap::ClangExpressionDeclMap (bool keep_result_in_memory, ExecutionContext &exe_ctx) : 54 ClangASTSource (exe_ctx.GetTargetSP()), 55 m_found_entities (), 56 m_struct_members (), 57 m_keep_result_in_memory (keep_result_in_memory), 58 m_parser_vars (), 59 m_struct_vars () 60{ 61 EnableStructVars(); 62} 63 64ClangExpressionDeclMap::~ClangExpressionDeclMap() 65{ 66 // Note: The model is now that the parser's AST context and all associated 67 // data does not vanish until the expression has been executed. This means 68 // that valuable lookup data (like namespaces) doesn't vanish, but 69 70 DidParse(); 71 DidDematerialize(); 72 DisableStructVars(); 73} 74 75bool 76ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx) 77{ 78 EnableParserVars(); 79 m_parser_vars->m_exe_ctx = exe_ctx; 80 81 Target *target = exe_ctx.GetTargetPtr(); 82 if (exe_ctx.GetFramePtr()) 83 m_parser_vars->m_sym_ctx = exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything); 84 else if (exe_ctx.GetThreadPtr()) 85 m_parser_vars->m_sym_ctx = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything); 86 else if (exe_ctx.GetProcessPtr()) 87 { 88 m_parser_vars->m_sym_ctx.Clear(); 89 m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP(); 90 } 91 else if (target) 92 { 93 m_parser_vars->m_sym_ctx.Clear(); 94 m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP(); 95 } 96 97 if (target) 98 { 99 m_parser_vars->m_persistent_vars = &target->GetPersistentVariables(); 100 101 if (!target->GetScratchClangASTContext()) 102 return false; 103 } 104 105 m_parser_vars->m_target_info = GetTargetInfo(); 106 107 return true; 108} 109 110void 111ClangExpressionDeclMap::DidParse() 112{ 113 if (m_parser_vars.get()) 114 { 115 for (size_t entity_index = 0, num_entities = m_found_entities.GetSize(); 116 entity_index < num_entities; 117 ++entity_index) 118 { 119 ClangExpressionVariableSP var_sp(m_found_entities.GetVariableAtIndex(entity_index)); 120 if (var_sp && 121 var_sp->m_parser_vars.get() && 122 var_sp->m_parser_vars->m_lldb_value) 123 delete var_sp->m_parser_vars->m_lldb_value; 124 125 var_sp->DisableParserVars(); 126 } 127 128 for (size_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->GetSize(); 129 pvar_index < num_pvars; 130 ++pvar_index) 131 { 132 ClangExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index)); 133 if (pvar_sp) 134 pvar_sp->DisableParserVars(); 135 } 136 137 DisableParserVars(); 138 } 139} 140 141// Interface for IRForTarget 142 143ClangExpressionDeclMap::TargetInfo 144ClangExpressionDeclMap::GetTargetInfo() 145{ 146 assert (m_parser_vars.get()); 147 148 TargetInfo ret; 149 150 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 151 152 Process *process = exe_ctx.GetProcessPtr(); 153 if (process) 154 { 155 ret.byte_order = process->GetByteOrder(); 156 ret.address_byte_size = process->GetAddressByteSize(); 157 } 158 else 159 { 160 Target *target = exe_ctx.GetTargetPtr(); 161 if (target) 162 { 163 ret.byte_order = target->GetArchitecture().GetByteOrder(); 164 ret.address_byte_size = target->GetArchitecture().GetAddressByteSize(); 165 } 166 } 167 168 return ret; 169} 170 171const ConstString & 172ClangExpressionDeclMap::GetPersistentResultName () 173{ 174 assert (m_struct_vars.get()); 175 assert (m_parser_vars.get()); 176 if (!m_struct_vars->m_result_name) 177 { 178 Target *target = m_parser_vars->GetTarget(); 179 assert (target); 180 m_struct_vars->m_result_name = target->GetPersistentVariables().GetNextPersistentVariableName(); 181 } 182 return m_struct_vars->m_result_name; 183} 184 185lldb::ClangExpressionVariableSP 186ClangExpressionDeclMap::BuildIntegerVariable (const ConstString &name, 187 lldb_private::TypeFromParser type, 188 const llvm::APInt& value) 189{ 190 assert (m_parser_vars.get()); 191 192 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 193 194 Target *target = exe_ctx.GetTargetPtr(); 195 196 if (!target) 197 return ClangExpressionVariableSP(); 198 199 ASTContext *context(target->GetScratchClangASTContext()->getASTContext()); 200 201 TypeFromUser user_type(m_ast_importer->CopyType(context, 202 type.GetASTContext(), 203 type.GetOpaqueQualType()), 204 context); 205 206 if (!user_type.GetOpaqueQualType()) 207 { 208 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 209 210 if (log) 211 log->Printf("ClangExpressionDeclMap::BuildIntegerVariable - Couldn't export the type for a constant integer result"); 212 213 return lldb::ClangExpressionVariableSP(); 214 } 215 216 if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx.GetBestExecutionContextScope (), 217 name, 218 user_type, 219 m_parser_vars->m_target_info.byte_order, 220 m_parser_vars->m_target_info.address_byte_size)) 221 return lldb::ClangExpressionVariableSP(); 222 223 ClangExpressionVariableSP pvar_sp (m_parser_vars->m_persistent_vars->GetVariable(name)); 224 225 if (!pvar_sp) 226 return lldb::ClangExpressionVariableSP(); 227 228 uint8_t *pvar_data = pvar_sp->GetValueBytes(); 229 if (pvar_data == NULL) 230 return lldb::ClangExpressionVariableSP(); 231 232 uint64_t value64 = value.getLimitedValue(); 233 234 size_t num_val_bytes = sizeof(value64); 235 size_t num_data_bytes = pvar_sp->GetByteSize(); 236 237 size_t num_bytes = num_val_bytes; 238 if (num_bytes > num_data_bytes) 239 num_bytes = num_data_bytes; 240 241 for (size_t byte_idx = 0; 242 byte_idx < num_bytes; 243 ++byte_idx) 244 { 245 uint64_t shift = byte_idx * 8; 246 uint64_t mask = 0xffll << shift; 247 uint8_t cur_byte = (uint8_t)((value64 & mask) >> shift); 248 249 switch (m_parser_vars->m_target_info.byte_order) 250 { 251 case eByteOrderBig: 252 // High Low 253 // Original: |AABBCCDDEEFFGGHH| 254 // Target: |EEFFGGHH| 255 256 pvar_data[num_data_bytes - (1 + byte_idx)] = cur_byte; 257 break; 258 case eByteOrderLittle: 259 // Target: |HHGGFFEE| 260 pvar_data[byte_idx] = cur_byte; 261 break; 262 default: 263 return lldb::ClangExpressionVariableSP(); 264 } 265 } 266 267 pvar_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried; 268 pvar_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 269 pvar_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 270 271 return pvar_sp; 272} 273 274lldb::ClangExpressionVariableSP 275ClangExpressionDeclMap::BuildCastVariable (const ConstString &name, 276 VarDecl *decl, 277 lldb_private::TypeFromParser type) 278{ 279 assert (m_parser_vars.get()); 280 281 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 282 283 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 284 Target *target = exe_ctx.GetTargetPtr(); 285 if (target == NULL) 286 return lldb::ClangExpressionVariableSP(); 287 288 ASTContext *context(target->GetScratchClangASTContext()->getASTContext()); 289 290 ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl)); 291 292 if (!var_sp) 293 var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl); 294 295 if (!var_sp) 296 return ClangExpressionVariableSP(); 297 298 TypeFromUser user_type(m_ast_importer->CopyType(context, 299 type.GetASTContext(), 300 type.GetOpaqueQualType()), 301 context); 302 303 if (!user_type.GetOpaqueQualType()) 304 { 305 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 306 307 if (log) 308 log->Printf("ClangExpressionDeclMap::BuildCastVariable - Couldn't export the type for a constant cast result"); 309 310 return lldb::ClangExpressionVariableSP(); 311 } 312 313 TypeFromUser var_type = var_sp->GetTypeFromUser(); 314 315 StackFrame *frame = exe_ctx.GetFramePtr(); 316 if (frame == NULL) 317 return lldb::ClangExpressionVariableSP(); 318 319 VariableSP var = FindVariableInScope (*frame, var_sp->GetName(), &var_type); 320 321 if (!var) 322 return lldb::ClangExpressionVariableSP(); // but we should handle this; it may be a persistent variable 323 324 ValueObjectSP var_valobj = frame->GetValueObjectForFrameVariable(var, lldb::eNoDynamicValues); 325 326 if (!var_valobj) 327 return lldb::ClangExpressionVariableSP(); 328 329 ValueObjectSP var_casted_valobj = var_valobj->CastPointerType(name.GetCString(), user_type); 330 331 if (!var_casted_valobj) 332 return lldb::ClangExpressionVariableSP(); 333 334 if (log) 335 { 336 StreamString my_stream_string; 337 338 ClangASTType::DumpTypeDescription (var_type.GetASTContext(), 339 var_type.GetOpaqueQualType(), 340 &my_stream_string); 341 342 343 log->Printf("Building cast variable to type: %s", my_stream_string.GetString().c_str()); 344 } 345 346 ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->CreatePersistentVariable (var_casted_valobj); 347 348 if (!pvar_sp) 349 return lldb::ClangExpressionVariableSP(); 350 351 if (pvar_sp != m_parser_vars->m_persistent_vars->GetVariable(name)) 352 return lldb::ClangExpressionVariableSP(); 353 354 pvar_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried; 355 pvar_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 356 pvar_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 357 358 return pvar_sp; 359} 360 361bool 362ClangExpressionDeclMap::ResultIsReference (const ConstString &name) 363{ 364 ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->GetVariable(name); 365 366 return (pvar_sp->m_flags & ClangExpressionVariable::EVIsProgramReference); 367} 368 369bool 370ClangExpressionDeclMap::CompleteResultVariable (lldb::ClangExpressionVariableSP &valobj, 371 lldb_private::Value &value, 372 const ConstString &name, 373 lldb_private::TypeFromParser type, 374 bool transient, 375 bool maybe_make_load) 376{ 377 assert (m_parser_vars.get()); 378 379 ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->GetVariable(name); 380 381 if (!pvar_sp) 382 return false; 383 384 if (maybe_make_load && 385 value.GetValueType() == Value::eValueTypeFileAddress && 386 m_parser_vars->m_exe_ctx.GetProcessPtr()) 387 { 388 value.SetValueType(Value::eValueTypeLoadAddress); 389 } 390 391 if (pvar_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && 392 !pvar_sp->m_live_sp && 393 !transient) 394 { 395 // The reference comes from the program. We need to set up a live SP for it. 396 397 unsigned long long address = value.GetScalar().ULongLong(); 398 AddressType address_type = value.GetValueAddressType(); 399 400 pvar_sp->m_live_sp = ValueObjectConstResult::Create(m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), 401 pvar_sp->GetTypeFromUser().GetASTContext(), 402 pvar_sp->GetTypeFromUser().GetOpaqueQualType(), 403 pvar_sp->GetName(), 404 address, 405 address_type, 406 pvar_sp->GetByteSize()); 407 } 408 409 if (pvar_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry) 410 { 411 pvar_sp->ValueUpdated(); 412 413 const size_t pvar_byte_size = pvar_sp->GetByteSize(); 414 uint8_t *pvar_data = pvar_sp->GetValueBytes(); 415 416 if (!ReadTarget(pvar_data, value, pvar_byte_size)) 417 return false; 418 419 pvar_sp->m_flags &= ~(ClangExpressionVariable::EVNeedsFreezeDry); 420 } 421 422 valobj = pvar_sp; 423 424 return true; 425} 426 427void 428ClangExpressionDeclMap::RemoveResultVariable 429( 430 const ConstString &name 431) 432{ 433 ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->GetVariable(name); 434 m_parser_vars->m_persistent_vars->RemovePersistentVariable(pvar_sp); 435} 436 437bool 438ClangExpressionDeclMap::AddPersistentVariable 439( 440 const NamedDecl *decl, 441 const ConstString &name, 442 TypeFromParser parser_type, 443 bool is_result, 444 bool is_lvalue 445) 446{ 447 assert (m_parser_vars.get()); 448 449 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 450 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 451 Target *target = exe_ctx.GetTargetPtr(); 452 if (target == NULL) 453 return false; 454 455 ASTContext *context(target->GetScratchClangASTContext()->getASTContext()); 456 457 TypeFromUser user_type(m_ast_importer->DeportType(context, 458 parser_type.GetASTContext(), 459 parser_type.GetOpaqueQualType()), 460 context); 461 462 if (!user_type.GetOpaqueQualType()) 463 { 464 if (log) 465 log->Printf("Persistent variable's type wasn't copied successfully"); 466 return false; 467 } 468 469 if (!m_parser_vars->m_target_info.IsValid()) 470 return false; 471 472 if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx.GetBestExecutionContextScope (), 473 name, 474 user_type, 475 m_parser_vars->m_target_info.byte_order, 476 m_parser_vars->m_target_info.address_byte_size)) 477 return false; 478 479 ClangExpressionVariableSP var_sp (m_parser_vars->m_persistent_vars->GetVariable(name)); 480 481 if (!var_sp) 482 return false; 483 484 var_sp->m_frozen_sp->SetHasCompleteType(); 485 486 if (is_result) 487 var_sp->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry; 488 else 489 var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget; // explicitly-declared persistent variables should persist 490 491 if (is_lvalue) 492 { 493 var_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference; 494 } 495 else 496 { 497 var_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 498 var_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 499 } 500 501 if (log) 502 log->Printf("Created persistent variable with flags 0x%hx", var_sp->m_flags); 503 504 var_sp->EnableParserVars(); 505 506 var_sp->m_parser_vars->m_named_decl = decl; 507 var_sp->m_parser_vars->m_parser_type = parser_type; 508 509 return true; 510} 511 512bool 513ClangExpressionDeclMap::AddValueToStruct 514( 515 const NamedDecl *decl, 516 const ConstString &name, 517 llvm::Value *value, 518 size_t size, 519 off_t alignment 520) 521{ 522 assert (m_struct_vars.get()); 523 assert (m_parser_vars.get()); 524 525 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 526 527 m_struct_vars->m_struct_laid_out = false; 528 529 if (m_struct_members.GetVariable(decl)) 530 return true; 531 532 ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl)); 533 534 if (!var_sp) 535 var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl); 536 537 if (!var_sp) 538 return false; 539 540 if (log) 541 log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure", 542 decl, 543 name.GetCString(), 544 var_sp->GetName().GetCString()); 545 546 // We know entity->m_parser_vars is valid because we used a parser variable 547 // to find it 548 var_sp->m_parser_vars->m_llvm_value = value; 549 550 var_sp->EnableJITVars(); 551 var_sp->m_jit_vars->m_alignment = alignment; 552 var_sp->m_jit_vars->m_size = size; 553 554 m_struct_members.AddVariable(var_sp); 555 556 return true; 557} 558 559bool 560ClangExpressionDeclMap::DoStructLayout () 561{ 562 assert (m_struct_vars.get()); 563 564 if (m_struct_vars->m_struct_laid_out) 565 return true; 566 567 off_t cursor = 0; 568 569 m_struct_vars->m_struct_alignment = 0; 570 m_struct_vars->m_struct_size = 0; 571 572 for (size_t member_index = 0, num_members = m_struct_members.GetSize(); 573 member_index < num_members; 574 ++member_index) 575 { 576 ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index)); 577 if (!member_sp) 578 return false; 579 580 if (!member_sp->m_jit_vars.get()) 581 return false; 582 583 if (member_index == 0) 584 m_struct_vars->m_struct_alignment = member_sp->m_jit_vars->m_alignment; 585 586 if (cursor % member_sp->m_jit_vars->m_alignment) 587 cursor += (member_sp->m_jit_vars->m_alignment - (cursor % member_sp->m_jit_vars->m_alignment)); 588 589 member_sp->m_jit_vars->m_offset = cursor; 590 cursor += member_sp->m_jit_vars->m_size; 591 } 592 593 m_struct_vars->m_struct_size = cursor; 594 595 m_struct_vars->m_struct_laid_out = true; 596 return true; 597} 598 599bool ClangExpressionDeclMap::GetStructInfo 600( 601 uint32_t &num_elements, 602 size_t &size, 603 off_t &alignment 604) 605{ 606 assert (m_struct_vars.get()); 607 608 if (!m_struct_vars->m_struct_laid_out) 609 return false; 610 611 num_elements = m_struct_members.GetSize(); 612 size = m_struct_vars->m_struct_size; 613 alignment = m_struct_vars->m_struct_alignment; 614 615 return true; 616} 617 618bool 619ClangExpressionDeclMap::GetStructElement 620( 621 const NamedDecl *&decl, 622 llvm::Value *&value, 623 off_t &offset, 624 ConstString &name, 625 uint32_t index 626) 627{ 628 assert (m_struct_vars.get()); 629 630 if (!m_struct_vars->m_struct_laid_out) 631 return false; 632 633 if (index >= m_struct_members.GetSize()) 634 return false; 635 636 ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index)); 637 638 if (!member_sp || 639 !member_sp->m_parser_vars.get() || 640 !member_sp->m_jit_vars.get() || 641 !member_sp->GetValueObject()) 642 return false; 643 644 decl = member_sp->m_parser_vars->m_named_decl; 645 value = member_sp->m_parser_vars->m_llvm_value; 646 offset = member_sp->m_jit_vars->m_offset; 647 name = member_sp->GetName(); 648 649 return true; 650} 651 652bool 653ClangExpressionDeclMap::GetFunctionInfo 654( 655 const NamedDecl *decl, 656 uint64_t &ptr 657) 658{ 659 ClangExpressionVariableSP entity_sp(m_found_entities.GetVariable(decl)); 660 661 if (!entity_sp) 662 return false; 663 664 // We know m_parser_vars is valid since we searched for the variable by 665 // its NamedDecl 666 667 ptr = entity_sp->m_parser_vars->m_lldb_value->GetScalar().ULongLong(); 668 669 return true; 670} 671 672static void 673FindCodeSymbolInContext 674( 675 const ConstString &name, 676 SymbolContext &sym_ctx, 677 SymbolContextList &sc_list 678) 679{ 680 if (sym_ctx.module_sp) 681 sym_ctx.module_sp->FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list); 682 683 if (!sc_list.GetSize()) 684 sym_ctx.target_sp->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list); 685} 686 687bool 688ClangExpressionDeclMap::GetFunctionAddress 689( 690 const ConstString &name, 691 uint64_t &func_addr 692) 693{ 694 assert (m_parser_vars.get()); 695 696 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 697 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 698 Target *target = exe_ctx.GetTargetPtr(); 699 // Back out in all cases where we're not fully initialized 700 if (target == NULL) 701 return false; 702 if (!m_parser_vars->m_sym_ctx.target_sp) 703 return false; 704 705 SymbolContextList sc_list; 706 707 FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, sc_list); 708 709 if (!sc_list.GetSize()) 710 { 711 // We occasionally get debug information in which a const function is reported 712 // as non-const, so the mangled name is wrong. This is a hack to compensate. 713 714 if (!strncmp(name.GetCString(), "_ZN", 3) && 715 strncmp(name.GetCString(), "_ZNK", 4)) 716 { 717 std::string fixed_scratch("_ZNK"); 718 fixed_scratch.append(name.GetCString() + 3); 719 ConstString fixed_name(fixed_scratch.c_str()); 720 721 if (log) 722 log->Printf("Failed to find symbols given non-const name %s; trying %s", name.GetCString(), fixed_name.GetCString()); 723 724 FindCodeSymbolInContext(fixed_name, m_parser_vars->m_sym_ctx, sc_list); 725 } 726 } 727 728 if (!sc_list.GetSize()) 729 return false; 730 731 SymbolContext sym_ctx; 732 sc_list.GetContextAtIndex(0, sym_ctx); 733 734 const Address *func_so_addr = NULL; 735 736 if (sym_ctx.function) 737 func_so_addr = &sym_ctx.function->GetAddressRange().GetBaseAddress(); 738 else if (sym_ctx.symbol) 739 func_so_addr = &sym_ctx.symbol->GetAddress(); 740 else 741 return false; 742 743 if (!func_so_addr || !func_so_addr->IsValid()) 744 return false; 745 746 func_addr = func_so_addr->GetCallableLoadAddress (target); 747 748 return true; 749} 750 751addr_t 752ClangExpressionDeclMap::GetSymbolAddress (Target &target, const ConstString &name, lldb::SymbolType symbol_type) 753{ 754 SymbolContextList sc_list; 755 756 target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list); 757 758 const uint32_t num_matches = sc_list.GetSize(); 759 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; 760 761 for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++) 762 { 763 SymbolContext sym_ctx; 764 sc_list.GetContextAtIndex(i, sym_ctx); 765 766 const Address *sym_address = &sym_ctx.symbol->GetAddress(); 767 768 if (!sym_address || !sym_address->IsValid()) 769 return LLDB_INVALID_ADDRESS; 770 771 if (sym_address) 772 { 773 switch (sym_ctx.symbol->GetType()) 774 { 775 case eSymbolTypeCode: 776 case eSymbolTypeTrampoline: 777 symbol_load_addr = sym_address->GetCallableLoadAddress (&target); 778 break; 779 780 case eSymbolTypeData: 781 case eSymbolTypeRuntime: 782 case eSymbolTypeVariable: 783 case eSymbolTypeLocal: 784 case eSymbolTypeParam: 785 case eSymbolTypeInvalid: 786 case eSymbolTypeAbsolute: 787 case eSymbolTypeException: 788 case eSymbolTypeSourceFile: 789 case eSymbolTypeHeaderFile: 790 case eSymbolTypeObjectFile: 791 case eSymbolTypeCommonBlock: 792 case eSymbolTypeBlock: 793 case eSymbolTypeVariableType: 794 case eSymbolTypeLineEntry: 795 case eSymbolTypeLineHeader: 796 case eSymbolTypeScopeBegin: 797 case eSymbolTypeScopeEnd: 798 case eSymbolTypeAdditional: 799 case eSymbolTypeCompiler: 800 case eSymbolTypeInstrumentation: 801 case eSymbolTypeUndefined: 802 case eSymbolTypeObjCClass: 803 case eSymbolTypeObjCMetaClass: 804 case eSymbolTypeObjCIVar: 805 symbol_load_addr = sym_address->GetLoadAddress (&target); 806 break; 807 } 808 } 809 } 810 811 return symbol_load_addr; 812} 813 814addr_t 815ClangExpressionDeclMap::GetSymbolAddress (const ConstString &name, lldb::SymbolType symbol_type) 816{ 817 assert (m_parser_vars.get()); 818 819 if (!m_parser_vars->m_exe_ctx.GetTargetPtr()) 820 return false; 821 822 return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(), name, symbol_type); 823} 824 825// Interface for IRInterpreter 826 827Value 828ClangExpressionDeclMap::WrapBareAddress (lldb::addr_t addr) 829{ 830 Value ret; 831 832 ret.SetContext(Value::eContextTypeInvalid, NULL); 833 834 if (m_parser_vars->m_exe_ctx.GetProcessPtr()) 835 ret.SetValueType(Value::eValueTypeLoadAddress); 836 else 837 ret.SetValueType(Value::eValueTypeFileAddress); 838 839 ret.GetScalar() = (unsigned long long)addr; 840 841 return ret; 842} 843 844bool 845ClangExpressionDeclMap::WriteTarget (lldb_private::Value &value, 846 const uint8_t *data, 847 size_t length) 848{ 849 assert (m_parser_vars.get()); 850 851 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 852 853 Process *process = exe_ctx.GetProcessPtr(); 854 if (value.GetContextType() == Value::eContextTypeRegisterInfo) 855 { 856 if (!process) 857 return false; 858 859 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); 860 RegisterInfo *reg_info = value.GetRegisterInfo(); 861 862 if (!reg_ctx) 863 return false; 864 865 lldb_private::RegisterValue reg_value; 866 Error err; 867 868 if (!reg_value.SetFromMemoryData (reg_info, data, length, process->GetByteOrder(), err)) 869 return false; 870 871 return reg_ctx->WriteRegister(reg_info, reg_value); 872 } 873 else 874 { 875 switch (value.GetValueType()) 876 { 877 default: 878 return false; 879 case Value::eValueTypeFileAddress: 880 { 881 if (!process) 882 return false; 883 884 Target *target = exe_ctx.GetTargetPtr(); 885 Address file_addr; 886 887 if (!target->GetImages().ResolveFileAddress((lldb::addr_t)value.GetScalar().ULongLong(), file_addr)) 888 return false; 889 890 lldb::addr_t load_addr = file_addr.GetLoadAddress(target); 891 892 Error err; 893 process->WriteMemory(load_addr, data, length, err); 894 895 return err.Success(); 896 } 897 case Value::eValueTypeLoadAddress: 898 { 899 if (!process) 900 return false; 901 902 Error err; 903 process->WriteMemory((lldb::addr_t)value.GetScalar().ULongLong(), data, length, err); 904 905 return err.Success(); 906 } 907 case Value::eValueTypeHostAddress: 908 { 909 if (value.GetScalar().ULongLong() == 0 || data == NULL) 910 return false; 911 memcpy ((void *)value.GetScalar().ULongLong(), data, length); 912 return true; 913 } 914 case Value::eValueTypeScalar: 915 return false; 916 } 917 } 918} 919 920bool 921ClangExpressionDeclMap::ReadTarget (uint8_t *data, 922 lldb_private::Value &value, 923 size_t length) 924{ 925 assert (m_parser_vars.get()); 926 927 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 928 929 Process *process = exe_ctx.GetProcessPtr(); 930 931 if (value.GetContextType() == Value::eContextTypeRegisterInfo) 932 { 933 if (!process) 934 return false; 935 936 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); 937 RegisterInfo *reg_info = value.GetRegisterInfo(); 938 939 if (!reg_ctx) 940 return false; 941 942 lldb_private::RegisterValue reg_value; 943 Error err; 944 945 if (!reg_ctx->ReadRegister(reg_info, reg_value)) 946 return false; 947 948 return reg_value.GetAsMemoryData(reg_info, data, length, process->GetByteOrder(), err); 949 } 950 else 951 { 952 switch (value.GetValueType()) 953 { 954 default: 955 return false; 956 case Value::eValueTypeFileAddress: 957 { 958 Target *target = exe_ctx.GetTargetPtr(); 959 if (target == NULL) 960 return false; 961 962 Address file_addr; 963 964 if (!target->GetImages().ResolveFileAddress((lldb::addr_t)value.GetScalar().ULongLong(), file_addr)) 965 return false; 966 967 Error err; 968 target->ReadMemory(file_addr, false, data, length, err); 969 970 return err.Success(); 971 } 972 case Value::eValueTypeLoadAddress: 973 { 974 if (!process) 975 return false; 976 977 Error err; 978 process->ReadMemory((lldb::addr_t)value.GetScalar().ULongLong(), data, length, err); 979 980 return err.Success(); 981 } 982 case Value::eValueTypeHostAddress: 983 { 984 void *host_addr = (void*)value.GetScalar().ULongLong(); 985 986 if (!host_addr) 987 return false; 988 989 memcpy (data, host_addr, length); 990 return true; 991 } 992 case Value::eValueTypeScalar: 993 return false; 994 } 995 } 996} 997 998lldb_private::Value 999ClangExpressionDeclMap::LookupDecl (clang::NamedDecl *decl, ClangExpressionVariable::FlagType &flags) 1000{ 1001 assert (m_parser_vars.get()); 1002 1003 ClangExpressionVariableSP expr_var_sp (m_found_entities.GetVariable(decl)); 1004 ClangExpressionVariableSP persistent_var_sp (m_parser_vars->m_persistent_vars->GetVariable(decl)); 1005 1006 if (expr_var_sp) 1007 { 1008 flags = expr_var_sp->m_flags; 1009 1010 if (!expr_var_sp->m_parser_vars.get()) 1011 return Value(); 1012 1013 bool is_reference = expr_var_sp->m_flags & ClangExpressionVariable::EVTypeIsReference; 1014 1015 if (expr_var_sp->m_parser_vars->m_lldb_var) 1016 { 1017 std::auto_ptr<Value> value(GetVariableValue(expr_var_sp->m_parser_vars->m_lldb_var, NULL)); 1018 1019 if (is_reference && value.get() && value->GetValueType() == Value::eValueTypeLoadAddress) 1020 { 1021 Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); 1022 1023 if (!process) 1024 return Value(); 1025 1026 lldb::addr_t value_addr = value->GetScalar().ULongLong(); 1027 Error read_error; 1028 addr_t ref_value = process->ReadPointerFromMemory (value_addr, read_error); 1029 1030 if (!read_error.Success()) 1031 return Value(); 1032 1033 value->GetScalar() = (unsigned long long)ref_value; 1034 } 1035 1036 if (value.get()) 1037 return *value; 1038 else 1039 return Value(); 1040 } 1041 else if (expr_var_sp->m_parser_vars->m_lldb_sym) 1042 { 1043 const Address sym_address = expr_var_sp->m_parser_vars->m_lldb_sym->GetAddress(); 1044 1045 if (!sym_address.IsValid()) 1046 return Value(); 1047 1048 Value ret; 1049 1050 ProcessSP process_sp (m_parser_vars->m_exe_ctx.GetProcessSP()); 1051 1052 if (process_sp) 1053 { 1054 uint64_t symbol_load_addr = sym_address.GetLoadAddress(&process_sp->GetTarget()); 1055 1056 ret.GetScalar() = symbol_load_addr; 1057 ret.SetValueType(Value::eValueTypeLoadAddress); 1058 } 1059 else 1060 { 1061 uint64_t symbol_file_addr = sym_address.GetFileAddress(); 1062 1063 ret.GetScalar() = symbol_file_addr; 1064 ret.SetValueType(Value::eValueTypeFileAddress); 1065 } 1066 1067 return ret; 1068 } 1069 else if (RegisterInfo *reg_info = expr_var_sp->GetRegisterInfo()) 1070 { 1071 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 1072 1073 if (!frame) 1074 return Value(); 1075 1076 RegisterContextSP reg_context_sp(frame->GetRegisterContextSP()); 1077 1078 RegisterValue reg_value; 1079 1080 if (!reg_context_sp->ReadRegister(reg_info, reg_value)) 1081 return Value(); 1082 1083 Value ret; 1084 1085 ret.SetContext(Value::eContextTypeRegisterInfo, reg_info); 1086 if (!reg_value.GetScalarValue(ret.GetScalar())) 1087 return Value(); 1088 1089 return ret; 1090 } 1091 else 1092 { 1093 return Value(); 1094 } 1095 } 1096 else if (persistent_var_sp) 1097 { 1098 flags = persistent_var_sp->m_flags; 1099 1100 if ((persistent_var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference || 1101 persistent_var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) && 1102 persistent_var_sp->m_live_sp && 1103 ((persistent_var_sp->m_live_sp->GetValue().GetValueType() == Value::eValueTypeLoadAddress && 1104 m_parser_vars->m_exe_ctx.GetProcessSP() && 1105 m_parser_vars->m_exe_ctx.GetProcessSP()->IsAlive()) || 1106 (persistent_var_sp->m_live_sp->GetValue().GetValueType() == Value::eValueTypeFileAddress))) 1107 { 1108 return persistent_var_sp->m_live_sp->GetValue(); 1109 } 1110 else 1111 { 1112 lldb_private::Value ret; 1113 ret.SetValueType(Value::eValueTypeHostAddress); 1114 ret.SetContext(Value::eContextTypeInvalid, NULL); 1115 ret.GetScalar() = (lldb::addr_t)persistent_var_sp->GetValueBytes(); 1116 return ret; 1117 } 1118 } 1119 else 1120 { 1121 return Value(); 1122 } 1123} 1124 1125Value 1126ClangExpressionDeclMap::GetSpecialValue (const ConstString &name) 1127{ 1128 assert(m_parser_vars.get()); 1129 1130 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 1131 1132 if (!frame) 1133 return Value(); 1134 1135 VariableList *vars = frame->GetVariableList(false); 1136 1137 if (!vars) 1138 return Value(); 1139 1140 lldb::VariableSP var = vars->FindVariable(name); 1141 1142 if (!var || 1143 !var->IsInScope(frame) || 1144 !var->LocationIsValidForFrame (frame)) 1145 return Value(); 1146 1147 std::auto_ptr<Value> value(GetVariableValue(var, NULL)); 1148 1149 if (value.get() && value->GetValueType() == Value::eValueTypeLoadAddress) 1150 { 1151 Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); 1152 1153 if (!process) 1154 return Value(); 1155 1156 lldb::addr_t value_addr = value->GetScalar().ULongLong(); 1157 Error read_error; 1158 addr_t ptr_value = process->ReadPointerFromMemory (value_addr, read_error); 1159 1160 if (!read_error.Success()) 1161 return Value(); 1162 1163 value->GetScalar() = (unsigned long long)ptr_value; 1164 } 1165 1166 if (value.get()) 1167 return *value; 1168 else 1169 return Value(); 1170} 1171 1172// Interface for CommandObjectExpression 1173 1174bool 1175ClangExpressionDeclMap::Materialize 1176( 1177 lldb::addr_t &struct_address, 1178 Error &err 1179) 1180{ 1181 if (!m_parser_vars.get()) 1182 return false; 1183 1184 EnableMaterialVars(); 1185 1186 m_material_vars->m_process = m_parser_vars->m_exe_ctx.GetProcessPtr(); 1187 1188 bool result = DoMaterialize(false /* dematerialize */, 1189 LLDB_INVALID_ADDRESS /* top of stack frame */, 1190 LLDB_INVALID_ADDRESS /* bottom of stack frame */, 1191 NULL, /* result SP */ 1192 err); 1193 1194 if (result) 1195 struct_address = m_material_vars->m_materialized_location; 1196 1197 return result; 1198} 1199 1200bool 1201ClangExpressionDeclMap::GetObjectPointer 1202( 1203 lldb::addr_t &object_ptr, 1204 ConstString &object_name, 1205 Error &err, 1206 bool suppress_type_check 1207) 1208{ 1209 assert (m_struct_vars.get()); 1210 1211 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 1212 Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); 1213 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 1214 1215 if (frame == NULL || process == NULL || target == NULL) 1216 { 1217 err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString()); 1218 return false; 1219 } 1220 1221 if (!m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) 1222 { 1223 err.SetErrorStringWithFormat("Couldn't load '%s' because its type is unknown", object_name.AsCString()); 1224 return false; 1225 } 1226 1227 const bool object_pointer = true; 1228 1229 VariableSP object_ptr_var = FindVariableInScope (*frame, 1230 object_name, 1231 (suppress_type_check ? NULL : &m_struct_vars->m_object_pointer_type), 1232 object_pointer); 1233 1234 if (!object_ptr_var) 1235 { 1236 err.SetErrorStringWithFormat("Couldn't find '%s' with appropriate type in scope", object_name.AsCString()); 1237 return false; 1238 } 1239 1240 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(object_ptr_var, 1241 NULL)); 1242 1243 if (!location_value.get()) 1244 { 1245 err.SetErrorStringWithFormat("Couldn't get the location for '%s'", object_name.GetCString()); 1246 return false; 1247 } 1248 1249 switch (location_value->GetValueType()) 1250 { 1251 default: 1252 err.SetErrorStringWithFormat("'%s' is not in memory; LLDB must be extended to handle registers", object_name.GetCString()); 1253 return false; 1254 case Value::eValueTypeLoadAddress: 1255 { 1256 lldb::addr_t value_addr = location_value->GetScalar().ULongLong(); 1257 uint32_t address_byte_size = target->GetArchitecture().GetAddressByteSize(); 1258 1259 if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(), 1260 m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8) 1261 { 1262 err.SetErrorStringWithFormat("'%s' is not of an expected pointer size", object_name.GetCString()); 1263 return false; 1264 } 1265 1266 Error read_error; 1267 object_ptr = process->ReadPointerFromMemory (value_addr, read_error); 1268 if (read_error.Fail() || object_ptr == LLDB_INVALID_ADDRESS) 1269 { 1270 err.SetErrorStringWithFormat("Coldn't read '%s' from the target: %s", object_name.GetCString(), read_error.AsCString()); 1271 return false; 1272 } 1273 return true; 1274 } 1275 case Value::eValueTypeScalar: 1276 { 1277 if (location_value->GetContextType() != Value::eContextTypeRegisterInfo) 1278 { 1279 StreamString ss; 1280 location_value->Dump(&ss); 1281 1282 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", object_name.GetCString(), ss.GetString().c_str()); 1283 return false; 1284 } 1285 1286 RegisterInfo *reg_info = location_value->GetRegisterInfo(); 1287 1288 if (!reg_info) 1289 { 1290 err.SetErrorStringWithFormat("Couldn't get the register information for %s", object_name.GetCString()); 1291 return false; 1292 } 1293 1294 RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext(); 1295 1296 if (!reg_ctx) 1297 { 1298 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", object_name.GetCString(), reg_info->name); 1299 return false; 1300 } 1301 1302 uint32_t register_number = reg_info->kinds[lldb::eRegisterKindLLDB]; 1303 1304 object_ptr = reg_ctx->ReadRegisterAsUnsigned(register_number, 0x0); 1305 1306 return true; 1307 } 1308 } 1309} 1310 1311bool 1312ClangExpressionDeclMap::Dematerialize 1313( 1314 ClangExpressionVariableSP &result_sp, 1315 lldb::addr_t stack_frame_top, 1316 lldb::addr_t stack_frame_bottom, 1317 Error &err 1318) 1319{ 1320 return DoMaterialize(true, stack_frame_top, stack_frame_bottom, &result_sp, err); 1321 1322 DidDematerialize(); 1323} 1324 1325void 1326ClangExpressionDeclMap::DidDematerialize() 1327{ 1328 if (m_material_vars.get()) 1329 { 1330 if (m_material_vars->m_materialized_location) 1331 { 1332 //#define SINGLE_STEP_EXPRESSIONS 1333 1334#ifndef SINGLE_STEP_EXPRESSIONS 1335 m_material_vars->m_process->DeallocateMemory(m_material_vars->m_materialized_location); 1336#endif 1337 m_material_vars->m_materialized_location = 0; 1338 } 1339 1340 DisableMaterialVars(); 1341 } 1342} 1343 1344bool 1345ClangExpressionDeclMap::DumpMaterializedStruct 1346( 1347 Stream &s, 1348 Error &err 1349) 1350{ 1351 assert (m_struct_vars.get()); 1352 assert (m_material_vars.get()); 1353 1354 if (!m_struct_vars->m_struct_laid_out) 1355 { 1356 err.SetErrorString("Structure hasn't been laid out yet"); 1357 return false; 1358 } 1359 Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); 1360 1361 if (!process) 1362 { 1363 err.SetErrorString("Couldn't find the process"); 1364 return false; 1365 } 1366 1367 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 1368 if (!target) 1369 { 1370 err.SetErrorString("Couldn't find the target"); 1371 return false; 1372 } 1373 1374 if (!m_material_vars->m_materialized_location) 1375 { 1376 err.SetErrorString("No materialized location"); 1377 return false; 1378 } 1379 1380 lldb::DataBufferSP data_sp(new DataBufferHeap(m_struct_vars->m_struct_size, 0)); 1381 1382 Error error; 1383 if (process->ReadMemory (m_material_vars->m_materialized_location, 1384 data_sp->GetBytes(), 1385 data_sp->GetByteSize(), error) != data_sp->GetByteSize()) 1386 { 1387 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString()); 1388 return false; 1389 } 1390 1391 DataExtractor extractor(data_sp, process->GetByteOrder(), target->GetArchitecture().GetAddressByteSize()); 1392 1393 for (size_t member_idx = 0, num_members = m_struct_members.GetSize(); 1394 member_idx < num_members; 1395 ++member_idx) 1396 { 1397 ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_idx)); 1398 1399 if (!member_sp) 1400 return false; 1401 1402 s.Printf("[%s]\n", member_sp->GetName().GetCString()); 1403 1404 if (!member_sp->m_jit_vars.get()) 1405 return false; 1406 1407 extractor.Dump (&s, // stream 1408 member_sp->m_jit_vars->m_offset, // offset 1409 lldb::eFormatBytesWithASCII, // format 1410 1, // byte size of individual entries 1411 member_sp->m_jit_vars->m_size, // number of entries 1412 16, // entries per line 1413 m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, // address to print 1414 0, // bit size (bitfields only; 0 means ignore) 1415 0); // bit alignment (bitfields only; 0 means ignore) 1416 1417 s.PutChar('\n'); 1418 } 1419 1420 return true; 1421} 1422 1423bool 1424ClangExpressionDeclMap::DoMaterialize 1425( 1426 bool dematerialize, 1427 lldb::addr_t stack_frame_top, 1428 lldb::addr_t stack_frame_bottom, 1429 lldb::ClangExpressionVariableSP *result_sp_ptr, 1430 Error &err 1431) 1432{ 1433 if (result_sp_ptr) 1434 result_sp_ptr->reset(); 1435 1436 assert (m_struct_vars.get()); 1437 1438 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1439 1440 if (!m_struct_vars->m_struct_laid_out) 1441 { 1442 err.SetErrorString("Structure hasn't been laid out yet"); 1443 return false; 1444 } 1445 1446 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 1447 if (!frame) 1448 { 1449 err.SetErrorString("Received null execution frame"); 1450 return false; 1451 } 1452 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 1453 1454 ClangPersistentVariables &persistent_vars = target->GetPersistentVariables(); 1455 1456 if (!m_struct_vars->m_struct_size) 1457 { 1458 if (log) 1459 log->PutCString("Not bothering to allocate a struct because no arguments are needed"); 1460 1461 m_material_vars->m_allocated_area = 0UL; 1462 1463 return true; 1464 } 1465 1466 const SymbolContext &sym_ctx(frame->GetSymbolContext(lldb::eSymbolContextEverything)); 1467 1468 if (!dematerialize) 1469 { 1470 Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); 1471 if (m_material_vars->m_materialized_location) 1472 { 1473 process->DeallocateMemory(m_material_vars->m_materialized_location); 1474 m_material_vars->m_materialized_location = 0; 1475 } 1476 1477 if (log) 1478 log->PutCString("Allocating memory for materialized argument struct"); 1479 1480 lldb::addr_t mem = process->AllocateMemory(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size, 1481 lldb::ePermissionsReadable | lldb::ePermissionsWritable, 1482 err); 1483 1484 if (mem == LLDB_INVALID_ADDRESS) 1485 { 1486 err.SetErrorStringWithFormat("Couldn't allocate 0x%llx bytes for materialized argument struct", 1487 (unsigned long long)(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size)); 1488 return false; 1489 } 1490 1491 m_material_vars->m_allocated_area = mem; 1492 } 1493 1494 m_material_vars->m_materialized_location = m_material_vars->m_allocated_area; 1495 1496 if (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment) 1497 m_material_vars->m_materialized_location += (m_struct_vars->m_struct_alignment - (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment)); 1498 1499 for (uint64_t member_index = 0, num_members = m_struct_members.GetSize(); 1500 member_index < num_members; 1501 ++member_index) 1502 { 1503 ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index)); 1504 1505 if (m_found_entities.ContainsVariable (member_sp)) 1506 { 1507 if (!member_sp->GetValueObject()) 1508 { 1509 err.SetErrorString("Variable being materialized doesn't have a frozen version"); 1510 return false; 1511 } 1512 1513 RegisterInfo *reg_info = member_sp->GetRegisterInfo (); 1514 if (reg_info) 1515 { 1516 // This is a register variable 1517 1518 RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext(); 1519 1520 if (!reg_ctx) 1521 { 1522 err.SetErrorString("Couldn't get register context"); 1523 return false; 1524 } 1525 1526 if (!DoMaterializeOneRegister (dematerialize, 1527 *reg_ctx, 1528 *reg_info, 1529 m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, 1530 err)) 1531 return false; 1532 } 1533 else 1534 { 1535 if (!member_sp->m_jit_vars.get()) 1536 { 1537 err.SetErrorString("Variable being materialized doesn't have necessary state"); 1538 return false; 1539 } 1540 1541 if (!DoMaterializeOneVariable (dematerialize, 1542 sym_ctx, 1543 member_sp, 1544 m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, 1545 err)) 1546 return false; 1547 } 1548 } 1549 else 1550 { 1551 // No need to look for presistent variables if the name doesn't start 1552 // with with a '$' character... 1553 if (member_sp->GetName().AsCString ("!")[0] == '$' && persistent_vars.ContainsVariable(member_sp)) 1554 { 1555 1556 if (member_sp->GetName() == m_struct_vars->m_result_name) 1557 { 1558 if (log) 1559 log->PutCString("Found result member in the struct"); 1560 1561 if (result_sp_ptr) 1562 *result_sp_ptr = member_sp; 1563 1564 } 1565 1566 if (!DoMaterializeOnePersistentVariable (dematerialize, 1567 member_sp, 1568 m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, 1569 stack_frame_top, 1570 stack_frame_bottom, 1571 err)) 1572 return false; 1573 } 1574 else 1575 { 1576 err.SetErrorStringWithFormat("Unexpected variable %s", member_sp->GetName().GetCString()); 1577 return false; 1578 } 1579 } 1580 } 1581 1582 return true; 1583} 1584 1585bool 1586ClangExpressionDeclMap::DoMaterializeOnePersistentVariable 1587( 1588 bool dematerialize, 1589 ClangExpressionVariableSP &var_sp, 1590 lldb::addr_t addr, 1591 lldb::addr_t stack_frame_top, 1592 lldb::addr_t stack_frame_bottom, 1593 Error &err 1594) 1595{ 1596 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1597 1598 if (!var_sp) 1599 { 1600 err.SetErrorString("Invalid persistent variable"); 1601 return LLDB_INVALID_ADDRESS; 1602 } 1603 1604 const size_t pvar_byte_size = var_sp->GetByteSize(); 1605 1606 uint8_t *pvar_data = var_sp->GetValueBytes(); 1607 if (pvar_data == NULL) 1608 { 1609 err.SetErrorString("Persistent variable being materialized contains no data"); 1610 return false; 1611 } 1612 1613 Error error; 1614 Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); 1615 1616 lldb::addr_t mem; // The address of a spare memory area used to hold the persistent variable. 1617 1618 if (dematerialize) 1619 { 1620 if (log) 1621 log->Printf("Dematerializing persistent variable with flags 0x%hx", var_sp->m_flags); 1622 1623 if ((var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) || 1624 (var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference)) 1625 { 1626 // Get the location of the target out of the struct. 1627 1628 Error read_error; 1629 mem = process->ReadPointerFromMemory (addr, read_error); 1630 1631 if (mem == LLDB_INVALID_ADDRESS) 1632 { 1633 err.SetErrorStringWithFormat("Couldn't read address of %s from struct: %s", var_sp->GetName().GetCString(), error.AsCString()); 1634 return false; 1635 } 1636 1637 if (var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && 1638 !var_sp->m_live_sp) 1639 { 1640 // If the reference comes from the program, then the ClangExpressionVariable's 1641 // live variable data hasn't been set up yet. Do this now. 1642 1643 var_sp->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (), 1644 var_sp->GetTypeFromUser().GetASTContext(), 1645 var_sp->GetTypeFromUser().GetOpaqueQualType(), 1646 var_sp->GetName(), 1647 mem, 1648 eAddressTypeLoad, 1649 pvar_byte_size); 1650 } 1651 1652 if (!var_sp->m_live_sp) 1653 { 1654 err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", var_sp->GetName().GetCString()); 1655 return false; 1656 } 1657 1658 if (var_sp->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad) 1659 { 1660 err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", var_sp->GetName().GetCString()); 1661 return false; 1662 } 1663 1664 if (var_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry || 1665 var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget) 1666 { 1667 mem = var_sp->m_live_sp->GetValue().GetScalar().ULongLong(); 1668 1669 if (log) 1670 log->Printf("Dematerializing %s from 0x%llx (size = %u)", var_sp->GetName().GetCString(), (uint64_t)mem, (unsigned)pvar_byte_size); 1671 1672 // Read the contents of the spare memory area 1673 1674 var_sp->ValueUpdated (); 1675 if (process->ReadMemory (mem, pvar_data, pvar_byte_size, error) != pvar_byte_size) 1676 { 1677 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString()); 1678 return false; 1679 } 1680 1681 if (stack_frame_top != LLDB_INVALID_ADDRESS && 1682 stack_frame_bottom != LLDB_INVALID_ADDRESS && 1683 mem >= stack_frame_bottom && 1684 mem <= stack_frame_top) 1685 { 1686 // If the variable is resident in the stack frame created by the expression, 1687 // then it cannot be relied upon to stay around. We treat it as needing 1688 // reallocation. 1689 1690 var_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 1691 var_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 1692 var_sp->m_flags &= ~ClangExpressionVariable::EVIsProgramReference; 1693 } 1694 1695 var_sp->m_flags &= ~ClangExpressionVariable::EVNeedsFreezeDry; 1696 } 1697 1698 if (var_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation && 1699 !(var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)) 1700 { 1701 if (m_keep_result_in_memory) 1702 { 1703 var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget; 1704 } 1705 else 1706 { 1707 Error deallocate_error = process->DeallocateMemory(mem); 1708 1709 if (!err.Success()) 1710 { 1711 err.SetErrorStringWithFormat ("Couldn't deallocate memory for %s: %s", var_sp->GetName().GetCString(), deallocate_error.AsCString()); 1712 return false; 1713 } 1714 } 1715 } 1716 } 1717 else 1718 { 1719 err.SetErrorStringWithFormat("Persistent variables without separate allocations are not currently supported."); 1720 return false; 1721 } 1722 } 1723 else 1724 { 1725 if (log) 1726 log->Printf("Materializing persistent variable with flags 0x%hx", var_sp->m_flags); 1727 1728 if (var_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation) 1729 { 1730 // Allocate a spare memory area to store the persistent variable's contents. 1731 1732 Error allocate_error; 1733 1734 mem = process->AllocateMemory(pvar_byte_size, 1735 lldb::ePermissionsReadable | lldb::ePermissionsWritable, 1736 allocate_error); 1737 1738 if (mem == LLDB_INVALID_ADDRESS) 1739 { 1740 err.SetErrorStringWithFormat("Couldn't allocate a memory area to store %s: %s", var_sp->GetName().GetCString(), allocate_error.AsCString()); 1741 return false; 1742 } 1743 1744 if (log) 1745 log->Printf("Allocated %s (0x%llx) sucessfully", var_sp->GetName().GetCString(), mem); 1746 1747 // Put the location of the spare memory into the live data of the ValueObject. 1748 1749 var_sp->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), 1750 var_sp->GetTypeFromUser().GetASTContext(), 1751 var_sp->GetTypeFromUser().GetOpaqueQualType(), 1752 var_sp->GetName(), 1753 mem, 1754 eAddressTypeLoad, 1755 pvar_byte_size); 1756 1757 // Clear the flag if the variable will never be deallocated. 1758 1759 if (var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget) 1760 var_sp->m_flags &= ~ClangExpressionVariable::EVNeedsAllocation; 1761 1762 // Write the contents of the variable to the area. 1763 1764 if (process->WriteMemory (mem, pvar_data, pvar_byte_size, error) != pvar_byte_size) 1765 { 1766 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString()); 1767 return false; 1768 } 1769 } 1770 1771 if ((var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && var_sp->m_live_sp) || 1772 var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) 1773 { 1774 // Now write the location of the area into the struct. 1775 Error write_error; 1776 if (!process->WriteScalarToMemory (addr, 1777 var_sp->m_live_sp->GetValue().GetScalar(), 1778 process->GetAddressByteSize(), 1779 write_error)) 1780 { 1781 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", var_sp->GetName().GetCString(), write_error.AsCString()); 1782 return false; 1783 } 1784 1785 if (log) 1786 log->Printf("Materialized %s into 0x%llx", var_sp->GetName().GetCString(), var_sp->m_live_sp->GetValue().GetScalar().ULongLong()); 1787 } 1788 else if (!(var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference)) 1789 { 1790 err.SetErrorStringWithFormat("Persistent variables without separate allocations are not currently supported."); 1791 return false; 1792 } 1793 } 1794 1795 return true; 1796} 1797 1798bool 1799ClangExpressionDeclMap::DoMaterializeOneVariable 1800( 1801 bool dematerialize, 1802 const SymbolContext &sym_ctx, 1803 ClangExpressionVariableSP &expr_var, 1804 lldb::addr_t addr, 1805 Error &err 1806) 1807{ 1808 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1809 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 1810 Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); 1811 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 1812 1813 if (!frame || !process || !target || !m_parser_vars.get() || !expr_var->m_parser_vars.get()) 1814 { 1815 err.SetErrorString("Necessary state for variable materialization isn't present"); 1816 return false; 1817 } 1818 1819 // Vital information about the value 1820 1821 const ConstString &name(expr_var->GetName()); 1822 TypeFromUser type(expr_var->GetTypeFromUser()); 1823 1824 VariableSP &var(expr_var->m_parser_vars->m_lldb_var); 1825 lldb_private::Symbol *sym(expr_var->m_parser_vars->m_lldb_sym); 1826 1827 bool is_reference(expr_var->m_flags & ClangExpressionVariable::EVTypeIsReference); 1828 1829 std::auto_ptr<lldb_private::Value> location_value; 1830 1831 if (var) 1832 { 1833 location_value.reset(GetVariableValue(var, 1834 NULL)); 1835 } 1836 else if (sym) 1837 { 1838 addr_t location_load_addr = GetSymbolAddress(*target, name, lldb::eSymbolTypeAny); 1839 1840 if (location_load_addr == LLDB_INVALID_ADDRESS) 1841 { 1842 if (log) 1843 err.SetErrorStringWithFormat ("Couldn't find value for global symbol %s", 1844 name.GetCString()); 1845 } 1846 1847 location_value.reset(new Value); 1848 1849 location_value->SetValueType(Value::eValueTypeLoadAddress); 1850 location_value->GetScalar() = location_load_addr; 1851 } 1852 else 1853 { 1854 err.SetErrorStringWithFormat ("Couldn't find %s with appropriate type", 1855 name.GetCString()); 1856 return false; 1857 } 1858 1859 if (log) 1860 { 1861 StreamString my_stream_string; 1862 1863 ClangASTType::DumpTypeDescription (type.GetASTContext(), 1864 type.GetOpaqueQualType(), 1865 &my_stream_string); 1866 1867 log->Printf ("%s %s with type %s", 1868 dematerialize ? "Dematerializing" : "Materializing", 1869 name.GetCString(), 1870 my_stream_string.GetString().c_str()); 1871 } 1872 1873 if (!location_value.get()) 1874 { 1875 err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString()); 1876 return false; 1877 } 1878 1879 // The size of the type contained in addr 1880 1881 size_t value_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType()); 1882 size_t value_byte_size = value_bit_size % 8 ? ((value_bit_size + 8) / 8) : (value_bit_size / 8); 1883 1884 Value::ValueType value_type = location_value->GetValueType(); 1885 1886 switch (value_type) 1887 { 1888 default: 1889 { 1890 StreamString ss; 1891 1892 location_value->Dump(&ss); 1893 1894 err.SetErrorStringWithFormat ("%s has a value of unhandled type: %s", 1895 name.GetCString(), 1896 ss.GetString().c_str()); 1897 return false; 1898 } 1899 break; 1900 case Value::eValueTypeLoadAddress: 1901 { 1902 if (!dematerialize) 1903 { 1904 Error write_error; 1905 1906 if (is_reference) 1907 { 1908 Error read_error; 1909 1910 addr_t ref_value = process->ReadPointerFromMemory(location_value->GetScalar().ULongLong(), read_error); 1911 1912 if (!read_error.Success()) 1913 { 1914 err.SetErrorStringWithFormat ("Couldn't read reference to %s from the target: %s", 1915 name.GetCString(), 1916 read_error.AsCString()); 1917 return false; 1918 } 1919 1920 if (!process->WritePointerToMemory(addr, 1921 ref_value, 1922 write_error)) 1923 { 1924 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 1925 name.GetCString(), 1926 write_error.AsCString()); 1927 return false; 1928 } 1929 } 1930 else 1931 { 1932 if (!process->WriteScalarToMemory (addr, 1933 location_value->GetScalar(), 1934 process->GetAddressByteSize(), 1935 write_error)) 1936 { 1937 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 1938 name.GetCString(), 1939 write_error.AsCString()); 1940 return false; 1941 } 1942 } 1943 } 1944 } 1945 break; 1946 case Value::eValueTypeScalar: 1947 { 1948 if (location_value->GetContextType() != Value::eContextTypeRegisterInfo) 1949 { 1950 StreamString ss; 1951 location_value->Dump(&ss); 1952 1953 err.SetErrorStringWithFormat ("%s is a scalar of unhandled type: %s", 1954 name.GetCString(), 1955 ss.GetString().c_str()); 1956 return false; 1957 } 1958 1959 RegisterInfo *reg_info = location_value->GetRegisterInfo(); 1960 1961 if (!reg_info) 1962 { 1963 err.SetErrorStringWithFormat ("Couldn't get the register information for %s", 1964 name.GetCString()); 1965 return false; 1966 } 1967 1968 RegisterValue reg_value; 1969 1970 RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext(); 1971 1972 if (!reg_ctx) 1973 { 1974 err.SetErrorStringWithFormat ("Couldn't read register context to read %s from %s", 1975 name.GetCString(), 1976 reg_info->name); 1977 return false; 1978 } 1979 1980 uint32_t register_byte_size = reg_info->byte_size; 1981 1982 if (dematerialize) 1983 { 1984 if (is_reference) 1985 return true; // reference types don't need demateralizing 1986 1987 // Get the location of the spare memory area out of the variable's live data. 1988 1989 if (!expr_var->m_live_sp) 1990 { 1991 err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", name.GetCString()); 1992 return false; 1993 } 1994 1995 if (expr_var->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad) 1996 { 1997 err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", name.GetCString()); 1998 return false; 1999 } 2000 2001 Scalar ®_addr = expr_var->m_live_sp->GetValue().GetScalar(); 2002 2003 err = reg_ctx->ReadRegisterValueFromMemory (reg_info, 2004 reg_addr.ULongLong(), 2005 value_byte_size, 2006 reg_value); 2007 if (err.Fail()) 2008 return false; 2009 2010 if (!reg_ctx->WriteRegister (reg_info, reg_value)) 2011 { 2012 err.SetErrorStringWithFormat ("Couldn't write %s to register %s", 2013 name.GetCString(), 2014 reg_info->name); 2015 return false; 2016 } 2017 2018 // Deallocate the spare area and clear the variable's live data. 2019 2020 Error deallocate_error = process->DeallocateMemory(reg_addr.ULongLong()); 2021 2022 if (!deallocate_error.Success()) 2023 { 2024 err.SetErrorStringWithFormat ("Couldn't deallocate spare memory area for %s: %s", 2025 name.GetCString(), 2026 deallocate_error.AsCString()); 2027 return false; 2028 } 2029 2030 expr_var->m_live_sp.reset(); 2031 } 2032 else 2033 { 2034 Error write_error; 2035 2036 RegisterValue reg_value; 2037 2038 if (!reg_ctx->ReadRegister (reg_info, reg_value)) 2039 { 2040 err.SetErrorStringWithFormat ("Couldn't read %s from %s", 2041 name.GetCString(), 2042 reg_info->name); 2043 return false; 2044 } 2045 2046 if (is_reference) 2047 { 2048 write_error = reg_ctx->WriteRegisterValueToMemory(reg_info, 2049 addr, 2050 process->GetAddressByteSize(), 2051 reg_value); 2052 2053 if (!write_error.Success()) 2054 { 2055 err.SetErrorStringWithFormat ("Couldn't write %s from register %s to the target: %s", 2056 name.GetCString(), 2057 reg_info->name, 2058 write_error.AsCString()); 2059 return false; 2060 } 2061 2062 return true; 2063 } 2064 2065 // Allocate a spare memory area to place the register's contents into. This memory area will be pointed to by the slot in the 2066 // struct. 2067 2068 Error allocate_error; 2069 2070 Scalar reg_addr (process->AllocateMemory (value_byte_size, 2071 lldb::ePermissionsReadable | lldb::ePermissionsWritable, 2072 allocate_error)); 2073 2074 if (reg_addr.ULongLong() == LLDB_INVALID_ADDRESS) 2075 { 2076 err.SetErrorStringWithFormat ("Couldn't allocate a memory area to store %s: %s", 2077 name.GetCString(), 2078 allocate_error.AsCString()); 2079 return false; 2080 } 2081 2082 // Put the location of the spare memory into the live data of the ValueObject. 2083 2084 expr_var->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), 2085 type.GetASTContext(), 2086 type.GetOpaqueQualType(), 2087 name, 2088 reg_addr.ULongLong(), 2089 eAddressTypeLoad, 2090 value_byte_size); 2091 2092 // Now write the location of the area into the struct. 2093 2094 if (!process->WriteScalarToMemory (addr, 2095 reg_addr, 2096 process->GetAddressByteSize(), 2097 write_error)) 2098 { 2099 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", 2100 name.GetCString(), 2101 write_error.AsCString()); 2102 return false; 2103 } 2104 2105 if (value_byte_size > register_byte_size) 2106 { 2107 err.SetErrorStringWithFormat ("%s is too big to store in %s", 2108 name.GetCString(), 2109 reg_info->name); 2110 return false; 2111 } 2112 2113 if (!reg_ctx->ReadRegister (reg_info, reg_value)) 2114 { 2115 err.SetErrorStringWithFormat ("Couldn't read %s from %s", 2116 name.GetCString(), 2117 reg_info->name); 2118 return false; 2119 } 2120 2121 err = reg_ctx->WriteRegisterValueToMemory (reg_info, 2122 reg_addr.ULongLong(), 2123 value_byte_size, 2124 reg_value); 2125 if (err.Fail()) 2126 return false; 2127 } 2128 } 2129 } 2130 2131 return true; 2132} 2133 2134bool 2135ClangExpressionDeclMap::DoMaterializeOneRegister 2136( 2137 bool dematerialize, 2138 RegisterContext ®_ctx, 2139 const RegisterInfo ®_info, 2140 lldb::addr_t addr, 2141 Error &err 2142) 2143{ 2144 uint32_t register_byte_size = reg_info.byte_size; 2145 RegisterValue reg_value; 2146 if (dematerialize) 2147 { 2148 Error read_error (reg_ctx.ReadRegisterValueFromMemory(®_info, addr, register_byte_size, reg_value)); 2149 if (read_error.Fail()) 2150 { 2151 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", reg_info.name, read_error.AsCString()); 2152 return false; 2153 } 2154 2155 if (!reg_ctx.WriteRegister (®_info, reg_value)) 2156 { 2157 err.SetErrorStringWithFormat("Couldn't write register %s (dematerialize)", reg_info.name); 2158 return false; 2159 } 2160 } 2161 else 2162 { 2163 2164 if (!reg_ctx.ReadRegister(®_info, reg_value)) 2165 { 2166 err.SetErrorStringWithFormat("Couldn't read %s (materialize)", reg_info.name); 2167 return false; 2168 } 2169 2170 Error write_error (reg_ctx.WriteRegisterValueToMemory(®_info, addr, register_byte_size, reg_value)); 2171 if (write_error.Fail()) 2172 { 2173 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", reg_info.name, write_error.AsCString()); 2174 return false; 2175 } 2176 } 2177 2178 return true; 2179} 2180 2181lldb::VariableSP 2182ClangExpressionDeclMap::FindVariableInScope 2183( 2184 StackFrame &frame, 2185 const ConstString &name, 2186 TypeFromUser *type, 2187 bool object_pointer 2188) 2189{ 2190 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 2191 2192 ValueObjectSP valobj; 2193 VariableSP var_sp; 2194 Error err; 2195 2196 valobj = frame.GetValueForVariableExpressionPath(name.GetCString(), 2197 eNoDynamicValues, 2198 StackFrame::eExpressionPathOptionCheckPtrVsMember, 2199 var_sp, 2200 err); 2201 2202 if (!err.Success() || 2203 !var_sp || 2204 !var_sp->IsInScope(&frame) || 2205 !var_sp->LocationIsValidForFrame (&frame)) 2206 return lldb::VariableSP(); 2207 2208 if (var_sp) 2209 { 2210 if (!type) 2211 return var_sp; 2212 2213 TypeFromUser candidate_type(var_sp->GetType()->GetClangFullType(), 2214 var_sp->GetType()->GetClangAST()); 2215 2216 if (candidate_type.GetASTContext() != type->GetASTContext()) 2217 { 2218 if (log) 2219 log->PutCString("Skipping a candidate variable because of different AST contexts"); 2220 return lldb::VariableSP(); 2221 } 2222 2223 if (object_pointer) 2224 { 2225 clang::QualType desired_qual_type = clang::QualType::getFromOpaquePtr(type->GetOpaqueQualType()); 2226 clang::QualType candidate_qual_type = clang::QualType::getFromOpaquePtr(candidate_type.GetOpaqueQualType()); 2227 2228 const clang::ObjCObjectPointerType *desired_objc_ptr_type = desired_qual_type->getAs<clang::ObjCObjectPointerType>(); 2229 const clang::ObjCObjectPointerType *candidate_objc_ptr_type = desired_qual_type->getAs<clang::ObjCObjectPointerType>(); 2230 2231 if (desired_objc_ptr_type && candidate_objc_ptr_type) { 2232 clang::QualType desired_target_type = desired_objc_ptr_type->getPointeeType().getUnqualifiedType(); 2233 clang::QualType candidate_target_type = candidate_objc_ptr_type->getPointeeType().getUnqualifiedType(); 2234 2235 if (ClangASTContext::AreTypesSame(type->GetASTContext(), 2236 desired_target_type.getAsOpaquePtr(), 2237 candidate_target_type.getAsOpaquePtr())) 2238 return var_sp; 2239 } 2240 2241 const clang::PointerType *desired_ptr_type = desired_qual_type->getAs<clang::PointerType>(); 2242 const clang::PointerType *candidate_ptr_type = candidate_qual_type->getAs<clang::PointerType>(); 2243 2244 if (desired_ptr_type && candidate_ptr_type) { 2245 clang::QualType desired_target_type = desired_ptr_type->getPointeeType().getUnqualifiedType(); 2246 clang::QualType candidate_target_type = candidate_ptr_type->getPointeeType().getUnqualifiedType(); 2247 2248 if (ClangASTContext::AreTypesSame(type->GetASTContext(), 2249 desired_target_type.getAsOpaquePtr(), 2250 candidate_target_type.getAsOpaquePtr())) 2251 return var_sp; 2252 } 2253 2254 return lldb::VariableSP(); 2255 } 2256 else 2257 { 2258 if (ClangASTContext::AreTypesSame(type->GetASTContext(), 2259 type->GetOpaqueQualType(), 2260 var_sp->GetType()->GetClangFullType())) 2261 return var_sp; 2262 } 2263 } 2264 2265 return lldb::VariableSP(); 2266} 2267 2268Symbol * 2269ClangExpressionDeclMap::FindGlobalDataSymbol 2270( 2271 Target &target, 2272 const ConstString &name 2273) 2274{ 2275 SymbolContextList sc_list; 2276 2277 target.GetImages().FindSymbolsWithNameAndType(name, 2278 eSymbolTypeData, 2279 sc_list); 2280 2281 if (sc_list.GetSize()) 2282 { 2283 SymbolContext sym_ctx; 2284 sc_list.GetContextAtIndex(0, sym_ctx); 2285 2286 return sym_ctx.symbol; 2287 } 2288 2289 return NULL; 2290} 2291 2292lldb::VariableSP 2293ClangExpressionDeclMap::FindGlobalVariable 2294( 2295 Target &target, 2296 ModuleSP &module, 2297 const ConstString &name, 2298 ClangNamespaceDecl *namespace_decl, 2299 TypeFromUser *type 2300) 2301{ 2302 VariableList vars; 2303 2304 if (module && namespace_decl) 2305 module->FindGlobalVariables (name, namespace_decl, true, -1, vars); 2306 else 2307 target.GetImages().FindGlobalVariables(name, true, -1, vars); 2308 2309 if (vars.GetSize()) 2310 { 2311 if (type) 2312 { 2313 for (size_t i = 0; i < vars.GetSize(); ++i) 2314 { 2315 VariableSP var_sp = vars.GetVariableAtIndex(i); 2316 2317 if (type->GetASTContext() == var_sp->GetType()->GetClangAST()) 2318 { 2319 if (ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var_sp->GetType()->GetClangFullType())) 2320 return var_sp; 2321 } 2322 } 2323 } 2324 else 2325 { 2326 return vars.GetVariableAtIndex(0); 2327 } 2328 } 2329 2330 return VariableSP(); 2331} 2332 2333// Interface for ClangASTSource 2334 2335void 2336ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context) 2337{ 2338 assert (m_ast_context); 2339 2340 const ConstString name(context.m_decl_name.getAsString().c_str()); 2341 2342 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 2343 2344 if (GetImportInProgress()) 2345 { 2346 if (log && log->GetVerbose()) 2347 log->Printf("Ignoring a query during an import"); 2348 return; 2349 } 2350 2351 static unsigned int invocation_id = 0; 2352 unsigned int current_id = invocation_id++; 2353 2354 if (log) 2355 { 2356 if (!context.m_decl_context) 2357 log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a NULL DeclContext", current_id, name.GetCString()); 2358 else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context)) 2359 log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in '%s'", current_id, name.GetCString(), context_named_decl->getNameAsString().c_str()); 2360 else 2361 log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a '%s'", current_id, name.GetCString(), context.m_decl_context->getDeclKindName()); 2362 } 2363 2364 if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context)) 2365 { 2366 ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context); 2367 2368 if (log && log->GetVerbose()) 2369 log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)", 2370 current_id, 2371 namespace_map.get(), 2372 (int)namespace_map->size()); 2373 2374 if (!namespace_map) 2375 return; 2376 2377 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end(); 2378 i != e; 2379 ++i) 2380 { 2381 if (log) 2382 log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s", 2383 current_id, 2384 i->second.GetNamespaceDecl()->getNameAsString().c_str(), 2385 i->first->GetFileSpec().GetFilename().GetCString()); 2386 2387 FindExternalVisibleDecls(context, 2388 i->first, 2389 i->second, 2390 current_id); 2391 } 2392 } 2393 else if (isa<TranslationUnitDecl>(context.m_decl_context)) 2394 { 2395 ClangNamespaceDecl namespace_decl; 2396 2397 if (log) 2398 log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id); 2399 2400 FindExternalVisibleDecls(context, 2401 lldb::ModuleSP(), 2402 namespace_decl, 2403 current_id); 2404 } 2405 2406 if (!context.m_found.variable) 2407 ClangASTSource::FindExternalVisibleDecls(context); 2408} 2409 2410void 2411ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context, 2412 lldb::ModuleSP module_sp, 2413 ClangNamespaceDecl &namespace_decl, 2414 unsigned int current_id) 2415{ 2416 assert (m_ast_context); 2417 2418 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 2419 2420 SymbolContextList sc_list; 2421 2422 const ConstString name(context.m_decl_name.getAsString().c_str()); 2423 2424 const char *name_unique_cstr = name.GetCString(); 2425 2426 if (name_unique_cstr == NULL) 2427 return; 2428 2429 static ConstString id_name("id"); 2430 static ConstString Class_name("Class"); 2431 2432 if (name == id_name || name == Class_name) 2433 return; 2434 2435 // Only look for functions by name out in our symbols if the function 2436 // doesn't start with our phony prefix of '$' 2437 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 2438 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 2439 if (name_unique_cstr[0] == '$' && !namespace_decl) 2440 { 2441 static ConstString g_lldb_class_name ("$__lldb_class"); 2442 2443 if (name == g_lldb_class_name) 2444 { 2445 // Clang is looking for the type of "this" 2446 2447 if (frame == NULL) 2448 return; 2449 2450 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction); 2451 2452 if (!sym_ctx.function) 2453 return; 2454 2455 // Get the block that defines the function 2456 Block *function_block = sym_ctx.GetFunctionBlock(); 2457 2458 if (!function_block) 2459 return; 2460 2461 clang::DeclContext *decl_context = function_block->GetClangDeclContext(); 2462 2463 if (!decl_context) 2464 return; 2465 2466 clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context); 2467 2468 if (!method_decl) 2469 return; 2470 2471 clang::CXXRecordDecl *class_decl = method_decl->getParent(); 2472 2473 QualType class_qual_type(class_decl->getTypeForDecl(), 0); 2474 2475 TypeFromUser class_user_type (class_qual_type.getAsOpaquePtr(), 2476 &class_decl->getASTContext()); 2477 2478 if (log) 2479 { 2480 ASTDumper ast_dumper(class_qual_type); 2481 log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString()); 2482 } 2483 2484 AddOneType(context, class_user_type, current_id, true); 2485 2486 if (method_decl->isInstance()) 2487 { 2488 // self is a pointer to the object 2489 2490 QualType class_pointer_type = method_decl->getASTContext().getPointerType(class_qual_type); 2491 2492 TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(), 2493 &method_decl->getASTContext()); 2494 2495 m_struct_vars->m_object_pointer_type = self_user_type; 2496 } 2497 2498 return; 2499 } 2500 2501 static ConstString g_lldb_objc_class_name ("$__lldb_objc_class"); 2502 if (name == g_lldb_objc_class_name) 2503 { 2504 // Clang is looking for the type of "*self" 2505 2506 if (!frame) 2507 return; 2508 2509 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction); 2510 2511 if (!sym_ctx.function) 2512 return; 2513 2514 // Get the block that defines the function 2515 Block *function_block = sym_ctx.GetFunctionBlock(); 2516 2517 if (!function_block) 2518 return; 2519 2520 clang::DeclContext *decl_context = function_block->GetClangDeclContext(); 2521 2522 if (!decl_context) 2523 return; 2524 2525 clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context); 2526 2527 if (!method_decl) 2528 return; 2529 2530 ObjCInterfaceDecl* self_interface = method_decl->getClassInterface(); 2531 2532 if (!self_interface) 2533 return; 2534 2535 const clang::Type *interface_type = self_interface->getTypeForDecl(); 2536 2537 TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(), 2538 &method_decl->getASTContext()); 2539 2540 if (log) 2541 { 2542 ASTDumper ast_dumper(interface_type); 2543 log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString()); 2544 } 2545 2546 AddOneType(context, class_user_type, current_id, false); 2547 2548#if 0 2549 VariableList *vars = frame->GetVariableList(false); 2550 2551 lldb::VariableSP self_var = vars->FindVariable(ConstString("self")); 2552 2553 if (self_var && 2554 self_var->IsInScope(frame) && 2555 self_var->LocationIsValidForFrame (frame)) { 2556 Type *self_type = self_var->GetType(); 2557 2558 if (!self_type) 2559 return; 2560 2561 TypeFromUser self_user_type(self_type->GetClangFullType(), 2562 self_type->GetClangAST()); 2563 } 2564#endif 2565 2566 if (method_decl->isInstanceMethod()) 2567 { 2568 // self is a pointer to the object 2569 2570 QualType class_pointer_type = method_decl->getASTContext().getObjCObjectPointerType(QualType(interface_type, 0)); 2571 2572 TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(), 2573 &method_decl->getASTContext()); 2574 2575 m_struct_vars->m_object_pointer_type = self_user_type; 2576 } 2577 else 2578 { 2579 // self is a Class pointer 2580 QualType class_type = method_decl->getASTContext().getObjCClassType(); 2581 2582 TypeFromUser self_user_type(class_type.getAsOpaquePtr(), 2583 &method_decl->getASTContext()); 2584 2585 m_struct_vars->m_object_pointer_type = self_user_type; 2586 } 2587 2588 return; 2589 } 2590 2591 // any other $__lldb names should be weeded out now 2592 if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1)) 2593 return; 2594 2595 do 2596 { 2597 if (!target) 2598 break; 2599 2600 ClangASTContext *scratch_clang_ast_context = target->GetScratchClangASTContext(); 2601 2602 if (!scratch_clang_ast_context) 2603 break; 2604 2605 ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext(); 2606 2607 if (!scratch_ast_context) 2608 break; 2609 2610 TypeDecl *ptype_type_decl = m_parser_vars->m_persistent_vars->GetPersistentType(name); 2611 2612 if (!ptype_type_decl) 2613 break; 2614 2615 Decl *parser_ptype_decl = m_ast_importer->CopyDecl(m_ast_context, scratch_ast_context, ptype_type_decl); 2616 2617 if (!parser_ptype_decl) 2618 break; 2619 2620 TypeDecl *parser_ptype_type_decl = dyn_cast<TypeDecl>(parser_ptype_decl); 2621 2622 if (!parser_ptype_type_decl) 2623 break; 2624 2625 if (log) 2626 log->Printf(" CEDM::FEVD[%u] Found persistent type %s", current_id, name.GetCString()); 2627 2628 context.AddNamedDecl(parser_ptype_type_decl); 2629 } while (0); 2630 2631 ClangExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name)); 2632 2633 if (pvar_sp) 2634 { 2635 AddOneVariable(context, pvar_sp, current_id); 2636 return; 2637 } 2638 2639 const char *reg_name(&name.GetCString()[1]); 2640 2641 if (m_parser_vars->m_exe_ctx.GetRegisterContext()) 2642 { 2643 const RegisterInfo *reg_info(m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(reg_name)); 2644 2645 if (reg_info) 2646 { 2647 if (log) 2648 log->Printf(" CEDM::FEVD[%u] Found register %s", current_id, reg_info->name); 2649 2650 AddOneRegister(context, reg_info, current_id); 2651 } 2652 } 2653 } 2654 else 2655 { 2656 ValueObjectSP valobj; 2657 VariableSP var; 2658 Error err; 2659 2660 if (frame && !namespace_decl) 2661 { 2662 valobj = frame->GetValueForVariableExpressionPath(name_unique_cstr, 2663 eNoDynamicValues, 2664 StackFrame::eExpressionPathOptionCheckPtrVsMember, 2665 var, 2666 err); 2667 2668 // If we found a variable in scope, no need to pull up function names 2669 if (err.Success() && var) 2670 { 2671 AddOneVariable(context, var, valobj, current_id); 2672 context.m_found.variable = true; 2673 return; 2674 } 2675 } 2676 2677 if (target) 2678 { 2679 var = FindGlobalVariable (*target, 2680 module_sp, 2681 name, 2682 &namespace_decl, 2683 NULL); 2684 2685 if (var) 2686 { 2687 valobj = ValueObjectVariable::Create(target, var); 2688 AddOneVariable(context, var, valobj, current_id); 2689 context.m_found.variable = true; 2690 return; 2691 } 2692 } 2693 2694 if (!context.m_found.variable) 2695 { 2696 const bool include_inlines = false; 2697 const bool append = false; 2698 2699 if (namespace_decl && module_sp) 2700 { 2701 const bool include_symbols = false; 2702 2703 module_sp->FindFunctions(name, 2704 &namespace_decl, 2705 eFunctionNameTypeBase, 2706 include_symbols, 2707 include_inlines, 2708 append, 2709 sc_list); 2710 } 2711 else if (!namespace_decl) 2712 { 2713 const bool include_symbols = true; 2714 2715 // TODO Fix FindFunctions so that it doesn't return 2716 // instance methods for eFunctionNameTypeBase. 2717 2718 target->GetImages().FindFunctions(name, 2719 eFunctionNameTypeBase, 2720 include_symbols, 2721 include_inlines, 2722 append, 2723 sc_list); 2724 } 2725 2726 if (sc_list.GetSize()) 2727 { 2728 Symbol *generic_symbol = NULL; 2729 Symbol *non_extern_symbol = NULL; 2730 2731 for (uint32_t index = 0, num_indices = sc_list.GetSize(); 2732 index < num_indices; 2733 ++index) 2734 { 2735 SymbolContext sym_ctx; 2736 sc_list.GetContextAtIndex(index, sym_ctx); 2737 2738 if (sym_ctx.function) 2739 { 2740 clang::DeclContext *decl_ctx = sym_ctx.function->GetClangDeclContext(); 2741 2742 // Filter out class/instance methods. 2743 if (dyn_cast<clang::ObjCMethodDecl>(decl_ctx)) 2744 continue; 2745 if (dyn_cast<clang::CXXMethodDecl>(decl_ctx)) 2746 continue; 2747 2748 // TODO only do this if it's a C function; C++ functions may be 2749 // overloaded 2750 if (!context.m_found.function_with_type_info) 2751 AddOneFunction(context, sym_ctx.function, NULL, current_id); 2752 context.m_found.function_with_type_info = true; 2753 context.m_found.function = true; 2754 } 2755 else if (sym_ctx.symbol) 2756 { 2757 if (sym_ctx.symbol->IsExternal()) 2758 generic_symbol = sym_ctx.symbol; 2759 else 2760 non_extern_symbol = sym_ctx.symbol; 2761 } 2762 } 2763 2764 if (!context.m_found.function_with_type_info) 2765 { 2766 if (generic_symbol) 2767 { 2768 AddOneFunction (context, NULL, generic_symbol, current_id); 2769 context.m_found.function = true; 2770 } 2771 else if (non_extern_symbol) 2772 { 2773 AddOneFunction (context, NULL, non_extern_symbol, current_id); 2774 context.m_found.function = true; 2775 } 2776 } 2777 } 2778 2779 if (!context.m_found.variable && !namespace_decl) 2780 { 2781 // We couldn't find a non-symbol variable for this. Now we'll hunt for a generic 2782 // data symbol, and -- if it is found -- treat it as a variable. 2783 2784 Symbol *data_symbol = FindGlobalDataSymbol(*target, name); 2785 2786 if (data_symbol) 2787 { 2788 AddOneGenericVariable(context, *data_symbol, current_id); 2789 context.m_found.variable = true; 2790 } 2791 } 2792 } 2793 } 2794} 2795 2796static clang_type_t 2797MaybePromoteToBlockPointerType 2798( 2799 ASTContext *ast_context, 2800 clang_type_t candidate_type 2801) 2802{ 2803 if (!candidate_type) 2804 return candidate_type; 2805 2806 QualType candidate_qual_type = QualType::getFromOpaquePtr(candidate_type); 2807 2808 const PointerType *candidate_pointer_type = dyn_cast<PointerType>(candidate_qual_type); 2809 2810 if (!candidate_pointer_type) 2811 return candidate_type; 2812 2813 QualType pointee_qual_type = candidate_pointer_type->getPointeeType(); 2814 2815 const RecordType *pointee_record_type = dyn_cast<RecordType>(pointee_qual_type); 2816 2817 if (!pointee_record_type) 2818 return candidate_type; 2819 2820 RecordDecl *pointee_record_decl = pointee_record_type->getDecl(); 2821 2822 if (!pointee_record_decl->isRecord()) 2823 return candidate_type; 2824 2825 if (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_"))) 2826 return candidate_type; 2827 2828 QualType generic_function_type = ast_context->getFunctionNoProtoType(ast_context->UnknownAnyTy); 2829 QualType block_pointer_type = ast_context->getBlockPointerType(generic_function_type); 2830 2831 return block_pointer_type.getAsOpaquePtr(); 2832} 2833 2834Value * 2835ClangExpressionDeclMap::GetVariableValue 2836( 2837 VariableSP &var, 2838 ASTContext *parser_ast_context, 2839 TypeFromUser *user_type, 2840 TypeFromParser *parser_type 2841) 2842{ 2843 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 2844 2845 Type *var_type = var->GetType(); 2846 2847 if (!var_type) 2848 { 2849 if (log) 2850 log->PutCString("Skipped a definition because it has no type"); 2851 return NULL; 2852 } 2853 2854 clang_type_t var_opaque_type = var_type->GetClangFullType(); 2855 2856 if (!var_opaque_type) 2857 { 2858 if (log) 2859 log->PutCString("Skipped a definition because it has no Clang type"); 2860 return NULL; 2861 } 2862 2863 ASTContext *ast = var_type->GetClangASTContext().getASTContext(); 2864 2865 if (!ast) 2866 { 2867 if (log) 2868 log->PutCString("There is no AST context for the current execution context"); 2869 return NULL; 2870 } 2871 2872 // commented out because of <rdar://problem/11024417> 2873 //var_opaque_type = MaybePromoteToBlockPointerType (ast, var_opaque_type); 2874 2875 DWARFExpression &var_location_expr = var->LocationExpression(); 2876 2877 std::auto_ptr<Value> var_location(new Value); 2878 2879 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS; 2880 2881 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 2882 2883 if (var_location_expr.IsLocationList()) 2884 { 2885 SymbolContext var_sc; 2886 var->CalculateSymbolContext (&var_sc); 2887 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target); 2888 } 2889 Error err; 2890 2891 if (!var_location_expr.Evaluate(&m_parser_vars->m_exe_ctx, ast, NULL, NULL, NULL, loclist_base_load_addr, NULL, *var_location.get(), &err)) 2892 { 2893 if (log) 2894 log->Printf("Error evaluating location: %s", err.AsCString()); 2895 return NULL; 2896 } 2897 2898 void *type_to_use = NULL; 2899 2900 if (parser_ast_context) 2901 { 2902 type_to_use = GuardedCopyType(parser_ast_context, ast, var_opaque_type); 2903 2904 if (!type_to_use) 2905 { 2906 if (log) 2907 log->Printf("Couldn't copy a variable's type into the parser's AST context"); 2908 2909 return NULL; 2910 } 2911 2912 if (parser_type) 2913 *parser_type = TypeFromParser(type_to_use, parser_ast_context); 2914 } 2915 else 2916 type_to_use = var_opaque_type; 2917 2918 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid) 2919 var_location.get()->SetContext(Value::eContextTypeClangType, type_to_use); 2920 2921 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress) 2922 { 2923 SymbolContext var_sc; 2924 var->CalculateSymbolContext(&var_sc); 2925 2926 if (!var_sc.module_sp) 2927 return NULL; 2928 2929 ObjectFile *object_file = var_sc.module_sp->GetObjectFile(); 2930 2931 if (!object_file) 2932 return NULL; 2933 2934 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList()); 2935 2936 lldb::addr_t load_addr = so_addr.GetLoadAddress(target); 2937 2938 if (load_addr != LLDB_INVALID_ADDRESS) 2939 { 2940 var_location->GetScalar() = load_addr; 2941 var_location->SetValueType(Value::eValueTypeLoadAddress); 2942 } 2943 } 2944 2945 if (user_type) 2946 *user_type = TypeFromUser(var_opaque_type, ast); 2947 2948 return var_location.release(); 2949} 2950 2951void 2952ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP var, ValueObjectSP valobj, unsigned int current_id) 2953{ 2954 assert (m_parser_vars.get()); 2955 2956 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 2957 2958 TypeFromUser ut; 2959 TypeFromParser pt; 2960 2961 Value *var_location = GetVariableValue (var, 2962 m_ast_context, 2963 &ut, 2964 &pt); 2965 2966 clang::QualType parser_opaque_type = QualType::getFromOpaquePtr(pt.GetOpaqueQualType()); 2967 2968 if (parser_opaque_type.isNull()) 2969 return; 2970 2971 if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) 2972 { 2973 if (const TagType *tag_type = dyn_cast<TagType>(parser_type)) 2974 CompleteType(tag_type->getDecl()); 2975 } 2976 2977 if (!var_location) 2978 return; 2979 2980 NamedDecl *var_decl; 2981 2982 bool is_reference = ClangASTContext::IsReferenceType(pt.GetOpaqueQualType()); 2983 2984 if (is_reference) 2985 var_decl = context.AddVarDecl(pt.GetOpaqueQualType()); 2986 else 2987 var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(pt.GetASTContext(), pt.GetOpaqueQualType())); 2988 2989 std::string decl_name(context.m_decl_name.getAsString()); 2990 ConstString entity_name(decl_name.c_str()); 2991 ClangExpressionVariableSP entity(m_found_entities.CreateVariable (valobj)); 2992 2993 assert (entity.get()); 2994 entity->EnableParserVars(); 2995 entity->m_parser_vars->m_parser_type = pt; 2996 entity->m_parser_vars->m_named_decl = var_decl; 2997 entity->m_parser_vars->m_llvm_value = NULL; 2998 entity->m_parser_vars->m_lldb_value = var_location; 2999 entity->m_parser_vars->m_lldb_var = var; 3000 3001 if (is_reference) 3002 entity->m_flags |= ClangExpressionVariable::EVTypeIsReference; 3003 3004 if (log) 3005 { 3006 ASTDumper orig_dumper(ut.GetOpaqueQualType()); 3007 ASTDumper ast_dumper(var_decl); 3008 log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)", current_id, decl_name.c_str(), ast_dumper.GetCString(), orig_dumper.GetCString()); 3009 } 3010} 3011 3012void 3013ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 3014 ClangExpressionVariableSP &pvar_sp, 3015 unsigned int current_id) 3016{ 3017 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 3018 3019 TypeFromUser user_type (pvar_sp->GetTypeFromUser()); 3020 3021 TypeFromParser parser_type (GuardedCopyType(m_ast_context, 3022 user_type.GetASTContext(), 3023 user_type.GetOpaqueQualType()), 3024 m_ast_context); 3025 3026 if (!parser_type.GetOpaqueQualType()) 3027 { 3028 if (log) 3029 log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s", current_id, pvar_sp->GetName().GetCString()); 3030 return; 3031 } 3032 3033 NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(parser_type.GetASTContext(), parser_type.GetOpaqueQualType())); 3034 3035 pvar_sp->EnableParserVars(); 3036 pvar_sp->m_parser_vars->m_parser_type = parser_type; 3037 pvar_sp->m_parser_vars->m_named_decl = var_decl; 3038 pvar_sp->m_parser_vars->m_llvm_value = NULL; 3039 pvar_sp->m_parser_vars->m_lldb_value = NULL; 3040 3041 if (log) 3042 { 3043 ASTDumper ast_dumper(var_decl); 3044 log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id, pvar_sp->GetName().GetCString(), ast_dumper.GetCString()); 3045 } 3046} 3047 3048void 3049ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, 3050 Symbol &symbol, 3051 unsigned int current_id) 3052{ 3053 assert(m_parser_vars.get()); 3054 3055 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 3056 3057 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 3058 3059 if (target == NULL) 3060 return; 3061 3062 ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext(); 3063 3064 TypeFromUser user_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(scratch_ast_context, true)), 3065 scratch_ast_context); 3066 3067 TypeFromParser parser_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(m_ast_context, true)), 3068 m_ast_context); 3069 3070 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); 3071 3072 std::string decl_name(context.m_decl_name.getAsString()); 3073 ConstString entity_name(decl_name.c_str()); 3074 ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (), 3075 entity_name, 3076 user_type, 3077 m_parser_vars->m_target_info.byte_order, 3078 m_parser_vars->m_target_info.address_byte_size)); 3079 assert (entity.get()); 3080 3081 std::auto_ptr<Value> symbol_location(new Value); 3082 3083 Address &symbol_address = symbol.GetAddress(); 3084 lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target); 3085 3086 symbol_location->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); 3087 symbol_location->GetScalar() = symbol_load_addr; 3088 symbol_location->SetValueType(Value::eValueTypeLoadAddress); 3089 3090 entity->EnableParserVars(); 3091 entity->m_parser_vars->m_parser_type = parser_type; 3092 entity->m_parser_vars->m_named_decl = var_decl; 3093 entity->m_parser_vars->m_llvm_value = NULL; 3094 entity->m_parser_vars->m_lldb_value = symbol_location.release(); 3095 entity->m_parser_vars->m_lldb_sym = &symbol; 3096 3097 if (log) 3098 { 3099 ASTDumper ast_dumper(var_decl); 3100 3101 log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id, decl_name.c_str(), ast_dumper.GetCString()); 3102 } 3103} 3104 3105bool 3106ClangExpressionDeclMap::ResolveUnknownTypes() 3107{ 3108 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 3109 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 3110 3111 ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext(); 3112 3113 for (size_t index = 0, num_entities = m_found_entities.GetSize(); 3114 index < num_entities; 3115 ++index) 3116 { 3117 ClangExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index); 3118 3119 if (entity->m_flags & ClangExpressionVariable::EVUnknownType) 3120 { 3121 const NamedDecl *named_decl = entity->m_parser_vars->m_named_decl; 3122 const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl); 3123 3124 if (!var_decl) 3125 { 3126 if (log) 3127 log->Printf("Entity of unknown type does not have a VarDecl"); 3128 return false; 3129 } 3130 3131 if (log) 3132 { 3133 ASTDumper ast_dumper(const_cast<VarDecl*>(var_decl)); 3134 log->Printf("Variable of unknown type now has Decl %s", ast_dumper.GetCString()); 3135 } 3136 3137 QualType var_type = var_decl->getType(); 3138 TypeFromParser parser_type(var_type.getAsOpaquePtr(), &var_decl->getASTContext()); 3139 3140 lldb::clang_type_t copied_type = m_ast_importer->CopyType(scratch_ast_context, &var_decl->getASTContext(), var_type.getAsOpaquePtr()); 3141 3142 if (!copied_type) 3143 { 3144 if (log) 3145 log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable"); 3146 3147 return (bool) lldb::ClangExpressionVariableSP(); 3148 } 3149 3150 TypeFromUser user_type(copied_type, scratch_ast_context); 3151 3152 entity->m_parser_vars->m_lldb_value->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType()); 3153 entity->m_parser_vars->m_parser_type = parser_type; 3154 3155 entity->SetClangAST(user_type.GetASTContext()); 3156 entity->SetClangType(user_type.GetOpaqueQualType()); 3157 3158 entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType); 3159 } 3160 } 3161 3162 return true; 3163} 3164 3165void 3166ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context, 3167 const RegisterInfo *reg_info, 3168 unsigned int current_id) 3169{ 3170 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 3171 3172 void *ast_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(m_ast_context, 3173 reg_info->encoding, 3174 reg_info->byte_size * 8); 3175 3176 if (!ast_type) 3177 { 3178 if (log) 3179 log->Printf(" Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str()); 3180 return; 3181 } 3182 3183 TypeFromParser parser_type (ast_type, 3184 m_ast_context); 3185 3186 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); 3187 3188 ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), 3189 m_parser_vars->m_target_info.byte_order, 3190 m_parser_vars->m_target_info.address_byte_size)); 3191 assert (entity.get()); 3192 std::string decl_name(context.m_decl_name.getAsString()); 3193 entity->SetName (ConstString (decl_name.c_str())); 3194 entity->SetRegisterInfo (reg_info); 3195 entity->EnableParserVars(); 3196 entity->m_parser_vars->m_parser_type = parser_type; 3197 entity->m_parser_vars->m_named_decl = var_decl; 3198 entity->m_parser_vars->m_llvm_value = NULL; 3199 entity->m_parser_vars->m_lldb_value = NULL; 3200 entity->m_flags |= ClangExpressionVariable::EVBareRegister; 3201 3202 if (log) 3203 { 3204 ASTDumper ast_dumper(var_decl); 3205 log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id, context.m_decl_name.getAsString().c_str(), ast_dumper.GetCString()); 3206 } 3207} 3208 3209void 3210ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context, 3211 Function* fun, 3212 Symbol* symbol, 3213 unsigned int current_id) 3214{ 3215 assert (m_parser_vars.get()); 3216 3217 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 3218 3219 NamedDecl *fun_decl = NULL; 3220 std::auto_ptr<Value> fun_location(new Value); 3221 const Address *fun_address = NULL; 3222 3223 // only valid for Functions, not for Symbols 3224 void *fun_opaque_type = NULL; 3225 ASTContext *fun_ast_context = NULL; 3226 3227 if (fun) 3228 { 3229 Type *fun_type = fun->GetType(); 3230 3231 if (!fun_type) 3232 { 3233 if (log) 3234 log->PutCString(" Skipped a function because it has no type"); 3235 return; 3236 } 3237 3238 fun_opaque_type = fun_type->GetClangFullType(); 3239 3240 if (!fun_opaque_type) 3241 { 3242 if (log) 3243 log->PutCString(" Skipped a function because it has no Clang type"); 3244 return; 3245 } 3246 3247 fun_address = &fun->GetAddressRange().GetBaseAddress(); 3248 3249 fun_ast_context = fun_type->GetClangASTContext().getASTContext(); 3250 void *copied_type = GuardedCopyType(m_ast_context, fun_ast_context, fun_opaque_type); 3251 if (copied_type) 3252 { 3253 fun_decl = context.AddFunDecl(copied_type); 3254 } 3255 else 3256 { 3257 // We failed to copy the type we found 3258 if (log) 3259 { 3260 log->Printf (" Failed to import the function type '%s' {0x%8.8llx} into the expression parser AST contenxt", 3261 fun_type->GetName().GetCString(), 3262 fun_type->GetID()); 3263 } 3264 3265 return; 3266 } 3267 } 3268 else if (symbol) 3269 { 3270 fun_address = &symbol->GetAddress(); 3271 fun_decl = context.AddGenericFunDecl(); 3272 } 3273 else 3274 { 3275 if (log) 3276 log->PutCString(" AddOneFunction called with no function and no symbol"); 3277 return; 3278 } 3279 3280 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 3281 3282 lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target); 3283 fun_location->SetValueType(Value::eValueTypeLoadAddress); 3284 fun_location->GetScalar() = load_addr; 3285 3286 ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (), 3287 m_parser_vars->m_target_info.byte_order, 3288 m_parser_vars->m_target_info.address_byte_size)); 3289 assert (entity.get()); 3290 std::string decl_name(context.m_decl_name.getAsString()); 3291 entity->SetName(ConstString(decl_name.c_str())); 3292 entity->SetClangType (fun_opaque_type); 3293 entity->SetClangAST (fun_ast_context); 3294 3295 entity->EnableParserVars(); 3296 entity->m_parser_vars->m_named_decl = fun_decl; 3297 entity->m_parser_vars->m_llvm_value = NULL; 3298 entity->m_parser_vars->m_lldb_value = fun_location.release(); 3299 3300 if (log) 3301 { 3302 ASTDumper ast_dumper(fun_decl); 3303 3304 StreamString ss; 3305 3306 fun_address->Dump(&ss, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); 3307 3308 log->Printf(" CEDM::FEVD[%u] Found %s function %s (description %s), returned %s", 3309 current_id, 3310 (fun ? "specific" : "generic"), 3311 decl_name.c_str(), 3312 ss.GetData(), 3313 ast_dumper.GetCString()); 3314 } 3315} 3316 3317void 3318ClangExpressionDeclMap::AddOneType(NameSearchContext &context, 3319 TypeFromUser &ut, 3320 unsigned int current_id, 3321 bool add_method) 3322{ 3323 ASTContext *parser_ast_context = m_ast_context; 3324 ASTContext *user_ast_context = ut.GetASTContext(); 3325 3326 void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType()); 3327 3328 if (!copied_type) 3329 { 3330 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 3331 3332 if (log) 3333 log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type"); 3334 3335 return; 3336 } 3337 3338 if (add_method && ClangASTContext::IsAggregateType(copied_type) && ClangASTContext::GetCompleteType (parser_ast_context, copied_type)) 3339 { 3340 void *args[1]; 3341 3342 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false); 3343 3344 clang_type_t method_type = ClangASTContext::CreateFunctionType (parser_ast_context, 3345 ClangASTContext::GetBuiltInType_void(parser_ast_context), 3346 args, 3347 1, 3348 false, 3349 ClangASTContext::GetTypeQualifiers(copied_type)); 3350 3351 const bool is_virtual = false; 3352 const bool is_static = false; 3353 const bool is_inline = false; 3354 const bool is_explicit = false; 3355 const bool is_attr_used = true; 3356 const bool is_artificial = false; 3357 3358 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context, 3359 copied_type, 3360 "$__lldb_expr", 3361 method_type, 3362 lldb::eAccessPublic, 3363 is_virtual, 3364 is_static, 3365 is_inline, 3366 is_explicit, 3367 is_attr_used, 3368 is_artificial); 3369 } 3370 3371 context.AddTypeDecl(copied_type); 3372} 3373