Author: spyffe Date: Tue Sep 13 16:18:27 2016 New Revision: 281398 URL: http://llvm.org/viewvc/llvm-project?rev=281398&view=rev Log: Cleaned up some of the "frame diagnose" code to use Operands as currency.
Also added some utility functions around Operands to make code easier and more compact to write. Modified: lldb/trunk/include/lldb/Core/Disassembler.h lldb/trunk/include/lldb/Expression/DWARFExpression.h lldb/trunk/source/Core/Disassembler.cpp lldb/trunk/source/Expression/DWARFExpression.cpp lldb/trunk/source/Target/StackFrame.cpp Modified: lldb/trunk/include/lldb/Core/Disassembler.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Disassembler.h?rev=281398&r1=281397&r2=281398&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Disassembler.h (original) +++ lldb/trunk/include/lldb/Core/Disassembler.h Tue Sep 13 16:18:27 2016 @@ -169,6 +169,13 @@ public: bool m_clobbered = false; bool IsValid() { return m_type != Type::Invalid; } + + static Operand BuildRegister(ConstString &r); + static Operand BuildImmediate(lldb::addr_t imm, bool neg); + static Operand BuildImmediate(int64_t imm); + static Operand BuildDereference(const Operand &ref); + static Operand BuildSum(const Operand &lhs, const Operand &rhs); + static Operand BuildProduct(const Operand &lhs, const Operand &rhs); }; virtual bool ParseOperands(llvm::SmallVectorImpl<Operand> &operands) { @@ -204,6 +211,27 @@ protected: } }; +namespace OperandMatchers { +std::function<bool(const Instruction::Operand &)> +MatchBinaryOp(std::function<bool(const Instruction::Operand &)> base, + std::function<bool(const Instruction::Operand &)> left, + std::function<bool(const Instruction::Operand &)> right); + +std::function<bool(const Instruction::Operand &)> +MatchUnaryOp(std::function<bool(const Instruction::Operand &)> base, + std::function<bool(const Instruction::Operand &)> child); + +std::function<bool(const Instruction::Operand &)> +MatchRegOp(const RegisterInfo &info); + +std::function<bool(const Instruction::Operand &)> MatchImmOp(int64_t imm); + +std::function<bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm); + +std::function<bool(const Instruction::Operand &)> +MatchOpType(Instruction::Operand::Type type); +} + class InstructionList { public: InstructionList(); Modified: lldb/trunk/include/lldb/Expression/DWARFExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/DWARFExpression.h?rev=281398&r1=281397&r2=281398&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/DWARFExpression.h (original) +++ lldb/trunk/include/lldb/Expression/DWARFExpression.h Tue Sep 13 16:18:27 2016 @@ -12,6 +12,7 @@ #include "lldb/Core/Address.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Disassembler.h" #include "lldb/Core/Error.h" #include "lldb/Core/Scalar.h" #include "lldb/lldb-private.h" @@ -385,11 +386,7 @@ public: const DataExtractor &debug_loc_data, lldb::offset_t offset); - bool IsRegister(StackFrame &frame, const RegisterInfo *®ister_info); - - bool IsDereferenceOfRegister(StackFrame &frame, - const RegisterInfo *®ister_info, - int64_t &offset); + bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op); protected: //------------------------------------------------------------------ Modified: lldb/trunk/source/Core/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=281398&r1=281397&r2=281398&view=diff ============================================================================== --- lldb/trunk/source/Core/Disassembler.cpp (original) +++ lldb/trunk/source/Core/Disassembler.cpp Tue Sep 13 16:18:27 2016 @@ -1320,3 +1320,116 @@ void PseudoInstruction::SetDescription(c if (description && strlen(description) > 0) m_description = description; } + +Instruction::Operand Instruction::Operand::BuildRegister(ConstString &r) { + Operand ret; + ret.m_type = Type::Register; + ret.m_register = r; + return ret; +} + +Instruction::Operand Instruction::Operand::BuildImmediate(lldb::addr_t imm, + bool neg) { + Operand ret; + ret.m_type = Type::Immediate; + ret.m_immediate = imm; + ret.m_negative = neg; + return ret; +} + +Instruction::Operand Instruction::Operand::BuildImmediate(int64_t imm) { + Operand ret; + ret.m_type = Type::Immediate; + if (imm < 0) { + ret.m_immediate = -imm; + ret.m_negative = true; + } else { + ret.m_immediate = imm; + ret.m_negative = false; + } + return ret; +} + +Instruction::Operand +Instruction::Operand::BuildDereference(const Operand &ref) { + Operand ret; + ret.m_type = Type::Dereference; + ret.m_children = {ref}; + return ret; +} + +Instruction::Operand Instruction::Operand::BuildSum(const Operand &lhs, + const Operand &rhs) { + Operand ret; + ret.m_type = Type::Sum; + ret.m_children = {lhs, rhs}; + return ret; +} + +Instruction::Operand Instruction::Operand::BuildProduct(const Operand &lhs, + const Operand &rhs) { + Operand ret; + ret.m_type = Type::Product; + ret.m_children = {lhs, rhs}; + return ret; +} + +std::function<bool(const Instruction::Operand &)> +lldb_private::OperandMatchers::MatchBinaryOp( + std::function<bool(const Instruction::Operand &)> base, + std::function<bool(const Instruction::Operand &)> left, + std::function<bool(const Instruction::Operand &)> right) { + return [base, left, right](const Instruction::Operand &op) -> bool { + return (base(op) && op.m_children.size() == 2 && + ((left(op.m_children[0]) && right(op.m_children[1])) || + (left(op.m_children[1]) && right(op.m_children[0])))); + }; +} + +std::function<bool(const Instruction::Operand &)> +lldb_private::OperandMatchers::MatchUnaryOp( + std::function<bool(const Instruction::Operand &)> base, + std::function<bool(const Instruction::Operand &)> child) { + return [base, child](const Instruction::Operand &op) -> bool { + return (base(op) && op.m_children.size() == 1 && child(op.m_children[0])); + }; +} + +std::function<bool(const Instruction::Operand &)> +lldb_private::OperandMatchers::MatchRegOp(const RegisterInfo &info) { + return [&info](const Instruction::Operand &op) { + return (op.m_type == Instruction::Operand::Type::Register && + (op.m_register == ConstString(info.name) || + op.m_register == ConstString(info.alt_name))); + }; +} + +std::function<bool(const Instruction::Operand &)> +lldb_private::OperandMatchers::MatchImmOp(int64_t imm) { + return [imm](const Instruction::Operand &op) { + return (op.m_type == Instruction::Operand::Type::Immediate && + ((op.m_negative && op.m_immediate == (uint64_t)-imm) || + (!op.m_negative && op.m_immediate == (uint64_t)imm))); + }; +} + +std::function<bool(const Instruction::Operand &)> +lldb_private::OperandMatchers::FetchImmOp(int64_t &imm) { + return [&imm](const Instruction::Operand &op) { + if (op.m_type != Instruction::Operand::Type::Immediate) { + return false; + } + if (op.m_negative) { + imm = -((int64_t)op.m_immediate); + } else { + imm = ((int64_t)op.m_immediate); + } + return true; + }; +} + +std::function<bool(const Instruction::Operand &)> +lldb_private::OperandMatchers::MatchOpType(Instruction::Operand::Type type) { + return [type](const Instruction::Operand &op) { return op.m_type == type; }; +} + Modified: lldb/trunk/source/Expression/DWARFExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=281398&r1=281397&r2=281398&view=diff ============================================================================== --- lldb/trunk/source/Expression/DWARFExpression.cpp (original) +++ lldb/trunk/source/Expression/DWARFExpression.cpp Tue Sep 13 16:18:27 2016 @@ -3305,8 +3305,10 @@ bool DWARFExpression::GetOpAndEndOffsets return true; } -bool DWARFExpression::IsRegister(StackFrame &frame, - const RegisterInfo *®ister_info) { +bool DWARFExpression::MatchesOperand(StackFrame &frame, + const Instruction::Operand &operand) { + using namespace OperandMatchers; + lldb::offset_t op_offset; lldb::offset_t end_offset; if (!GetOpAndEndOffsets(frame, op_offset, end_offset)) { @@ -3325,77 +3327,69 @@ bool DWARFExpression::IsRegister(StackFr DataExtractor opcodes = m_data; uint8_t opcode = opcodes.GetU8(&op_offset); - if (opcode >= DW_OP_reg0 && opcode <= DW_OP_breg31) { - register_info = - reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_reg0); - return register_info != nullptr; - } - switch (opcode) { - default: - return false; - case DW_OP_regx: { - uint32_t reg_num = m_data.GetULEB128(&op_offset); - register_info = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num); - return register_info != nullptr; - } - } -} + if (opcode == DW_OP_fbreg) { + int64_t offset = opcodes.GetSLEB128(&op_offset); -bool DWARFExpression::IsDereferenceOfRegister( - StackFrame &frame, const RegisterInfo *®ister_info, int64_t &offset) { - lldb::offset_t op_offset; - lldb::offset_t end_offset; - if (!GetOpAndEndOffsets(frame, op_offset, end_offset)) { - return false; - } + DWARFExpression *fb_expr = frame.GetFrameBaseExpression(nullptr); + if (!fb_expr) { + return false; + } - if (!m_data.ValidOffset(op_offset) || op_offset >= end_offset) { - return false; - } + std::function<bool(const Instruction::Operand &)> recurse = + [&frame, fb_expr](const Instruction::Operand &child) { + return fb_expr->MatchesOperand(frame, child); + }; + + if (!offset && + MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference), + recurse)(operand)) { + return true; + } - RegisterContextSP reg_ctx_sp = frame.GetRegisterContext(); - if (!reg_ctx_sp) { + return MatchUnaryOp( + MatchOpType(Instruction::Operand::Type::Dereference), + MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum), + MatchImmOp(offset), recurse))(operand); + } + + bool dereference = false; + const RegisterInfo *reg = nullptr; + int64_t offset = 0; + + if (opcode >= DW_OP_reg0 && opcode <= DW_OP_reg31) { + reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_reg0); + } else if (opcode >= DW_OP_breg0 && opcode <= DW_OP_breg31) { + offset = opcodes.GetSLEB128(&op_offset); + reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, opcode - DW_OP_breg0); + } else if (opcode == DW_OP_regx) { + uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset)); + reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num); + } else if (opcode == DW_OP_bregx) { + uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset)); + offset = opcodes.GetSLEB128(&op_offset); + reg = reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num); + } else { return false; } - DataExtractor opcodes = m_data; - uint8_t opcode = opcodes.GetU8(&op_offset); - - switch (opcode) { - default: + if (!reg) { return false; - case DW_OP_bregx: { - uint32_t reg_num = static_cast<uint32_t>(opcodes.GetULEB128(&op_offset)); - int64_t breg_offset = opcodes.GetSLEB128(&op_offset); - - const RegisterInfo *reg_info = - reg_ctx_sp->GetRegisterInfo(m_reg_kind, reg_num); - if (!reg_info) { - return false; - } - - register_info = reg_info; - offset = breg_offset; - return true; } - case DW_OP_fbreg: { - int64_t fbreg_offset = opcodes.GetSLEB128(&op_offset); - - DWARFExpression *dwarf_expression = frame.GetFrameBaseExpression(nullptr); - if (!dwarf_expression) { - return false; + if (dereference) { + if (!offset && + MatchUnaryOp(MatchOpType(Instruction::Operand::Type::Dereference), + MatchRegOp(*reg))(operand)) { + return true; } - const RegisterInfo *fbr_info; - - if (!dwarf_expression->IsRegister(frame, fbr_info)) { - return false; - } - - register_info = fbr_info; - offset = fbreg_offset; - return true; - } + return MatchUnaryOp( + MatchOpType(Instruction::Operand::Type::Dereference), + MatchBinaryOp(MatchOpType(Instruction::Operand::Type::Sum), + MatchRegOp(*reg), + MatchImmOp(offset)))(operand); + } else { + return MatchRegOp(*reg)(operand); } } + Modified: lldb/trunk/source/Target/StackFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=281398&r1=281397&r2=281398&view=diff ============================================================================== --- lldb/trunk/source/Target/StackFrame.cpp (original) +++ lldb/trunk/source/Target/StackFrame.cpp Tue Sep 13 16:18:27 2016 @@ -1489,21 +1489,19 @@ lldb::ValueObjectSP DoGuessValueAt(Stack // First, check the variable list to see if anything is at the specified // location. - for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi) { - VariableSP var_sp = variables.GetVariableAtIndex(vi); - DWARFExpression &dwarf_expression = var_sp->LocationExpression(); - const RegisterInfo *expression_reg; - int64_t expression_offset; - ExecutionContext exe_ctx; + Instruction::Operand op = + offset ? Instruction::Operand::BuildDereference( + Instruction::Operand::BuildSum( + Instruction::Operand::BuildRegister(reg), + Instruction::Operand::BuildImmediate(offset))) + : Instruction::Operand::BuildDereference( + Instruction::Operand::BuildRegister(reg)); - if (dwarf_expression.IsDereferenceOfRegister(frame, expression_reg, - expression_offset)) { - if ((reg == ConstString(expression_reg->name) || - reg == ConstString(expression_reg->alt_name)) && - expression_offset == offset) { - return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues); - } + for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi) { + VariableSP var_sp = variables.GetVariableAtIndex(vi); + if (var_sp->LocationExpression().MatchesOperand(frame, op)) { + return frame.GetValueObjectForFrameVariable(var_sp, eNoDynamicValues); } } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits