diff options
| author | Sean Callanan <scallanan@apple.com> | 2010-11-30 00:27:43 +0000 |
|---|---|---|
| committer | Sean Callanan <scallanan@apple.com> | 2010-11-30 00:27:43 +0000 |
| commit | 348b5897f94a856044cab9a241e889013a8611cc (patch) | |
| tree | 8070b4d713419013d95954b08751ab52d621be15 /lldb | |
| parent | 027bd47e3ec8fa6dc7948fdab92e58f395b34653 (diff) | |
| download | bcm5719-llvm-348b5897f94a856044cab9a241e889013a8611cc.tar.gz bcm5719-llvm-348b5897f94a856044cab9a241e889013a8611cc.zip | |
Added a feature where registers can be referred to
using special $-variables from expressions.
(lldb) expr $rip
These variables are available for reading and
writing.
llvm-svn: 120367
Diffstat (limited to 'lldb')
| -rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionDeclMap.h | 46 | ||||
| -rw-r--r-- | lldb/include/lldb/Expression/ClangExpressionVariable.h | 9 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangASTSource.cpp | 2 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 147 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangExpressionVariable.cpp | 1 |
5 files changed, 197 insertions, 8 deletions
diff --git a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h index 140a345b8be..2c4d0c5ce45 100644 --- a/lldb/include/lldb/Expression/ClangExpressionDeclMap.h +++ b/lldb/include/lldb/Expression/ClangExpressionDeclMap.h @@ -491,6 +491,18 @@ private: //------------------------------------------------------------------ /// Use the NameSearchContext to generate a Decl for the given + /// register. + /// + /// @param[in] context + /// The NameSearchContext to use when constructing the Decl. + /// + /// @param[in] reg_info + /// The information corresponding to that register. + //------------------------------------------------------------------ + void AddOneRegister(NameSearchContext &context, const lldb::RegisterInfo *reg_info); + + //------------------------------------------------------------------ + /// Use the NameSearchContext to generate a Decl for the given /// type. (Types are not placed in the Tuple list.) /// /// @param[in] context @@ -605,6 +617,40 @@ private: 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] exe_ctx + /// The execution context to use. + /// + /// @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, + ExecutionContext &exe_ctx, + RegisterContext ®_ctx, + const lldb::RegisterInfo ®_info, + lldb::addr_t addr, + Error &err); + + //------------------------------------------------------------------ /// A wrapper for ClangASTContext::CopyType that sets a flag that /// indicates that we should not respond to queries during import. /// diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h index 6fe345aa619..516f596b02a 100644 --- a/lldb/include/lldb/Expression/ClangExpressionVariable.h +++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h @@ -20,6 +20,7 @@ // Other libraries and framework includes // Project includes +#include "lldb/lldb-types.h" #include "lldb/Core/ClangForward.h" #include "lldb/Core/ConstString.h" #include "lldb/Symbol/TaggedASTType.h" @@ -89,9 +90,11 @@ struct ClangExpressionVariable //---------------------------------------------------------------------- /// The following values should stay valid for the life of the variable //---------------------------------------------------------------------- - ConstString m_name; ///< The name of the variable - TypeFromUser m_user_type; ///< The type of the variable according to some LLDB context; - ///< NULL if the type hasn't yet been migrated to one + ConstString m_name; ///< The name of the variable + TypeFromUser m_user_type; ///< The type of the variable according to some LLDB context; + ///< NULL if the type hasn't yet been migrated to one + + const lldb::RegisterInfo *m_register_info; ///< if non-NULL, LLDB's information for the register this value is stored in. Only used for register values //---------------------------------------------------------------------- /// The following values indicate where the variable originally came from diff --git a/lldb/source/Expression/ClangASTSource.cpp b/lldb/source/Expression/ClangASTSource.cpp index e808a04386b..95a35b9b098 100644 --- a/lldb/source/Expression/ClangASTSource.cpp +++ b/lldb/source/Expression/ClangASTSource.cpp @@ -132,6 +132,8 @@ clang::ASTContext *NameSearchContext::GetASTContext() { clang::NamedDecl *NameSearchContext::AddVarDecl(void *type) { IdentifierInfo *ii = m_decl_name.getAsIdentifierInfo(); + + assert (type && "Type for variable must be non-NULL!"); clang::NamedDecl *Decl = VarDecl::Create(m_ast_source.m_ast_context, const_cast<DeclContext*>(m_decl_context), diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index b6427cc7c08..e77a3083d52 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -584,11 +584,26 @@ ClangExpressionDeclMap::DoMaterialize if (entity) { - if (!member.m_jit_vars.get()) - return false; - - if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name, member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err)) - return false; + if (entity->m_register_info) + { + // This is a register variable + + RegisterContext *reg_ctx = exe_ctx->GetRegisterContext(); + + if (!reg_ctx) + return false; + + if (!DoMaterializeOneRegister(dematerialize, *exe_ctx, *reg_ctx, *entity->m_register_info, m_materialized_location + member.m_jit_vars->m_offset, err)) + return false; + } + else + { + if (!member.m_jit_vars.get()) + return false; + + if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name, member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err)) + return false; + } } else if (persistent_variable) { @@ -917,6 +932,72 @@ ClangExpressionDeclMap::DoMaterializeOneVariable return true; } +bool +ClangExpressionDeclMap::DoMaterializeOneRegister +( + bool dematerialize, + ExecutionContext &exe_ctx, + RegisterContext ®_ctx, + const lldb::RegisterInfo ®_info, + lldb::addr_t addr, + Error &err +) +{ + uint32_t register_number = reg_info.kinds[lldb::eRegisterKindLLDB]; + uint32_t register_byte_size = reg_info.byte_size; + + Error error; + + if (dematerialize) + { + DataBufferHeap register_data (register_byte_size, 0); + + Error error; + if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes(), register_byte_size, error) != register_byte_size) + { + err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", reg_info.name, error.AsCString()); + return false; + } + + DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize()); + + if (!reg_ctx.WriteRegisterBytes(register_number, register_extractor, 0)) + { + err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name); + return false; + } + } + else + { + DataExtractor register_extractor; + + if (!reg_ctx.ReadRegisterBytes(register_number, register_extractor)) + { + err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name); + return false; + } + + uint32_t register_offset = 0; + + const void *register_data = register_extractor.GetData(®ister_offset, register_byte_size); + + if (!register_data) + { + err.SetErrorStringWithFormat("Read but couldn't extract data for %s", reg_info.name); + return false; + } + + Error error; + if (exe_ctx.process->WriteMemory (addr, register_data, register_byte_size, error) != register_byte_size) + { + err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString()); + return false; + } + } + + return true; +} + Variable * ClangExpressionDeclMap::FindVariableInScope ( @@ -1121,7 +1202,20 @@ ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name)); if (pvar) + { AddOneVariable(context, pvar); + return; + } + + const char *reg_name(&name.GetCString()[1]); + + if (m_exe_ctx.GetRegisterContext()) + { + const lldb::RegisterInfo *reg_info(m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(reg_name)); + + if (reg_info) + AddOneRegister(context, reg_info); + } } lldb::TypeSP type_sp (m_sym_ctx.FindTypeByName (name)); @@ -1338,6 +1432,49 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, } } +void +ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, + const RegisterInfo *reg_info) +{ + lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); + + void *ast_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(context.GetASTContext(), + reg_info->encoding, + reg_info->byte_size * 8); + + if (!ast_type) + { + log->Printf("Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str()); + return; + } + + TypeFromParser parser_type(ast_type, + context.GetASTContext()); + + NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType()); + + ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable())); + std::string decl_name(context.m_decl_name.getAsString()); + entity.m_name.SetCString (decl_name.c_str()); + entity.m_register_info = reg_info; + + entity.EnableParserVars(); + entity.m_parser_vars->m_parser_type = parser_type; + entity.m_parser_vars->m_named_decl = var_decl; + entity.m_parser_vars->m_llvm_value = NULL; + entity.m_parser_vars->m_lldb_value = NULL; + + if (log) + { + std::string var_decl_print_string; + llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string); + var_decl->print(var_decl_print_stream); + var_decl_print_stream.flush(); + + log->Printf("Added register %s, returned %s", context.m_decl_name.getAsString().c_str(), var_decl_print_string.c_str()); + } +} + clang::NamespaceDecl * ClangExpressionDeclMap::AddNamespace (NameSearchContext &context, const ClangNamespaceDecl &namespace_decl) { diff --git a/lldb/source/Expression/ClangExpressionVariable.cpp b/lldb/source/Expression/ClangExpressionVariable.cpp index d1ae1d5c8ca..6a78363c2be 100644 --- a/lldb/source/Expression/ClangExpressionVariable.cpp +++ b/lldb/source/Expression/ClangExpressionVariable.cpp @@ -29,6 +29,7 @@ ClangExpressionVariable::ClangExpressionVariable() : m_name(), m_user_type (TypeFromUser(NULL, NULL)), m_store (NULL), + m_register_info (NULL), m_index (0), m_parser_vars(), m_jit_vars (), |

