41 uint32_t size = entity.
GetSize();
77 const bool zero_memory =
false;
79 auto address_or_error = map.
Malloc(
82 8, lldb::ePermissionsReadable | lldb::ePermissionsWritable,
84 if (!address_or_error) {
86 "couldn't allocate a memory area to store %s: %s",
88 toString(address_or_error.takeError()).c_str());
93 LLDB_LOGF(log,
"Allocated %s (0x%" PRIx64
") successfully",
110 map.
Leak(mem, leak_error);
136 "couldn't write %s to the target: %s",
153 if (!deallocate_error.
Success()) {
155 "couldn't deallocate memory for %s: %s",
169 "EntityPersistentVariable::Materialize [address = 0x%" PRIx64
170 ", m_name = %s, m_flags = 0x%hx]",
200 "couldn't write the location of %s to memory: %s",
206 "no materialization happened for persistent variable %s",
221 "EntityPersistentVariable::Dematerialize [address = 0x%" PRIx64
222 ", m_name = %s, m_flags = 0x%hx]",
223 (uint64_t)process_address +
m_offset,
250 "couldn't read the address of program-allocated variable %s: %s",
265 location <= frame_top) {
286 "couldn't find the memory area used to store %s",
294 "the address of the memory area for %s is in an incorrect format",
303 LLDB_LOGF(log,
"Dematerializing %s from 0x%" PRIx64
" (size = %llu)",
306 (
unsigned long long)llvm::expectedToOptional(
324 "couldn't read the contents of %s from memory: %s",
335 "no dematerialization happened for persistent variable %s",
358 dump_stream.
Printf(
"0x%" PRIx64
": EntityPersistentVariable (%s)\n",
363 dump_stream.
Printf(
"Pointer:\n");
370 dump_stream.
Printf(
" <could not be read>\n");
380 dump_stream.
Printf(
"Target:\n");
387 dump_stream.
Printf(
" <could not be read>\n");
401 dump_stream.
Printf(
" <could not be read>\n");
425 *iter = std::make_unique<EntityPersistentVariable>(persistent_variable_sp,
428 (*iter)->SetOffset(ret);
454 "EntityVariable::Materialize [address = 0x%" PRIx64
455 ", m_variable_sp = %s]",
456 (uint64_t)load_addr,
GetName().GetCString());
468 "couldn't get a value object for variable %s",
GetName().AsCString());
474 if (valobj_error.
Fail()) {
476 "couldn't get the value of variable %s: %s",
GetName().AsCString(),
484 valobj_sp->GetData(valobj_extractor, extract_error);
486 if (!extract_error.
Success()) {
488 "couldn't read contents of reference variable %s: %s",
501 "couldn't write the contents of reference "
502 "variable %s to memory: %s",
508 valobj_sp->GetAddressOf(
false).address;
515 "couldn't write the address of variable %s to memory: %s",
522 valobj_sp->GetData(data, extract_error);
523 if (!extract_error.
Success()) {
525 "couldn't get the value of %s: %s",
GetName().AsCString(),
532 "trying to create a temporary region for %s but one exists",
538 llvm::expectedToOptional(
GetByteSize(scope)).value_or(0)) {
541 "the variable '%s' has no location, "
542 "it may have been optimized out",
546 "size of variable %s (%" PRIu64
547 ") is larger than the ValueObject's size (%" PRIu64
")",
549 llvm::expectedToOptional(
GetByteSize(scope)).value_or(0),
556 if (!opt_bit_align) {
558 "can't get the type alignment for %s",
GetName().AsCString());
562 size_t byte_align = (*opt_bit_align + 7) / 8;
564 const bool zero_memory =
false;
565 if (
auto address_or_error = map.
Malloc(
567 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
572 "couldn't allocate a temporary region for %s: %s",
574 toString(address_or_error.takeError()).c_str());
590 "couldn't write to the temporary region for %s: %s",
595 Status pointer_write_error;
598 pointer_write_error);
600 if (!pointer_write_error.
Success()) {
602 "couldn't write the address of the temporary region for %s: %s",
617 "EntityVariable::Dematerialize [address = 0x%" PRIx64
618 ", m_variable_sp = %s]",
619 (uint64_t)load_addr,
GetName().AsCString());
632 "couldn't get a value object for variable %s",
643 llvm::expectedToOptional(valobj_sp->GetByteSize()).value_or(0),
646 if (!extract_error.
Success()) {
648 "couldn't get the data for variable %s",
GetName().AsCString());
652 bool actually_write =
true;
658 actually_write =
false;
664 if (actually_write) {
665 valobj_sp->SetData(data, set_error);
669 "couldn't write the new contents of %s back into the variable",
681 "couldn't free the temporary region for %s: %s",
697 dump_stream.
Printf(
"0x%" PRIx64
": EntityVariable\n", load_addr);
704 dump_stream.
Printf(
"Pointer:\n");
711 dump_stream.
Printf(
" <could not be read>\n");
728 dump_stream.
Printf(
"Points to process memory:\n");
730 dump_stream.
Printf(
"Temporary allocation:\n");
734 dump_stream.
Printf(
" <could not be be found>\n");
742 dump_stream.
Printf(
" <could not be read>\n");
787 virtual llvm::Expected<uint64_t>
798 virtual std::optional<size_t>
818 m_variable_sp->GetType()->GetForwardCompilerType().IsReferenceType();
828 llvm::Expected<uint64_t>
837 std::optional<size_t>
839 return m_variable_sp->GetType()->GetLayoutCompilerType().GetTypeBitAlign(
871 llvm::Expected<uint64_t>
874 return m_valobj_sp->GetCompilerType().GetByteSize(scope);
876 return llvm::createStringError(
"no value object");
886 std::optional<size_t>
889 return m_valobj_sp->GetCompilerType().GetTypeBitAlign(scope);
902 *iter = std::make_unique<EntityVariable>(variable_sp);
904 (*iter)->SetOffset(ret);
911 assert(valobj_provider);
913 *iter = std::make_unique<EntityValueObject>(name, std::move(valobj_provider));
915 (*iter)->SetOffset(ret);
937 "Trying to create a temporary region for the result "
948 auto byte_size_or_err =
m_type.GetByteSize(exe_scope);
949 if (!byte_size_or_err) {
953 auto byte_size = *byte_size_or_err;
955 std::optional<size_t> opt_bit_align =
m_type.GetTypeBitAlign(exe_scope);
956 if (!opt_bit_align) {
958 "can't get the alignment of type \"%s\"",
959 m_type.GetTypeName().AsCString());
963 size_t byte_align = (*opt_bit_align + 7) / 8;
965 const bool zero_memory =
true;
966 if (
auto address_or_error = map.
Malloc(
967 byte_size, byte_align,
968 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
973 "couldn't allocate a temporary region for the result: %s",
974 toString(address_or_error.takeError()).c_str());
980 Status pointer_write_error;
983 pointer_write_error);
985 if (!pointer_write_error.
Success()) {
987 "couldn't write the address of the "
988 "temporary region for the result: %s",
1005 "Couldn't dematerialize a result variable: invalid "
1006 "execution context scope");
1018 "Couldn't dematerialize a result variable: couldn't "
1019 "read its address");
1027 "Couldn't dematerialize a result variable: no target");
1031 auto type_system_or_err =
1032 target_sp->GetScratchTypeSystemForLanguage(
m_type.GetMinimumLanguage());
1034 if (
auto error = type_system_or_err.takeError()) {
1036 "Couldn't dematerialize a result variable: "
1037 "couldn't get the corresponding type "
1039 llvm::toString(std::move(
error)).c_str());
1042 auto ts = *type_system_or_err;
1045 "Couldn't dematerialize a result variable: "
1046 "couldn't corresponding type system is "
1051 ts->GetPersistentExpressionState();
1053 if (!persistent_state) {
1055 "Couldn't dematerialize a result variable: "
1056 "corresponding type system doesn't handle persistent "
1070 "couldn't dematerialize a result variable: "
1071 "failed to make persistent variable %s",
1084 !(address >= frame_bottom && address < frame_top);
1092 ret->ValueUpdated();
1094 const size_t pvar_byte_size =
1095 llvm::expectedToOptional(ret->GetByteSize()).value_or(0);
1096 uint8_t *pvar_data = ret->GetValueBytes();
1098 map.
ReadMemory(pvar_data, address, pvar_byte_size, read_error);
1102 "Couldn't dematerialize a result variable: couldn't read its memory");
1124 Log *log)
override {
1129 dump_stream.
Printf(
"0x%" PRIx64
": EntityResultVariable\n", load_addr);
1136 dump_stream.
Printf(
"Pointer:\n");
1143 dump_stream.
Printf(
" <could not be read>\n");
1160 dump_stream.
Printf(
"Points to process memory:\n");
1162 dump_stream.
Printf(
"Temporary allocation:\n");
1166 dump_stream.
Printf(
" <could not be be found>\n");
1174 dump_stream.
Printf(
" <could not be read>\n");
1211 bool is_program_reference,
1212 bool keep_in_memory,
1216 *iter = std::make_unique<EntityResultVariable>(type, is_program_reference,
1217 keep_in_memory, delegate);
1219 (*iter)->SetOffset(ret);
1239 "EntitySymbol::Materialize [address = 0x%" PRIx64
1241 (uint64_t)load_addr,
m_symbol.GetName().AsCString());
1257 "couldn't resolve symbol %s because there is no target",
1267 Status pointer_write_error;
1271 if (!pointer_write_error.
Success()) {
1273 "couldn't write the address of symbol %s: %s",
1288 "EntitySymbol::Dematerialize [address = 0x%" PRIx64
1290 (uint64_t)load_addr,
m_symbol.GetName().AsCString());
1297 Log *log)
override {
1304 dump_stream.
Printf(
"0x%" PRIx64
": EntitySymbol (%s)\n", load_addr,
1308 dump_stream.
Printf(
"Pointer:\n");
1315 dump_stream.
Printf(
" <could not be read>\n");
1335 *iter = std::make_unique<EntitySymbol>(symbol_sp);
1337 (*iter)->SetOffset(ret);
1358 "EntityRegister::Materialize [address = 0x%" PRIx64
1359 ", m_register_info = %s]",
1365 if (!frame_sp.get()) {
1367 "couldn't materialize register %s without a stack frame",
1382 "data for register %s had size %llu but we expected %llu",
1403 "couldn't write the contents of register %s: %s",
1418 "EntityRegister::Dematerialize [address = 0x%" PRIx64
1419 ", m_register_info = %s]",
1427 if (!frame_sp.get()) {
1429 "couldn't dematerialize register %s without a stack frame",
1439 if (!extract_error.
Success()) {
1460 if (!reg_context_sp->WriteRegister(&
m_register_info, register_value)) {
1468 Log *log)
override {
1475 dump_stream.
Printf(
"0x%" PRIx64
": EntityRegister (%s)\n", load_addr,
1479 dump_stream.
Printf(
"Value:\n");
1486 dump_stream.
Printf(
" <could not be read>\n");
1508 *iter = std::make_unique<EntityRegister>(register_info);
1510 (*iter)->SetOffset(ret);
1517 if (dematerializer_sp)
1518 dematerializer_sp->Wipe();
1530 if (dematerializer_sp) {
1544 entity_up->Materialize(frame_sp, map, process_address,
error);
1546 if (!
error.Success())
1553 "Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64
1555 static_cast<void *
>(frame_sp.get()), process_address);
1557 entity_up->DumpToLog(map, process_address, log);
1572 frame_sp = thread_sp->GetFrameWithStackID(
m_stack_id);
1576 exe_scope =
m_map->GetBestExecutionContextScope();
1580 "Couldn't dematerialize: invalid dematerializer");
1588 "Materializer::Dematerialize (frame_sp = %p, process_address "
1589 "= 0x%" PRIx64
") about to dematerialize:",
1597 frame_bottom,
error);
1599 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.
ValueType GetError() const
Access the error value.
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),...