persona0220 updated this revision to Diff 440808.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128477/new/

https://reviews.llvm.org/D128477

Files:
  lldb/include/lldb/Core/Disassembler.h
  lldb/include/lldb/Target/TraceCursor.h
  lldb/include/lldb/Target/TraceInstructionDumper.h
  lldb/include/lldb/lldb-enumerations.h
  lldb/source/API/SBInstruction.cpp
  lldb/source/API/SBInstructionList.cpp
  lldb/source/Commands/CommandObjectDisassemble.cpp
  lldb/source/Commands/CommandObjectDisassemble.h
  lldb/source/Commands/CommandObjectThread.cpp
  lldb/source/Commands/Options.td
  lldb/source/Core/Disassembler.cpp
  lldb/source/Core/DumpDataExtractor.cpp
  lldb/source/Expression/IRExecutionUnit.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.cpp
  lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
  lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.cpp
  lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h
  lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp
  
lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
  lldb/source/Symbol/Function.cpp
  lldb/source/Symbol/Symbol.cpp
  lldb/source/Target/ThreadPlanTracer.cpp
  lldb/source/Target/TraceCursor.cpp
  lldb/source/Target/TraceInstructionDumper.cpp

Index: lldb/source/Target/TraceInstructionDumper.cpp
===================================================================
--- lldb/source/Target/TraceInstructionDumper.cpp
+++ lldb/source/Target/TraceInstructionDumper.cpp
@@ -151,6 +151,7 @@
         insn.symbol_info->instruction->Dump(&m_s, /*max_opcode_byte_size=*/0,
                                             /*show_address=*/false,
                                             /*show_bytes=*/false,
+                                            /*show_kind=*/m_options.show_kind,
                                             &insn.symbol_info->exe_ctx,
                                             &insn.symbol_info->sc,
                                             /*prev_sym_ctx=*/nullptr,
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/source/Target/ThreadPlanTracer.cpp
===================================================================
--- lldb/source/Target/ThreadPlanTracer.cpp
+++ lldb/source/Target/ThreadPlanTracer.cpp
@@ -170,12 +170,13 @@
       if (instruction_list.GetSize()) {
         const bool show_bytes = true;
         const bool show_address = true;
+        const bool show_kind = true;
         Instruction *instruction =
             instruction_list.GetInstructionAtIndex(0).get();
         const FormatEntity::Entry *disassemble_format =
             m_process.GetTarget().GetDebugger().GetDisassemblyFormat();
         instruction->Dump(stream, max_opcode_byte_size, show_address,
-                          show_bytes, nullptr, nullptr, nullptr,
+                          show_bytes, show_kind, nullptr, nullptr, nullptr,
                           disassemble_format, 0);
       }
     }
Index: lldb/source/Symbol/Symbol.cpp
===================================================================
--- lldb/source/Symbol/Symbol.cpp
+++ lldb/source/Symbol/Symbol.cpp
@@ -558,8 +558,9 @@
   if (disassembler_sp) {
     const bool show_address = true;
     const bool show_bytes = false;
+    const bool show_kind = false;
     disassembler_sp->GetInstructionList().Dump(&strm, show_address, show_bytes,
-                                               &exe_ctx);
+                                               show_kind, &exe_ctx);
     return true;
   }
   return false;
Index: lldb/source/Symbol/Function.cpp
===================================================================
--- lldb/source/Symbol/Function.cpp
+++ lldb/source/Symbol/Function.cpp
@@ -440,8 +440,9 @@
   if (disassembler_sp) {
     const bool show_address = true;
     const bool show_bytes = false;
+    const bool show_kind = false;
     disassembler_sp->GetInstructionList().Dump(&strm, show_address, show_bytes,
-                                               &exe_ctx);
+                                               show_kind, &exe_ctx);
     return true;
   }
   return false;
Index: lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
===================================================================
--- lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
+++ lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
@@ -83,6 +83,7 @@
       const uint32_t addr_byte_size = m_arch.GetAddressByteSize();
       const bool show_address = true;
       const bool show_bytes = true;
