persona0220 created this revision.
persona0220 added reviewers: wallace, jj10306.
Herald added a project: All.
persona0220 requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

To build complex binding upon instruction trace, additional metadata 
'instruction type' is needed.

This diff has followings:

- Add a flag -k  / --kind for instruction dump
- Remove SetGranularity and SetIgnoreErros from Trace cursor

Sample output:

  (lldb) thread trace dump instruction -k
  thread #1: tid = 3198805
    libc.so.6`_IO_puts + 356
      2107: 0x00007ffff7163594 (    return)     retq
      2106: 0x00007ffff7163592 (     other)     popq   %r13
      2105: 0x00007ffff7163590 (     other)     popq   %r12
      2104: 0x00007ffff716358f (     other)     popq   %rbp
      2103: 0x00007ffff716358e (     other)     popq   %rbx
      2102: 0x00007ffff716358c (     other)     movl   %ebx, %eax
      2101: 0x00007ffff7163588 (     other)     addq   $0x8, %rsp
      2100: 0x00007ffff7163570 ( cond jump)     je     0x89588                  
 ; <+344>
      2099: 0x00007ffff716356e (     other)     decl   (%rdx)
      2098: 0x00007ffff7163565 ( cond jump)     je     0x8956e                  
 ; <+318>
      2097: 0x00007ffff716355e (     other)     cmpl   $0x0, 0x33c02b(%rip)     
 ; __libc_multiple_threads
      2096: 0x00007ffff7163556 (     other)     movq   $0x0, 0x8(%rdx)
      2095: 0x00007ffff7163554 ( cond jump)     jne    0x89588                  
 ; <+344>
      2094: 0x00007ffff7163550 (     other)     subl   $0x1, 0x4(%rdx)
      2093: 0x00007ffff7163549 (     other)     movq   0x88(%rbp), %rdx
      2092: 0x00007ffff7163547 ( cond jump)     jne    0x89588                  
 ; <+344>
      2091: 0x00007ffff7163540 (     other)     testl  $0x8000, (%rbp)          
 ; imm = 0x8000
      2090: 0x00007ffff716353c (     other)     cmovaq %rax, %rbx
      2089: 0x00007ffff7163535 (     other)     cmpq   $0x7fffffff, %rbx        
 ; imm = 0x7FFFFFFF
      2088: 0x00007ffff7163530 (     other)     movl   $0x7fffffff, %eax        
 ; imm = 0x7FFFFFFF


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128477

Files:
  lldb/include/lldb/Target/TraceCursor.h
  lldb/include/lldb/Target/TraceInstructionDumper.h
  lldb/include/lldb/lldb-enumerations.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Commands/Options.td
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
  lldb/source/Target/TraceCursor.cpp
  lldb/source/Target/TraceInstructionDumper.cpp

Index: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
+++ lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
@@ -46,10 +46,7 @@
     if (m_tsc_range && !m_tsc_range->InRange(m_pos))
       m_tsc_range = IsForwards() ? m_tsc_range->Next() : m_tsc_range->Prev();
 
-    if (!m_ignore_errors && IsError())
-      return true;
-    if (GetInstructionControlFlowType() & m_granularity)
-      return true;
+    return true;
   }
 
   // Didn't find any matching instructions
Index: lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
+++ lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
@@ -62,31 +62,34 @@
 TraceInstructionControlFlowType
 DecodedThread::GetInstructionControlFlowType(size_t insn_index) const {
   if (IsInstructionAnError(insn_index))
-    return (TraceInstructionControlFlowType)0;
+    return eTraceInstructionControlFlowTypeError;
 
   TraceInstructionControlFlowType mask =
       eTraceInstructionControlFlowTypeInstruction;
 
-  lldb::addr_t load_address = m_instruction_ips[insn_index];
-  uint8_t insn_byte_size = m_instruction_sizes[insn_index];
   pt_insn_class iclass = m_instruction_classes[insn_index];
 
   switch (iclass) {
-  case ptic_cond_jump:
-  case ptic_jump:
-  case ptic_far_jump:
-    mask |= eTraceInstructionControlFlowTypeBranch;
-    if (insn_index + 1 < m_instruction_ips.size() &&
-        load_address + insn_byte_size != m_instruction_ips[insn_index + 1])
-      mask |= eTraceInstructionControlFlowTypeTakenBranch;
+  case ptic_call:
+    mask |= eTraceInstructionControlFlowTypeCall;
     break;
   case ptic_return:
-  case ptic_far_return:
     mask |= eTraceInstructionControlFlowTypeReturn;
     break;
-  case ptic_call:
+  case ptic_jump:
+    mask |= eTraceInstructionControlFlowTypeJump;
+    break;
+  case ptic_cond_jump:
+    mask |= eTraceInstructionControlFlowTypeCondJump;
+    break;
   case ptic_far_call:
-    mask |= eTraceInstructionControlFlowTypeCall;
+    mask |= eTraceInstructionControlFlowTypeFarCall;
+    break;
+  case ptic_far_return:
+    mask |= eTraceInstructionControlFlowTypeFarReturn;
+    break;
+  case ptic_far_jump:
+    mask |= eTraceInstructionControlFlowTypeFarJump;
     break;
   default:
     break;
Index: lldb/source/Target/TraceCursor.cpp
===================================================================
--- lldb/source/Target/TraceCursor.cpp
+++ lldb/source/Target/TraceCursor.cpp
@@ -21,15 +21,6 @@
   return m_exe_ctx_ref;
 }
 
-void TraceCursor::SetGranularity(
-    lldb::TraceInstructionControlFlowType granularity) {
-  m_granularity = granularity;
-}
-
-void TraceCursor::SetIgnoreErrors(bool ignore_errors) {
-  m_ignore_errors = ignore_errors;
-}
-
 void TraceCursor::SetForwards(bool forwards) { m_forwards = forwards; }
 
 bool TraceCursor::IsForwards() const { return m_forwards; }
Index: lldb/include/lldb/lldb-enumerations.h
===================================================================
--- lldb/include/lldb/lldb-enumerations.h
+++ lldb/include/lldb/lldb-enumerations.h
@@ -965,17 +965,27 @@
 ///
 /// A single instruction can match one or more of these categories.
 FLAGS_ENUM(TraceInstructionControlFlowType){
-    /// Any instruction.
+    /// The instruction could not be classified.
+    eTraceInstructionControlFlowTypeError = 0,
+    /// The instruction is something not listed below.
     eTraceInstructionControlFlowTypeInstruction = (1u << 1),
-    /// A conditional or unconditional branch/jump.
-    eTraceInstructionControlFlowTypeBranch = (1u << 2),
-    /// A conditional or unconditional branch/jump that changed
-    /// the control flow of the program.
-    eTraceInstructionControlFlowTypeTakenBranch = (1u << 3),
-    /// A call to a function.
-    eTraceInstructionControlFlowTypeCall = (1u << 4),
-    /// A return from a function.
-    eTraceInstructionControlFlowTypeReturn = (1u << 5)};
+    /// The instruction is a near (function) call.
+    eTraceInstructionControlFlowTypeCall = (1u << 2),
+    /// The instruction is a near (function) return.
+    eTraceInstructionControlFlowTypeReturn = (1u << 3),
+    /// The instruction is a near unconditional jump.
+    eTraceInstructionControlFlowTypeJump = (1u << 4),
+    /// The instruction is a near conditional jump.
+    eTraceInstructionControlFlowTypeCondJump = (1u << 5),
+    /// The instruction is a call-like far transfer.
+    /// E.g. SYSCALL, SYSENTER, or FAR CALL.
+    eTraceInstructionControlFlowTypeFarCall = (1u << 6),
+    /// The instruction is a return-like far transfer.
+    /// E.g. SYSRET, SYSEXIT, IRET, or FAR RET.
+    eTraceInstructionControlFlowTypeFarReturn = (1u << 7),
+    /// The instruction is a jump-like far transfer.
+    /// E.g. FAR JMP.
+    eTraceInstructionControlFlowTypeFarJump = (1u << 8)};
 
 LLDB_MARK_AS_BITMASK_ENUM(TraceInstructionControlFlowType)
 
Index: lldb/source/Commands/Options.td
===================================================================
--- lldb/source/Commands/Options.td
+++ lldb/source/Commands/Options.td
@@ -1128,6 +1128,8 @@
     Group<1>,
     Desc<"Dump only instruction address without disassembly nor symbol "
     "information.">;
+  def thread_trace_dump_instructions_show_kind : Option<"kind", "k">, Group<1>,
+    Desc<"For each instruction, print the instruction type">;
   def thread_trace_dump_instructions_show_tsc : Option<"tsc", "t">, Group<1>,
     Desc<"For each instruction, print the corresponding timestamp counter if "
     "available.">;
Index: lldb/source/Commands/CommandObjectThread.cpp
===================================================================
--- lldb/source/Commands/CommandObjectThread.cpp
+++ lldb/source/Commands/CommandObjectThread.cpp
@@ -2156,6 +2156,10 @@
         m_dumper_options.forwards = true;
         break;
       }
+      case 'k': {
+        m_dumper_options.show_kind = true;
+        break;
+      }
       case 't': {
         m_dumper_options.show_tsc = true;
         break;
Index: lldb/include/lldb/Target/TraceInstructionDumper.h
===================================================================
--- lldb/include/lldb/Target/TraceInstructionDumper.h
+++ lldb/include/lldb/Target/TraceInstructionDumper.h
@@ -36,6 +36,8 @@
   /// Dump only instruction addresses without disassembly nor symbol
   /// information.
   bool raw = false;
+  /// For each instruction, print the instruction type.
+  bool show_kind = false;
   /// For each instruction, print the corresponding timestamp counter if
   /// available.
   bool show_tsc = false;
@@ -100,6 +102,8 @@
 
   void PrintInstructionHeader();
 
+  void PrintInstructionType();
+
   void DumpInstructionDisassembly(const InstructionSymbolInfo &insn);
 
   /// Dump the symbol context of the given instruction address if it's different
Index: lldb/include/lldb/Target/TraceCursor.h
===================================================================
--- lldb/include/lldb/Target/TraceCursor.h
+++ lldb/include/lldb/Target/TraceCursor.h
@@ -40,18 +40,13 @@
 ///
 /// Defaults:
 ///   By default, the cursor points at the end item of the trace, moves
-///   backwards, has a move granularity of \a
-///   eTraceInstructionControlFlowTypeInstruction (i.e. visit every instruction)
-///   and stops at every error (the "ignore errors" flag is \b false). See the
-///   \a TraceCursor::Next() method for more documentation.
+///   backwards, and stops at every error.
+//    See the \a TraceCursor::Next() method for more documentation.
 ///
 /// Sample usage:
 ///
 ///  TraceCursorUP cursor = trace.GetTrace(thread);
 ///
-///  cursor->SetGranularity(eTraceInstructionControlFlowTypeCall |
-///    eTraceInstructionControlFlowTypeReturn);
-///
 ///  do {
 ///     if (llvm::Error error = cursor->GetError())
 ///       cout << "error found at: " << llvm::toString(error) << endl;
@@ -66,8 +61,8 @@
 ///  } while(cursor->Next());
 ///
 /// Low level traversal:
-///   Unlike the \a TraceCursor::Next() API, which uses a given granularity and
-///   direction to advance the cursor, the \a TraceCursor::Seek() method can be
+///   Unlike the \a TraceCursor::Next() API, which direction to advance
+//    the cursor, the \a TraceCursor::Seek() method can be
 ///   used to reposition the cursor to an offset of the end, beginning, or
 ///   current position of the trace.
 class TraceCursor {
@@ -90,12 +85,6 @@
 
   virtual ~TraceCursor() = default;
 
-  /// Set the granularity to use in the \a TraceCursor::Next() method.
-  void SetGranularity(lldb::TraceInstructionControlFlowType granularity);
-
-  /// Set the "ignore errors" flag to use in the \a TraceCursor::Next() method.
-  void SetIgnoreErrors(bool ignore_errors);
-
   /// Set the direction to use in the \a TraceCursor::Next() method.
   ///
   /// \param[in] forwards
@@ -109,8 +98,7 @@
   ///     \b true if the current direction is forwards, \b false if backwards.
   bool IsForwards() const;
 
-  /// Move the cursor to the next instruction that matches the current
-  /// granularity.
+  /// Move the cursor to the next instruction
   ///
   /// Direction:
   ///     The traversal is done following the current direction of the trace. If
@@ -119,17 +107,6 @@
   ///     the opposite direction. By default, a cursor moves backwards unless
   ///     changed with \a TraceCursor::SetForwards().
   ///
-  /// Granularity:
-  ///     The cursor will traverse the trace looking for the first instruction
-  ///     that matches the current granularity. If there aren't any matching
-  ///     instructions, the cursor won't move, to give the opportunity of
-  ///     changing granularities.
-  ///
-  /// Ignore errors:
-  ///     If the "ignore errors" flags is \b false, the traversal will stop as
-  ///     soon as it finds an error in the trace and the cursor will point at
-  ///     it.
-  ///
   /// \return
   ///     \b true if the cursor effectively moved, \b false otherwise.
   virtual bool Next() = 0;
@@ -256,9 +233,6 @@
 protected:
   ExecutionContextRef m_exe_ctx_ref;
 
-  lldb::TraceInstructionControlFlowType m_granularity =
-      lldb::eTraceInstructionControlFlowTypeInstruction;
-  bool m_ignore_errors = false;
   bool m_forwards = false;
 };
 
Index: lldb/source/Target/TraceInstructionDumper.cpp
===================================================================
--- lldb/source/Target/TraceInstructionDumper.cpp
+++ lldb/source/Target/TraceInstructionDumper.cpp
@@ -168,6 +168,47 @@
   }
 }
 
+void TraceInstructionDumper::PrintInstructionType() {
+  if (m_options.show_kind) {
+    m_s << " (";
+
+    if (m_cursor_up->GetInstructionControlFlowType() ==
+        eTraceInstructionControlFlowTypeError) {
+      m_s.Format("{0,10}", "error) ");
+      return;
+    }
+
+    switch (m_cursor_up->GetInstructionControlFlowType() ^
+            eTraceInstructionControlFlowTypeInstruction) {
+    case eTraceInstructionControlFlowTypeCall:
+      m_s.Format("{0,10}", "call");
+      break;
+    case eTraceInstructionControlFlowTypeReturn:
+      m_s.Format("{0,10}", "return");
+      break;
+    case eTraceInstructionControlFlowTypeJump:
+      m_s.Format("{0,10}", "jump");
+      break;
+    case eTraceInstructionControlFlowTypeCondJump:
+      m_s.Format("{0,10}", "cond jump");
+      break;
+    case eTraceInstructionControlFlowTypeFarCall:
+      m_s.Format("{0,10}", "far call");
+      break;
+    case eTraceInstructionControlFlowTypeFarReturn:
+      m_s.Format("{0,10}", "far return");
+      break;
+    case eTraceInstructionControlFlowTypeFarJump:
+      m_s.Format("{0,10}", "far jump");
+      break;
+    default:
+      m_s.Format("{0,10}", "other");
+      break;
+    }
+    m_s << ") ";
+  }
+}
+
 void TraceInstructionDumper::PrintEvents() {
   if (!m_options.show_events)
     return;
@@ -288,6 +329,7 @@
 
       PrintInstructionHeader();
       m_s.Format("{0:x+16}", m_cursor_up->GetLoadAddress());
+      PrintInstructionType();
 
       if (!m_options.raw)
         DumpInstructionDisassembly(insn_info);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to