zturner created this revision.
Herald added a subscriber: mgorny.

This completely removes the dependency from `lldbUtility` -> `lldbCore` and 
`lldbTarget`.  This was done with the following restructure:

1. `ProcessStructReader`: `Utility` -> `Target`
2. `ModuleCache`: `Utility` -> `Target`
3. `RegisterNumber`: `Utility` -> `Target`

4. `Endian`: `Host` -> `Utility`
5. `Flags`: `Core` -> `Utility`

This is enforced in the CMake by removing `lldbCore` and `lldbUtility` as 
linker inputs to both the `lldbUtility` target as well as the `UtilityTests` 
gtest target.

Unfortunately we are still requiring the dependency on `lldbHost`, which in 
turn depends on everything else, so for now we are still linking against `Core` 
and `Utility` transitively.  After the dependency on `Host` is broken, this 
effort will be complete.  But that is the only remaining step.


https://reviews.llvm.org/D29909

Files:
  lldb/include/lldb/Core/Flags.h
  lldb/include/lldb/Host/Endian.h
  lldb/include/lldb/Target/ModuleCache.h
  lldb/include/lldb/Target/ProcessStructReader.h
  lldb/include/lldb/Target/RegisterNumber.h
  lldb/include/lldb/Utility/Endian.h
  lldb/include/lldb/Utility/Flags.h
  lldb/include/lldb/Utility/ProcessStructReader.h
  lldb/include/lldb/Utility/PseudoTerminal.h
  lldb/include/lldb/Utility/RegisterNumber.h
  lldb/include/lldb/Utility/Stream.h
  lldb/source/Target/CMakeLists.txt
  lldb/source/Target/ModuleCache.cpp
  lldb/source/Target/Platform.cpp
  lldb/source/Target/RegisterContext.cpp
  lldb/source/Target/RegisterNumber.cpp
  lldb/source/Utility/CMakeLists.txt
  lldb/source/Utility/ModuleCache.cpp
  lldb/source/Utility/ModuleCache.h
  lldb/source/Utility/RegisterNumber.cpp
  lldb/unittests/CMakeLists.txt
  lldb/unittests/Target/CMakeLists.txt
  lldb/unittests/Target/Inputs/TestModule.c
  lldb/unittests/Target/ModuleCacheTest.cpp
  lldb/unittests/Utility/CMakeLists.txt
  lldb/unittests/Utility/Inputs/TestModule.c
  lldb/unittests/Utility/Inputs/TestModule.so
  lldb/unittests/Utility/ModuleCacheTest.cpp

Index: lldb/unittests/Utility/ModuleCacheTest.cpp
===================================================================
--- lldb/unittests/Utility/ModuleCacheTest.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-#include "gtest/gtest.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-
-#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
-#include "Utility/ModuleCache.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Symbol/SymbolContext.h"
-
-extern const char *TestMainArgv0;
-
-using namespace lldb_private;
-using namespace lldb;
-
-namespace {
-
-class ModuleCacheTest : public testing::Test {
-public:
-  static void SetUpTestCase();
-
-  static void TearDownTestCase();
-
-protected:
-  static FileSpec s_cache_dir;
-  static llvm::SmallString<128> s_test_executable;
-
-  void TryGetAndPut(const FileSpec &cache_dir, const char *hostname,
-                    bool expect_download);
-};
-}
-
-FileSpec ModuleCacheTest::s_cache_dir;
-llvm::SmallString<128> ModuleCacheTest::s_test_executable;
-
-static const char dummy_hostname[] = "dummy_hostname";
-static const char dummy_remote_dir[] = "bin";
-static const char module_name[] = "TestModule.so";
-static const char module_uuid[] =
-    "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476";
-static const uint32_t uuid_bytes = 20;
-static const size_t module_size = 5602;
-
-static FileSpec GetDummyRemotePath() {
-  FileSpec fs("/", false, FileSpec::ePathSyntaxPosix);
-  fs.AppendPathComponent(dummy_remote_dir);
-  fs.AppendPathComponent(module_name);
-  return fs;
-}
-
-static FileSpec GetUuidView(FileSpec spec) {
-  spec.AppendPathComponent(".cache");
-  spec.AppendPathComponent(module_uuid);
-  spec.AppendPathComponent(module_name);
-  return spec;
-}
-
-static FileSpec GetSysrootView(FileSpec spec, const char *hostname) {
-  spec.AppendPathComponent(hostname);
-  spec.AppendPathComponent(dummy_remote_dir);
-  spec.AppendPathComponent(module_name);
-  return spec;
-}
-
-void ModuleCacheTest::SetUpTestCase() {
-  HostInfo::Initialize();
-  ObjectFileELF::Initialize();
-
-  FileSpec tmpdir_spec;
-  HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, s_cache_dir);
-
-  llvm::StringRef exe_folder = llvm::sys::path::parent_path(TestMainArgv0);
-  s_test_executable = exe_folder;
-  llvm::sys::path::append(s_test_executable, "Inputs", module_name);
-}
-
-void ModuleCacheTest::TearDownTestCase() {
-  ObjectFileELF::Terminate();
-  HostInfo::Terminate();
-}
-
-static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) {
-  FileSpec uuid_view = GetUuidView(cache_dir);
-  EXPECT_TRUE(uuid_view.Exists()) << "uuid_view is: " << uuid_view.GetCString();
-  EXPECT_EQ(module_size, uuid_view.GetByteSize());
-
-  FileSpec sysroot_view = GetSysrootView(cache_dir, hostname);
-  EXPECT_TRUE(sysroot_view.Exists()) << "sysroot_view is: "
-                                     << sysroot_view.GetCString();
-  EXPECT_EQ(module_size, sysroot_view.GetByteSize());
-}
-
-void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir,
-                                   const char *hostname, bool expect_download) {
-  ModuleCache mc;
-  ModuleSpec module_spec;
-  module_spec.GetFileSpec() = GetDummyRemotePath();
-  module_spec.GetUUID().SetFromCString(module_uuid, uuid_bytes);
-  module_spec.SetObjectSize(module_size);
-  ModuleSP module_sp;
-  bool did_create;
-  bool download_called = false;
-
-  Error error = mc.GetAndPut(
-      cache_dir, hostname, module_spec,
-      [this, &download_called](const ModuleSpec &module_spec,
-                               const FileSpec &tmp_download_file_spec) {
-        download_called = true;
-        EXPECT_STREQ(GetDummyRemotePath().GetCString(),
-                     module_spec.GetFileSpec().GetCString());
-        std::error_code ec = llvm::sys::fs::copy_file(
-            s_test_executable, tmp_download_file_spec.GetCString());
-        EXPECT_FALSE(ec);
-        return Error();
-      },
-      [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) {
-        return Error("Not supported.");
-      },
-      module_sp, &did_create);
-  EXPECT_EQ(expect_download, download_called);
-
-  EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString();
-  EXPECT_TRUE(did_create);
-  ASSERT_TRUE(bool(module_sp));
-
-  SymbolContextList sc_list;
-  EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"),
-                                               eFunctionNameTypeFull, sc_list));
-  EXPECT_STREQ(GetDummyRemotePath().GetCString(),
-               module_sp->GetPlatformFileSpec().GetCString());
-  EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str());
-}
-
-TEST_F(ModuleCacheTest, GetAndPut) {
-  FileSpec test_cache_dir = s_cache_dir;
-  test_cache_dir.AppendPathComponent("GetAndPut");
-
-  const bool expect_download = true;
-  TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
-  VerifyDiskState(test_cache_dir, dummy_hostname);
-}
-
-TEST_F(ModuleCacheTest, GetAndPutUuidExists) {
-  FileSpec test_cache_dir = s_cache_dir;
-  test_cache_dir.AppendPathComponent("GetAndPutUuidExists");
-
-  FileSpec uuid_view = GetUuidView(test_cache_dir);
-  std::error_code ec =
-      llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString());
-  ASSERT_FALSE(ec);
-  ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString());
-  ASSERT_FALSE(ec);
-
-  const bool expect_download = false;
-  TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
-  VerifyDiskState(test_cache_dir, dummy_hostname);
-}
-
-TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) {
-  FileSpec test_cache_dir = s_cache_dir;
-  test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname");
-
-  const bool expect_download = true;
-  TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download);
-  VerifyDiskState(test_cache_dir, "tab_colon_asterisk_");
-}
Index: lldb/unittests/Utility/Inputs/TestModule.c
===================================================================
--- lldb/unittests/Utility/Inputs/TestModule.c
+++ /dev/null
@@ -1,9 +0,0 @@
-// Compile with $CC -nostdlib -shared TestModule.c -o TestModule.so
-// The actual contents of the test module is not important here. I am using this
-// because it
-// produces an extremely tiny (but still perfectly valid) module.
-
-void boom(void) {
-  char *BOOM;
-  *BOOM = 47;
-}
Index: lldb/unittests/Utility/CMakeLists.txt
===================================================================
--- lldb/unittests/Utility/CMakeLists.txt
+++ lldb/unittests/Utility/CMakeLists.txt
@@ -1,19 +1,13 @@
 add_lldb_unittest(UtilityTests
   ConstStringTest.cpp
-  ModuleCacheTest.cpp
   StringExtractorTest.cpp
   TaskPoolTest.cpp
   TimeoutTest.cpp
   UriParserTest.cpp
 
   LINK_LIBS
-      lldbCore
       lldbHost
-      lldbSymbol
       lldbUtility
-      lldbPluginObjectFileELF
     LINK_COMPONENTS
       Support
   )