+      const bool show_kind = true;
       m_inst_emulator_up->GetRegisterInfo(unwind_plan.GetRegisterKind(),
                                           unwind_plan.GetInitialCFARegister(),
                                           m_cfa_reg_info);
@@ -244,7 +245,8 @@
               lldb_private::FormatEntity::Entry format;
               FormatEntity::Parse("${frame.pc}: ", format);
               inst->Dump(&strm, inst_list.GetMaxOpcocdeByteSize(), show_address,
-                         show_bytes, nullptr, nullptr, nullptr, &format, 0);
+                         show_bytes, show_kind, nullptr, nullptr, nullptr,
+                         &format, 0);
               log->PutString(strm.GetString());
             }
 
Index: lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp
===================================================================
--- lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp
+++ lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp
@@ -157,14 +157,13 @@
       more_data_in_trace = cursor.Next();
     } else {
       lldb::addr_t current_instruction_load_address = cursor.GetLoadAddress();
-      lldb::TraceInstructionControlFlowType current_instruction_type =
+      lldb::InstructionControlFlowType current_instruction_type =
           cursor.GetInstructionControlFlowType();
 
       m_instruction_layer_up->AppendInstruction(
           current_instruction_load_address);
       more_data_in_trace = cursor.Next();
-      if (current_instruction_type &
-          lldb::eTraceInstructionControlFlowTypeCall) {
+      if (current_instruction_type & lldb::eInstructionControlFlowTypeCall) {
         if (more_data_in_trace && !cursor.IsError()) {
           m_instruction_layer_up->AddCallInstructionMetadata(
               current_instruction_load_address,
Index: lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h
+++ lldb/source/Plugins/Trace/intel-pt/TraceCursorIntelPT.h
@@ -31,8 +31,7 @@
 
   lldb::TraceEvents GetEvents() override;
 
-  lldb::TraceInstructionControlFlowType
-  GetInstructionControlFlowType() override;
+  lldb::InstructionControlFlowType GetInstructionControlFlowType() override;
 
   bool IsError() override;
 
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
@@ -112,8 +109,7 @@
   return m_decoded_thread_sp->GetEvents(m_pos);
 }
 
-TraceInstructionControlFlowType
-TraceCursorIntelPT::GetInstructionControlFlowType() {
+InstructionControlFlowType TraceCursorIntelPT::GetInstructionControlFlowType() {
   return m_decoded_thread_sp->GetInstructionControlFlowType(m_pos);
 }
 
Index: lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
===================================================================
--- lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
+++ lldb/source/Plugins/Trace/intel-pt/DecodedThread.h
@@ -182,7 +182,7 @@
   ///
   /// \return
   ///     The control flow categories, or \b 0 if the instruction is an error.
-  lldb::TraceInstructionControlFlowType
+  lldb::InstructionControlFlowType
   GetInstructionControlFlowType(size_t insn_index) const;
 
   /// Construct the TSC range that covers the given instruction index.
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
@@ -59,34 +59,36 @@
   return m_instruction_ips[insn_index];
 }
 
-TraceInstructionControlFlowType
+InstructionControlFlowType
 DecodedThread::GetInstructionControlFlowType(size_t insn_index) const {
   if (IsInstructionAnError(insn_index))
-    return (TraceInstructionControlFlowType)0;
+    return eInstructionControlFlowTypeUnknown;
 
-  TraceInstructionControlFlowType mask =
-      eTraceInstructionControlFlowTypeInstruction;
+  InstructionControlFlowType mask = eInstructionControlFlowTypeOther;
 
-  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 |= eInstructionControlFlowTypeCall;
     break;
   case ptic_return:
-  case ptic_far_return:
-    mask |= eTraceInstructionControlFlowTypeReturn;
+    mask |= eInstructionControlFlowTypeReturn;
+    break;
+  case ptic_jump:
+    mask |= eInstructionControlFlowTypeJump;
+    break;
+  case ptic_cond_jump:
+    mask |= eInstructionControlFlowTypeCondJump;
     break;
-  case ptic_call:
   case ptic_far_call:
-    mask |= eTraceInstructionControlFlowTypeCall;
+    mask |= eInstructionControlFlowTypeFarCall;
+    break;
+  case ptic_far_return:
+    mask |= eInstructionControlFlowTypeFarReturn;
+    break;
+  case ptic_far_jump:
+    mask |= eInstructionControlFlowTypeFarJump;
     break;
   default:
     break;
Index: lldb/source/Expression/IRExecutionUnit.cpp
===================================================================
--- lldb/source/Expression/IRExecutionUnit.cpp
+++ lldb/source/Expression/IRExecutionUnit.cpp
@@ -200,7 +200,7 @@
                                       UINT32_MAX, false, false);
 
   InstructionList &instruction_list = disassembler_sp->GetInstructionList();
-  instruction_list.Dump(&stream, true, true, &exe_ctx);
+  instruction_list.Dump(&stream, true, true, true, &exe_ctx);
   return ret;
 }
 
Index: lldb/source/Core/DumpDataExtractor.cpp
===================================================================
--- lldb/source/Core/DumpDataExtractor.cpp
+++ lldb/source/Core/DumpDataExtractor.cpp
@@ -170,10 +170,11 @@
         offset += bytes_consumed;
         const bool show_address = base_addr != LLDB_INVALID_ADDRESS;
         const bool show_bytes = true;
+        const bool show_kind = true;
         ExecutionContext exe_ctx;
         exe_scope->CalculateExecutionContext(exe_ctx);
         disassembler_sp->GetInstructionList().Dump(s, show_address, show_bytes,
-                                                   &exe_ctx);
+                                                   show_kind, &exe_ctx);
       }
     }
   } else
