[Lldb-commits] [lldb] r231734 - Add Utility/ModuleCache class and integrate it with PlatformGDBRemoteServer - in order to allow modules caching from remote targets.

Oleksiy Vyalov ovyalov at google.com
Mon Mar 9 18:15:28 PDT 2015


Author: ovyalov
Date: Mon Mar  9 20:15:28 2015
New Revision: 231734

URL: http://llvm.org/viewvc/llvm-project?rev=231734&view=rev
Log:
Add Utility/ModuleCache class and integrate it with PlatformGDBRemoteServer - in order to allow modules caching from remote targets.

http://reviews.llvm.org/D8037


Added:
    lldb/trunk/source/Utility/ModuleCache.cpp
    lldb/trunk/source/Utility/ModuleCache.h
Modified:
    lldb/trunk/include/lldb/Core/ModuleSpec.h
    lldb/trunk/include/lldb/Host/HostInfoBase.h
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/include/lldb/lldb-enumerations.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Core/Debugger.cpp
    lldb/trunk/source/Core/UUID.cpp
    lldb/trunk/source/Host/common/HostInfoBase.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
    lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
    lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp
    lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.h
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
    lldb/trunk/source/Target/Platform.cpp
    lldb/trunk/source/Utility/CMakeLists.txt
    lldb/trunk/test/python_api/hello_world/TestHelloWorld.py

