labath updated this revision to Diff 106165.
labath added a comment.
Herald added subscribers: javed.absar, mgorny.

The architecture plugin idea


https://reviews.llvm.org/D31172

Files:
  include/lldb/Core/ArchSpec.h
  include/lldb/Core/Architecture.h
  include/lldb/Core/PluginManager.h
  include/lldb/Target/Process.h
  source/API/SystemInitializerFull.cpp
  source/Core/ArchSpec.cpp
  source/Core/PluginManager.cpp
  source/Plugins/Architecture/Arm/ArchitectureArm.cpp
  source/Plugins/Architecture/Arm/ArchitectureArm.h
  source/Plugins/Architecture/Arm/CMakeLists.txt
  source/Plugins/Architecture/CMakeLists.txt
  source/Plugins/CMakeLists.txt
  source/Target/Process.cpp
  source/Target/Thread.cpp

Index: source/Target/Thread.cpp
===================================================================
--- source/Target/Thread.cpp
+++ source/Target/Thread.cpp
@@ -442,10 +442,8 @@
     if (m_stop_info_override_stop_id != process_stop_id) {
       m_stop_info_override_stop_id = process_stop_id;
       if (m_stop_info_sp) {
-        ArchSpec::StopInfoOverrideCallbackType callback =
-            GetProcess()->GetStopInfoOverrideCallback();
-        if (callback)
-          callback(*this);
+        if (Architecture *arch = GetProcess()->GetArchitecturePlugin())
+          arch->OverrideStopInfo(*this);
       }
     }
   }
Index: source/Target/Process.cpp
===================================================================
--- source/Target/Process.cpp
+++ source/Target/Process.cpp
@@ -743,8 +743,7 @@
       m_profile_data_comm_mutex(), m_profile_data(), m_iohandler_sync(0),
       m_memory_cache(*this), m_allocated_memory_cache(*this),
       m_should_detach(false), m_next_event_action_ap(), m_public_run_lock(),
-      m_private_run_lock(), m_stop_info_override_callback(nullptr),
-      m_finalizing(false), m_finalize_called(false),
+      m_private_run_lock(), m_finalizing(false), m_finalize_called(false),
       m_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false),
       m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false),
       m_can_interpret_function_calls(false), m_warnings_issued(),
@@ -855,6 +854,7 @@
   m_dynamic_checkers_ap.reset();
   m_abi_sp.reset();
   m_os_ap.reset();
+  m_architecture_up.reset();
   m_system_runtime_ap.reset();
   m_dyld_ap.reset();
   m_jit_loaders_ap.reset();
@@ -871,7 +871,6 @@
   m_language_runtimes.clear();
   m_instrumentation_runtimes.clear();
   m_next_event_action_ap.reset();
-  m_stop_info_override_callback = nullptr;
   // Clear the last natural stop ID since it has a strong
   // reference to this process
   m_mod_id.SetStopEventForLastNaturalStopID(EventSP());
@@ -2711,8 +2710,8 @@
   m_jit_loaders_ap.reset();
   m_system_runtime_ap.reset();
   m_os_ap.reset();
+  m_architecture_up.reset();
   m_process_input_reader.reset();
-  m_stop_info_override_callback = nullptr;
 
   Module *exe_module = GetTarget().GetExecutableModulePointer();
   if (exe_module) {
@@ -2800,8 +2799,8 @@
             else
               StartPrivateStateThread();
 
-            m_stop_info_override_callback =
-                GetTarget().GetArchitecture().GetStopInfoOverrideCallback();
+            m_architecture_up = PluginManager::CreateArchitectureInstance(
+                GetTarget().GetArchitecture());
 
             // Target was stopped at entry as was intended. Need to notify the
             // listeners
@@ -2986,7 +2985,6 @@
   m_jit_loaders_ap.reset();
   m_system_runtime_ap.reset();
   m_os_ap.reset();
-  m_stop_info_override_callback = nullptr;
 
   lldb::pid_t attach_pid = attach_info.GetProcessID();
   Status error;
@@ -3220,7 +3218,7 @@
     }
   }
 
-  m_stop_info_override_callback = process_arch.GetStopInfoOverrideCallback();
+  m_architecture_up = PluginManager::CreateArchitectureInstance(process_arch);
 }
 
 Status Process::ConnectRemote(Stream *strm, llvm::StringRef remote_url) {
@@ -5849,7 +5847,6 @@
   m_instrumentation_runtimes.clear();
   m_thread_list.DiscardThreadPlans();
   m_memory_cache.Clear(true);
-  m_stop_info_override_callback = nullptr;
   DoDidExec();
   CompleteAttach();
   // Flush the process (threads and all stack frames) after running
Index: source/Plugins/CMakeLists.txt
===================================================================
--- source/Plugins/CMakeLists.txt
+++ source/Plugins/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_subdirectory(ABI)
+add_subdirectory(Architecture)
 add_subdirectory(Disassembler)
 add_subdirectory(DynamicLoader)
 add_subdirectory(ExpressionParser)
Index: source/Plugins/Architecture/CMakeLists.txt
===================================================================
--- /dev/null
+++ source/Plugins/Architecture/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(Arm)
Index: source/Plugins/Architecture/Arm/CMakeLists.txt
===================================================================
--- /dev/null
+++ source/Plugins/Architecture/Arm/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_lldb_library(lldbPluginArchitectureArm PLUGIN
+  ArchitectureArm.cpp
+
+  LINK_LIBS
+    lldbPluginProcessUtility
+    lldbCore
+    lldbTarget
+  LINK_COMPONENTS
+    Support
+  )
Index: source/Plugins/Architecture/Arm/ArchitectureArm.h
===================================================================
--- /dev/null
+++ source/Plugins/Architecture/Arm/ArchitectureArm.h
@@ -0,0 +1,31 @@
+//===-- ArchitectureArm.h ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_PLUGIN_ARCHITECTURE_ARM_H
+#define LLDB_PLUGIN_ARCHITECTURE_ARM_H
+
+#include "lldb/Core/Architecture.h"
+
+namespace lldb_private {
+
+class ArchitectureArm : public Architecture {
+public:
+  static void Initialize();
+  static void Terminate();
+
+  void OverrideStopInfo(Thread &thread) override;
+
+private:
+  static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
+  ArchitectureArm() = default;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_PLUGIN_ARCHITECTURE_ARM_H
Index: source/Plugins/Architecture/Arm/ArchitectureArm.cpp
===================================================================
--- /dev/null
+++ source/Plugins/Architecture/Arm/ArchitectureArm.cpp
@@ -0,0 +1,124 @@
+//===-- ArchitectureArm.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/Architecture/Arm/ArchitectureArm.h"
+#include "Plugins/Process/Utility/ARMDefines.h"
+#include "Plugins/Process/Utility/InstructionUtils.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+void ArchitectureArm::Initialize() {
+  PluginManager::RegisterPlugin(ConstString("ArchitectureArm"),
+                                "Arm-specific algorithms",
+                                &ArchitectureArm::Create);
+}
+
+void ArchitectureArm::Terminate() {
+  PluginManager::UnregisterPlugin(&ArchitectureArm::Create);
+}
+
+std::unique_ptr<Architecture> ArchitectureArm::Create(const ArchSpec &arch) {
+  if (arch.GetMachine() != llvm::Triple::arm)
+    return nullptr;
+  return std::unique_ptr<Architecture>(new ArchitectureArm());
+}
+
+void ArchitectureArm::OverrideStopInfo(Thread &thread) {
+  // We need to check if we are stopped in Thumb mode in a IT instruction
+  // and detect if the condition doesn't pass. If this is the case it means
+  // we won't actually execute this instruction. If this happens we need to
+  // clear the stop reason to no thread plans think we are stopped for a
+  // reason and the plans should keep going.
+  //
+  // We do this because when single stepping many ARM processes, debuggers
+  // often use the BVR/BCR registers that says "stop when the PC is not
+  // equal to its current value". This method of stepping means we can end
+  // up stopping on instructions inside an if/then block that wouldn't get
+  // executed. By fixing this we can stop the debugger from seeming like
+  // you stepped through both the "if" _and_ the "else" clause when source
+  // level stepping because the debugger stops regardless due to the BVR/BCR
+  // triggering a stop.
+  //
+  // It also means we can set breakpoints on instructions inside an an
+  // if/then block and correctly skip them if we use the BKPT instruction.
+  // The ARM and Thumb BKPT instructions are unconditional even when executed
+  // in a Thumb IT block.
+  //
+  // If your debugger inserts software traps in ARM/Thumb code, it will
+  // need to use 16 and 32 bit instruction for 16 and 32 bit thumb
+  // instructions respectively. If your debugger inserts a 16 bit thumb
+  // trap on top of a 32 bit thumb instruction for an opcode that is inside
+  // an if/then, it will change the it/then to conditionally execute your
+  // 16 bit trap and then cause your program to crash if it executes the
+  // trailing 16 bits (the second half of the 32 bit thumb instruction you
+  // partially overwrote).
+
+  RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
+  if (!reg_ctx_sp)
+    return;
+
+  const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
+  if (cpsr == 0)
+    return;
+
+  // Read the J and T bits to get the ISETSTATE
+  const uint32_t J = Bit32(cpsr, 24);
+  const uint32_t T = Bit32(cpsr, 5);
+  const uint32_t ISETSTATE = J << 1 | T;
+  if (ISETSTATE == 0) {
+// NOTE: I am pretty sure we want to enable the code below
+// that detects when we stop on an instruction in ARM mode
+// that is conditional and the condition doesn't pass. This
+// can happen if you set a breakpoint on an instruction that
+// is conditional. We currently will _always_ stop on the
+// instruction which is bad. You can also run into this while
+// single stepping and you could appear to run code in the "if"
+// and in the "else" clause because it would stop at all of the
+// conditional instructions in both.
+// In such cases, we really don't want to stop at this location.
+// I will check with the lldb-dev list first before I enable this.
+#if 0
+    // ARM mode: check for condition on intsruction
+    const addr_t pc = reg_ctx_sp->GetPC();
+    Status error;
+    // If we fail to read the opcode we will get UINT64_MAX as the
+    // result in "opcode" which we can use to detect if we read a
+    // valid opcode.
+    const uint64_t opcode = thread.GetProcess()->ReadUnsignedIntegerFromMemory(pc, 4, UINT64_MAX, error);
+    if (opcode <= UINT32_MAX)
+    {
+        const uint32_t condition = Bits32((uint32_t)opcode, 31, 28);
+        if (!ARMConditionPassed(condition, cpsr))
+        {
+            // We ARE stopped on an ARM instruction whose condition doesn't
+            // pass so this instruction won't get executed.
+            // Regardless of why it stopped, we need to clear the stop info
+            thread.SetStopInfo (StopInfoSP());
+        }
+    }
+#endif
+  } else if (ISETSTATE == 1) {
+    // Thumb mode
+    const uint32_t ITSTATE = Bits32(cpsr, 15, 10) << 2 | Bits32(cpsr, 26, 25);
+    if (ITSTATE != 0) {
+      const uint32_t condition = Bits32(ITSTATE, 7, 4);
+      if (!ARMConditionPassed(condition, cpsr)) {
+        // We ARE stopped in a Thumb IT instruction on an instruction whose
+        // condition doesn't pass so this instruction won't get executed.
+        // Regardless of why it stopped, we need to clear the stop info
+        thread.SetStopInfo(StopInfoSP());
+      }
+    }
+  }
+}
Index: source/Core/PluginManager.cpp
===================================================================
--- source/Core/PluginManager.cpp
+++ source/Core/PluginManager.cpp
@@ -275,6 +275,54 @@
   return nullptr;
 }
 
+#pragma mark Architecture
+
+struct ArchitectureInstance {
+  ConstString name;
+  std::string description;
+  PluginManager::ArchitectureCreateInstance create_callback;
+};
+
+typedef std::vector<ArchitectureInstance> ArchitectureInstances;
+
+std::mutex g_architecture_mutex;
+
+static ArchitectureInstances &GetArchitectureInstances() {
+  static ArchitectureInstances g_instances;
+  return g_instances;
+}
+
+void PluginManager::RegisterPlugin(const ConstString &name,
+                                   llvm::StringRef description,
+                                   ArchitectureCreateInstance create_callback) {
+  std::lock_guard<std::mutex> guard(g_architecture_mutex);
+  GetArchitectureInstances().push_back({name, description, create_callback});
+}
+
+void PluginManager::UnregisterPlugin(
+    ArchitectureCreateInstance create_callback) {
+  std::lock_guard<std::mutex> guard(g_architecture_mutex);
+  auto &instances = GetArchitectureInstances();
+
+  for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) {
+    if (pos->create_callback == create_callback) {
+      instances.erase(pos);
+      return;
+    }
+  }
+  llvm_unreachable("Plugin not found");
+}
+
+std::unique_ptr<Architecture>
+PluginManager::CreateArchitectureInstance(const ArchSpec &arch) {
+  std::lock_guard<std::mutex> guard(g_architecture_mutex);
+  for (const auto &instances : GetArchitectureInstances()) {
+    if (auto plugin_up = instances.create_callback(arch))
+      return plugin_up;
+  }
+  return nullptr;
+}
+
 #pragma mark Disassembler
 
 struct DisassemblerInstance {
Index: source/Core/ArchSpec.cpp
===================================================================
--- source/Core/ArchSpec.cpp
+++ source/Core/ArchSpec.cpp
@@ -11,17 +11,12 @@
 
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Target/Platform.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Thread.h"
 #include "lldb/Utility/NameMatches.h"
 #include "lldb/Utility/Stream.h" // for Stream
 #include "lldb/Utility/StringList.h"
 #include "lldb/lldb-defines.h" // for LLDB_INVALID_C...
 #include "lldb/lldb-forward.h" // for RegisterContextSP
 
-#include "Plugins/Process/Utility/ARMDefines.h"
-#include "Plugins/Process/Utility/InstructionUtils.h"
-
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/Twine.h" // for Twine
 #include "llvm/BinaryFormat/COFF.h"
@@ -1502,102 +1497,6 @@
   return lhs_core < rhs_core;
 }
 
-static void StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread) {
-  // We need to check if we are stopped in Thumb mode in a IT instruction
-  // and detect if the condition doesn't pass. If this is the case it means
-  // we won't actually execute this instruction. If this happens we need to
-  // clear the stop reason to no thread plans think we are stopped for a
-  // reason and the plans should keep going.
-  //
-  // We do this because when single stepping many ARM processes, debuggers
-  // often use the BVR/BCR registers that says "stop when the PC is not
-  // equal to its current value". This method of stepping means we can end
-  // up stopping on instructions inside an if/then block that wouldn't get
-  // executed. By fixing this we can stop the debugger from seeming like
-  // you stepped through both the "if" _and_ the "else" clause when source
-  // level stepping because the debugger stops regardless due to the BVR/BCR
-  // triggering a stop.
-  //
-  // It also means we can set breakpoints on instructions inside an an
-  // if/then block and correctly skip them if we use the BKPT instruction.
-  // The ARM and Thumb BKPT instructions are unconditional even when executed
-  // in a Thumb IT block.
-  //
-  // If your debugger inserts software traps in ARM/Thumb code, it will
-  // need to use 16 and 32 bit instruction for 16 and 32 bit thumb
-  // instructions respectively. If your debugger inserts a 16 bit thumb
-  // trap on top of a 32 bit thumb instruction for an opcode that is inside
-  // an if/then, it will change the it/then to conditionally execute your
-  // 16 bit trap and then cause your program to crash if it executes the
-  // trailing 16 bits (the second half of the 32 bit thumb instruction you
-  // partially overwrote).
-
-  RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
-  if (reg_ctx_sp) {
-    const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
-    if (cpsr != 0) {
-      // Read the J and T bits to get the ISETSTATE
-      const uint32_t J = Bit32(cpsr, 24);
-      const uint32_t T = Bit32(cpsr, 5);
-      const uint32_t ISETSTATE = J << 1 | T;
-      if (ISETSTATE == 0) {
-// NOTE: I am pretty sure we want to enable the code below
-// that detects when we stop on an instruction in ARM mode
-// that is conditional and the condition doesn't pass. This
-// can happen if you set a breakpoint on an instruction that
-// is conditional. We currently will _always_ stop on the
-// instruction which is bad. You can also run into this while
-// single stepping and you could appear to run code in the "if"
-// and in the "else" clause because it would stop at all of the
-// conditional instructions in both.
-// In such cases, we really don't want to stop at this location.
-// I will check with the lldb-dev list first before I enable this.
-#if 0
-                // ARM mode: check for condition on intsruction
-                const addr_t pc = reg_ctx_sp->GetPC();
-                Status error;
-                // If we fail to read the opcode we will get UINT64_MAX as the
-                // result in "opcode" which we can use to detect if we read a
-                // valid opcode.
-                const uint64_t opcode = thread.GetProcess()->ReadUnsignedIntegerFromMemory(pc, 4, UINT64_MAX, error);
-                if (opcode <= UINT32_MAX)
-                {
-                    const uint32_t condition = Bits32((uint32_t)opcode, 31, 28);
-                    if (!ARMConditionPassed(condition, cpsr))
-                    {
-                        // We ARE stopped on an ARM instruction whose condition doesn't
-                        // pass so this instruction won't get executed.
-                        // Regardless of why it stopped, we need to clear the stop info
-                        thread.SetStopInfo (StopInfoSP());
-                    }
-                }
-#endif
-      } else if (ISETSTATE == 1) {
-        // Thumb mode
-        const uint32_t ITSTATE =
-            Bits32(cpsr, 15, 10) << 2 | Bits32(cpsr, 26, 25);
-        if (ITSTATE != 0) {
-          const uint32_t condition = Bits32(ITSTATE, 7, 4);
-          if (!ARMConditionPassed(condition, cpsr)) {
-            // We ARE stopped in a Thumb IT instruction on an instruction whose
-            // condition doesn't pass so this instruction won't get executed.
-            // Regardless of why it stopped, we need to clear the stop info
-            thread.SetStopInfo(StopInfoSP());
-          }
-        }
-      }
-    }
-  }
-}
-
-ArchSpec::StopInfoOverrideCallbackType
-ArchSpec::GetStopInfoOverrideCallback() const {
-  const llvm::Triple::ArchType machine = GetMachine();
-  if (machine == llvm::Triple::arm)
-    return StopInfoOverrideCallbackTypeARM;
-  return nullptr;
-}
-
 bool ArchSpec::IsFullySpecifiedTriple() const {
   const auto &user_specified_triple = GetTriple();
 
Index: source/API/SystemInitializerFull.cpp
===================================================================
--- source/API/SystemInitializerFull.cpp
+++ source/API/SystemInitializerFull.cpp
@@ -42,17 +42,18 @@
 #include "Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h"
 #include "Plugins/ABI/SysV-s390x/ABISysV_s390x.h"
 #include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
+#include "Plugins/Architecture/Arm/ArchitectureArm.h"
 #include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
 #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.h"
 #include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
 #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
 #include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
 #include "Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h"
 #include "Plugins/Instruction/ARM64/EmulateInstructionARM64.h"
 #include "Plugins/InstrumentationRuntime/ASan/ASanRuntime.h"
+#include "Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h"
 #include "Plugins/InstrumentationRuntime/TSan/TSanRuntime.h"
 #include "Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.h"
-#include "Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.h"
 #include "Plugins/JITLoader/GDB/JITLoaderGDB.h"
 #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
 #include "Plugins/Language/Go/GoLanguage.h"
@@ -304,6 +305,9 @@
   ABISysV_mips::Initialize();
   ABISysV_mips64::Initialize();
   ABISysV_s390x::Initialize();
+
+  ArchitectureArm::Initialize();
+
   DisassemblerLLVMC::Initialize();
 
   JITLoaderGDB::Initialize();
Index: include/lldb/Target/Process.h
===================================================================
--- include/lldb/Target/Process.h
+++ include/lldb/Target/Process.h
@@ -28,6 +28,7 @@
 // Project includes
 #include "lldb/Breakpoint/BreakpointSiteList.h"
 #include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Architecture.h"
 #include "lldb/Core/Broadcaster.h"
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/Event.h"
@@ -2514,9 +2515,7 @@
 
   OperatingSystem *GetOperatingSystem() { return m_os_ap.get(); }
 
-  ArchSpec::StopInfoOverrideCallbackType GetStopInfoOverrideCallback() const {
-    return m_stop_info_override_callback;
-  }
+  Architecture *GetArchitecturePlugin() { return m_architecture_up.get(); }
 
   virtual LanguageRuntime *GetLanguageRuntime(lldb::LanguageType language,
                                               bool retry_if_null = true);
@@ -3082,6 +3081,7 @@
                                                          ///data that
                                                          ///expressions use.
   lldb::OperatingSystemUP m_os_ap;
+  std::unique_ptr<Architecture> m_architecture_up;
   lldb::SystemRuntimeUP m_system_runtime_ap;
   lldb::UnixSignalsSP
       m_unix_signals_sp; /// This is the current signal set for this process.
@@ -3106,7 +3106,6 @@
   std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions;
   ProcessRunLock m_public_run_lock;
   ProcessRunLock m_private_run_lock;
-  ArchSpec::StopInfoOverrideCallbackType m_stop_info_override_callback;
   bool m_currently_handling_do_on_removals;
   bool m_resume_requested; // If m_currently_handling_event or
                            // m_currently_handling_do_on_removals are true,
Index: include/lldb/Core/PluginManager.h
===================================================================
--- include/lldb/Core/PluginManager.h
+++ include/lldb/Core/PluginManager.h
@@ -10,6 +10,7 @@
 #ifndef liblldb_PluginManager_h_
 #define liblldb_PluginManager_h_
 
+#include "lldb/Core/Architecture.h"
 #include "lldb/Utility/FileSpec.h"
 #include "lldb/Utility/Status.h"          // for Status
 #include "lldb/lldb-enumerations.h"       // for ScriptLanguage
@@ -53,6 +54,21 @@
   static ABICreateInstance
   GetABICreateCallbackForPluginName(const ConstString &name);
 
+  //------------------------------------------------------------------
+  // Architecture
+  //------------------------------------------------------------------
+  using ArchitectureCreateInstance =
+      std::unique_ptr<Architecture> (*)(const ArchSpec &);
+
+  static void RegisterPlugin(const ConstString &name,
+                             llvm::StringRef description,
+                             ArchitectureCreateInstance create_callback);
+
+  static void UnregisterPlugin(ArchitectureCreateInstance create_callback);
+
+  static std::unique_ptr<Architecture>
+  CreateArchitectureInstance(const ArchSpec &arch);
+
   //------------------------------------------------------------------
   // Disassembler
   //------------------------------------------------------------------
Index: include/lldb/Core/Architecture.h
===================================================================
--- /dev/null
+++ include/lldb/Core/Architecture.h
@@ -0,0 +1,43 @@
+//===-- Architecture.h ------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_CORE_ARCHITECTURE_H
+#define LLDB_CORE_ARCHITECTURE_H
+
+#include "lldb/Core/PluginInterface.h"
+
+namespace lldb_private {
+
+class Architecture {
+public:
+  Architecture() = default;
+  virtual ~Architecture() = default;
+
+  //------------------------------------------------------------------
+  /// This is currently intended to handle cases where a
+  /// program stops at an instruction that won't get executed and it
+  /// allows the stop reasonm, like "breakpoint hit", to be replaced
+  /// with a different stop reason like "no stop reason".
+  ///
+  /// This is specifically used for ARM in Thumb code when we stop in
+  /// an IT instruction (if/then/else) where the instruction won't get
+  /// executed and therefore it wouldn't be correct to show the program
+  /// stopped at the current PC. The code is generic and applies to all
+  /// ARM CPUs.
+  //------------------------------------------------------------------
+  virtual void OverrideStopInfo(Thread &thread) = 0;
+
+private:
+  Architecture(const Architecture &) = delete;
+  void operator=(const Architecture &) = delete;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_CORE_ARCHITECTURE_H
Index: include/lldb/Core/ArchSpec.h
===================================================================
--- include/lldb/Core/ArchSpec.h
+++ include/lldb/Core/ArchSpec.h
@@ -25,16 +25,9 @@
 
 namespace lldb_private {
 class Platform;
-}
-namespace lldb_private {
 class Stream;
-}
-namespace lldb_private {
 class StringList;
 }
-namespace lldb_private {
-class Thread;
-}
 
 namespace lldb_private {
 
@@ -257,8 +250,6 @@
 
   };
 
-  typedef void (*StopInfoOverrideCallbackType)(lldb_private::Thread &thread);
-
   //------------------------------------------------------------------
   /// Default constructor.
   ///
@@ -573,29 +564,6 @@
   //------------------------------------------------------------------
   bool IsCompatibleMatch(const ArchSpec &rhs) const;
 
-  //------------------------------------------------------------------
-  /// Get a stop info override callback for the current architecture.
-  ///
-  /// Most platform specific code should go in lldb_private::Platform,
-  /// but there are cases where no matter which platform you are on
-  /// certain things hold true.
-  ///
-  /// This callback is currently intended to handle cases where a
-  /// program stops at an instruction that won't get executed and it
-  /// allows the stop reasonm, like "breakpoint hit", to be replaced
-  /// with a different stop reason like "no stop reason".
-  ///
-  /// This is specifically used for ARM in Thumb code when we stop in
-  /// an IT instruction (if/then/else) where the instruction won't get
-  /// executed and therefore it wouldn't be correct to show the program
-  /// stopped at the current PC. The code is generic and applies to all
-  /// ARM CPUs.
-  ///
-  /// @return NULL or a valid stop info override callback for the
-  ///     current architecture.
-  //------------------------------------------------------------------
-  StopInfoOverrideCallbackType GetStopInfoOverrideCallback() const;
-
   bool IsFullySpecifiedTriple() const;
 
   void PiecewiseTripleCompare(const ArchSpec &other, bool &arch_different,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to