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 {0} to the target: {1}",
152 if (!deallocate_error.
Success()) {
154 "couldn't deallocate memory for %s: %s",
167 "EntityPersistentVariable::Materialize [address = {0:x}, m_name = "
168 "{1}, m_flags = {2:x}]",
196 "couldn't write the location of {0} to memory: {1}",
201 "no materialization happened for persistent variable {0}",
215 "EntityPersistentVariable::Dematerialize [address = {0:x}, m_name "
216 "= {1}, m_flags = {2}]",
217 (uint64_t)process_address +
m_offset,
243 "couldn't read the address of program-allocated variable %s: %s",
258 location <= frame_top) {
279 "couldn't find the memory area used to store %s",
287 "the address of the memory area for %s is in an incorrect format",
296 LLDB_LOGF(log,
"Dematerializing %s from 0x%" PRIx64
" (size = %llu)",
299 (
unsigned long long)llvm::expectedToOptional(
317 "couldn't read the contents of %s from memory: %s",
328 "no dematerialization happened for persistent variable {0}",
351 dump_stream.
Format(
"{0:x}: EntityPersistentVariable ({1})\n", load_addr,
355 dump_stream.
Printf(
"Pointer:\n");
362 dump_stream.
Printf(
" <could not be read>\n");
372 dump_stream.
Printf(
"Target:\n");
379 dump_stream.
Printf(
" <could not be read>\n");
393 dump_stream.
Printf(
" <could not be read>\n");
417 *iter = std::make_unique<EntityPersistentVariable>(persistent_variable_sp,
420 (*iter)->SetOffset(ret);
445 "EntityVariable::Materialize [address = 0x%" PRIx64
446 ", m_variable_sp = %s]",
447 (uint64_t)load_addr,
GetName().GetCString());
458 "couldn't get a value object for variable {0}",
GetName());
462 Status valobj_error = valobj_sp->GetError().Clone();
464 if (valobj_error.
Fail()) {
466 "couldn't get the value of variable {0}: {1}",
GetName(),
474 valobj_sp->GetData(valobj_extractor, extract_error);
476 if (!extract_error.
Success()) {
478 "couldn't read contents of reference variable {0}: {1}",
GetName(),
491 "couldn't write the contents of reference variable {0} to memory: "
498 valobj_sp->GetAddressOf(
false).address;
505 "couldn't write the address of variable {0} to memory: {1}",
512 valobj_sp->GetData(data, extract_error);
513 if (!extract_error.
Success()) {
515 "couldn't get the value of {0}: {1}",
GetName(),
522 "trying to create a temporary region for {0} but one exists",
528 llvm::expectedToOptional(
GetByteSize(scope)).value_or(0)) {
531 "the variable '{0}' has no location, "
532 "it may have been optimized out",
536 "size of variable {0} ({1}) is larger than the ValueObject's "
539 llvm::expectedToOptional(
GetByteSize(scope)).value_or(0),
546 if (!opt_bit_align) {
548 "can't get the type alignment for {0}",
GetName());
552 size_t byte_align = (*opt_bit_align + 7) / 8;
554 const bool zero_memory =
false;
555 if (
auto address_or_error = map.
Malloc(
557 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
562 "couldn't allocate a temporary region for {0}: {1}",
GetName(),
563 toString(address_or_error.takeError()));
579 "couldn't write to the temporary region for {0}: {1}",
GetName(),
584 Status pointer_write_error;
587 pointer_write_error);
589 if (!pointer_write_error.
Success()) {
591 "couldn't write the address of the temporary region for {0}: {1}",
606 "EntityVariable::Dematerialize [address = {0:x}, m_variable_sp = {1}]",
607 (uint64_t)load_addr,
GetName());
619 "couldn't get a value object for variable {0}",
GetName());
629 llvm::expectedToOptional(valobj_sp->GetByteSize()).value_or(0),
632 if (!extract_error.
Success()) {
634 "couldn't get the data for variable {0}",
GetName());
638 bool actually_write =
true;
644 actually_write =
false;
650 if (actually_write) {
651 valobj_sp->SetData(data, set_error);
655 "couldn't write the new contents of {0} back into the variable",
667 "couldn't free the temporary region for {0}: {1}",
GetName(),
683 dump_stream.
Printf(
"0x%" PRIx64
": EntityVariable\n", load_addr);
690 dump_stream.
Printf(
"Pointer:\n");
697 dump_stream.
Printf(
" <could not be read>\n");
714 dump_stream.
Printf(
"Points to process memory:\n");
716 dump_stream.
Printf(
"Temporary allocation:\n");
720 dump_stream.
Printf(
" <could not be be found>\n");
728 dump_stream.
Printf(
" <could not be read>\n");
773 virtual llvm::Expected<uint64_t>
784 virtual std::optional<size_t>
804 m_variable_sp->GetType()->GetForwardCompilerType().IsReferenceType();
814 llvm::Expected<uint64_t>
823 std::optional<size_t>
825 return m_variable_sp->GetType()->GetLayoutCompilerType().GetTypeBitAlign(
857 llvm::Expected<uint64_t>
860 return m_valobj_sp->GetCompilerType().GetByteSize(scope);
862 return llvm::createStringError(
"no value object");
872 std::optional<size_t>
875 return m_valobj_sp->GetCompilerType().GetTypeBitAlign(scope);
888 *iter = std::make_unique<EntityVariable>(variable_sp);
890 (*iter)->SetOffset(ret);
897 assert(valobj_provider);
899 *iter = std::make_unique<EntityValueObject>(name, std::move(valobj_provider));
901 (*iter)->SetOffset(ret);
923 "Trying to create a temporary region for the result "
934 auto byte_size_or_err =
m_type.GetByteSize(exe_scope);
935 if (!byte_size_or_err) {
939 auto byte_size = *byte_size_or_err;
941 std::optional<size_t> opt_bit_align =
m_type.GetTypeBitAlign(exe_scope);
942 if (!opt_bit_align) {
944 "can't get the alignment of type \"{0}\"",
m_type.GetTypeName());
948 size_t byte_align = (*opt_bit_align + 7) / 8;
950 const bool zero_memory =
true;
951 if (
auto address_or_error = map.
Malloc(
952 byte_size, byte_align,
953 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
958 "couldn't allocate a temporary region for the result: %s",
959 toString(address_or_error.takeError()).c_str());
965 Status pointer_write_error;
968 pointer_write_error);
970 if (!pointer_write_error.
Success()) {
972 "couldn't write the address of the "
973 "temporary region for the result: %s",
990 "Couldn't dematerialize a result variable: invalid "
991 "execution context scope");
1003 "Couldn't dematerialize a result variable: couldn't "
1004 "read its address");
1012 "Couldn't dematerialize a result variable: no target");
1016 auto type_system_or_err =
1017 target_sp->GetScratchTypeSystemForLanguage(
m_type.GetMinimumLanguage());
1019 if (
auto error = type_system_or_err.takeError()) {
1021 "Couldn't dematerialize a result variable: "
1022 "couldn't get the corresponding type "
1024 llvm::toString(std::move(
error)).c_str());
1027 auto ts = *type_system_or_err;
1030 "Couldn't dematerialize a result variable: "
1031 "couldn't corresponding type system is "
1036 ts->GetPersistentExpressionState();
1038 if (!persistent_state) {
1040 "Couldn't dematerialize a result variable: "
1041 "corresponding type system doesn't handle persistent "
1055 "couldn't dematerialize a result variable: failed to make persistent "
1069 !(address >= frame_bottom && address < frame_top);
1077 ret->ValueUpdated();
1079 const size_t pvar_byte_size =
1080 llvm::expectedToOptional(ret->GetByteSize()).value_or(0);
1081 uint8_t *pvar_data = ret->GetValueBytes();
1083 map.
ReadMemory(pvar_data, address, pvar_byte_size, read_error);
1087 "Couldn't dematerialize a result variable: couldn't read its memory");
1109 Log *log)
override {
1114 dump_stream.
Printf(
"0x%" PRIx64
": EntityResultVariable\n", load_addr);
1121 dump_stream.
Printf(
"Pointer:\n");
1128 dump_stream.
Printf(
" <could not be read>\n");
1145 dump_stream.
Printf(
"Points to process memory:\n");
1147 dump_stream.
Printf(
"Temporary allocation:\n");
1151 dump_stream.
Printf(
" <could not be be found>\n");
1159 dump_stream.
Printf(
" <could not be read>\n");
1196 bool is_program_reference,
1197 bool keep_in_memory,
1201 *iter = std::make_unique<EntityResultVariable>(type, is_program_reference,
1202 keep_in_memory, delegate);
1204 (*iter)->SetOffset(ret);
1222 LLDB_LOG(log,
"EntitySymbol::Materialize [address = {0}, m_symbol = {1}]",
1223 (uint64_t)load_addr,
m_symbol.GetName());
1238 "couldn't resolve symbol {0} because there is no target",
1248 Status pointer_write_error;
1252 if (!pointer_write_error.
Success()) {
1254 "couldn't write the address of symbol {0}: {1}",
m_symbol.GetName(),
1268 "EntitySymbol::Dematerialize [address = {0:x}, m_symbol = {1}]",
1269 (uint64_t)load_addr,
m_symbol.GetName());
1275 Log *log)
override {
1282 dump_stream.
Format(
"{0:x}: EntitySymbol ({1})\n", load_addr,
1286 dump_stream.
Printf(
"Pointer:\n");
1293 dump_stream.
Printf(
" <could not be read>\n");
1313 *iter = std::make_unique<EntitySymbol>(symbol_sp);
1315 (*iter)->SetOffset(ret);
1335 "EntityRegister::Materialize [address = 0x%" PRIx64
1336 ", m_register_info = %s]",
1341 if (!frame_sp.get()) {
1343 "couldn't materialize register %s without a stack frame",
1358 "data for register %s had size %llu but we expected %llu",
1379 "couldn't write the contents of register %s: %s",
1393 "EntityRegister::Dematerialize [address = 0x%" PRIx64
1394 ", m_register_info = %s]",
1401 if (!frame_sp.get()) {
1403 "couldn't dematerialize register %s without a stack frame",
1413 if (!extract_error.
Success()) {
1434 if (!reg_context_sp->WriteRegister(&
m_register_info, register_value)) {
1442 Log *log)
override {
1449 dump_stream.
Printf(
"0x%" PRIx64
": EntityRegister (%s)\n", load_addr,
1453 dump_stream.
Printf(
"Value:\n");
1460 dump_stream.
Printf(
" <could not be read>\n");
1482 *iter = std::make_unique<EntityRegister>(register_info);
1484 (*iter)->SetOffset(ret);
1491 if (dematerializer_sp)
1492 dematerializer_sp->Wipe();
1504 if (dematerializer_sp) {
1518 entity_up->Materialize(frame_sp, map, process_address,
error);
1520 if (!
error.Success())
1527 "Materializer::Materialize (frame_sp = %p, process_address = 0x%" PRIx64
1529 static_cast<void *
>(frame_sp.get()), process_address);
1531 entity_up->DumpToLog(map, process_address, log);
1546 frame_sp = thread_sp->GetFrameWithStackID(
m_stack_id);
1550 exe_scope =
m_map->GetBestExecutionContextScope();
1554 "Couldn't dematerialize: invalid dematerializer");
1562 "Materializer::Dematerialize (frame_sp = %p, process_address "
1563 "= 0x%" PRIx64
") about to dematerialize:",
1571 frame_bottom,
error);
1573 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.
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.
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),...