tatyana-krasnukha updated this revision to Diff 183301.
tatyana-krasnukha added a comment.
Herald added subscribers: jsji, atanasyan, kbarton, nemanjai, sdardis.

Moved ARC flags enum inside the `ArchitectureArc` class;

Made `OverrideStopInfo` with empty body instead of being pure virtual. If this 
change is Ok I'll commit it before ARC support.


Repository:
  rLLDB LLDB

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

https://reviews.llvm.org/D55718

Files:
  include/lldb/Core/Architecture.h
  include/lldb/Utility/ArchSpec.h
  source/API/SystemInitializerFull.cpp
  source/Plugins/Architecture/Arc/ArchitectureArc.cpp
  source/Plugins/Architecture/Arc/ArchitectureArc.h
  source/Plugins/Architecture/Arc/CMakeLists.txt
  source/Plugins/Architecture/CMakeLists.txt
  source/Plugins/Architecture/Mips/ArchitectureMips.h
  source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
  source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
  source/Plugins/Process/Utility/DynamicRegisterInfo.h
  source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Target/Platform.cpp
  source/Target/Thread.cpp
  source/Utility/ArchSpec.cpp

Index: source/Utility/ArchSpec.cpp
===================================================================
--- source/Utility/ArchSpec.cpp
+++ source/Utility/ArchSpec.cpp
@@ -220,7 +220,8 @@
     {eByteOrderLittle, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba4,
      "kalimba4"},
     {eByteOrderLittle, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba5,
-     "kalimba5"}};
+     "kalimba5"},
+    {eByteOrderLittle, 4, 2, 4, llvm::Triple::arc, ArchSpec::eCore_arc, "arc"}};
 
 // Ensure that we have an entry in the g_core_definitions for each core. If you
 // comment out an entry above, you will need to comment out the corresponding