Index: lldb/source/Core/Disassembler.cpp
===================================================================
--- lldb/source/Core/Disassembler.cpp
+++ lldb/source/Core/Disassembler.cpp
@@ -527,8 +527,9 @@
       }
 
       const bool show_bytes = (options & eOptionShowBytes) != 0;
-      inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc,
-                 &prev_sc, nullptr, address_text_size);
+      const bool show_kind = (options & eOptionShowKind) != 0;
+      inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, show_kind,
+                 &exe_ctx, &sc, &prev_sc, nullptr, address_text_size);
       strm.EOL();
     } else {
       break;
@@ -568,6 +569,234 @@
 
 Instruction::~Instruction() = default;
 
+lldb::InstructionControlFlowType
+Instruction::instruction_decode(uint8_t opcode, uint8_t modrm, uint8_t map) {
+  lldb::InstructionControlFlowType itype;
+  // Decide iclass based on opcode and modrm, map
+  if (map > PTI_MAP_1)
+    return lldb::eInstructionControlFlowTypeUnknown;
+
+  if (opcode >= 0x70 && opcode <= 0x7F) {
+    if (map == PTI_MAP_0)
+      return lldb::eInstructionControlFlowTypeCondJump;
+  } else if (opcode >= 0x80 && opcode <= 0x8F) {
+    if (map == PTI_MAP_1)
+      return lldb::eInstructionControlFlowTypeCondJump;
+  }
+
+  itype = lldb::eInstructionControlFlowTypeOther;
+  switch (opcode) {
+  case 0x9A:
+    if (map == PTI_MAP_0)
+      itype = lldb::eInstructionControlFlowTypeFarCall;
+    break;
+  case 0xFF:
+    if (map == PTI_MAP_0) {
+      uint8_t modrm_reg = (modrm >> 3) & 7;
+      if (modrm_reg == 2)
+        itype = lldb::eInstructionControlFlowTypeCall;
+      else if (modrm_reg == 3)
+        itype = lldb::eInstructionControlFlowTypeFarCall;
+      else if (modrm_reg == 4)
+        itype = lldb::eInstructionControlFlowTypeJump;
+      else if (modrm_reg == 5)
+        itype = lldb::eInstructionControlFlowTypeFarJump;
+    }
+    break;
+  case 0xE8:
+    if (map == PTI_MAP_0)
+      itype = lldb::eInstructionControlFlowTypeCall;
+    break;
+  case 0xCD:
+  case 0xCC:
+  case 0xCE:
+  case 0xF1:
+    if (map == PTI_MAP_0)
+      itype = lldb::eInstructionControlFlowTypeFarCall;
+    break;
+  case 0xCF:
+    if (map == PTI_MAP_0)
+      itype = lldb::eInstructionControlFlowTypeFarReturn;
+    break;
+  case 0xE9:
+  case 0xEB:
+    if (map == PTI_MAP_0)
+      itype = lldb::eInstructionControlFlowTypeJump;
+    break;
+  case 0xEA:
+    if (map == PTI_MAP_0)
+      itype = lldb::eInstructionControlFlowTypeFarJump;
+    break;
+  case 0xE3:
+  case 0xE0:
+  case 0xE1:
+  case 0xE2:
+    if (map == PTI_MAP_0)
+      itype = lldb::eInstructionControlFlowTypeCondJump;
+    break;
+  case 0xC3:
+  case 0xC2:
+    if (map == PTI_MAP_0)
+      itype = lldb::eInstructionControlFlowTypeReturn;
+    break;
+  case 0xCB:
+  case 0xCA:
+    if (map == PTI_MAP_0)
+      itype = lldb::eInstructionControlFlowTypeFarReturn;
+    break;
+  case 0x05:
+  case 0x34:
+    if (map == PTI_MAP_1)
+      itype = lldb::eInstructionControlFlowTypeFarCall;
+    break;
+  case 0x35:
+  case 0x07:
+    if (map == PTI_MAP_1)
+      itype = lldb::eInstructionControlFlowTypeFarReturn;
+    break;
+  case 0x01:
+    if (map == PTI_MAP_1) {
+      switch (modrm) {
+      case 0xc1:
+        itype = lldb::eInstructionControlFlowTypeFarCall;
+        break;
+      case 0xc2:
+      case 0xc3:
+        itype = lldb::eInstructionControlFlowTypeFarReturn;
+        break;
+      default:
+        break;
+      }
+    }
+    break;
+  default:
+    break;
+  }
+  return itype;
+}
+
+lldb::InstructionControlFlowType
+Instruction::GetControlFlowInstructionKind(const ExecutionContext *exe_ctx) {
+  uint8_t *opcode_bytes = (uint8_t *)m_opcode.GetOpcodeBytes();
+  uint8_t opcode, modrm, map;
+  int op_idx = 0;
+  bool prefix_done = false;
+
+  if (!opcode_bytes) {
+    // x86_64 and i386 are the only ones that use bytes right now
+    // Else, we have ARM or MIPS, not yet implemented
+    return lldb::eInstructionControlFlowTypeUnknown;
+  }
+
+  // Get opcode and modrm
+  map = PTI_MAP_INVALID;
+  while (!prefix_done) {
+    opcode = opcode_bytes[op_idx];
+    switch (opcode) {
+    // prefix_ignore
+    case 0x26:
+    case 0x2e:
+    case 0x36:
+    case 0x3e:
+    case 0x64:
+    case 0x65:
+    // prefix_osz, prefix_asz
+    case 0x66:
+    case 0x67:
+    // prefix_lock, prefix_f2, prefix_f3
+    case 0xf0:
+    case 0xf2:
+    case 0xf3:
+      op_idx++;
+      break;
+
+    // prefix_rex
+    case 0x40 ... 0x4f:
+      if (exe_ctx->GetTargetRef().GetArchitecture().GetMachine() ==
+          llvm::Triple::ArchType::x86_64)
+        op_idx++;
+      else
+        prefix_done = true;
+      break;
+
+    // prefix_vex_c4, c5
+    case 0xc5:
+      if (exe_ctx->GetTargetRef().GetArchitecture().GetMachine() !=
+              llvm::Triple::ArchType::x86_64 &&
+          (opcode_bytes[op_idx + 1] & 0xc0) != 0xc0) {
+        prefix_done = true;
+        break;
+      }
+
+      map = PTI_MAP_1;
+      opcode = opcode_bytes[op_idx + 2];
+      modrm = opcode_bytes[op_idx + 3];
+      return instruction_decode(opcode, modrm, map);
+      break;
+
+    case 0xc4:
+      if (exe_ctx->GetTargetRef().GetArchitecture().GetMachine() !=
+              llvm::Triple::ArchType::x86_64 &&
+          (opcode_bytes[op_idx + 1] & 0xc0) != 0xc0) {
+        prefix_done = true;
+        break;
+      }
+      map = opcode_bytes[op_idx + 1] & 0x1f;
+      opcode = opcode_bytes[op_idx + 3];
+      modrm = opcode_bytes[op_idx + 4];
+      return instruction_decode(opcode, modrm, map);
+      break;
+
+    // prefix_evex
+    case 0x62:
+      if (exe_ctx->GetTargetRef().GetArchitecture().GetMachine() !=
+              llvm::Triple::ArchType::x86_64 &&
+          (opcode_bytes[op_idx + 1] & 0xc0) != 0xc0) {
+        prefix_done = true;
+        break;
+      }
+      map = opcode_bytes[op_idx + 1] & 0x03;
+      opcode = opcode_bytes[op_idx + 4];
+      modrm = opcode_bytes[op_idx + 5];
+      return instruction_decode(opcode, modrm, map);
+      break;
+    default:
+      prefix_done = true;
+      break;
+    }
+  } // prefix done
+
+  opcode = opcode_bytes[op_idx];
+  modrm = opcode_bytes[op_idx + 1];
+  map = PTI_MAP_0;
+
+  if (opcode == 0x0F) {
+    if (opcode_bytes[op_idx + 1] == 0x38) {
+      map = PTI_MAP_2;
+      opcode = opcode_bytes[op_idx + 2];
+      modrm = opcode_bytes[op_idx + 3];
+    } else if (opcode_bytes[op_idx + 1] == 0x3A) {
+      map = PTI_MAP_3;
+      opcode = opcode_bytes[op_idx + 2];
+      modrm = opcode_bytes[op_idx + 3];
+    } else if ((opcode_bytes[op_idx + 1] & 0xf8) == 0x38) {
+      map = PTI_MAP_INVALID;
+      opcode = opcode_bytes[op_idx + 2];
+      modrm = opcode_bytes[op_idx + 3];
+    } else if (opcode_bytes[op_idx + 1] == 0x0F) {
+      map = PTI_MAP_AMD3DNOW;
+      opcode = opcode_bytes[op_idx + 1];
+      modrm = opcode_bytes[op_idx + 2];
+    } else {
+      map = PTI_MAP_1;
+      opcode = opcode_bytes[op_idx + 1];
+      modrm = opcode_bytes[op_idx + 2];
+    }
+  }
+
+  return instruction_decode(opcode, modrm, map);
+}
+
 AddressClass Instruction::GetAddressClass() {
   if (m_address_class == AddressClass::eInvalid)
     m_address_class = m_address.GetAddressClass();
@@ -575,7 +804,7 @@
 }
 
 void Instruction::Dump(lldb_private::Stream *s, uint32_t max_opcode_byte_size,
-                       bool show_address, bool show_bytes,
+                       bool show_address, bool show_bytes, bool show_kind,
                        const ExecutionContext *exe_ctx,
                        const SymbolContext *sym_ctx,
                        const SymbolContext *prev_sym_ctx,
@@ -613,6 +842,39 @@
     }
   }
 