-
-add_unittest_inputs(UtilityTests TestModule.so)
Index: lldb/unittests/Target/ModuleCacheTest.cpp
===================================================================
--- /dev/null
+++ lldb/unittests/Target/ModuleCacheTest.cpp
@@ -0,0 +1,169 @@
+#include "gtest/gtest.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/ModuleCache.h"
+
+extern const char *TestMainArgv0;
+
+using namespace lldb_private;
+using namespace lldb;
+
+namespace {
+
+class ModuleCacheTest : public testing::Test {
+public:
+  static void SetUpTestCase();
+
+  static void TearDownTestCase();
+
+protected:
+  static FileSpec s_cache_dir;
+  static llvm::SmallString<128> s_test_executable;
+
+  void TryGetAndPut(const FileSpec &cache_dir, const char *hostname,
+                    bool expect_download);
+};
+}
+
+FileSpec ModuleCacheTest::s_cache_dir;
+llvm::SmallString<128> ModuleCacheTest::s_test_executable;
+
+static const char dummy_hostname[] = "dummy_hostname";
+static const char dummy_remote_dir[] = "bin";
+static const char module_name[] = "TestModule.so";
+static const char module_uuid[] =
+    "F4E7E991-9B61-6AD4-0073-561AC3D9FA10-C043A476";
+static const uint32_t uuid_bytes = 20;
+static const size_t module_size = 5602;
+
+static FileSpec GetDummyRemotePath() {
+  FileSpec fs("/", false, FileSpec::ePathSyntaxPosix);
+  fs.AppendPathComponent(dummy_remote_dir);
+  fs.AppendPathComponent(module_name);
+  return fs;
+}
+
+static FileSpec GetUuidView(FileSpec spec) {
+  spec.AppendPathComponent(".cache");
+  spec.AppendPathComponent(module_uuid);
+  spec.AppendPathComponent(module_name);
+  return spec;
+}
+
+static FileSpec GetSysrootView(FileSpec spec, const char *hostname) {
+  spec.AppendPathComponent(hostname);
+  spec.AppendPathComponent(dummy_remote_dir);
+  spec.AppendPathComponent(module_name);
+  return spec;
+}
+
+void ModuleCacheTest::SetUpTestCase() {
+  HostInfo::Initialize();
+  ObjectFileELF::Initialize();
+
+  FileSpec tmpdir_spec;
+  HostInfo::GetLLDBPath(lldb::ePathTypeLLDBTempSystemDir, s_cache_dir);
+
+  llvm::StringRef exe_folder = llvm::sys::path::parent_path(TestMainArgv0);
+  s_test_executable = exe_folder;
+  llvm::sys::path::append(s_test_executable, "Inputs", module_name);
+}
+
+void ModuleCacheTest::TearDownTestCase() {
+  ObjectFileELF::Terminate();
+  HostInfo::Terminate();
+}
+
+static void VerifyDiskState(const FileSpec &cache_dir, const char *hostname) {
+  FileSpec uuid_view = GetUuidView(cache_dir);
+  EXPECT_TRUE(uuid_view.Exists()) << "uuid_view is: " << uuid_view.GetCString();
+  EXPECT_EQ(module_size, uuid_view.GetByteSize());
+
+  FileSpec sysroot_view = GetSysrootView(cache_dir, hostname);
+  EXPECT_TRUE(sysroot_view.Exists()) << "sysroot_view is: "
+                                     << sysroot_view.GetCString();
+  EXPECT_EQ(module_size, sysroot_view.GetByteSize());
+}
+
+void ModuleCacheTest::TryGetAndPut(const FileSpec &cache_dir,
+                                   const char *hostname, bool expect_download) {
+  ModuleCache mc;
+  ModuleSpec module_spec;
+  module_spec.GetFileSpec() = GetDummyRemotePath();
+  module_spec.GetUUID().SetFromCString(module_uuid, uuid_bytes);
+  module_spec.SetObjectSize(module_size);
+  ModuleSP module_sp;
+  bool did_create;
+  bool download_called = false;
+
+  Error error = mc.GetAndPut(
+      cache_dir, hostname, module_spec,
+      [this, &download_called](const ModuleSpec &module_spec,
+                               const FileSpec &tmp_download_file_spec) {
+        download_called = true;
+        EXPECT_STREQ(GetDummyRemotePath().GetCString(),
+                     module_spec.GetFileSpec().GetCString());
+        std::error_code ec = llvm::sys::fs::copy_file(
+            s_test_executable, tmp_download_file_spec.GetCString());
+        EXPECT_FALSE(ec);
+        return Error();
+      },
+      [](const ModuleSP &module_sp, const FileSpec &tmp_download_file_spec) {
+        return Error("Not supported.");
+      },
+      module_sp, &did_create);
+  EXPECT_EQ(expect_download, download_called);
+
+  EXPECT_TRUE(error.Success()) << "Error was: " << error.AsCString();
+  EXPECT_TRUE(did_create);
+  ASSERT_TRUE(bool(module_sp));
+
+  SymbolContextList sc_list;
+  EXPECT_EQ(1u, module_sp->FindFunctionSymbols(ConstString("boom"),
+                                               eFunctionNameTypeFull, sc_list));
+  EXPECT_STREQ(GetDummyRemotePath().GetCString(),
+               module_sp->GetPlatformFileSpec().GetCString());
+  EXPECT_STREQ(module_uuid, module_sp->GetUUID().GetAsString().c_str());
+}
+
+TEST_F(ModuleCacheTest, GetAndPut) {
+  FileSpec test_cache_dir = s_cache_dir;
+  test_cache_dir.AppendPathComponent("GetAndPut");
+
+  const bool expect_download = true;
+  TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
+  VerifyDiskState(test_cache_dir, dummy_hostname);
+}
+
+TEST_F(ModuleCacheTest, GetAndPutUuidExists) {
+  FileSpec test_cache_dir = s_cache_dir;
+  test_cache_dir.AppendPathComponent("GetAndPutUuidExists");
+
+  FileSpec uuid_view = GetUuidView(test_cache_dir);
+  std::error_code ec =
+      llvm::sys::fs::create_directories(uuid_view.GetDirectory().GetCString());
+  ASSERT_FALSE(ec);
+  ec = llvm::sys::fs::copy_file(s_test_executable, uuid_view.GetCString());
+  ASSERT_FALSE(ec);
+
+  const bool expect_download = false;
+  TryGetAndPut(test_cache_dir, dummy_hostname, expect_download);
+  VerifyDiskState(test_cache_dir, dummy_hostname);
+}
+
+TEST_F(ModuleCacheTest, GetAndPutStrangeHostname) {
+  FileSpec test_cache_dir = s_cache_dir;
+  test_cache_dir.AppendPathComponent("GetAndPutStrangeHostname");
+
+  const bool expect_download = true;
+  TryGetAndPut(test_cache_dir, "tab\tcolon:asterisk*", expect_download);
+  VerifyDiskState(test_cache_dir, "tab_colon_asterisk_");
+}
Index: lldb/unittests/Target/Inputs/TestModule.c
===================================================================
--- /dev/null
+++ lldb/unittests/Target/Inputs/TestModule.c
@@ -0,0 +1,9 @@
+// Compile with $CC -nostdlib -shared TestModule.c -o TestModule.so
+// The actual contents of the test module is not important here. I am using this
+// because it
+// produces an extremely tiny (but still perfectly valid) module.
+
+void boom(void) {
+  char *BOOM;
+  *BOOM = 47;
+}
Index: lldb/unittests/Target/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/unittests/Target/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_lldb_unittest(TargetTests
+  ModuleCacheTest.cpp
+
+  LINK_LIBS
+      lldbCore
+      lldbHost
+      lldbSymbol
+      lldbUtility
+      lldbPluginObjectFileELF
+    LINK_COMPONENTS
+      Support
+  )
+
+add_unittest_inputs(TargetTests TestModule.so)
Index: lldb/unittests/CMakeLists.txt
===================================================================
--- lldb/unittests/CMakeLists.txt
+++ lldb/unittests/CMakeLists.txt
@@ -66,5 +66,6 @@
 add_subdirectory(ScriptInterpreter)
 add_subdirectory(Symbol)
 add_subdirectory(SymbolFile)
+add_subdirectory(Target)
 add_subdirectory(UnwindAssembly)
 add_subdirectory(Utility)
