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 %s to the target: %s",
153 live_valobj_sp.reset();
155 if (!deallocate_error.
Success()) {
157 "couldn't deallocate memory for %s: %s",
171 "EntityPersistentVariable::Materialize [address = 0x%" PRIx64
172 ", m_name = %s, m_flags = 0x%hx]",
202 "couldn't write the location of %s to memory: %s",
208 "no materialization happened for persistent variable %s",
223 "EntityPersistentVariable::Dematerialize [address = 0x%" PRIx64
224 ", m_name = %s, m_flags = 0x%hx]",
225 (uint64_t)process_address +
m_offset,
254 "couldn't read the address of program-allocated variable %s: %s",
269 location <= frame_top) {
284 if (!live_valobj_sp) {
286 "couldn't find the memory area used to store %s",
291 lldb::addr_t mem = live_valobj_sp->GetValue().GetScalar().ULongLong();
293 if (live_valobj_sp->GetValue().GetValueAddressType() !=
296 "the address of the memory area for %s is in an incorrect format",
305 LLDB_LOGF(log,
"Dematerializing %s from 0x%" PRIx64
" (size = %llu)",
308 (
unsigned long long)llvm::expectedToOptional(
326 "couldn't read the contents of %s from memory: %s",
336 "no dematerialization happened for persistent variable %s",
359 dump_stream.
Printf(
"0x%" PRIx64
": EntityPersistentVariable (%s)\n",
364 dump_stream.
Printf(
"Pointer:\n");
371 dump_stream.
Printf(
" <could not be read>\n");
381 dump_stream.
Printf(
"Target:\n");
388 dump_stream.
Printf(
" <could not be read>\n");
402 dump_stream.
Printf(
" <could not be read>\n");
426 *iter = std::make_unique<EntityPersistentVariable>(persistent_variable_sp,
429 (*iter)->SetOffset(ret);
455 "EntityVariable::Materialize [address = 0x%" PRIx64
456 ", m_variable_sp = %s]",
457 (uint64_t)load_addr,
GetName().GetCString());
469 "couldn't get a value object for variable %s",
GetName().AsCString());
473 Status valobj_error = valobj_sp->GetError().Clone();
475 if (valobj_error.
Fail()) {
477 "couldn't get the value of variable %s: %s",
GetName().AsCString(),
485 valobj_sp->GetData(valobj_extractor, extract_error);
487 if (!extract_error.
Success()) {
489 "couldn't read contents of reference variable %s: %s",
502 "couldn't write the contents of reference "
503 "variable %s to memory: %s",
509 valobj_sp->GetAddressOf(
false).address;
516 "couldn't write the address of variable %s to memory: %s",
523 valobj_sp->GetData(data, extract_error);
524 if (!extract_error.
Success()) {
526 "couldn't get the value of %s: %s",
GetName().AsCString(),
533 "trying to create a temporary region for %s but one exists",
539 llvm::expectedToOptional(
GetByteSize(scope)).value_or(0)) {
542 "the variable '%s' has no location, "
543 "it may have been optimized out",
547 "size of variable %s (%" PRIu64
548 ") is larger than the ValueObject's size (%" PRIu64
")",
550 llvm::expectedToOptional(
GetByteSize(scope)).value_or(0),
557 if (!opt_bit_align) {
559 "can't get the type alignment for %s",
GetName().AsCString());
563 size_t byte_align = (*opt_bit_align + 7) / 8;
565 const bool zero_memory =
false;
566 if (
auto address_or_error = map.
Malloc(
568 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
573 "couldn't allocate a temporary region for %s: %s",
575 toString(address_or_error.takeError()).c_str());
591 "couldn't write to the temporary region for %s: %s",
596 Status pointer_write_error;
599 pointer_write_error);
601 if (!pointer_write_error.
Success()) {
603 "couldn't write the address of the temporary region for %s: %s",
618 "EntityVariable::Dematerialize [address = 0x%" PRIx64
619 ", m_variable_sp = %s]",
620 (uint64_t)load_addr,
GetName().AsCString());
633 "couldn't get a value object for variable %s",
644 llvm::expectedToOptional(valobj_sp->GetByteSize()).value_or(0),
647 if (!extract_error.
Success()) {
649 "couldn't get the data for variable %s",
GetName().AsCString());
653 bool actually_write =
true;
659 actually_write =
false;
665 if (actually_write) {
666 valobj_sp->SetData(data, set_error);
670 "couldn't write the new contents of %s back into the variable",
682 "couldn't free the temporary region for %s: %s",
698 dump_stream.
Printf(
"0x%" PRIx64
": EntityVariable\n", load_addr);
705 dump_stream.
Printf(
"Pointer:\n");
712 dump_stream.
Printf(
" <could not be read>\n");
729 dump_stream.
Printf(
"Points to process memory:\n");
731 dump_stream.
Printf(
"Temporary allocation:\n");
735 dump_stream.
Printf(
" <could not be be found>\n");
743 dump_stream.
Printf(
" <could not be read>\n");
788 virtual llvm::Expected<uint64_t>
799 virtual std::optional<size_t>
819 m_variable_sp->GetType()->GetForwardCompilerType().IsReferenceType();
829 llvm::Expected<uint64_t>
838 std::optional<size_t>
840 return m_variable_sp->GetType()->GetLayoutCompilerType().GetTypeBitAlign(
872 llvm::Expected<uint64_t>
875 return m_valobj_sp->GetCompilerType().GetByteSize(scope);
877 return llvm::createStringError(
"no value object");
887 std::optional<size_t>
890 return m_valobj_sp->GetCompilerType().GetTypeBitAlign(scope);
903 *iter = std::make_unique<EntityVariable>(variable_sp);
905 (*iter)->SetOffset(ret);
912 assert(valobj_provider);
914 *iter = std::make_unique<EntityValueObject>(name, std::move(valobj_provider));
916 (*iter)->SetOffset(ret);
938 "Trying to create a temporary region for the result "
949 auto byte_size_or_err =
m_type.GetByteSize(exe_scope);
950 if (!byte_size_or_err) {
954 auto byte_size = *byte_size_or_err;
956 std::optional<size_t> opt_bit_align =
m_type.GetTypeBitAlign(exe_scope);
957 if (!opt_bit_align) {
959 "can't get the alignment of type \"%s\"",
960 m_type.GetTypeName().AsCString());
964 size_t byte_align = (*opt_bit_align + 7) / 8;
966 const bool zero_memory =
true;
967 if (
auto address_or_error = map.
Malloc(
968 byte_size, byte_align,
969 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
974 "couldn't allocate a temporary region for the result: %s",
975 toString(address_or_error.takeError()).c_str());
981 Status pointer_write_error;
984 pointer_write_error);
986 if (!pointer_write_error.
Success()) {
988 "couldn't write the address of the "
989 "temporary region for the result: %s",
1006 "Couldn't dematerialize a result variable: invalid "
1007 "execution context scope");
1019 "Couldn't dematerialize a result variable: couldn't "
1020 "read its address");
1028 "Couldn't dematerialize a result variable: no target");
1032 auto type_system_or_err =
1033 target_sp->GetScratchTypeSystemForLanguage(
m_type.GetMinimumLanguage());
1035 if (
auto error = type_system_or_err.takeError()) {
1037 "Couldn't dematerialize a result variable: "
1038 "couldn't get the corresponding type "
1040 llvm::toString(std::move(
error)).c_str());
1043 auto ts = *type_system_or_err;
1046 "Couldn't dematerialize a result variable: "
1047 "couldn't corresponding type system is "
1052 ts->GetPersistentExpressionState();
1054 if (!persistent_state) {
1056 "Couldn't dematerialize a result variable: "
1057 "corresponding type system doesn't handle persistent "
1071 "couldn't dematerialize a result variable: "
1072 "failed to make persistent variable %s",
1085 !(address >= frame_bottom && address < frame_top);
1093 ret->ValueUpdated();
1095 const size_t pvar_byte_size =
1096 llvm::expectedToOptional(ret->GetByteSize()).value_or(0);
1097 uint8_t *pvar_data = ret->GetValueBytes();
1099 map.
ReadMemory(pvar_data, address, pvar_byte_size, read_error);
1103 "Couldn't dematerialize a result variable: couldn't read its memory");
1125 Log *log)
override {
1130 dump_stream.
Printf(
"0x%" PRIx64
": EntityResultVariable\n", load_addr);
1137 dump_stream.
Printf(
"Pointer:\n");
1144 dump_stream.
Printf(
" <could not be read>\n");
1161 dump_stream.
Printf(
"Points to process memory:\n");
1163 dump_stream.
Printf(
"Temporary allocation:\n");
1167 dump_stream.
Printf(
" <could not be be found>\n");
1175 dump_stream.
Printf(
" <could not be read>\n");
1212 bool is_program_reference,
1213 bool keep_in_memory,
1217 *iter = std::make_unique<EntityResultVariable>(type, is_program_reference,
1218 keep_in_memory, delegate);
1220 (*iter)->SetOffset(ret);
1240 "EntitySymbol::Materialize [address = 0x%" PRIx64
1242 (uint64_t)load_addr,
m_symbol.GetName().AsCString());
1258 "couldn't resolve symbol %s because there is no target",
1268 Status pointer_write_error;
1272 if (!pointer_write_error.
Success()) {
1274 "couldn't write the address of symbol %s: %s",
1289 "EntitySymbol::Dematerialize [address = 0x%" PRIx64
1291 (uint64_t)load_addr,
m_symbol.GetName().AsCString());
1298 Log *log)
override {
1305 dump_stream.
Printf(
"0x%" PRIx64
": EntitySymbol (%s)\n", load_addr,
1309 dump_stream.
Printf(
"Pointer:\n");
1316 dump_stream.
Printf(
" <could not be read>\n");
1336 *iter = std::make_unique<EntitySymbol>(symbol_sp);
1338 (*iter)->SetOffset(ret);
1359 "EntityRegister::Materialize [address = 0x%" PRIx64
1360 ", m_register_info = %s]",
1366 if (!frame_sp.get()) {
1368 "couldn't materialize register %s without a stack frame",
1383 "data for register %s had size %llu but we expected %llu",
1404 "couldn't write the contents of register %s: %s",
1419 "EntityRegister::Dematerialize [address = 0x%" PRIx64
1420 ", m_register_info = %s]",
1428 if (!frame_sp.get()) {
1430 "couldn't dematerialize register %s without a stack frame",
1440 if (!extract_error.
Success()) {
1461 if (!reg_context_sp->WriteRegister(&
m_register_info, register_value)) {
1469 Log *log)
override {
1476 dump_stream.
Printf(
"0x%" PRIx64
": EntityRegister (%s)\n", load_addr,
1480 dump_stream.
Printf(
"Value:\n");
1487 dump_stream.
Printf(
" <could not be read>\n");
1509 *iter = std::make_unique<EntityRegister>(register_info);
1511 (*iter)->SetOffset(ret);
1518 if (dematerializer_sp)
1519 dematerializer_sp->Wipe();
1531 if (dematerializer_sp) {
1545 entity_up->Materialize(frame_sp, map, process_address,
error);
1547 if (!
error.Success())
1554 "Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64
1556 static_cast<void *
>(frame_sp.get()), process_address);
1558 entity_up->DumpToLog(map, process_address, log);
1573 frame_sp = thread_sp->GetFrameWithStackID(
m_stack_id);
1577 exe_scope =
m_map->GetBestExecutionContextScope();
1581 "Couldn't dematerialize: invalid dematerializer");
1589 "Materializer::Dematerialize (frame_sp = %p, process_address "
1590 "= 0x%" PRIx64
") about to dematerialize:",
1598 frame_bottom,
error);
1600 if (!
error.Success())
static llvm::raw_ostream & error(Stream &strm)
#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.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
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 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
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output 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)
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.
const char * toString(AppleArm64ExceptionClass EC)
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),...