1 //===-- Materializer.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/Core/Log.h" 11 #include "lldb/Core/RegisterValue.h" 12 #include "lldb/Core/ValueObjectConstResult.h" 13 #include "lldb/Core/ValueObjectVariable.h" 14 #include "lldb/Expression/ClangExpressionVariable.h" 15 #include "lldb/Expression/Materializer.h" 16 #include "lldb/Symbol/ClangASTContext.h" 17 #include "lldb/Symbol/Symbol.h" 18 #include "lldb/Symbol/Type.h" 19 #include "lldb/Symbol/Variable.h" 20 #include "lldb/Target/ExecutionContext.h" 21 #include "lldb/Target/RegisterContext.h" 22 #include "lldb/Target/StackFrame.h" 23 #include "lldb/Target/Target.h" 24 25 using namespace lldb_private; 26 27 uint32_t 28 Materializer::AddStructMember (Entity &entity) 29 { 30 uint32_t size = entity.GetSize(); 31 uint32_t alignment = entity.GetAlignment(); 32 33 uint32_t ret; 34 35 if (m_current_offset == 0) 36 m_struct_alignment = alignment; 37 38 if (m_current_offset % alignment) 39 m_current_offset += (alignment - (m_current_offset % alignment)); 40 41 ret = m_current_offset; 42 43 m_current_offset += size; 44 45 return ret; 46 } 47 48 void 49 Materializer::Entity::SetSizeAndAlignmentFromType (ClangASTType &type) 50 { 51 m_size = type.GetTypeByteSize(); 52 53 uint32_t bit_alignment = type.GetTypeBitAlign(); 54 55 if (bit_alignment % 8) 56 { 57 bit_alignment += 8; 58 bit_alignment &= ~((uint32_t)0x111u); 59 } 60 61 m_alignment = bit_alignment / 8; 62 } 63 64 class EntityPersistentVariable : public Materializer::Entity 65 { 66 public: 67 EntityPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp) : 68 Entity(), 69 m_persistent_variable_sp(persistent_variable_sp) 70 { 71 // Hard-coding to maximum size of a pointer since persistent variables are materialized by reference 72 m_size = 8; 73 m_alignment = 8; 74 } 75 76 void MakeAllocation (IRMemoryMap &map, Error &err) 77 { 78 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 79 80 // Allocate a spare memory area to store the persistent variable's contents. 81 82 Error allocate_error; 83 84 lldb::addr_t mem = map.Malloc(m_persistent_variable_sp->GetByteSize(), 85 8, 86 lldb::ePermissionsReadable | lldb::ePermissionsWritable, 87 IRMemoryMap::eAllocationPolicyMirror, 88 allocate_error); 89 90 if (!allocate_error.Success()) 91 { 92 err.SetErrorToGenericError(); 93 err.SetErrorStringWithFormat("Couldn't allocate a memory area to store %s: %s", m_persistent_variable_sp->GetName().GetCString(), allocate_error.AsCString()); 94 return; 95 } 96 97 if (log) 98 log->Printf("Allocated %s (0x%" PRIx64 ") sucessfully", m_persistent_variable_sp->GetName().GetCString(), mem); 99 100 // Put the location of the spare memory into the live data of the ValueObject. 101 102 m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope(), 103 m_persistent_variable_sp->GetTypeFromUser().GetASTContext(), 104 m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(), 105 m_persistent_variable_sp->GetName(), 106 mem, 107 eAddressTypeLoad, 108 m_persistent_variable_sp->GetByteSize()); 109 110 // Clear the flag if the variable will never be deallocated. 111 112 if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget) 113 m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVNeedsAllocation; 114 115 // Write the contents of the variable to the area. 116 117 Error write_error; 118 119 map.WriteMemory (mem, 120 m_persistent_variable_sp->GetValueBytes(), 121 m_persistent_variable_sp->GetByteSize(), 122 write_error); 123 124 if (!write_error.Success()) 125 { 126 err.SetErrorToGenericError(); 127 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", m_persistent_variable_sp->GetName().AsCString(), 128 write_error.AsCString()); 129 return; 130 } 131 } 132 133 void DestroyAllocation (IRMemoryMap &map, Error &err) 134 { 135 Error deallocate_error; 136 137 map.Free((lldb::addr_t)m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong(), deallocate_error); 138 139 m_persistent_variable_sp->m_live_sp.reset(); 140 141 if (!deallocate_error.Success()) 142 { 143 err.SetErrorToGenericError(); 144 err.SetErrorStringWithFormat ("Couldn't deallocate memory for %s: %s", m_persistent_variable_sp->GetName().GetCString(), deallocate_error.AsCString()); 145 } 146 } 147 148 void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 149 { 150 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 151 152 if (log) 153 { 154 log->Printf("EntityPersistentVariable::Materialize [process_address = 0x%llx, m_name = %s, m_flags = 0x%hx]", 155 (uint64_t)process_address, 156 m_persistent_variable_sp->GetName().AsCString(), 157 m_persistent_variable_sp->m_flags); 158 } 159 160 if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation) 161 { 162 MakeAllocation(map, err); 163 m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 164 165 if (!err.Success()) 166 return; 167 } 168 169 if ((m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && m_persistent_variable_sp->m_live_sp) || 170 m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) 171 { 172 Error write_error; 173 174 map.WriteScalarToMemory(process_address + m_offset, 175 m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(), 176 map.GetAddressByteSize(), 177 write_error); 178 179 if (!write_error.Success()) 180 { 181 err.SetErrorToGenericError(); 182 err.SetErrorStringWithFormat("Couldn't write the location of %s to memory: %s", m_persistent_variable_sp->GetName().AsCString(), write_error.AsCString()); 183 } 184 } 185 else 186 { 187 err.SetErrorToGenericError(); 188 err.SetErrorStringWithFormat("No materialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString()); 189 return; 190 } 191 } 192 193 void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, 194 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) 195 { 196 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 197 198 if (log) 199 { 200 log->Printf("EntityPersistentVariable::Dematerialize [process_address = 0x%llx, m_name = %s, m_flags = 0x%hx]", 201 (uint64_t)process_address, 202 m_persistent_variable_sp->GetName().AsCString(), 203 m_persistent_variable_sp->m_flags); 204 } 205 206 if ((m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) || 207 (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference)) 208 { 209 if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && 210 !m_persistent_variable_sp->m_live_sp) 211 { 212 // If the reference comes from the program, then the ClangExpressionVariable's 213 // live variable data hasn't been set up yet. Do this now. 214 215 lldb::addr_t location; 216 Error read_error; 217 218 map.ReadPointerFromMemory(&location, process_address + m_offset, read_error); 219 220 if (!read_error.Success()) 221 { 222 err.SetErrorToGenericError(); 223 err.SetErrorStringWithFormat("Couldn't read the address of program-allocated variable %s: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString()); 224 return; 225 } 226 227 m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope (), 228 m_persistent_variable_sp->GetTypeFromUser().GetASTContext(), 229 m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(), 230 m_persistent_variable_sp->GetName(), 231 location, 232 eAddressTypeLoad, 233 m_persistent_variable_sp->GetByteSize()); 234 235 if (frame_top != LLDB_INVALID_ADDRESS && 236 frame_bottom != LLDB_INVALID_ADDRESS && 237 location >= frame_bottom && 238 location <= frame_top) 239 { 240 // If the variable is resident in the stack frame created by the expression, 241 // then it cannot be relied upon to stay around. We treat it as needing 242 // reallocation. 243 m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 244 m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 245 m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry; 246 m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVIsProgramReference; 247 } 248 } 249 250 lldb::addr_t mem = m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong(); 251 252 if (!m_persistent_variable_sp->m_live_sp) 253 { 254 err.SetErrorToGenericError(); 255 err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", m_persistent_variable_sp->GetName().GetCString()); 256 return; 257 } 258 259 if (m_persistent_variable_sp->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad) 260 { 261 err.SetErrorToGenericError(); 262 err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", m_persistent_variable_sp->GetName().GetCString()); 263 return; 264 } 265 266 if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry || 267 m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget) 268 { 269 if (log) 270 log->Printf("Dematerializing %s from 0x%" PRIx64 " (size = %llu)", m_persistent_variable_sp->GetName().GetCString(), (uint64_t)mem, (unsigned long long)m_persistent_variable_sp->GetByteSize()); 271 272 // Read the contents of the spare memory area 273 274 m_persistent_variable_sp->ValueUpdated (); 275 276 Error read_error; 277 278 map.ReadMemory(m_persistent_variable_sp->GetValueBytes(), 279 mem, 280 m_persistent_variable_sp->GetByteSize(), 281 read_error); 282 283 if (!read_error.Success()) 284 { 285 err.SetErrorToGenericError(); 286 err.SetErrorStringWithFormat ("Couldn't read the contents of %s from memory: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString()); 287 return; 288 } 289 290 m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVNeedsFreezeDry; 291 } 292 } 293 else 294 { 295 err.SetErrorToGenericError(); 296 err.SetErrorStringWithFormat("No dematerialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString()); 297 return; 298 } 299 300 lldb::ProcessSP process_sp = map.GetBestExecutionContextScope()->CalculateProcess(); 301 if (!process_sp || 302 !process_sp->CanJIT()) 303 { 304 // Allocations are not persistent so persistent variables cannot stay materialized. 305 306 m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 307 308 DestroyAllocation(map, err); 309 if (!err.Success()) 310 return; 311 } 312 else if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation && 313 !(m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)) 314 { 315 DestroyAllocation(map, err); 316 if (!err.Success()) 317 return; 318 } 319 } 320 321 void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 322 { 323 StreamString dump_stream; 324 325 Error err; 326 327 dump_stream.Printf("0x%llx: EntityPersistentVariable (%s)\n", (unsigned long long)process_address + m_offset, m_persistent_variable_sp->GetName().AsCString()); 328 329 { 330 dump_stream.Printf("Pointer:\n"); 331 332 DataBufferHeap data (m_size, 0); 333 334 map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); 335 336 if (!err.Success()) 337 { 338 dump_stream.Printf(" <could not be read>\n"); 339 } 340 else 341 { 342 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 343 344 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); 345 346 dump_stream.PutChar('\n'); 347 } 348 } 349 350 { 351 dump_stream.Printf("Target:\n"); 352 353 lldb::addr_t target_address; 354 355 map.ReadPointerFromMemory (&target_address, process_address + m_offset, err); 356 357 if (!err.Success()) 358 { 359 dump_stream.Printf(" <could not be read>\n"); 360 } 361 else 362 { 363 DataBufferHeap data (m_persistent_variable_sp->GetByteSize(), 0); 364 365 map.ReadMemory(data.GetBytes(), target_address, m_persistent_variable_sp->GetByteSize(), err); 366 367 if (!err.Success()) 368 { 369 dump_stream.Printf(" <could not be read>\n"); 370 } 371 else 372 { 373 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 374 375 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, target_address); 376 377 dump_stream.PutChar('\n'); 378 } 379 } 380 } 381 382 log->PutCString(dump_stream.GetData()); 383 } 384 385 void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 386 { 387 } 388 private: 389 lldb::ClangExpressionVariableSP m_persistent_variable_sp; 390 }; 391 392 uint32_t 393 Materializer::AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err) 394 { 395 EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 396 iter->reset (new EntityPersistentVariable (persistent_variable_sp)); 397 uint32_t ret = AddStructMember(**iter); 398 (*iter)->SetOffset(ret); 399 return ret; 400 } 401 402 class EntityVariable : public Materializer::Entity 403 { 404 public: 405 EntityVariable (lldb::VariableSP &variable_sp) : 406 Entity(), 407 m_variable_sp(variable_sp), 408 m_is_reference(false), 409 m_temporary_allocation(LLDB_INVALID_ADDRESS), 410 m_temporary_allocation_size(0) 411 { 412 // Hard-coding to maximum size of a pointer since all variables are materialized by reference 413 m_size = 8; 414 m_alignment = 8; 415 m_is_reference = ClangASTContext::IsReferenceType(m_variable_sp->GetType()->GetClangForwardType()); 416 } 417 418 void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 419 { 420 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 421 422 if (log) 423 { 424 log->Printf("EntityVariable::Materialize [process_address = 0x%llx, m_variable_sp = %s]", 425 (uint64_t)process_address, 426 m_variable_sp->GetName().AsCString()); 427 } 428 429 ExecutionContextScope *scope = frame_sp.get(); 430 431 if (!scope) 432 scope = map.GetBestExecutionContextScope(); 433 434 lldb::ValueObjectSP valobj_sp = ValueObjectVariable::Create(scope, m_variable_sp); 435 436 if (!valobj_sp) 437 { 438 err.SetErrorToGenericError(); 439 err.SetErrorStringWithFormat("Couldn't get a value object for variable %s", m_variable_sp->GetName().AsCString()); 440 return; 441 } 442 443 if (m_is_reference) 444 { 445 DataExtractor valobj_extractor; 446 valobj_sp->GetData(valobj_extractor); 447 lldb::offset_t offset = 0; 448 lldb::addr_t reference_addr = valobj_extractor.GetAddress(&offset); 449 450 Error write_error; 451 map.WritePointerToMemory(process_address + m_offset, reference_addr, write_error); 452 453 if (!write_error.Success()) 454 { 455 err.SetErrorToGenericError(); 456 err.SetErrorStringWithFormat("Couldn't write the contents of reference variable %s to memory: %s", m_variable_sp->GetName().AsCString(), write_error.AsCString()); 457 return; 458 } 459 } 460 else 461 { 462 Error get_address_error; 463 lldb::ValueObjectSP addr_of_valobj_sp = valobj_sp->AddressOf(get_address_error); 464 if (get_address_error.Success()) 465 { 466 DataExtractor valobj_extractor; 467 addr_of_valobj_sp->GetData(valobj_extractor); 468 lldb::offset_t offset = 0; 469 lldb::addr_t addr_of_valobj_addr = valobj_extractor.GetAddress(&offset); 470 471 Error write_error; 472 map.WritePointerToMemory(process_address + m_offset, addr_of_valobj_addr, write_error); 473 474 if (!write_error.Success()) 475 { 476 err.SetErrorToGenericError(); 477 err.SetErrorStringWithFormat("Couldn't write the address of variable %s to memory: %s", m_variable_sp->GetName().AsCString(), write_error.AsCString()); 478 return; 479 } 480 } 481 else 482 { 483 DataExtractor data; 484 valobj_sp->GetData(data); 485 486 if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 487 { 488 err.SetErrorToGenericError(); 489 err.SetErrorStringWithFormat("Trying to create a temporary region for %s but one exists", m_variable_sp->GetName().AsCString()); 490 return; 491 } 492 493 if (data.GetByteSize() != m_variable_sp->GetType()->GetByteSize()) 494 { 495 err.SetErrorToGenericError(); 496 err.SetErrorStringWithFormat("Size of variable %s disagrees with the ValueObject's size", m_variable_sp->GetName().AsCString()); 497 return; 498 } 499 500 size_t bit_align = ClangASTType::GetTypeBitAlign(m_variable_sp->GetType()->GetClangAST(), m_variable_sp->GetType()->GetClangLayoutType()); 501 size_t byte_align = (bit_align + 7) / 8; 502 503 Error alloc_error; 504 505 m_temporary_allocation = map.Malloc(data.GetByteSize(), byte_align, lldb::ePermissionsReadable | lldb::ePermissionsWritable, IRMemoryMap::eAllocationPolicyMirror, alloc_error); 506 m_temporary_allocation_size = data.GetByteSize(); 507 508 if (!alloc_error.Success()) 509 { 510 err.SetErrorToGenericError(); 511 err.SetErrorStringWithFormat("Couldn't allocate a temporary region for %s: %s", m_variable_sp->GetName().AsCString(), alloc_error.AsCString()); 512 return; 513 } 514 515 Error write_error; 516 517 map.WriteMemory(m_temporary_allocation, data.GetDataStart(), data.GetByteSize(), write_error); 518 519 if (!write_error.Success()) 520 { 521 err.SetErrorToGenericError(); 522 err.SetErrorStringWithFormat("Couldn't write to the temporary region for %s: %s", m_variable_sp->GetName().AsCString(), write_error.AsCString()); 523 return; 524 } 525 526 Error pointer_write_error; 527 528 map.WritePointerToMemory(process_address + m_offset, m_temporary_allocation, pointer_write_error); 529 530 if (!pointer_write_error.Success()) 531 { 532 err.SetErrorToGenericError(); 533 err.SetErrorStringWithFormat("Couldn't write the address of the temporary region for %s: %s", m_variable_sp->GetName().AsCString(), pointer_write_error.AsCString()); 534 } 535 } 536 } 537 } 538 539 void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, 540 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) 541 { 542 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 543 544 if (log) 545 { 546 log->Printf("EntityVariable::Dematerialize [process_address = 0x%llx, m_variable_sp = %s]", 547 (uint64_t)process_address, 548 m_variable_sp->GetName().AsCString()); 549 } 550 551 if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 552 { 553 ExecutionContextScope *scope = frame_sp.get(); 554 555 if (!scope) 556 scope = map.GetBestExecutionContextScope(); 557 558 lldb::ValueObjectSP valobj_sp = ValueObjectVariable::Create(scope, m_variable_sp); 559 560 if (!valobj_sp) 561 { 562 err.SetErrorToGenericError(); 563 err.SetErrorStringWithFormat("Couldn't get a value object for variable %s", m_variable_sp->GetName().AsCString()); 564 return; 565 } 566 567 lldb_private::DataExtractor data; 568 569 Error extract_error; 570 571 map.GetMemoryData(data, m_temporary_allocation, valobj_sp->GetByteSize(), extract_error); 572 573 if (!extract_error.Success()) 574 { 575 err.SetErrorToGenericError(); 576 err.SetErrorStringWithFormat("Couldn't get the data for variable %s", m_variable_sp->GetName().AsCString()); 577 return; 578 } 579 580 Error set_error; 581 582 valobj_sp->SetData(data, set_error); 583 584 if (!set_error.Success()) 585 { 586 err.SetErrorToGenericError(); 587 err.SetErrorStringWithFormat("Couldn't write the new contents of %s back into the variable", m_variable_sp->GetName().AsCString()); 588 return; 589 } 590 591 Error free_error; 592 593 map.Free(m_temporary_allocation, free_error); 594 595 if (!free_error.Success()) 596 { 597 err.SetErrorToGenericError(); 598 err.SetErrorStringWithFormat("Couldn't free the temporary region for %s: %s", m_variable_sp->GetName().AsCString(), free_error.AsCString()); 599 return; 600 } 601 602 m_temporary_allocation = LLDB_INVALID_ADDRESS; 603 m_temporary_allocation_size = 0; 604 } 605 } 606 607 void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 608 { 609 StreamString dump_stream; 610 611 dump_stream.Printf("0x%llx: EntityVariable\n", (unsigned long long)process_address + m_offset); 612 613 Error err; 614 615 lldb::addr_t ptr = LLDB_INVALID_ADDRESS; 616 617 { 618 dump_stream.Printf("Pointer:\n"); 619 620 DataBufferHeap data (m_size, 0); 621 622 map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); 623 624 if (!err.Success()) 625 { 626 dump_stream.Printf(" <could not be read>\n"); 627 } 628 else 629 { 630 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 631 632 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); 633 634 lldb::offset_t offset; 635 636 ptr = extractor.GetPointer(&offset); 637 638 dump_stream.PutChar('\n'); 639 } 640 } 641 642 if (m_temporary_allocation == LLDB_INVALID_ADDRESS) 643 { 644 dump_stream.Printf("Points to process memory:\n"); 645 } 646 else 647 { 648 dump_stream.Printf("Temporary allocation:\n"); 649 } 650 651 if (ptr == LLDB_INVALID_ADDRESS) 652 { 653 dump_stream.Printf(" <could not be be found>\n"); 654 } 655 else 656 { 657 DataBufferHeap data (m_temporary_allocation_size, 0); 658 659 map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err); 660 661 if (!err.Success()) 662 { 663 dump_stream.Printf(" <could not be read>\n"); 664 } 665 else 666 { 667 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 668 669 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); 670 671 dump_stream.PutChar('\n'); 672 } 673 } 674 675 log->PutCString(dump_stream.GetData()); 676 } 677 678 void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 679 { 680 if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 681 { 682 Error free_error; 683 684 map.Free(m_temporary_allocation, free_error); 685 686 m_temporary_allocation = LLDB_INVALID_ADDRESS; 687 m_temporary_allocation_size = 0; 688 } 689 690 } 691 private: 692 lldb::VariableSP m_variable_sp; 693 bool m_is_reference; 694 lldb::addr_t m_temporary_allocation; 695 size_t m_temporary_allocation_size; 696 }; 697 698 uint32_t 699 Materializer::AddVariable (lldb::VariableSP &variable_sp, Error &err) 700 { 701 EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 702 iter->reset (new EntityVariable (variable_sp)); 703 uint32_t ret = AddStructMember(**iter); 704 (*iter)->SetOffset(ret); 705 return ret; 706 } 707 708 class EntityResultVariable : public Materializer::Entity 709 { 710 public: 711 EntityResultVariable (const TypeFromUser &type, bool is_program_reference, bool keep_in_memory) : 712 Entity(), 713 m_type(type), 714 m_is_program_reference(is_program_reference), 715 m_keep_in_memory(keep_in_memory), 716 m_temporary_allocation(LLDB_INVALID_ADDRESS), 717 m_temporary_allocation_size(0) 718 { 719 // Hard-coding to maximum size of a pointer since all results are materialized by reference 720 m_size = 8; 721 m_alignment = 8; 722 } 723 724 void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 725 { 726 if (!m_is_program_reference) 727 { 728 if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 729 { 730 err.SetErrorToGenericError(); 731 err.SetErrorString("Trying to create a temporary region for the result but one exists"); 732 return; 733 } 734 735 size_t byte_size = m_type.GetTypeByteSize(); 736 size_t bit_align = m_type.GetTypeBitAlign(); 737 size_t byte_align = (bit_align + 7) / 8; 738 739 Error alloc_error; 740 741 m_temporary_allocation = map.Malloc(byte_size, byte_align, lldb::ePermissionsReadable | lldb::ePermissionsWritable, IRMemoryMap::eAllocationPolicyMirror, alloc_error); 742 m_temporary_allocation_size = byte_size; 743 744 if (!alloc_error.Success()) 745 { 746 err.SetErrorToGenericError(); 747 err.SetErrorStringWithFormat("Couldn't allocate a temporary region for the result: %s", alloc_error.AsCString()); 748 return; 749 } 750 751 Error pointer_write_error; 752 753 map.WritePointerToMemory(process_address + m_offset, m_temporary_allocation, pointer_write_error); 754 755 if (!pointer_write_error.Success()) 756 { 757 err.SetErrorToGenericError(); 758 err.SetErrorStringWithFormat("Couldn't write the address of the temporary region for the result: %s", pointer_write_error.AsCString()); 759 } 760 } 761 } 762 763 void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, 764 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) 765 { 766 err.SetErrorToGenericError(); 767 err.SetErrorString("Tried to detmaterialize a result variable with the normal Dematerialize method"); 768 } 769 770 void Dematerialize (lldb::ClangExpressionVariableSP &result_variable_sp, 771 lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, 772 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) 773 { 774 err.Clear(); 775 776 ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope(); 777 778 if (!exe_scope) 779 { 780 err.SetErrorToGenericError(); 781 err.SetErrorString("Couldn't dematerialize a result variable: invalid execution context scope"); 782 return; 783 } 784 785 lldb::addr_t address; 786 Error read_error; 787 788 map.ReadPointerFromMemory (&address, process_address + m_offset, read_error); 789 790 if (!read_error.Success()) 791 { 792 err.SetErrorToGenericError(); 793 err.SetErrorString("Couldn't dematerialize a result variable: couldn't read its address"); 794 return; 795 } 796 797 lldb::TargetSP target_sp = exe_scope->CalculateTarget(); 798 799 if (!target_sp) 800 { 801 err.SetErrorToGenericError(); 802 err.SetErrorString("Couldn't dematerialize a result variable: no target"); 803 return; 804 } 805 806 ConstString name = target_sp->GetPersistentVariables().GetNextPersistentVariableName(); 807 808 lldb::ClangExpressionVariableSP ret; 809 810 ret = target_sp->GetPersistentVariables().CreateVariable(exe_scope, 811 name, 812 m_type, 813 map.GetByteOrder(), 814 map.GetAddressByteSize()); 815 816 if (!ret) 817 { 818 err.SetErrorToGenericError(); 819 err.SetErrorStringWithFormat("Couldn't dematerialize a result variable: failed to make persistent variable %s", name.AsCString()); 820 return; 821 } 822 823 lldb::ProcessSP process_sp = map.GetBestExecutionContextScope()->CalculateProcess(); 824 825 bool can_persist = (m_is_program_reference && process_sp && process_sp->CanJIT() && !(address >= frame_bottom && address < frame_top)); 826 827 if (can_persist && m_keep_in_memory) 828 { 829 ret->m_live_sp = ValueObjectConstResult::Create(exe_scope, 830 m_type.GetASTContext(), 831 m_type.GetOpaqueQualType(), 832 name, 833 address, 834 eAddressTypeLoad, 835 ret->GetByteSize()); 836 } 837 838 ret->ValueUpdated(); 839 840 const size_t pvar_byte_size = ret->GetByteSize(); 841 uint8_t *pvar_data = ret->GetValueBytes(); 842 843 map.ReadMemory(pvar_data, address, pvar_byte_size, read_error); 844 845 if (!read_error.Success()) 846 { 847 err.SetErrorToGenericError(); 848 err.SetErrorString("Couldn't dematerialize a result variable: couldn't read its memory"); 849 return; 850 } 851 852 result_variable_sp = ret; 853 854 if (!can_persist || !m_keep_in_memory) 855 { 856 ret->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 857 858 if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 859 { 860 Error free_error; 861 map.Free(m_temporary_allocation, free_error); 862 } 863 } 864 else 865 { 866 ret->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 867 } 868 869 m_temporary_allocation = LLDB_INVALID_ADDRESS; 870 m_temporary_allocation_size = 0; 871 } 872 873 void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 874 { 875 StreamString dump_stream; 876 877 dump_stream.Printf("0x%llx: EntityResultVariable\n", (unsigned long long)process_address + m_offset); 878 879 Error err; 880 881 lldb::addr_t ptr = LLDB_INVALID_ADDRESS; 882 883 { 884 dump_stream.Printf("Pointer:\n"); 885 886 DataBufferHeap data (m_size, 0); 887 888 map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); 889 890 if (!err.Success()) 891 { 892 dump_stream.Printf(" <could not be read>\n"); 893 } 894 else 895 { 896 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 897 898 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); 899 900 lldb::offset_t offset; 901 902 ptr = extractor.GetPointer(&offset); 903 904 dump_stream.PutChar('\n'); 905 } 906 } 907 908 if (m_temporary_allocation == LLDB_INVALID_ADDRESS) 909 { 910 dump_stream.Printf("Points to process memory:\n"); 911 } 912 else 913 { 914 dump_stream.Printf("Temporary allocation:\n"); 915 } 916 917 if (ptr == LLDB_INVALID_ADDRESS) 918 { 919 dump_stream.Printf(" <could not be be found>\n"); 920 } 921 else 922 { 923 DataBufferHeap data (m_temporary_allocation_size, 0); 924 925 map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err); 926 927 if (!err.Success()) 928 { 929 dump_stream.Printf(" <could not be read>\n"); 930 } 931 else 932 { 933 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 934 935 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); 936 937 dump_stream.PutChar('\n'); 938 } 939 } 940 941 log->PutCString(dump_stream.GetData()); 942 } 943 944 void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 945 { 946 if (!m_keep_in_memory && m_temporary_allocation != LLDB_INVALID_ADDRESS) 947 { 948 Error free_error; 949 950 map.Free(m_temporary_allocation, free_error); 951 } 952 953 m_temporary_allocation = LLDB_INVALID_ADDRESS; 954 m_temporary_allocation_size = 0; 955 } 956 private: 957 TypeFromUser m_type; 958 bool m_is_program_reference; 959 bool m_keep_in_memory; 960 961 lldb::addr_t m_temporary_allocation; 962 size_t m_temporary_allocation_size; 963 }; 964 965 uint32_t 966 Materializer::AddResultVariable (const TypeFromUser &type, bool is_program_reference, bool keep_in_memory, Error &err) 967 { 968 EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 969 iter->reset (new EntityResultVariable (type, is_program_reference, keep_in_memory)); 970 uint32_t ret = AddStructMember(**iter); 971 (*iter)->SetOffset(ret); 972 m_result_entity = iter->get(); 973 return ret; 974 } 975 976 class EntitySymbol : public Materializer::Entity 977 { 978 public: 979 EntitySymbol (const Symbol &symbol) : 980 Entity(), 981 m_symbol(symbol) 982 { 983 // Hard-coding to maximum size of a symbol 984 m_size = 8; 985 m_alignment = 8; 986 } 987 988 void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 989 { 990 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 991 992 if (log) 993 { 994 log->Printf("EntitySymbol::Materialize [process_address = 0x%llx, m_symbol = %s]", 995 (uint64_t)process_address, 996 m_symbol.GetName().AsCString()); 997 } 998 999 Address &sym_address = m_symbol.GetAddress(); 1000 1001 ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope(); 1002 1003 lldb::TargetSP target_sp; 1004 1005 if (exe_scope) 1006 target_sp = map.GetBestExecutionContextScope()->CalculateTarget(); 1007 1008 if (!target_sp) 1009 { 1010 err.SetErrorToGenericError(); 1011 err.SetErrorStringWithFormat("Couldn't resolve symbol %s because there is no target", m_symbol.GetName().AsCString()); 1012 return; 1013 } 1014 1015 lldb::addr_t resolved_address = sym_address.GetLoadAddress(target_sp.get()); 1016 1017 if (resolved_address == LLDB_INVALID_ADDRESS) 1018 resolved_address = sym_address.GetFileAddress(); 1019 1020 Error pointer_write_error; 1021 1022 map.WritePointerToMemory(process_address + m_offset, resolved_address, pointer_write_error); 1023 1024 if (!pointer_write_error.Success()) 1025 { 1026 err.SetErrorToGenericError(); 1027 err.SetErrorStringWithFormat("Couldn't write the address of symbol %s: %s", m_symbol.GetName().AsCString(), pointer_write_error.AsCString()); 1028 return; 1029 } 1030 } 1031 1032 void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, 1033 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) 1034 { 1035 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1036 1037 if (log) 1038 { 1039 log->Printf("EntitySymbol::Dematerialize [process_address = 0x%llx, m_symbol = %s]", 1040 (uint64_t)process_address, 1041 m_symbol.GetName().AsCString()); 1042 } 1043 1044 // no work needs to be done 1045 } 1046 1047 void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 1048 { 1049 StreamString dump_stream; 1050 1051 Error err; 1052 1053 dump_stream.Printf("0x%llx: EntitySymbol (%s)\n", (unsigned long long)process_address + m_offset, m_symbol.GetName().AsCString()); 1054 1055 { 1056 dump_stream.Printf("Pointer:\n"); 1057 1058 DataBufferHeap data (m_size, 0); 1059 1060 map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); 1061 1062 if (!err.Success()) 1063 { 1064 dump_stream.Printf(" <could not be read>\n"); 1065 } 1066 else 1067 { 1068 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 1069 1070 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); 1071 1072 dump_stream.PutChar('\n'); 1073 } 1074 } 1075 1076 log->PutCString(dump_stream.GetData()); 1077 } 1078 1079 void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 1080 { 1081 } 1082 private: 1083 Symbol m_symbol; 1084 }; 1085 1086 uint32_t 1087 Materializer::AddSymbol (const Symbol &symbol_sp, Error &err) 1088 { 1089 EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 1090 iter->reset (new EntitySymbol (symbol_sp)); 1091 uint32_t ret = AddStructMember(**iter); 1092 (*iter)->SetOffset(ret); 1093 return ret; 1094 } 1095 1096 class EntityRegister : public Materializer::Entity 1097 { 1098 public: 1099 EntityRegister (const RegisterInfo ®ister_info) : 1100 Entity(), 1101 m_register_info(register_info) 1102 { 1103 // Hard-coding alignment conservatively 1104 m_size = m_register_info.byte_size; 1105 m_alignment = m_register_info.byte_size; 1106 } 1107 1108 void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 1109 { 1110 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1111 1112 if (log) 1113 { 1114 log->Printf("EntityRegister::Materialize [process_address = 0x%llx, m_register_info = %s]", 1115 (uint64_t)process_address, 1116 m_register_info.name); 1117 } 1118 1119 RegisterValue reg_value; 1120 1121 if (!frame_sp.get()) 1122 { 1123 err.SetErrorToGenericError(); 1124 err.SetErrorStringWithFormat("Couldn't materialize register %s without a stack frame", m_register_info.name); 1125 return; 1126 } 1127 1128 lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext(); 1129 1130 if (!reg_context_sp->ReadRegister(&m_register_info, reg_value)) 1131 { 1132 err.SetErrorToGenericError(); 1133 err.SetErrorStringWithFormat("Couldn't read the value of register %s", m_register_info.name); 1134 return; 1135 } 1136 1137 DataExtractor register_data; 1138 1139 if (!reg_value.GetData(register_data)) 1140 { 1141 err.SetErrorToGenericError(); 1142 err.SetErrorStringWithFormat("Couldn't get the data for register %s", m_register_info.name); 1143 return; 1144 } 1145 1146 if (register_data.GetByteSize() != m_register_info.byte_size) 1147 { 1148 err.SetErrorToGenericError(); 1149 err.SetErrorStringWithFormat("Data for register %s had size %llu but we expected %llu", m_register_info.name, (unsigned long long)register_data.GetByteSize(), (unsigned long long)m_register_info.byte_size); 1150 return; 1151 } 1152 1153 Error write_error; 1154 1155 map.WriteMemory(process_address + m_offset, register_data.GetDataStart(), register_data.GetByteSize(), write_error); 1156 1157 if (!write_error.Success()) 1158 { 1159 err.SetErrorToGenericError(); 1160 err.SetErrorStringWithFormat("Couldn't write the contents of register %s: %s", m_register_info.name, write_error.AsCString()); 1161 return; 1162 } 1163 } 1164 1165 void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, 1166 lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) 1167 { 1168 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1169 1170 if (log) 1171 { 1172 log->Printf("EntityRegister::Dematerialize [process_address = 0x%llx, m_register_info = %s]", 1173 (uint64_t)process_address, 1174 m_register_info.name); 1175 } 1176 1177 Error extract_error; 1178 1179 DataExtractor register_data; 1180 1181 if (!frame_sp.get()) 1182 { 1183 err.SetErrorToGenericError(); 1184 err.SetErrorStringWithFormat("Couldn't dematerialize register %s without a stack frame", m_register_info.name); 1185 return; 1186 } 1187 1188 lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext(); 1189 1190 map.GetMemoryData(register_data, process_address + m_offset, m_register_info.byte_size, extract_error); 1191 1192 if (!extract_error.Success()) 1193 { 1194 err.SetErrorToGenericError(); 1195 err.SetErrorStringWithFormat("Couldn't get the data for register %s: %s", m_register_info.name, extract_error.AsCString()); 1196 return; 1197 } 1198 1199 RegisterValue register_value (const_cast<uint8_t*>(register_data.GetDataStart()), register_data.GetByteSize(), register_data.GetByteOrder()); 1200 1201 if (!reg_context_sp->WriteRegister(&m_register_info, register_value)) 1202 { 1203 err.SetErrorToGenericError(); 1204 err.SetErrorStringWithFormat("Couldn't write the value of register %s", m_register_info.name); 1205 return; 1206 } 1207 } 1208 1209 void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 1210 { 1211 StreamString dump_stream; 1212 1213 Error err; 1214 1215 dump_stream.Printf("0x%llx: EntityRegister (%s)\n", (unsigned long long)process_address + m_offset, m_register_info.name); 1216 1217 { 1218 dump_stream.Printf("Value:\n"); 1219 1220 DataBufferHeap data (m_size, 0); 1221 1222 map.ReadMemory(data.GetBytes(), process_address + m_offset, m_size, err); 1223 1224 if (!err.Success()) 1225 { 1226 dump_stream.Printf(" <could not be read>\n"); 1227 } 1228 else 1229 { 1230 DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 1231 1232 extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); 1233 1234 dump_stream.PutChar('\n'); 1235 } 1236 } 1237 1238 log->PutCString(dump_stream.GetData()); 1239 } 1240 1241 void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 1242 { 1243 } 1244 private: 1245 RegisterInfo m_register_info; 1246 }; 1247 1248 uint32_t 1249 Materializer::AddRegister (const RegisterInfo ®ister_info, Error &err) 1250 { 1251 EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 1252 iter->reset (new EntityRegister (register_info)); 1253 uint32_t ret = AddStructMember(**iter); 1254 (*iter)->SetOffset(ret); 1255 return ret; 1256 } 1257 1258 Materializer::Materializer () : 1259 m_dematerializer_wp(), 1260 m_result_entity(NULL), 1261 m_current_offset(0), 1262 m_struct_alignment(8) 1263 { 1264 } 1265 1266 Materializer::~Materializer () 1267 { 1268 DematerializerSP dematerializer_sp = m_dematerializer_wp.lock(); 1269 1270 if (dematerializer_sp) 1271 dematerializer_sp->Wipe(); 1272 } 1273 1274 Materializer::DematerializerSP 1275 Materializer::Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &error) 1276 { 1277 ExecutionContextScope *exe_scope = frame_sp.get(); 1278 1279 if (!exe_scope) 1280 exe_scope = map.GetBestExecutionContextScope(); 1281 1282 DematerializerSP dematerializer_sp = m_dematerializer_wp.lock(); 1283 1284 if (dematerializer_sp) 1285 { 1286 error.SetErrorToGenericError(); 1287 error.SetErrorString("Couldn't materialize: already materialized"); 1288 } 1289 1290 DematerializerSP ret(new Dematerializer(*this, frame_sp, map, process_address)); 1291 1292 if (!exe_scope) 1293 { 1294 error.SetErrorToGenericError(); 1295 error.SetErrorString("Couldn't materialize: target doesn't exist"); 1296 } 1297 1298 for (EntityUP &entity_up : m_entities) 1299 { 1300 entity_up->Materialize(frame_sp, map, process_address, error); 1301 1302 if (!error.Success()) 1303 return DematerializerSP(); 1304 } 1305 1306 if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 1307 { 1308 log->Printf("Materializer::Materialize (frame_sp = %p, process_address = 0x%llx) materialized:", frame_sp.get(), process_address); 1309 for (EntityUP &entity_up : m_entities) 1310 entity_up->DumpToLog(map, process_address, log); 1311 } 1312 1313 m_dematerializer_wp = ret; 1314 1315 return ret; 1316 } 1317 1318 void 1319 Materializer::Dematerializer::Dematerialize (Error &error, lldb::ClangExpressionVariableSP &result_sp, lldb::addr_t frame_bottom, lldb::addr_t frame_top) 1320 { 1321 lldb::StackFrameSP frame_sp = m_frame_wp.lock(); 1322 1323 ExecutionContextScope *exe_scope = m_map->GetBestExecutionContextScope(); 1324 1325 if (!IsValid()) 1326 { 1327 error.SetErrorToGenericError(); 1328 error.SetErrorString("Couldn't dematerialize: invalid dematerializer"); 1329 } 1330 1331 if (!exe_scope) 1332 { 1333 error.SetErrorToGenericError(); 1334 error.SetErrorString("Couldn't dematerialize: target is gone"); 1335 } 1336 else 1337 { 1338 if (Log *log =lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 1339 { 1340 log->Printf("Materializer::Dematerialize (frame_sp = %p, process_address = 0x%llx) about to dematerialize:", frame_sp.get(), m_process_address); 1341 for (EntityUP &entity_up : m_materializer->m_entities) 1342 entity_up->DumpToLog(*m_map, m_process_address, log); 1343 } 1344 1345 for (EntityUP &entity_up : m_materializer->m_entities) 1346 { 1347 if (entity_up.get() == m_materializer->m_result_entity) 1348 { 1349 static_cast<EntityResultVariable*>(m_materializer->m_result_entity)->Dematerialize (result_sp, frame_sp, *m_map, m_process_address, frame_top, frame_bottom, error); 1350 } 1351 else 1352 { 1353 entity_up->Dematerialize (frame_sp, *m_map, m_process_address, frame_top, frame_bottom, error); 1354 } 1355 1356 if (!error.Success()) 1357 break; 1358 } 1359 } 1360 1361 Wipe(); 1362 } 1363 1364 void 1365 Materializer::Dematerializer::Wipe () 1366 { 1367 if (!IsValid()) 1368 return; 1369 1370 for (EntityUP &entity_up : m_materializer->m_entities) 1371 { 1372 entity_up->Wipe (*m_map, m_process_address); 1373 } 1374 1375 m_materializer = NULL; 1376 m_map = NULL; 1377 m_process_address = LLDB_INVALID_ADDRESS; 1378 } 1379