+  if (show_kind) {
+    // TODO-SUJIN
+    switch (GetControlFlowInstructionKind(exe_ctx)) {
+    case eInstructionControlFlowTypeUnknown:
+      ss.Printf("%-12s", "unknwon");
+      break;
+    case eInstructionControlFlowTypeOther:
+      ss.Printf("%-12s", "other");
+      break;
+    case eInstructionControlFlowTypeCall:
+      ss.Printf("%-12s", "call");
+      break;
+    case eInstructionControlFlowTypeReturn:
+      ss.Printf("%-12s", "return");
+      break;
+    case eInstructionControlFlowTypeJump:
+      ss.Printf("%-12s", "jump");
+      break;
+    case eInstructionControlFlowTypeCondJump:
+      ss.Printf("%-12s", "cond jump");
+      break;
+    case eInstructionControlFlowTypeFarCall:
+      ss.Printf("%-12s", "far call");
+      break;
+    case eInstructionControlFlowTypeFarReturn:
+      ss.Printf("%-12s", "far return");
+      break;
+    case eInstructionControlFlowTypeFarJump:
+      ss.Printf("%-12s", "far jump");
+      break;
+    }
+  }
+
   const size_t opcode_pos = ss.GetSizeOfLastLine();
 
   // The default opcode size of 7 characters is plenty for most architectures
@@ -957,7 +1219,7 @@
 }
 
 void InstructionList::Dump(Stream *s, bool show_address, bool show_bytes,
-                           const ExecutionContext *exe_ctx) {
+                           bool show_kind, const ExecutionContext *exe_ctx) {
   const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
   collection::const_iterator pos, begin, end;
 
@@ -975,8 +1237,8 @@
        pos != end; ++pos) {
     if (pos != begin)
       s->EOL();
-    (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx,
-                 nullptr, nullptr, disassembly_format, 0);
+    (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, show_kind,
+                 exe_ctx, nullptr, nullptr, disassembly_format, 0);
   }
 }
 
@@ -994,7 +1256,7 @@
   size_t num_instructions = m_instructions.size();
 
   uint32_t next_branch = UINT32_MAX;
-  
+
   if (found_calls)
     *found_calls = false;
   for (size_t i = start; i < num_instructions; i++) {
Index: lldb/source/Commands/Options.td
===================================================================
--- lldb/source/Commands/Options.td
+++ lldb/source/Commands/Options.td
@@ -300,6 +300,8 @@
 let Command = "disassemble" in {
   def disassemble_options_bytes : Option<"bytes", "b">,
     Desc<"Show opcode bytes when disassembling.">;
+  def disassemble_options_kind : Option<"kind", "k">,
+    Desc<"Show instruction control flow type.">;
   def disassemble_options_context : Option<"context", "C">, Arg<"NumLines">,
     Desc<"Number of context lines of source to show.">;
   def disassemble_options_mixed : Option<"mixed", "m">,
@@ -1150,6 +1152,8 @@
   def thread_trace_dump_instructions_pretty_print: Option<"pretty-json", "J">,
     Group<1>,
     Desc<"Dump in JSON format but pretty printing the output for easier readability.">;
+  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
@@ -2164,6 +2164,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/source/Commands/CommandObjectDisassemble.h
===================================================================
--- lldb/source/Commands/CommandObjectDisassemble.h
+++ lldb/source/Commands/CommandObjectDisassemble.h
@@ -46,6 +46,7 @@
 
     bool show_mixed; // Show mixed source/assembly
     bool show_bytes;
+    bool show_kind;
     uint32_t num_lines_context = 0;
     uint32_t num_instructions = 0;
     bool raw;
Index: lldb/source/Commands/CommandObjectDisassemble.cpp
===================================================================
--- lldb/source/Commands/CommandObjectDisassemble.cpp
+++ lldb/source/Commands/CommandObjectDisassemble.cpp
@@ -65,6 +65,10 @@
     show_bytes = true;
     break;
 
+  case 'k':
+    show_kind = true;
+    break;
+
   case 's': {
     start_addr = OptionArgParser::ToAddress(execution_context, option_arg,
                                             LLDB_INVALID_ADDRESS, &error);
@@ -154,6 +158,7 @@
     ExecutionContext *execution_context) {
   show_mixed = false;
   show_bytes = false;
+  show_kind = false;
   num_lines_context = 0;
   num_instructions = 0;
   func_name.clear();
@@ -493,6 +498,9 @@
   if (m_options.show_bytes)
     options |= Disassembler::eOptionShowBytes;
 
+  if (m_options.show_kind)
+    options |= Disassembler::eOptionShowKind;
+
   if (m_options.raw)
     options |= Disassembler::eOptionRawOuput;
 
Index: lldb/source/API/SBInstructionList.cpp
===================================================================
--- lldb/source/API/SBInstructionList.cpp
+++ lldb/source/API/SBInstructionList.cpp
@@ -165,8 +165,8 @@
               addr, eSymbolContextEverything, sc);
         }
 
-        inst->Dump(&sref, max_opcode_byte_size, true, false, nullptr, &sc,
-                   &prev_sc, &format, 0);
+        inst->Dump(&sref, max_opcode_byte_size, true, false, false, nullptr,
+                   &sc, &prev_sc, &format, 0);
         sref.EOL();
       }
       return true;
Index: lldb/source/API/SBInstruction.cpp
===================================================================
--- lldb/source/API/SBInstruction.cpp
+++ lldb/source/API/SBInstruction.cpp
@@ -241,7 +241,8 @@
     // didn't have a stream already created, one will get created...
     FormatEntity::Entry format;
     FormatEntity::Parse("${addr}: ", format);
-    inst_sp->Dump(&s.ref(), 0, true, false, nullptr, &sc, nullptr, &format, 0);
+    inst_sp->Dump(&s.ref(), 0, true, false, false, nullptr, &sc, nullptr,
+                  &format, 0);
     return true;
   }
   return false;
@@ -275,8 +276,8 @@
     StreamFile out_stream(out_sp);
     FormatEntity::Entry format;
     FormatEntity::Parse("${addr}: ", format);
-    inst_sp->Dump(&out_stream, 0, true, false, nullptr, &sc, nullptr, &format,
-                  0);
+    inst_sp->Dump(&out_stream, 0, true, false, false, nullptr, &sc, nullptr,
+                  &format, 0);
   }
 }
 
Index: lldb/include/lldb/lldb-enumerations.h
===================================================================
--- lldb/include/lldb/lldb-enumerations.h
+++ lldb/include/lldb/lldb-enumerations.h
@@ -970,20 +970,30 @@
 /// control flow of a trace.
 ///
 /// A single instruction can match one or more of these categories.
