Index: include/lldb/Host/android/HostInfoAndroid.h =================================================================== --- include/lldb/Host/android/HostInfoAndroid.h +++ include/lldb/Host/android/HostInfoAndroid.h @@ -21,6 +21,7 @@ public: static FileSpec GetDefaultShell(); + static FileSpec ResolveLibraryPath (const std::string& path, const ArchSpec& arch); protected: static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64); Index: source/Host/android/HostInfoAndroid.cpp =================================================================== --- source/Host/android/HostInfoAndroid.cpp +++ source/Host/android/HostInfoAndroid.cpp @@ -9,8 +9,11 @@ #include "lldb/Host/android/HostInfoAndroid.h" #include "lldb/Host/linux/HostInfoLinux.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" using namespace lldb_private; +using namespace llvm; void HostInfoAndroid::ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64) @@ -39,3 +42,57 @@ { return FileSpec("/system/bin/sh", false); } + +FileSpec +HostInfoAndroid::ResolveLibraryPath(const std::string& module_path, const ArchSpec& arch) +{ + static const char* const ld_library_path_separator = ":"; + static const char* const default_lib32_path[] = { + "/vendor/lib", + "/system/lib", + nullptr + }; + static const char* const default_lib64_path[] = { + "/vendor/lib64", + "/system/lib64", + nullptr + }; + + if (module_path.empty() || module_path[0] == '/') + return FileSpec(module_path.c_str(), true); + + SmallVector ld_paths; + + if (const char* ld_library_path = ::getenv("LD_LIBRARY_PATH")) + StringRef(ld_library_path).split(ld_paths, StringRef(ld_library_path_separator), -1, false); + + const char* const* default_lib_path = nullptr; + switch (arch.GetAddressByteSize()) + { + case 4: + default_lib_path = default_lib32_path; + break; + case 8: + default_lib_path = default_lib64_path; + break; + default: + assert(false && "Unknown address byte size"); + return FileSpec(); + } + + for(const char* const* it = default_lib_path; *it; ++it) + ld_paths.push_back(StringRef(*it)); + + for (const StringRef& path : ld_paths) + { + std::string path_candidate = path; + path_candidate += '/'; + path_candidate += module_path; + + FileSpec file_candidate(path_candidate.c_str(), true); + if (file_candidate.Exists()) + return file_candidate; + } + + return FileSpec(); +} Index: source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp =================================================================== --- source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -252,6 +252,13 @@ 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) Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp =================================================================== --- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -39,6 +39,10 @@ #include "ProcessGDBRemoteLog.h" #include "Utility/StringExtractorGDBRemote.h" +#ifdef __ANDROID__ +#include "lldb/Host/android/HostInfoAndroid.h" +#endif + using namespace lldb; using namespace lldb_private; @@ -1131,14 +1135,21 @@ packet.GetHexByteStringTerminatedBy(module_path, ';'); if (module_path.empty()) return SendErrorResponse (1); - const FileSpec module_path_spec(module_path.c_str(), true); if (packet.GetChar() != ';') return SendErrorResponse (2); std::string triple; packet.GetHexByteString(triple); - const ModuleSpec module_spec(module_path_spec, ArchSpec(triple.c_str())); + 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 ModuleSpec module_spec(module_path_spec, arch); ModuleSpecList module_specs; if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, module_specs)) @@ -1173,6 +1184,9 @@ response.PutCStringAsRawHex8( module_arch.GetTriple().getTriple().c_str()); response.PutChar(';'); + response.PutCString("file_path:"); + response.PutCStringAsRawHex8(module_path_spec.GetPath().c_str()); + response.PutChar(';'); response.PutCString("file_offset:"); response.PutHex64(file_offset); response.PutChar(';');