41 uint32_t size = entity.
GetSize();
77 const bool zero_memory =
false;
79 const uint64_t malloc_size =
82 auto address_or_error = map.
Malloc(
83 malloc_size, 8, lldb::ePermissionsReadable | lldb::ePermissionsWritable,
85 if (!address_or_error) {
87 "couldn't allocate a memory area to store %s: %s",
89 toString(address_or_error.takeError()).c_str());
95 log,
"Allocated 0x%" PRIx64
"bytes for %s (0x%" PRIx64
") successfully",
112 map.
Leak(mem, leak_error);
138 "couldn't write {0} to the target: {1}",
152 live_valobj_sp.reset();
154 if (!deallocate_error.
Success()) {
156 "couldn't deallocate memory for %s: %s",
169 "EntityPersistentVariable::Materialize [address = {0:x}, m_name = "
170 "{1}, m_flags = {2:x}]",
198 "couldn't write the location of {0} to memory: {1}",
203 "no materialization happened for persistent variable {0}",
217 "EntityPersistentVariable::Dematerialize [address = {0:x}, m_name "
218 "= {1}, m_flags = {2}]",
219 (uint64_t)process_address +
m_offset,
247 "couldn't read the address of program-allocated variable %s: %s",
262 location <= frame_top) {
277 if (!live_valobj_sp) {
279 "couldn't find the memory area used to store %s",
284 lldb::addr_t mem = live_valobj_sp->GetValue().GetScalar().ULongLong();
286 if (live_valobj_sp->GetValue().GetValueAddressType() !=
289 "the address of the memory area for %s is in an incorrect format",
298 LLDB_LOGF(log,
"Dematerializing %s from 0x%" PRIx64
" (size = %llu)",
301 (
unsigned long long)llvm::expectedToOptional(
319 "couldn't read the contents of %s from memory: %s",
329 "no dematerialization happened for persistent variable {0}",
352 dump_stream.
Format(
"{0:x}: EntityPersistentVariable ({1})\n", load_addr,
363 dump_stream.
PutCString(
" <could not be read>\n");
380 dump_stream.
PutCString(
" <could not be read>\n");
394 dump_stream.
PutCString(
" <could not be read>\n");
418 *iter = std::make_unique<EntityPersistentVariable>(persistent_variable_sp,
421 (*iter)->SetOffset(ret);
446 "EntityVariable::Materialize [address = 0x%" PRIx64
447 ", m_variable_sp = %s]",
448 (uint64_t)load_addr,
GetName().GetCString());
459 "couldn't get a value object for variable {0}",
GetName());
463 Status valobj_error = valobj_sp->GetError().Clone();
465 if (valobj_error.
Fail()) {
467 "couldn't get the value of variable {0}: {1}",
GetName(),
475 valobj_sp->GetData(valobj_extractor, extract_error);
477 if (!extract_error.
Success()) {
479 "couldn't read contents of reference variable {0}: {1}",
GetName(),
492 "couldn't write the contents of reference variable {} to memory: "
499 valobj_sp->GetAddressOf(
false).address;
506 "couldn't write the address of variable {0} to memory: {1}",
513 valobj_sp->GetData(data, extract_error);
514 if (!extract_error.
Success()) {
516 "couldn't get the value of {0}: {1}",
GetName(),
523 "trying to create a temporary region for {0} but one exists",
529 llvm::expectedToOptional(
GetByteSize(scope)).value_or(0)) {
532 "the variable '{0}' has no location, "
533 "it may have been optimized out",
537 "size of variable {0} ({1}) is larger than the ValueObject's "
540 llvm::expectedToOptional(
GetByteSize(scope)).value_or(0),
547 if (!opt_bit_align) {
549 "can't get the type alignment for {0}",
GetName());
553 size_t byte_align = (*opt_bit_align + 7) / 8;
555 const bool zero_memory =
false;
556 if (
auto address_or_error = map.
Malloc(
558 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
563 "couldn't allocate a temporary region for {0}: {1}",
GetName(),
564 toString(address_or_error.takeError()));
580 "couldn't write to the temporary region for {0}: {1}",
GetName(),
585 Status pointer_write_error;
588 pointer_write_error);
590 if (!pointer_write_error.
Success()) {
592 "couldn't write the address of the temporary region for {0}: {1}",
607 "EntityVariable::Dematerialize [address = {0:x}, m_variable_sp = {1}]",
608 (uint64_t)load_addr,
GetName());
620 "couldn't get a value object for variable {0}",
GetName());
630 llvm::expectedToOptional(valobj_sp->GetByteSize()).value_or(0),
633 if (!extract_error.
Success()) {
635 "couldn't get the data for variable {0}",
GetName());
639 bool actually_write =
true;
645 actually_write =
false;
651 if (actually_write) {
652 valobj_sp->SetData(data, set_error);
656 "couldn't write the new contents of {0} back into the variable",
668 "couldn't free the temporary region for {0}: {1}",
GetName(),
684 dump_stream.
Printf(
"0x%" PRIx64
": EntityVariable\n", load_addr);
698 dump_stream.
PutCString(
" <could not be read>\n");
715 dump_stream.
PutCString(
"Points to process memory:\n");
717 dump_stream.
PutCString(
"Temporary allocation:\n");
721 dump_stream.
PutCString(
" <could not be be found>\n");
729 dump_stream.
PutCString(
" <could not be read>\n");
774 virtual llvm::Expected<uint64_t>
785 virtual std::optional<size_t>
805 m_variable_sp->GetType()->GetForwardCompilerType().IsReferenceType();
815 llvm::Expected<uint64_t>
824 std::optional<size_t>
826 return m_variable_sp->GetType()->GetLayoutCompilerType().GetTypeBitAlign(
858 llvm::Expected<uint64_t>
861 return m_valobj_sp->GetCompilerType().GetByteSize(scope);
863 return llvm::createStringError(
"no value object");
873 std::optional<size_t>
876 return m_valobj_sp->GetCompilerType().GetTypeBitAlign(scope);
889 *iter = std::make_unique<EntityVariable>(variable_sp);
891 (*iter)->SetOffset(ret);
898 assert(valobj_provider);
900 *iter = std::make_unique<EntityValueObject>(name, std::move(valobj_provider));
902 (*iter)->SetOffset(ret);
924 "Trying to create a temporary region for the result "
935 auto byte_size_or_err =
m_type.GetByteSize(exe_scope);
936 if (!byte_size_or_err) {
940 auto byte_size = *byte_size_or_err;
942 std::optional<size_t> opt_bit_align =
m_type.GetTypeBitAlign(exe_scope);
943 if (!opt_bit_align) {
945 "can't get the alignment of type \"{0}\"",
m_type.GetTypeName());
949 size_t byte_align = (*opt_bit_align + 7) / 8;
951 const bool zero_memory =
true;
952 if (
auto address_or_error = map.
Malloc(
953 byte_size, byte_align,
954 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
959 "couldn't allocate a temporary region for the result: %s",
960 toString(address_or_error.takeError()).c_str());
966 Status pointer_write_error;
969 pointer_write_error);
971 if (!pointer_write_error.
Success()) {
973 "couldn't write the address of the "
974 "temporary region for the result: %s",
991 "Couldn't dematerialize a result variable: invalid "
992 "execution context scope");
1004 "Couldn't dematerialize a result variable: couldn't "
1005 "read its address");
1013 "Couldn't dematerialize a result variable: no target");
1017 auto type_system_or_err =
1018 target_sp->GetScratchTypeSystemForLanguage(
m_type.GetMinimumLanguage());
1020 if (
auto error = type_system_or_err.takeError()) {
1022 "Couldn't dematerialize a result variable: "
1023 "couldn't get the corresponding type "
1025 llvm::toString(std::move(
error)).c_str());
1028 auto ts = *type_system_or_err;
1031 "Couldn't dematerialize a result variable: "
1032 "couldn't corresponding type system is "
1037 ts->GetPersistentExpressionState();
1039 if (!persistent_state) {
1041 "Couldn't dematerialize a result variable: "
1042 "corresponding type system doesn't handle persistent "
1056 "couldn't dematerialize a result variable: failed to make persistent "
1070 !(address >= frame_bottom && address < frame_top);
1078 ret->ValueUpdated();
1080 const size_t pvar_byte_size =
1081 llvm::expectedToOptional(ret->GetByteSize()).value_or(0);
1082 uint8_t *pvar_data = ret->GetValueBytes();
1084 map.
ReadMemory(pvar_data, address, pvar_byte_size, read_error);
1088 "Couldn't dematerialize a result variable: couldn't read its memory");
1110 Log *log)
override {
1115 dump_stream.
Printf(
"0x%" PRIx64
": EntityResultVariable\n", load_addr);
1129 dump_stream.
PutCString(
" <could not be read>\n");
1146 dump_stream.
PutCString(
"Points to process memory:\n");
1148 dump_stream.
PutCString(
"Temporary allocation:\n");
1152 dump_stream.
PutCString(
" <could not be be found>\n");
1160 dump_stream.
PutCString(
" <could not be read>\n");
1197 bool is_program_reference,
1198 bool keep_in_memory,
1202 *iter = std::make_unique<EntityResultVariable>(type, is_program_reference,
1203 keep_in_memory, delegate);
1205 (*iter)->SetOffset(ret);
1223 LLDB_LOG(log,
"EntitySymbol::Materialize [address = {0}, m_symbol = {1}]",
1224 (uint64_t)load_addr,
m_symbol.GetName());
1239 "couldn't resolve symbol {0} because there is no target",
1249 Status pointer_write_error;
1253 if (!pointer_write_error.
Success()) {
1255 "couldn't write the address of symbol {0}: {1}",
m_symbol.GetName(),
1269 "EntitySymbol::Dematerialize [address = {0:x}, m_symbol = {1}]",
1270 (uint64_t)load_addr,
m_symbol.GetName());
1276 Log *log)
override {
1283 dump_stream.
Format(
"{0:x}: EntitySymbol ({1})\n", load_addr,
1294 dump_stream.
PutCString(
" <could not be read>\n");
1314 *iter = std::make_unique<EntitySymbol>(symbol_sp);
1316 (*iter)->SetOffset(ret);
1336 "EntityRegister::Materialize [address = 0x%" PRIx64
1337 ", m_register_info = %s]",
1342 if (!frame_sp.get()) {
1344 "couldn't materialize register %s without a stack frame",
1359 "data for register %s had size %llu but we expected %llu",
1380 "couldn't write the contents of register %s: %s",
1394 "EntityRegister::Dematerialize [address = 0x%" PRIx64
1395 ", m_register_info = %s]",
1402 if (!frame_sp.get()) {
1404 "couldn't dematerialize register %s without a stack frame",
1414 if (!extract_error.
Success()) {
1435 if (!reg_context_sp->WriteRegister(&
m_register_info, register_value)) {
1443 Log *log)
override {
1450 dump_stream.
Printf(
"0x%" PRIx64
": EntityRegister (%s)\n", load_addr,
1461 dump_stream.
PutCString(
" <could not be read>\n");
1483 *iter = std::make_unique<EntityRegister>(register_info);
1485 (*iter)->SetOffset(ret);
1492 if (dematerializer_sp)
1493 dematerializer_sp->Wipe();
1505 if (dematerializer_sp) {
1519 entity_up->Materialize(frame_sp, map, process_address,
error);
1521 if (!
error.Success())
1528 "Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64
1530 static_cast<void *
>(frame_sp.get()), process_address);
1532 entity_up->DumpToLog(map, process_address, log);
1547 frame_sp = thread_sp->GetFrameWithStackID(
m_stack_id);
1551 exe_scope =
m_map->GetBestExecutionContextScope();
1555 "Couldn't dematerialize: invalid dematerializer");
1563 "Materializer::Dematerialize (frame_sp = %p, process_address "
1564 "= 0x%" PRIx64
") about to dematerialize:",
1572 frame_bottom,
error);
1574 if (!
error.Success())
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
static constexpr uint32_t g_default_var_byte_size
static constexpr uint32_t g_default_var_alignment
static llvm::StringRef GetName(XcodeSDK::Type type)
Materializer::PersistentVariableDelegate * m_delegate
lldb::ExpressionVariableSP m_persistent_variable_sp
void DestroyAllocation(IRMemoryMap &map, Status &err)
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
void MakeAllocation(IRMemoryMap &map, Status &err)
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
EntityPersistentVariable(lldb::ExpressionVariableSP &persistent_variable_sp, Materializer::PersistentVariableDelegate *delegate)
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
RegisterInfo m_register_info
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
lldb::DataBufferSP m_register_contents
EntityRegister(const RegisterInfo ®ister_info)
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
Materializer::PersistentVariableDelegate * m_delegate
bool m_is_program_reference
This is used both to control whether this result entity can (and should) track the value in inferior ...
size_t m_temporary_allocation_size
EntityResultVariable(const CompilerType &type, bool is_program_reference, bool keep_in_memory, Materializer::PersistentVariableDelegate *delegate)
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
lldb::addr_t m_temporary_allocation
EntitySymbol(const Symbol &symbol)
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
ConstString GetName() const override
ValueObjectProviderTy m_valobj_provider
lldb::ValueObjectSP m_valobj_sp
bool LocationExpressionIsValid() const override
Returns 'true' if the location expression associated with this variable is valid.
std::optional< size_t > GetTypeBitAlign(ExecutionContextScope *scope) const override
Returns alignment of the type associated with this variable in bits.
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *scope) const override
Returns size in bytes of the type associated with this variable.
lldb::ValueObjectSP SetupValueObject(ExecutionContextScope *scope) override
Creates and returns ValueObject tied to this variable and prepares Entity for materialization.
EntityValueObject(ConstString name, ValueObjectProviderTy provider)
lldb::DataBufferSP m_original_data
size_t m_temporary_allocation_size
lldb::addr_t m_temporary_allocation
void Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err) override
virtual ~EntityVariableBase()=default
void Wipe(IRMemoryMap &map, lldb::addr_t process_address) override
void DumpToLog(IRMemoryMap &map, lldb::addr_t process_address, Log *log) override
virtual std::optional< size_t > GetTypeBitAlign(ExecutionContextScope *scope) const =0
Returns alignment of the type associated with this variable in bits.
virtual ConstString GetName() const =0
virtual bool LocationExpressionIsValid() const =0
Returns 'true' if the location expression associated with this variable is valid.
virtual lldb::ValueObjectSP SetupValueObject(ExecutionContextScope *scope)=0
Creates and returns ValueObject tied to this variable and prepares Entity for materialization.
virtual llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *scope) const =0
Returns size in bytes of the type associated with this variable.
void Dematerialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, lldb::addr_t frame_top, lldb::addr_t frame_bottom, Status &err) override
ConstString GetName() const override
std::optional< size_t > GetTypeBitAlign(ExecutionContextScope *scope) const override
Returns alignment of the type associated with this variable in bits.
lldb::ValueObjectSP SetupValueObject(ExecutionContextScope *scope) override
Creates and returns ValueObject tied to this variable and prepares Entity for materialization.
bool LocationExpressionIsValid() const override
Returns 'true' if the location expression associated with this variable is valid.
lldb::VariableSP m_variable_sp
Variable that this entity is based on.
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *scope) const override
Returns size in bytes of the type associated with this variable.
EntityVariable(lldb::VariableSP &variable_sp)
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
lldb::addr_t GetFileAddress() const
Get the file address.
Generic representation of a type in a programming language.
A uniqued constant string class.
A subclass of DataBuffer that stores a data buffer on the heap.
lldb::offset_t GetByteSize() const override
Get the number of bytes in the data buffer.
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
virtual lldb::StackFrameSP CalculateStackFrame()=0
virtual lldb::ProcessSP CalculateProcess()=0
virtual lldb::TargetSP CalculateTarget()=0
@ EVIsLLDBAllocated
This variable is resident in a location specifically allocated for it by LLDB in the target process.
@ EVNeedsFreezeDry
Copy from m_live_sp to m_frozen_sp during dematerialization.
@ EVNeedsAllocation
Space for this variable has yet to be allocated in the target process.
@ EVIsProgramReference
This variable is a reference to a (possibly invalid) area managed by the target program.
@ EVKeepInTarget
Keep the allocation after the expression is complete rather than freeze drying its contents and freei...
Encapsulates memory that may exist in the process but must also be available in the host process.
void Free(lldb::addr_t process_address, Status &error)
lldb::ByteOrder GetByteOrder()
llvm::Expected< lldb::addr_t > Malloc(size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, bool zero_memory, AllocationPolicy *used_policy=nullptr)
void ReadPointerFromMemory(lldb::addr_t *address, lldb::addr_t process_address, Status &error)
ExecutionContextScope * GetBestExecutionContextScope() const
void GetMemoryData(DataExtractor &extractor, lldb::addr_t process_address, size_t size, Status &error)
uint32_t GetAddressByteSize()
void WritePointerToMemory(lldb::addr_t process_address, lldb::addr_t pointer, Status &error)
void WriteScalarToMemory(lldb::addr_t process_address, Scalar &scalar, size_t size, Status &error)
void Leak(lldb::addr_t process_address, Status &error)
void WriteMemory(lldb::addr_t process_address, const uint8_t *bytes, size_t size, Status &error)
void ReadMemory(uint8_t *bytes, lldb::addr_t process_address, size_t size, Status &error)
@ eAllocationPolicyMirror
The intent is that this allocation exist both in the host and the process and have the same content i...
void PutString(llvm::StringRef str)
Materializer * m_materializer
void Dematerialize(Status &err, lldb::addr_t frame_top, lldb::addr_t frame_bottom)
lldb::ThreadWP m_thread_wp
lldb::addr_t m_process_address
virtual ~PersistentVariableDelegate()
PersistentVariableDelegate()
uint32_t AddResultVariable(const CompilerType &type, bool is_lvalue, bool keep_in_memory, PersistentVariableDelegate *delegate, Status &err)
uint32_t AddStructMember(Entity &entity)
std::unique_ptr< Entity > EntityUP
std::shared_ptr< Dematerializer > DematerializerSP
DematerializerSP Materialize(lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Status &err)
uint32_t AddSymbol(const Symbol &symbol_sp, Status &err)
uint32_t AddRegister(const RegisterInfo ®ister_info, Status &err)
DematerializerWP m_dematerializer_wp
uint32_t AddValueObject(ConstString name, ValueObjectProviderTy valobj_provider, Status &err)
Create entity from supplied ValueObject and count it as a member of the materialized struct.
uint32_t AddPersistentVariable(lldb::ExpressionVariableSP &persistent_variable_sp, PersistentVariableDelegate *delegate, Status &err)
uint32_t AddVariable(lldb::VariableSP &variable_sp, Status &err)
uint32_t m_current_offset
uint32_t m_struct_alignment
virtual lldb::ExpressionVariableSP CreatePersistentVariable(const lldb::ValueObjectSP &valobj_sp)=0
virtual ConstString GetNextPersistentVariableName(bool is_error=false)=0
Return a new persistent variable name with the specified prefix.
uint32_t GetAsMemoryData(const RegisterInfo ®_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
uint32_t GetByteSize() const
void Clear()
Clear the object state.
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool Success() const
Test for success condition.
llvm::StringRef GetString() const
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address=LLDB_INVALID_ADDRESS, ValueObjectManager *manager=nullptr)
These routines create ValueObjectConstResult ValueObjects from various data sources.
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
uint8_t * GetBytes()
Get a pointer to the data.
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::function< lldb::ValueObjectSP(ConstString, StackFrame *)> ValueObjectProviderTy
Functor that returns a ValueObjectSP for a variable given its name and the StackFrame of interest.
void DumpHexBytes(Stream *s, const void *src, size_t src_len, uint32_t bytes_per_line, lldb::addr_t base_addr)
@ eAddressTypeLoad
Address is an address as in the current target inferior process.
std::string toString(FormatterBytecode::OpCodes op)
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::ExpressionVariable > ExpressionVariableSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Variable > VariableSP
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
Every register is described in detail including its name, alternate name (optional),...