@@ -457,7 +458,9 @@
     {ArchSpec::eCore_kalimba4, llvm::ELF::EM_CSR_KALIMBA,
      llvm::Triple::KalimbaSubArch_v4, 0xFFFFFFFFu, 0xFFFFFFFFu}, // KALIMBA
     {ArchSpec::eCore_kalimba5, llvm::ELF::EM_CSR_KALIMBA,
-     llvm::Triple::KalimbaSubArch_v5, 0xFFFFFFFFu, 0xFFFFFFFFu} // KALIMBA
+     llvm::Triple::KalimbaSubArch_v5, 0xFFFFFFFFu, 0xFFFFFFFFu}, // KALIMBA
+    {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE,
+     0xFFFFFFFFu, 0xFFFFFFFFu } // ARC
 };
 
 static const ArchDefinition g_elf_arch_def = {
Index: source/Target/Thread.cpp
===================================================================
--- source/Target/Thread.cpp
+++ source/Target/Thread.cpp
@@ -2060,6 +2060,7 @@
     switch (machine) {
     case llvm::Triple::x86_64:
     case llvm::Triple::x86:
+    case llvm::Triple::arc:
     case llvm::Triple::arm:
     case llvm::Triple::aarch64:
     case llvm::Triple::thumb:
Index: source/Target/Platform.cpp
===================================================================
--- source/Target/Platform.cpp
+++ source/Target/Platform.cpp
@@ -1868,6 +1868,12 @@
   size_t trap_opcode_size = 0;
 
   switch (arch.GetMachine()) {
+  case llvm::Triple::arc: {
+    static const uint8_t g_hex_opcode[] = { 0xff, 0x7f };
+    trap_opcode = g_hex_opcode;
+    trap_opcode_size = sizeof(g_hex_opcode);
+  } break;
+
   case llvm::Triple::aarch64: {
     static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
     trap_opcode = g_aarch64_opcode;
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -70,6 +70,7 @@
 #include "lldb/Utility/Timer.h"
 
 #include "GDBRemoteRegisterContext.h"
+#include "Plugins/Architecture/Arc/ArchitectureArc.h"
 #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
 #include "Plugins/Process/Utility/GDBRemoteSignals.h"
 #include "Plugins/Process/Utility/InferiorCallPOSIX.h"
@@ -81,6 +82,8 @@
 #include "lldb/Utility/StringExtractorGDBRemote.h"
 
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Threading.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -1090,6 +1093,77 @@
   return error;
 }
 
+namespace arc {
+bool CheckArchitectureCompatibility(const ArchSpec &arch_spec,
+                                    Flags arch_features) {
+  return ((arch_spec.GetByteOrder() == eByteOrderBig) ==
+          arch_features.Test(ArchitectureArc::eBigEndian)) &&
+          ((arch_spec.GetAddressByteSize() == 4) ==
+          arch_features.Test(ArchitectureArc::eAddressSize32));
+}
+
+Status SetArchitectureFlags(ProcessGDBRemote &process,
+                            const DynamicRegisterInfo &registers,
+                            Architecture &arch) {
+  auto read_register_value = [&registers, &process] (ConstString reg_name)
+      -> llvm::Expected<uint32_t> {
+    bool case_sensitive = false;
+    auto reg_info = registers.GetRegisterInfo(reg_name, case_sensitive);
+    if (!reg_info)
+      return llvm::createStringError(llvm::errc::result_out_of_range,
+          "Cannot find register info for \"%s\"", reg_name.AsCString());
+
+    // Configuration registers are not context-dependent.
+    const auto tid = LLDB_INVALID_THREAD_ID;
+
+    // Cannot use GDBRemoteRegisterContext here, it is not created yet.
+    DataBufferSP buffer_sp = process.GetGDBRemote().ReadRegister(tid,
+      reg_info->kinds[eRegisterKindProcessPlugin]);
+    if (!buffer_sp || buffer_sp->GetByteSize() < reg_info->byte_size)
+      return llvm::createStringError(llvm::inconvertibleErrorCode(),
+          "Failed to read configuration register \"%s\"", reg_name.AsCString());
+
+    return RegisterValue(buffer_sp->GetBytes(), buffer_sp->GetByteSize(),
+                         process.GetByteOrder()).GetAsUInt32();
+  };
+
+  ConstString rf_build("rf_build");
+  auto expected_reg_value = read_register_value(rf_build);
+  if (!expected_reg_value)
+    return Status(expected_reg_value.takeError());
+
+  Flags flags_to_set;
+
+  // RF_BUILD "Number of Entries" bit.
+  const uint32_t rf_entries = 1 << 9;
+  if (expected_reg_value.get() & rf_entries)
+    flags_to_set.Set(ArchitectureArc::eReducedRegisterFile);
+
+  ConstString isa_config("isa_config");
+  expected_reg_value = read_register_value(isa_config);
+  if (!expected_reg_value)
+    return Status(expected_reg_value.takeError());
+
+  // ISA_CONFIG "Byte Order" bit.
+  const uint_least32_t byte_order = 1 << 20;
+  if (expected_reg_value.get() & byte_order)
+    flags_to_set.Set(ArchitectureArc::eBigEndian);
+
+  // ISA_CONFIG "Address Size" field.
+  const uint_least32_t addr_size = 4 << 16;
+  if (expected_reg_value.get() & addr_size)
+    flags_to_set.Set(ArchitectureArc::eAddressSize32);
+
+  if (CheckArchitectureCompatibility(process.GetTarget().GetArchitecture(),
+                                     flags_to_set))
+    arch.GetFlags().Set(flags_to_set.Get());
+  else
+    return Status("The architecture has incompatible features");
+
+  return Status();
+}
+} // namespace arc
+
 void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) {
   Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
   if (log)
@@ -1210,6 +1284,16 @@
         m_gdb_comm.GetSupportedStructuredDataPlugins();
     if (supported_packets_array)
       MapSupportedStructuredDataPlugins(*supported_packets_array);
+
+    if (llvm::Triple::arc == GetTarget().GetArchitecture().GetMachine()) {
+      auto arch_plugin = GetTarget().GetArchitecturePlugin();
+      if (nullptr != arch_plugin) {
+        auto status = arc::SetArchitectureFlags(*this, m_register_info,
+                                                *arch_plugin);
+        if (status.Fail() && log)
+          log->PutCString(status.AsCString());
+      }
+    }
   }
 }
 
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -344,7 +344,7 @@
                                   // not, we assume no limit
 
   // build the qSupported packet
-  std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"};
+  std::vector<std::string> features = {"xmlRegisters=i386,arm,mips,arc"};
   StreamString packet;
   packet.PutCString("qSupported");
   for (uint32_t i = 0; i < features.size(); ++i) {
Index: source/Plugins/Process/Utility/DynamicRegisterInfo.h
===================================================================
--- source/Plugins/Process/Utility/DynamicRegisterInfo.h
+++ source/Plugins/Process/Utility/DynamicRegisterInfo.h
@@ -51,6 +51,9 @@
 
   lldb_private::RegisterInfo *GetRegisterInfoAtIndex(uint32_t i);
 
+  const lldb_private::RegisterInfo *GetRegisterInfo(
+    const lldb_private::ConstString &reg_name, bool case_sensitive = true) const;
+
   const lldb_private::RegisterSet *GetRegisterSet(uint32_t i) const;
 
   uint32_t GetRegisterSetIndexByName(lldb_private::ConstString &set_name,
@@ -76,9 +79,6 @@
   typedef std::vector<uint8_t> dwarf_opcode;
   typedef std::map<uint32_t, dwarf_opcode> dynamic_reg_size_map;
 
-  const lldb_private::RegisterInfo *
-  GetRegisterInfo(const lldb_private::ConstString &reg_name) const;
-
   void MoveFrom(DynamicRegisterInfo &&info);
 
   reg_collection m_regs;
Index: source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
===================================================================
--- source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
+++ source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
@@ -621,6 +621,57 @@
       }
       break;
 
+    case llvm::Triple::arc:
+      {
+        enum ArgumentRegisters {
+            eArg1 = 0, eArg2, eArg3, eArg4, eArg5, eArg6, eArg7, eArg8 };
+        for (auto &reg : m_regs) {
+          if (strcmp(reg.name, "pc") == 0)
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+          else if ((strcmp(reg.name, "fp") == 0) ||
+                   (strcmp(reg.name, "r27") == 0))
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+          else if ((strcmp(reg.name, "sp") == 0) ||
+                   (strcmp(reg.name, "r28") == 0))
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+          else if ((strcmp(reg.name, "blink") == 0) ||
+                   (strcmp(reg.name, "r31") == 0))
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+          else if (strcmp(reg.name, "status32") == 0)
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+
+          switch (reg.kinds[eRegisterKindDWARF]) {
+          case eArg1:
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG1;
+            break;
+          case eArg2:
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG2;
+            break;
+          case eArg3:
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG3;
+            break;
+          case eArg4:
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG4;
+            break;
+          case eArg5:
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG5;
+            break;
+          case eArg6:
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG6;
+            break;
+          case eArg7:
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG7;
+            break;
+          case eArg8:
+            reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_ARG8;
+            break;
+          default:
+            break;
+          }
+        }
+      }
+      break;
+
     default:
       break;
     }
@@ -746,13 +797,10 @@
 }
 
 const lldb_private::RegisterInfo *DynamicRegisterInfo::GetRegisterInfo(
-    const lldb_private::ConstString &reg_name) const {
-  for (auto &reg_info : m_regs) {
-    // We can use pointer comparison since we used a ConstString to set the
-    // "name" member in AddRegister()
-    if (reg_info.name == reg_name.GetCString()) {
+    const lldb_private::ConstString &reg_name, bool case_sensitive) const {
+  for (const auto &reg_info : m_regs) {
+    if (ConstString::Equals(ConstString(reg_info.name), reg_name, case_sensitive))
       return &reg_info;
-    }
   }
-  return NULL;
+  return nullptr;
 }
Index: source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
===================================================================
--- source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
+++ source/Plugins/Architecture/PPC64/ArchitecturePPC64.h
@@ -22,8 +22,6 @@
   ConstString GetPluginName() override;
   uint32_t GetPluginVersion() override;
 
-  void OverrideStopInfo(Thread &thread) const override {}
-
   //------------------------------------------------------------------
   /// This method compares current address with current function's
   /// local entry point, returning the bytes to skip if they match.
Index: source/Plugins/Architecture/Mips/ArchitectureMips.h
===================================================================
--- source/Plugins/Architecture/Mips/ArchitectureMips.h
+++ source/Plugins/Architecture/Mips/ArchitectureMips.h
@@ -23,8 +23,6 @@
   ConstString GetPluginName() override;
   uint32_t GetPluginVersion() override;
 
-  void OverrideStopInfo(Thread &thread) const override {}
-
   lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr,
                                        Target &) const override;
 