Modified: lldb/trunk/include/lldb/Core/ModuleSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ModuleSpec.h?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ModuleSpec.h (original)
+++ lldb/trunk/include/lldb/Core/ModuleSpec.h Mon Mar  9 20:15:28 2015
@@ -14,6 +14,7 @@
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/UUID.h"
 #include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Mutex.h"
 #include "lldb/Target/PathMappingList.h"
 
 namespace lldb_private {
@@ -29,6 +30,7 @@ public:
         m_uuid (),
         m_object_name (),
         m_object_offset (0),
+        m_object_size (0),
         m_object_mod_time (),
         m_source_mappings ()
     {
@@ -42,6 +44,7 @@ public:
         m_uuid (),
         m_object_name (),
         m_object_offset (0),
+        m_object_size (file_spec.GetByteSize ()),
         m_object_mod_time (),
         m_source_mappings ()
     {
@@ -55,6 +58,7 @@ public:
         m_uuid (),
         m_object_name (),
         m_object_offset (0),
+        m_object_size (file_spec.GetByteSize ()),
         m_object_mod_time (),
         m_source_mappings ()
     {
@@ -68,6 +72,7 @@ public:
         m_uuid (rhs.m_uuid),
         m_object_name (rhs.m_object_name),
         m_object_offset (rhs.m_object_offset),
+        m_object_size (rhs.m_object_size),
         m_object_mod_time (rhs.m_object_mod_time),
         m_source_mappings (rhs.m_source_mappings)
     {
@@ -85,6 +90,7 @@ public:
             m_uuid = rhs.m_uuid;
             m_object_name = rhs.m_object_name;
             m_object_offset = rhs.m_object_offset;
+            m_object_size = rhs.m_object_size;
             m_object_mod_time = rhs.m_object_mod_time;
             m_source_mappings = rhs.m_source_mappings;
         }
@@ -254,7 +260,19 @@ public:
     {
         m_object_offset = object_offset;
     }
-    
+
+    uint64_t
+    GetObjectSize () const
+    {
+        return m_object_size;
+    }
+
+    void
+    SetObjectSize (uint64_t object_size)
+    {
+        m_object_size = object_size;
+    }
+
     TimeValue &
     GetObjectModificationTime ()
     {
@@ -283,6 +301,7 @@ public:
         m_uuid.Clear();
         m_object_name.Clear();
         m_object_offset = 0;
+        m_object_size = 0;
         m_source_mappings.Clear(false);
         m_object_mod_time.Clear();
     }
@@ -302,6 +321,8 @@ public:
             return true;
         if (m_object_name)
             return true;
+        if (m_object_size)
+            return true;
         if (m_object_mod_time.IsValid())
             return true;
         return false;
@@ -362,7 +383,14 @@ public:
         {
             if (dumped_something)
                 strm.PutCString(", ");
-            strm.Printf("object_offset = 0x%" PRIx64, m_object_offset);
+            strm.Printf("object_offset = %" PRIu64, m_object_offset);
+            dumped_something = true;
+        }
+        if (m_object_size > 0)
+        {
+            if (dumped_something)
+                strm.PutCString(", ");
+            strm.Printf("object size = %" PRIu64, m_object_size);
             dumped_something = true;
         }
         if (m_object_mod_time.IsValid())
@@ -425,6 +453,7 @@ protected:
     UUID m_uuid;
     ConstString m_object_name;
     uint64_t m_object_offset;
+    uint64_t m_object_size;
     TimeValue m_object_mod_time;
     mutable PathMappingList m_source_mappings;
 };

Modified: lldb/trunk/include/lldb/Host/HostInfoBase.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/HostInfoBase.h?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/HostInfoBase.h (original)
+++ lldb/trunk/include/lldb/Host/HostInfoBase.h Mon Mar  9 20:15:28 2015
@@ -115,7 +115,8 @@ class HostInfoBase
   protected:
     static bool ComputeSharedLibraryDirectory(FileSpec &file_spec);
     static bool ComputeSupportExeDirectory(FileSpec &file_spec);
-    static bool ComputeTempFileDirectory(FileSpec &file_spec);
+    static bool ComputeProcessTempFileDirectory(FileSpec &file_spec);
+    static bool ComputeGlobalTempFileDirectory(FileSpec &file_spec);
     static bool ComputeHeaderDirectory(FileSpec &file_spec);
     static bool ComputeSystemPluginsDirectory(FileSpec &file_spec);
     static bool ComputeClangDirectory(FileSpec &file_spec);

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Mon Mar  9 20:15:28 2015
@@ -13,6 +13,7 @@
 // C Includes
 // C++ Includes
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -23,6 +24,7 @@
 #include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/PluginInterface.h"
+#include "lldb/Core/UserSettingsController.h"
 #include "lldb/Interpreter/Options.h"
 #include "lldb/Host/Mutex.h"
 
@@ -32,6 +34,29 @@
 
 namespace lldb_private {
 
+class ModuleCache;
+
+    class PlatformProperties : public Properties
+    {
+    public:
+        static ConstString
+        GetSettingName ();
+
+        PlatformProperties();
+
+        bool
+        GetUseModuleCache () const;
+        bool
+        SetUseModuleCache (bool use_module_cache);
+
+        FileSpec
+        GetModuleCacheDirectory () const;
+        bool
+        SetModuleCacheDirectory (const FileSpec& dir_spec);
+    };
+
+    typedef std::shared_ptr<PlatformProperties> PlatformPropertiesSP;
+
     //----------------------------------------------------------------------
     /// @class Platform Platform.h "lldb/Target/Platform.h"
     /// @brief A plug-in interface definition class for debug platform that
@@ -49,13 +74,15 @@ namespace lldb_private {
         public PluginInterface
     {
     public:
-
         static void
         Initialize ();
 
         static void
         Terminate ();
 
+        static const PlatformPropertiesSP &
+        GetGlobalPlatformProperties ();
+
         //------------------------------------------------------------------
         /// Get the native host platform plug-in.
         ///
@@ -350,6 +377,11 @@ namespace lldb_private {
                          lldb::ModuleSP *old_module_sp_ptr,
                          bool *did_create_ptr);
 
+        virtual bool
+        GetModuleSpec (const FileSpec& module_file_spec,
+                       const ArchSpec& arch,
+                       ModuleSpec &module_spec);
+
         virtual Error
         ConnectRemote (Args& args);
 
@@ -988,6 +1020,7 @@ namespace lldb_private {
         std::string m_local_cache_directory;
         std::vector<ConstString> m_trap_handlers;
         bool m_calculated_trap_handlers;
+        const std::unique_ptr<ModuleCache> m_module_cache;
 
         //------------------------------------------------------------------
         /// Ask the Platform subclass to fill in the list of trap handler names
@@ -1090,6 +1123,22 @@ namespace lldb_private {
             m_gid_map.clear();
         }
 
+        bool
+        GetCachedSharedModule (const ModuleSpec &module_spec,
+                               lldb::ModuleSP &module_sp);
+
+        Error
+        DownloadModuleSlice (const FileSpec& src_file_spec,
+                             const uint64_t src_offset,
+                             const uint64_t src_size,
+                             const FileSpec& dst_file_spec);
+
+        bool
+        GetFileFromLocalCache (const ModuleSpec& module_spec,
+                               FileSpec &cached_file_spec);
+
+        FileSpec GetModuleCacheRoot ();
+
     private:
         DISALLOW_COPY_AND_ASSIGN (Platform);
     };

Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Mon Mar  9 20:15:28 2015
@@ -860,14 +860,15 @@ namespace lldb {
     //----------------------------------------------------------------------
     typedef enum PathType
     {
-        ePathTypeLLDBShlibDir,          // The directory where the lldb.so (unix) or LLDB mach-o file in LLDB.framework (MacOSX) exists
-        ePathTypeSupportExecutableDir,  // Find LLDB support executable directory (debugserver, etc)
-        ePathTypeHeaderDir,             // Find LLDB header file directory
-        ePathTypePythonDir,             // Find Python modules (PYTHONPATH) directory
-        ePathTypeLLDBSystemPlugins,     // System plug-ins directory
-        ePathTypeLLDBUserPlugins,       // User plug-ins directory
-        ePathTypeLLDBTempSystemDir,     // The LLDB temp directory for this system that will be cleaned up on exit
-        ePathTypeClangDir               // Find path to Clang builtin headers
+        ePathTypeLLDBShlibDir,            // The directory where the lldb.so (unix) or LLDB mach-o file in LLDB.framework (MacOSX) exists
+        ePathTypeSupportExecutableDir,    // Find LLDB support executable directory (debugserver, etc)
+        ePathTypeHeaderDir,               // Find LLDB header file directory
+        ePathTypePythonDir,               // Find Python modules (PYTHONPATH) directory
+        ePathTypeLLDBSystemPlugins,       // System plug-ins directory
+        ePathTypeLLDBUserPlugins,         // User plug-ins directory
+        ePathTypeLLDBTempSystemDir,       // The LLDB temp directory for this system that will be cleaned up on exit
+        ePathTypeGlobalLLDBTempSystemDir, // The LLDB temp directory for this system, NOT cleaned up on a process exit.
+        ePathTypeClangDir                 // Find path to Clang builtin headers
     } PathType;
     
     //----------------------------------------------------------------------

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Mar  9 20:15:28 2015
@@ -98,6 +98,8 @@
 		254FBB971A81B03100BD6378 /* SBLaunchInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 254FBB961A81B03100BD6378 /* SBLaunchInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		254FBBA31A9166F100BD6378 /* SBAttachInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 254FBBA21A9166F100BD6378 /* SBAttachInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		254FBBA51A91670E00BD6378 /* SBAttachInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 254FBBA41A91670E00BD6378 /* SBAttachInfo.cpp */; };
+		257E47171AA56C2000A62F81 /* ModuleCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 257E47151AA56C2000A62F81 /* ModuleCache.cpp */; };
+		257E47181AA56C2000A62F81 /* ModuleCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 257E47161AA56C2000A62F81 /* ModuleCache.h */; };
 		260157C61885F51C00F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
 		260157C81885F53100F875CF /* libpanel.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 260157C41885F4FF00F875CF /* libpanel.dylib */; };
 		2606EDDF184E68A10034641B /* liblldb-core.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2689FFCA13353D7A00698AC0 /* liblldb-core.a */; };
@@ -1213,6 +1215,8 @@
 		254FBBA21A9166F100BD6378 /* SBAttachInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBAttachInfo.h; path = include/lldb/API/SBAttachInfo.h; sourceTree = "<group>"; };
 		254FBBA41A91670E00BD6378 /* SBAttachInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBAttachInfo.cpp; path = source/API/SBAttachInfo.cpp; sourceTree = "<group>"; };
 		254FBBA61A91672800BD6378 /* SBAttachInfo.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBAttachInfo.i; sourceTree = "<group>"; };
+		257E47151AA56C2000A62F81 /* ModuleCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleCache.cpp; path = source/Utility/ModuleCache.cpp; sourceTree = "<group>"; };
+		257E47161AA56C2000A62F81 /* ModuleCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModuleCache.h; path = source/Utility/ModuleCache.h; sourceTree = "<group>"; };
 		260157C41885F4FF00F875CF /* libpanel.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpanel.dylib; path = /usr/lib/libpanel.dylib; sourceTree = "<absolute>"; };
 		260223E7115F06D500A601A2 /* SBCommunication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBCommunication.h; path = include/lldb/API/SBCommunication.h; sourceTree = "<group>"; };
 		260223E8115F06E500A601A2 /* SBCommunication.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBCommunication.cpp; path = source/API/SBCommunication.cpp; sourceTree = "<group>"; };
@@ -3448,6 +3452,8 @@
 		2682F168115ED9C800CCFF99 /* Utility */ = {
 			isa = PBXGroup;
 			children = (
+				257E47151AA56C2000A62F81 /* ModuleCache.cpp */,
+				257E47161AA56C2000A62F81 /* ModuleCache.h */,
 				33064C9B1A5C7A490033D415 /* UriParser.h */,
 				33064C991A5C7A330033D415 /* UriParser.cpp */,
 				AF9107E91685709A00DBCD3C /* ARM64_GCC_Registers.h */,
@@ -5212,6 +5218,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				26A527C214E24F5F00F3A14A /* ProcessMachCore.h in Headers */,
+				257E47181AA56C2000A62F81 /* ModuleCache.h in Headers */,
 				26BC17AC18C7F4CB00D2196D /* ProcessElfCore.h in Headers */,
 				26A527C414E24F5F00F3A14A /* ThreadMachCore.h in Headers */,
 				26474CD318D0CB710073DEBA /* RegisterInfos_i386.h in Headers */,
@@ -5976,6 +5983,7 @@
 				25420ED21A649D88009ADBCB /* PipeBase.cpp in Sources */,
 				2689007313353E1A00698AC0 /* Symbols.cpp in Sources */,
 				26474CBC18D0CB2D0073DEBA /* RegisterContextMach_arm.cpp in Sources */,
+				257E47171AA56C2000A62F81 /* ModuleCache.cpp in Sources */,
 				2689007413353E1A00698AC0 /* Terminal.cpp in Sources */,
 				2689007513353E1A00698AC0 /* TimeValue.cpp in Sources */,
 				2689007613353E1A00698AC0 /* CFCBundle.cpp in Sources */,

Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Mon Mar  9 20:15:28 2015
@@ -697,6 +697,10 @@ Debugger::Debugger(lldb::LogOutputCallba
                                      ConstString("Settings specify to debugging targets."),
                                      true,
                                      Target::GetGlobalProperties()->GetValueProperties());
+    m_collection_sp->AppendProperty (ConstString("platform"),
+                                     ConstString("Platform settings."),
+                                     true,
+                                     Platform::GetGlobalPlatformProperties()->GetValueProperties());
     if (m_command_interpreter_ap.get())
     {
         m_collection_sp->AppendProperty (ConstString("interpreter"),

Modified: lldb/trunk/source/Core/UUID.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/UUID.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Core/UUID.cpp (original)
+++ lldb/trunk/source/Core/UUID.cpp Mon Mar  9 20:15:28 2015
@@ -234,7 +234,10 @@ UUID::SetFromCString (const char *cstr,
     // If we successfully decoded a UUID, return the amount of characters that
     // were consumed
     if (uuid_byte_idx == num_uuid_bytes)
+    {
+        m_num_uuid_bytes = num_uuid_bytes;
         return p - cstr;
+    }
 
     // Else return zero to indicate we were not able to parse a UUID value
     return 0;

Modified: lldb/trunk/source/Host/common/HostInfoBase.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/HostInfoBase.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/HostInfoBase.cpp (original)
+++ lldb/trunk/source/Host/common/HostInfoBase.cpp Mon Mar  9 20:15:28 2015
@@ -68,7 +68,8 @@ namespace
         FileSpec m_lldb_clang_resource_dir;
         FileSpec m_lldb_system_plugin_dir;
         FileSpec m_lldb_user_plugin_dir;
-        FileSpec m_lldb_tmp_dir;
+        FileSpec m_lldb_process_tmp_dir;
+        FileSpec m_lldb_global_tmp_dir;
     };
     
     HostInfoBaseFields *g_fields = nullptr;
@@ -263,13 +264,27 @@ HostInfoBase::GetLLDBPath(lldb::PathType
                 static std::once_flag g_once_flag;
                 static bool success = false;
                 std::call_once(g_once_flag,  []() {
-                    success = HostInfo::ComputeTempFileDirectory (g_fields->m_lldb_tmp_dir);
+                    success = HostInfo::ComputeProcessTempFileDirectory (g_fields->m_lldb_process_tmp_dir);
                     Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
                     if (log)
-                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_tmp_dir.GetPath().c_str());
+                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeLLDBTempSystemDir) => '%s'", g_fields->m_lldb_process_tmp_dir.GetPath().c_str());
                 });
                 if (success)
-                    result = &g_fields->m_lldb_tmp_dir;
+                    result = &g_fields->m_lldb_process_tmp_dir;
+            }
+            break;
+        case lldb::ePathTypeGlobalLLDBTempSystemDir:
+            {
+                static std::once_flag g_once_flag;
+                static bool success = false;
+                std::call_once(g_once_flag,  []() {
+                    success = HostInfo::ComputeGlobalTempFileDirectory (g_fields->m_lldb_global_tmp_dir);
+                    Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+                    if (log)
+                        log->Printf("HostInfoBase::GetLLDBPath(ePathTypeGlobalLLDBTempSystemDir) => '%s'", g_fields->m_lldb_global_tmp_dir.GetPath().c_str());
+                });
+                if (success)
+                    result = &g_fields->m_lldb_global_tmp_dir;
             }
             break;
     }
@@ -305,8 +320,32 @@ HostInfoBase::ComputeSupportExeDirectory
 }
 
 bool
-HostInfoBase::ComputeTempFileDirectory(FileSpec &file_spec)
+HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec)
 {
+    FileSpec temp_file_spec;
+    if (!ComputeGlobalTempFileDirectory(temp_file_spec))
+        return false;
+
+    std::string pid_str;
+    llvm::raw_string_ostream pid_stream(pid_str);
+    pid_stream << Host::GetCurrentProcessID();
+    temp_file_spec.AppendPathComponent(pid_stream.str().c_str());
+    std::string final_path = temp_file_spec.GetPath();
+    if (!FileSystem::MakeDirectory(final_path.c_str(), eFilePermissionsDirectoryDefault).Success())
+        return false;
+
+    // Make an atexit handler to clean up the process specify LLDB temp dir
+    // and all of its contents.
+    ::atexit(CleanupProcessSpecificLLDBTempDir);
+    file_spec.GetDirectory().SetCStringWithLength(final_path.c_str(), final_path.size());
+    return true;
+}
+
+bool
+HostInfoBase::ComputeGlobalTempFileDirectory(FileSpec &file_spec)
+{
+    file_spec.Clear();
+
     const char *tmpdir_cstr = getenv("TMPDIR");
     if (tmpdir_cstr == NULL)
     {
@@ -322,18 +361,7 @@ HostInfoBase::ComputeTempFileDirectory(F
     if (!FileSystem::MakeDirectory(temp_file_spec.GetPath().c_str(), eFilePermissionsDirectoryDefault).Success())
         return false;
 
-    std::string pid_str;
-    llvm::raw_string_ostream pid_stream(pid_str);
-    pid_stream << Host::GetCurrentProcessID();
-    temp_file_spec.AppendPathComponent(pid_stream.str().c_str());
-    std::string final_path = temp_file_spec.GetPath();
-    if (!FileSystem::MakeDirectory(final_path.c_str(), eFilePermissionsDirectoryDefault).Success())
-        return false;
-
-    // Make an atexit handler to clean up the process specify LLDB temp dir
-    // and all of its contents.
-    ::atexit(CleanupProcessSpecificLLDBTempDir);
-    file_spec.GetDirectory().SetCStringWithLength(final_path.c_str(), final_path.size());
+    file_spec = temp_file_spec;
     return true;
 }
 

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Mon Mar  9 20:15:28 2015
@@ -851,6 +851,7 @@ DynamicLoaderMacOSXDYLD::AddModulesUsing
                         if (!commpage_image_module_sp)
                         {
                             module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
+                            module_spec.SetObjectSize (objfile->GetByteSize());
                             commpage_image_module_sp  = target.GetSharedModule (module_spec);
                             if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
                             {

Modified: lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp Mon Mar  9 20:15:28 2015
@@ -595,7 +595,8 @@ ObjectContainerBSDArchive::GetModuleSpec
                             TimeValue object_mod_time;
                             object_mod_time.OffsetWithSeconds(object->ar_date);
                             spec.GetObjectName () = object->ar_name;
-                            spec.SetObjectOffset(object_file_offset);
+                            spec.SetObjectOffset (object_file_offset);
+                            spec.SetObjectSize (file_size - object_file_offset);
                             spec.GetObjectModificationTime () = object_mod_time;
                         }
                     }

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Mon Mar  9 20:15:28 2015
@@ -604,8 +604,7 @@ ObjectFileELF::GetModuleSpecifications (
         {
             if (data_sp)
             {
-                ModuleSpec spec;
-                spec.GetFileSpec() = file;
+                ModuleSpec spec (file);
 
                 const uint32_t sub_type = subTypeFromElfHeader(header);
                 spec.GetArchitecture().SetArchitecture(eArchTypeELF,

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Mon Mar  9 20:15:28 2015
@@ -995,7 +995,8 @@ ObjectFileMachO::GetModuleSpecifications
                 ModuleSpec spec;
                 spec.GetFileSpec() = file;
                 spec.SetObjectOffset(file_offset);
-                
+                spec.SetObjectSize(length);
+
                 if (GetArchitecture (header, data, data_offset, spec.GetArchitecture()))
                 {
                     if (spec.GetArchitecture().IsValid())

Modified: lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp Mon Mar  9 20:15:28 2015
@@ -165,6 +165,18 @@ PlatformFreeBSD::~PlatformFreeBSD()
 }
 
 //TODO:VK: inherit PlatformPOSIX
+
+bool
+PlatformFreeBSD::GetModuleSpec (const FileSpec& module_file_spec,
+                                const ArchSpec& arch,
+                                ModuleSpec &module_spec)
+{
+    if (m_remote_platform_sp)
+        return m_remote_platform_sp->GetModuleSpec (module_file_spec, arch, module_spec);
+
+    return Platform::GetModuleSpec (module_file_spec, arch, module_spec);
+}
+
 lldb_private::Error
 PlatformFreeBSD::RunShellCommand (const char *command,
                                   const char *working_dir,

Modified: lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h (original)
+++ lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h Mon Mar  9 20:15:28 2015
@@ -71,6 +71,11 @@ public:
     //------------------------------------------------------------
     // lldb_private::Platform functions
     //------------------------------------------------------------
+    virtual bool
+    GetModuleSpec (const lldb_private::FileSpec& module_file_spec,
+                   const lldb_private::ArchSpec& arch,
+                   lldb_private::ModuleSpec &module_spec);
+
     virtual lldb_private::Error
     RunShellCommand (const char *command,
                      const char *working_dir,

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp Mon Mar  9 20:15:28 2015
@@ -50,6 +50,17 @@ PlatformPOSIX::~PlatformPOSIX()
 {
 }
 
+bool
+PlatformPOSIX::GetModuleSpec (const FileSpec& module_file_spec,
+                              const ArchSpec& arch,
+                              ModuleSpec &module_spec)
+{
+    if (m_remote_platform_sp)
+        return m_remote_platform_sp->GetModuleSpec (module_file_spec, arch, module_spec);
+
+    return Platform::GetModuleSpec (module_file_spec, arch, module_spec);
+}
+
 lldb_private::OptionGroupOptions*
 PlatformPOSIX::GetConnectionOptions (lldb_private::CommandInterpreter& interpreter)
 {

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h Mon Mar  9 20:15:28 2015
@@ -31,6 +31,12 @@ public:
     //------------------------------------------------------------
     // lldb_private::Platform functions
     //------------------------------------------------------------
+
+    virtual bool
+    GetModuleSpec (const lldb_private::FileSpec& module_file_spec,
+                   const lldb_private::ArchSpec& arch,
+                   lldb_private::ModuleSpec &module_spec);
+
     virtual lldb_private::OptionGroupOptions
     *GetConnectionOptions(
         lldb_private::CommandInterpreter &interpreter) override;
@@ -115,7 +121,7 @@ public:
                      int *signo_ptr,                // Pass NULL if you don't want the signal that caused the process to exit
                      std::string *command_output,   // Pass NULL if you don't want the command output
                      uint32_t timeout_sec) override;// Timeout in seconds to wait for shell program to finish
-    
+
     virtual lldb_private::Error
     MakeDirectory (const char *path, uint32_t mode) override;
     

Modified: lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp Mon Mar  9 20:15:28 2015
@@ -201,6 +201,17 @@ PlatformWindows::~PlatformWindows()
 {
 }
 
+bool
+PlatformWindows::GetModuleSpec (const FileSpec& module_file_spec,
+                                const ArchSpec& arch,
+                                ModuleSpec &module_spec)
+{
+    if (m_remote_platform_sp)
+        return m_remote_platform_sp->GetModuleSpec (module_file_spec, arch, module_spec);
+
+    return Platform::GetModuleSpec (module_file_spec, arch, module_spec);
+}
+
 Error
 PlatformWindows::ResolveExecutable (const ModuleSpec &ms,
                                     lldb::ModuleSP &exe_module_sp,

Modified: lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.h?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.h (original)
+++ lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.h Mon Mar  9 20:15:28 2015
@@ -59,6 +59,11 @@ public:
     //------------------------------------------------------------
     // lldb_private::Platform functions
     //------------------------------------------------------------
+    virtual bool
+    GetModuleSpec (const lldb_private::FileSpec& module_file_spec,
+                   const lldb_private::ArchSpec& arch,
+                   lldb_private::ModuleSpec &module_spec);
+
     virtual Error
     ResolveExecutable(const lldb_private::ModuleSpec &module_spec,
                       lldb::ModuleSP &module_sp,

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp Mon Mar  9 20:15:28 2015
@@ -27,6 +27,8 @@
 #include "lldb/Host/ConnectionFileDescriptor.h"
 #include "lldb/Host/FileSpec.h"
 #include "lldb/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/StringConvert.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 
@@ -196,6 +198,73 @@ PlatformRemoteGDBServer::ResolveExecutab
     return error;
 }
 
+bool
+PlatformRemoteGDBServer::GetModuleSpec (const FileSpec& module_file_spec,
+                                        const ArchSpec& arch,
+                                        ModuleSpec &module_spec)
+{
+    Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
+
+    const auto module_path = module_file_spec.GetPath ();
+
+    StringExtractorGDBRemote response;
+    if (!m_gdb_client.GetModuleInfo (module_path.c_str (), arch, response))
+    {
+        if (log)
+            log->Printf ("PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
+                         __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str ());
+        return false;
+    }
+
+    std::string name;
+    std::string value;
+    bool success;
+    StringExtractor extractor;
+
+    module_spec.Clear ();
+    module_spec.GetFileSpec () = module_file_spec;
+
+    while (response.GetNameColonValue (name, value))
+    {
+        if (name == "uuid" || name == "md5")
+        {
+            extractor.GetStringRef ().swap (value);
+            extractor.SetFilePos (0);
+            extractor.GetHexByteString (value);
+            module_spec.GetUUID().SetFromCString (value.c_str(), value.size() / 2);
+        }
+        else if (name == "triple")
+        {
+            extractor.GetStringRef ().swap (value);
+            extractor.SetFilePos (0);
+            extractor.GetHexByteString (value);
+            module_spec.GetArchitecture().SetTriple (value.c_str ());
+        }
+        else if (name == "file_offset")
+        {
+            const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
+            if (success)
+                module_spec.SetObjectOffset (ival);
+        }
+        else if (name == "file_size")
+        {
+            const auto ival = StringConvert::ToUInt64 (value.c_str (), 0, 16, &success);
+            if (success)
+                module_spec.SetObjectSize (ival);
+        }
+    }
+
+    if (log)
+    {
+        StreamString stream;
+        module_spec.Dump (stream);
+        log->Printf ("PlatformRemoteGDBServer::%s - got module info for (%s:%s) : %s",
+                     __FUNCTION__, module_path.c_str (), arch.GetTriple ().getTriple ().c_str (), stream.GetString ().c_str ());
+    }
+
+    return true;
+}
+
 Error
 PlatformRemoteGDBServer::GetFileWithUUID (const FileSpec &platform_file, 
                                           const UUID *uuid_ptr,
@@ -346,7 +415,6 @@ PlatformRemoteGDBServer::ConnectRemote (
         {
             const char *url = args.GetArgumentAtIndex(0);
             m_gdb_client.SetConnection (new ConnectionFileDescriptor());
-
             // we're going to reuse the hostname when we connect to the debugserver
             std::string scheme;
             int port;
@@ -380,7 +448,6 @@ PlatformRemoteGDBServer::ConnectRemote (
             error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>");
         }
     }
-
     return error;
 }
 
@@ -840,4 +907,4 @@ void
 PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames ()
 {   
     m_trap_handlers.push_back (ConstString ("_sigtramp"));
-}   
+}

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h Mon Mar  9 20:15:28 2015
@@ -68,6 +68,11 @@ public:
                        lldb::ModuleSP &module_sp,
                        const lldb_private::FileSpecList *module_search_paths_ptr);
 
+    virtual bool
+    GetModuleSpec (const lldb_private::FileSpec& module_file_spec,
+                   const lldb_private::ArchSpec& arch,
+                   lldb_private::ModuleSpec &module_spec);
+
     virtual const char *
     GetDescription ();
 
@@ -127,7 +132,6 @@ public:
     
     virtual bool
     SetRemoteWorkingDirectory(const lldb_private::ConstString &path);
-    
 
     // Remote subclasses should override this and return a valid instance
     // name if connected.

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Mon Mar  9 20:15:28 2015
@@ -3720,5 +3720,6 @@ GDBRemoteCommunicationClient::GetModuleI
     const auto& tripple = arch_spec.GetTriple().getTriple();
     packet.PutBytesAsRawHex8(tripple.c_str(), tripple.size());
 
-    return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success;
+    return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success &&
+        !response.IsErrorResponse ();
 }

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp Mon Mar  9 20:15:28 2015
@@ -19,7 +19,6 @@
 // Other libraries and framework includes
 #include "llvm/ADT/Triple.h"
 #include "lldb/Core/Log.h"
-#include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/StreamGDBRemote.h"
 #include "lldb/Core/StreamString.h"
@@ -1149,19 +1148,16 @@ GDBRemoteCommunicationServerCommon::Hand
     if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec))
         return SendErrorResponse (4);
 
-    const ModuleSP module(new Module(matched_module_spec));
-
-    const auto obj_file(module->GetObjectFile());
-    const auto file_offset = obj_file->GetFileOffset();
-    const auto file_size = obj_file->GetByteSize();
+    const auto file_offset = matched_module_spec.GetObjectOffset();
+    const auto file_size = matched_module_spec.GetObjectSize();
+    const auto uuid_str = matched_module_spec.GetUUID().GetAsString("");
 
     StreamGDBRemote response;
 
-    const auto uuid_str = module->GetUUID().GetAsString();
     if (uuid_str.empty())
     {
         std::string md5_hash;
-        if (!FileSystem::CalculateMD5AsString(module_path_spec, file_offset, file_size, md5_hash))
+        if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(), file_offset, file_size, md5_hash))
             return SendErrorResponse (5);
         response.PutCString ("md5:");
         response.PutCStringAsRawHex8(md5_hash.c_str());

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Mon Mar  9 20:15:28 2015
@@ -10,13 +10,19 @@
 #include "lldb/Target/Platform.h"
 
 // C Includes
+
 // C++ Includes
+#include <algorithm>
+#include <fstream>
+#include <vector>
+
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Breakpoint/BreakpointIDList.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/StructuredData.h"
@@ -24,9 +30,16 @@
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
+#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Interpreter/Property.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/Utils.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
+
+#include "Utility/ModuleCache.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -48,6 +61,73 @@ Platform::GetHostPlatformName ()
     return "host";
 }
 
+namespace {
+
+    PropertyDefinition
+    g_properties[] =
+    {
+        { "use-module-cache"      , OptionValue::eTypeBoolean , true,  true, nullptr, nullptr, "Use module cache." },
+        { "module-cache-directory", OptionValue::eTypeFileSpec, true,  0 ,   nullptr, nullptr, "Root directory for cached modules." },
+        {  nullptr                , OptionValue::eTypeInvalid , false, 0,    nullptr, nullptr, nullptr }
+    };
+
+    enum
+    {
+        ePropertyUseModuleCache,
+        ePropertyModuleCacheDirectory
+    };
+
+}  // namespace
+
+
+ConstString
+PlatformProperties::GetSettingName ()
+{
+    static ConstString g_setting_name("platform");
+    return g_setting_name;
+}
+
+PlatformProperties::PlatformProperties ()
+{
+    m_collection_sp.reset (new OptionValueProperties (GetSettingName ()));
+    m_collection_sp->Initialize (g_properties);
+
+    auto module_cache_dir = GetModuleCacheDirectory ();
+    if (!module_cache_dir)
+    {
+        if (!HostInfo::GetLLDBPath (ePathTypeGlobalLLDBTempSystemDir, module_cache_dir))
+            module_cache_dir = FileSpec ("/tmp/lldb", false);
+        module_cache_dir.AppendPathComponent ("module_cache");
+        SetModuleCacheDirectory (module_cache_dir);
+    }
+}
+
+bool
+PlatformProperties::GetUseModuleCache () const
+{
+    const auto idx = ePropertyUseModuleCache;
+    return m_collection_sp->GetPropertyAtIndexAsBoolean (
+        nullptr, idx, g_properties[idx].default_uint_value != 0);
+}
+
+bool
+PlatformProperties::SetUseModuleCache (bool use_module_cache)
+{
+    return m_collection_sp->SetPropertyAtIndexAsBoolean (nullptr, ePropertyUseModuleCache, use_module_cache);
+}
+
+FileSpec
+PlatformProperties::GetModuleCacheDirectory () const
+{
+    return m_collection_sp->GetPropertyAtIndexAsFileSpec (nullptr, ePropertyModuleCacheDirectory);
+}
+
+bool
+PlatformProperties::SetModuleCacheDirectory (const FileSpec& dir_spec)
+{
+    return m_collection_sp->SetPropertyAtIndexAsFileSpec (nullptr, ePropertyModuleCacheDirectory, dir_spec);
+}
+
 //------------------------------------------------------------------
 /// Get the native host platform plug-in. 
 ///
@@ -97,6 +177,13 @@ Platform::Terminate ()
     }
 }
 
+const PlatformPropertiesSP &
+Platform::GetGlobalPlatformProperties ()
+{
+    static const auto g_settings_sp (std::make_shared<PlatformProperties> ());
+    return g_settings_sp;
+}
+
 void
 Platform::SetHostPlatform (const lldb::PlatformSP &platform_sp)
 {
@@ -165,20 +252,37 @@ Platform::GetSharedModule (const ModuleS
                            ModuleSP *old_module_sp_ptr,
                            bool *did_create_ptr)
 {
-    // Don't do any path remapping for the default implementation
-    // of the platform GetSharedModule function, just call through
-    // to our static ModuleList function. Platform subclasses that
-    // implement remote debugging, might have a developer kits
-    // installed that have cached versions of the files for the
-    // remote target, or might implement a download and cache 
-    // locally implementation.
-    const bool always_create = false;
+    if (!IsHost () && GetGlobalPlatformProperties ()->GetUseModuleCache ())
+    {
+        // Use caching only when talking to a remote platform.
+        if (GetCachedSharedModule (module_spec, module_sp))
+        {
+            if (did_create_ptr)
+                *did_create_ptr = true;
+
+            return Error ();
+        }
+    }
     return ModuleList::GetSharedModule (module_spec, 
                                         module_sp,
                                         module_search_paths_ptr,
                                         old_module_sp_ptr,
                                         did_create_ptr,
-                                        always_create);
+                                        false);
+}
+
+bool
+Platform::GetModuleSpec (const FileSpec& module_file_spec,
+                         const ArchSpec& arch,
+                         ModuleSpec &module_spec)
+{
+    ModuleSpecList module_specs;
+    if (ObjectFile::GetModuleSpecifications (module_file_spec, 0, 0, module_specs) == 0)
+        return false;
+
+    ModuleSpec matched_module_spec;
+    return module_specs.FindMatchingModuleSpec (ModuleSpec (module_file_spec, arch),
+                                                module_spec);
 }
 
 PlatformSP
@@ -321,7 +425,8 @@ Platform::Platform (bool is_host) :
     m_ssh_opts (),
     m_ignores_remote_hostname (false),
     m_trap_handlers(),
-    m_calculated_trap_handlers (false)
+    m_calculated_trap_handlers (false),
+    m_module_cache (llvm::make_unique<ModuleCache> ())
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)
@@ -1647,3 +1752,154 @@ Platform::GetTrapHandlerSymbolNames ()
     return m_trap_handlers;
 }
 