Index: lldb/source/Utility/RegisterNumber.cpp
===================================================================
--- lldb/source/Utility/RegisterNumber.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-//===--------------------- RegisterNumber.cpp -------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/RegisterNumber.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Thread.h"
-
-using namespace lldb_private;
-
-RegisterNumber::RegisterNumber(lldb_private::Thread &thread,
-                               lldb::RegisterKind kind, uint32_t num)
-    : m_reg_ctx_sp(thread.GetRegisterContext()), m_regnum(num), m_kind(kind),
-      m_kind_regnum_map(), m_name("") {
-  if (m_reg_ctx_sp.get()) {
-    const lldb_private::RegisterInfo *reginfo =
-        m_reg_ctx_sp->GetRegisterInfoAtIndex(
-            GetAsKind(lldb::eRegisterKindLLDB));
-    if (reginfo && reginfo->name) {
-      m_name = reginfo->name;
-    }
-  }
-}
-
-RegisterNumber::RegisterNumber()
-    : m_reg_ctx_sp(), m_regnum(LLDB_INVALID_REGNUM),
-      m_kind(lldb::kNumRegisterKinds), m_kind_regnum_map(), m_name(nullptr) {}
-
-void RegisterNumber::init(lldb_private::Thread &thread, lldb::RegisterKind kind,
-                          uint32_t num) {
-  m_reg_ctx_sp = thread.GetRegisterContext();
-  m_regnum = num;
-  m_kind = kind;
-  if (m_reg_ctx_sp.get()) {
-    const lldb_private::RegisterInfo *reginfo =
-        m_reg_ctx_sp->GetRegisterInfoAtIndex(
-            GetAsKind(lldb::eRegisterKindLLDB));
-    if (reginfo && reginfo->name) {
-      m_name = reginfo->name;
-    }
-  }
-}
-
-const RegisterNumber &RegisterNumber::operator=(const RegisterNumber &rhs) {
-  m_reg_ctx_sp = rhs.m_reg_ctx_sp;
-  m_regnum = rhs.m_regnum;
-  m_kind = rhs.m_kind;
-  for (auto it : rhs.m_kind_regnum_map)
-    m_kind_regnum_map[it.first] = it.second;
-  m_name = rhs.m_name;
-  return *this;
-}
-
-bool RegisterNumber::operator==(RegisterNumber &rhs) {
-  if (IsValid() != rhs.IsValid())
-    return false;
-
-  if (m_kind == rhs.m_kind) {
-    if (m_regnum == rhs.m_regnum)
-      return true;
-    else
-      return false;
-  }
-
-  uint32_t rhs_regnum = rhs.GetAsKind(m_kind);
-  if (rhs_regnum != LLDB_INVALID_REGNUM) {
-    if (m_regnum == rhs_regnum)
-      return true;
-    else
-      return false;
-  }
-  uint32_t lhs_regnum = GetAsKind(rhs.m_kind);
-  {
-    if (lhs_regnum == rhs.m_regnum)
-      return true;
-    else
-      return false;
-  }
-  return false;
-}
-
-bool RegisterNumber::operator!=(RegisterNumber &rhs) { return !(*this == rhs); }
-
-bool RegisterNumber::IsValid() const {
-  return m_reg_ctx_sp.get() && m_kind != lldb::kNumRegisterKinds &&
-         m_regnum != LLDB_INVALID_REGNUM;
-}
-
-uint32_t RegisterNumber::GetAsKind(lldb::RegisterKind kind) {
-  if (m_regnum == LLDB_INVALID_REGNUM)
-    return LLDB_INVALID_REGNUM;
-
-  if (kind == m_kind)
-    return m_regnum;
-
-  Collection::iterator iter = m_kind_regnum_map.find(kind);
-  if (iter != m_kind_regnum_map.end()) {
-    return iter->second;
-  }
-  uint32_t output_regnum = LLDB_INVALID_REGNUM;
-  if (m_reg_ctx_sp &&
-      m_reg_ctx_sp->ConvertBetweenRegisterKinds(m_kind, m_regnum, kind,
-                                                output_regnum) &&
-      output_regnum != LLDB_INVALID_REGNUM) {
-    m_kind_regnum_map[kind] = output_regnum;
-  }
-  return output_regnum;
-}
-
-uint32_t RegisterNumber::GetRegisterNumber() const { return m_regnum; }
-
-lldb::RegisterKind RegisterNumber::GetRegisterKind() const { return m_kind; }
-
-const char *RegisterNumber::GetName() { return m_name; }
Index: lldb/source/Utility/ModuleCache.h
===================================================================
--- lldb/source/Utility/ModuleCache.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//===-- ModuleCache.h -------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef utility_ModuleCache_h_
-#define utility_ModuleCache_h_
-
-#include "lldb/lldb-forward.h"
-#include "lldb/lldb-types.h"
-
-#include "lldb/Host/File.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Utility/Error.h"
-
-#include <functional>
-#include <string>
-#include <unordered_map>
-
-namespace lldb_private {
-
-class Module;
-class UUID;
-
-//----------------------------------------------------------------------
-/// @class ModuleCache ModuleCache.h "Utility/ModuleCache.h"
-/// @brief A module cache class.
-///
-/// Caches locally modules that are downloaded from remote targets.
-/// Each cached module maintains 2 views:
-///  - UUID view:
-///  /${CACHE_ROOT}/${PLATFORM_NAME}/.cache/${UUID}/${MODULE_FILENAME}
-///  - Sysroot view:
-///  /${CACHE_ROOT}/${PLATFORM_NAME}/${HOSTNAME}/${MODULE_FULL_FILEPATH}
-///
-/// UUID views stores a real module file, whereas Sysroot view holds a symbolic
-/// link to UUID-view file.
-///
-/// Example:
-/// UUID view   :
-/// /tmp/lldb/remote-linux/.cache/30C94DC6-6A1F-E951-80C3-D68D2B89E576-D5AE213C/libc.so.6
-/// Sysroot view: /tmp/lldb/remote-linux/ubuntu/lib/x86_64-linux-gnu/libc.so.6
-//----------------------------------------------------------------------
-
-class ModuleCache {
-public:
-  using ModuleDownloader =
-      std::function<Error(const ModuleSpec &, const FileSpec &)>;
-  using SymfileDownloader =
-      std::function<Error(const lldb::ModuleSP &, const FileSpec &)>;
-
-  Error GetAndPut(const FileSpec &root_dir_spec, const char *hostname,
-                  const ModuleSpec &module_spec,
-                  const ModuleDownloader &module_downloader,
-                  const SymfileDownloader &symfile_downloader,
-                  lldb::ModuleSP &cached_module_sp, bool *did_create_ptr);
-
-private:
-  Error Put(const FileSpec &root_dir_spec, const char *hostname,
-            const ModuleSpec &module_spec, const FileSpec &tmp_file,
-            const FileSpec &target_file);
-
-  Error Get(const FileSpec &root_dir_spec, const char *hostname,
-            const ModuleSpec &module_spec, lldb::ModuleSP &cached_module_sp,
-            bool *did_create_ptr);
-
-  std::unordered_map<std::string, lldb::ModuleWP> m_loaded_modules;
-};
-
-} // namespace lldb_private
-
-#endif // utility_ModuleCache_h_
Index: lldb/source/Utility/ModuleCache.cpp
===================================================================
--- lldb/source/Utility/ModuleCache.cpp
+++ /dev/null
@@ -1,336 +0,0 @@
-//===--------------------- ModuleCache.cpp ----------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ModuleCache.h"
-
-#include "lldb/Core/Log.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/File.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/LockFile.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/FileUtilities.h"
-
-#include <assert.h>
-
-#include <cstdio>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-const char *kModulesSubdir = ".cache";
-const char *kLockDirName = ".lock";
-const char *kTempFileName = ".temp";
-const char *kTempSymFileName = ".symtemp";
-const char *kSymFileExtension = ".sym";
-const char *kFSIllegalChars = "\\/:*?\"<>|";
-
-std::string GetEscapedHostname(const char *hostname) {
-  if (hostname == nullptr)
-    hostname = "unknown";
-  std::string result(hostname);
-  size_t size = result.size();
-  for (size_t i = 0; i < size; ++i) {
-    if ((result[i] >= 1 && result[i] <= 31) ||
-        strchr(kFSIllegalChars, result[i]) != nullptr)
-      result[i] = '_';
-  }
-  return result;
-}
-
-class ModuleLock {
-private:
-  File m_file;
-  std::unique_ptr<lldb_private::LockFile> m_lock;
-  FileSpec m_file_spec;
-
-public:
-  ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid, Error &error);
-  void Delete();
-};
-
-FileSpec JoinPath(const FileSpec &path1, const char *path2) {
-  FileSpec result_spec(path1);
-  result_spec.AppendPathComponent(path2);
-  return result_spec;
-}
-
-Error MakeDirectory(const FileSpec &dir_path) {
-  if (dir_path.Exists()) {
-    if (!dir_path.IsDirectory())
-      return Error("Invalid existing path");
-
-    return Error();
-  }
-
-  return FileSystem::MakeDirectory(dir_path, eFilePermissionsDirectoryDefault);
-}
-
-FileSpec GetModuleDirectory(const FileSpec &root_dir_spec, const UUID &uuid) {
-  const auto modules_dir_spec = JoinPath(root_dir_spec, kModulesSubdir);
-  return JoinPath(modules_dir_spec, uuid.GetAsString().c_str());
-}
-
-FileSpec GetSymbolFileSpec(const FileSpec &module_file_spec) {
-  return FileSpec(module_file_spec.GetPath() + kSymFileExtension, false);
-}
-
-void DeleteExistingModule(const FileSpec &root_dir_spec,
-                          const FileSpec &sysroot_module_path_spec) {
-  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
-  UUID module_uuid;
-  {
-    auto module_sp =
-        std::make_shared<Module>(ModuleSpec(sysroot_module_path_spec));
-    module_uuid = module_sp->GetUUID();
-  }
-
-  if (!module_uuid.IsValid())
-    return;
-
-  Error error;
-  ModuleLock lock(root_dir_spec, module_uuid, error);
-  if (error.Fail()) {
-    if (log)
-      log->Printf("Failed to lock module %s: %s",
-                  module_uuid.GetAsString().c_str(), error.AsCString());
-  }
-
-  auto link_count = FileSystem::GetHardlinkCount(sysroot_module_path_spec);
-  if (link_count == -1)
-    return;
-
-  if (link_count > 2) // module is referred by other hosts.
-    return;
-
-  const auto module_spec_dir = GetModuleDirectory(root_dir_spec, module_uuid);
-  FileSystem::DeleteDirectory(module_spec_dir, true);
-  lock.Delete();
-}
-
-void DecrementRefExistingModule(const FileSpec &root_dir_spec,
-                                const FileSpec &sysroot_module_path_spec) {
-  // Remove $platform/.cache/$uuid folder if nobody else references it.
-  DeleteExistingModule(root_dir_spec, sysroot_module_path_spec);
-
-  // Remove sysroot link.
-  FileSystem::Unlink(sysroot_module_path_spec);
-
-  FileSpec symfile_spec = GetSymbolFileSpec(sysroot_module_path_spec);
-  if (symfile_spec.Exists()) // delete module's symbol file if exists.
-    FileSystem::Unlink(symfile_spec);
-}
-
-Error CreateHostSysRootModuleLink(const FileSpec &root_dir_spec,
-                                  const char *hostname,
-                                  const FileSpec &platform_module_spec,
-                                  const FileSpec &local_module_spec,
-                                  bool delete_existing) {
-  const auto sysroot_module_path_spec =
-      JoinPath(JoinPath(root_dir_spec, hostname),
-               platform_module_spec.GetPath().c_str());
-  if (sysroot_module_path_spec.Exists()) {
-    if (!delete_existing)
-      return Error();
-
-    DecrementRefExistingModule(root_dir_spec, sysroot_module_path_spec);
-  }
-
-  const auto error = MakeDirectory(
-      FileSpec(sysroot_module_path_spec.GetDirectory().AsCString(), false));
-  if (error.Fail())
-    return error;
-
-  return FileSystem::Hardlink(sysroot_module_path_spec, local_module_spec);
-}
-
-} // namespace
-
-ModuleLock::ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid,
-                       Error &error) {
-  const auto lock_dir_spec = JoinPath(root_dir_spec, kLockDirName);
-  error = MakeDirectory(lock_dir_spec);
-  if (error.Fail())
-    return;
-
-  m_file_spec = JoinPath(lock_dir_spec, uuid.GetAsString().c_str());
-  m_file.Open(m_file_spec.GetCString(), File::eOpenOptionWrite |
-                                            File::eOpenOptionCanCreate |
-                                            File::eOpenOptionCloseOnExec);
-  if (!m_file) {
-    error.SetErrorToErrno();
-    return;
-  }
-
-  m_lock.reset(new lldb_private::LockFile(m_file.GetDescriptor()));
-  error = m_lock->WriteLock(0, 1);
-  if (error.Fail())
-    error.SetErrorStringWithFormat("Failed to lock file: %s",
-                                   error.AsCString());
-}
-
-void ModuleLock::Delete() {
-  if (!m_file)
-    return;
-
-  m_file.Close();
-  FileSystem::Unlink(m_file_spec);
-}
-
-/////////////////////////////////////////////////////////////////////////
-
-Error ModuleCache::Put(const FileSpec &root_dir_spec, const char *hostname,
-                       const ModuleSpec &module_spec, const FileSpec &tmp_file,
-                       const FileSpec &target_file) {
-  const auto module_spec_dir =
-      GetModuleDirectory(root_dir_spec, module_spec.GetUUID());
-  const auto module_file_path =
-      JoinPath(module_spec_dir, target_file.GetFilename().AsCString());
-
-  const auto tmp_file_path = tmp_file.GetPath();
-  const auto err_code =
-      llvm::sys::fs::rename(tmp_file_path, module_file_path.GetPath());
-  if (err_code)
-    return Error("Failed to rename file %s to %s: %s", tmp_file_path.c_str(),
-                 module_file_path.GetPath().c_str(),
-                 err_code.message().c_str());
-
-  const auto error = CreateHostSysRootModuleLink(
-      root_dir_spec, hostname, target_file, module_file_path, true);
-  if (error.Fail())
-    return Error("Failed to create link to %s: %s",
-                 module_file_path.GetPath().c_str(), error.AsCString());
-  return Error();
-}
-
-Error ModuleCache::Get(const FileSpec &root_dir_spec, const char *hostname,
-                       const ModuleSpec &module_spec,
-                       ModuleSP &cached_module_sp, bool *did_create_ptr) {
-  const auto find_it =
-      m_loaded_modules.find(module_spec.GetUUID().GetAsString());
-  if (find_it != m_loaded_modules.end()) {
-    cached_module_sp = (*find_it).second.lock();
-    if (cached_module_sp)
-      return Error();
-    m_loaded_modules.erase(find_it);
-  }
-
-  const auto module_spec_dir =
-      GetModuleDirectory(root_dir_spec, module_spec.GetUUID());
-  const auto module_file_path = JoinPath(
-      module_spec_dir, module_spec.GetFileSpec().GetFilename().AsCString());
-
-  if (!module_file_path.Exists())
-    return Error("Module %s not found", module_file_path.GetPath().c_str());
-  if (module_file_path.GetByteSize() != module_spec.GetObjectSize())
-    return Error("Module %s has invalid file size",
-                 module_file_path.GetPath().c_str());
-
-  // We may have already cached module but downloaded from an another host - in
-  // this case let's create a link to it.
-  auto error = CreateHostSysRootModuleLink(root_dir_spec, hostname,
-                                           module_spec.GetFileSpec(),
-                                           module_file_path, false);
-  if (error.Fail())
-    return Error("Failed to create link to %s: %s",
-                 module_file_path.GetPath().c_str(), error.AsCString());
-
-  auto cached_module_spec(module_spec);
-  cached_module_spec.GetUUID().Clear(); // Clear UUID since it may contain md5
-                                        // content hash instead of real UUID.
-  cached_module_spec.GetFileSpec() = module_file_path;
-  cached_module_spec.GetPlatformFileSpec() = module_spec.GetFileSpec();
-
-  error = ModuleList::GetSharedModule(cached_module_spec, cached_module_sp,
-                                      nullptr, nullptr, did_create_ptr, false);
-  if (error.Fail())
-    return error;
-
-  FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec());
-  if (symfile_spec.Exists())
-    cached_module_sp->SetSymbolFileFileSpec(symfile_spec);
-
-  m_loaded_modules.insert(
-      std::make_pair(module_spec.GetUUID().GetAsString(), cached_module_sp));
-
-  return Error();
-}
-
-Error ModuleCache::GetAndPut(const FileSpec &root_dir_spec,
-                             const char *hostname,
-                             const ModuleSpec &module_spec,
-                             const ModuleDownloader &module_downloader,
-                             const SymfileDownloader &symfile_downloader,
-                             lldb::ModuleSP &cached_module_sp,
-                             bool *did_create_ptr) {
-  const auto module_spec_dir =
-      GetModuleDirectory(root_dir_spec, module_spec.GetUUID());
-  auto error = MakeDirectory(module_spec_dir);
-  if (error.Fail())
-    return error;
-
-  ModuleLock lock(root_dir_spec, module_spec.GetUUID(), error);
-  if (error.Fail())
-    return Error("Failed to lock module %s: %s",
-                 module_spec.GetUUID().GetAsString().c_str(),
-                 error.AsCString());
-
-  const auto escaped_hostname(GetEscapedHostname(hostname));
-  // Check local cache for a module.
-  error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec,
-              cached_module_sp, did_create_ptr);
-  if (error.Success())
-    return error;
-
-  const auto tmp_download_file_spec = JoinPath(module_spec_dir, kTempFileName);
-  error = module_downloader(module_spec, tmp_download_file_spec);
-  llvm::FileRemover tmp_file_remover(tmp_download_file_spec.GetPath());
-  if (error.Fail())
-    return Error("Failed to download module: %s", error.AsCString());
-
-  // Put downloaded file into local module cache.
-  error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec,
-              tmp_download_file_spec, module_spec.GetFileSpec());
-  if (error.Fail())
-    return Error("Failed to put module into cache: %s", error.AsCString());
-
-  tmp_file_remover.releaseFile();
-  error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec,
-              cached_module_sp, did_create_ptr);
-  if (error.Fail())
-    return error;
-
-  // Fetching a symbol file for the module
-  const auto tmp_download_sym_file_spec =
-      JoinPath(module_spec_dir, kTempSymFileName);
-  error = symfile_downloader(cached_module_sp, tmp_download_sym_file_spec);
-  llvm::FileRemover tmp_symfile_remover(tmp_download_sym_file_spec.GetPath());
-  if (error.Fail())
-    // Failed to download a symfile but fetching the module was successful. The
-    // module might
-    // contain the necessary symbols and the debugging is also possible without
-    // a symfile.
-    return Error();
-
-  error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec,
-              tmp_download_sym_file_spec,
-              GetSymbolFileSpec(module_spec.GetFileSpec()));
-  if (error.Fail())
-    return Error("Failed to put symbol file into cache: %s", error.AsCString());
-
-  tmp_symfile_remover.releaseFile();
-
-  FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec());
-  cached_module_sp->SetSymbolFileFileSpec(symfile_spec);
-  return Error();
-}
Index: lldb/source/Utility/CMakeLists.txt
===================================================================
--- lldb/source/Utility/CMakeLists.txt
+++ lldb/source/Utility/CMakeLists.txt
@@ -3,11 +3,9 @@
   Error.cpp
   JSON.cpp
   LLDBAssert.cpp
-  ModuleCache.cpp
   NameMatches.cpp
   PseudoTerminal.cpp
   Range.cpp
-  RegisterNumber.cpp
   RegularExpression.cpp
   SelectHelper.cpp
   SharingPtr.cpp
@@ -20,9 +18,7 @@
   UriParser.cpp
 
   LINK_LIBS
-    lldbCore
     lldbHost
-    lldbTarget
 
   LINK_COMPONENTS
     Support
Index: lldb/source/Target/RegisterNumber.cpp
===================================================================
--- /dev/null
+++ lldb/source/Target/RegisterNumber.cpp
@@ -0,0 +1,119 @@
+//===--------------------- RegisterNumber.cpp -------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/RegisterNumber.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb_private;
+
+RegisterNumber::RegisterNumber(lldb_private::Thread &thread,
+                               lldb::RegisterKind kind, uint32_t num)
+    : m_reg_ctx_sp(thread.GetRegisterContext()), m_regnum(num), m_kind(kind),
+      m_kind_regnum_map(), m_name("") {
+  if (m_reg_ctx_sp.get()) {
+    const lldb_private::RegisterInfo *reginfo =
+        m_reg_ctx_sp->GetRegisterInfoAtIndex(
+            GetAsKind(lldb::eRegisterKindLLDB));
+    if (reginfo && reginfo->name) {
+      m_name = reginfo->name;
+    }
+  }
+}
+
+RegisterNumber::RegisterNumber()
+    : m_reg_ctx_sp(), m_regnum(LLDB_INVALID_REGNUM),
+      m_kind(lldb::kNumRegisterKinds), m_kind_regnum_map(), m_name(nullptr) {}
+
+void RegisterNumber::init(lldb_private::Thread &thread, lldb::RegisterKind kind,
+                          uint32_t num) {
+  m_reg_ctx_sp = thread.GetRegisterContext();
+  m_regnum = num;
+  m_kind = kind;
+  if (m_reg_ctx_sp.get()) {
+    const lldb_private::RegisterInfo *reginfo =
+        m_reg_ctx_sp->GetRegisterInfoAtIndex(
+            GetAsKind(lldb::eRegisterKindLLDB));
+    if (reginfo && reginfo->name) {
+      m_name = reginfo->name;
+    }
+  }
+}
+
+const RegisterNumber &RegisterNumber::operator=(const RegisterNumber &rhs) {
+  m_reg_ctx_sp = rhs.m_reg_ctx_sp;
+  m_regnum = rhs.m_regnum;
+  m_kind = rhs.m_kind;
+  for (auto it : rhs.m_kind_regnum_map)
+    m_kind_regnum_map[it.first] = it.second;
+  m_name = rhs.m_name;
+  return *this;
+}
+
+bool RegisterNumber::operator==(RegisterNumber &rhs) {
+  if (IsValid() != rhs.IsValid())
+    return false;
+
+  if (m_kind == rhs.m_kind) {
+    if (m_regnum == rhs.m_regnum)
+      return true;
+    else
+      return false;
+  }
+
+  uint32_t rhs_regnum = rhs.GetAsKind(m_kind);
+  if (rhs_regnum != LLDB_INVALID_REGNUM) {
+    if (m_regnum == rhs_regnum)
+      return true;
+    else
+      return false;
+  }
+  uint32_t lhs_regnum = GetAsKind(rhs.m_kind);
+  {
+    if (lhs_regnum == rhs.m_regnum)
+      return true;
+    else
+      return false;
+  }
+  return false;
+}
+
+bool RegisterNumber::operator!=(RegisterNumber &rhs) { return !(*this == rhs); }
+
+bool RegisterNumber::IsValid() const {
+  return m_reg_ctx_sp.get() && m_kind != lldb::kNumRegisterKinds &&
+         m_regnum != LLDB_INVALID_REGNUM;
+}
+
+uint32_t RegisterNumber::GetAsKind(lldb::RegisterKind kind) {
+  if (m_regnum == LLDB_INVALID_REGNUM)
+    return LLDB_INVALID_REGNUM;
+
+  if (kind == m_kind)
+    return m_regnum;
+
+  Collection::iterator iter = m_kind_regnum_map.find(kind);
+  if (iter != m_kind_regnum_map.end()) {
+    return iter->second;
+  }
+  uint32_t output_regnum = LLDB_INVALID_REGNUM;
+  if (m_reg_ctx_sp &&
+      m_reg_ctx_sp->ConvertBetweenRegisterKinds(m_kind, m_regnum, kind,
+                                                output_regnum) &&
+      output_regnum != LLDB_INVALID_REGNUM) {
+    m_kind_regnum_map[kind] = output_regnum;
+  }
+  return output_regnum;
+}
+
+uint32_t RegisterNumber::GetRegisterNumber() const { return m_regnum; }
+
+lldb::RegisterKind RegisterNumber::GetRegisterKind() const { return m_kind; }
+
+const char *RegisterNumber::GetName() { return m_name; }
Index: lldb/source/Target/RegisterContext.cpp
===================================================================
--- lldb/source/Target/RegisterContext.cpp
+++ lldb/source/Target/RegisterContext.cpp
@@ -18,12 +18,12 @@
 #include "lldb/Core/Scalar.h"
 #include "lldb/Core/Value.h"
 #include "lldb/Expression/DWARFExpression.h"
