From dad4db713de4e2d7e783cde6fc3191624c7bac29 Mon Sep 17 00:00:00 2001 From: Tamas Berghammer Date: Fri, 13 Mar 2015 11:16:08 +0000 Subject: [PATCH] Add filepath to qModuleInfo packet The file path is currently required on android because the executables only contain the name of the system libraries without their path. This CL add an extra field to the qModuleInfo packet to return the full path of a modul and add logic to locate a shared module on android. Differential revision: http://reviews.llvm.org/D8221 llvm-svn: 232156 --- lldb/include/lldb/Host/android/HostInfoAndroid.h | 1 + lldb/source/Host/android/HostInfoAndroid.cpp | 55 ++++++++++++++++++++++ .../gdb-server/PlatformRemoteGDBServer.cpp | 7 +++ .../GDBRemoteCommunicationServerCommon.cpp | 18 ++++++- 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/lldb/include/lldb/Host/android/HostInfoAndroid.h b/lldb/include/lldb/Host/android/HostInfoAndroid.h index 63908c2..ed9d3ee 100644 --- a/lldb/include/lldb/Host/android/HostInfoAndroid.h +++ b/lldb/include/lldb/Host/android/HostInfoAndroid.h @@ -21,6 +21,7 @@ class HostInfoAndroid : public HostInfoLinux public: static FileSpec GetDefaultShell(); + static FileSpec ResolveLibraryPath (const std::string& path, const ArchSpec& arch); protected: static void ComputeHostArchitectureSupport(ArchSpec &arch_32, ArchSpec &arch_64); diff --git a/lldb/source/Host/android/HostInfoAndroid.cpp b/lldb/source/Host/android/HostInfoAndroid.cpp index de5bae7..b819f92 100644 --- a/lldb/source/Host/android/HostInfoAndroid.cpp +++ b/lldb/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,55 @@ HostInfoAndroid::GetDefaultShell() { 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) + { + FileSpec file_candidate(path.str().c_str(), true); + file_candidate.AppendPathComponent(module_path.c_str()); + + if (file_candidate.Exists()) + return file_candidate; + } + + return FileSpec(); +} diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index 6ab48c8..b36d4c0 100644 --- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -252,6 +252,13 @@ PlatformRemoteGDBServer::GetModuleSpec (const FileSpec& module_file_spec, 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) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index 0a2385f..31202fc 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/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 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote 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 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote 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(';'); -- 2.7.4