aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
diff options
context:
space:
mode:
authorKazuki Sakamoto <sakamoto@splhack.org>2023-06-12 10:49:54 -0700
committerKazuki Sakamoto <kaz@meta.com>2023-06-20 15:21:46 -0700
commit12dee9d3cd762d9754e2adadffa13c1cce85cf07 (patch)
tree79acbb2c1f7e8a5580209e59c6e15ae1fb88f310 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
parent6c8731551884713f7d322852844a67d38a433623 (diff)
downloadllvm-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.cpp43
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;
}