+bool
+Platform::GetCachedSharedModule (const ModuleSpec &module_spec,
+                                 lldb::ModuleSP &module_sp)
+{
+    FileSpec cached_file_spec;
+    if (m_module_cache && GetFileFromLocalCache (module_spec, cached_file_spec))
+    {
+        auto cached_module_spec (module_spec);
+        cached_module_spec.GetFileSpec () = cached_file_spec;
+        cached_module_spec.GetPlatformFileSpec () = module_spec.GetFileSpec ();
+        module_sp.reset (new Module (cached_module_spec));
+
+        return true;
+    }
+    return false;
+}
+
+bool
+Platform::GetFileFromLocalCache (const ModuleSpec& module_spec,
+                                 FileSpec &cached_file_spec)
+{
+    Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
+
+    // Get module information from a target.
+    ModuleSpec resolved_module_spec;
+    if (!GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec))
+        return false;
+
+    // Check local cache for a module.
+    auto error = m_module_cache->Get (GetModuleCacheRoot (),
+                                      GetHostname (),
+                                      resolved_module_spec.GetUUID (),
+                                      resolved_module_spec.GetFileSpec (),
+                                      cached_file_spec);
+    if (error.Success ())
+        return true;
+
+    if (log)
+        log->Printf("Platform::%s - module %s not found in local cache: %s",
+                    __FUNCTION__, resolved_module_spec.GetUUID ().GetAsString ().c_str (), error.AsCString ());
+
+    // Get temporary file name for a downloaded module.
+    llvm::SmallString<PATH_MAX> tmp_download_file_path;
+    const auto err_code = llvm::sys::fs::createTemporaryFile (
+        "lldb", resolved_module_spec.GetUUID ().GetAsString ().c_str (), tmp_download_file_path);
+    if (err_code)
+    {
+        if (log)
+            log->Printf ("Platform::%s - failed to create unique file: %s",
+                         __FUNCTION__, err_code.message ().c_str ());
+        return false;
+    }
+
+    llvm::FileRemover tmp_file_remover (tmp_download_file_path.c_str ());
+
+    const FileSpec tmp_download_file_spec (tmp_download_file_path.c_str (), true);
+    // Download a module file.
+    error = DownloadModuleSlice (resolved_module_spec.GetFileSpec (),
+                                 resolved_module_spec.GetObjectOffset (),
+                                 resolved_module_spec.GetObjectSize (),
+                                 tmp_download_file_spec);
+    if (error.Fail ())
+    {
+        if (log)
+            log->Printf("Platform::%s - failed to download %s to %s: %s",
+                        __FUNCTION__, module_spec.GetFileSpec ().GetPath ().c_str (),
+                        tmp_download_file_path.c_str (), error.AsCString ());
+        return false;
+    }
+
+    // Put downloaded file into local module cache.
+    error = m_module_cache->Put (GetModuleCacheRoot (),
+                                 GetHostname (),
+                                 resolved_module_spec.GetUUID (),
+                                 resolved_module_spec.GetFileSpec (),
+                                 tmp_download_file_spec);
+    if (error.Fail ())
+    {
+        if (log)
+            log->Printf("Platform::%s - failed to put module %s into cache: %s",
+                        __FUNCTION__, resolved_module_spec.GetUUID ().GetAsString ().c_str (),
+                        error.AsCString ());
+        return false;
+    }
+
+    error = m_module_cache->Get (GetModuleCacheRoot (),
+                                 GetHostname (),
+                                 resolved_module_spec.GetUUID (),
+                                 resolved_module_spec.GetFileSpec (),
+                                 cached_file_spec);
+    return error.Success ();
+}
+
+Error
+Platform::DownloadModuleSlice (const FileSpec& src_file_spec,
+                               const uint64_t src_offset,
+                               const uint64_t src_size,
+                               const FileSpec& dst_file_spec)
+{
+    Error error;
+
+    std::ofstream dst (dst_file_spec.GetPath(), std::ios::out | std::ios::binary);
+    if (!dst.is_open())
+    {
+        error.SetErrorStringWithFormat ("unable to open destination file: %s", dst_file_spec.GetPath ().c_str ());
+        return error;
+    }
+
+    auto src_fd = OpenFile (src_file_spec,
+                            File::eOpenOptionRead,
+                            lldb::eFilePermissionsFileDefault,
+                            error);
+
+   if (error.Fail ())
+   {
+       error.SetErrorStringWithFormat ("unable to open source file: %s", error.AsCString ());
+       return error;
+   }
+
+    std::vector<char> buffer (1024);
+    auto offset = src_offset;
+    uint64_t total_bytes_read = 0;
+    while (total_bytes_read < src_size)
+    {
+        const auto to_read = std::min (static_cast<uint64_t>(buffer.size ()), src_size - total_bytes_read);
+        const uint64_t n_read = ReadFile (src_fd, offset, &buffer[0], to_read, error);
+        if (error.Fail ())
+            break;
+        if (n_read == 0)
+        {
+            error.SetErrorString ("read 0 bytes");
+            break;
+        }
+        offset += n_read;
+        total_bytes_read += n_read;
+        dst.write (&buffer[0], n_read);
+    }
+
+    Error close_error;
+    CloseFile (src_fd, close_error);  // Ignoring close error.
+
+    return error;
+}
+
+FileSpec
+Platform::GetModuleCacheRoot ()
+{
+    auto dir_spec = GetGlobalPlatformProperties ()->GetModuleCacheDirectory ();
+    dir_spec.AppendPathComponent (GetName ().AsCString ());
+    return dir_spec;
+}

