splhack updated this revision to Diff 531579.
splhack added a comment.
Fixed diff dependencies in order to fix CI
https://reviews.llvm.org/B238946
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D152933/new/
https://reviews.llvm.org/D152933
Files:
lldb/source/Plugins/Platform/Android/CMakeLists.txt
lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
lldb/source/Plugins/Platform/Android/PlatformAndroid.h
lldb/source/Plugins/Platform/Android/PlatformAndroidProperties.td
lldb/unittests/Platform/Android/PlatformAndroidTest.cpp
Index: lldb/unittests/Platform/Android/PlatformAndroidTest.cpp
===================================================================
--- lldb/unittests/Platform/Android/PlatformAndroidTest.cpp
+++ lldb/unittests/Platform/Android/PlatformAndroidTest.cpp
@@ -52,6 +52,7 @@
}
MOCK_METHOD0(GetAdbClient, AdbClientSP());
+ MOCK_METHOD0(GetPropertyRunAs, llvm::StringRef());
};
} // namespace
@@ -100,6 +101,32 @@
.Success());
}
+TEST_F(PlatformAndroidTest, DownloadModuleSliceWithZipFileAndRunAs) {
+ auto adb_client = new MockAdbClient();
+ EXPECT_CALL(*adb_client,
+ ShellToFile(StrEq("run-as 'com.example.test' "
+ "dd if='/system/app/Test/Test.apk' "
+ "iflag=skip_bytes,count_bytes "
+ "skip=4096 count=3600 status=none"),
+ _, _))
+ .Times(1)
+ .WillOnce(Return(Status()));
+
+ EXPECT_CALL(*this, GetPropertyRunAs())
+ .Times(1)
+ .WillOnce(Return(llvm::StringRef("com.example.test")));
+
+ EXPECT_CALL(*this, GetAdbClient())
+ .Times(1)
+ .WillOnce(Return(ByMove(std::move(AdbClientSP(adb_client)))));
+
+ EXPECT_TRUE(
+ DownloadModuleSlice(
+ FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096,
+ 3600, FileSpec())
+ .Success());
+}
+
TEST_F(PlatformAndroidTest, GetFileWithNormalFile) {
auto sync_service = new MockSyncService();
EXPECT_CALL(*sync_service, Stat(FileSpec("/data/local/tmp/test"), _, _, _))
@@ -152,3 +179,40 @@
FileSpec())
.Success());
}
+
+TEST_F(PlatformAndroidTest, GetFileWithCatFallbackAndRunAs) {
+ auto sync_service = new MockSyncService();
+ EXPECT_CALL(
+ *sync_service,
+ Stat(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), _, _, _))
+ .Times(1)
+ .WillOnce(DoAll(SetArgReferee<1>(0), Return(Status())));
+
+ auto adb_client0 = new MockAdbClient();
+ EXPECT_CALL(*adb_client0, GetSyncService(_))
+ .Times(1)
+ .WillOnce(Return(ByMove(std::move(SyncServiceSP(sync_service)))));
+
+ auto adb_client1 = new MockAdbClient();
+ EXPECT_CALL(
+ *adb_client1,
+ ShellToFile(StrEq("run-as 'com.example.app' "
+ "cat '/data/data/com.example.app/lib-main/libtest.so'"),
+ _, _))
+ .Times(1)
+ .WillOnce(Return(Status()));
+
+ EXPECT_CALL(*this, GetPropertyRunAs())
+ .Times(1)
+ .WillOnce(Return(llvm::StringRef("com.example.app")));
+
+ EXPECT_CALL(*this, GetAdbClient())
+ .Times(2)
+ .WillOnce(Return(ByMove(std::move(AdbClientSP(adb_client0)))))
+ .WillOnce(Return(ByMove(std::move(AdbClientSP(adb_client1)))));
+
+ EXPECT_TRUE(
+ GetFile(FileSpec("/data/data/com.example.app/lib-main/libtest.so"),
+ FileSpec())
+ .Success());
+}
Index: lldb/source/Plugins/Platform/Android/PlatformAndroidProperties.td
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Platform/Android/PlatformAndroidProperties.td
@@ -0,0 +1,9 @@
+include "../../../../include/lldb/Core/PropertiesBase.td"
+
+let Definition = "android" in {
+ def PlatformRunAs: Property<"run-as", "String">,
+ Global,
+ DefaultStringValue<"">,
+ Desc<"Specify package name to run adb shell command with 'run-as' as the "
+ "package user when necessary (e.g. to get file with 'cat' and 'dd').">;
+}
Index: lldb/source/Plugins/Platform/Android/PlatformAndroid.h
===================================================================
--- lldb/source/Plugins/Platform/Android/PlatformAndroid.h
+++ lldb/source/Plugins/Platform/Android/PlatformAndroid.h
@@ -30,6 +30,8 @@
// lldb_private::PluginInterface functions
static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch);
+ static void DebuggerInitialize(lldb_private::Debugger &debugger);
+
static llvm::StringRef GetPluginNameStatic(bool is_host) {
return is_host ? Platform::GetHostPlatformName() : "remote-android";
}
@@ -73,6 +75,10 @@
typedef std::unique_ptr<AdbClient> AdbClientSP;
virtual AdbClientSP GetAdbClient();
+ virtual llvm::StringRef GetPropertyRunAs();
+
+ std::string GetRunAs();
+
private:
AdbClient::SyncService *GetSyncService(Status &error);
@@ -81,7 +87,7 @@
uint32_t m_sdk_version;
};
-} // namespace platofor_android
+} // namespace platform_android
} // namespace lldb_private
#endif // LLDB_SOURCE_PLUGINS_PLATFORM_ANDROID_PLATFORMANDROID_H
Index: lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
===================================================================
--- lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -29,10 +29,36 @@
LLDB_PLUGIN_DEFINE(PlatformAndroid)
-static uint32_t g_initialize_count = 0;
-static const unsigned int g_android_default_cache_size =
+namespace {
+
+#define LLDB_PROPERTIES_android
+#include "PlatformAndroidProperties.inc"
+
+enum {
+#define LLDB_PROPERTIES_android
+#include "PlatformAndroidPropertiesEnum.inc"
+};
+
+class PluginProperties : public Properties {
+public:
+ PluginProperties() {
+ m_collection_sp = std::make_shared<OptionValueProperties>(
+ ConstString(PlatformAndroid::GetPluginNameStatic(false)));
+ m_collection_sp->Initialize(g_android_properties);
+ }
+};
+
+static PluginProperties &GetGlobalProperties() {
+ static PluginProperties g_settings;
+ return g_settings;
+}
+
+uint32_t g_initialize_count = 0;
+const unsigned int g_android_default_cache_size =
2048; // Fits inside 4k adb packet.
+} // end of anonymous namespace
+
void PlatformAndroid::Initialize() {
PlatformLinux::Initialize();
@@ -45,7 +71,7 @@
PluginManager::RegisterPlugin(
PlatformAndroid::GetPluginNameStatic(false),
PlatformAndroid::GetPluginDescriptionStatic(false),
- PlatformAndroid::CreateInstance);
+ PlatformAndroid::CreateInstance, PlatformAndroid::DebuggerInitialize);
}
}
@@ -128,6 +154,16 @@
return PlatformSP();
}
+void PlatformAndroid::DebuggerInitialize(Debugger &debugger) {
+ if (!PluginManager::GetSettingForPlatformPlugin(
+ debugger, ConstString(GetPluginNameStatic(false)))) {
+ PluginManager::CreateSettingForPlatformPlugin(
+ debugger, GetGlobalProperties().GetValueProperties(),
+ "Properties for the Android platform plugin.",
+ /*is_global_property=*/true);
+ }
+}
+
PlatformAndroid::PlatformAndroid(bool is_host)
: PlatformLinux(is_host), m_sdk_version(0) {}
@@ -204,7 +240,8 @@
AdbClientSP adb(GetAdbClient());
char cmd[PATH_MAX];
- snprintf(cmd, sizeof(cmd), "cat '%s'", source_file.c_str());
+ snprintf(cmd, sizeof(cmd), "%scat '%s'", GetRunAs().c_str(),
+ source_file.c_str());
return adb->ShellToFile(cmd, minutes(1), destination);
}
@@ -255,9 +292,9 @@
// Use 'shell dd' to download the file slice with the offset and size.
char cmd[PATH_MAX];
snprintf(cmd, sizeof(cmd),
- "dd if='%s' iflag=skip_bytes,count_bytes "
+ "%sdd if='%s' iflag=skip_bytes,count_bytes "
"skip=%" PRIu64 " count=%" PRIu64 " status=none",
- source_file.c_str(), src_offset, src_size);
+ GetRunAs().c_str(), source_file.c_str(), src_offset, src_size);
return adb->ShellToFile(cmd, minutes(1), dst_file_spec);
}
@@ -324,7 +361,7 @@
AdbClientSP adb(GetAdbClient());
std::string tmpdir;
Status error = adb->Shell("mktemp --directory --tmpdir /data/local/tmp",
- seconds(5), &tmpdir);
+ seconds(5), &tmpdir);
if (error.Fail() || tmpdir.empty())
return Status("Failed to generate temporary directory on the device (%s)",
error.AsCString());
@@ -394,6 +431,26 @@
return std::make_unique<AdbClient>(m_device_id);
}
+llvm::StringRef PlatformAndroid::GetPropertyRunAs() {
+ return GetGlobalProperties().GetPropertyAtIndexAs<llvm::StringRef>(
+ ePropertyPlatformRunAs, "");
+}
+
+std::string PlatformAndroid::GetRunAs() {
+ llvm::StringRef run_as = GetPropertyRunAs();
+ if (!run_as.empty()) {
+ // When LLDB fails to pull file from a package directory due to security
+ // constraint, user needs to set the package name to
+ // 'platform.plugin.remote-android.run-as' property in order to run shell
+ // commands as the package user. (e.g. to get file with 'cat' and 'dd').
+ // https://cs.android.com/android/platform/superproject/+/master:
+ // system/core/run-as/run-as.cpp;l=39-61;
+ // drc=4a77a84a55522a3b122f9c63ef0d0b8a6a131627
+ return std::string("run-as '") + run_as.str() + "' ";
+ }
+ return run_as.str();
+}
+
AdbClient::SyncService *PlatformAndroid::GetSyncService(Status &error) {
if (m_adb_sync_svc && m_adb_sync_svc->IsConnected())
return m_adb_sync_svc.get();
Index: lldb/source/Plugins/Platform/Android/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Platform/Android/CMakeLists.txt
+++ lldb/source/Plugins/Platform/Android/CMakeLists.txt
@@ -1,3 +1,11 @@
+lldb_tablegen(PlatformAndroidProperties.inc -gen-lldb-property-defs
+ SOURCE PlatformAndroidProperties.td
+ TARGET LLDBPluginPlatformAndroidPropertiesGen)
+
+lldb_tablegen(PlatformAndroidPropertiesEnum.inc -gen-lldb-property-enum-defs
+ SOURCE PlatformAndroidProperties.td
+ TARGET LLDBPluginPlatformAndroidPropertiesEnumGen)
+
add_lldb_library(lldbPluginPlatformAndroid PLUGIN
AdbClient.cpp
PlatformAndroid.cpp
@@ -11,3 +19,7 @@
LINK_COMPONENTS
Support
)
+
+add_dependencies(lldbPluginPlatformAndroid
+ LLDBPluginPlatformAndroidPropertiesGen
+ LLDBPluginPlatformAndroidPropertiesEnumGen)
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits