From 14b1bae5ee36f3b5590e301c03d0362016015de0 Mon Sep 17 00:00:00 2001 From: Sean Callanan Date: Tue, 16 Apr 2013 23:25:35 +0000 Subject: [PATCH] Flipped the big switch: LLDB now uses the new Materializer for all expressions that need to run in the target. This includes the following changes: - Removed a bunch of (de-)materialization code from ClangExpressionDeclMap and assumed the presence of a Materializer where we previously had a fallback. - Ensured that an IRMemoryMap is passed into ClangExpressionDeclMap::Materialize(). - Fixed object ownership on LLVMContext; it is now owned by the IRExecutionUnit, since the Module and the ExecutionEngine both depend on its existence. - Fixed a few bugs in IRMemoryMap and the Materializer that showed up during testing. llvm-svn: 179649 --- .../lldb/Expression/ClangExpressionDeclMap.h | 153 +-- .../include/lldb/Expression/IRExecutionUnit.h | 4 +- lldb/include/lldb/Expression/Materializer.h | 50 +- .../Expression/ClangExpressionDeclMap.cpp | 945 ++---------------- .../Expression/ClangExpressionParser.cpp | 3 +- .../source/Expression/ClangUserExpression.cpp | 5 +- lldb/source/Expression/IRExecutionUnit.cpp | 7 +- lldb/source/Expression/IRMemoryMap.cpp | 6 +- lldb/source/Expression/Materializer.cpp | 172 +++- 9 files changed, 255 insertions(+), 1090 deletions(-) diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index e228f29ce5e3..7d0d22b6d05c 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -27,6 +27,7 @@ #include "lldb/Core/Value.h" #include "lldb/Expression/ClangASTSource.h" #include "lldb/Expression/ClangExpressionVariable.h" +#include "lldb/Expression/Materializer.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/ExecutionContext.h" @@ -541,7 +542,8 @@ public: /// True on success; false otherwise. //------------------------------------------------------------------ bool - Materialize (lldb::addr_t &struct_address, + Materialize (IRMemoryMap &map, + lldb::addr_t &struct_address, Error &error); //------------------------------------------------------------------ @@ -618,6 +620,7 @@ public: //------------------------------------------------------------------ bool Dematerialize (lldb::ClangExpressionVariableSP &result_sp, + IRMemoryMap &map, lldb::addr_t stack_frame_top, lldb::addr_t stack_frame_bottom, Error &error); @@ -782,6 +785,8 @@ private: { } + Materializer::DematerializerSP m_dematerializer_sp; ///< The dematerializer to use. + Process *m_process; ///< The process that the struct is materialized into. lldb::addr_t m_allocated_area; ///< The base of the memory allocated for the struct. Starts on a potentially unaligned address and may therefore be larger than the struct. lldb::addr_t m_materialized_location; ///< The address at which the struct is placed. Falls inside the allocated area. @@ -1074,6 +1079,7 @@ private: //------------------------------------------------------------------ bool DoMaterialize (bool dematerialize, + IRMemoryMap &map, lldb::addr_t stack_frame_top, lldb::addr_t stack_frame_bottom, lldb::ClangExpressionVariableSP *result_sp_ptr, @@ -1084,151 +1090,6 @@ private: //------------------------------------------------------------------ void DidDematerialize (); - - //------------------------------------------------------------------ - /// Actually do the task of materializing or dematerializing a persistent - /// variable. - /// - /// @param[in] dematerialize - /// True if the variable is to be dematerialized; false if it is to - /// be materialized. - /// - /// @param[in] var_sp - /// The persistent variable to materialize - /// - /// @param[in] addr - /// The address at which to materialize the variable. - /// - /// @param[in] stack_frame_top, stack_frame_bottom - /// If not LLDB_INVALID_ADDRESS, the bounds for the stack frame - /// in which the expression ran. A result whose address falls - /// inside this stack frame is dematerialized as a value - /// requiring rematerialization. - /// - /// @param[in] err - /// An Error to populate with any messages related to - /// (de)materializing the persistent variable. - /// - /// @return - /// True on success; false otherwise. - //------------------------------------------------------------------ - bool - DoMaterializeOnePersistentVariable (bool dematerialize, - lldb::ClangExpressionVariableSP &var_sp, - lldb::addr_t addr, - lldb::addr_t stack_frame_top, - lldb::addr_t stack_frame_bottom, - Error &err); - - //------------------------------------------------------------------ - /// Create a temporary buffer in the target process to store the value - /// of a persistent variable that would otherwise not be accessible in - /// memory (e.g., register values or constants). - /// - /// @param[in] process - /// The process to use when allocating the memory. - /// - /// @param[in] expr_var - /// The variable whose live data will hold this buffer. - /// - /// @param[in] err - /// An Error to populate with any messages related to - /// allocating the memory. - /// - /// @return - /// True on success; false otherwise. - //------------------------------------------------------------------ - bool - CreateLiveMemoryForExpressionVariable (Process &process, - lldb::ClangExpressionVariableSP &expr_var, - Error &err); - - //------------------------------------------------------------------ - /// Delete a temporary buffer created with - /// CreateLiveMemoryForExpressionVariable. - /// - /// @param[in] process - /// The process to use when deallocating the memory. - /// - /// @param[in] expr_var - /// The variable whose live data will hold this buffer. - /// - /// @param[in] err - /// An Error to populate with any messages related to - /// allocating the memory. - /// - /// @return - /// True on success; false otherwise. - //------------------------------------------------------------------ - bool - DeleteLiveMemoryForExpressionVariable (Process &process, - lldb::ClangExpressionVariableSP &expr_var, - Error &err); - - //------------------------------------------------------------------ - /// Actually do the task of materializing or dematerializing a - /// variable. - /// - /// @param[in] dematerialize - /// True if the variable is to be dematerialized; false if it is to - /// be materialized. - /// - /// @param[in] sym_ctx - /// The symbol context to use (for looking the variable up). - /// - /// @param[in] expr_var - /// The entity that the expression parser uses for the variable. - /// In case the variable needs to be copied into the target's - /// memory, this location is stored in the variable during - /// materialization and cleared when it is demateralized. - /// - /// @param[in] addr - /// The address at which to materialize the variable. - /// - /// @param[in] err - /// An Error to populate with any messages related to - /// (de)materializing the persistent variable. - /// - /// @return - /// True on success; false otherwise. - //------------------------------------------------------------------ - bool - DoMaterializeOneVariable (bool dematerialize, - const SymbolContext &sym_ctx, - lldb::ClangExpressionVariableSP &expr_var, - lldb::addr_t addr, - Error &err); - - //------------------------------------------------------------------ - /// Actually do the task of materializing or dematerializing a - /// register variable. - /// - /// @param[in] dematerialize - /// True if the variable is to be dematerialized; false if it is to - /// be materialized. - /// - /// @param[in] reg_ctx - /// The register context to use. - /// - /// @param[in] reg_info - /// The information for the register to read/write. - /// - /// @param[in] addr - /// The address at which to materialize the variable. - /// - /// @param[in] err - /// An Error to populate with any messages related to - /// (de)materializing the persistent variable. - /// - /// @return - /// True on success; false otherwise. - //------------------------------------------------------------------ - bool - DoMaterializeOneRegister (bool dematerialize, - RegisterContext ®_ctx, - const RegisterInfo ®_info, - lldb::addr_t addr, - Error &err); }; } // namespace lldb_private diff --git a/lldb/include/lldb/Expression/IRExecutionUnit.h b/lldb/include/lldb/Expression/IRExecutionUnit.h index ed24b9cf5c5a..e394230b5679 100644 --- a/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -64,7 +64,8 @@ public: //------------------------------------------------------------------ /// Constructor //------------------------------------------------------------------ - IRExecutionUnit (std::auto_ptr &module_ap, + IRExecutionUnit (std::auto_ptr &context_ap, + std::auto_ptr &module_ap, ConstString &name, const lldb::TargetSP &target_sp, std::vector &cpu_features); @@ -491,6 +492,7 @@ private: typedef std::vector RecordVector; RecordVector m_records; + std::auto_ptr m_context_ap; std::auto_ptr m_execution_engine_ap; std::auto_ptr m_module_ap; ///< Holder for the module until it's been handed off llvm::Module *m_module; ///< Owned by the execution engine diff --git a/lldb/include/lldb/Expression/Materializer.h b/lldb/include/lldb/Expression/Materializer.h index 33d56e50c2a7..524f61a0de52 100644 --- a/lldb/include/lldb/Expression/Materializer.h +++ b/lldb/include/lldb/Expression/Materializer.h @@ -25,13 +25,33 @@ class Materializer { public: Materializer (); + ~Materializer (); class Dematerializer { public: - void Dematerialize(Error &err, - lldb::addr_t frame_top, - lldb::addr_t frame_bottom); + Dematerializer () : + m_materializer(NULL), + m_map(NULL), + m_process_address(LLDB_INVALID_ADDRESS) + { + } + + ~Dematerializer () + { + Wipe (); + } + + void Dematerialize (Error &err, + lldb::addr_t frame_top, + lldb::addr_t frame_bottom); + + void Wipe (); + + bool IsValid () + { + return m_materializer && m_map && (m_process_address != LLDB_INVALID_ADDRESS); + } private: friend class Materializer; @@ -39,20 +59,23 @@ public: lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address) : - m_materializer(materializer), + m_materializer(&materializer), m_frame_wp(frame_sp), - m_map(map), + m_map(&map), m_process_address(process_address) { } - Materializer &m_materializer; + Materializer *m_materializer; lldb::StackFrameWP m_frame_wp; - IRMemoryMap &m_map; + 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); + typedef std::shared_ptr DematerializerSP; + typedef std::weak_ptr DematerializerWP; + + DematerializerSP 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); @@ -88,6 +111,7 @@ public: 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; virtual void DumpToLog (IRMemoryMap &map, lldb::addr_t process_address, Log *log) = 0; + virtual void Wipe (IRMemoryMap &map, lldb::addr_t process_address) = 0; uint32_t GetAlignment () { @@ -122,11 +146,11 @@ private: typedef std::unique_ptr EntityUP; typedef std::vector EntityVector; - unsigned m_result_index; - Mutex m_needs_dematerialize; - EntityVector m_entities; - uint32_t m_current_offset; - uint32_t m_struct_alignment; + unsigned m_result_index; + DematerializerWP m_dematerializer_wp; + EntityVector m_entities; + uint32_t m_current_offset; + uint32_t m_struct_alignment; }; } diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index c1bef43cf88c..5753918c1246 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -629,44 +629,11 @@ ClangExpressionDeclMap::DoStructLayout () if (m_struct_vars->m_struct_laid_out) return true; - if (m_parser_vars->m_materializer) - { - m_struct_vars->m_struct_alignment = m_parser_vars->m_materializer->GetStructAlignment(); - m_struct_vars->m_struct_size = m_parser_vars->m_materializer->GetStructByteSize(); - m_struct_vars->m_struct_laid_out = true; - return true; - } - - off_t cursor = 0; - - m_struct_vars->m_struct_alignment = 0; - m_struct_vars->m_struct_size = 0; - - for (size_t member_index = 0, num_members = m_struct_members.GetSize(); - member_index < num_members; - ++member_index) - { - ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index)); - if (!member_sp) - return false; - - ClangExpressionVariable::JITVars *jit_vars = member_sp->GetJITVars(GetParserID()); - - if (!jit_vars) - return false; - - if (member_index == 0) - m_struct_vars->m_struct_alignment = jit_vars->m_alignment; - - if (cursor % jit_vars->m_alignment) - cursor += (jit_vars->m_alignment - (cursor % jit_vars->m_alignment)); - - jit_vars->m_offset = cursor; - cursor += jit_vars->m_size; - } - - m_struct_vars->m_struct_size = cursor; + if (!m_parser_vars->m_materializer) + return false; + m_struct_vars->m_struct_alignment = m_parser_vars->m_materializer->GetStructAlignment(); + m_struct_vars->m_struct_size = m_parser_vars->m_materializer->GetStructByteSize(); m_struct_vars->m_struct_laid_out = true; return true; } @@ -1315,6 +1282,7 @@ ClangExpressionDeclMap::GetSpecialValue (const ConstString &name) bool ClangExpressionDeclMap::Materialize ( + IRMemoryMap &map, lldb::addr_t &struct_address, Error &err ) @@ -1326,7 +1294,8 @@ ClangExpressionDeclMap::Materialize m_material_vars->m_process = m_parser_vars->m_exe_ctx.GetProcessPtr(); - bool result = DoMaterialize(false /* dematerialize */, + bool result = DoMaterialize(false /* dematerialize */, + map, LLDB_INVALID_ADDRESS /* top of stack frame */, LLDB_INVALID_ADDRESS /* bottom of stack frame */, NULL, /* result SP */ @@ -1453,12 +1422,13 @@ bool ClangExpressionDeclMap::Dematerialize ( ClangExpressionVariableSP &result_sp, + IRMemoryMap &map, lldb::addr_t stack_frame_top, lldb::addr_t stack_frame_bottom, Error &err ) { - return DoMaterialize(true, stack_frame_top, stack_frame_bottom, &result_sp, err); + return DoMaterialize(true, map, stack_frame_top, stack_frame_bottom, &result_sp, err); DidDematerialize(); } @@ -1567,6 +1537,7 @@ bool ClangExpressionDeclMap::DoMaterialize ( bool dematerialize, + IRMemoryMap &map, lldb::addr_t stack_frame_top, lldb::addr_t stack_frame_bottom, lldb::ClangExpressionVariableSP *result_sp_ptr, @@ -1606,873 +1577,103 @@ ClangExpressionDeclMap::DoMaterialize return true; } - const SymbolContext &sym_ctx(frame->GetSymbolContext(lldb::eSymbolContextEverything)); - - if (!dematerialize) + if (!m_parser_vars->m_materializer) { - Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); - if (m_material_vars->m_materialized_location) - { - process->DeallocateMemory(m_material_vars->m_materialized_location); - m_material_vars->m_materialized_location = 0; - } + err.SetErrorString("No materializer"); - if (log) - log->PutCString("Allocating memory for materialized argument struct"); - - lldb::addr_t mem = process->AllocateMemory(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - err); - - if (mem == LLDB_INVALID_ADDRESS) - { - err.SetErrorStringWithFormat("Couldn't allocate 0x%llx bytes for materialized argument struct", - (unsigned long long)(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size)); - return false; - } - - m_material_vars->m_allocated_area = mem; - } - - m_material_vars->m_materialized_location = m_material_vars->m_allocated_area; - - if (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment) - m_material_vars->m_materialized_location += (m_struct_vars->m_struct_alignment - (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment)); - - for (uint64_t member_index = 0, num_members = m_struct_members.GetSize(); - member_index < num_members; - ++member_index) - { - ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index)); - - ClangExpressionVariable::JITVars *jit_vars = member_sp->GetJITVars(GetParserID()); - - if (!jit_vars) - { - err.SetErrorString("Variable being materialized doesn't have JIT state"); - return false; - } - - if (m_found_entities.ContainsVariable (member_sp)) - { - if (!member_sp->GetValueObject()) - { - err.SetErrorString("Variable being materialized doesn't have a frozen version"); - return false; - } - - RegisterInfo *reg_info = member_sp->GetRegisterInfo (); - if (reg_info) - { - // This is a register variable - - RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext(); - - if (!reg_ctx) - { - err.SetErrorString("Couldn't get register context"); - return false; - } - - if (!DoMaterializeOneRegister (dematerialize, - *reg_ctx, - *reg_info, - m_material_vars->m_materialized_location + jit_vars->m_offset, - err)) - return false; - } - else - { - if (!DoMaterializeOneVariable (dematerialize, - sym_ctx, - member_sp, - m_material_vars->m_materialized_location + jit_vars->m_offset, - err)) - return false; - } - } - else - { - // No need to look for presistent variables if the name doesn't start - // with with a '$' character... - if (member_sp->GetName().AsCString ("!")[0] == '$' && persistent_vars.ContainsVariable(member_sp)) - { - - if (member_sp->GetName() == m_struct_vars->m_result_name) - { - if (log) - log->PutCString("Found result member in the struct"); - - if (result_sp_ptr) - *result_sp_ptr = member_sp; - - } - - if (!DoMaterializeOnePersistentVariable (dematerialize, - member_sp, - m_material_vars->m_materialized_location + jit_vars->m_offset, - stack_frame_top, - stack_frame_bottom, - err)) - return false; - } - else - { - err.SetErrorStringWithFormat("Unexpected variable %s", member_sp->GetName().GetCString()); - return false; - } - } - } - - return true; -} - -bool -ClangExpressionDeclMap::DoMaterializeOnePersistentVariable -( - bool dematerialize, - ClangExpressionVariableSP &var_sp, - lldb::addr_t addr, - lldb::addr_t stack_frame_top, - lldb::addr_t stack_frame_bottom, - Error &err -) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - - if (!var_sp) - { - err.SetErrorString("Invalid persistent variable"); - return LLDB_INVALID_ADDRESS; - } - - const size_t pvar_byte_size = var_sp->GetByteSize(); - - uint8_t *pvar_data = var_sp->GetValueBytes(); - if (pvar_data == NULL) - { - err.SetErrorString("Persistent variable being materialized contains no data"); return false; } - Error error; - Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); - - lldb::addr_t mem; // The address of a spare memory area used to hold the persistent variable. + lldb::StackFrameSP frame_sp = frame->shared_from_this(); + ClangExpressionVariableSP result_sp; if (dematerialize) { - if (log) - log->Printf("Dematerializing persistent variable with flags 0x%hx", var_sp->m_flags); + Error dematerialize_error; - if ((var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) || - (var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference)) + bool ret = true; + + m_material_vars->m_dematerializer_sp->Dematerialize(dematerialize_error, stack_frame_top, stack_frame_bottom); + m_material_vars->m_dematerializer_sp.reset(); + + if (!dematerialize_error.Success()) { - // Get the location of the target out of the struct. - - Error read_error; - mem = process->ReadPointerFromMemory (addr, read_error); - - if (mem == LLDB_INVALID_ADDRESS) - { - err.SetErrorStringWithFormat("Couldn't read address of %s from struct: %s", var_sp->GetName().GetCString(), error.AsCString()); - return false; - } - - if (var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && - !var_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. - - var_sp->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (), - var_sp->GetTypeFromUser().GetASTContext(), - var_sp->GetTypeFromUser().GetOpaqueQualType(), - var_sp->GetName(), - mem, - eAddressTypeLoad, - pvar_byte_size); - } - - if (!var_sp->m_live_sp) - { - err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", var_sp->GetName().GetCString()); - return false; - } - - if (var_sp->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad) - { - err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", var_sp->GetName().GetCString()); - return false; - } - - if (var_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry || - var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget) - { - mem = var_sp->m_live_sp->GetValue().GetScalar().ULongLong(); - - if (log) - log->Printf("Dematerializing %s from 0x%" PRIx64 " (size = %u)", var_sp->GetName().GetCString(), (uint64_t)mem, (unsigned)pvar_byte_size); - - // Read the contents of the spare memory area - - var_sp->ValueUpdated (); - if (process->ReadMemory (mem, pvar_data, pvar_byte_size, error) != pvar_byte_size) - { - err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString()); - return false; - } - - if (stack_frame_top != LLDB_INVALID_ADDRESS && - stack_frame_bottom != LLDB_INVALID_ADDRESS && - mem >= stack_frame_bottom && - mem <= stack_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. - - var_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; - var_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation; - var_sp->m_flags &= ~ClangExpressionVariable::EVIsProgramReference; - } - - var_sp->m_flags &= ~ClangExpressionVariable::EVNeedsFreezeDry; - } - - if (var_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation && - !(var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)) - { - if (m_keep_result_in_memory) - { - var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget; - } - else - { - Error deallocate_error = process->DeallocateMemory(mem); - - if (!err.Success()) - { - err.SetErrorStringWithFormat ("Couldn't deallocate memory for %s: %s", var_sp->GetName().GetCString(), deallocate_error.AsCString()); - return false; - } - } - } + err.SetErrorStringWithFormat("Couldn't dematerialize: %s", dematerialize_error.AsCString()); + ret = false; } else { - err.SetErrorStringWithFormat("Persistent variables without separate allocations are not currently supported."); - return false; - } - } - else - { - if (log) - log->Printf("Materializing persistent variable with flags 0x%hx", var_sp->m_flags); - - if (var_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation) - { - // Allocate a spare memory area to store the persistent variable's contents. - - Error allocate_error; - - mem = process->AllocateMemory(pvar_byte_size, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - allocate_error); - - if (mem == LLDB_INVALID_ADDRESS) + Error free_error; + map.Free(m_material_vars->m_materialized_location, free_error); + if (!free_error.Success()) { - err.SetErrorStringWithFormat("Couldn't allocate a memory area to store %s: %s", var_sp->GetName().GetCString(), allocate_error.AsCString()); - return false; - } - - if (log) - log->Printf("Allocated %s (0x%" PRIx64 ") sucessfully", var_sp->GetName().GetCString(), mem); - - // Put the location of the spare memory into the live data of the ValueObject. - - var_sp->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), - var_sp->GetTypeFromUser().GetASTContext(), - var_sp->GetTypeFromUser().GetOpaqueQualType(), - var_sp->GetName(), - mem, - eAddressTypeLoad, - pvar_byte_size); - - // Clear the flag if the variable will never be deallocated. - - if (var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget) - var_sp->m_flags &= ~ClangExpressionVariable::EVNeedsAllocation; - - // Write the contents of the variable to the area. - - if (process->WriteMemory (mem, pvar_data, pvar_byte_size, error) != pvar_byte_size) - { - err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString()); - return false; + err.SetErrorStringWithFormat("Couldn't free struct from materialization: %s", free_error.AsCString()); + ret = false; } } - if ((var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && var_sp->m_live_sp) || - var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) + if (ret) { - // Now write the location of the area into the struct. - Error write_error; - if (!process->WriteScalarToMemory (addr, - var_sp->m_live_sp->GetValue().GetScalar(), - process->GetAddressByteSize(), - write_error)) + for (uint64_t member_index = 0, num_members = m_struct_members.GetSize(); + member_index < num_members; + ++member_index) { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", var_sp->GetName().GetCString(), write_error.AsCString()); - return false; + ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index)); + + if (!m_found_entities.ContainsVariable (member_sp)) + { + // No need to look for presistent variables if the name doesn't start + // with with a '$' character... + if (member_sp->GetName().AsCString ("!")[0] == '$' && persistent_vars.ContainsVariable(member_sp)) + { + if (member_sp->GetName() == m_struct_vars->m_result_name) + { + if (log) + log->PutCString("Found result member in the struct"); + + if (result_sp_ptr) + *result_sp_ptr = member_sp; + + break; + } + } + } } - - if (log) - log->Printf("Materialized %s into 0x%llx", var_sp->GetName().GetCString(), var_sp->m_live_sp->GetValue().GetScalar().ULongLong()); - } - else if (!(var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference)) - { - err.SetErrorStringWithFormat("Persistent variables without separate allocations are not currently supported."); - return false; - } - } - - return true; -} - -bool -ClangExpressionDeclMap::CreateLiveMemoryForExpressionVariable -( - Process &process, - ClangExpressionVariableSP &expr_var, - Error &err -) -{ - Error allocate_error; - TypeFromUser type(expr_var->GetTypeFromUser()); - const ConstString &name(expr_var->GetName()); - - size_t value_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType()); - size_t value_byte_size = value_bit_size % 8 ? ((value_bit_size + 8) / 8) : (value_bit_size / 8); - - Scalar val_addr (process.AllocateMemory (value_byte_size, - lldb::ePermissionsReadable | lldb::ePermissionsWritable, - allocate_error)); - - if (val_addr.ULongLong() == LLDB_INVALID_ADDRESS) - { - err.SetErrorStringWithFormat ("Couldn't allocate a memory area to store %s: %s", - name.GetCString(), - allocate_error.AsCString()); - return false; - } - - // Put the location of the spare memory into the live data of the ValueObject. - - expr_var->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), - type.GetASTContext(), - type.GetOpaqueQualType(), - name, - val_addr.ULongLong(), - eAddressTypeLoad, - value_byte_size); - - return true; -} - -bool -ClangExpressionDeclMap::DeleteLiveMemoryForExpressionVariable -( - Process &process, - ClangExpressionVariableSP &expr_var, - Error &err -) -{ - const ConstString &name(expr_var->GetName()); - - Scalar &val_addr = expr_var->m_live_sp->GetValue().GetScalar(); - - Error deallocate_error = process.DeallocateMemory(val_addr.ULongLong()); - - if (!deallocate_error.Success()) - { - err.SetErrorStringWithFormat ("Couldn't deallocate spare memory area for %s: %s", - name.GetCString(), - deallocate_error.AsCString()); - return false; - } - - expr_var->m_live_sp.reset(); - - return true; -} - -bool -ClangExpressionDeclMap::DoMaterializeOneVariable -( - bool dematerialize, - const SymbolContext &sym_ctx, - ClangExpressionVariableSP &expr_var, - lldb::addr_t addr, - Error &err -) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); - Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); - Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr(); - StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); - - ClangExpressionVariable::ParserVars *var_parser_vars = expr_var->GetParserVars(GetParserID()); - - if (!frame || !process || !target || !m_parser_vars.get() || !var_parser_vars) - { - err.SetErrorString("Necessary state for variable materialization isn't present"); - return false; - } - - // Vital information about the value - - const ConstString &name(expr_var->GetName()); - TypeFromUser type(expr_var->GetTypeFromUser()); - - VariableSP &var(var_parser_vars->m_lldb_var); - const lldb_private::Symbol *symbol = var_parser_vars->m_lldb_sym; - - bool is_reference(expr_var->m_flags & ClangExpressionVariable::EVTypeIsReference); - - std::auto_ptr location_value; - - if (var) - { - location_value.reset(GetVariableValue(var, - NULL)); - } - else if (symbol) - { - addr_t location_load_addr = GetSymbolAddress(*target, process, name, lldb::eSymbolTypeAny); - - if (location_load_addr == LLDB_INVALID_ADDRESS) - { - if (log) - err.SetErrorStringWithFormat ("Couldn't find value for global symbol %s", - name.GetCString()); } - location_value.reset(new Value); - - location_value->SetValueType(Value::eValueTypeLoadAddress); - location_value->GetScalar() = location_load_addr; + return ret; } else { - err.SetErrorStringWithFormat ("Couldn't find %s with appropriate type", - name.GetCString()); - return false; - } - - if (log) - { - StreamString my_stream_string; + Error malloc_error; - ClangASTType::DumpTypeDescription (type.GetASTContext(), - type.GetOpaqueQualType(), - &my_stream_string); + m_material_vars->m_allocated_area = LLDB_INVALID_ADDRESS; + m_material_vars->m_materialized_location = map.Malloc(m_parser_vars->m_materializer->GetStructByteSize(), + m_parser_vars->m_materializer->GetStructAlignment(), + lldb::ePermissionsReadable | lldb::ePermissionsWritable, + IRMemoryMap::eAllocationPolicyMirror, + malloc_error); - log->Printf ("%s %s with type %s", - dematerialize ? "Dematerializing" : "Materializing", - name.GetCString(), - my_stream_string.GetString().c_str()); - } - - if (!location_value.get()) - { - err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString()); - return false; - } - - // The size of the type contained in addr - - size_t value_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType()); - size_t value_byte_size = value_bit_size % 8 ? ((value_bit_size + 8) / 8) : (value_bit_size / 8); - - Value::ValueType value_type = location_value->GetValueType(); - - switch (value_type) - { - default: + if (!malloc_error.Success()) { - StreamString ss; + err.SetErrorStringWithFormat("Couldn't malloc struct for materialization: %s", malloc_error.AsCString()); - location_value->Dump(&ss); + return false; + } + + Error materialize_error; + + m_material_vars->m_dematerializer_sp = m_parser_vars->m_materializer->Materialize(frame_sp, result_sp, map, m_material_vars->m_materialized_location, materialize_error); + + if (!materialize_error.Success()) + { + err.SetErrorStringWithFormat("Couldn't materialize: %s", materialize_error.AsCString()); - err.SetErrorStringWithFormat ("%s has a value of unhandled type: %s", - name.GetCString(), - ss.GetString().c_str()); - return false; - } - break; - case Value::eValueTypeHostAddress: - { - if (dematerialize) - { - if (!DeleteLiveMemoryForExpressionVariable(*process, expr_var, err)) - return false; - } - else - { - DataExtractor value_data_extractor; - - if (location_value->GetData(value_data_extractor)) - { - if (value_byte_size != value_data_extractor.GetByteSize()) - { - err.SetErrorStringWithFormat ("Size mismatch for %s: %" PRIu64 " versus %" PRIu64, - name.GetCString(), - (uint64_t)value_data_extractor.GetByteSize(), - (uint64_t)value_byte_size); - return false; - } - - if (!CreateLiveMemoryForExpressionVariable(*process, expr_var, err)) - return false; - - Scalar &buf_addr = expr_var->m_live_sp->GetValue().GetScalar(); - - Error write_error; - - if (!process->WriteMemory(buf_addr.ULongLong(), - value_data_extractor.GetDataStart(), - value_data_extractor.GetByteSize(), - write_error)) - { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", - name.GetCString(), - write_error.AsCString()); - return false; - } - - if (!process->WriteScalarToMemory(addr, - buf_addr, - process->GetAddressByteSize(), - write_error)) - { - err.SetErrorStringWithFormat ("Couldn't write the address of %s to the target: %s", - name.GetCString(), - write_error.AsCString()); - return false; - } - } - else - { - err.SetErrorStringWithFormat ("%s is marked as a host address but doesn't contain any data", - name.GetCString()); - return false; - } - } - } - break; - case Value::eValueTypeLoadAddress: - { - if (!dematerialize) - { - Error write_error; - - if (is_reference) - { - Error read_error; - - addr_t ref_value = process->ReadPointerFromMemory(location_value->GetScalar().ULongLong(), read_error); - - if (!read_error.Success()) - { - err.SetErrorStringWithFormat ("Couldn't read reference to %s from the target: %s", - name.GetCString(), - read_error.AsCString()); - return false; - } - - if (!process->WritePointerToMemory(addr, - ref_value, - write_error)) - { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", - name.GetCString(), - write_error.AsCString()); - return false; - } - } - else - { - if (!process->WriteScalarToMemory (addr, - location_value->GetScalar(), - process->GetAddressByteSize(), - write_error)) - { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", - name.GetCString(), - write_error.AsCString()); - return false; - } - } - } - } - break; - case Value::eValueTypeScalar: - { - if (location_value->GetContextType() == Value::eContextTypeRegisterInfo) - { - RegisterInfo *reg_info = location_value->GetRegisterInfo(); - - if (!reg_info) - { - err.SetErrorStringWithFormat ("Couldn't get the register information for %s", - name.GetCString()); - return false; - } - - RegisterValue reg_value; - - RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext(); - - if (!reg_ctx) - { - err.SetErrorStringWithFormat ("Couldn't read register context to read %s from %s", - name.GetCString(), - reg_info->name); - return false; - } - - uint32_t register_byte_size = reg_info->byte_size; - - if (dematerialize) - { - if (is_reference) - return true; // reference types don't need demateralizing - - // Get the location of the spare memory area out of the variable's live data. - - if (!expr_var->m_live_sp) - { - err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", name.GetCString()); - return false; - } - - if (expr_var->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad) - { - err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", name.GetCString()); - return false; - } - - Scalar ®_addr = expr_var->m_live_sp->GetValue().GetScalar(); - - err = reg_ctx->ReadRegisterValueFromMemory (reg_info, - reg_addr.ULongLong(), - value_byte_size, - reg_value); - if (err.Fail()) - return false; - - if (!reg_ctx->WriteRegister (reg_info, reg_value)) - { - err.SetErrorStringWithFormat ("Couldn't write %s to register %s", - name.GetCString(), - reg_info->name); - return false; - } - - if (!DeleteLiveMemoryForExpressionVariable(*process, expr_var, err)) - return false; - } - else - { - Error write_error; - - RegisterValue reg_value; - - if (!reg_ctx->ReadRegister (reg_info, reg_value)) - { - err.SetErrorStringWithFormat ("Couldn't read %s from %s", - name.GetCString(), - reg_info->name); - return false; - } - - if (is_reference) - { - write_error = reg_ctx->WriteRegisterValueToMemory(reg_info, - addr, - process->GetAddressByteSize(), - reg_value); - - if (!write_error.Success()) - { - err.SetErrorStringWithFormat ("Couldn't write %s from register %s to the target: %s", - name.GetCString(), - reg_info->name, - write_error.AsCString()); - return false; - } - - return true; - } - - // Allocate a spare memory area to place the register's contents into. This memory area will be pointed to by the slot in the - // struct. - - if (!CreateLiveMemoryForExpressionVariable (*process, expr_var, err)) - return false; - - // Now write the location of the area into the struct. - - Scalar ®_addr = expr_var->m_live_sp->GetValue().GetScalar(); - - if (!process->WriteScalarToMemory (addr, - reg_addr, - process->GetAddressByteSize(), - write_error)) - { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", - name.GetCString(), - write_error.AsCString()); - return false; - } - - if (value_byte_size > register_byte_size) - { - err.SetErrorStringWithFormat ("%s is too big to store in %s", - name.GetCString(), - reg_info->name); - return false; - } - - if (!reg_ctx->ReadRegister (reg_info, reg_value)) - { - err.SetErrorStringWithFormat ("Couldn't read %s from %s", - name.GetCString(), - reg_info->name); - return false; - } - - err = reg_ctx->WriteRegisterValueToMemory (reg_info, - reg_addr.ULongLong(), - value_byte_size, - reg_value); - if (err.Fail()) - return false; - } - } - else - { - // The location_value is a scalar. We need to make space for it - // or delete the space we made previously. - if (dematerialize) - { - if (!DeleteLiveMemoryForExpressionVariable(*process, expr_var, err)) - return false; - } - else - { - DataExtractor value_data_extractor; - - if (location_value->GetData(value_data_extractor)) - { - if (value_byte_size != value_data_extractor.GetByteSize()) - { - err.SetErrorStringWithFormat ("Size mismatch for %s: %" PRIu64 " versus %" PRIu64, - name.GetCString(), - (uint64_t)value_data_extractor.GetByteSize(), - (uint64_t)value_byte_size); - return false; - } - - if (!CreateLiveMemoryForExpressionVariable(*process, expr_var, err)) - return false; - - Scalar &buf_addr = expr_var->m_live_sp->GetValue().GetScalar(); - - Error write_error; - - if (!process->WriteMemory(buf_addr.ULongLong(), - value_data_extractor.GetDataStart(), - value_data_extractor.GetByteSize(), - write_error)) - { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", - name.GetCString(), - write_error.AsCString()); - return false; - } - - if (!process->WriteScalarToMemory(addr, - buf_addr, - process->GetAddressByteSize(), - write_error)) - { - err.SetErrorStringWithFormat ("Couldn't write the address of %s to the target: %s", - name.GetCString(), - write_error.AsCString()); - return false; - } - } - else - { - err.SetErrorStringWithFormat ("%s is marked as a scalar value but doesn't contain any data", - name.GetCString()); - return false; - } - } - } - } - } - - return true; -} - -bool -ClangExpressionDeclMap::DoMaterializeOneRegister -( - bool dematerialize, - RegisterContext ®_ctx, - const RegisterInfo ®_info, - lldb::addr_t addr, - Error &err -) -{ - uint32_t register_byte_size = reg_info.byte_size; - RegisterValue reg_value; - if (dematerialize) - { - Error read_error (reg_ctx.ReadRegisterValueFromMemory(®_info, addr, register_byte_size, reg_value)); - if (read_error.Fail()) - { - err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", reg_info.name, read_error.AsCString()); return false; } - if (!reg_ctx.WriteRegister (®_info, reg_value)) - { - err.SetErrorStringWithFormat("Couldn't write register %s (dematerialize)", reg_info.name); - return false; - } + return true; } - else - { - - if (!reg_ctx.ReadRegister(®_info, reg_value)) - { - err.SetErrorStringWithFormat("Couldn't read %s (materialize)", reg_info.name); - return false; - } - - Error write_error (reg_ctx.WriteRegisterValueToMemory(®_info, addr, register_byte_size, reg_value)); - if (write_error.Fail()) - { - err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", reg_info.name, write_error.AsCString()); - return false; - } - } - - return true; } lldb::VariableSP diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp index def49f58f98e..59b00bf5f04b 100644 --- a/lldb/source/Expression/ClangExpressionParser.cpp +++ b/lldb/source/Expression/ClangExpressionParser.cpp @@ -501,7 +501,8 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr, log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName()); } - m_execution_unit.reset(new IRExecutionUnit(module_ap, // handed off here + m_execution_unit.reset(new IRExecutionUnit(m_llvm_context, // handed off here + module_ap, // handed off here function_name, exe_ctx.GetTargetSP(), m_compiler->getTargetOpts().Features)); diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index 4ecd1890e0e5..1a11b9778384 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -29,6 +29,7 @@ #include "lldb/Expression/ClangFunction.h" #include "lldb/Expression/ClangUserExpression.h" #include "lldb/Expression/ExpressionSourceCode.h" +#include "lldb/Expression/IRExecutionUnit.h" #include "lldb/Expression/Materializer.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/Block.h" @@ -551,7 +552,7 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, } } - if (!m_expr_decl_map->Materialize(struct_address, materialize_error)) + if (!m_expr_decl_map->Materialize(*m_execution_unit_ap, struct_address, materialize_error)) { error_stream.Printf("Couldn't materialize struct: %s\n", materialize_error.AsCString()); return false; @@ -654,7 +655,7 @@ ClangUserExpression::FinalizeJITExecution (Stream &error_stream, lldb::addr_t function_stack_bottom = function_stack_pointer - Host::GetPageSize(); - if (!m_expr_decl_map->Dematerialize(result, function_stack_pointer, function_stack_bottom, expr_error)) + if (!m_expr_decl_map->Dematerialize(result, *m_execution_unit_ap, function_stack_pointer, function_stack_bottom, expr_error)) { error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error")); return false; diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp index 0f7be347a1ee..206a6a394f26 100644 --- a/lldb/source/Expression/IRExecutionUnit.cpp +++ b/lldb/source/Expression/IRExecutionUnit.cpp @@ -25,11 +25,13 @@ using namespace lldb_private; -IRExecutionUnit::IRExecutionUnit (std::auto_ptr &module_ap, +IRExecutionUnit::IRExecutionUnit (std::auto_ptr &context_ap, + std::auto_ptr &module_ap, ConstString &name, const lldb::TargetSP &target_sp, std::vector &cpu_features) : IRMemoryMap(target_sp), + m_context_ap(context_ap), m_module_ap(module_ap), m_module(m_module_ap.get()), m_cpu_features(cpu_features), @@ -400,6 +402,9 @@ IRExecutionUnit::GetRunnableInfo(Error &error, IRExecutionUnit::~IRExecutionUnit () { + m_module_ap.reset(); + m_execution_engine_ap.reset(); + m_context_ap.reset(); } IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) : diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp index aff4b16f65d6..268fe3c09b2a 100644 --- a/lldb/source/Expression/IRMemoryMap.cpp +++ b/lldb/source/Expression/IRMemoryMap.cpp @@ -87,10 +87,8 @@ IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size) { AllocationMap::iterator iter = m_allocations.lower_bound (addr); - if (iter == m_allocations.end()) - return iter; - - if (iter->first > addr) + if (iter == m_allocations.end() || + iter->first > addr) { if (iter == m_allocations.begin()) return m_allocations.end(); diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp index 4a527b9d06d9..7f5400177796 100644 --- a/lldb/source/Expression/Materializer.cpp +++ b/lldb/source/Expression/Materializer.cpp @@ -67,10 +67,9 @@ public: Entity(), m_persistent_variable_sp(persistent_variable_sp) { - ClangASTType type(m_persistent_variable_sp->GetClangAST(), - m_persistent_variable_sp->GetClangType()); - - SetSizeAndAlignmentFromType(type); + // Hard-coding to maximum size of a pointer since persistent variables are materialized by reference + m_size = 8; + m_alignment = 8; } void MakeAllocation (IRMemoryMap &map, Error &err) @@ -143,7 +142,7 @@ public: } } - virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) + void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -180,14 +179,17 @@ public: } else { + // This is the result variable + /* 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) + 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) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -208,10 +210,10 @@ public: // 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; + lldb::addr_t location; Error read_error; - map.ReadScalarFromMemory(location_scalar, process_address + m_offset, map.GetAddressByteSize(), read_error); + map.ReadPointerFromMemory(&location, process_address + m_offset, read_error); if (!read_error.Success()) { @@ -219,9 +221,7 @@ public: 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(), @@ -327,6 +327,8 @@ public: DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + + dump_stream.PutChar('\n'); } } @@ -356,6 +358,8 @@ public: DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, target_address); + + dump_stream.PutChar('\n'); } } } @@ -363,7 +367,9 @@ public: log->PutCString(dump_stream.GetData()); } - + void Wipe (IRMemoryMap &map, lldb::addr_t process_address) + { + } private: lldb::ClangExpressionVariableSP m_persistent_variable_sp; }; @@ -394,7 +400,7 @@ public: m_is_reference = ClangASTContext::IsReferenceType(m_variable_sp->GetType()->GetClangForwardType()); } - virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) + void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -515,7 +521,7 @@ public: } } - virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, + 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) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -607,10 +613,12 @@ public: DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + + dump_stream.PutChar('\n'); } } - if (m_is_reference) + if (m_temporary_allocation == LLDB_INVALID_ADDRESS) { dump_stream.Printf("Points to process memory.\n"); } @@ -618,31 +626,40 @@ public: { dump_stream.Printf("Temporary allocation:\n"); - if (m_temporary_allocation == LLDB_INVALID_ADDRESS) + DataBufferHeap data (m_temporary_allocation_size, 0); + + map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err); + + if (!err.Success()) { dump_stream.Printf(" \n"); } else { - DataBufferHeap data (m_temporary_allocation_size, 0); + DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); - map.ReadMemory(data.GetBytes(), m_temporary_allocation, m_temporary_allocation_size, err); + extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); - if (!err.Success()) - { - dump_stream.Printf(" \n"); - } - else - { - DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); - - extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); - } + dump_stream.PutChar('\n'); } } log->PutCString(dump_stream.GetData()); } + + void Wipe (IRMemoryMap &map, lldb::addr_t process_address) + { + if (m_temporary_allocation != LLDB_INVALID_ADDRESS) + { + Error free_error; + + map.Free(m_temporary_allocation, free_error); + + m_temporary_allocation = LLDB_INVALID_ADDRESS; + m_temporary_allocation_size = 0; + } + + } private: lldb::VariableSP m_variable_sp; bool m_is_reference; @@ -671,11 +688,11 @@ public: SetSizeAndAlignmentFromType(m_type); } - virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) + void Materialize (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, + 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) { } @@ -688,6 +705,10 @@ public: log->PutCString(dump_stream.GetData()); } + + void Wipe (IRMemoryMap &map, lldb::addr_t process_address) + { + } private: ClangASTType m_type; bool m_keep_in_memory; @@ -715,7 +736,7 @@ public: m_alignment = 8; } - virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) + void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -759,7 +780,7 @@ public: } } - virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, + 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) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -798,11 +819,17 @@ public: DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + + dump_stream.PutChar('\n'); } } log->PutCString(dump_stream.GetData()); } + + void Wipe (IRMemoryMap &map, lldb::addr_t process_address) + { + } private: Symbol m_symbol; }; @@ -829,7 +856,7 @@ public: m_alignment = m_register_info.byte_size; } - virtual void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) + void Materialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &err) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -886,7 +913,7 @@ public: } } - virtual void Dematerialize (lldb::StackFrameSP &frame_sp, IRMemoryMap &map, lldb::addr_t process_address, + 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) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -954,11 +981,17 @@ public: DataExtractor extractor (data.GetBytes(), data.GetByteSize(), map.GetByteOrder(), map.GetAddressByteSize()); extractor.DumpHexBytes(&dump_stream, data.GetBytes(), data.GetByteSize(), 16, process_address + m_offset); + + dump_stream.PutChar('\n'); } } log->PutCString(dump_stream.GetData()); } + + void Wipe (IRMemoryMap &map, lldb::addr_t process_address) + { + } private: RegisterInfo m_register_info; }; @@ -974,25 +1007,42 @@ Materializer::AddRegister (const RegisterInfo ®ister_info, Error &err) } Materializer::Materializer () : - m_needs_dematerialize(Mutex::eMutexTypeNormal), + m_dematerializer_wp(), m_current_offset(0), m_struct_alignment(8) { } +Materializer::~Materializer () +{ + DematerializerSP dematerializer_sp = m_dematerializer_wp.lock(); + + if (dematerializer_sp) + dematerializer_sp->Wipe(); +} -Materializer::Dematerializer +Materializer::DematerializerSP Materializer::Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVariableSP &result_sp, IRMemoryMap &map, lldb::addr_t process_address, Error &error) { ExecutionContextScope *exe_scope = frame_sp.get(); - + if (!exe_scope) exe_scope = map.GetBestExecutionContextScope(); + DematerializerSP dematerializer_sp = m_dematerializer_wp.lock(); + + if (dematerializer_sp) + { + error.SetErrorToGenericError(); + error.SetErrorString("Couldn't materialize: already materialized"); + } + + DematerializerSP ret(new Dematerializer(*this, frame_sp, map, process_address)); + if (!exe_scope) { error.SetErrorToGenericError(); - error.SetErrorString("Couldn't dematerialize: target doesn't exist"); + error.SetErrorString("Couldn't materialize: target doesn't exist"); } for (EntityUP &entity_up : m_entities) @@ -1000,19 +1050,19 @@ Materializer::Materialize (lldb::StackFrameSP &frame_sp, lldb::ClangExpressionVa entity_up->Materialize(frame_sp, map, process_address, error); if (!error.Success()) - return Dematerializer (*this, frame_sp, map, LLDB_INVALID_ADDRESS); + return DematerializerSP(); } - if (Log *log =lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) + if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) { log->Printf("Materializer::Materialize (frame_sp = %p, process_address = 0x%llx) materialized:", frame_sp.get(), process_address); for (EntityUP &entity_up : m_entities) entity_up->DumpToLog(map, process_address, log); } - - m_needs_dematerialize.Lock(); - return Dematerializer (*this, frame_sp, map, process_address); + m_dematerializer_wp = ret; + + return ret; } void @@ -1020,7 +1070,13 @@ Materializer::Dematerializer::Dematerialize (Error &error, lldb::addr_t frame_to { lldb::StackFrameSP frame_sp = m_frame_wp.lock(); - ExecutionContextScope *exe_scope = m_map.GetBestExecutionContextScope(); + ExecutionContextScope *exe_scope = m_map->GetBestExecutionContextScope(); + + if (!IsValid()) + { + error.SetErrorToGenericError(); + error.SetErrorString("Couldn't dematerialize: invalid dematerializer"); + } if (!exe_scope) { @@ -1032,18 +1088,34 @@ Materializer::Dematerializer::Dematerialize (Error &error, lldb::addr_t frame_to if (Log *log =lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) { log->Printf("Materializer::Dematerialize (frame_sp = %p, process_address = 0x%llx) about to dematerialize:", frame_sp.get(), m_process_address); - for (EntityUP &entity_up : m_materializer.m_entities) - entity_up->DumpToLog(m_map, m_process_address, log); + for (EntityUP &entity_up : m_materializer->m_entities) + entity_up->DumpToLog(*m_map, m_process_address, log); } - for (EntityUP &entity_up : m_materializer.m_entities) + for (EntityUP &entity_up : m_materializer->m_entities) { - entity_up->Dematerialize (frame_sp, m_map, m_process_address, frame_top, frame_bottom, error); + entity_up->Dematerialize (frame_sp, *m_map, m_process_address, frame_top, frame_bottom, error); if (!error.Success()) break; } } - m_materializer.m_needs_dematerialize.Unlock(); + Wipe(); +} + +void +Materializer::Dematerializer::Wipe () +{ + if (!IsValid()) + return; + + for (EntityUP &entity_up : m_materializer->m_entities) + { + entity_up->Wipe (*m_map, m_process_address); + } + + m_materializer = NULL; + m_map = NULL; + m_process_address = LLDB_INVALID_ADDRESS; }