Replicated the materialization logic for persistent
variables in the Materializer. We don't use this code yet, but will soon once the other materializers are online. llvm-svn: 179390
This commit is contained in:
parent
e14b765a89
commit
35005f768e
|
@ -38,6 +38,7 @@ class IRMemoryMap
|
|||
{
|
||||
public:
|
||||
IRMemoryMap (lldb::ProcessSP process_sp);
|
||||
IRMemoryMap (lldb::TargetSP target_sp);
|
||||
~IRMemoryMap ();
|
||||
|
||||
enum AllocationPolicy {
|
||||
|
@ -53,7 +54,14 @@ public:
|
|||
void Free (lldb::addr_t process_address, Error &error);
|
||||
|
||||
void WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error);
|
||||
void WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error);
|
||||
void ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error);
|
||||
void ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error);
|
||||
|
||||
lldb::ByteOrder GetByteOrder();
|
||||
uint32_t GetAddressByteSize();
|
||||
|
||||
ExecutionContextScope *GetBestExecutionContextScope();
|
||||
|
||||
protected:
|
||||
lldb::ProcessWP GetProcessWP ()
|
||||
|
@ -76,6 +84,7 @@ private:
|
|||
};
|
||||
|
||||
lldb::ProcessWP m_process_wp;
|
||||
lldb::TargetWP m_target_wp;
|
||||
typedef std::map<lldb::addr_t, Allocation> AllocationMap;
|
||||
AllocationMap m_allocations;
|
||||
|
||||
|
|
|
@ -29,7 +29,9 @@ public:
|
|||
class Dematerializer
|
||||
{
|
||||
public:
|
||||
void Dematerialize(Error &err);
|
||||
void Dematerialize(Error &err,
|
||||
lldb::addr_t frame_top,
|
||||
lldb::addr_t frame_bottom);
|
||||
private:
|
||||
friend class Materializer;
|
||||
|
||||
|
@ -54,7 +56,7 @@ public:
|
|||
|
||||
uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
|
||||
uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
|
||||
uint32_t AddResultVariable (const ClangASTType &type, Error &err);
|
||||
uint32_t AddResultVariable (const ClangASTType &type, bool keep_in_memory, Error &err);
|
||||
uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
|
||||
uint32_t AddRegister (const RegisterInfo ®ister_info, Error &err);
|
||||
|
||||
|
@ -83,7 +85,8 @@ public:
|
|||
}
|
||||
|
||||
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
|
||||
lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err) = 0;
|
||||
|
||||
uint32_t GetAlignment ()
|
||||
{
|
||||
|
@ -250,138 +253,3 @@ private:
|
|||
}
|
||||
|
||||
#endif
|
||||
//===-- Materializer.h ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef lldb_Materializer_h
|
||||
#define lldb_Materializer_h
|
||||
|
||||
#include "lldb/lldb-private-types.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Expression/IRMemoryMap.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
#include "lldb/Symbol/SymbolContext.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace lldb_private
|
||||
{
|
||||
|
||||
class Materializer
|
||||
{
|
||||
public:
|
||||
Materializer ();
|
||||
|
||||
class Dematerializer
|
||||
{
|
||||
public:
|
||||
void Dematerialize(Error &err);
|
||||
private:
|
||||
friend class Materializer;
|
||||
|
||||
Dematerializer (Materializer &materializer,
|
||||
lldb::StackFrameSP &frame_sp,
|
||||
IRMemoryMap &map,
|
||||
lldb::addr_t process_address) :
|
||||
m_materializer(materializer),
|
||||
m_frame_wp(frame_sp),
|
||||
m_map(map),
|
||||
m_process_address(process_address)
|
||||
{
|
||||
}
|
||||
|
||||
Materializer &m_materializer;
|
||||
lldb::StackFrameWP m_frame_wp;
|
||||
IRMemoryMap &m_map;
|
||||
lldb::addr_t m_process_address;
|
||||
};
|
||||
|
||||
Dematerializer Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err);
|
||||
|
||||
uint32_t AddPersistentVariable (lldb::ClangExpressionVariableSP &persistent_variable_sp, Error &err);
|
||||
uint32_t AddVariable (lldb::VariableSP &variable_sp, Error &err);
|
||||
uint32_t AddResultVariable (const ClangASTType &type, Error &err);
|
||||
uint32_t AddSymbol (const Symbol &symbol_sp, Error &err);
|
||||
uint32_t AddRegister (const RegisterInfo ®ister_info, Error &err);
|
||||
|
||||
uint32_t GetStructAlignment ()
|
||||
{
|
||||
return m_struct_alignment;
|
||||
}
|
||||
|
||||
uint32_t GetStructSize ()
|
||||
{
|
||||
return m_current_offset;
|
||||
}
|
||||
|
||||
uint32_t GetNumEntities ()
|
||||
{
|
||||
return m_entities.size();
|
||||
}
|
||||
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
Entity () :
|
||||
m_alignment(1),
|
||||
m_size(0),
|
||||
m_offset(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~Entity ()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) = 0;
|
||||
|
||||
uint32_t GetAlignment ()
|
||||
{
|
||||
return m_alignment;
|
||||
}
|
||||
|
||||
uint32_t GetSize ()
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
uint32_t GetOffset ()
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
void SetOffset (uint32_t offset)
|
||||
{
|
||||
m_offset = offset;
|
||||
}
|
||||
protected:
|
||||
void SetSizeAndAlignmentFromType (ClangASTType &type);
|
||||
|
||||
uint32_t m_alignment;
|
||||
uint32_t m_size;
|
||||
uint32_t m_offset;
|
||||
};
|
||||
|
||||
private:
|
||||
uint32_t AddStructMember (Entity &entity);
|
||||
|
||||
typedef std::unique_ptr<Entity> EntityUP;
|
||||
typedef std::vector<EntityUP> EntityVector;
|
||||
|
||||
unsigned m_result_index;
|
||||
Mutex m_needs_dematerialize;
|
||||
EntityVector m_entities;
|
||||
uint32_t m_current_offset;
|
||||
uint32_t m_struct_alignment;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -510,6 +510,11 @@ ClangExpressionDeclMap::AddPersistentVariable
|
|||
var_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
|
||||
}
|
||||
|
||||
if (m_keep_result_in_memory)
|
||||
{
|
||||
var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget;
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf("Created persistent variable with flags 0x%hx", var_sp->m_flags);
|
||||
|
||||
|
@ -523,7 +528,7 @@ ClangExpressionDeclMap::AddPersistentVariable
|
|||
if (m_parser_vars->m_materializer)
|
||||
{
|
||||
Error err;
|
||||
m_parser_vars->m_materializer->AddResultVariable(user_type, err);
|
||||
m_parser_vars->m_materializer->AddResultVariable(user_type, m_keep_result_in_memory, err);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -7,15 +7,26 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Core/DataBufferHeap.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/Scalar.h"
|
||||
#include "lldb/Expression/IRMemoryMap.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
|
||||
using namespace lldb_private;
|
||||
|
||||
IRMemoryMap::IRMemoryMap (lldb::ProcessSP process_sp) :
|
||||
m_process_wp(process_sp)
|
||||
m_process_wp(process_sp),
|
||||
m_target_wp(process_sp->GetTarget().shared_from_this())
|
||||
{
|
||||
}
|
||||
|
||||
IRMemoryMap::IRMemoryMap (lldb::TargetSP target_sp) :
|
||||
m_process_wp(),
|
||||
m_target_wp(target_sp)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -97,6 +108,54 @@ IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size)
|
|||
return m_allocations.end();
|
||||
}
|
||||
|
||||
lldb::ByteOrder
|
||||
IRMemoryMap::GetByteOrder()
|
||||
{
|
||||
lldb::ProcessSP process_sp = m_process_wp.lock();
|
||||
|
||||
if (process_sp)
|
||||
return process_sp->GetByteOrder();
|
||||
|
||||
lldb::TargetSP target_sp = m_target_wp.lock();
|
||||
|
||||
if (target_sp)
|
||||
return target_sp->GetDefaultArchitecture().GetByteOrder();
|
||||
|
||||
return lldb::eByteOrderInvalid;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
IRMemoryMap::GetAddressByteSize()
|
||||
{
|
||||
lldb::ProcessSP process_sp = m_process_wp.lock();
|
||||
|
||||
if (process_sp)
|
||||
return process_sp->GetAddressByteSize();
|
||||
|
||||
lldb::TargetSP target_sp = m_target_wp.lock();
|
||||
|
||||
if (target_sp)
|
||||
return target_sp->GetDefaultArchitecture().GetAddressByteSize();
|
||||
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
ExecutionContextScope *
|
||||
IRMemoryMap::GetBestExecutionContextScope()
|
||||
{
|
||||
lldb::ProcessSP process_sp = m_process_wp.lock();
|
||||
|
||||
if (process_sp)
|
||||
return process_sp.get();
|
||||
|
||||
lldb::TargetSP target_sp = m_target_wp.lock();
|
||||
|
||||
if (target_sp)
|
||||
return target_sp.get();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lldb::addr_t
|
||||
IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error)
|
||||
{
|
||||
|
@ -335,6 +394,34 @@ IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, si
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error)
|
||||
{
|
||||
if (size == UINT32_MAX)
|
||||
size = scalar.GetByteSize();
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
uint8_t buf[32];
|
||||
const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error);
|
||||
if (mem_size > 0)
|
||||
{
|
||||
return WriteMemory(process_address, buf, mem_size, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorToGenericError();
|
||||
error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorToGenericError();
|
||||
error.SetErrorString ("Couldn't write scalar: its size was zero");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error)
|
||||
{
|
||||
|
@ -408,3 +495,39 @@ IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t si
|
|||
(uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error)
|
||||
{
|
||||
if (size > 0)
|
||||
{
|
||||
DataBufferHeap buf(size, 0);
|
||||
ReadMemory(buf.GetBytes(), process_address, size, error);
|
||||
|
||||
if (!error.Success())
|
||||
return;
|
||||
|
||||
DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize());
|
||||
|
||||
lldb::offset_t offset = 0;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
default:
|
||||
error.SetErrorToGenericError();
|
||||
error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %lld", (unsigned long long)size);
|
||||
return;
|
||||
case 1: scalar = extractor.GetU8(&offset); break;
|
||||
case 2: scalar = extractor.GetU16(&offset); break;
|
||||
case 4: scalar = extractor.GetU32(&offset); break;
|
||||
case 8: scalar = extractor.GetU64(&offset); break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error.SetErrorToGenericError();
|
||||
error.SetErrorString ("Couldn't write scalar: its size was zero");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/ValueObjectConstResult.h"
|
||||
#include "lldb/Expression/ClangExpressionVariable.h"
|
||||
#include "lldb/Expression/Materializer.h"
|
||||
#include "lldb/Symbol/ClangASTContext.h"
|
||||
|
@ -67,12 +69,234 @@ public:
|
|||
SetSizeAndAlignmentFromType(type);
|
||||
}
|
||||
|
||||
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
|
||||
void MakeAllocation (IRMemoryMap &map, Error &err)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
||||
|
||||
// Allocate a spare memory area to store the persistent variable's contents.
|
||||
|
||||
Error allocate_error;
|
||||
|
||||
lldb::addr_t mem = map.Malloc(m_persistent_variable_sp->GetByteSize(),
|
||||
8,
|
||||
lldb::ePermissionsReadable | lldb::ePermissionsWritable,
|
||||
IRMemoryMap::eAllocationPolicyMirror,
|
||||
allocate_error);
|
||||
|
||||
if (!allocate_error.Success())
|
||||
{
|
||||
err.SetErrorToGenericError();
|
||||
err.SetErrorStringWithFormat("Couldn't allocate a memory area to store %s: %s", m_persistent_variable_sp->GetName().GetCString(), allocate_error.AsCString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (log)
|
||||
log->Printf("Allocated %s (0x%" PRIx64 ") sucessfully", m_persistent_variable_sp->GetName().GetCString(), mem);
|
||||
|
||||
// Put the location of the spare memory into the live data of the ValueObject.
|
||||
|
||||
m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope(),
|
||||
m_persistent_variable_sp->GetTypeFromUser().GetASTContext(),
|
||||
m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(),
|
||||
m_persistent_variable_sp->GetName(),
|
||||
mem,
|
||||
eAddressTypeLoad,
|
||||
m_persistent_variable_sp->GetByteSize());
|
||||
|
||||
// Clear the flag if the variable will never be deallocated.
|
||||
|
||||
if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)
|
||||
m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVNeedsAllocation;
|
||||
|
||||
// Write the contents of the variable to the area.
|
||||
|
||||
Error write_error;
|
||||
|
||||
map.WriteMemory (mem,
|
||||
m_persistent_variable_sp->GetValueBytes(),
|
||||
m_persistent_variable_sp->GetByteSize(),
|
||||
write_error);
|
||||
|
||||
if (!write_error.Success())
|
||||
{
|
||||
err.SetErrorToGenericError();
|
||||
err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", m_persistent_variable_sp->GetName().AsCString(),
|
||||
write_error.AsCString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
|
||||
void DestroyAllocation (IRMemoryMap &map, Error &err)
|
||||
{
|
||||
Error deallocate_error;
|
||||
|
||||
map.Free((lldb::addr_t)m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong(), deallocate_error);
|
||||
|
||||
if (!deallocate_error.Success())
|
||||
{
|
||||
err.SetErrorToGenericError();
|
||||
err.SetErrorStringWithFormat ("Couldn't deallocate memory for %s: %s", m_persistent_variable_sp->GetName().GetCString(), deallocate_error.AsCString());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
||||
|
||||
if (log)
|
||||
{
|
||||
log->Printf("EntityPersistentVariable::Materialize [process_address = 0x%llx, m_name = %s, m_flags = 0x%hx]",
|
||||
(uint64_t)process_address,
|
||||
m_persistent_variable_sp->GetName().AsCString(),
|
||||
m_persistent_variable_sp->m_flags);
|
||||
}
|
||||
|
||||
if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation)
|
||||
{
|
||||
MakeAllocation(map, err);
|
||||
if (!err.Success())
|
||||
return;
|
||||
}
|
||||
|
||||
if ((m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && m_persistent_variable_sp->m_live_sp) ||
|
||||
m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated)
|
||||
{
|
||||
Error write_error;
|
||||
|
||||
map.WriteScalarToMemory(process_address + m_offset,
|
||||
m_persistent_variable_sp->m_live_sp->GetValue().GetScalar(),
|
||||
m_persistent_variable_sp->m_live_sp->GetProcessSP()->GetAddressByteSize(),
|
||||
write_error);
|
||||
|
||||
if (!write_error.Success())
|
||||
{
|
||||
err.SetErrorToGenericError();
|
||||
err.SetErrorStringWithFormat("Couldn't write the location of %s to memory: %s", m_persistent_variable_sp->GetName().AsCString(), write_error.AsCString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err.SetErrorToGenericError();
|
||||
err.SetErrorStringWithFormat("No materialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map,
|
||||
lldb::addr_t frame_top, lldb::addr_t frame_bottom, lldb::addr_t process_address, Error &err)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
|
||||
|
||||
if (log)
|
||||
{
|
||||
log->Printf("EntityPersistentVariable::Dematerialize [process_address = 0x%llx, m_name = %s, m_flags = 0x%hx]",
|
||||
(uint64_t)process_address,
|
||||
m_persistent_variable_sp->GetName().AsCString(),
|
||||
m_persistent_variable_sp->m_flags);
|
||||
}
|
||||
|
||||
if ((m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) ||
|
||||
(m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference))
|
||||
{
|
||||
if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVIsProgramReference &&
|
||||
!m_persistent_variable_sp->m_live_sp)
|
||||
{
|
||||
// If the reference comes from the program, then the ClangExpressionVariable's
|
||||
// live variable data hasn't been set up yet. Do this now.
|
||||
|
||||
Scalar location_scalar;
|
||||
Error read_error;
|
||||
|
||||
map.ReadScalarFromMemory(location_scalar, process_address + m_offset, map.GetAddressByteSize(), read_error);
|
||||
|
||||
if (!read_error.Success())
|
||||
{
|
||||
err.SetErrorToGenericError();
|
||||
err.SetErrorStringWithFormat("Couldn't read the address of program-allocated variable %s: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString());
|
||||
return;
|
||||
}
|
||||
|
||||
lldb::addr_t location = location_scalar.ULongLong();
|
||||
|
||||
m_persistent_variable_sp->m_live_sp = ValueObjectConstResult::Create (map.GetBestExecutionContextScope (),
|
||||
m_persistent_variable_sp->GetTypeFromUser().GetASTContext(),
|
||||
m_persistent_variable_sp->GetTypeFromUser().GetOpaqueQualType(),
|
||||
m_persistent_variable_sp->GetName(),
|
||||
location,
|
||||
eAddressTypeLoad,
|
||||
m_persistent_variable_sp->GetByteSize());
|
||||
|
||||
if (frame_top != LLDB_INVALID_ADDRESS &&
|
||||
frame_bottom != LLDB_INVALID_ADDRESS &&
|
||||
location >= frame_bottom &&
|
||||
location <= frame_top)
|
||||
{
|
||||
// If the variable is resident in the stack frame created by the expression,
|
||||
// then it cannot be relied upon to stay around. We treat it as needing
|
||||
// reallocation.
|
||||
m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
|
||||
m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
|
||||
m_persistent_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
|
||||
m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVIsProgramReference;
|
||||
}
|
||||
}
|
||||
|
||||
lldb::addr_t mem = m_persistent_variable_sp->m_live_sp->GetValue().GetScalar().ULongLong();
|
||||
|
||||
if (!m_persistent_variable_sp->m_live_sp)
|
||||
{
|
||||
err.SetErrorToGenericError();
|
||||
err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", m_persistent_variable_sp->GetName().GetCString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_persistent_variable_sp->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad)
|
||||
{
|
||||
err.SetErrorToGenericError();
|
||||
err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", m_persistent_variable_sp->GetName().GetCString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry ||
|
||||
m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)
|
||||
{
|
||||
if (log)
|
||||
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());
|
||||
|
||||
// Read the contents of the spare memory area
|
||||
|
||||
m_persistent_variable_sp->ValueUpdated ();
|
||||
|
||||
Error read_error;
|
||||
|
||||
map.ReadMemory(m_persistent_variable_sp->GetValueBytes(),
|
||||
mem,
|
||||
m_persistent_variable_sp->GetByteSize(),
|
||||
read_error);
|
||||
|
||||
if (!read_error.Success())
|
||||
{
|
||||
err.SetErrorStringWithFormat ("Couldn't read the contents of %s from memory: %s", m_persistent_variable_sp->GetName().GetCString(), read_error.AsCString());
|
||||
return;
|
||||
}
|
||||
|
||||
m_persistent_variable_sp->m_flags &= ~ClangExpressionVariable::EVNeedsFreezeDry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err.SetErrorToGenericError();
|
||||
err.SetErrorStringWithFormat("No dematerialization happened for persistent variable %s", m_persistent_variable_sp->GetName().AsCString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation &&
|
||||
!(m_persistent_variable_sp->m_flags & ClangExpressionVariable::EVKeepInTarget))
|
||||
{
|
||||
DestroyAllocation(map, err);
|
||||
if (!err.Success())
|
||||
return;
|
||||
}
|
||||
}
|
||||
private:
|
||||
lldb::ClangExpressionVariableSP m_persistent_variable_sp;
|
||||
|
@ -104,7 +328,8 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
|
||||
lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
|
||||
{
|
||||
}
|
||||
private:
|
||||
|
@ -124,9 +349,10 @@ Materializer::AddVariable (lldb::VariableSP &variable_sp, Error &err)
|
|||
class EntityResultVariable : public Materializer::Entity
|
||||
{
|
||||
public:
|
||||
EntityResultVariable (const ClangASTType &type) :
|
||||
EntityResultVariable (const ClangASTType &type, bool keep_in_memory) :
|
||||
Entity(),
|
||||
m_type(type)
|
||||
m_type(type),
|
||||
m_keep_in_memory(keep_in_memory)
|
||||
{
|
||||
SetSizeAndAlignmentFromType(m_type);
|
||||
}
|
||||
|
@ -135,18 +361,20 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
|
||||
lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
|
||||
{
|
||||
}
|
||||
private:
|
||||
ClangASTType m_type;
|
||||
ClangASTType m_type;
|
||||
bool m_keep_in_memory;
|
||||
};
|
||||
|
||||
uint32_t
|
||||
Materializer::AddResultVariable (const ClangASTType &type, Error &err)
|
||||
Materializer::AddResultVariable (const ClangASTType &type, bool keep_in_memory, Error &err)
|
||||
{
|
||||
EntityVector::iterator iter = m_entities.insert(m_entities.end(), EntityUP());
|
||||
iter->reset (new EntityResultVariable (type));
|
||||
iter->reset (new EntityResultVariable (type, keep_in_memory));
|
||||
uint32_t ret = AddStructMember(**iter);
|
||||
(*iter)->SetOffset(ret);
|
||||
return ret;
|
||||
|
@ -168,7 +396,8 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
|
||||
lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
|
||||
{
|
||||
}
|
||||
private:
|
||||
|
@ -201,7 +430,8 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err)
|
||||
virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address,
|
||||
lldb::addr_t frame_top, lldb::addr_t frame_bottom, Error &err)
|
||||
{
|
||||
}
|
||||
private:
|
||||
|
@ -243,7 +473,7 @@ Materializer::Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVa
|
|||
}
|
||||
|
||||
void
|
||||
Materializer::Dematerializer::Dematerialize (Error &error)
|
||||
Materializer::Dematerializer::Dematerialize (Error &error, lldb::addr_t frame_top, lldb::addr_t frame_bottom)
|
||||
{
|
||||
lldb::StackFrameSP frame_sp = m_frame_wp.lock();
|
||||
|
||||
|
@ -256,7 +486,7 @@ Materializer::Dematerializer::Dematerialize (Error &error)
|
|||
{
|
||||
for (EntityUP &entity_up : m_materializer.m_entities)
|
||||
{
|
||||
entity_up->Dematerialize (frame_sp, m_map, m_process_address, error);
|
||||
entity_up->Dematerialize (frame_sp, m_map, m_process_address, frame_top, frame_bottom, error);
|
||||
|
||||
if (!error.Success())
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue