[Lldb-commits] [lldb] r281398 - Cleaned up some of the "frame diagnose" code to use Operands as currency.

Sean Callanan via lldb-commits lldb-commits at lists.llvm.org
Tue Sep 13 14:18:27 PDT 2016


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 *&register_info);
-
-  bool IsDereferenceOfRegister(StackFrame &frame,
-                               const RegisterInfo *&register_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 *&register_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 *&register_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);
     }
   }
 




More information about the lldb-commits mailing list