Modified: lldb/trunk/source/Utility/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/CMakeLists.txt?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/source/Utility/CMakeLists.txt (original)
+++ lldb/trunk/source/Utility/CMakeLists.txt Mon Mar  9 20:15:28 2015
@@ -6,6 +6,7 @@ add_lldb_library(lldbUtility
   JSON.cpp
   KQueue.cpp
   LLDBAssert.cpp
+  ModuleCache.cpp
   PseudoTerminal.cpp
   Range.cpp
   RegisterNumber.cpp

Added: lldb/trunk/source/Utility/ModuleCache.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/ModuleCache.cpp?rev=231734&view=auto
==============================================================================
--- lldb/trunk/source/Utility/ModuleCache.cpp (added)
+++ lldb/trunk/source/Utility/ModuleCache.cpp Mon Mar  9 20:15:28 2015
@@ -0,0 +1,132 @@
+//===--------------------- 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/Module.h"
+#include "lldb/Host/FileSystem.h"
+#include "llvm/Support/FileSystem.h"
+
+#include <assert.h>
+
+#include <cstdio>
+#
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+
+const char* kModulesSubdir = ".cache";
+
+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.GetPath ().c_str (),
+                                      eFilePermissionsDirectoryDefault);
+}
+
+}  // namespace
+
+Error
+ModuleCache::Put (const FileSpec &root_dir_spec,
+                  const char *hostname,
+                  const UUID &uuid,
+                  const FileSpec &platform_module_spec,
+                  const FileSpec &tmp_file)
+{
+    const auto module_spec_dir = GetModuleDirectory (root_dir_spec, uuid);
+    auto error = MakeDirectory (module_spec_dir);
+    if (error.Fail ())
+        return error;
+
+    const auto module_file_path = JoinPath (module_spec_dir, platform_module_spec.GetFilename ().AsCString ());
+
+    const auto tmp_file_path = tmp_file.GetPath ();
+    const auto err_code = llvm::sys::fs::copy_file (tmp_file_path.c_str (), module_file_path.GetPath ().c_str ());
+    if (err_code)
+    {
+        error.SetErrorStringWithFormat ("failed to copy file %s to %s: %s",
+                                        tmp_file_path.c_str (),
+                                        module_file_path.GetPath ().c_str (),
+                                        err_code.message ().c_str ());
+    }
+
+    // Create sysroot link to a module.
+    const auto sysroot_module_path_spec = GetHostSysRootModulePath (root_dir_spec, hostname, platform_module_spec);
+    return CreateHostSysRootModuleSymLink (sysroot_module_path_spec, module_file_path);
+}
+
+Error
+ModuleCache::Get (const FileSpec &root_dir_spec,
+                  const char *hostname,
+                  const UUID &uuid,
+                  const FileSpec &platform_module_spec,
+                  FileSpec &cached_module_spec)
+{
+    cached_module_spec.Clear ();
+
+    const auto module_spec_dir = GetModuleDirectory (root_dir_spec, uuid);
+    const auto module_file_path = JoinPath (module_spec_dir, platform_module_spec.GetFilename ().AsCString ());
+
+    Error error;
+    if (!module_file_path.Exists ())
+    {
+        error.SetErrorStringWithFormat ("module %s not found", module_file_path.GetPath ().c_str ());
+        return error;
+    }
+    cached_module_spec = module_file_path;
+
+    // We may have already cached module but downloaded from an another host - in this case let's create a symlink to it.
+    const auto sysroot_module_path_spec = GetHostSysRootModulePath (root_dir_spec, hostname, platform_module_spec);
+    if (!sysroot_module_path_spec.Exists ())
+        CreateHostSysRootModuleSymLink (sysroot_module_path_spec, cached_module_spec);
+
+    return error;
+}
+
+FileSpec
+ModuleCache::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
+ModuleCache::GetHostSysRootModulePath (const FileSpec &root_dir_spec, const char *hostname, const FileSpec &platform_module_spec)
+{
+    const auto sysroot_dir = JoinPath (root_dir_spec, hostname);
+    return JoinPath (sysroot_dir, platform_module_spec.GetPath ().c_str ());
+}
+
+Error
+ModuleCache::CreateHostSysRootModuleSymLink (const FileSpec &sysroot_module_path_spec, const FileSpec &module_file_path)
+{
+    const auto error = MakeDirectory (FileSpec (sysroot_module_path_spec.GetDirectory ().AsCString (), false));
+    if (error.Fail ())
+        return error;
+
+    return FileSystem::Symlink (sysroot_module_path_spec.GetPath ().c_str (),
+                                module_file_path.GetPath ().c_str ());
+}