-FLAGS_ENUM(TraceInstructionControlFlowType){
-    /// Any instruction.
-    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)};
-
-LLDB_MARK_AS_BITMASK_ENUM(TraceInstructionControlFlowType)
+FLAGS_ENUM(InstructionControlFlowType){
+    /// The instruction could not be classified.
+    eInstructionControlFlowTypeUnknown = 0,
+    /// The instruction is something not listed below.
+    eInstructionControlFlowTypeOther = (1u << 1),
+    /// The instruction is a near (function) call.
+    eInstructionControlFlowTypeCall = (1u << 2),
+    /// The instruction is a near (function) return.
+    eInstructionControlFlowTypeReturn = (1u << 3),
+    /// The instruction is a near unconditional jump.
+    eInstructionControlFlowTypeJump = (1u << 4),
+    /// The instruction is a near conditional jump.
+    eInstructionControlFlowTypeCondJump = (1u << 5),
+    /// The instruction is a call-like far transfer.
+    /// E.g. SYSCALL, SYSENTER, or FAR CALL.
+    eInstructionControlFlowTypeFarCall = (1u << 6),
+    /// The instruction is a return-like far transfer.
+    /// E.g. SYSRET, SYSEXIT, IRET, or FAR RET.
+    eInstructionControlFlowTypeFarReturn = (1u << 7),
+    /// The instruction is a jump-like far transfer.
+    /// E.g. FAR JMP.
+    eInstructionControlFlowTypeFarJump = (1u << 8)};
+
+LLDB_MARK_AS_BITMASK_ENUM(InstructionControlFlowType)
 
 /// Watchpoint Kind.
 ///
Index: lldb/include/lldb/Target/TraceInstructionDumper.h
===================================================================
--- lldb/include/lldb/Target/TraceInstructionDumper.h
+++ lldb/include/lldb/Target/TraceInstructionDumper.h
@@ -34,6 +34,8 @@
   bool show_tsc = false;
   /// Dump the events that happened between instructions.
   bool show_events = false;
+  /// For each instruction, print the instruction type.
+  bool show_kind = false;
   /// Optional custom id to start traversing from.
   llvm::Optional<uint64_t> id = llvm::None;
   /// Optional number of instructions to skip from the starting position
Index: lldb/include/lldb/Target/TraceCursor.h
===================================================================
--- lldb/include/lldb/Target/TraceCursor.h
+++ lldb/include/lldb/Target/TraceCursor.h
@@ -40,34 +40,29 @@
 ///
 /// 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;
 ///     else if (cursor->GetInstructionControlFlowType() &
-///         eTraceInstructionControlFlowTypeCall)
+///         eInstructionControlFlowTypeCall)
 ///       std::cout << "call found at " << cursor->GetLoadAddress() <<
 ///       std::endl;
 ///     else if (cursor->GetInstructionControlFlowType() &
-///         eTraceInstructionControlFlowTypeReturn)
+///         eInstructionControlFlowTypeReturn)
 ///       std::cout << "return found at " << cursor->GetLoadAddress() <<
 ///       std::endl;
 ///  } 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;
@@ -251,19 +228,15 @@
   virtual lldb::TraceEvents GetEvents() = 0;
 
   /// \return
-  ///     The \a lldb::TraceInstructionControlFlowType categories the
+  ///     The \a lldb::InstructionControlFlowType categories the
   ///     instruction the cursor is pointing at falls into. If the cursor points
   ///     to an error in the trace, return \b 0.
-  virtual lldb::TraceInstructionControlFlowType
-  GetInstructionControlFlowType() = 0;
+  virtual lldb::InstructionControlFlowType GetInstructionControlFlowType() = 0;
   /// \}
 
 protected:
   ExecutionContextRef m_exe_ctx_ref;
 
-  lldb::TraceInstructionControlFlowType m_granularity =
-      lldb::eTraceInstructionControlFlowTypeInstruction;
-  bool m_ignore_errors = false;
   bool m_forwards = false;
 };
 
Index: lldb/include/lldb/Core/Disassembler.h
===================================================================
--- lldb/include/lldb/Core/Disassembler.h
+++ lldb/include/lldb/Core/Disassembler.h
@@ -79,6 +79,12 @@
     return m_comment.c_str();
   }
 
+  lldb::InstructionControlFlowType
+  instruction_decode(uint8_t opcode, uint8_t modrm, uint8_t map);
+
+  lldb::InstructionControlFlowType
+  GetControlFlowInstructionKind(const ExecutionContext *exe_ctx);
+
   virtual void
   CalculateMnemonicOperandsAndComment(const ExecutionContext *exe_ctx) = 0;
 
@@ -105,6 +111,9 @@
   /// \param[in] show_bytes
   ///     Whether the bytes of the assembly instruction should be printed.
   ///
+  /// \param[in] show_kind
+  ///     Whether the control flow type of the instruction should be printed.
+  ///
   /// \param[in] max_opcode_byte_size
   ///     The size (in bytes) of the largest instruction in the list that
   ///     we are printing (for text justification/alignment purposes)
@@ -140,7 +149,8 @@
   ///     so this method can properly align the instruction opcodes.
   ///     May be 0 to indicate no indentation/alignment of the opcodes.
   virtual void Dump(Stream *s, uint32_t max_opcode_byte_size, bool show_address,
-                    bool show_bytes, const ExecutionContext *exe_ctx,
+                    bool show_bytes, bool show_kind,
+                    const ExecutionContext *exe_ctx,
                     const SymbolContext *sym_ctx,
                     const SymbolContext *prev_sym_ctx,
                     const FormatEntity::Entry *disassembly_addr_format,
@@ -213,6 +223,15 @@
 
   virtual bool IsCall() { return false; }
 
+  enum {
+    PTI_MAP_0,
+    PTI_MAP_1,
+    PTI_MAP_2,
+    PTI_MAP_3,
+    PTI_MAP_AMD3DNOW,
+    PTI_MAP_INVALID
+  };
+
 protected:
   Address m_address; // The section offset address of this instruction
                      // We include an address class in the Instruction class to
@@ -319,7 +338,7 @@
 
   void Append(lldb::InstructionSP &inst_sp);
 
-  void Dump(Stream *s, bool show_address, bool show_bytes,
+  void Dump(Stream *s, bool show_address, bool show_bytes, bool show_kind,
             const ExecutionContext *exe_ctx);
 
 private:
@@ -375,7 +394,8 @@
     eOptionMarkPCSourceLine = (1u << 2), // Mark the source line that contains
                                          // the current PC (mixed mode only)
     eOptionMarkPCAddress =
-        (1u << 3) // Mark the disassembly line the contains the PC
+        (1u << 3), // Mark the disassembly line the contains the PC
+    eOptionShowKind = (1u << 4),
   };
 
   enum HexImmediateStyle {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to