13b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan//===-- Materializer.cpp ----------------------------------------*- C++ -*-===// 23b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan// 33b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan// The LLVM Compiler Infrastructure 43b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan// 53b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan// This file is distributed under the University of Illinois Open Source 63b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan// License. See LICENSE.TXT for details. 73b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan// 83b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan//===----------------------------------------------------------------------===// 93b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 10f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan#include "lldb/Core/Log.h" 11973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan#include "lldb/Core/RegisterValue.h" 12f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan#include "lldb/Core/ValueObjectConstResult.h" 13934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan#include "lldb/Core/ValueObjectVariable.h" 143b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan#include "lldb/Expression/ClangExpressionVariable.h" 153b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan#include "lldb/Expression/Materializer.h" 163b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan#include "lldb/Symbol/ClangASTContext.h" 173b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan#include "lldb/Symbol/Symbol.h" 183b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan#include "lldb/Symbol/Type.h" 193b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan#include "lldb/Symbol/Variable.h" 203b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan#include "lldb/Target/ExecutionContext.h" 21973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan#include "lldb/Target/RegisterContext.h" 22934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan#include "lldb/Target/StackFrame.h" 230f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan#include "lldb/Target/Target.h" 24d0f064d4e5ccef341ecbd6a462bbff5f085a3f77Sean Callanan#include "lldb/Target/Thread.h" 253b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 263b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananusing namespace lldb_private; 273b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 283b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananuint32_t 293b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean CallananMaterializer::AddStructMember (Entity &entity) 303b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 313b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan uint32_t size = entity.GetSize(); 323b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan uint32_t alignment = entity.GetAlignment(); 333b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 343b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan uint32_t ret; 353b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 36ce66f96d4329a5664561ceb6f1fc571ed497bcefSean Callanan if (m_current_offset == 0) 373b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_struct_alignment = alignment; 383b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 393b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan if (m_current_offset % alignment) 403b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_current_offset += (alignment - (m_current_offset % alignment)); 413b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 423b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan ret = m_current_offset; 433b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 443b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_current_offset += size; 453b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 463b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan return ret; 473b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 483b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 493b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananvoid 503b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean CallananMaterializer::Entity::SetSizeAndAlignmentFromType (ClangASTType &type) 513b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 5252f792329be5db8e38961350589e97e8f2823acdGreg Clayton m_size = type.GetByteSize(); 533b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 543b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan uint32_t bit_alignment = type.GetTypeBitAlign(); 553b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 563b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan if (bit_alignment % 8) 573b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 583b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan bit_alignment += 8; 593b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan bit_alignment &= ~((uint32_t)0x111u); 603b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 613b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 623b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_alignment = bit_alignment / 8; 633b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 643b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 653b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananclass EntityPersistentVariable : public Materializer::Entity 663b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 673b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananpublic: 683b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan EntityPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp) : 693b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan Entity(), 703b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_persistent_variable_sp(persistent_variable_sp) 713b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 72a6686e36cd56843e594139324884585fb47b918bSean Callanan // Hard-coding to maximum size of a pointer since persistent variables are materialized by reference 73a6686e36cd56843e594139324884585fb47b918bSean Callanan m_size = 8; 74a6686e36cd56843e594139324884585fb47b918bSean Callanan m_alignment = 8; 753b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 763b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 77f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan void MakeAllocation (IRMemoryMap &map, Error &err) 78f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 79f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 80f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 81f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // Allocate a spare memory area to store the persistent variable's contents. 82f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 83f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan Error allocate_error; 84f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 85f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan lldb::addr_t mem = map.Malloc(m_persistent_variable_sp->GetByteSize(), 86f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 8, 87f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan lldb::ePermissionsReadable | lldb::ePermissionsWritable, 88f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan IRMemoryMap::eAllocationPolicyMirror, 89f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan allocate_error); 90f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 91f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (!allocate_error.Success()) 92f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 93668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't allocate a memory area to store %s: %s", m_persistent_variable_sp->GetName().GetCString(), allocate_error.AsCString()); 94f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 95f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 96f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 97f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (log) 98f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan log->Printf("Allocated %s (0x%" PRIx64 ") sucessfully", m_persistent_variable_sp->GetName().GetCString(), mem); 99f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 100f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // Put the location of the spare memory into the live data of the ValueObject. 101f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 102f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope(), 10352f792329be5db8e38961350589e97e8f2823acdGreg Clayton m_persistent_variable_sp->GetTypeFromUser(), 104f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->GetName(), 105f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan mem, 106f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan eAddressTypeLoad, 107f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->GetByteSize()); 108f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 109f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // Clear the flag if the variable will never be deallocated. 110f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 111f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget) 112e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan { 113e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan Error leak_error; 114e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan map.Leak(mem, leak_error); 115f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVNeedsAllocation; 116e7872343f18b90e4134fb91a616b138ba6bd6b92Sean Callanan } 117f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 118f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // Write the contents of the variable to the area. 119f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 120f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan Error write_error; 121f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 122f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan map.WriteMemory (mem, 123f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->GetValueBytes(), 124f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->GetByteSize(), 125f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan write_error); 126f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 127f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (!write_error.Success()) 128f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 129668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat ("couldn't write %s to the target: %s", m_persistent_variable_sp->GetName().AsCString(), 130f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan write_error.AsCString()); 131f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 132f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 133f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 134f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 135f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan void DestroyAllocation (IRMemoryMap &map, Error &err) 136f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 137f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan Error deallocate_error; 138f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 139f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan map.Free((lldb::addr_t)m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong(), deallocate_error); 1406c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan 1416c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan m_persistent_variable_sp->m_live_sp.reset(); 142f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 143f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (!deallocate_error.Success()) 144f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 145668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat ("couldn't deallocate memory for %s: %s", m_persistent_variable_sp->GetName().GetCString(), deallocate_error.AsCString()); 146f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 147f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 148f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 149a6686e36cd56843e594139324884585fb47b918bSean Callanan void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 1503b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 151f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 152f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 15352f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 15452f792329be5db8e38961350589e97e8f2823acdGreg Clayton 155f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (log) 156f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 15752f792329be5db8e38961350589e97e8f2823acdGreg Clayton log->Printf("EntityPersistentVariable::Materialize [address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]", 15852f792329be5db8e38961350589e97e8f2823acdGreg Clayton (uint64_t)load_addr, 159f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->GetName().AsCString(), 160f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags); 161f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 162f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 163f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation) 164f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 165f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan MakeAllocation(map, err); 1666c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 1676c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan 168f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (!err.Success()) 169f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 170f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 171f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 172f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if ((m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && m_persistent_variable_sp->m_live_sp) || 173f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) 174f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 175f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan Error write_error; 1766c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan 17752f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.WriteScalarToMemory(load_addr, 178f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(), 1796c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan map.GetAddressByteSize(), 180f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan write_error); 181f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 182f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (!write_error.Success()) 183f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 184668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write the location of %s to memory: %s", m_persistent_variable_sp->GetName().AsCString(), write_error.AsCString()); 185f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 186f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 187f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan else 188f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 189668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("no materialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString()); 190f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 191f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 1923b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 1933b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 19452f792329be5db8e38961350589e97e8f2823acdGreg Clayton void Dematerialize (lldb::StackFrameSP &frame_sp, 19552f792329be5db8e38961350589e97e8f2823acdGreg Clayton IRMemoryMap &map, 19652f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t process_address, 19752f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_top, 19852f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_bottom, 19952f792329be5db8e38961350589e97e8f2823acdGreg Clayton Error &err) 2003b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 201f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 202f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 20352f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 20452f792329be5db8e38961350589e97e8f2823acdGreg Clayton 205f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (log) 206f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 20752f792329be5db8e38961350589e97e8f2823acdGreg Clayton log->Printf("EntityPersistentVariable::Dematerialize [address = 0x%" PRIx64 ", m_name = %s, m_flags = 0x%hx]", 20852f792329be5db8e38961350589e97e8f2823acdGreg Clayton (uint64_t)process_address + m_offset, 209f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->GetName().AsCString(), 210f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags); 211f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 212f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 213f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if ((m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) || 214f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference)) 215f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 216f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && 217f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan !m_persistent_variable_sp->m_live_sp) 218f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 219f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // If the reference comes from the program, then the ClangExpressionVariable's 220f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // live variable data hasn't been set up yet. Do this now. 221f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 222a6686e36cd56843e594139324884585fb47b918bSean Callanan lldb::addr_t location; 223f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan Error read_error; 224f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 22552f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.ReadPointerFromMemory(&location, load_addr, read_error); 226f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 227f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (!read_error.Success()) 228f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 229668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't read the address of program-allocated variable %s: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString()); 230f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 231f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 232a6686e36cd56843e594139324884585fb47b918bSean Callanan 233f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope (), 23452f792329be5db8e38961350589e97e8f2823acdGreg Clayton m_persistent_variable_sp->GetTypeFromUser(), 235f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->GetName(), 236f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan location, 237f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan eAddressTypeLoad, 238f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->GetByteSize()); 239f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 240f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (frame_top != LLDB_INVALID_ADDRESS && 241f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan frame_bottom != LLDB_INVALID_ADDRESS && 242f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan location >= frame_bottom && 243f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan location <= frame_top) 244f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 245f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // If the variable is resident in the stack frame created by the expression, 246f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // then it cannot be relied upon to stay around. We treat it as needing 247f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // reallocation. 248f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 249f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 250f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry; 251f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVIsProgramReference; 252f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 253f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 254f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 255f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan lldb::addr_t mem = m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong(); 256f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 257f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (!m_persistent_variable_sp->m_live_sp) 258f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 259668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't find the memory area used to store %s", m_persistent_variable_sp->GetName().GetCString()); 260f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 261f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 262f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 263f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (m_persistent_variable_sp->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad) 264f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 265668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("the address of the memory area for %s is in an incorrect format", m_persistent_variable_sp->GetName().GetCString()); 266f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 267f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 268f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 269f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry || 270f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget) 271f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 272f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (log) 273f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 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()); 274f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 275f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan // Read the contents of the spare memory area 276f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 277f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->ValueUpdated (); 278f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 279f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan Error read_error; 280f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 281f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan map.ReadMemory(m_persistent_variable_sp->GetValueBytes(), 282f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan mem, 283f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->GetByteSize(), 284f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan read_error); 285f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 286f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (!read_error.Success()) 287f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 288668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat ("couldn't read the contents of %s from memory: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString()); 289f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 290f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 291f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 292f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVNeedsFreezeDry; 293f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 294f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 295f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan else 296f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 297668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("no dematerialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString()); 298f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 299f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 300f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan 3016c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan lldb::ProcessSP process_sp = map.GetBestExecutionContextScope()->CalculateProcess(); 3026c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan if (!process_sp || 3036c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan !process_sp->CanJIT()) 3046c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan { 3056c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan // Allocations are not persistent so persistent variables cannot stay materialized. 3066c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan 3076c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 3086c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan 3096c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan DestroyAllocation(map, err); 3106c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan if (!err.Success()) 3116c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan return; 3126c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan } 3136c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan else if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation && 3146c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan !(m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)) 315f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan { 316f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan DestroyAllocation(map, err); 317f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan if (!err.Success()) 318f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan return; 319f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan } 3203b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 32176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 32276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 32376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 32476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan StreamString dump_stream; 32576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 32676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan Error err; 32776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 32852f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 32952f792329be5db8e38961350589e97e8f2823acdGreg Clayton 33052f792329be5db8e38961350589e97e8f2823acdGreg Clayton dump_stream.Printf("0x%" PRIx64 ": EntityPersistentVariable (%s)\n", load_addr, m_persistent_variable_sp->GetName().AsCString()); 33176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 33276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 33376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf("Pointer:\n"); 33476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 33576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataBufferHeap data (m_size, 0); 33676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 33752f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.ReadMemory(data.GetBytes(), load_addr, m_size, err); 33876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 33976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan if (!err.Success()) 34076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 34176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf(" <could not be read>\n"); 34276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 34376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan else 34476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 34576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 34676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 34752f792329be5db8e38961350589e97e8f2823acdGreg Clayton extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); 348a6686e36cd56843e594139324884585fb47b918bSean Callanan 349a6686e36cd56843e594139324884585fb47b918bSean Callanan dump_stream.PutChar('\n'); 35076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 35176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 35276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 35376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 35476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf("Target:\n"); 35576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 35676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan lldb::addr_t target_address; 35776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 35852f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.ReadPointerFromMemory (&target_address, load_addr, err); 35976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 36076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan if (!err.Success()) 36176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 36276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf(" <could not be read>\n"); 36376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 36476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan else 36576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 36676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataBufferHeap data (m_persistent_variable_sp->GetByteSize(), 0); 36776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 36876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan map.ReadMemory(data.GetBytes(), target_address, m_persistent_variable_sp->GetByteSize(), err); 36976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 37076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan if (!err.Success()) 37176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 37276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf(" <could not be read>\n"); 37376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 37476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan else 37576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 37676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 37776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 37876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, target_address); 379a6686e36cd56843e594139324884585fb47b918bSean Callanan 380a6686e36cd56843e594139324884585fb47b918bSean Callanan dump_stream.PutChar('\n'); 38176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 38276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 38376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 38476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 38576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan log->PutCString(dump_stream.GetData()); 38676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 38776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 388a6686e36cd56843e594139324884585fb47b918bSean Callanan void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 389a6686e36cd56843e594139324884585fb47b918bSean Callanan { 390a6686e36cd56843e594139324884585fb47b918bSean Callanan } 3913b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananprivate: 3923b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan lldb::ClangExpressionVariableSP m_persistent_variable_sp; 3933b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan}; 3943b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 3953b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananuint32_t 3963b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean CallananMaterializer::AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err) 3973b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 3983b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 3993b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan iter->reset (new EntityPersistentVariable (persistent_variable_sp)); 4003b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan uint32_t ret = AddStructMember(**iter); 4013b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan (*iter)->SetOffset(ret); 4023b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan return ret; 4033b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 4043b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 4053b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananclass EntityVariable : public Materializer::Entity 4063b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 4073b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananpublic: 4083b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan EntityVariable (lldb::VariableSP &variable_sp) : 4093b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan Entity(), 410934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan m_variable_sp(variable_sp), 411934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan m_is_reference(false), 41276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan m_temporary_allocation(LLDB_INVALID_ADDRESS), 41376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan m_temporary_allocation_size(0) 4143b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 415934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan // Hard-coding to maximum size of a pointer since all variables are materialized by reference 416ce66f96d4329a5664561ceb6f1fc571ed497bcefSean Callanan m_size = 8; 417ce66f96d4329a5664561ceb6f1fc571ed497bcefSean Callanan m_alignment = 8; 41852f792329be5db8e38961350589e97e8f2823acdGreg Clayton m_is_reference = m_variable_sp->GetType()->GetClangForwardType().IsReferenceType(); 4193b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 4203b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 421a6686e36cd56843e594139324884585fb47b918bSean Callanan void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 4223b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 423934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 424934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 42552f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 426934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (log) 427934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 42852f792329be5db8e38961350589e97e8f2823acdGreg Clayton log->Printf("EntityVariable::Materialize [address = 0x%" PRIx64 ", m_variable_sp = %s]", 42952f792329be5db8e38961350589e97e8f2823acdGreg Clayton (uint64_t)load_addr, 430934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan m_variable_sp->GetName().AsCString()); 431934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 432934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 433faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan ExecutionContextScope *scope = frame_sp.get(); 434faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan 435faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan if (!scope) 436faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan scope = map.GetBestExecutionContextScope(); 437faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan 438faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan lldb::ValueObjectSP valobj_sp = ValueObjectVariable::Create(scope, m_variable_sp); 439934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 440934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (!valobj_sp) 441934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 442668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't get a value object for variable %s", m_variable_sp->GetName().AsCString()); 443934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan return; 444934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 445934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 446934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (m_is_reference) 447934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 448934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan DataExtractor valobj_extractor; 449934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan valobj_sp->GetData(valobj_extractor); 450934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan lldb::offset_t offset = 0; 451934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan lldb::addr_t reference_addr = valobj_extractor.GetAddress(&offset); 452934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 453934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan Error write_error; 45452f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.WritePointerToMemory(load_addr, reference_addr, write_error); 455934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 456934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (!write_error.Success()) 457934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 458668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write the contents of reference variable %s to memory: %s", m_variable_sp->GetName().AsCString(), write_error.AsCString()); 459934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan return; 460934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 461934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 462934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan else 463934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 464934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan Error get_address_error; 465934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan lldb::ValueObjectSP addr_of_valobj_sp = valobj_sp->AddressOf(get_address_error); 466934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (get_address_error.Success()) 467934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 468934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan DataExtractor valobj_extractor; 469934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan addr_of_valobj_sp->GetData(valobj_extractor); 470934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan lldb::offset_t offset = 0; 471934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan lldb::addr_t addr_of_valobj_addr = valobj_extractor.GetAddress(&offset); 472934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 473934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan Error write_error; 47452f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.WritePointerToMemory(load_addr, addr_of_valobj_addr, write_error); 475934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 476934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (!write_error.Success()) 477934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 478668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write the address of variable %s to memory: %s", m_variable_sp->GetName().AsCString(), write_error.AsCString()); 479934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan return; 480934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 481934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 482934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan else 483934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 484934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan DataExtractor data; 485934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan valobj_sp->GetData(data); 486934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 4870f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 488934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 489668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("trying to create a temporary region for %s but one exists", m_variable_sp->GetName().AsCString()); 490934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan return; 491934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 492934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 493934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (data.GetByteSize() != m_variable_sp->GetType()->GetByteSize()) 494934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 495668010966e95642360fd12094b28755e5dda5343Greg Clayton if (data.GetByteSize() == 0 && m_variable_sp->LocationExpression().IsValid() == false) 496668010966e95642360fd12094b28755e5dda5343Greg Clayton { 497668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("the variable '%s' has no location, it may have been optimized out", m_variable_sp->GetName().AsCString()); 498668010966e95642360fd12094b28755e5dda5343Greg Clayton } 499668010966e95642360fd12094b28755e5dda5343Greg Clayton else 500668010966e95642360fd12094b28755e5dda5343Greg Clayton { 501668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("size of variable %s disagrees with the ValueObject's size", m_variable_sp->GetName().AsCString()); 502668010966e95642360fd12094b28755e5dda5343Greg Clayton } 503934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan return; 504934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 505934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 50652f792329be5db8e38961350589e97e8f2823acdGreg Clayton size_t bit_align = m_variable_sp->GetType()->GetClangLayoutType().GetTypeBitAlign(); 507934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan size_t byte_align = (bit_align + 7) / 8; 508934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 509934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan Error alloc_error; 510934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 511934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan m_temporary_allocation = map.Malloc(data.GetByteSize(), byte_align, lldb::ePermissionsReadable | lldb::ePermissionsWritable, IRMemoryMap::eAllocationPolicyMirror, alloc_error); 51276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan m_temporary_allocation_size = data.GetByteSize(); 513934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 514934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (!alloc_error.Success()) 515934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 516668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't allocate a temporary region for %s: %s", m_variable_sp->GetName().AsCString(), alloc_error.AsCString()); 517934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan return; 518934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 519934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 520934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan Error write_error; 521934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 522934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan map.WriteMemory(m_temporary_allocation, data.GetDataStart(), data.GetByteSize(), write_error); 523934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 524934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (!write_error.Success()) 525934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 526668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write to the temporary region for %s: %s", m_variable_sp->GetName().AsCString(), write_error.AsCString()); 527934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan return; 528934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 529934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 530934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan Error pointer_write_error; 531934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 53252f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.WritePointerToMemory(load_addr, m_temporary_allocation, pointer_write_error); 533934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 534934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (!pointer_write_error.Success()) 535934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 536668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write the address of the temporary region for %s: %s", m_variable_sp->GetName().AsCString(), pointer_write_error.AsCString()); 537934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 538934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 539934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 5403b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 5413b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 54252f792329be5db8e38961350589e97e8f2823acdGreg Clayton void Dematerialize (lldb::StackFrameSP &frame_sp, 54352f792329be5db8e38961350589e97e8f2823acdGreg Clayton IRMemoryMap &map, 54452f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t process_address, 54552f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_top, 54652f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_bottom, 54752f792329be5db8e38961350589e97e8f2823acdGreg Clayton Error &err) 5483b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 549934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 550934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 55152f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 552934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (log) 553934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 55452f792329be5db8e38961350589e97e8f2823acdGreg Clayton log->Printf("EntityVariable::Dematerialize [address = 0x%" PRIx64 ", m_variable_sp = %s]", 55552f792329be5db8e38961350589e97e8f2823acdGreg Clayton (uint64_t)load_addr, 556934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan m_variable_sp->GetName().AsCString()); 557934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 558934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 559934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 560934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 561faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan ExecutionContextScope *scope = frame_sp.get(); 562faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan 563faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan if (!scope) 564faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan scope = map.GetBestExecutionContextScope(); 565faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan 566faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan lldb::ValueObjectSP valobj_sp = ValueObjectVariable::Create(scope, m_variable_sp); 567934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 568934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (!valobj_sp) 569934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 570668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't get a value object for variable %s", m_variable_sp->GetName().AsCString()); 571934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan return; 572934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 573934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 574e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan lldb_private::DataExtractor data; 575e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan 576e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan Error extract_error; 577e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan 578e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan map.GetMemoryData(data, m_temporary_allocation, valobj_sp->GetByteSize(), extract_error); 579e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan 580e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan if (!extract_error.Success()) 581e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan { 582668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't get the data for variable %s", m_variable_sp->GetName().AsCString()); 583e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan return; 584e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan } 585e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan 586e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan Error set_error; 587e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan 588e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan valobj_sp->SetData(data, set_error); 589e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan 590e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan if (!set_error.Success()) 591e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan { 592668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write the new contents of %s back into the variable", m_variable_sp->GetName().AsCString()); 593e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan return; 594e287e900488e20e07ef986ec0524b872fbeafa5dSean Callanan } 595934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 596934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan Error free_error; 597934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 598934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan map.Free(m_temporary_allocation, free_error); 599934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 600934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan if (!free_error.Success()) 601934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan { 602668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't free the temporary region for %s: %s", m_variable_sp->GetName().AsCString(), free_error.AsCString()); 603934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan return; 604934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 605934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan 606934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan m_temporary_allocation = LLDB_INVALID_ADDRESS; 60776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan m_temporary_allocation_size = 0; 608934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan } 6093b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 61076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 61176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 61276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 61376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan StreamString dump_stream; 61452f792329be5db8e38961350589e97e8f2823acdGreg Clayton 61552f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 61652f792329be5db8e38961350589e97e8f2823acdGreg Clayton dump_stream.Printf("0x%" PRIx64 ": EntityVariable\n", load_addr); 61776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 6180f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan Error err; 6190f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 6200f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan lldb::addr_t ptr = LLDB_INVALID_ADDRESS; 62176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 62276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 62376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf("Pointer:\n"); 62476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 62576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataBufferHeap data (m_size, 0); 62676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 62752f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.ReadMemory(data.GetBytes(), load_addr, m_size, err); 62876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 62976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan if (!err.Success()) 63076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 63176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf(" <could not be read>\n"); 63276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 63376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan else 63476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 63576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 63676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 63752f792329be5db8e38961350589e97e8f2823acdGreg Clayton extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); 638a6686e36cd56843e594139324884585fb47b918bSean Callanan 6390f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan lldb::offset_t offset; 6400f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 6410f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan ptr = extractor.GetPointer(&offset); 6420f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 643a6686e36cd56843e594139324884585fb47b918bSean Callanan dump_stream.PutChar('\n'); 64476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 64576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 64676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 647a6686e36cd56843e594139324884585fb47b918bSean Callanan if (m_temporary_allocation == LLDB_INVALID_ADDRESS) 64876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 6490f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.Printf("Points to process memory:\n"); 65076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 65176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan else 65276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 65376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf("Temporary allocation:\n"); 6540f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 6550f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 6560f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (ptr == LLDB_INVALID_ADDRESS) 6570f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 6580f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.Printf(" <could not be be found>\n"); 6590f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 6600f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan else 6610f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 662a6686e36cd56843e594139324884585fb47b918bSean Callanan DataBufferHeap data (m_temporary_allocation_size, 0); 663a6686e36cd56843e594139324884585fb47b918bSean Callanan 664a6686e36cd56843e594139324884585fb47b918bSean Callanan map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err); 665a6686e36cd56843e594139324884585fb47b918bSean Callanan 666a6686e36cd56843e594139324884585fb47b918bSean Callanan if (!err.Success()) 66776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 66876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf(" <could not be read>\n"); 66976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 67076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan else 67176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 672a6686e36cd56843e594139324884585fb47b918bSean Callanan DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 67376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 67452f792329be5db8e38961350589e97e8f2823acdGreg Clayton extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); 67576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 676a6686e36cd56843e594139324884585fb47b918bSean Callanan dump_stream.PutChar('\n'); 67776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 67876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 67976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 68076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan log->PutCString(dump_stream.GetData()); 68176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 682a6686e36cd56843e594139324884585fb47b918bSean Callanan 683a6686e36cd56843e594139324884585fb47b918bSean Callanan void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 684a6686e36cd56843e594139324884585fb47b918bSean Callanan { 685a6686e36cd56843e594139324884585fb47b918bSean Callanan if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 686a6686e36cd56843e594139324884585fb47b918bSean Callanan { 687a6686e36cd56843e594139324884585fb47b918bSean Callanan Error free_error; 688a6686e36cd56843e594139324884585fb47b918bSean Callanan 689a6686e36cd56843e594139324884585fb47b918bSean Callanan map.Free(m_temporary_allocation, free_error); 690a6686e36cd56843e594139324884585fb47b918bSean Callanan 691a6686e36cd56843e594139324884585fb47b918bSean Callanan m_temporary_allocation = LLDB_INVALID_ADDRESS; 692a6686e36cd56843e594139324884585fb47b918bSean Callanan m_temporary_allocation_size = 0; 693a6686e36cd56843e594139324884585fb47b918bSean Callanan } 694a6686e36cd56843e594139324884585fb47b918bSean Callanan 695a6686e36cd56843e594139324884585fb47b918bSean Callanan } 6963b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananprivate: 697934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan lldb::VariableSP m_variable_sp; 698934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan bool m_is_reference; 699934d6160f5e62914c20f8e229c5e1ca4d9ead99fSean Callanan lldb::addr_t m_temporary_allocation; 70076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan size_t m_temporary_allocation_size; 7013b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan}; 7023b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 7033b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananuint32_t 7043b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean CallananMaterializer::AddVariable (lldb::VariableSP &variable_sp, Error &err) 7053b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 7063b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 7073b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan iter->reset (new EntityVariable (variable_sp)); 7083b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan uint32_t ret = AddStructMember(**iter); 7093b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan (*iter)->SetOffset(ret); 7103b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan return ret; 7113b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 7123b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 7133b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananclass EntityResultVariable : public Materializer::Entity 7143b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 7153b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananpublic: 7160f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan EntityResultVariable (const TypeFromUser &type, bool is_program_reference, bool keep_in_memory) : 7173b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan Entity(), 718f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan m_type(type), 7190f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_is_program_reference(is_program_reference), 7200f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_keep_in_memory(keep_in_memory), 7210f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_temporary_allocation(LLDB_INVALID_ADDRESS), 7220f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_temporary_allocation_size(0) 7233b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 7240f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan // Hard-coding to maximum size of a pointer since all results are materialized by reference 7250f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_size = 8; 7260f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_alignment = 8; 7273b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 7283b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 729a6686e36cd56843e594139324884585fb47b918bSean Callanan void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 7303b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 7310f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!m_is_program_reference) 7320f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 7330f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 7340f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 7350f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan err.SetErrorString("Trying to create a temporary region for the result but one exists"); 7360f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan return; 7370f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 7380f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 73952f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 74052f792329be5db8e38961350589e97e8f2823acdGreg Clayton 74152f792329be5db8e38961350589e97e8f2823acdGreg Clayton size_t byte_size = m_type.GetByteSize(); 7420f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan size_t bit_align = m_type.GetTypeBitAlign(); 7430f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan size_t byte_align = (bit_align + 7) / 8; 7440f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 7450f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan Error alloc_error; 7460f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 7470f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_temporary_allocation = map.Malloc(byte_size, byte_align, lldb::ePermissionsReadable | lldb::ePermissionsWritable, IRMemoryMap::eAllocationPolicyMirror, alloc_error); 7480f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_temporary_allocation_size = byte_size; 7490f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 7500f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!alloc_error.Success()) 7510f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 752668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't allocate a temporary region for the result: %s", alloc_error.AsCString()); 7530f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan return; 7540f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 7550f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 7560f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan Error pointer_write_error; 7570f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 75852f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.WritePointerToMemory(load_addr, m_temporary_allocation, pointer_write_error); 7590f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 7600f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!pointer_write_error.Success()) 7610f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 762668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write the address of the temporary region for the result: %s", pointer_write_error.AsCString()); 7630f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 7640f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 7653b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 7663b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 76752f792329be5db8e38961350589e97e8f2823acdGreg Clayton void Dematerialize (lldb::StackFrameSP &frame_sp, 76852f792329be5db8e38961350589e97e8f2823acdGreg Clayton IRMemoryMap &map, 76952f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t process_address, 77052f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_top, 77152f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_bottom, 77252f792329be5db8e38961350589e97e8f2823acdGreg Clayton Error &err) 7733b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 7740f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan err.SetErrorString("Tried to detmaterialize a result variable with the normal Dematerialize method"); 7750f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 7760f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 7770f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan void Dematerialize (lldb::ClangExpressionVariableSP &result_variable_sp, 77852f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::StackFrameSP &frame_sp, 77952f792329be5db8e38961350589e97e8f2823acdGreg Clayton IRMemoryMap &map, 78052f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t process_address, 78152f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_top, 78252f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_bottom, 78352f792329be5db8e38961350589e97e8f2823acdGreg Clayton Error &err) 7840f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 7850f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan err.Clear(); 7860f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 7870f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope(); 7880f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 7890f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!exe_scope) 7900f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 7910f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan err.SetErrorString("Couldn't dematerialize a result variable: invalid execution context scope"); 7920f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan return; 7930f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 7940f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 7950f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan lldb::addr_t address; 7960f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan Error read_error; 79752f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 7980f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 79952f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.ReadPointerFromMemory (&address, load_addr, read_error); 8000f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8010f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!read_error.Success()) 8020f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 8030f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan err.SetErrorString("Couldn't dematerialize a result variable: couldn't read its address"); 8040f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan return; 8050f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 8060f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8070f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan lldb::TargetSP target_sp = exe_scope->CalculateTarget(); 8080f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8090f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!target_sp) 8100f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 8110f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan err.SetErrorString("Couldn't dematerialize a result variable: no target"); 8120f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan return; 8130f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 8140f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8150f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan ConstString name = target_sp->GetPersistentVariables().GetNextPersistentVariableName(); 8160f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8170f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan lldb::ClangExpressionVariableSP ret; 8180f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8190f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan ret = target_sp->GetPersistentVariables().CreateVariable(exe_scope, 8200f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan name, 8210f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_type, 8220f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan map.GetByteOrder(), 8230f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan map.GetAddressByteSize()); 8240f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8250f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!ret) 8260f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 827668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't dematerialize a result variable: failed to make persistent variable %s", name.AsCString()); 8280f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan return; 8290f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 8300f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8316c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan lldb::ProcessSP process_sp = map.GetBestExecutionContextScope()->CalculateProcess(); 8326c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan 833cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan bool can_persist = (m_is_program_reference && process_sp && process_sp->CanJIT() && !(address >= frame_bottom && address < frame_top)); 8346c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan 8356c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan if (can_persist && m_keep_in_memory) 8366c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan { 8376c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan ret->m_live_sp = ValueObjectConstResult::Create(exe_scope, 83852f792329be5db8e38961350589e97e8f2823acdGreg Clayton m_type, 8396c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan name, 8406c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan address, 8416c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan eAddressTypeLoad, 8426c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan ret->GetByteSize()); 8436c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan } 8440f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8450f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan ret->ValueUpdated(); 8460f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8470f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan const size_t pvar_byte_size = ret->GetByteSize(); 8480f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan uint8_t *pvar_data = ret->GetValueBytes(); 8490f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8500f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan map.ReadMemory(pvar_data, address, pvar_byte_size, read_error); 8510f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8520f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!read_error.Success()) 8530f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 8540f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan err.SetErrorString("Couldn't dematerialize a result variable: couldn't read its memory"); 8550f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan return; 8560f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 8570f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8580f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan result_variable_sp = ret; 8590f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8606c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan if (!can_persist || !m_keep_in_memory) 8610f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 8620f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan ret->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 8630f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8646c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan if (m_temporary_allocation != LLDB_INVALID_ADDRESS) 8656c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan { 8666c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan Error free_error; 8676c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan map.Free(m_temporary_allocation, free_error); 8686c7168f14bcd3dac3c6fc584401e36e981f14819Sean Callanan } 8690f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 8700f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan else 8710f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 8720f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan ret->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 8730f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 8740f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8750f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_temporary_allocation = LLDB_INVALID_ADDRESS; 8760f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_temporary_allocation_size = 0; 8773b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 87876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 87976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 88076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 88176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan StreamString dump_stream; 88252f792329be5db8e38961350589e97e8f2823acdGreg Clayton 88352f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 88452f792329be5db8e38961350589e97e8f2823acdGreg Clayton 88552f792329be5db8e38961350589e97e8f2823acdGreg Clayton dump_stream.Printf("0x%" PRIx64 ": EntityResultVariable\n", load_addr); 88676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 8870f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan Error err; 8880f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8890f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan lldb::addr_t ptr = LLDB_INVALID_ADDRESS; 8900f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8910f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 8920f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.Printf("Pointer:\n"); 8930f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8940f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan DataBufferHeap data (m_size, 0); 8950f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 89652f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.ReadMemory(data.GetBytes(), load_addr, m_size, err); 8970f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 8980f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!err.Success()) 8990f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 9000f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.Printf(" <could not be read>\n"); 9010f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9020f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan else 9030f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 9040f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 9050f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 90652f792329be5db8e38961350589e97e8f2823acdGreg Clayton extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); 9070f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9080f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan lldb::offset_t offset; 9090f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9100f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan ptr = extractor.GetPointer(&offset); 9110f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9120f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.PutChar('\n'); 9130f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9140f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9150f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9160f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (m_temporary_allocation == LLDB_INVALID_ADDRESS) 9170f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 9180f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.Printf("Points to process memory:\n"); 9190f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9200f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan else 9210f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 9220f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.Printf("Temporary allocation:\n"); 9230f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9240f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9250f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (ptr == LLDB_INVALID_ADDRESS) 9260f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 9270f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.Printf(" <could not be be found>\n"); 9280f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9290f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan else 9300f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 9310f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan DataBufferHeap data (m_temporary_allocation_size, 0); 9320f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9330f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err); 9340f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9350f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!err.Success()) 9360f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 9370f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.Printf(" <could not be read>\n"); 9380f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9390f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan else 9400f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 9410f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 9420f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 94352f792329be5db8e38961350589e97e8f2823acdGreg Clayton extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); 9440f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9450f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan dump_stream.PutChar('\n'); 9460f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9470f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9480f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 94976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan log->PutCString(dump_stream.GetData()); 95076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 951a6686e36cd56843e594139324884585fb47b918bSean Callanan 952a6686e36cd56843e594139324884585fb47b918bSean Callanan void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 953a6686e36cd56843e594139324884585fb47b918bSean Callanan { 9540f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (!m_keep_in_memory && m_temporary_allocation != LLDB_INVALID_ADDRESS) 9550f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 9560f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan Error free_error; 9570f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9580f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan map.Free(m_temporary_allocation, free_error); 9590f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 9600f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9610f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_temporary_allocation = LLDB_INVALID_ADDRESS; 9620f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_temporary_allocation_size = 0; 963a6686e36cd56843e594139324884585fb47b918bSean Callanan } 9643b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananprivate: 9650f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan TypeFromUser m_type; 9660f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan bool m_is_program_reference; 967f4b59480e8d1056b1638141a6a627b252f657db0Sean Callanan bool m_keep_in_memory; 9680f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 9690f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan lldb::addr_t m_temporary_allocation; 9700f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan size_t m_temporary_allocation_size; 9713b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan}; 9723b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 9733b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananuint32_t 9740f0551e67d8ea8d63ace5456f7d42d951827b017Sean CallananMaterializer::AddResultVariable (const TypeFromUser &type, bool is_program_reference, bool keep_in_memory, Error &err) 9753b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 9763b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 9770f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan iter->reset (new EntityResultVariable (type, is_program_reference, keep_in_memory)); 9783b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan uint32_t ret = AddStructMember(**iter); 9793b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan (*iter)->SetOffset(ret); 9800f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_result_entity = iter->get(); 9813b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan return ret; 9823b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 9833b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 9843b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananclass EntitySymbol : public Materializer::Entity 9853b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 9863b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananpublic: 9873b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan EntitySymbol (const Symbol &symbol) : 9883b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan Entity(), 9893b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_symbol(symbol) 9903b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 9913b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan // Hard-coding to maximum size of a symbol 9923b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_size = 8; 9933b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_alignment = 8; 9943b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 9953b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 996a6686e36cd56843e594139324884585fb47b918bSean Callanan void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 9973b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 998973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 999973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 100052f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 100152f792329be5db8e38961350589e97e8f2823acdGreg Clayton 1002973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (log) 1003973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 100452f792329be5db8e38961350589e97e8f2823acdGreg Clayton log->Printf("EntitySymbol::Materialize [address = 0x%" PRIx64 ", m_symbol = %s]", 100552f792329be5db8e38961350589e97e8f2823acdGreg Clayton (uint64_t)load_addr, 1006973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan m_symbol.GetName().AsCString()); 1007973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1008973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1009aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan Address &sym_address = m_symbol.GetAddress(); 1010aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan 1011aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope(); 1012aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan 1013aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan lldb::TargetSP target_sp; 1014aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan 1015aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan if (exe_scope) 1016aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan target_sp = map.GetBestExecutionContextScope()->CalculateTarget(); 1017aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan 1018aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan if (!target_sp) 1019aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan { 1020668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't resolve symbol %s because there is no target", m_symbol.GetName().AsCString()); 1021aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan return; 1022aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan } 1023aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan 1024aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan lldb::addr_t resolved_address = sym_address.GetLoadAddress(target_sp.get()); 1025aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan 1026aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan if (resolved_address == LLDB_INVALID_ADDRESS) 1027aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan resolved_address = sym_address.GetFileAddress(); 1028aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan 1029aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan Error pointer_write_error; 1030aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan 103152f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.WritePointerToMemory(load_addr, resolved_address, pointer_write_error); 1032aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan 1033aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan if (!pointer_write_error.Success()) 1034aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan { 1035668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write the address of symbol %s: %s", m_symbol.GetName().AsCString(), pointer_write_error.AsCString()); 1036973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan return; 1037aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan } 10383b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 10393b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 104052f792329be5db8e38961350589e97e8f2823acdGreg Clayton void Dematerialize (lldb::StackFrameSP &frame_sp, 104152f792329be5db8e38961350589e97e8f2823acdGreg Clayton IRMemoryMap &map, 104252f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t process_address, 104352f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_top, 104452f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_bottom, 104552f792329be5db8e38961350589e97e8f2823acdGreg Clayton Error &err) 10463b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 1047973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1048973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 104952f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 105052f792329be5db8e38961350589e97e8f2823acdGreg Clayton 1051973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (log) 1052973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 105352f792329be5db8e38961350589e97e8f2823acdGreg Clayton log->Printf("EntitySymbol::Dematerialize [address = 0x%" PRIx64 ", m_symbol = %s]", 105452f792329be5db8e38961350589e97e8f2823acdGreg Clayton (uint64_t)load_addr, 1055973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan m_symbol.GetName().AsCString()); 1056973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1057973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1058aa5dca00ffd36aead6cc615c5ed2d74edb9fd84eSean Callanan // no work needs to be done 10593b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 106076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 106176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 106276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 106376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan StreamString dump_stream; 106476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 106576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan Error err; 106676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 106752f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 106852f792329be5db8e38961350589e97e8f2823acdGreg Clayton 106952f792329be5db8e38961350589e97e8f2823acdGreg Clayton dump_stream.Printf("0x%" PRIx64 ": EntitySymbol (%s)\n", load_addr, m_symbol.GetName().AsCString()); 107076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 107176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 107276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf("Pointer:\n"); 107376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 107476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataBufferHeap data (m_size, 0); 107576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 107652f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.ReadMemory(data.GetBytes(), load_addr, m_size, err); 107776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 107876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan if (!err.Success()) 107976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 108076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf(" <could not be read>\n"); 108176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 108276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan else 108376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 108476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 108576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 108652f792329be5db8e38961350589e97e8f2823acdGreg Clayton extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); 1087a6686e36cd56843e594139324884585fb47b918bSean Callanan 1088a6686e36cd56843e594139324884585fb47b918bSean Callanan dump_stream.PutChar('\n'); 108976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 109076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 109176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 109276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan log->PutCString(dump_stream.GetData()); 109376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 1094a6686e36cd56843e594139324884585fb47b918bSean Callanan 1095a6686e36cd56843e594139324884585fb47b918bSean Callanan void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 1096a6686e36cd56843e594139324884585fb47b918bSean Callanan { 1097a6686e36cd56843e594139324884585fb47b918bSean Callanan } 10983b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananprivate: 10993b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan Symbol m_symbol; 11003b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan}; 11013b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 11023b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananuint32_t 11033b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean CallananMaterializer::AddSymbol (const Symbol &symbol_sp, Error &err) 11043b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 11053b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 11063b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan iter->reset (new EntitySymbol (symbol_sp)); 11073b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan uint32_t ret = AddStructMember(**iter); 11083b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan (*iter)->SetOffset(ret); 11093b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan return ret; 11103b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 11113b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 11123b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananclass EntityRegister : public Materializer::Entity 11133b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 11143b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananpublic: 11153b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan EntityRegister (const RegisterInfo ®ister_info) : 11163b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan Entity(), 11173b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_register_info(register_info) 11183b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 11193b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan // Hard-coding alignment conservatively 11203b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_size = m_register_info.byte_size; 11213b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_alignment = m_register_info.byte_size; 11223b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 11233b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 1124a6686e36cd56843e594139324884585fb47b918bSean Callanan void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) 11253b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 1126973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1127973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 112852f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 112952f792329be5db8e38961350589e97e8f2823acdGreg Clayton 1130973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (log) 1131973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 113252f792329be5db8e38961350589e97e8f2823acdGreg Clayton log->Printf("EntityRegister::Materialize [address = 0x%" PRIx64 ", m_register_info = %s]", 113352f792329be5db8e38961350589e97e8f2823acdGreg Clayton (uint64_t)load_addr, 1134973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan m_register_info.name); 1135973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1136973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1137973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan RegisterValue reg_value; 1138973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1139973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (!frame_sp.get()) 1140973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 1141668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't materialize register %s without a stack frame", m_register_info.name); 1142973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan return; 1143973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1144973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1145973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext(); 1146973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1147973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (!reg_context_sp->ReadRegister(&m_register_info, reg_value)) 1148973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 1149668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't read the value of register %s", m_register_info.name); 1150973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan return; 1151973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1152973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1153973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan DataExtractor register_data; 1154973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1155973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (!reg_value.GetData(register_data)) 1156973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 1157668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't get the data for register %s", m_register_info.name); 1158973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan return; 1159973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1160973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1161973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (register_data.GetByteSize() != m_register_info.byte_size) 1162973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 1163668010966e95642360fd12094b28755e5dda5343Greg Clayton 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); 1164973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan return; 1165973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1166973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 11674a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan m_register_contents.reset(new DataBufferHeap(register_data.GetDataStart(), register_data.GetByteSize())); 11684a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan 1169973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan Error write_error; 1170973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 117152f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.WriteMemory(load_addr, register_data.GetDataStart(), register_data.GetByteSize(), write_error); 1172973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1173973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (!write_error.Success()) 1174973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 1175668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write the contents of register %s: %s", m_register_info.name, write_error.AsCString()); 1176973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan return; 1177973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 11783b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 11793b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 118052f792329be5db8e38961350589e97e8f2823acdGreg Clayton void Dematerialize (lldb::StackFrameSP &frame_sp, 118152f792329be5db8e38961350589e97e8f2823acdGreg Clayton IRMemoryMap &map, 118252f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t process_address, 118352f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_top, 118452f792329be5db8e38961350589e97e8f2823acdGreg Clayton lldb::addr_t frame_bottom, 118552f792329be5db8e38961350589e97e8f2823acdGreg Clayton Error &err) 11863b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 1187973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); 1188973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 118952f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 119052f792329be5db8e38961350589e97e8f2823acdGreg Clayton 1191973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (log) 1192973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 119352f792329be5db8e38961350589e97e8f2823acdGreg Clayton log->Printf("EntityRegister::Dematerialize [address = 0x%" PRIx64 ", m_register_info = %s]", 119452f792329be5db8e38961350589e97e8f2823acdGreg Clayton (uint64_t)load_addr, 1195973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan m_register_info.name); 1196973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1197973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1198973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan Error extract_error; 1199973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1200973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan DataExtractor register_data; 1201973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1202973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (!frame_sp.get()) 1203973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 1204668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't dematerialize register %s without a stack frame", m_register_info.name); 1205973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan return; 1206973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1207973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1208973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan lldb::RegisterContextSP reg_context_sp = frame_sp->GetRegisterContext(); 1209973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 121052f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.GetMemoryData(register_data, load_addr, m_register_info.byte_size, extract_error); 1211973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1212973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (!extract_error.Success()) 1213973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 1214668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't get the data for register %s: %s", m_register_info.name, extract_error.AsCString()); 1215973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan return; 1216973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 1217973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 12184a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan if (!memcmp(register_data.GetDataStart(), m_register_contents->GetBytes(), register_data.GetByteSize())) 12194a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan { 12204a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan // No write required, and in particular we avoid errors if the register wasn't writable 12214a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan 12224a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan m_register_contents.reset(); 12234a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan return; 12244a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan } 12254a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan 12264a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan m_register_contents.reset(); 12274a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan 1228973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan RegisterValue register_value (const_cast<uint8_t*>(register_data.GetDataStart()), register_data.GetByteSize(), register_data.GetByteOrder()); 1229973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan 1230973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan if (!reg_context_sp->WriteRegister(&m_register_info, register_value)) 1231973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan { 1232668010966e95642360fd12094b28755e5dda5343Greg Clayton err.SetErrorStringWithFormat("couldn't write the value of register %s", m_register_info.name); 1233973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan return; 1234973172e84ad0ecb1e5209f6e3c3c824da19b7f21Sean Callanan } 12353b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 123676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 123776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) 123876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 123976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan StreamString dump_stream; 124076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 124176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan Error err; 124276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 124352f792329be5db8e38961350589e97e8f2823acdGreg Clayton const lldb::addr_t load_addr = process_address + m_offset; 124452f792329be5db8e38961350589e97e8f2823acdGreg Clayton 124552f792329be5db8e38961350589e97e8f2823acdGreg Clayton 124652f792329be5db8e38961350589e97e8f2823acdGreg Clayton dump_stream.Printf("0x%" PRIx64 ": EntityRegister (%s)\n", load_addr, m_register_info.name); 124776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 124876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 124976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf("Value:\n"); 125076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 125176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataBufferHeap data (m_size, 0); 125276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 125352f792329be5db8e38961350589e97e8f2823acdGreg Clayton map.ReadMemory(data.GetBytes(), load_addr, m_size, err); 125476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 125576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan if (!err.Success()) 125676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 125776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan dump_stream.Printf(" <could not be read>\n"); 125876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 125976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan else 126076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 126176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); 126276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 126352f792329be5db8e38961350589e97e8f2823acdGreg Clayton extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, load_addr); 1264a6686e36cd56843e594139324884585fb47b918bSean Callanan 1265a6686e36cd56843e594139324884585fb47b918bSean Callanan dump_stream.PutChar('\n'); 126676f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 126776f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 126876f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 126976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan log->PutCString(dump_stream.GetData()); 127076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 1271a6686e36cd56843e594139324884585fb47b918bSean Callanan 1272a6686e36cd56843e594139324884585fb47b918bSean Callanan void Wipe (IRMemoryMap &map, lldb::addr_t process_address) 1273a6686e36cd56843e594139324884585fb47b918bSean Callanan { 1274a6686e36cd56843e594139324884585fb47b918bSean Callanan } 12753b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananprivate: 12763b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan RegisterInfo m_register_info; 12774a4448ba891e48882f8a8c0e891d4fb207a74a0aSean Callanan lldb::DataBufferSP m_register_contents; 12783b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan}; 12793b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 12803b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananuint32_t 12813b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean CallananMaterializer::AddRegister (const RegisterInfo ®ister_info, Error &err) 12823b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 12833b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP()); 12843b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan iter->reset (new EntityRegister (register_info)); 12853b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan uint32_t ret = AddStructMember(**iter); 12863b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan (*iter)->SetOffset(ret); 12873b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan return ret; 12883b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 12893b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 12903b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean CallananMaterializer::Materializer () : 1291a6686e36cd56843e594139324884585fb47b918bSean Callanan m_dematerializer_wp(), 12920f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan m_result_entity(NULL), 12933b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_current_offset(0), 12943b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan m_struct_alignment(8) 12953b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 12963b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 12973b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 1298a6686e36cd56843e594139324884585fb47b918bSean CallananMaterializer::~Materializer () 1299a6686e36cd56843e594139324884585fb47b918bSean Callanan{ 1300a6686e36cd56843e594139324884585fb47b918bSean Callanan DematerializerSP dematerializer_sp = m_dematerializer_wp.lock(); 1301a6686e36cd56843e594139324884585fb47b918bSean Callanan 1302a6686e36cd56843e594139324884585fb47b918bSean Callanan if (dematerializer_sp) 1303a6686e36cd56843e594139324884585fb47b918bSean Callanan dematerializer_sp->Wipe(); 1304a6686e36cd56843e594139324884585fb47b918bSean Callanan} 13053b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 1306a6686e36cd56843e594139324884585fb47b918bSean CallananMaterializer::DematerializerSP 13070f0551e67d8ea8d63ace5456f7d42d951827b017Sean CallananMaterializer::Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &error) 13083b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 1309faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan ExecutionContextScope *exe_scope = frame_sp.get(); 1310a6686e36cd56843e594139324884585fb47b918bSean Callanan 1311faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan if (!exe_scope) 1312faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan exe_scope = map.GetBestExecutionContextScope(); 1313faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan 1314a6686e36cd56843e594139324884585fb47b918bSean Callanan DematerializerSP dematerializer_sp = m_dematerializer_wp.lock(); 1315a6686e36cd56843e594139324884585fb47b918bSean Callanan 1316a6686e36cd56843e594139324884585fb47b918bSean Callanan if (dematerializer_sp) 1317a6686e36cd56843e594139324884585fb47b918bSean Callanan { 1318a6686e36cd56843e594139324884585fb47b918bSean Callanan error.SetErrorToGenericError(); 1319a6686e36cd56843e594139324884585fb47b918bSean Callanan error.SetErrorString("Couldn't materialize: already materialized"); 1320a6686e36cd56843e594139324884585fb47b918bSean Callanan } 1321a6686e36cd56843e594139324884585fb47b918bSean Callanan 1322a6686e36cd56843e594139324884585fb47b918bSean Callanan DematerializerSP ret(new Dematerializer(*this, frame_sp, map, process_address)); 1323a6686e36cd56843e594139324884585fb47b918bSean Callanan 1324faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan if (!exe_scope) 1325faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan { 1326faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan error.SetErrorToGenericError(); 1327a6686e36cd56843e594139324884585fb47b918bSean Callanan error.SetErrorString("Couldn't materialize: target doesn't exist"); 1328faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan } 1329faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan 13303b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan for (EntityUP &entity_up : m_entities) 13313b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 13323b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan entity_up->Materialize(frame_sp, map, process_address, error); 13333b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 13343b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan if (!error.Success()) 1335a6686e36cd56843e594139324884585fb47b918bSean Callanan return DematerializerSP(); 13363b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 13373b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 1338a6686e36cd56843e594139324884585fb47b918bSean Callanan if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 133976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 1340884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec log->Printf("Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64 ") materialized:", frame_sp.get(), process_address); 134176f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan for (EntityUP &entity_up : m_entities) 134276f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan entity_up->DumpToLog(map, process_address, log); 134376f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 13443b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 1345a6686e36cd56843e594139324884585fb47b918bSean Callanan m_dematerializer_wp = ret; 1346a6686e36cd56843e594139324884585fb47b918bSean Callanan 1347a6686e36cd56843e594139324884585fb47b918bSean Callanan return ret; 13483b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 13493b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 13503b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callananvoid 1351cdc3ea5398f251d3eca482595f103b1874e51538Sean CallananMaterializer::Dematerializer::Dematerialize (Error &error, lldb::ClangExpressionVariableSP &result_sp, lldb::addr_t frame_bottom, lldb::addr_t frame_top) 13523b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan{ 1353d0f064d4e5ccef341ecbd6a462bbff5f085a3f77Sean Callanan lldb::StackFrameSP frame_sp; 1354d0f064d4e5ccef341ecbd6a462bbff5f085a3f77Sean Callanan 1355d0f064d4e5ccef341ecbd6a462bbff5f085a3f77Sean Callanan lldb::ThreadSP thread_sp = m_thread_wp.lock(); 1356d0f064d4e5ccef341ecbd6a462bbff5f085a3f77Sean Callanan if (thread_sp) 1357d0f064d4e5ccef341ecbd6a462bbff5f085a3f77Sean Callanan frame_sp = thread_sp->GetFrameWithStackID(m_stack_id); 13583b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 1359a6686e36cd56843e594139324884585fb47b918bSean Callanan ExecutionContextScope *exe_scope = m_map->GetBestExecutionContextScope(); 1360a6686e36cd56843e594139324884585fb47b918bSean Callanan 1361a6686e36cd56843e594139324884585fb47b918bSean Callanan if (!IsValid()) 1362a6686e36cd56843e594139324884585fb47b918bSean Callanan { 1363a6686e36cd56843e594139324884585fb47b918bSean Callanan error.SetErrorToGenericError(); 1364a6686e36cd56843e594139324884585fb47b918bSean Callanan error.SetErrorString("Couldn't dematerialize: invalid dematerializer"); 1365a6686e36cd56843e594139324884585fb47b918bSean Callanan } 1366faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan 1367faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan if (!exe_scope) 13683b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 13693b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan error.SetErrorToGenericError(); 1370faafd193bf7dc065e5f6fb99e4c538cc452af7e4Sean Callanan error.SetErrorString("Couldn't dematerialize: target is gone"); 13713b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 13723b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan else 13733b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 137476f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan if (Log *log =lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 137576f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan { 1376884288bcb6824452a3c64eb772c0976501acc47aMatt Kopec log->Printf("Materializer::Dematerialize (frame_sp = %p, process_address = 0x%" PRIx64 ") about to dematerialize:", frame_sp.get(), m_process_address); 1377a6686e36cd56843e594139324884585fb47b918bSean Callanan for (EntityUP &entity_up : m_materializer->m_entities) 1378a6686e36cd56843e594139324884585fb47b918bSean Callanan entity_up->DumpToLog(*m_map, m_process_address, log); 137976f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan } 138076f9879afa1508febd5538a63a3fad7f01c6c64fSean Callanan 1381a6686e36cd56843e594139324884585fb47b918bSean Callanan for (EntityUP &entity_up : m_materializer->m_entities) 13823b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan { 13830f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan if (entity_up.get() == m_materializer->m_result_entity) 13840f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 13850f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan static_cast<EntityResultVariable*>(m_materializer->m_result_entity)->Dematerialize (result_sp, frame_sp, *m_map, m_process_address, frame_top, frame_bottom, error); 13860f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 13870f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan else 13880f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan { 13890f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan entity_up->Dematerialize (frame_sp, *m_map, m_process_address, frame_top, frame_bottom, error); 13900f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan } 13910f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 13923b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan if (!error.Success()) 13933b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan break; 13943b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 13953b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan } 13963b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan 1397a6686e36cd56843e594139324884585fb47b918bSean Callanan Wipe(); 1398a6686e36cd56843e594139324884585fb47b918bSean Callanan} 1399a6686e36cd56843e594139324884585fb47b918bSean Callanan 1400a6686e36cd56843e594139324884585fb47b918bSean Callananvoid 1401a6686e36cd56843e594139324884585fb47b918bSean CallananMaterializer::Dematerializer::Wipe () 1402a6686e36cd56843e594139324884585fb47b918bSean Callanan{ 1403a6686e36cd56843e594139324884585fb47b918bSean Callanan if (!IsValid()) 1404a6686e36cd56843e594139324884585fb47b918bSean Callanan return; 1405a6686e36cd56843e594139324884585fb47b918bSean Callanan 1406a6686e36cd56843e594139324884585fb47b918bSean Callanan for (EntityUP &entity_up : m_materializer->m_entities) 1407a6686e36cd56843e594139324884585fb47b918bSean Callanan { 1408a6686e36cd56843e594139324884585fb47b918bSean Callanan entity_up->Wipe (*m_map, m_process_address); 1409a6686e36cd56843e594139324884585fb47b918bSean Callanan } 1410a6686e36cd56843e594139324884585fb47b918bSean Callanan 1411a6686e36cd56843e594139324884585fb47b918bSean Callanan m_materializer = NULL; 1412a6686e36cd56843e594139324884585fb47b918bSean Callanan m_map = NULL; 1413a6686e36cd56843e594139324884585fb47b918bSean Callanan m_process_address = LLDB_INVALID_ADDRESS; 14143b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan} 1415