Index: source/Plugins/Architecture/CMakeLists.txt
===================================================================
--- source/Plugins/Architecture/CMakeLists.txt
+++ source/Plugins/Architecture/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(Arc)
 add_subdirectory(Arm)
 add_subdirectory(Mips)
 add_subdirectory(PPC64)
Index: source/Plugins/Architecture/Arc/CMakeLists.txt
===================================================================
--- source/Plugins/Architecture/Arc/CMakeLists.txt
+++ source/Plugins/Architecture/Arc/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_lldb_library(lldbPluginArchitectureArc PLUGIN
+  ArchitectureArc.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbTarget
+    lldbUtility
+  LINK_COMPONENTS
+    Support
+  )
Index: source/Plugins/Architecture/Arc/ArchitectureArc.h
===================================================================
--- source/Plugins/Architecture/Arc/ArchitectureArc.h
+++ source/Plugins/Architecture/Arc/ArchitectureArc.h
@@ -0,0 +1,39 @@
+//===-- ArchitectureArc.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_ARC_H
+#define LLDB_PLUGIN_ARCHITECTURE_ARC_H
+
+#include "lldb/Core/Architecture.h"
+
+namespace lldb_private {
+
+class ArchitectureArc : public Architecture {
+public:
+  FLAGS_ANONYMOUS_ENUM() {
+    eReducedRegisterFile = (1u << 0),
+    eBigEndian = (1u << 1),
+    eAddressSize32 = (1u << 2)
+  };
+
+  static ConstString GetPluginNameStatic();
+  static void Initialize();
+  static void Terminate();
+
+  ConstString GetPluginName() override;
+  uint32_t GetPluginVersion() override;
+
+private:
+  static std::unique_ptr<Architecture> Create(const ArchSpec &arch);
+  ArchitectureArc() = default;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_PLUGIN_ARCHITECTURE_ARC_H
Index: source/Plugins/Architecture/Arc/ArchitectureArc.cpp
===================================================================
--- source/Plugins/Architecture/Arc/ArchitectureArc.cpp
+++ source/Plugins/Architecture/Arc/ArchitectureArc.cpp
@@ -0,0 +1,38 @@
+//===-- ArchitectureArc.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/Arc/ArchitectureArc.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Utility/ArchSpec.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+ConstString ArchitectureArc::GetPluginNameStatic() {
+  return ConstString("arc");
+}
+
+void ArchitectureArc::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                "ARC-specific algorithms",
+                                &ArchitectureArc::Create);
+}
+
+void ArchitectureArc::Terminate() {
+  PluginManager::UnregisterPlugin(&ArchitectureArc::Create);
+}
+
+std::unique_ptr<Architecture> ArchitectureArc::Create(const ArchSpec &arch) {
+  if (arch.GetMachine() != llvm::Triple::arc)
+    return nullptr;
+  return std::unique_ptr<Architecture>(new ArchitectureArc());
+}
+
+ConstString ArchitectureArc::GetPluginName() { return GetPluginNameStatic(); }
+uint32_t ArchitectureArc::GetPluginVersion() { return 1; }
Index: source/API/SystemInitializerFull.cpp
===================================================================
--- source/API/SystemInitializerFull.cpp
+++ source/API/SystemInitializerFull.cpp
@@ -38,6 +38,7 @@
 #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/Arc/ArchitectureArc.h"
 #include "Plugins/Architecture/Arm/ArchitectureArm.h"
 #include "Plugins/Architecture/Mips/ArchitectureMips.h"
 #include "Plugins/Architecture/PPC64/ArchitecturePPC64.h"