-#include "lldb/Host/Endian.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
+#include "lldb/Utility/Endian.h"
 
 using namespace lldb;
 using namespace lldb_private;
Index: lldb/source/Target/Platform.cpp
===================================================================
--- lldb/source/Target/Platform.cpp
+++ lldb/source/Target/Platform.cpp
@@ -18,7 +18,6 @@
 #include "llvm/Support/Path.h"
 
 // Project includes
-#include "Utility/ModuleCache.h"
 #include "lldb/Breakpoint/BreakpointIDList.h"
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/DataBufferHeap.h"
@@ -36,6 +35,7 @@
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Interpreter/Property.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/ModuleCache.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
Index: lldb/source/Target/ModuleCache.cpp
===================================================================
--- /dev/null
+++ lldb/source/Target/ModuleCache.cpp
@@ -0,0 +1,336 @@
+//===--------------------- ModuleCache.cpp ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ModuleCache.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/File.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/LockFile.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
+
+#include <assert.h>
+
+#include <cstdio>
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+const char *kModulesSubdir = ".cache";
+const char *kLockDirName = ".lock";
+const char *kTempFileName = ".temp";
+const char *kTempSymFileName = ".symtemp";
+const char *kSymFileExtension = ".sym";
+const char *kFSIllegalChars = "\\/:*?\"<>|";
+
+std::string GetEscapedHostname(const char *hostname) {
+  if (hostname == nullptr)
+    hostname = "unknown";
+  std::string result(hostname);
+  size_t size = result.size();
+  for (size_t i = 0; i < size; ++i) {
+    if ((result[i] >= 1 && result[i] <= 31) ||
+        strchr(kFSIllegalChars, result[i]) != nullptr)
+      result[i] = '_';
+  }
+  return result;
+}
+
+class ModuleLock {
+private:
+  File m_file;
+  std::unique_ptr<lldb_private::LockFile> m_lock;
+  FileSpec m_file_spec;
+
+public:
+  ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid, Error &error);
+  void Delete();
+};
+
+FileSpec JoinPath(const FileSpec &path1, const char *path2) {
+  FileSpec result_spec(path1);
+  result_spec.AppendPathComponent(path2);
+  return result_spec;
+}
+
+Error MakeDirectory(const FileSpec &dir_path) {
+  if (dir_path.Exists()) {
+    if (!dir_path.IsDirectory())
+      return Error("Invalid existing path");
+
+    return Error();
+  }
+
+  return FileSystem::MakeDirectory(dir_path, eFilePermissionsDirectoryDefault);
+}
+
+FileSpec GetModuleDirectory(const FileSpec &root_dir_spec, const UUID &uuid) {
+  const auto modules_dir_spec = JoinPath(root_dir_spec, kModulesSubdir);
+  return JoinPath(modules_dir_spec, uuid.GetAsString().c_str());
+}
+
+FileSpec GetSymbolFileSpec(const FileSpec &module_file_spec) {
+  return FileSpec(module_file_spec.GetPath() + kSymFileExtension, false);
+}
+
+void DeleteExistingModule(const FileSpec &root_dir_spec,
+                          const FileSpec &sysroot_module_path_spec) {
+  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
+  UUID module_uuid;
+  {
+    auto module_sp =
+        std::make_shared<Module>(ModuleSpec(sysroot_module_path_spec));
+    module_uuid = module_sp->GetUUID();
+  }
+
+  if (!module_uuid.IsValid())
+    return;
+
+  Error error;
+  ModuleLock lock(root_dir_spec, module_uuid, error);
+  if (error.Fail()) {
+    if (log)
+      log->Printf("Failed to lock module %s: %s",
+                  module_uuid.GetAsString().c_str(), error.AsCString());
+  }
+
+  auto link_count = FileSystem::GetHardlinkCount(sysroot_module_path_spec);
+  if (link_count == -1)
+    return;
+
+  if (link_count > 2) // module is referred by other hosts.
+    return;
+
+  const auto module_spec_dir = GetModuleDirectory(root_dir_spec, module_uuid);
+  FileSystem::DeleteDirectory(module_spec_dir, true);
+  lock.Delete();
+}
+
+void DecrementRefExistingModule(const FileSpec &root_dir_spec,
+                                const FileSpec &sysroot_module_path_spec) {
+  // Remove $platform/.cache/$uuid folder if nobody else references it.
+  DeleteExistingModule(root_dir_spec, sysroot_module_path_spec);
+
+  // Remove sysroot link.
+  FileSystem::Unlink(sysroot_module_path_spec);
+
+  FileSpec symfile_spec = GetSymbolFileSpec(sysroot_module_path_spec);
+  if (symfile_spec.Exists()) // delete module's symbol file if exists.
+    FileSystem::Unlink(symfile_spec);
+}
+
+Error CreateHostSysRootModuleLink(const FileSpec &root_dir_spec,
+                                  const char *hostname,
+                                  const FileSpec &platform_module_spec,
+                                  const FileSpec &local_module_spec,
+                                  bool delete_existing) {
+  const auto sysroot_module_path_spec =
+      JoinPath(JoinPath(root_dir_spec, hostname),
+               platform_module_spec.GetPath().c_str());
+  if (sysroot_module_path_spec.Exists()) {
+    if (!delete_existing)
+      return Error();
+
+    DecrementRefExistingModule(root_dir_spec, sysroot_module_path_spec);
+  }
+
+  const auto error = MakeDirectory(
+      FileSpec(sysroot_module_path_spec.GetDirectory().AsCString(), false));
+  if (error.Fail())
+    return error;
+
+  return FileSystem::Hardlink(sysroot_module_path_spec, local_module_spec);
+}
+
+} // namespace
+
+ModuleLock::ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid,
+                       Error &error) {
+  const auto lock_dir_spec = JoinPath(root_dir_spec, kLockDirName);
+  error = MakeDirectory(lock_dir_spec);
+  if (error.Fail())
+    return;
+
+  m_file_spec = JoinPath(lock_dir_spec, uuid.GetAsString().c_str());
+  m_file.Open(m_file_spec.GetCString(), File::eOpenOptionWrite |
+                                            File::eOpenOptionCanCreate |
+                                            File::eOpenOptionCloseOnExec);
+  if (!m_file) {
+    error.SetErrorToErrno();
+    return;
+  }
+
+  m_lock.reset(new lldb_private::LockFile(m_file.GetDescriptor()));
+  error = m_lock->WriteLock(0, 1);
+  if (error.Fail())
+    error.SetErrorStringWithFormat("Failed to lock file: %s",
+                                   error.AsCString());
+}
+
+void ModuleLock::Delete() {
+  if (!m_file)
+    return;
+
+  m_file.Close();
+  FileSystem::Unlink(m_file_spec);
+}
+
+/////////////////////////////////////////////////////////////////////////
+
+Error ModuleCache::Put(const FileSpec &root_dir_spec, const char *hostname,
+                       const ModuleSpec &module_spec, const FileSpec &tmp_file,
+                       const FileSpec &target_file) {
+  const auto module_spec_dir =
+      GetModuleDirectory(root_dir_spec, module_spec.GetUUID());
+  const auto module_file_path =
+      JoinPath(module_spec_dir, target_file.GetFilename().AsCString());
+
+  const auto tmp_file_path = tmp_file.GetPath();
+  const auto err_code =
+      llvm::sys::fs::rename(tmp_file_path, module_file_path.GetPath());
+  if (err_code)
+    return Error("Failed to rename file %s to %s: %s", tmp_file_path.c_str(),
+                 module_file_path.GetPath().c_str(),
+                 err_code.message().c_str());
+
+  const auto error = CreateHostSysRootModuleLink(
+      root_dir_spec, hostname, target_file, module_file_path, true);
+  if (error.Fail())
+    return Error("Failed to create link to %s: %s",
+                 module_file_path.GetPath().c_str(), error.AsCString());
+  return Error();
+}
+
+Error ModuleCache::Get(const FileSpec &root_dir_spec, const char *hostname,
+                       const ModuleSpec &module_spec,
+                       ModuleSP &cached_module_sp, bool *did_create_ptr) {
+  const auto find_it =
+      m_loaded_modules.find(module_spec.GetUUID().GetAsString());
+  if (find_it != m_loaded_modules.end()) {
+    cached_module_sp = (*find_it).second.lock();
+    if (cached_module_sp)
+      return Error();
+    m_loaded_modules.erase(find_it);
+  }
+
+  const auto module_spec_dir =
+      GetModuleDirectory(root_dir_spec, module_spec.GetUUID());
+  const auto module_file_path = JoinPath(
+      module_spec_dir, module_spec.GetFileSpec().GetFilename().AsCString());
+
+  if (!module_file_path.Exists())
+    return Error("Module %s not found", module_file_path.GetPath().c_str());
+  if (module_file_path.GetByteSize() != module_spec.GetObjectSize())
+    return Error("Module %s has invalid file size",
+                 module_file_path.GetPath().c_str());
+
+  // We may have already cached module but downloaded from an another host - in
+  // this case let's create a link to it.
+  auto error = CreateHostSysRootModuleLink(root_dir_spec, hostname,
+                                           module_spec.GetFileSpec(),
+                                           module_file_path, false);
+  if (error.Fail())
+    return Error("Failed to create link to %s: %s",
+                 module_file_path.GetPath().c_str(), error.AsCString());
+
+  auto cached_module_spec(module_spec);
+  cached_module_spec.GetUUID().Clear(); // Clear UUID since it may contain md5
+                                        // content hash instead of real UUID.
+  cached_module_spec.GetFileSpec() = module_file_path;
+  cached_module_spec.GetPlatformFileSpec() = module_spec.GetFileSpec();
+
+  error = ModuleList::GetSharedModule(cached_module_spec, cached_module_sp,
+                                      nullptr, nullptr, did_create_ptr, false);
+  if (error.Fail())
+    return error;
+
+  FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec());
+  if (symfile_spec.Exists())
+    cached_module_sp->SetSymbolFileFileSpec(symfile_spec);
+
+  m_loaded_modules.insert(
+      std::make_pair(module_spec.GetUUID().GetAsString(), cached_module_sp));
+
+  return Error();
+}
+
+Error ModuleCache::GetAndPut(const FileSpec &root_dir_spec,
+                             const char *hostname,
+                             const ModuleSpec &module_spec,
+                             const ModuleDownloader &module_downloader,
+                             const SymfileDownloader &symfile_downloader,
+                             lldb::ModuleSP &cached_module_sp,
+                             bool *did_create_ptr) {
+  const auto module_spec_dir =
+      GetModuleDirectory(root_dir_spec, module_spec.GetUUID());
+  auto error = MakeDirectory(module_spec_dir);
+  if (error.Fail())
+    return error;
+
+  ModuleLock lock(root_dir_spec, module_spec.GetUUID(), error);
+  if (error.Fail())
+    return Error("Failed to lock module %s: %s",
+                 module_spec.GetUUID().GetAsString().c_str(),
+                 error.AsCString());
+
+  const auto escaped_hostname(GetEscapedHostname(hostname));
+  // Check local cache for a module.
+  error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec,
+              cached_module_sp, did_create_ptr);
+  if (error.Success())
+    return error;
+
+  const auto tmp_download_file_spec = JoinPath(module_spec_dir, kTempFileName);
+  error = module_downloader(module_spec, tmp_download_file_spec);
+  llvm::FileRemover tmp_file_remover(tmp_download_file_spec.GetPath());
+  if (error.Fail())
+    return Error("Failed to download module: %s", error.AsCString());
+
+  // Put downloaded file into local module cache.
+  error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec,
+              tmp_download_file_spec, module_spec.GetFileSpec());
+  if (error.Fail())
+    return Error("Failed to put module into cache: %s", error.AsCString());
+
+  tmp_file_remover.releaseFile();
+  error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec,
+              cached_module_sp, did_create_ptr);
+  if (error.Fail())
+    return error;
+
+  // Fetching a symbol file for the module
+  const auto tmp_download_sym_file_spec =
+      JoinPath(module_spec_dir, kTempSymFileName);
+  error = symfile_downloader(cached_module_sp, tmp_download_sym_file_spec);
+  llvm::FileRemover tmp_symfile_remover(tmp_download_sym_file_spec.GetPath());
+  if (error.Fail())
+    // Failed to download a symfile but fetching the module was successful. The
+    // module might
+    // contain the necessary symbols and the debugging is also possible without
+    // a symfile.
+    return Error();
+
+  error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec,
+              tmp_download_sym_file_spec,
+              GetSymbolFileSpec(module_spec.GetFileSpec()));
+  if (error.Fail())
+    return Error("Failed to put symbol file into cache: %s", error.AsCString());
+
+  tmp_symfile_remover.releaseFile();
+
+  FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec());
+  cached_module_sp->SetSymbolFileFileSpec(symfile_spec);
+  return Error();
+}
Index: lldb/source/Target/CMakeLists.txt
===================================================================
--- lldb/source/Target/CMakeLists.txt
+++ lldb/source/Target/CMakeLists.txt
@@ -13,6 +13,7 @@
   LanguageRuntime.cpp
   Memory.cpp
   MemoryHistory.cpp
