diff options
author | Kazuki Sakamoto <sakamoto@splhack.org> | 2023-06-12 10:49:54 -0700 |
---|---|---|
committer | Kazuki Sakamoto <kaz@meta.com> | 2023-06-20 15:21:46 -0700 |
commit | 12dee9d3cd762d9754e2adadffa13c1cce85cf07 (patch) | |
tree | 79acbb2c1f7e8a5580209e59c6e15ae1fb88f310 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp | |
parent | 6c8731551884713f7d322852844a67d38a433623 (diff) | |
download | llvm-12dee9d3cd762d9754e2adadffa13c1cce85cf07.zip llvm-12dee9d3cd762d9754e2adadffa13c1cce85cf07.tar.gz llvm-12dee9d3cd762d9754e2adadffa13c1cce85cf07.tar.bz2 |
[lldb][Android] Support zip .so file
In Android API level 23 and above, dynamic loader is able to load .so file
directly from APK, which is zip file.
https://android.googlesource.com/platform/bionic/+/master/
android-changes-for-ndk-developers.md#
opening-shared-libraries-directly-from-an-apk
The .so file is page aligned and uncompressed, so
ObjectFileELF::GetModuleSpecifications works with .so file offset and size
directly from zip file without extracting it. (D152757)
GDBRemoteCommunicationServerCommon::GetModuleInfo returns a module spec to LLDB
with "zip_path!/so_path" file spec, which is passed through from Android
dynamic loader, and the .so file offset and size.
PlatformAndroid::DownloadModuleSlice uses 'shell dd' to download the .so file
slice from the zip file with the .so file offset and size.
Differential Revision: https://reviews.llvm.org/D152759
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index 9e90e98..b4fb5b6 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -44,9 +44,9 @@ #ifdef __ANDROID__ #include "lldb/Host/android/HostInfoAndroid.h" +#include "lldb/Host/common/ZipFileResolver.h" #endif - using namespace lldb; using namespace lldb_private::process_gdb_remote; using namespace lldb_private; @@ -1138,7 +1138,7 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo( response.PutCString("file_path:"); response.PutStringAsRawHex8( - matched_module_spec.GetFileSpec().GetPath().c_str()); + matched_module_spec.GetFileSpec().GetPath().c_str()); response.PutChar(';'); response.PutCString("file_offset:"); response.PutHex64(file_offset); @@ -1326,17 +1326,50 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch); - const ModuleSpec module_spec(module_path_spec, arch); + + lldb::offset_t file_offset = 0; + lldb::offset_t file_size = 0; +#ifdef __ANDROID__ + // In Android API level 23 and above, dynamic loader is able to load .so file + // directly from zip file. In that case, module_path will be + // "zip_path!/so_path". Resolve the zip file path, .so file offset and size. + ZipFileResolver::FileKind file_kind = ZipFileResolver::eFileKindInvalid; + std::string file_path; + if (!ZipFileResolver::ResolveSharedLibraryPath( + module_path_spec, file_kind, file_path, file_offset, file_size)) { + return ModuleSpec(); + } + lldbassert(file_kind != ZipFileResolver::eFileKindInvalid); + // For zip .so file, this file_path will contain only the actual zip file + // path for the object file processing. Otherwise it is the same as + // module_path. + const FileSpec actual_module_path_spec(file_path); +#else + // It is just module_path_spec reference for other platforms. + const FileSpec &actual_module_path_spec = module_path_spec; +#endif + + const ModuleSpec module_spec(actual_module_path_spec, arch); ModuleSpecList module_specs; - if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, - module_specs)) + if (!ObjectFile::GetModuleSpecifications(actual_module_path_spec, file_offset, + file_size, module_specs)) return ModuleSpec(); ModuleSpec matched_module_spec; if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) return ModuleSpec(); +#ifdef __ANDROID__ + if (file_kind == ZipFileResolver::eFileKindZip) { + // For zip .so file, matched_module_spec contains only the actual zip file + // path for the object file processing. Overwrite the matched_module_spec + // file spec with the original module_path_spec to pass "zip_path!/so_path" + // through to PlatformAndroid::DownloadModuleSlice. + *matched_module_spec.GetFileSpecPtr() = module_path_spec; + } +#endif + return matched_module_spec; } |