@@ -326,6 +327,7 @@
   ABISysV_mips64::Initialize();
   ABISysV_s390x::Initialize();
 
+  ArchitectureArc::Initialize();
   ArchitectureArm::Initialize();
   ArchitectureMips::Initialize();
   ArchitecturePPC64::Initialize();
@@ -443,6 +445,7 @@
 
   ClangASTContext::Terminate();
 
+  ArchitectureArc::Terminate();
   ArchitectureArm::Terminate();
   ArchitectureMips::Terminate();
   ArchitecturePPC64::Terminate();
Index: include/lldb/Utility/ArchSpec.h
===================================================================
--- include/lldb/Utility/ArchSpec.h
+++ include/lldb/Utility/ArchSpec.h
@@ -189,6 +189,8 @@
     eCore_kalimba4,
     eCore_kalimba5,
 
+    eCore_arc, // little endian ARC
+
     kNumCores,
 
     kCore_invalid,
Index: include/lldb/Core/Architecture.h
===================================================================
--- include/lldb/Core/Architecture.h
+++ include/lldb/Core/Architecture.h
@@ -10,6 +10,7 @@
 #define LLDB_CORE_ARCHITECTURE_H
 
 #include "lldb/Core/PluginInterface.h"
+#include "lldb/Utility/Flags.h"
 
 namespace lldb_private {
 
@@ -30,7 +31,7 @@
   /// stopped at the current PC. The code is generic and applies to all
   /// ARM CPUs.
   //------------------------------------------------------------------
-  virtual void OverrideStopInfo(Thread &thread) const = 0;
+  virtual void OverrideStopInfo(Thread &thread) const {}
 
   //------------------------------------------------------------------
   /// This method is used to get the number of bytes that should be
@@ -111,9 +112,14 @@
     return addr;
   }
 
+  const Flags &GetFlags() const { return m_flags; }
+  Flags &GetFlags() { return m_flags; }
+
 private:
   Architecture(const Architecture &) = delete;
   void operator=(const Architecture &) = delete;
+
+  Flags m_flags;
 };
 
 } // namespace lldb_private
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to