+  ModuleCache.cpp
   ObjCLanguageRuntime.cpp
   OperatingSystem.cpp
   PathMappingList.cpp
@@ -24,6 +25,7 @@
   QueueItem.cpp
   QueueList.cpp
   RegisterContext.cpp
+  RegisterNumber.cpp
   SectionLoadHistory.cpp
   SectionLoadList.cpp
   StackFrame.cpp
Index: lldb/include/lldb/Utility/Stream.h
===================================================================
--- lldb/include/lldb/Utility/Stream.h
+++ lldb/include/lldb/Utility/Stream.h
@@ -16,7 +16,8 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Core/Flags.h"
+#include "lldb/Utility/Flags.h"
+
 #include "lldb/lldb-private.h"
 
 #include "llvm/Support/FormatVariadic.h"
Index: lldb/include/lldb/Utility/RegisterNumber.h
===================================================================
--- lldb/include/lldb/Utility/RegisterNumber.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===-- RegisterNumber.h ----------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_RegisterNumber_h
-#define liblldb_RegisterNumber_h
-
-#include "lldb/lldb-private.h"
-#include <map>
-
-//--------------------------------------------------------------------
-/// A class to represent register numbers, and able to convert between
-/// different register numbering schemes that may be used in a single
-/// debug session.
-//--------------------------------------------------------------------
-
-class RegisterNumber {
-public:
-  RegisterNumber(lldb_private::Thread &thread, lldb::RegisterKind kind,
-                 uint32_t num);
-
-  // This constructor plus the init() method below allow for the placeholder
-  // creation of an invalid object initially, possibly to be filled in.  It
-  // would be more consistent to have three Set* methods to set the three
-  // data that the object needs.
-  RegisterNumber();
-
-  void init(lldb_private::Thread &thread, lldb::RegisterKind kind,
-            uint32_t num);
-
-  const RegisterNumber &operator=(const RegisterNumber &rhs);
-
-  bool operator==(RegisterNumber &rhs);
-
-  bool operator!=(RegisterNumber &rhs);
-
-  bool IsValid() const;
-
-  uint32_t GetAsKind(lldb::RegisterKind kind);
-
-  uint32_t GetRegisterNumber() const;
-
-  lldb::RegisterKind GetRegisterKind() const;
-
-  const char *GetName();
-
-private:
-  typedef std::map<lldb::RegisterKind, uint32_t> Collection;
-
-  lldb::RegisterContextSP m_reg_ctx_sp;
-  uint32_t m_regnum;
-  lldb::RegisterKind m_kind;
-  Collection m_kind_regnum_map;
-  const char *m_name;
-};
-
-#endif // liblldb_RegisterNumber_h
Index: lldb/include/lldb/Utility/PseudoTerminal.h
===================================================================
--- lldb/include/lldb/Utility/PseudoTerminal.h
+++ lldb/include/lldb/Utility/PseudoTerminal.h
@@ -19,7 +19,7 @@
 namespace lldb_utility {
 
 //----------------------------------------------------------------------
-/// @class PseudoTerminal PseudoTerminal.h "lldb/Core/PseudoTerminal.h"
+/// @class PseudoTerminal PseudoTerminal.h "lldb/Utility/PseudoTerminal.h"
 /// @brief A pseudo terminal helper class.
 ///
 /// The pseudo terminal class abstracts the use of pseudo terminals on
Index: lldb/include/lldb/Utility/ProcessStructReader.h
===================================================================
--- lldb/include/lldb/Utility/ProcessStructReader.h
+++ /dev/null
@@ -1,103 +0,0 @@
-//===---------------------ProcessStructReader.h ------------------*- C++
-//-*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef utility_ProcessStructReader_h_
-#define utility_ProcessStructReader_h_
-
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-types.h"
-
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Symbol/CompilerType.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/ConstString.h"
-#include "lldb/Utility/Error.h"
-
-#include <initializer_list>
-#include <map>
-#include <string>
-
-namespace lldb_private {
-class ProcessStructReader {
-protected:
-  struct FieldImpl {
-    CompilerType type;
-    size_t offset;
-    size_t size;
-  };
-
-  std::map<ConstString, FieldImpl> m_fields;
-  DataExtractor m_data;
-  lldb::ByteOrder m_byte_order;
-  size_t m_addr_byte_size;
-
-public:
-  ProcessStructReader(Process *process, lldb::addr_t base_addr,
-                      CompilerType struct_type) {
-    if (!process)
-      return;
-    if (base_addr == 0 || base_addr == LLDB_INVALID_ADDRESS)
-      return;
-    m_byte_order = process->GetByteOrder();
-    m_addr_byte_size = process->GetAddressByteSize();
-
-    for (size_t idx = 0; idx < struct_type.GetNumFields(); idx++) {
-      std::string name;
-      uint64_t bit_offset;
-      uint32_t bitfield_bit_size;
-      bool is_bitfield;
-      CompilerType field_type = struct_type.GetFieldAtIndex(
-          idx, name, &bit_offset, &bitfield_bit_size, &is_bitfield);
-      // no support for bitfields in here (yet)
-      if (is_bitfield)
-        return;
-      auto size = field_type.GetByteSize(nullptr);
-      // no support for things larger than a uint64_t (yet)
-      if (size > 8)
-        return;
-      ConstString const_name = ConstString(name.c_str());
-      size_t byte_index = static_cast<size_t>(bit_offset / 8);
-      m_fields[const_name] =
-          FieldImpl{field_type, byte_index, static_cast<size_t>(size)};
-    }
-    size_t total_size = struct_type.GetByteSize(nullptr);
-    lldb::DataBufferSP buffer_sp(new DataBufferHeap(total_size, 0));
-    Error error;
-    process->ReadMemoryFromInferior(base_addr, buffer_sp->GetBytes(),
-                                    total_size, error);
-    if (error.Fail())
-      return;
-    m_data = DataExtractor(buffer_sp, m_byte_order, m_addr_byte_size);
-  }
-
-  template <typename RetType>
-  RetType GetField(ConstString name, RetType fail_value = RetType()) {
-    auto iter = m_fields.find(name), end = m_fields.end();
-    if (iter == end)
-      return fail_value;
-    auto size = iter->second.size;
-    if (sizeof(RetType) < size)
-      return fail_value;
-    lldb::offset_t offset = iter->second.offset;
-    if (offset + size > m_data.GetByteSize())
-      return fail_value;
-    return (RetType)(m_data.GetMaxU64(&offset, size));
-  }
-
-  size_t GetOffsetOf(ConstString name, size_t fail_value = SIZE_MAX) {
-    auto iter = m_fields.find(name), end = m_fields.end();
-    if (iter == end)
-      return fail_value;
-    return iter->second.offset;
-  }
-};
-}
-
-#endif // utility_ProcessStructReader_h_
Index: lldb/include/lldb/Utility/Flags.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Utility/Flags.h
@@ -0,0 +1,193 @@
+//===-- Flags.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_UTILITY_FLAGS_H
+#define LLDB_UTILITY_FLAGS_H
+
+#include <cstddef>
+#include <cstdint>
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class Flags Flags.h "lldb/Utility/Flags.h"
+/// @brief A class to manage flags.
+///
+/// The Flags class managed flag bits and allows testing and
+/// modification of individual or multiple flag bits.
+//----------------------------------------------------------------------
+class Flags {
+public:
+  //----------------------------------------------------------------------
+  /// The value type for flags is a 32 bit unsigned integer type.
+  //----------------------------------------------------------------------
+  typedef uint32_t ValueType;
+
+  //----------------------------------------------------------------------
+  /// Construct with initial flag bit values.
+  ///
+  /// Constructs this object with \a mask as the initial value for all
+  /// of the flags.
+  ///
+  /// @param[in] mask
+  ///     The initial value for all flags.
+  //----------------------------------------------------------------------
+  Flags(ValueType flags = 0) : m_flags(flags) {}
+
+  //----------------------------------------------------------------------
+  /// Copy constructor.
+  ///
+  /// Construct and copy the flags from \a rhs.
+  ///
+  /// @param[in] rhs
+  ///     A const Flags object reference to copy.
+  //----------------------------------------------------------------------
+  Flags(const Flags &rhs) : m_flags(rhs.m_flags) {}
+
+  //----------------------------------------------------------------------
+  /// Destructor.
+  //----------------------------------------------------------------------
+  ~Flags() {}
+
+  //----------------------------------------------------------------------
+  /// Get accessor for all flags.
+  ///
+  /// @return
+  ///     Returns all of the flags as a Flags::ValueType.
+  //----------------------------------------------------------------------
+  ValueType Get() const { return m_flags; }
+
+  //----------------------------------------------------------------------
+  /// Return the number of flags that can be represented in this
+  /// object.
+  ///
+  /// @return
+  ///     The maximum number bits in this flag object.
+  //----------------------------------------------------------------------
+  size_t GetBitSize() const { return sizeof(ValueType) * 8; }
+
+  //----------------------------------------------------------------------
+  /// Set accessor for all flags.
+  ///
+  /// @param[in] flags
+  ///     The bits with which to replace all of the current flags.
+  //----------------------------------------------------------------------
+  void Reset(ValueType flags) { m_flags = flags; }
+
+  //----------------------------------------------------------------------
+  /// Clear one or more flags.
+  ///
+  /// @param[in] mask
+  ///     A bitfield containing one or more flags.
+  ///
+  /// @return
+  ///     The new flags after clearing all bits from \a mask.
+  //----------------------------------------------------------------------
+  ValueType Clear(ValueType mask = ~(ValueType)0) {
+    m_flags &= ~mask;
+    return m_flags;
+  }
+
+  //----------------------------------------------------------------------
+  /// Set one or more flags by logical OR'ing \a mask with the current
+  /// flags.
+  ///
+  /// @param[in] mask
+  ///     A bitfield containing one or more flags.
+  ///
+  /// @return
+  ///     The new flags after setting all bits from \a mask.
+  //----------------------------------------------------------------------
+  ValueType Set(ValueType mask) {
+    m_flags |= mask;
+    return m_flags;
+  }
+
+  //----------------------------------------------------------------------
+  /// Test if all bits in \a mask are 1 in the current flags
+  ///
+  /// @return
+  ///     \b true if all flags in \a mask are 1, \b false
+  ///     otherwise.
+  //----------------------------------------------------------------------
+  bool AllSet(ValueType mask) const { return (m_flags & mask) == mask; }
+
+  //----------------------------------------------------------------------
+  /// Test one or more flags.
+  ///
+  /// @return
+  ///     \b true if any flags in \a mask are 1, \b false
+  ///     otherwise.
+  //----------------------------------------------------------------------
+  bool AnySet(ValueType mask) const { return (m_flags & mask) != 0; }
+
+  //----------------------------------------------------------------------
+  /// Test a single flag bit.
+  ///
+  /// @return
+  ///     \b true if \a bit is set, \b false otherwise.
+  //----------------------------------------------------------------------
+  bool Test(ValueType bit) const { return (m_flags & bit) != 0; }
+
+  //----------------------------------------------------------------------
+  /// Test if all bits in \a mask are clear.
+  ///
+  /// @return
+  ///     \b true if \b all flags in \a mask are clear, \b false
+  ///     otherwise.
+  //----------------------------------------------------------------------
+  bool AllClear(ValueType mask) const { return (m_flags & mask) == 0; }
+
+  bool AnyClear(ValueType mask) const { return (m_flags & mask) != mask; }
+
+  //----------------------------------------------------------------------
+  /// Test a single flag bit to see if it is clear (zero).
+  ///
+  /// @return
+  ///     \b true if \a bit is 0, \b false otherwise.
+  //----------------------------------------------------------------------
+  bool IsClear(ValueType bit) const { return (m_flags & bit) == 0; }
+
+  //----------------------------------------------------------------------
+  /// Get the number of zero bits in \a m_flags.
+  ///
+  /// @return
+  ///     The number of bits that are set to 0 in the current flags.
+  //----------------------------------------------------------------------
+  size_t ClearCount() const {
+    size_t count = 0;
+    for (ValueType shift = 0; shift < sizeof(ValueType) * 8; ++shift) {
+      if ((m_flags & (1u << shift)) == 0)
+        ++count;
+    }
+    return count;
+  }
+
+  //----------------------------------------------------------------------
+  /// Get the number of one bits in \a m_flags.
+  ///
+  /// @return
+  ///     The number of bits that are set to 1 in the current flags.
+  //----------------------------------------------------------------------
+  size_t SetCount() const {
+    size_t count = 0;
+    for (ValueType mask = m_flags; mask; mask >>= 1) {
+      if (mask & 1u)
+        ++count;
+    }
+    return count;
+  }
+
+protected:
+  ValueType m_flags; ///< The flags.
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Flags_h_
Index: lldb/include/lldb/Utility/Endian.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Utility/Endian.h
@@ -0,0 +1,32 @@
+//===-- Endian.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_UTILITY_ENDIAN_H
+#define LLDB_UTILITY_ENDIAN_H
+
+#include "lldb/lldb-enumerations.h"
+
+namespace lldb_private {
+
+namespace endian {
+
+static union EndianTest {
+  uint32_t num;
+  uint8_t bytes[sizeof(uint32_t)];
+} const endianTest = {0x01020304};
+
+inline lldb::ByteOrder InlHostByteOrder() {
+  return (lldb::ByteOrder)endianTest.bytes[0];
+}
+
+//    ByteOrder const InlHostByteOrder = (ByteOrder)endianTest.bytes[0];
+}
+}
+
+#endif // liblldb_host_endian_h_
Index: lldb/include/lldb/Target/RegisterNumber.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Target/RegisterNumber.h
@@ -0,0 +1,62 @@
+//===-- RegisterNumber.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_TARGET_REGISTERNUMBER_H
+#define LLDB_TARGET_REGISTERNUMBER_H
+
+#include "lldb/lldb-private.h"
+#include <map>
+
+//--------------------------------------------------------------------
+/// A class to represent register numbers, and able to convert between
+/// different register numbering schemes that may be used in a single
+/// debug session.
+//--------------------------------------------------------------------
+
+class RegisterNumber {
+public:
+  RegisterNumber(lldb_private::Thread &thread, lldb::RegisterKind kind,
+                 uint32_t num);
+
+  // This constructor plus the init() method below allow for the placeholder
+  // creation of an invalid object initially, possibly to be filled in.  It
+  // would be more consistent to have three Set* methods to set the three
+  // data that the object needs.
+  RegisterNumber();
+
+  void init(lldb_private::Thread &thread, lldb::RegisterKind kind,
+            uint32_t num);
+
+  const RegisterNumber &operator=(const RegisterNumber &rhs);
+
+  bool operator==(RegisterNumber &rhs);
+
+  bool operator!=(RegisterNumber &rhs);
+
+  bool IsValid() const;
+
+  uint32_t GetAsKind(lldb::RegisterKind kind);
+
+  uint32_t GetRegisterNumber() const;
+
+  lldb::RegisterKind GetRegisterKind() const;
+
+  const char *GetName();
+
+private:
+  typedef std::map<lldb::RegisterKind, uint32_t> Collection;
+
+  lldb::RegisterContextSP m_reg_ctx_sp;
+  uint32_t m_regnum;
+  lldb::RegisterKind m_kind;
+  Collection m_kind_regnum_map;
+  const char *m_name;
+};
+
+#endif // liblldb_RegisterNumber_h
Index: lldb/include/lldb/Target/ProcessStructReader.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Target/ProcessStructReader.h
@@ -0,0 +1,102 @@
+//===---------------------ProcessStructReader.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_TARGET_PROCESSSTRUCTREADER_H
+#define LLDB_TARGET_PROCESSSTRUCTREADER_H
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
+
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Error.h"
+
+#include <initializer_list>
+#include <map>
+#include <string>
+
+namespace lldb_private {
+class ProcessStructReader {
+protected:
+  struct FieldImpl {
+    CompilerType type;
+    size_t offset;
+    size_t size;
+  };
+
+  std::map<ConstString, FieldImpl> m_fields;
+  DataExtractor m_data;
+  lldb::ByteOrder m_byte_order;
+  size_t m_addr_byte_size;
+
+public:
+  ProcessStructReader(Process *process, lldb::addr_t base_addr,
+                      CompilerType struct_type) {
+    if (!process)
+      return;
+    if (base_addr == 0 || base_addr == LLDB_INVALID_ADDRESS)
+      return;
+    m_byte_order = process->GetByteOrder();
+    m_addr_byte_size = process->GetAddressByteSize();
+
+    for (size_t idx = 0; idx < struct_type.GetNumFields(); idx++) {
+      std::string name;
+      uint64_t bit_offset;
+      uint32_t bitfield_bit_size;
+      bool is_bitfield;
+      CompilerType field_type = struct_type.GetFieldAtIndex(
+          idx, name, &bit_offset, &bitfield_bit_size, &is_bitfield);
+      // no support for bitfields in here (yet)
+      if (is_bitfield)
+        return;
+      auto size = field_type.GetByteSize(nullptr);
+      // no support for things larger than a uint64_t (yet)
+      if (size > 8)
+        return;
+      ConstString const_name = ConstString(name.c_str());
+      size_t byte_index = static_cast<size_t>(bit_offset / 8);
+      m_fields[const_name] =
+          FieldImpl{field_type, byte_index, static_cast<size_t>(size)};
+    }
+    size_t total_size = struct_type.GetByteSize(nullptr);
+    lldb::DataBufferSP buffer_sp(new DataBufferHeap(total_size, 0));
+    Error error;
+    process->ReadMemoryFromInferior(base_addr, buffer_sp->GetBytes(),
+                                    total_size, error);
+    if (error.Fail())
+      return;
+    m_data = DataExtractor(buffer_sp, m_byte_order, m_addr_byte_size);
+  }
+
+  template <typename RetType>
+  RetType GetField(ConstString name, RetType fail_value = RetType()) {
+    auto iter = m_fields.find(name), end = m_fields.end();
+    if (iter == end)
+      return fail_value;
+    auto size = iter->second.size;
+    if (sizeof(RetType) < size)
+      return fail_value;
+    lldb::offset_t offset = iter->second.offset;
+    if (offset + size > m_data.GetByteSize())
+      return fail_value;
+    return (RetType)(m_data.GetMaxU64(&offset, size));
+  }
+
+  size_t GetOffsetOf(ConstString name, size_t fail_value = SIZE_MAX) {
+    auto iter = m_fields.find(name), end = m_fields.end();
+    if (iter == end)
+      return fail_value;
+    return iter->second.offset;
+  }
+};
+}
+
+#endif // utility_ProcessStructReader_h_
Index: lldb/include/lldb/Target/ModuleCache.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Target/ModuleCache.h
@@ -0,0 +1,76 @@
+//===-- ModuleCache.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_TARGET_MODULECACHE_H
+#define LLDB_TARGET_MODULECACHE_H
+
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include "lldb/Host/File.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Utility/Error.h"
+
+#include <functional>
+#include <string>
+#include <unordered_map>
+
+namespace lldb_private {
+
+class Module;
+class UUID;
+
+//----------------------------------------------------------------------
+/// @class ModuleCache ModuleCache.h "lldb/Target/ModuleCache.h"
+/// @brief A module cache class.
+///
+/// Caches locally modules that are downloaded from remote targets.
+/// Each cached module maintains 2 views:
+///  - UUID view:
+///  /${CACHE_ROOT}/${PLATFORM_NAME}/.cache/${UUID}/${MODULE_FILENAME}
+///  - Sysroot view:
+///  /${CACHE_ROOT}/${PLATFORM_NAME}/${HOSTNAME}/${MODULE_FULL_FILEPATH}
+///
+/// UUID views stores a real module file, whereas Sysroot view holds a symbolic
+/// link to UUID-view file.
+///
+/// Example:
+/// UUID view   :
+/// /tmp/lldb/remote-linux/.cache/30C94DC6-6A1F-E951-80C3-D68D2B89E576-D5AE213C/libc.so.6
+/// Sysroot view: /tmp/lldb/remote-linux/ubuntu/lib/x86_64-linux-gnu/libc.so.6
+//----------------------------------------------------------------------
+
+class ModuleCache {
+public:
+  using ModuleDownloader =
+      std::function<Error(const ModuleSpec &, const FileSpec &)>;
+  using SymfileDownloader =
+      std::function<Error(const lldb::ModuleSP &, const FileSpec &)>;
+
+  Error GetAndPut(const FileSpec &root_dir_spec, const char *hostname,
+                  const ModuleSpec &module_spec,
+                  const ModuleDownloader &module_downloader,
+                  const SymfileDownloader &symfile_downloader,
+                  lldb::ModuleSP &cached_module_sp, bool *did_create_ptr);
+
+private:
+  Error Put(const FileSpec &root_dir_spec, const char *hostname,
+            const ModuleSpec &module_spec, const FileSpec &tmp_file,
+            const FileSpec &target_file);
+
+  Error Get(const FileSpec &root_dir_spec, const char *hostname,
+            const ModuleSpec &module_spec, lldb::ModuleSP &cached_module_sp,
+            bool *did_create_ptr);
+
+  std::unordered_map<std::string, lldb::ModuleWP> m_loaded_modules;
+};
+
+} // namespace lldb_private
+
+#endif // utility_ModuleCache_h_
Index: lldb/include/lldb/Host/Endian.h
===================================================================
--- lldb/include/lldb/Host/Endian.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===-- Endian.h ------------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_host_endian_h_
-#define liblldb_host_endian_h_
-
-#include "lldb/lldb-enumerations.h"
-
-namespace lldb_private {
-
-namespace endian {
-
-static union EndianTest {
-  uint32_t num;
-  uint8_t bytes[sizeof(uint32_t)];
-} const endianTest = {0x01020304};
-
-inline lldb::ByteOrder InlHostByteOrder() {
-  return (lldb::ByteOrder)endianTest.bytes[0];
-}
-
-//    ByteOrder const InlHostByteOrder = (ByteOrder)endianTest.bytes[0];
-}
-}
-
-#endif // liblldb_host_endian_h_
Index: lldb/include/lldb/Core/Flags.h
===================================================================
--- lldb/include/lldb/Core/Flags.h
+++ /dev/null
@@ -1,193 +0,0 @@
-//===-- Flags.h -------------------------------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Flags_h_
-#define liblldb_Flags_h_
-
-#include <cstddef>
-#include <cstdint>
-
-namespace lldb_private {
-
-//----------------------------------------------------------------------
-/// @class Flags Flags.h "lldb/Core/Flags.h"
-/// @brief A class to manage flags.
-///
-/// The Flags class managed flag bits and allows testing and
-/// modification of individual or multiple flag bits.
-//----------------------------------------------------------------------
-class Flags {
-public:
-  //----------------------------------------------------------------------
-  /// The value type for flags is a 32 bit unsigned integer type.
-  //----------------------------------------------------------------------
-  typedef uint32_t ValueType;
-
-  //----------------------------------------------------------------------
-  /// Construct with initial flag bit values.
-  ///
-  /// Constructs this object with \a mask as the initial value for all
-  /// of the flags.
-  ///
-  /// @param[in] mask
-  ///     The initial value for all flags.
-  //----------------------------------------------------------------------
-  Flags(ValueType flags = 0) : m_flags(flags) {}
-
-  //----------------------------------------------------------------------
-  /// Copy constructor.
-  ///
-  /// Construct and copy the flags from \a rhs.
-  ///
-  /// @param[in] rhs
-  ///     A const Flags object reference to copy.
-  //----------------------------------------------------------------------
-  Flags(const Flags &rhs) : m_flags(rhs.m_flags) {}
-
-  //----------------------------------------------------------------------
-  /// Destructor.
-  //----------------------------------------------------------------------
-  ~Flags() {}
-
-  //----------------------------------------------------------------------
-  /// Get accessor for all flags.
-  ///
-  /// @return
-  ///     Returns all of the flags as a Flags::ValueType.
-  //----------------------------------------------------------------------
-  ValueType Get() const { return m_flags; }
-
-  //----------------------------------------------------------------------
-  /// Return the number of flags that can be represented in this
-  /// object.
-  ///
-  /// @return
-  ///     The maximum number bits in this flag object.
-  //----------------------------------------------------------------------
-  size_t GetBitSize() const { return sizeof(ValueType) * 8; }
-
-  //----------------------------------------------------------------------
-  /// Set accessor for all flags.
-  ///
-  /// @param[in] flags
-  ///     The bits with which to replace all of the current flags.
-  //----------------------------------------------------------------------
-  void Reset(ValueType flags) { m_flags = flags; }
-
-  //----------------------------------------------------------------------
-  /// Clear one or more flags.
-  ///
-  /// @param[in] mask
-  ///     A bitfield containing one or more flags.
-  ///
-  /// @return
-  ///     The new flags after clearing all bits from \a mask.
-  //----------------------------------------------------------------------
-  ValueType Clear(ValueType mask = ~(ValueType)0) {
-    m_flags &= ~mask;
-    return m_flags;
-  }
-
-  //----------------------------------------------------------------------
-  /// Set one or more flags by logical OR'ing \a mask with the current
-  /// flags.
-  ///
-  /// @param[in] mask
-  ///     A bitfield containing one or more flags.
-  ///
-  /// @return
-  ///     The new flags after setting all bits from \a mask.
-  //----------------------------------------------------------------------
-  ValueType Set(ValueType mask) {
-    m_flags |= mask;
-    return m_flags;
-  }
-
-  //----------------------------------------------------------------------
-  /// Test if all bits in \a mask are 1 in the current flags
-  ///
-  /// @return
-  ///     \b true if all flags in \a mask are 1, \b false
-  ///     otherwise.
-  //----------------------------------------------------------------------
-  bool AllSet(ValueType mask) const { return (m_flags & mask) == mask; }
-
-  //----------------------------------------------------------------------
-  /// Test one or more flags.
-  ///
-  /// @return
-  ///     \b true if any flags in \a mask are 1, \b false
-  ///     otherwise.
-  //----------------------------------------------------------------------
-  bool AnySet(ValueType mask) const { return (m_flags & mask) != 0; }
-
-  //----------------------------------------------------------------------
-  /// Test a single flag bit.
-  ///
-  /// @return
-  ///     \b true if \a bit is set, \b false otherwise.
-  //----------------------------------------------------------------------
-  bool Test(ValueType bit) const { return (m_flags & bit) != 0; }
-
-  //----------------------------------------------------------------------
-  /// Test if all bits in \a mask are clear.
-  ///
-  /// @return
-  ///     \b true if \b all flags in \a mask are clear, \b false
-  ///     otherwise.
-  //----------------------------------------------------------------------
-  bool AllClear(ValueType mask) const { return (m_flags & mask) == 0; }
-
-  bool AnyClear(ValueType mask) const { return (m_flags & mask) != mask; }
-
-  //----------------------------------------------------------------------
-  /// Test a single flag bit to see if it is clear (zero).
-  ///
-  /// @return
-  ///     \b true if \a bit is 0, \b false otherwise.
-  //----------------------------------------------------------------------
-  bool IsClear(ValueType bit) const { return (m_flags & bit) == 0; }
-
-  //----------------------------------------------------------------------
-  /// Get the number of zero bits in \a m_flags.
-  ///
-  /// @return
-  ///     The number of bits that are set to 0 in the current flags.
-  //----------------------------------------------------------------------
-  size_t ClearCount() const {
-    size_t count = 0;
-    for (ValueType shift = 0; shift < sizeof(ValueType) * 8; ++shift) {
-      if ((m_flags & (1u << shift)) == 0)
-        ++count;
-    }
-    return count;
-  }
-
-  //----------------------------------------------------------------------
-  /// Get the number of one bits in \a m_flags.
-  ///
-  /// @return
-  ///     The number of bits that are set to 1 in the current flags.
-  //----------------------------------------------------------------------
-  size_t SetCount() const {
-    size_t count = 0;
-    for (ValueType mask = m_flags; mask; mask >>= 1) {
-      if (mask & 1u)
-        ++count;
-    }
-    return count;
-  }
-
-protected:
-  ValueType m_flags; ///< The flags.
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_Flags_h_
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to