Added: lldb/trunk/source/Utility/ModuleCache.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/ModuleCache.h?rev=231734&view=auto
==============================================================================
--- lldb/trunk/source/Utility/ModuleCache.h (added)
+++ lldb/trunk/source/Utility/ModuleCache.h Mon Mar  9 20:15:28 2015
@@ -0,0 +1,72 @@
+//===-- 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-types.h"
+#include "lldb/lldb-forward.h"
+
+#include "lldb/Core/Error.h"
+#include "lldb/Host/FileSpec.h"
+
+#include <string>
+
+namespace lldb_private {
+
+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:
+    Error
+    Put (const FileSpec &root_dir_spec,
+         const char *hostname,
+         const UUID &uuid,
+         const FileSpec &platform_module_spec,
+         const FileSpec &tmp_file);
+
+    Error
+    Get (const FileSpec &root_dir_spec,
+         const char *hostname,
+         const UUID &uuid,
+         const FileSpec &platform_module_spec,
+         FileSpec &cached_module_spec);
+
+private:
+    static FileSpec
+    GetModuleDirectory (const FileSpec &root_dir_spec, const UUID &uuid);
+
+    static FileSpec
+    GetHostSysRootModulePath (const FileSpec &root_dir_spec, const char *hostname, const FileSpec &platform_module_spec);
+
+    static Error
+    CreateHostSysRootModuleSymLink (const FileSpec &sysroot_module_path_spec, const FileSpec &module_file_path);
+};
+
+} // namespace lldb_private
+
+#endif  // utility_ModuleCache_h_

Modified: lldb/trunk/test/python_api/hello_world/TestHelloWorld.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/python_api/hello_world/TestHelloWorld.py?rev=231734&r1=231733&r2=231734&view=diff
==============================================================================
--- lldb/trunk/test/python_api/hello_world/TestHelloWorld.py (original)
+++ lldb/trunk/test/python_api/hello_world/TestHelloWorld.py Mon Mar  9 20:15:28 2015
@@ -46,7 +46,6 @@ class HelloWorldTestCase(TestBase):
         self.setTearDownCleanup(dictionary=self.d)
         self.hello_world_attach_with_id_api()
 
-    @not_remote_testsuite_ready
     @python_api_test
     @dwarf_test
     @expectedFailurei386 # llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly
@@ -56,7 +55,7 @@ class HelloWorldTestCase(TestBase):
         Use dwarf map (no dsym) and attach to process with id API.
         """
         self.buildDwarf(dictionary=self.d)
-        self.setTearDownCleanup(dictionary=self.d)
+        #self.setTearDownCleanup(dictionary=self.d)
         self.hello_world_attach_with_id_api()
 
     @not_remote_testsuite_ready
@@ -72,7 +71,6 @@ class HelloWorldTestCase(TestBase):
         self.setTearDownCleanup(dictionary=self.d)
         self.hello_world_attach_with_name_api()
 
-    @not_remote_testsuite_ready
     @python_api_test
     @dwarf_test
     @expectedFailurei386 # llvm.org/pr17384: lldb needs to be aware of linux-vdso.so to unwind stacks properly





More information about the lldb-commits mailing list