Fetch module specification from remote process also

Previously the remote module sepcification was fetched only from the
remote platform. With this CL if we have a remote process then we ask it
if it have any information from a given module. It is required because
on android the dynamic linker only reports the name of the SO file and
the platform can't always find it without a full path (the process can
do it based on /proc/<pid>/maps).

Differential revision: http://reviews.llvm.org/D8547

llvm-svn: 233061
diff --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index cd52f05..dd2ecfc 100644
--- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -613,6 +613,7 @@
 
 Error
 PlatformFreeBSD::GetSharedModule (const ModuleSpec &module_spec,
+                                  Process* process,
                                   ModuleSP &module_sp,
                                   const FileSpecList *module_search_paths_ptr,
                                   ModuleSP *old_module_sp_ptr,
@@ -628,6 +629,7 @@
         if (m_remote_platform_sp)
         {
             error = m_remote_platform_sp->GetSharedModule (module_spec,
+                                                           process,
                                                            module_sp,
                                                            module_search_paths_ptr,
                                                            old_module_sp_ptr,
@@ -639,6 +641,7 @@
     {
         // Fall back to the local platform and find the file locally
         error = Platform::GetSharedModule (module_spec,
+                                           process,
                                            module_sp,
                                            module_search_paths_ptr,
                                            old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
index 714b0d4..57dfb6b 100644
--- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -152,10 +152,11 @@
 
     lldb_private::Error
     GetSharedModule (const lldb_private::ModuleSpec &module_spec,
+                     lldb_private::Process* process,
                      lldb::ModuleSP &module_sp,
                      const lldb_private::FileSpecList *module_search_paths_ptr,
                      lldb::ModuleSP *old_module_sp_ptr,
-                     bool *did_create_ptr);
+                     bool *did_create_ptr) override;
 
     virtual bool
     GetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch);
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 02ff14f..a2c33d5 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -234,11 +234,11 @@
         if (resolved_module_spec.GetArchitecture().IsValid())
         {
             error = ModuleList::GetSharedModule (resolved_module_spec,
-                                                 exe_module_sp, 
+                                                 exe_module_sp,
                                                  module_search_paths_ptr,
-                                                 NULL, 
+                                                 NULL,
                                                  NULL);
-        
+
             if (error.Fail() || exe_module_sp.get() == NULL || exe_module_sp->GetObjectFile() == NULL)
             {
                 exe_module_sp.reset();
@@ -256,11 +256,12 @@
             for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx)
             {
                 error = GetSharedModule (resolved_module_spec,
-                                         exe_module_sp, 
+                                         NULL,
+                                         exe_module_sp,
                                          module_search_paths_ptr,
-                                         NULL, 
+                                         NULL,
                                          NULL);
-                // Did we find an executable using one of the 
+                // Did we find an executable using one of the
                 if (error.Success())
                 {
                     if (exe_module_sp && exe_module_sp->GetObjectFile())
@@ -467,6 +468,7 @@
 
 Error
 PlatformDarwin::GetSharedModule (const ModuleSpec &module_spec,
+                                 Process* process,
                                  ModuleSP &module_sp,
                                  const FileSpecList *module_search_paths_ptr,
                                  ModuleSP *old_module_sp_ptr,
@@ -482,6 +484,7 @@
         if (m_remote_platform_sp)
         {
             error = m_remote_platform_sp->GetSharedModule (module_spec,
+                                                           process,
                                                            module_sp,
                                                            module_search_paths_ptr,
                                                            old_module_sp_ptr,
@@ -493,6 +496,7 @@
     {
         // Fall back to the local platform and find the file locally
         error = Platform::GetSharedModule (module_spec,
+                                           process,
                                            module_sp,
                                            module_search_paths_ptr,
                                            old_module_sp_ptr,
@@ -513,6 +517,7 @@
                     if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec()))
                     {
                         Error new_error (Platform::GetSharedModule (new_module_spec,
+                                                                    process,
                                                                     module_sp,
                                                                     NULL,
                                                                     old_module_sp_ptr,
@@ -542,6 +547,7 @@
                                 ModuleSpec new_module_spec (module_spec);
                                 new_module_spec.GetFileSpec() = new_file_spec;
                                 Error new_error (Platform::GetSharedModule (new_module_spec,
+                                                                            process,
                                                                             module_sp,
                                                                             NULL,
                                                                             old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index cdc69a6..c68b5cc 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -42,9 +42,10 @@
     LocateExecutableScriptingResources (lldb_private::Target *target,
                                         lldb_private::Module &module,
                                         lldb_private::Stream* feedback_stream) override;
-    
+
     lldb_private::Error
     GetSharedModule (const lldb_private::ModuleSpec &module_spec,
+                     lldb_private::Process* process,
                      lldb::ModuleSP &module_sp,
                      const lldb_private::FileSpecList *module_search_paths_ptr,
                      lldb::ModuleSP *old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index aef8034..9ea7389 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -324,6 +324,7 @@
 
 lldb_private::Error
 PlatformMacOSX::GetSharedModule (const lldb_private::ModuleSpec &module_spec,
+                                 Process* process,
                                  lldb::ModuleSP &module_sp,
                                  const lldb_private::FileSpecList *module_search_paths_ptr,
                                  lldb::ModuleSP *old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
index bef8e98..0b8d35b 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
@@ -63,6 +63,7 @@
     
     lldb_private::Error
     GetSharedModule (const lldb_private::ModuleSpec &module_spec,
+                     lldb_private::Process* process,
                      lldb::ModuleSP &module_sp,
                      const lldb_private::FileSpecList *module_search_paths_ptr,
                      lldb::ModuleSP *old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index 7ae7e2d..37226e4 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -693,6 +693,7 @@
 
 Error
 PlatformRemoteiOS::GetSharedModule (const ModuleSpec &module_spec,
+                                    Process* process,
                                     ModuleSP &module_sp,
                                     const FileSpecList *module_search_paths_ptr,
                                     ModuleSP *old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
index e90b4d8..e089d39 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
@@ -87,6 +87,7 @@
 
     lldb_private::Error
     GetSharedModule (const lldb_private::ModuleSpec &module_spec,
+                     lldb_private::Process* process,
                      lldb::ModuleSP &module_sp,
                      const lldb_private::FileSpecList *module_search_paths_ptr,
                      lldb::ModuleSP *old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
index 70c81a2..3214cc2 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.cpp
@@ -371,6 +371,7 @@
 
 Error
 PlatformiOSSimulator::GetSharedModule (const ModuleSpec &module_spec,
+                                       Process* process,
                                        ModuleSP &module_sp,
                                        const FileSpecList *module_search_paths_ptr,
                                        ModuleSP *old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h b/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
index 4cb336a..51f8abb 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformiOSSimulator.h
@@ -85,6 +85,7 @@
 
     lldb_private::Error
     GetSharedModule (const lldb_private::ModuleSpec &module_spec,
+                     lldb_private::Process* process,
                      lldb::ModuleSP &module_sp,
                      const lldb_private::FileSpecList *module_search_paths_ptr,
                      lldb::ModuleSP *old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
index c08feef..9520cba 100644
--- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -617,6 +617,7 @@
 
 Error
 PlatformWindows::GetSharedModule (const ModuleSpec &module_spec,
+                                  Process* process,
                                   ModuleSP &module_sp,
                                   const FileSpecList *module_search_paths_ptr,
                                   ModuleSP *old_module_sp_ptr,
@@ -632,6 +633,7 @@
         if (m_remote_platform_sp)
         {
             error = m_remote_platform_sp->GetSharedModule (module_spec,
+                                                           process,
                                                            module_sp,
                                                            module_search_paths_ptr,
                                                            old_module_sp_ptr,
@@ -643,6 +645,7 @@
     {
         // Fall back to the local platform and find the file locally
         error = Platform::GetSharedModule (module_spec,
+                                           process,
                                            module_sp,
                                            module_search_paths_ptr,
                                            old_module_sp_ptr,
diff --git a/lldb/source/Plugins/Platform/Windows/PlatformWindows.h b/lldb/source/Plugins/Platform/Windows/PlatformWindows.h
index 7a78565..c5d4c7d 100644
--- a/lldb/source/Plugins/Platform/Windows/PlatformWindows.h
+++ b/lldb/source/Plugins/Platform/Windows/PlatformWindows.h
@@ -133,10 +133,11 @@
 
     lldb_private::Error
     GetSharedModule(const lldb_private::ModuleSpec &module_spec,
+                    lldb_private::Process* process,
                     lldb::ModuleSP &module_sp,
                     const lldb_private::FileSpecList *module_search_paths_ptr,
                     lldb::ModuleSP *old_module_sp_ptr,
-                    bool *did_create_ptr);
+                    bool *did_create_ptr) override;
 
     virtual bool
     GetSupportedArchitectureAtIndex(uint32_t idx, lldb_private::ArchSpec &arch);
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index b36d4c0..9cd2270 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -207,8 +207,7 @@
 
     const auto module_path = module_file_spec.GetPath ();
 
-    StringExtractorGDBRemote response;
-    if (!m_gdb_client.GetModuleInfo (module_path.c_str (), arch, response))
+    if (!m_gdb_client.GetModuleInfo (module_file_spec, arch, module_spec))
     {
         if (log)
             log->Printf ("PlatformRemoteGDBServer::%s - failed to get module info for %s:%s",
@@ -216,51 +215,6 @@
         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);
-        }
-        else if (name == "file_path")
-        {
-            extractor.GetStringRef ().swap (value);
-            extractor.SetFilePos (0);
-            extractor.GetHexByteString (value);
-            module_spec.GetFileSpec () = FileSpec (value.c_str(), false);
-        }
-    }
-
     if (log)
     {
         StreamString stream;
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index fd3a62e..bdf1d72 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -136,12 +136,13 @@
     PtraceWrapper((req), (pid), (addr), (data), (data_size), (error))
 #endif
 
+using namespace lldb;
+using namespace lldb_private;
+using namespace llvm;
+
 // Private bits we only need internally.
 namespace
 {
-    using namespace lldb;
-    using namespace lldb_private;
-
     static void * const EXIT_OPERATION = nullptr;
 
     const UnixSignals&
@@ -1051,8 +1052,6 @@
 
 }
 
-using namespace lldb_private;
-
 // Simple helper function to ensure flags are enabled on the given file
 // descriptor.
 static bool
@@ -3979,3 +3978,42 @@
 
     return err;
 }
+
+Error
+NativeProcessLinux::GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec)
+{
+    char maps_file_name[32];
+    snprintf(maps_file_name, sizeof(maps_file_name), "/proc/%" PRIu64 "/maps", GetID());
+
+    FileSpec maps_file_spec(maps_file_name, false);
+    if (!maps_file_spec.Exists()) {
+        file_spec.Clear();
+        return Error("/proc/%" PRIu64 "/maps file doesn't exists!", GetID());
+    }
+
+    FileSpec module_file_spec(module_path, true);
+
+    std::ifstream maps_file(maps_file_name);
+    std::string maps_data_str((std::istreambuf_iterator<char>(maps_file)), std::istreambuf_iterator<char>());
+    StringRef maps_data(maps_data_str.c_str());
+
+    while (!maps_data.empty())
+    {
+        StringRef maps_row;
+        std::tie(maps_row, maps_data) = maps_data.split('\n');
+
+        SmallVector<StringRef, 16> maps_columns;
+        maps_row.split(maps_columns, StringRef(" "), -1, false);
+
+        if (maps_columns.size() >= 6)
+        {
+            file_spec.SetFile(maps_columns[5].str().c_str(), false);
+            if (file_spec.GetFilename() == module_file_spec.GetFilename())
+                return Error();
+        }
+    }
+
+    file_spec.Clear();
+    return Error("Module file (%s) not found in /proc/%" PRIu64 "/maps file!",
+                 module_file_spec.GetFilename().AsCString(), GetID());
+}
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
index 07220e9..b9aff86 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -157,7 +157,10 @@
         /// For instance, the extended floating-point register set.
         Error
         WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
-        
+
+        Error
+        GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override;
+
     protected:
         // ---------------------------------------------------------------------
         // NativeProcessProtocol protected interface
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index d9acf6c..aad69a0 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -21,6 +21,7 @@
 #include "llvm/ADT/Triple.h"
 #include "lldb/Interpreter/Args.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/State.h"
 #include "lldb/Core/StreamGDBRemote.h"
 #include "lldb/Core/StreamString.h"
@@ -3705,20 +3706,72 @@
 }
 
 bool
-GDBRemoteCommunicationClient::GetModuleInfo (const char* module_path,
+GDBRemoteCommunicationClient::GetModuleInfo (const FileSpec& module_file_spec,
                                              const lldb_private::ArchSpec& arch_spec,
-                                             StringExtractorGDBRemote &response)
+                                             ModuleSpec &module_spec)
 {
-    if (!(module_path && module_path[0]))
+    std::string module_path = module_file_spec.GetPath ();
+    if (module_path.empty ())
         return false;
 
     StreamString packet;
     packet.PutCString("qModuleInfo:");
-    packet.PutBytesAsRawHex8(module_path, strlen(module_path));
+    packet.PutCStringAsRawHex8(module_path.c_str());
     packet.PutCString(";");
     const auto& tripple = arch_spec.GetTriple().getTriple();
     packet.PutBytesAsRawHex8(tripple.c_str(), tripple.size());
 
-    return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success &&
-        !response.IsErrorResponse ();
+    StringExtractorGDBRemote response;
+    if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) != PacketResult::Success)
+        return false;
+
+    if (response.IsErrorResponse ())
+        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);
+        }
+        else if (name == "file_path")
+        {
+            extractor.GetStringRef ().swap (value);
+            extractor.SetFilePos (0);
+            extractor.GetHexByteString (value);
+            module_spec.GetFileSpec () = FileSpec (value.c_str(), false);
+        }
+    }
+
+    return true;
 }
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 0a0f0e4..acd8a17 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -535,9 +535,9 @@
     GetThreadExtendedInfoSupported();
 
     bool
-    GetModuleInfo (const char* module_path,
+    GetModuleInfo (const lldb_private::FileSpec& module_file_spec,
                    const lldb_private::ArchSpec& arch_spec,
-                   StringExtractorGDBRemote &response);
+                   lldb_private::ModuleSpec &module_spec);
 
 protected:
 
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index 74e2863..3e9ad7c 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -1144,12 +1144,7 @@
     packet.GetHexByteString(triple);
     ArchSpec arch(triple.c_str());
 
-#ifdef __ANDROID__
-    const FileSpec module_path_spec = HostInfoAndroid::ResolveLibraryPath(module_path, arch);
-#else
-    const FileSpec module_path_spec(module_path.c_str(), true);
-#endif
-
+    const FileSpec module_path_spec = FindModuleFile(module_path, arch);
     const ModuleSpec module_spec(module_path_spec, arch);
 
     ModuleSpecList module_specs;
@@ -1293,3 +1288,14 @@
             response.PutCString ("ptrsize:2;");
     }
 }
+
+FileSpec
+GDBRemoteCommunicationServerCommon::FindModuleFile(const std::string& module_path,
+                                                   const ArchSpec& arch)
+{
+#ifdef __ANDROID__
+    return HostInfoAndroid::ResolveLibraryPath(module_path, arch);
+#else
+    return FileSpec(module_path.c_str(), true);
+#endif
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
index 8b5248a..8fc270f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h
@@ -35,26 +35,6 @@
     virtual
     ~GDBRemoteCommunicationServerCommon();
 
-    bool
-    GetThreadSuffixSupported () override
-    {
-        return true;
-    }
-
-    //------------------------------------------------------------------
-    /// Launch a process with the current launch settings.
-    ///
-    /// This method supports running an lldb-gdbserver or similar
-    /// server in a situation where the startup code has been provided
-    /// with all the information for a child process to be launched.
-    ///
-    /// @return
-    ///     An Error object indicating the success or failure of the
-    ///     launch.
-    //------------------------------------------------------------------
-    virtual lldb_private::Error
-    LaunchProcess () = 0;
-
 protected:
     std::set<lldb::pid_t> m_spawned_pids;
     lldb_private::Mutex m_spawned_pids_mutex;
@@ -195,6 +175,29 @@
                                   return (static_cast<T*>(this)->*handler) (packet);
                               });
     }
+
+    bool
+    GetThreadSuffixSupported () override
+    {
+        return true;
+    }
+
+    //------------------------------------------------------------------
+    /// Launch a process with the current launch settings.
+    ///
+    /// This method supports running an lldb-gdbserver or similar
+    /// server in a situation where the startup code has been provided
+    /// with all the information for a child process to be launched.
+    ///
+    /// @return
+    ///     An Error object indicating the success or failure of the
+    ///     launch.
+    //------------------------------------------------------------------
+    virtual lldb_private::Error
+    LaunchProcess () = 0;
+
+    virtual lldb_private::FileSpec
+    FindModuleFile (const std::string& module_path, const lldb_private::ArchSpec& arch);
 };
 
 #endif  // liblldb_GDBRemoteCommunicationServerCommon_h_
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index d4a1643..3892f48 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -2735,3 +2735,20 @@
     m_active_auxv_buffer_sp.reset ();
 #endif
 }
+
+FileSpec
+GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string& module_path,
+                                                 const ArchSpec& arch)
+{
+    if (m_debugged_process_sp)
+    {
+        FileSpec file_spec;
+        if (m_debugged_process_sp->GetLoadedModuleFileSpec(module_path.c_str(), file_spec).Success())
+        {
+            if (file_spec.Exists())
+                return file_spec;
+        }
+    }
+
+    return GDBRemoteCommunicationServerCommon::FindModuleFile(module_path, arch);
+}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 5c8f669..d7fc115 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -252,6 +252,9 @@
     static void
     STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
 
+    lldb_private::FileSpec
+    FindModuleFile (const std::string& module_path, const lldb_private::ArchSpec& arch) override;
+
 private:
     bool
     DebuggedProcessReaped (lldb::pid_t pid);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 62695b4..d9912cc 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -3398,6 +3398,34 @@
     }
 }
 
+bool
+ProcessGDBRemote::GetModuleSpec(const FileSpec& module_file_spec,
+                                const ArchSpec& arch,
+                                ModuleSpec &module_spec)
+{
+    Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PLATFORM);
+
+    if (!m_gdb_comm.GetModuleInfo (module_file_spec, arch, module_spec))
+    {
+        if (log)
+            log->Printf ("ProcessGDBRemote::%s - failed to get module info for %s:%s",
+                         __FUNCTION__, module_file_spec.GetPath ().c_str (),
+                         arch.GetTriple ().getTriple ().c_str ());
+        return false;
+    }
+
+    if (log)
+    {
+        StreamString stream;
+        module_spec.Dump (stream);
+        log->Printf ("ProcessGDBRemote::%s - got module info for (%s:%s) : %s",
+                     __FUNCTION__, module_file_spec.GetPath ().c_str (),
+                     arch.GetTriple ().getTriple ().c_str (), stream.GetString ().c_str ());
+    }
+
+    return true;
+}
+
 class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed
 {
 private:
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 736525a..8cd445e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -236,6 +236,11 @@
     void
     SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max);
 
+    bool
+    GetModuleSpec(const lldb_private::FileSpec& module_file_spec,
+                  const lldb_private::ArchSpec& arch,
+                  lldb_private::ModuleSpec &module_spec) override;
+
 protected:
     friend class ThreadGDBRemote;
     friend class GDBRemoteCommunicationClient;
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index d8ad8c7..671ebf0 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -247,6 +247,7 @@
 
 Error
 Platform::GetSharedModule (const ModuleSpec &module_spec,
+                           Process* process,
                            ModuleSP &module_sp,
                            const FileSpecList *module_search_paths_ptr,
                            ModuleSP *old_module_sp_ptr,
@@ -255,7 +256,7 @@
     if (!IsHost () && GetGlobalPlatformProperties ()->GetUseModuleCache ())
     {
         // Use caching only when talking to a remote platform.
-        if (GetCachedSharedModule (module_spec, module_sp))
+        if (GetCachedSharedModule (module_spec, process, module_sp))
         {
             if (did_create_ptr)
                 *did_create_ptr = true;
@@ -1780,7 +1781,7 @@
 {
     if (GetGlobalPlatformProperties ()->GetUseModuleCache ())
     {
-        if (GetCachedSharedModule (module_spec, module_sp))
+        if (GetCachedSharedModule (module_spec, nullptr, module_sp))
             return Error ();
     }
 
@@ -1791,21 +1792,36 @@
 
 bool
 Platform::GetCachedSharedModule (const ModuleSpec &module_spec,
+                                 Process* process,
                                  lldb::ModuleSP &module_sp)
 {
-    return (m_module_cache && GetModuleFromLocalCache (module_spec, module_sp));
+    return (m_module_cache && GetModuleFromLocalCache (module_spec, process, module_sp));
 }
 
 bool
 Platform::GetModuleFromLocalCache (const ModuleSpec& module_spec,
+                                   Process* process,
                                    lldb::ModuleSP &module_sp)
 {
     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;
+    bool got_module_spec = false;
+
+    if (process)
+    {
+        // Try to get module information from the process
+        if (process->GetModuleSpec (module_spec.GetFileSpec (), module_spec.GetArchitecture (), resolved_module_spec))
+            got_module_spec = true;
+    }
+
+    if (!got_module_spec)
+    {
+        // Get module information from a target.
+        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 (),
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index b1aad10..579f9ae 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -16,6 +16,7 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/State.h"
 #include "lldb/Core/StreamFile.h"
@@ -6475,3 +6476,12 @@
     else
         return (*pos).second;
 }
+
+bool
+Process::GetModuleSpec(const FileSpec& module_file_spec,
+                       const ArchSpec& arch,
+                       ModuleSpec& module_spec)
+{
+    module_spec.Clear();
+    return false;
+}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index a39aeb1..d2d7651 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -1727,8 +1727,9 @@
                 // module in the shared module cache.
                 if (m_platform_sp)
                 {
-                    error = m_platform_sp->GetSharedModule (module_spec, 
-                                                            module_sp, 
+                    error = m_platform_sp->GetSharedModule (module_spec,
+                                                            m_process_sp.get(),
+                                                            module_sp,
                                                             &GetExecutableSearchPaths(),
                                                             &old_module_sp,
                                                             &did_create_module);